feat:参照研听的基础工程
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import '../../../common/domain/metal_type.dart';
|
||||
|
||||
enum MarketPeriod {
|
||||
h24('24h', '24时'),
|
||||
d5('5d', '5日'),
|
||||
m1('1m', '1月'),
|
||||
m3('3m', '3月'),
|
||||
y1('1y', '1年');
|
||||
|
||||
const MarketPeriod(this.id, this.label);
|
||||
|
||||
final String id;
|
||||
final String label;
|
||||
}
|
||||
|
||||
enum ExchangeChannelKind { spot, bar, retail, td, recycle }
|
||||
|
||||
class MetalQuote {
|
||||
const MetalQuote({
|
||||
required this.metal,
|
||||
required this.spotPrice,
|
||||
required this.changeAmount,
|
||||
required this.changePercent,
|
||||
required this.updatedAt,
|
||||
required this.sourceLabel,
|
||||
required this.basisLabel,
|
||||
});
|
||||
|
||||
final MetalType metal;
|
||||
final double spotPrice;
|
||||
final double changeAmount;
|
||||
final double changePercent;
|
||||
final DateTime updatedAt;
|
||||
final String sourceLabel;
|
||||
final String basisLabel;
|
||||
}
|
||||
|
||||
class MarketPoint {
|
||||
const MarketPoint({
|
||||
required this.time,
|
||||
required this.open,
|
||||
required this.high,
|
||||
required this.low,
|
||||
required this.close,
|
||||
});
|
||||
|
||||
final DateTime time;
|
||||
final double open;
|
||||
final double high;
|
||||
final double low;
|
||||
final double close;
|
||||
}
|
||||
|
||||
class ExchangeChannel {
|
||||
const ExchangeChannel({
|
||||
required this.id,
|
||||
required this.metal,
|
||||
required this.name,
|
||||
required this.kind,
|
||||
required this.pricePerGram,
|
||||
required this.source,
|
||||
required this.updatedAt,
|
||||
required this.hint,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final MetalType metal;
|
||||
final String name;
|
||||
final ExchangeChannelKind kind;
|
||||
final double pricePerGram;
|
||||
final String source;
|
||||
final DateTime updatedAt;
|
||||
final String hint;
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import '../../../common/domain/metal_type.dart';
|
||||
import 'market_models.dart';
|
||||
|
||||
final mockMarketRepositoryProvider = Provider<MockMarketRepository>(
|
||||
(ref) => MockMarketRepository(),
|
||||
);
|
||||
|
||||
class MockMarketRepository {
|
||||
MockMarketRepository();
|
||||
|
||||
final DateTime _updatedAt = DateTime(2026, 6, 18, 16, 11);
|
||||
|
||||
List<MetalQuote> getQuotes() {
|
||||
return [
|
||||
MetalQuote(
|
||||
metal: MetalType.gold,
|
||||
spotPrice: 943.05,
|
||||
changeAmount: 8.12,
|
||||
changePercent: 0.87,
|
||||
updatedAt: _updatedAt,
|
||||
sourceLabel: '行情聚合',
|
||||
basisLabel: '上海金现货参考价',
|
||||
),
|
||||
MetalQuote(
|
||||
metal: MetalType.platinum,
|
||||
spotPrice: 384.20,
|
||||
changeAmount: -2.46,
|
||||
changePercent: -0.64,
|
||||
updatedAt: _updatedAt,
|
||||
sourceLabel: '行情聚合',
|
||||
basisLabel: '国际盘换算参考价',
|
||||
),
|
||||
MetalQuote(
|
||||
metal: MetalType.silver,
|
||||
spotPrice: 15.75,
|
||||
changeAmount: 0.18,
|
||||
changePercent: 1.16,
|
||||
updatedAt: _updatedAt,
|
||||
sourceLabel: '行情聚合',
|
||||
basisLabel: '上海银现货参考价',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
MetalQuote quoteFor(MetalType metal) =>
|
||||
getQuotes().firstWhere((quote) => quote.metal == metal);
|
||||
|
||||
List<MarketPoint> chartFor(MetalType metal, MarketPeriod period) {
|
||||
final quote = quoteFor(metal);
|
||||
final points = <MarketPoint>[];
|
||||
final step = switch (period) {
|
||||
MarketPeriod.h24 => const Duration(hours: 2),
|
||||
MarketPeriod.d5 => const Duration(days: 1),
|
||||
MarketPeriod.m1 => const Duration(days: 3),
|
||||
MarketPeriod.m3 => const Duration(days: 9),
|
||||
MarketPeriod.y1 => const Duration(days: 30),
|
||||
};
|
||||
for (var i = 11; i >= 0; i--) {
|
||||
final drift = (i - 5.5) * quote.changeAmount / 10;
|
||||
final close = quote.spotPrice - drift;
|
||||
points.add(
|
||||
MarketPoint(
|
||||
time: _updatedAt.subtract(step * i),
|
||||
open: close - quote.changeAmount / 20,
|
||||
high: close + quote.spotPrice * 0.003,
|
||||
low: close - quote.spotPrice * 0.003,
|
||||
close: close,
|
||||
),
|
||||
);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
List<ExchangeChannel> channelsFor(MetalType metal, {double recycle = 0.97}) {
|
||||
final quote = quoteFor(metal);
|
||||
return switch (metal) {
|
||||
MetalType.gold => [
|
||||
_channel(
|
||||
'gold_spot',
|
||||
metal,
|
||||
'上海金现货',
|
||||
ExchangeChannelKind.spot,
|
||||
943.05,
|
||||
'上海金现货',
|
||||
'材料价值口径 · 非金店零售 / 回收价',
|
||||
),
|
||||
_channel(
|
||||
'gold_bar',
|
||||
metal,
|
||||
'投资金条',
|
||||
ExchangeChannelKind.bar,
|
||||
955.00,
|
||||
'银行 / 品牌金条参考',
|
||||
'投资金条参考 · 通常含少量升水',
|
||||
),
|
||||
_channel(
|
||||
'gold_ctf',
|
||||
metal,
|
||||
'周大福金店',
|
||||
ExchangeChannelKind.retail,
|
||||
1238.00,
|
||||
'品牌零售挂牌参考',
|
||||
'含工费与品牌溢价 · 以门店为准',
|
||||
),
|
||||
_channel(
|
||||
'gold_lfx',
|
||||
metal,
|
||||
'老凤祥金店',
|
||||
ExchangeChannelKind.retail,
|
||||
1248.00,
|
||||
'品牌零售挂牌参考',
|
||||
'含工费与品牌溢价 · 以门店为准',
|
||||
),
|
||||
_channel(
|
||||
'gold_td',
|
||||
metal,
|
||||
'黄金 T+D',
|
||||
ExchangeChannelKind.td,
|
||||
919.50,
|
||||
'SGE 递延参考',
|
||||
'交易品种参考 · 非实物购买价',
|
||||
),
|
||||
_channel(
|
||||
'gold_recycle',
|
||||
metal,
|
||||
'回收参考',
|
||||
ExchangeChannelKind.recycle,
|
||||
quote.spotPrice * recycle,
|
||||
'材料价值 × 回收折扣',
|
||||
'实际以门店检测为准',
|
||||
),
|
||||
],
|
||||
MetalType.platinum => [
|
||||
_channel(
|
||||
'platinum_spot',
|
||||
metal,
|
||||
'铂金现货',
|
||||
ExchangeChannelKind.spot,
|
||||
384.20,
|
||||
'国际盘换算参考',
|
||||
'材料价值口径 · 非饰品零售价',
|
||||
),
|
||||
_channel(
|
||||
'platinum_retail',
|
||||
metal,
|
||||
'铂金饰品',
|
||||
ExchangeChannelKind.retail,
|
||||
498.00,
|
||||
'零售挂牌参考',
|
||||
'含工费与品牌溢价',
|
||||
),
|
||||
_channel(
|
||||
'platinum_recycle',
|
||||
metal,
|
||||
'回收参考',
|
||||
ExchangeChannelKind.recycle,
|
||||
quote.spotPrice * recycle,
|
||||
'材料价值 × 回收折扣',
|
||||
'实际以门店检测为准',
|
||||
),
|
||||
],
|
||||
MetalType.silver => [
|
||||
_channel(
|
||||
'silver_spot',
|
||||
metal,
|
||||
'白银现货',
|
||||
ExchangeChannelKind.spot,
|
||||
15.75,
|
||||
'上海银现货',
|
||||
'材料价值口径 · 非饰品零售价',
|
||||
),
|
||||
_channel(
|
||||
'silver_retail',
|
||||
metal,
|
||||
'白银饰品',
|
||||
ExchangeChannelKind.retail,
|
||||
42.00,
|
||||
'零售挂牌参考',
|
||||
'含工费与品牌溢价',
|
||||
),
|
||||
_channel(
|
||||
'silver_recycle',
|
||||
metal,
|
||||
'回收参考',
|
||||
ExchangeChannelKind.recycle,
|
||||
quote.spotPrice * recycle,
|
||||
'材料价值 × 回收折扣',
|
||||
'实际以门店检测为准',
|
||||
),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
ExchangeChannel _channel(
|
||||
String id,
|
||||
MetalType metal,
|
||||
String name,
|
||||
ExchangeChannelKind kind,
|
||||
double price,
|
||||
String source,
|
||||
String hint,
|
||||
) {
|
||||
return ExchangeChannel(
|
||||
id: id,
|
||||
metal: metal,
|
||||
name: name,
|
||||
kind: kind,
|
||||
pricePerGram: price,
|
||||
source: source,
|
||||
updatedAt: _updatedAt,
|
||||
hint: hint,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user