import 'dart:io'; import 'package:dio/io.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart' as getx; import 'package:dio/dio.dart'; import 'package:wgshare/common/api/retrofit_client.dart'; import 'package:wgshare/common/config/request_config.dart'; import 'package:wgshare/common/store/user_store.dart'; import 'package:wgshare/utils/storage.dart'; import 'package:wgshare/utils/toast_utils.dart'; import 'package:wgshare/routes/app_routes.dart'; import 'package:package_info_plus/package_info_plus.dart'; import '../mixins/request_tool_mixin.dart'; import '../models/common/base_structure_result.dart'; import '../models/user_info_entity.dart'; class RequestTool { static late Dio _dio; // 初始化请求配置 static _init() { // 自定义 HttpClient final httpClient = HttpClient()..maxConnectionsPerHost = 12; // 设置每个主机的最大连接数 BaseOptions options = BaseOptions( baseUrl: RequestConfig().baseUrl, connectTimeout: const Duration(milliseconds: RequestConfig.connectTimeout), receiveTimeout: const Duration(milliseconds: RequestConfig.receiveTimeout), ); _dio = Dio(options) ..httpClientAdapter = IOHttpClientAdapter(createHttpClient: () => httpClient); _dio.interceptors.add(AuthInterceptor()); // 添加 token _dio.interceptors.add(ResponseHandle()); // 添加 数据返回拦截 _dio.interceptors.add(TheError()); // 添加 数据返回拦截 const isProd = bool.fromEnvironment('dart.vm.product'); if (!isProd && RequestConfig.requestDataPrinting) { _dio.interceptors .add(LogInterceptor(responseBody: true, requestBody: true)); //添加日志 } return RetrofitClient(_dio, baseUrl: RequestConfig().baseUrl); } final RetrofitClient _client; static RequestTool? _instance; RequestTool._internal(this._client); static get instance { if (_instance == null) { RetrofitClient client = _init(); _instance = RequestTool._internal(client); } return _instance!; } // DIO Dio getDio() => _dio; RetrofitClient getClient() => _client; } /* * *AuthInterceptor *添加header认证 * */ class AuthInterceptor extends Interceptor { @override onRequest(RequestOptions options, RequestInterceptorHandler handler) async { //获取app版本 PackageInfo packageInfo = await PackageInfo.fromPlatform(); String version = packageInfo.version; // ignore: non_constant_identifier_names String PLATFORM = "android"; //可根据代码进行判断 if (Platform.isIOS) { PLATFORM = "ios"; } else if (Platform.isAndroid) { PLATFORM = "android"; } else if (Platform.isWindows) { PLATFORM = "Windows"; } else if (Platform.isMacOS) { PLATFORM = "macos"; } else if (Platform.isLinux) { PLATFORM = "Linux"; } Map headers = {}; headers["Accept-Charset"] = "utf-8"; headers["Connection"] = "keep-alive"; headers["Accept"] = "*/*"; headers["x-version"] = version; //自己更改配置 headers["x-platform"] = PLATFORM; headers["Content-Type"] = "application/json"; //获取存储数据 保存header token String? token = UserStore.to.token; if (token?.isNotEmpty ?? false) { headers["Authorization"] = 'Bearer $token'; //添加自己项目中的请求头 进行保存 } options.headers = headers; return super.onRequest(options, handler); } } /* * ResponseHandle * 监听返回响应 **/ class ResponseHandle extends Interceptor { @override void onResponse(Response response, ResponseInterceptorHandler handler) { int? statusCode = response.statusCode; var data = response.data; var flag = data != null && ((data['code'] != null && (data['code'] == 401 || data['code'] == '401')) || (data['Code'] != null && (data['Code'] == 401 || data['Code'] == '401'))); if (statusCode == 401 || flag) { Future.delayed(const Duration(seconds: 2), () { StorageService.to.erase(); getx.Get.offAllNamed(Routes.loginPage); }); } if (data['code'] != 200) { ToastUtils.showError(data['message']); } super.onResponse(response, handler); } } class TheError extends Interceptor with RequestToolMixin { // late getx.Rx userInfo = UserStore.to.userDetailInfo; @override Future onError( DioException err, ErrorInterceptorHandler handler) async { var message = '请求错误,请重试'; int? statusCode; switch (err.type) { case DioExceptionType.connectionTimeout: message = '请求链接超时'; break; case DioExceptionType.badCertificate: message = '证书错误,清联系管理员'; break; case DioExceptionType.sendTimeout: message = '请求发送超时'; break; case DioExceptionType.receiveTimeout: message = '接收超时时发生'; break; case DioExceptionType.badResponse: if (err.response == null) { debugPrint('wgs输出===:请求进入异常但是请求response'); } else { Response? response = err.response; if (response != null) { statusCode = response.statusCode; var errorMap = response.data; // var runtimeType = errorMap.runtimeType; if (errorMap is Map && errorMap['error'] != null) { message = errorMap['error']?['message'] ?? '请求错误,请重试'; } else { if (statusCode != null) { switch (statusCode) { case 401: message = '用户登录失效,请重新登录'; /*Future.delayed(const Duration(seconds: 2), () { // UserStore.to.erase(); StorageService.to.erase(); getx.Get.offAllNamed(Routes.loginPage); });*/ break; case 404: message = '无效地址'; break; default: } } } } } break; case DioExceptionType.cancel: message = '请求已取消'; break; case DioExceptionType.connectionError: message = '当前无网络,请重试'; break; default: message = '请求错误'; } if (statusCode == 401) { BaseStructureResult res = await getClient() .refreshToken(UserStore.to.userInfoEntity.value!.refreshToken); if (null != res.data) { UserStore.to.setToken(res.data!.token); UserStore.to.setRefreshToken(res.data!.refreshToken); UserStore.to.setUserDetailInfo(res.data!); } } else { ToastUtils.showError(message); } return handler.next(err); } }