2026-04-07 01:05:05 +08:00
|
|
|
|
/// 幣種模型
|
2026-03-22 00:21:21 +08:00
|
|
|
|
class Coin {
|
|
|
|
|
|
final int id;
|
|
|
|
|
|
final String code;
|
|
|
|
|
|
final String name;
|
|
|
|
|
|
final String? icon;
|
|
|
|
|
|
final double price;
|
|
|
|
|
|
final double? priceUsd;
|
|
|
|
|
|
final double? priceCny;
|
2026-04-07 01:05:05 +08:00
|
|
|
|
final int priceType; // 1=實時價格, 2=管理員設置
|
2026-03-22 00:21:21 +08:00
|
|
|
|
final double change24h;
|
|
|
|
|
|
final double? high24h;
|
|
|
|
|
|
final double? low24h;
|
|
|
|
|
|
final double? volume24h;
|
|
|
|
|
|
final int status;
|
|
|
|
|
|
final int sort;
|
|
|
|
|
|
|
|
|
|
|
|
Coin({
|
|
|
|
|
|
required this.id,
|
|
|
|
|
|
required this.code,
|
|
|
|
|
|
required this.name,
|
|
|
|
|
|
this.icon,
|
|
|
|
|
|
required this.price,
|
|
|
|
|
|
this.priceUsd,
|
|
|
|
|
|
this.priceCny,
|
|
|
|
|
|
required this.priceType,
|
|
|
|
|
|
required this.change24h,
|
|
|
|
|
|
this.high24h,
|
|
|
|
|
|
this.low24h,
|
|
|
|
|
|
this.volume24h,
|
|
|
|
|
|
required this.status,
|
|
|
|
|
|
this.sort = 0,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
factory Coin.fromJson(Map<String, dynamic> json) {
|
|
|
|
|
|
return Coin(
|
|
|
|
|
|
id: json['id'] as int? ?? 0,
|
|
|
|
|
|
code: json['code'] as String? ?? '',
|
|
|
|
|
|
name: json['name'] as String? ?? '',
|
|
|
|
|
|
icon: json['icon'] as String?,
|
|
|
|
|
|
price: (json['price'] as num?)?.toDouble() ?? 0,
|
|
|
|
|
|
priceUsd: (json['priceUsd'] as num?)?.toDouble(),
|
|
|
|
|
|
priceCny: (json['priceCny'] as num?)?.toDouble(),
|
|
|
|
|
|
priceType: json['priceType'] as int? ?? 1,
|
|
|
|
|
|
change24h: (json['change24h'] as num?)?.toDouble() ?? 0,
|
|
|
|
|
|
high24h: (json['high24h'] as num?)?.toDouble(),
|
|
|
|
|
|
low24h: (json['low24h'] as num?)?.toDouble(),
|
|
|
|
|
|
volume24h: (json['volume24h'] as num?)?.toDouble(),
|
|
|
|
|
|
status: json['status'] as int? ?? 1,
|
|
|
|
|
|
sort: json['sort'] as int? ?? 0,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Map<String, dynamic> toJson() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
'id': id,
|
|
|
|
|
|
'code': code,
|
|
|
|
|
|
'name': name,
|
|
|
|
|
|
'icon': icon,
|
|
|
|
|
|
'price': price,
|
|
|
|
|
|
'priceUsd': priceUsd,
|
|
|
|
|
|
'priceCny': priceCny,
|
|
|
|
|
|
'priceType': priceType,
|
|
|
|
|
|
'change24h': change24h,
|
|
|
|
|
|
'high24h': high24h,
|
|
|
|
|
|
'low24h': low24h,
|
|
|
|
|
|
'volume24h': volume24h,
|
|
|
|
|
|
'status': status,
|
|
|
|
|
|
'sort': sort,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-07 01:05:05 +08:00
|
|
|
|
/// 顯示圖標(Unicode 符號)
|
2026-03-22 00:21:21 +08:00
|
|
|
|
String get displayIcon {
|
|
|
|
|
|
const icons = {
|
|
|
|
|
|
'BTC': '\u20BF',
|
|
|
|
|
|
'ETH': '\u039E',
|
|
|
|
|
|
'SOL': '\u25CD',
|
|
|
|
|
|
'USDT': '\u20AE',
|
|
|
|
|
|
'DOGE': '\uD83D\uDC15',
|
|
|
|
|
|
'XRP': '\u2715',
|
|
|
|
|
|
'BNB': '\u25B3',
|
|
|
|
|
|
'ADA': '\u25C6',
|
|
|
|
|
|
};
|
|
|
|
|
|
return icons[code] ?? '\u25CF';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-07 01:05:05 +08:00
|
|
|
|
/// 格式化價格顯示
|
2026-03-22 00:21:21 +08:00
|
|
|
|
String get formattedPrice {
|
|
|
|
|
|
if (price >= 1000) return price.toStringAsFixed(2);
|
|
|
|
|
|
if (price >= 1) return price.toStringAsFixed(4);
|
|
|
|
|
|
return price.toStringAsFixed(6);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-07 01:05:05 +08:00
|
|
|
|
/// 格式化漲跌幅
|
2026-03-22 00:21:21 +08:00
|
|
|
|
String get formattedChange {
|
|
|
|
|
|
final prefix = change24h >= 0 ? '+' : '';
|
|
|
|
|
|
return '$prefix${change24h.toStringAsFixed(2)}%';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-07 01:05:05 +08:00
|
|
|
|
/// 是否上漲
|
2026-03-22 00:21:21 +08:00
|
|
|
|
bool get isUp => change24h >= 0;
|
|
|
|
|
|
|
2026-04-07 01:05:05 +08:00
|
|
|
|
/// 是否為實時價格
|
2026-03-22 00:21:21 +08:00
|
|
|
|
bool get isRealtime => priceType == 1;
|
|
|
|
|
|
}
|