220 lines
6.8 KiB
Dart
220 lines
6.8 KiB
Dart
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<String, String> 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<UserInfoDetail?> userInfo = UserStore.to.userDetailInfo;
|
||
|
||
@override
|
||
Future<void> 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<UserInfoEntity> 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);
|
||
}
|
||
}
|