dio_client.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import 'package:dio/dio.dart' hide LogInterceptor;
  2. import 'package:sino_med_cloud/core/constants/api_constants.dart';
  3. import 'package:sino_med_cloud/core/network/interceptors/auth_interceptor.dart';
  4. import 'package:sino_med_cloud/core/network/interceptors/error_interceptor.dart';
  5. import 'package:sino_med_cloud/core/network/interceptors/log_interceptor.dart';
  6. import 'package:sino_med_cloud/core/utils/logger.dart';
  7. import 'package:sino_med_cloud/base/common_response.dart';
  8. /// Dio 客户端 - 统一网络请求管理
  9. class DioClient {
  10. // 使用一个内部方法来创建和配置 Dio 实例
  11. static final Dio _dio = _createDio();
  12. static Dio _createDio() {
  13. AppLogger.d('DioClient - 开始创建 Dio 实例并配置拦截器');
  14. final dio = Dio(
  15. BaseOptions(
  16. baseUrl: ApiConstants.baseUrl,
  17. connectTimeout: Duration(seconds: ApiConstants.connectTimeout),
  18. receiveTimeout: Duration(seconds: ApiConstants.receiveTimeout),
  19. sendTimeout: Duration(seconds: ApiConstants.sendTimeout),
  20. headers: {
  21. ApiConstants.contentType: ApiConstants.applicationJson,
  22. },
  23. ),
  24. );
  25. // 立即添加拦截器
  26. dio.interceptors.addAll([
  27. AuthInterceptor(), // 认证拦截器
  28. LogInterceptor(), // 日志拦截器
  29. ErrorInterceptor(), // 错误拦截器
  30. ]);
  31. AppLogger.d('DioClient - Dio 实例初始化完成,拦截器数量: ${dio.interceptors.length}');
  32. return dio;
  33. }
  34. // 暴露 dio 实例
  35. static Dio get dio => _dio;
  36. /// 重置 Dio 实例(用于重新配置)
  37. static void reset() {
  38. _dio.interceptors.clear();
  39. _dio.interceptors.addAll([
  40. AuthInterceptor(),
  41. LogInterceptor(),
  42. ErrorInterceptor(),
  43. ]);
  44. }
  45. // ==================== GET 请求 ====================
  46. /// GET 请求
  47. ///
  48. /// [path] 请求路径(相对于 baseUrl)
  49. /// [fromJsonT] JSON 转换为 T 类型的函数
  50. /// [queryParameters] 查询参数
  51. /// [options] 请求选项
  52. ///
  53. /// 返回 [BaseCommonResponse] 对象
  54. static Future<BaseCommonResponse<T>> get<T>(
  55. String path, {
  56. required T Function(Object? json) fromJsonT,
  57. Map<String, dynamic>? queryParameters,
  58. Options? options,
  59. CancelToken? cancelToken,
  60. ProgressCallback? onReceiveProgress,
  61. }) async {
  62. try {
  63. final response = await dio.get(
  64. path,
  65. queryParameters: queryParameters,
  66. options: options,
  67. cancelToken: cancelToken,
  68. onReceiveProgress: onReceiveProgress,
  69. );
  70. return BaseCommonResponse<T>.fromJson(
  71. response.data as Map<String, dynamic>,
  72. fromJsonT,
  73. );
  74. } on DioException catch (e) {
  75. // 错误已由 ErrorInterceptor 处理,直接抛出
  76. rethrow;
  77. }
  78. }
  79. // ==================== POST 请求 ====================
  80. /// POST 请求
  81. ///
  82. /// [path] 请求路径(相对于 baseUrl)
  83. /// [fromJsonT] JSON 转换为 T 类型的函数
  84. /// [data] 请求体数据
  85. /// [queryParameters] 查询参数
  86. /// [options] 请求选项
  87. ///
  88. /// 返回 [BaseCommonResponse] 对象
  89. static Future<BaseCommonResponse<T>> post<T>(
  90. String path, {
  91. required T Function(Object? json) fromJsonT,
  92. dynamic data,
  93. Map<String, dynamic>? queryParameters,
  94. Options? options,
  95. CancelToken? cancelToken,
  96. ProgressCallback? onSendProgress,
  97. ProgressCallback? onReceiveProgress,
  98. }) async {
  99. try {
  100. final response = await dio.post(
  101. path,
  102. data: data,
  103. queryParameters: queryParameters,
  104. options: options,
  105. cancelToken: cancelToken,
  106. onSendProgress: onSendProgress,
  107. onReceiveProgress: onReceiveProgress,
  108. );
  109. return BaseCommonResponse<T>.fromJson(
  110. response.data as Map<String, dynamic>,
  111. fromJsonT,
  112. );
  113. } on DioException catch (e) {
  114. // 错误已由 ErrorInterceptor 处理,直接抛出
  115. rethrow;
  116. }
  117. }
  118. // ==================== DELETE 请求 ====================
  119. /// DELETE 请求
  120. ///
  121. /// [path] 请求路径(相对于 baseUrl)
  122. /// [fromJsonT] JSON 转换为 T 类型的函数
  123. /// [data] 请求体数据(可选)
  124. /// [queryParameters] 查询参数
  125. /// [options] 请求选项
  126. ///
  127. /// 返回 [BaseCommonResponse] 对象
  128. static Future<BaseCommonResponse<T>> delete<T>(
  129. String path, {
  130. required T Function(Object? json) fromJsonT,
  131. dynamic data,
  132. Map<String, dynamic>? queryParameters,
  133. Options? options,
  134. CancelToken? cancelToken,
  135. }) async {
  136. try {
  137. final response = await dio.delete(
  138. path,
  139. data: data,
  140. queryParameters: queryParameters,
  141. options: options,
  142. cancelToken: cancelToken,
  143. );
  144. return BaseCommonResponse<T>.fromJson(
  145. response.data as Map<String, dynamic>,
  146. fromJsonT,
  147. );
  148. } on DioException catch (e) {
  149. // 错误已由 ErrorInterceptor 处理,直接抛出
  150. rethrow;
  151. }
  152. }
  153. // ==================== PUT 请求 ====================
  154. /// PUT 请求
  155. ///
  156. /// [path] 请求路径(相对于 baseUrl)
  157. /// [fromJsonT] JSON 转换为 T 类型的函数
  158. /// [data] 请求体数据
  159. /// [queryParameters] 查询参数
  160. /// [options] 请求选项
  161. ///
  162. /// 返回 [BaseCommonResponse] 对象
  163. static Future<BaseCommonResponse<T>> put<T>(
  164. String path, {
  165. required T Function(Object? json) fromJsonT,
  166. dynamic data,
  167. Map<String, dynamic>? queryParameters,
  168. Options? options,
  169. CancelToken? cancelToken,
  170. ProgressCallback? onSendProgress,
  171. ProgressCallback? onReceiveProgress,
  172. }) async {
  173. try {
  174. final response = await dio.put(
  175. path,
  176. data: data,
  177. queryParameters: queryParameters,
  178. options: options,
  179. cancelToken: cancelToken,
  180. onSendProgress: onSendProgress,
  181. onReceiveProgress: onReceiveProgress,
  182. );
  183. return BaseCommonResponse<T>.fromJson(
  184. response.data as Map<String, dynamic>,
  185. fromJsonT,
  186. );
  187. } on DioException catch (e) {
  188. // 错误已由 ErrorInterceptor 处理,直接抛出
  189. rethrow;
  190. }
  191. }
  192. // ==================== PATCH 请求 ====================
  193. /// PATCH 请求
  194. ///
  195. /// [path] 请求路径(相对于 baseUrl)
  196. /// [fromJsonT] JSON 转换为 T 类型的函数
  197. /// [data] 请求体数据
  198. /// [queryParameters] 查询参数
  199. /// [options] 请求选项
  200. ///
  201. /// 返回 [BaseCommonResponse] 对象
  202. static Future<BaseCommonResponse<T>> patch<T>(
  203. String path, {
  204. required T Function(Object? json) fromJsonT,
  205. dynamic data,
  206. Map<String, dynamic>? queryParameters,
  207. Options? options,
  208. CancelToken? cancelToken,
  209. ProgressCallback? onSendProgress,
  210. ProgressCallback? onReceiveProgress,
  211. }) async {
  212. try {
  213. final response = await dio.patch(
  214. path,
  215. data: data,
  216. queryParameters: queryParameters,
  217. options: options,
  218. cancelToken: cancelToken,
  219. onSendProgress: onSendProgress,
  220. onReceiveProgress: onReceiveProgress,
  221. );
  222. return BaseCommonResponse<T>.fromJson(
  223. response.data as Map<String, dynamic>,
  224. fromJsonT,
  225. );
  226. } on DioException catch (e) {
  227. // 错误已由 ErrorInterceptor 处理,直接抛出
  228. rethrow;
  229. }
  230. }
  231. }