dio_client.dart 7.9 KB

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