broker_repository.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import 'package:dio/dio.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import '../../core/network/api_response.dart';
  4. import '../../core/network/dio_client.dart';
  5. /// 经纪商 Repository — 对应 agent-api AgentController
  6. class BrokerRepository {
  7. BrokerRepository(this._dio);
  8. final Dio _dio;
  9. /// 获取代理商信息(包含总返佣余额)
  10. /// 获取代理商信息(对应安卓 uc/agent/info)
  11. Future<Map<String, dynamic>?> getBrokerInfo() async {
  12. final resp = await _dio.post('uc/agent/info');
  13. final body = resp.data;
  14. if (body is Map<String, dynamic>) {
  15. return body['data'] as Map<String, dynamic>?;
  16. }
  17. return null;
  18. }
  19. /// 获取下级成员列表
  20. Future<List<Map<String, dynamic>>> getMemberList({int page = 1, int pageSize = 50}) async {
  21. final resp = await _dio.post('uc/agent/member/list', data: {
  22. 'pageNo': page,
  23. 'pageSize': pageSize,
  24. });
  25. final body = resp.data;
  26. if (body is Map<String, dynamic>) {
  27. final data = body['data'];
  28. if (data is Map && data['content'] is List) {
  29. return (data['content'] as List).cast<Map<String, dynamic>>();
  30. }
  31. if (data is List) return data.cast<Map<String, dynamic>>();
  32. }
  33. return [];
  34. }
  35. /// 获取返佣记录(分页)— 对应安卓 uc/agent/reward
  36. Future<List<Map<String, dynamic>>> getRewardList({
  37. int page = 1,
  38. int pageSize = 20,
  39. DateTime? startTime,
  40. }) async {
  41. String? startTimeStr;
  42. if (startTime != null) {
  43. final y = startTime.year.toString().padLeft(4, '0');
  44. final mo = startTime.month.toString().padLeft(2, '0');
  45. final d = startTime.day.toString().padLeft(2, '0');
  46. final h = startTime.hour.toString().padLeft(2, '0');
  47. final mi = startTime.minute.toString().padLeft(2, '0');
  48. final s = startTime.second.toString().padLeft(2, '0');
  49. startTimeStr = '$y-$mo-$d $h:$mi:$s';
  50. }
  51. final resp = await _dio.post('uc/agent/reward', queryParameters: {
  52. 'pageNo': page.toString(),
  53. 'pageSize': pageSize.toString(),
  54. if (startTimeStr != null) 'startTime': startTimeStr,
  55. });
  56. final body = resp.data;
  57. if (body is Map<String, dynamic>) {
  58. final data = body['data'];
  59. if (data is Map && data['content'] is List) {
  60. return (data['content'] as List).cast<Map<String, dynamic>>();
  61. }
  62. if (data is List) return data.cast<Map<String, dynamic>>();
  63. }
  64. return [];
  65. }
  66. /// 获取返佣比例设置列表(对应安卓 uc/agent/reward/set/list)
  67. Future<List<Map<String, dynamic>>> getRewardSetList() async {
  68. final resp = await _dio.post('uc/agent/reward/set/list');
  69. final body = resp.data;
  70. if (body is Map<String, dynamic>) {
  71. final data = body['data'];
  72. if (data is List) return data.cast<Map<String, dynamic>>();
  73. }
  74. return [];
  75. }
  76. /// 设置下级返佣比率(对应安卓 uc/agent/reward/set)
  77. Future<void> setReward({required String memberId, required int rate, int? followRate}) async {
  78. final params = <String, String>{
  79. 'id': memberId,
  80. 'rate': rate.toString(),
  81. if (followRate != null) 'followRate': followRate.toString(),
  82. };
  83. await _dio.post(
  84. 'uc/agent/reward/set',
  85. data: params,
  86. options: Options(contentType: Headers.formUrlEncodedContentType),
  87. );
  88. }
  89. /// 获取今日统计(对应安卓 uc/agent/stat)
  90. Future<Map<String, dynamic>> getTotalAward({String? endDate}) async {
  91. final resp = await _dio.get('uc/agent/stat', queryParameters: {
  92. if (endDate != null) 'endDate': endDate,
  93. });
  94. final body = resp.data;
  95. if (body is Map<String, dynamic>) {
  96. return (body['data'] as Map<String, dynamic>?) ?? {};
  97. }
  98. return {};
  99. }
  100. /// 提交经纪商申请
  101. /// 返回 null 表示成功,非空 String 为后端 message
  102. Future<String?> submitApply() async {
  103. try {
  104. await _dio.post('uc/agent/apply/submit', data: <String, dynamic>{});
  105. return null;
  106. } on DioException catch (e) {
  107. return extractDioMessage(e);
  108. }
  109. }
  110. /// 查询我的申请列表
  111. Future<List<Map<String, dynamic>>> getMyApplyList({int page = 1, int pageSize = 10}) async {
  112. final resp = await _dio.post('uc/agent/apply/my-list', data: {
  113. 'pageNo': page,
  114. 'pageSize': pageSize,
  115. });
  116. final body = resp.data;
  117. if (body is Map<String, dynamic>) {
  118. final data = body['data'];
  119. if (data is Map && data['content'] is List) {
  120. return (data['content'] as List).cast<Map<String, dynamic>>();
  121. }
  122. if (data is List) return data.cast<Map<String, dynamic>>();
  123. }
  124. return [];
  125. }
  126. }
  127. String extractDioMessage(DioException error) {
  128. final fromBody = messageFromResponseData(error.response?.data);
  129. if (fromBody.isNotEmpty) {
  130. return fromBody;
  131. }
  132. if (error.error is ApiException) {
  133. final msg = (error.error as ApiException).message.trim();
  134. if (msg.isNotEmpty) {
  135. return msg;
  136. }
  137. }
  138. return error.message?.trim() ?? '';
  139. }
  140. String messageFromResponseData(dynamic data) {
  141. if (data is Map) {
  142. final msg = data['message']?.toString().trim() ??
  143. data['msg']?.toString().trim() ??
  144. '';
  145. if (msg.isNotEmpty) {
  146. return msg;
  147. }
  148. }
  149. return '';
  150. }
  151. bool isAlreadyBrokerError(String message) {
  152. return message.contains('ALREADY_BROKER') ||
  153. message.contains('已经是经纪商') ||
  154. message.contains('已是经纪商');
  155. }
  156. bool isApplyPendingError(String message) {
  157. return message.contains('APPLY_PENDING') ||
  158. message.contains('经纪商申请正在审批') ||
  159. message.contains('正在审批') ||
  160. message.contains('正在审核') ||
  161. message.contains('待审核');
  162. }
  163. final brokerRepositoryProvider = Provider<BrokerRepository>((ref) {
  164. return BrokerRepository(ref.read(dioClientProvider));
  165. });