| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import '../core/network/dio_client.dart';
- import '../data/services/spot_service.dart';
- /// 单币种配置(来自 spot/v1/config/coin/list)
- class SpotCoinConfig {
- final String coin;
- final String icon;
- final int scale; // 余额显示小数位数(coinScale/scale/minScale)
- final int volumePre; // 数量精度(volumePre,覆盖 scale)
- /// 前台展示小数位(后端 showPrecision,与 ConfigCoinSymbol 一致)
- final int showPrecision;
- const SpotCoinConfig({
- required this.coin,
- this.icon = '',
- this.scale = 8,
- this.volumePre = 8,
- this.showPrecision = 0,
- });
- /// 资产列表等「按币种展示数量」的小数位:仅用后端 showPrecision;未配置(≤0)时默认 2
- int get assetDisplayDecimals =>
- showPrecision > 0 ? showPrecision.clamp(0, 18) : 2;
- factory SpotCoinConfig.fromJson(Map<String, dynamic> json) {
- final coin = (json['symbol'] ?? json['coinId'] ?? json['coin'] ?? '')
- .toString()
- .toUpperCase();
- final scale =
- ((json['coinScale'] ?? json['scale'] ?? json['minScale']) as num?)
- ?.toInt() ??
- 8;
- final volumePre =
- (json['volumePre'] as num?)?.toInt() ?? scale;
- final showPrecision =
- (json['showPrecision'] as num?)?.toInt() ?? 0;
- return SpotCoinConfig(
- coin: coin,
- icon: json['icon'] as String? ?? '',
- scale: scale,
- volumePre: volumePre,
- showPrecision: showPrecision,
- );
- }
- }
- /// 全局现货币种缓存 — 缓存 spot/v1/config/coin/list 返回的所有币种信息
- /// 键为大写币种符号(如 "BTC", "USDT"),供现货资产列表查询图标和余额精度
- class SpotCoinCacheNotifier extends Notifier<Map<String, SpotCoinConfig>> {
- @override
- Map<String, SpotCoinConfig> build() {
- Future.microtask(_load);
- return {};
- }
- Future<void> _load() async {
- try {
- final dio = ref.read(dioClientProvider);
- final coins = await SpotService(dio).getCoins();
- final configs = coins
- .map(SpotCoinConfig.fromJson)
- .where((c) => c.coin.isNotEmpty);
- state = {for (final c in configs) c.coin: c};
- } catch (_) {}
- }
- Future<void> refresh() => _load();
- }
- final spotCoinCacheProvider =
- NotifierProvider<SpotCoinCacheNotifier, Map<String, SpotCoinConfig>>(
- SpotCoinCacheNotifier.new,
- );
- /// 键统一为大写,与 [SpotCoinCacheNotifier] 中 map 一致
- SpotCoinConfig? lookupSpotCoinConfig(
- Map<String, SpotCoinConfig> map,
- String coin,
- ) {
- final k = coin.trim().toUpperCase();
- if (k.isEmpty) return null;
- return map[k];
- }
- /// 仅使用现货币种配置里的 icon(去空白);空串表示只显示字母占位,与「资产→现货」一致
- String spotCoinIconUrl(Map<String, SpotCoinConfig> map, String coin) {
- final raw = lookupSpotCoinConfig(map, coin)?.icon ?? '';
- return raw.trim();
- }
|