base_dio.dart 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import 'package:connectivity_plus/connectivity_plus.dart';
  2. import 'package:dio/dio.dart';
  3. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  4. import 'package:lszlgl/main.dart';
  5. import 'package:lszlgl/service/user_service.dart';
  6. class BaseDio {
  7. static BaseDio? _instance;
  8. static BaseDio get() => _instance ??= BaseDio._();
  9. BaseDio._() {
  10. BaseOptions options = BaseOptions();
  11. dio = Dio(options);
  12. // 添加request拦截器
  13. dio.interceptors.add(MyInterceptor());
  14. // // 添加error拦截器
  15. // dio.interceptors.add(ErrorInterceptor());
  16. // // // 添加cache拦截器
  17. // dio.interceptors.add(NetCacheInterceptor());
  18. // // // 添加retry拦截器
  19. // dio.interceptors.add(
  20. // RetryOnConnectionChangeInterceptor(
  21. // requestRetrier: DioConnectivityRequestRetrier(
  22. // dio: dio,
  23. // connectivity: Connectivity(),
  24. // ),
  25. // ),
  26. // );
  27. }
  28. late final Dio dio;
  29. /// 初始化公共属性
  30. /// * [baseUrl] 前缀地址
  31. /// * [receiveTimeout] 接收超出时间
  32. /// * [connectTimeout] 连接超时时间
  33. /// * [sendTimeout] 发送超时时间
  34. void init({
  35. String? baseUrl,
  36. Duration? receiveTimeout = const Duration(seconds: 60),
  37. Duration? connectTimeout = const Duration(seconds: 30),
  38. Duration? sendTimeout = const Duration(seconds: 60),
  39. Map<String, String>? headers,
  40. List<Interceptor>? interceptors,
  41. }) {
  42. dio.options.copyWith(
  43. baseUrl: baseUrl,
  44. connectTimeout: connectTimeout,
  45. receiveTimeout: receiveTimeout,
  46. sendTimeout: sendTimeout,
  47. headers: headers,
  48. );
  49. if (interceptors != null && interceptors.isNotEmpty) {
  50. dio.interceptors.addAll(interceptors);
  51. }
  52. }
  53. }
  54. /// 拦截器
  55. class MyInterceptor extends Interceptor {
  56. @override
  57. void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
  58. // 请求
  59. var login = UserService.get().getLogin();
  60. if (login != null) {
  61. // 已登录添加token
  62. options.headers['Authorization'] = 'Bearer ${login.accessToken}';
  63. }
  64. Map<String, Object?> map = {};
  65. map['url'] = options.uri;
  66. map['method'] = options.method;
  67. map['headers'] = options.headers;
  68. map['data'] = options.data;
  69. if (options.queryParameters.isNotEmpty) map['queryParameters'] = options.queryParameters;
  70. if (options.extra.isNotEmpty) map['extra'] = options.extra;
  71. logger.i('ApiRequest: $map');
  72. handler.next(options);
  73. }
  74. @override
  75. void onResponse(Response response, ResponseInterceptorHandler handler) {
  76. // 响应
  77. Map<String, Object?> map = {};
  78. map['url'] = response.requestOptions.uri;
  79. map['statusCode'] = response.statusCode;
  80. map['statusMessage'] = response.statusMessage;
  81. if (response.data != null) {
  82. var code = response.data!['code'];
  83. var msg = response.data!['msg'];
  84. map['code'] = code;
  85. map['msg'] = msg;
  86. map['data'] = response.data!['data'];
  87. if (code != 0) {
  88. return handler.reject(
  89. DioException(
  90. requestOptions: response.requestOptions,
  91. response: response,
  92. type: DioExceptionType.badResponse,
  93. message: msg,
  94. ),
  95. true,
  96. );
  97. }
  98. }
  99. if (response.extra.isNotEmpty) map['extra'] = response.extra;
  100. logger.i('ApiResponse: $map');
  101. handler.next(response);
  102. }
  103. // 是否有网
  104. Future<bool> isConnected() async {
  105. var connectivityResult = await (Connectivity().checkConnectivity());
  106. return connectivityResult != ConnectivityResult.none;
  107. }
  108. @override
  109. void onError(DioException err, ErrorInterceptorHandler handler) async {
  110. // 增加网络检测
  111. if (err.type == DioExceptionType.unknown) {
  112. bool isConnectNetWork = await isConnected();
  113. if (!isConnectNetWork) {
  114. err.copyWith(message: '当前网络不可用,请检查您的网络');
  115. }
  116. }
  117. // error统一处理
  118. AppException appException = AppException.create(err);
  119. err.copyWith(error: appException);
  120. // 响应
  121. Map<String, Object?> map = {};
  122. map['url'] = err.requestOptions.uri;
  123. map['statusCode'] = err.response?.statusCode;
  124. map['data'] = err.response?.data;
  125. map['msg'] = appException.message;
  126. if (err.response?.extra.isNotEmpty ?? false) map['extra'] = err.response?.extra;
  127. logger.e('ApiError: $map');
  128. SmartDialog.showToast(appException.message ?? '');
  129. handler.next(err);
  130. }
  131. }
  132. /// 自定义异常
  133. class AppException implements Exception {
  134. final String? message;
  135. final int code;
  136. AppException(
  137. this.code,
  138. this.message,
  139. );
  140. @override
  141. String toString() {
  142. return 'code:$code, message:$message';
  143. }
  144. factory AppException.create(DioException error) {
  145. switch (error.type) {
  146. case DioExceptionType.connectionTimeout:
  147. return AppException(-1, '连接超时');
  148. case DioExceptionType.sendTimeout:
  149. return AppException(-1, '请求超时');
  150. case DioExceptionType.receiveTimeout:
  151. return AppException(-1, '响应超时');
  152. case DioExceptionType.badCertificate:
  153. return AppException(-1, '证书错误');
  154. case DioExceptionType.badResponse:
  155. var code = error.response?.data['code'];
  156. if (code == 401) UserService.get().logout();
  157. return AppException(code, error.response?.data['msg'] ?? '');
  158. case DioExceptionType.cancel:
  159. return AppException(-1, "请求取消");
  160. case DioExceptionType.connectionError:
  161. return AppException(-1, '连接超时');
  162. case DioExceptionType.unknown:
  163. return AppException(-1, error.message);
  164. }
  165. }
  166. }