spot_transfer_asset.dart 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import '../../data/models/asset/today_pnl.dart';
  2. import '../../data/models/finance/staking_wallet_balance.dart';
  3. /// 解析现货各币种可用余额(对齐 Web `parseSpotAvailableMap`)。
  4. Map<String, String> parseSpotAvailableMap(Map<String, dynamic> spotData) {
  5. final map = <String, String>{};
  6. final list = spotData['assetList'];
  7. if (list is! List) {
  8. return map;
  9. }
  10. for (final item in list) {
  11. if (item is! Map<String, dynamic>) {
  12. continue;
  13. }
  14. final coin = '${item['symbol'] ?? item['coinId'] ?? item['coin'] ?? ''}'
  15. .toUpperCase()
  16. .trim();
  17. if (coin.isEmpty) {
  18. continue;
  19. }
  20. final avail = item['available'] ?? item['balance'];
  21. map[coin] = '${avail ?? '0'}';
  22. }
  23. return map;
  24. }
  25. /// 现货币种开放列表(对齐 Web `parseOpenCoinSymbols`)。
  26. List<String> parseOpenCoinSymbols(List<Map<String, dynamic>> coinsRaw) {
  27. final set = <String>{};
  28. for (final item in coinsRaw) {
  29. final sym =
  30. '${item['symbol'] ?? item['coinSymbol'] ?? ''}'.toUpperCase().trim();
  31. if (sym.isNotEmpty) {
  32. set.add(sym);
  33. }
  34. }
  35. final list = set.toList()
  36. ..sort((a, b) {
  37. if (a == 'USDT') {
  38. return -1;
  39. }
  40. if (b == 'USDT') {
  41. return 1;
  42. }
  43. return a.compareTo(b);
  44. });
  45. if (list.isEmpty) {
  46. return const ['USDT'];
  47. }
  48. return list;
  49. }
  50. /// 资金账户各币种可用余额(对齐 Web `parseFundWalletBalances`)。
  51. Map<String, String> parseFundWalletBalances(dynamic raw) {
  52. final map = <String, String>{};
  53. final arr = raw is List
  54. ? raw
  55. : raw is Map<String, dynamic> && raw['data'] is List
  56. ? raw['data'] as List
  57. : null;
  58. if (arr == null) {
  59. return map;
  60. }
  61. for (final item in arr) {
  62. if (item is! Map<String, dynamic>) {
  63. continue;
  64. }
  65. final coin = item['coin'];
  66. final unit = '${item['coinUnit'] ?? (coin is Map ? coin['unit'] ?? coin['name'] : null) ?? item['unit'] ?? ''}'
  67. .toUpperCase()
  68. .trim();
  69. if (unit.isEmpty) {
  70. continue;
  71. }
  72. final bal = item['balance'] ?? item['available'] ?? item['useBalance'];
  73. map[unit] = '${bal ?? '0'}';
  74. }
  75. return map;
  76. }
  77. AccountInfo? pickStakingAccount(List<AccountInfo> list) {
  78. for (final row in list) {
  79. final name = row.name.trim();
  80. if (name.contains('质押') || name.toLowerCase().contains('staking')) {
  81. return row;
  82. }
  83. }
  84. return null;
  85. }
  86. String stakingOverviewLockedFromAccounts(List<AccountInfo> list) {
  87. final row = pickStakingAccount(list);
  88. if (row == null) {
  89. return '0';
  90. }
  91. return row.frozenBalance.toString();
  92. }
  93. String stakingOverviewAvailableFromAccounts(List<AccountInfo> list) {
  94. final row = pickStakingAccount(list);
  95. if (row == null) {
  96. return '0';
  97. }
  98. return row.balance.toString();
  99. }
  100. String stakingOverviewReleasedFromAccounts(List<AccountInfo> list) {
  101. final row = pickStakingAccount(list);
  102. if (row == null) {
  103. return '0';
  104. }
  105. return row.releasedTotal.toString();
  106. }
  107. /// 总览锁仓余额合并 wallet-new 与 staking/wallet(对齐 Web applyStakingOverviewBalances)
  108. ({String available, String locked, String released}) mergeStakingOverviewBalances({
  109. required String walletAvailable,
  110. required String walletLocked,
  111. required String walletReleased,
  112. StakingWalletBalance? apiWallet,
  113. }) {
  114. var available = walletAvailable;
  115. var locked = walletLocked;
  116. var released = walletReleased;
  117. if (apiWallet == null) {
  118. return (available: available, locked: locked, released: released);
  119. }
  120. final apiAvailable = apiWallet.availableBalance;
  121. final apiLocked = apiWallet.lockedBalance;
  122. final apiReleased = apiWallet.releasedTotal;
  123. if ((double.tryParse(available) ?? 0) <= 0 &&
  124. (double.tryParse(apiAvailable) ?? 0) > 0) {
  125. available = apiAvailable;
  126. }
  127. if ((double.tryParse(locked) ?? 0) <= 0 &&
  128. (double.tryParse(apiLocked) ?? 0) > 0) {
  129. locked = apiLocked;
  130. }
  131. if ((double.tryParse(released) ?? 0) <= 0 &&
  132. (double.tryParse(apiReleased) ?? 0) > 0) {
  133. released = apiReleased;
  134. }
  135. return (available: available, locked: locked, released: released);
  136. }