| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- /// 行情 Ticker 数据模型(不可变)
- /// 实现 == / hashCode 让 .select() 能正确判断单个 ticker 是否变化,
- /// 只有该 symbol 的价格/涨跌幅真正变了才触发对应行重建。
- class MarketTicker {
- final String symbol; // e.g. "BTCUSDT"
- final String baseAsset; // e.g. "BTC"
- final double lastPrice;
- final double change24h; // 24h 涨跌幅(百分比)
- final double volume24h; // 24h 成交额(USDT)
- final bool isFutures; // true = 永续合约,false = 现货
- final bool isHot; // 是否热门
- final String icon; // 币种图标 URL
- final int? pricePrecision; // 价格精度(小数位数),来自 coinScale
- final String? lastPriceStr; // WS 返回的原始价格字符串
- const MarketTicker({
- required this.symbol,
- required this.baseAsset,
- required this.lastPrice,
- required this.change24h,
- required this.volume24h,
- this.isFutures = true,
- this.isHot = false,
- this.icon = '',
- this.pricePrecision,
- this.lastPriceStr,
- });
- /// 从 /swap/coin/enabled-list 接口解析
- /// 接口字段: symbol("BTC/USDT"), coinSymbol("BTC"), baseSymbol("USDT"), isHot(1/0)
- /// 价格数据由 WebSocket 推送,初始为 0
- factory MarketTicker.fromJson(Map<String, dynamic> json) {
- // symbol 格式 "BTC/USDT" → 转为 "BTCUSDT"
- final rawSymbol = json['symbol'] as String? ?? '';
- final symbol = rawSymbol.replaceAll('/', '');
- final coinSymbol = json['coinSymbol'] as String? ?? '';
- final rawScale = (json['coinScale'] ?? json['minScale']) as num?;
- return MarketTicker(
- symbol: symbol,
- baseAsset: coinSymbol,
- lastPrice: 0,
- change24h: 0,
- volume24h: 0,
- isFutures: true,
- isHot: json['isHot'] == 1 || json['isHot'] == '1',
- icon: json['icon'] as String? ?? '',
- pricePrecision: rawScale?.toInt(),
- );
- }
- @override
- bool operator ==(Object other) =>
- identical(this, other) ||
- other is MarketTicker &&
- symbol == other.symbol &&
- baseAsset == other.baseAsset &&
- lastPrice == other.lastPrice &&
- change24h == other.change24h &&
- volume24h == other.volume24h &&
- isFutures == other.isFutures &&
- isHot == other.isHot &&
- icon == other.icon &&
- pricePrecision == other.pricePrecision &&
- lastPriceStr == other.lastPriceStr;
- @override
- int get hashCode =>
- Object.hash(symbol, baseAsset, lastPrice, change24h, volume24h, isFutures, isHot, icon, pricePrecision, lastPriceStr);
- MarketTicker copyWith({
- String? symbol,
- String? baseAsset,
- double? lastPrice,
- double? change24h,
- double? volume24h,
- bool? isFutures,
- bool? isHot,
- String? icon,
- int? pricePrecision,
- String? lastPriceStr,
- }) {
- return MarketTicker(
- symbol: symbol ?? this.symbol,
- baseAsset: baseAsset ?? this.baseAsset,
- lastPrice: lastPrice ?? this.lastPrice,
- change24h: change24h ?? this.change24h,
- volume24h: volume24h ?? this.volume24h,
- isFutures: isFutures ?? this.isFutures,
- isHot: isHot ?? this.isHot,
- icon: icon ?? this.icon,
- pricePrecision: pricePrecision ?? this.pricePrecision,
- lastPriceStr: lastPriceStr ?? this.lastPriceStr,
- );
- }
- }
|