dio_client.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. /// Dio 客户端 - 统一网络请求管理
  7. class DioClient {
  8. static final Dio _dio = Dio(
  9. BaseOptions(
  10. baseUrl: ApiConstants.baseUrl,
  11. connectTimeout: Duration(seconds: ApiConstants.connectTimeout),
  12. receiveTimeout: Duration(seconds: ApiConstants.receiveTimeout),
  13. sendTimeout: Duration(seconds: ApiConstants.sendTimeout),
  14. headers: {
  15. ApiConstants.contentType: ApiConstants.applicationJson,
  16. },
  17. ),
  18. );
  19. static Dio get dio {
  20. // 确保拦截器只添加一次
  21. // 拦截器执行顺序:按添加顺序执行
  22. // 1. AuthInterceptor - 在请求前添加 Token
  23. // 2. LogInterceptor - 记录请求和响应日志
  24. // 3. ErrorInterceptor - 统一处理错误
  25. if (_dio.interceptors.isEmpty) {
  26. _dio.interceptors.addAll([
  27. AuthInterceptor(), // 认证拦截器(自动添加 Token)
  28. LogInterceptor(), // 日志拦截器(使用 AppLogger 记录日志)
  29. ErrorInterceptor(), // 错误拦截器(统一错误处理)
  30. ]);
  31. // 调试:确认拦截器已添加
  32. assert(_dio.interceptors.length == 3, '拦截器应该添加3个');
  33. }
  34. return _dio;
  35. }
  36. /// 重置 Dio 实例(用于重新配置)
  37. static void reset() {
  38. _dio.interceptors.clear();
  39. }
  40. // ==================== GET 请求 ====================
  41. /// GET 请求
  42. ///
  43. /// [path] 请求路径(相对于 baseUrl)
  44. /// [queryParameters] 查询参数
  45. /// [options] 请求选项
  46. ///
  47. /// 返回 [Response] 对象
  48. static Future<Response<T>> get<T>(
  49. String path, {
  50. Map<String, dynamic>? queryParameters,
  51. Options? options,
  52. CancelToken? cancelToken,
  53. ProgressCallback? onReceiveProgress,
  54. }) async {
  55. try {
  56. final response = await dio.get<T>(
  57. path,
  58. queryParameters: queryParameters,
  59. options: options,
  60. cancelToken: cancelToken,
  61. onReceiveProgress: onReceiveProgress,
  62. );
  63. return response;
  64. } on DioException catch (e) {
  65. // 错误已由 ErrorInterceptor 处理,直接抛出
  66. rethrow;
  67. }
  68. }
  69. // ==================== POST 请求 ====================
  70. /// POST 请求
  71. ///
  72. /// [path] 请求路径(相对于 baseUrl)
  73. /// [data] 请求体数据
  74. /// [queryParameters] 查询参数
  75. /// [options] 请求选项
  76. ///
  77. /// 返回 [Response] 对象
  78. static Future<Response<T>> post<T>(
  79. String path, {
  80. dynamic data,
  81. Map<String, dynamic>? queryParameters,
  82. Options? options,
  83. CancelToken? cancelToken,
  84. ProgressCallback? onSendProgress,
  85. ProgressCallback? onReceiveProgress,
  86. }) async {
  87. try {
  88. final response = await dio.post<T>(
  89. path,
  90. data: data,
  91. queryParameters: queryParameters,
  92. options: options,
  93. cancelToken: cancelToken,
  94. onSendProgress: onSendProgress,
  95. onReceiveProgress: onReceiveProgress,
  96. );
  97. return response;
  98. } on DioException catch (e) {
  99. // 错误已由 ErrorInterceptor 处理,直接抛出
  100. rethrow;
  101. }
  102. }
  103. // ==================== DELETE 请求 ====================
  104. /// DELETE 请求
  105. ///
  106. /// [path] 请求路径(相对于 baseUrl)
  107. /// [data] 请求体数据(可选)
  108. /// [queryParameters] 查询参数
  109. /// [options] 请求选项
  110. ///
  111. /// 返回 [Response] 对象
  112. static Future<Response<T>> delete<T>(
  113. String path, {
  114. dynamic data,
  115. Map<String, dynamic>? queryParameters,
  116. Options? options,
  117. CancelToken? cancelToken,
  118. }) async {
  119. try {
  120. final response = await dio.delete<T>(
  121. path,
  122. data: data,
  123. queryParameters: queryParameters,
  124. options: options,
  125. cancelToken: cancelToken,
  126. );
  127. return response;
  128. } on DioException catch (e) {
  129. // 错误已由 ErrorInterceptor 处理,直接抛出
  130. rethrow;
  131. }
  132. }
  133. // ==================== PUT 请求====================
  134. /// PUT 请求
  135. ///
  136. /// [path] 请求路径(相对于 baseUrl)
  137. /// [data] 请求体数据
  138. /// [queryParameters] 查询参数
  139. /// [options] 请求选项
  140. ///
  141. /// 返回 [Response] 对象
  142. static Future<Response<T>> put<T>(
  143. String path, {
  144. dynamic data,
  145. Map<String, dynamic>? queryParameters,
  146. Options? options,
  147. CancelToken? cancelToken,
  148. ProgressCallback? onSendProgress,
  149. ProgressCallback? onReceiveProgress,
  150. }) async {
  151. try {
  152. final response = await dio.put<T>(
  153. path,
  154. data: data,
  155. queryParameters: queryParameters,
  156. options: options,
  157. cancelToken: cancelToken,
  158. onSendProgress: onSendProgress,
  159. onReceiveProgress: onReceiveProgress,
  160. );
  161. return response;
  162. } on DioException catch (e) {
  163. // 错误已由 ErrorInterceptor 处理,直接抛出
  164. rethrow;
  165. }
  166. }
  167. // ==================== PATCH 请求 ====================
  168. /// PATCH 请求
  169. ///
  170. /// [path] 请求路径(相对于 baseUrl)
  171. /// [data] 请求体数据
  172. /// [queryParameters] 查询参数
  173. /// [options] 请求选项
  174. ///
  175. /// 返回 [Response] 对象
  176. static Future<Response<T>> patch<T>(
  177. String path, {
  178. dynamic data,
  179. Map<String, dynamic>? queryParameters,
  180. Options? options,
  181. CancelToken? cancelToken,
  182. ProgressCallback? onSendProgress,
  183. ProgressCallback? onReceiveProgress,
  184. }) async {
  185. try {
  186. final response = await dio.patch<T>(
  187. path,
  188. data: data,
  189. queryParameters: queryParameters,
  190. options: options,
  191. cancelToken: cancelToken,
  192. onSendProgress: onSendProgress,
  193. onReceiveProgress: onReceiveProgress,
  194. );
  195. return response;
  196. } on DioException catch (e) {
  197. // 错误已由 ErrorInterceptor 处理,直接抛出
  198. rethrow;
  199. }
  200. }
  201. }