import 'dart:convert'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:dio/dio.dart'; import 'package:lszlgl/base/base_lifecycle_state.dart'; import 'package:lszlgl/main.dart'; import 'package:lszlgl/service/user_service.dart'; class BaseDio { static BaseDio? _instance; static BaseDio get() => _instance ??= BaseDio._(); BaseDio._() { BaseOptions options = BaseOptions(); dio = Dio(options); // 添加request拦截器 dio.interceptors.add(MyInterceptor()); // // 添加error拦截器 // dio.interceptors.add(ErrorInterceptor()); // // // 添加cache拦截器 // dio.interceptors.add(NetCacheInterceptor()); // // // 添加retry拦截器 // dio.interceptors.add( // RetryOnConnectionChangeInterceptor( // requestRetrier: DioConnectivityRequestRetrier( // dio: dio, // connectivity: Connectivity(), // ), // ), // ); } late final Dio dio; /// 初始化公共属性 /// * [baseUrl] 前缀地址 /// * [receiveTimeout] 接收超出时间 /// * [connectTimeout] 连接超时时间 /// * [sendTimeout] 发送超时时间 void init({ String? baseUrl, Duration? receiveTimeout = const Duration(seconds: 60), Duration? connectTimeout = const Duration(seconds: 30), Duration? sendTimeout = const Duration(seconds: 60), Map? headers, List? interceptors, }) { dio.options.copyWith( baseUrl: baseUrl, connectTimeout: connectTimeout, receiveTimeout: receiveTimeout, sendTimeout: sendTimeout, headers: headers, ); if (interceptors != null && interceptors.isNotEmpty) { dio.interceptors.addAll(interceptors); } } } /// 拦截器 class MyInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { // 请求 var login = UserService.get().getLogin(); if (login != null) { // 已登录添加token options.headers['Authorization'] = 'Bearer ${login.accessToken}'; } Map map = {}; map['url'] = options.uri; map['method'] = options.method; map['headers'] = options.headers; if (options.data is List || options.data is Map) { map['data'] = jsonEncode(options.data); } else { map['data'] = options.data.toString(); } if (options.queryParameters.isNotEmpty) map['queryParameters'] = options.queryParameters; if (options.extra.isNotEmpty) map['extra'] = options.extra; logger.i('ApiRequest: $map'); handler.next(options); } @override void onResponse(Response response, ResponseInterceptorHandler handler) { // 响应 Map map = {}; map['url'] = response.requestOptions.uri; map['statusCode'] = response.statusCode; map['statusMessage'] = response.statusMessage; if (response.data != null) { var code = response.data!['code']; var msg = response.data!['msg']; map['code'] = code; map['msg'] = msg; map['data'] = jsonEncode(response.data!['data']); if (code != 0) { return handler.reject( DioException( requestOptions: response.requestOptions, response: response, type: DioExceptionType.badResponse, message: msg, ), true, ); } } if (response.extra.isNotEmpty) map['extra'] = response.extra; logger.i('ApiResponse: $map'); handler.next(response); } // 是否有网 Future isConnected() async { var connectivityResult = await (Connectivity().checkConnectivity()); return connectivityResult != ConnectivityResult.none; } @override void onError(DioException err, ErrorInterceptorHandler handler) async { if (err.type == DioExceptionType.badResponse) { logger.e('ApiErrorResponse: ${err.response}'); } else { logger.e('ApiErrorSource: $err'); } // 增加网络检测 if (err.type == DioExceptionType.unknown) { bool isConnectNetWork = await isConnected(); if (!isConnectNetWork) { err.copyWith(message: '当前网络不可用,请检查您的网络'); } } // error统一处理 AppException appException = AppException.create(err); err.copyWith(error: appException); // 响应 Map map = {}; map['url'] = err.requestOptions.uri; map['errorType'] = err.type; map['statusCode'] = err.response?.statusCode; map['msg'] = appException.message; if (err.response?.extra.isNotEmpty ?? false) map['extra'] = err.response?.extra; logger.e('ApiError: $map'); MyNavigator.showToast(appException.message ?? ''); handler.next(err); } } /// 自定义异常 class AppException implements Exception { final String? message; final int code; AppException( this.code, this.message, ); @override String toString() { return 'code:$code, message:$message'; } factory AppException.create(DioException error) { switch (error.type) { case DioExceptionType.connectionTimeout: return AppException(-1, '连接超时'); case DioExceptionType.sendTimeout: return AppException(-1, '请求超时'); case DioExceptionType.receiveTimeout: return AppException(-1, '响应超时'); case DioExceptionType.badCertificate: return AppException(-1, '证书错误'); case DioExceptionType.badResponse: if (error.response?.data is Map) { var code = error.response?.data['code'] ?? -1; if (code == 401) UserService.get().logout(); return AppException(code, error.response?.data['msg'] ?? ''); } return AppException(-1, '请求失败'); case DioExceptionType.cancel: return AppException(-1, "请求取消"); case DioExceptionType.connectionError: return AppException(-1, '连接超时'); case DioExceptionType.unknown: return AppException(-1, error.message); } } }