withdraw_service.dart 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import 'package:decimal/decimal.dart';
  2. import 'package:dio/dio.dart';
  3. import '../models/asset/account_auth.dart';
  4. import '../models/asset/withdraw_balance.dart';
  5. import '../models/asset/withdraw_record.dart';
  6. /// 提币 API 服务(无状态)
  7. class WithdrawService {
  8. const WithdrawService(this._dio);
  9. final Dio _dio;
  10. /// 获取可用余额
  11. Future<WithdrawBalance> getBalance(String coinName) async {
  12. // 可用余额必须始终从服务器获取,不能使用缓存
  13. final response = await _dio.post<Map<String, dynamic>>(
  14. 'uc/asset/wallet/$coinName',
  15. options: Options(extra: {'noCache': true}),
  16. );
  17. final data = response.data?['data'];
  18. if (data is Map<String, dynamic>) {
  19. return WithdrawBalance.fromJson(data);
  20. }
  21. return WithdrawBalance();
  22. }
  23. /// 获取认证信息(Google验证状态等)
  24. Future<AccountAuth> getSecuritySetting() async {
  25. final response = await _dio.post<Map<String, dynamic>>(
  26. 'uc/approve/security/setting',
  27. );
  28. final data = response.data?['data'];
  29. if (data is Map<String, dynamic>) {
  30. return AccountAuth.fromJson(data);
  31. }
  32. return const AccountAuth();
  33. }
  34. /// 发送提币邮箱验证码
  35. Future<void> sendWithdrawEmailCode({
  36. required String unit,
  37. required String address,
  38. required String amount,
  39. }) async {
  40. await _dio.post(
  41. 'uc/withdraw/email/code',
  42. data: {'unit': unit, 'address': address, 'amount': amount},
  43. options: Options(contentType: Headers.formUrlEncodedContentType),
  44. );
  45. }
  46. /// 链上提币
  47. Future<void> withdrawApply({
  48. required String unit,
  49. required String amount,
  50. required String address,
  51. required String fee,
  52. required String vcode,
  53. required String jyPassword,
  54. required String vcode2,
  55. String remark = '',
  56. }) async {
  57. await _dio.post(
  58. 'uc/withdraw/apply/code',
  59. data: {
  60. 'unit': unit,
  61. 'amount': amount,
  62. 'address': address,
  63. 'fee': fee,
  64. 'vcode': vcode,
  65. 'vtype': '2', // 邮箱验证
  66. 'jyPassword': jyPassword,
  67. 'vcode2': vcode2,
  68. 'remark': remark,
  69. },
  70. options: Options(contentType: Headers.formUrlEncodedContentType),
  71. );
  72. }
  73. /// 获取内部转账最小金额(USDT 基础币种配置)
  74. Future<Decimal> getTransferMinAmount({String unit = 'USDT'}) async {
  75. try {
  76. final response = await _dio.post<Map<String, dynamic>>(
  77. 'uc/withdraw/support/coin/info',
  78. options: Options(extra: {'noCache': true}),
  79. );
  80. final data = response.data?['data'];
  81. if (data is List) {
  82. for (final item in data) {
  83. if (item is Map<String, dynamic> && item['unit'] == unit) {
  84. return Decimal.tryParse(item['minAmount']?.toString() ?? '') ?? Decimal.zero;
  85. }
  86. }
  87. }
  88. } catch (_) {}
  89. return Decimal.zero;
  90. }
  91. /// 内部转账
  92. Future<void> internalTransfer({
  93. required String unit,
  94. required String amount,
  95. required String address,
  96. required String vcode,
  97. required String jyPassword,
  98. required String vcode2,
  99. String remark = '',
  100. }) async {
  101. await _dio.post(
  102. 'uc/withdraw/transfer',
  103. data: {
  104. 'unit': unit,
  105. 'amount': amount,
  106. 'address': address,
  107. 'vcode': vcode,
  108. 'vtype': '2',
  109. 'jyPassword': jyPassword,
  110. 'vcode2': vcode2,
  111. 'remark': remark,
  112. },
  113. options: Options(contentType: Headers.formUrlEncodedContentType),
  114. );
  115. }
  116. /// 链上提现记录(page 从 0 开始)
  117. Future<List<WithdrawRecord>> getWithdrawRecords({
  118. int page = 0,
  119. int pageSize = 10,
  120. }) async {
  121. final response = await _dio.get<Map<String, dynamic>>(
  122. 'uc/withdraw/record',
  123. queryParameters: {'page': page, 'pageSize': pageSize},
  124. );
  125. return _parseRecordList(response.data);
  126. }
  127. /// 内部转账记录(pageNo 从 0 开始)
  128. Future<List<WithdrawRecord>> getTransferRecords({
  129. int pageNo = 0,
  130. int pageSize = 10,
  131. }) async {
  132. final response = await _dio.get<Map<String, dynamic>>(
  133. 'uc/withdraw/transfer/record',
  134. queryParameters: {'pageNo': pageNo, 'pageSize': pageSize},
  135. );
  136. return _parseRecordList(response.data);
  137. }
  138. /// 取消链上提现
  139. Future<void> cancelWithdraw(String id) async {
  140. await _dio.post('uc/withdraw/cancel', queryParameters: {'id': id});
  141. }
  142. /// 获取单条链上提现记录详情
  143. Future<WithdrawRecord> getWithdrawRecord(String id) async {
  144. final response = await _dio.get<Map<String, dynamic>>(
  145. 'uc/withdraw/record/$id',
  146. );
  147. final data = response.data?['data'];
  148. if (data is Map<String, dynamic>) {
  149. return WithdrawRecord.fromJson(data);
  150. }
  151. return WithdrawRecord(id: id);
  152. }
  153. /// 获取单条内部转账记录详情
  154. Future<WithdrawRecord> getTransferRecord(String id) async {
  155. final response = await _dio.get<Map<String, dynamic>>(
  156. 'uc/withdraw/transfer/record/$id',
  157. );
  158. final data = response.data?['data'];
  159. if (data is Map<String, dynamic>) {
  160. return WithdrawRecord.fromJson(data);
  161. }
  162. return WithdrawRecord(id: id);
  163. }
  164. /// 取消内部转账
  165. Future<void> cancelTransfer(String id) async {
  166. await _dio.post('uc/withdraw/transfer/cancel', queryParameters: {'id': id});
  167. }
  168. List<WithdrawRecord> _parseRecordList(Map<String, dynamic>? responseData) {
  169. final data = responseData?['data'];
  170. if (data is Map<String, dynamic>) {
  171. final content = data['content'];
  172. if (content is List) {
  173. return content
  174. .whereType<Map<String, dynamic>>()
  175. .map((e) => WithdrawRecord.fromJson(e))
  176. .toList();
  177. }
  178. }
  179. return [];
  180. }
  181. }