Making.School.Asignment.app/lib/common/request/rest_dio.dart

171 lines
5.7 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:get/get.dart' as getx;
import 'package:dio/dio.dart';
import 'package:package_info/package_info.dart';
import 'package:school_asignment_app/common/api/retrofit_client.dart';
import 'package:school_asignment_app/common/job/user_info.dart';
import 'package:school_asignment_app/common/request/request_config.dart';
import 'package:school_asignment_app/common/store/user_store.dart';
import 'package:school_asignment_app/common/utils/toast_utils.dart';
import 'package:school_asignment_app/routes/app_pages.dart';
class RequestTool {
// 初始化请求配置
static _init() {
BaseOptions options = BaseOptions(
baseUrl: RequestConfig().baseUrl,
connectTimeout: const Duration(milliseconds: RequestConfig.connectTimeout),
receiveTimeout: const Duration(milliseconds: RequestConfig.receiveTimeout),
);
Dio dio = Dio(options);
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!;
}
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;
//获取存储数据 保存header token
String? token = UserStore.to.token;
String? xToken = UserStore.to.xToken;
UserInfo? userInfo = UserStore.to.userInfo.value;
if (null != token && token.isNotEmpty) {
headers["Authorization"] = token; //添加自己项目中的请求头 进行保存
headers["x-Authorization"] = token; //添加自己项目中的请求头 进行保存
}
if ((userInfo?.isExpired() ?? false) && (xToken?.isNotEmpty ?? false)) {
headers["x-Authorization"] = xToken!;
}
options.headers = headers;
return super.onRequest(options, handler);
}
}
/*
* ResponseHandle
* 监听返回响应
**/
class ResponseHandle extends Interceptor {
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
if (RequestConfig.successCode.contains(response.statusCode)) {
//
String? token = response.headers.value('access-token');
String? xtoken = response.headers.value('x-access-token');
if (token?.isNotEmpty ?? false) {
UserStore.to.setToken(token!);
var payloadBase64 = token.split('.')[1];
final normalizedPayload = base64.normalize(payloadBase64);
final payloadString = utf8.decode(base64.decode(normalizedPayload));
UserStore.to.setUserInfo(UserInfo.fromJson(jsonDecode(payloadString)));
}
if (xtoken?.isNotEmpty ?? false) UserStore.to.setXToken(xtoken!);
}
super.onResponse(response, handler);
}
}
class TheError extends Interceptor {
@override
void onError(DioException error, ErrorInterceptorHandler handler) {
print('----------------');
print(error);
print('*************');
var message = '请求错误,请重试';
switch (error.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 (error.response == null) {
print('请求进入异常但是请求response');
} else {
var errorMap = error.response!.data;
if (errorMap['error'] != null) {
message = errorMap['error']?['message'] ?? '请求错误,请重试';
}
if (error.response!.statusCode == 401) {
message = '用户登录失效,请重新登录';
Future.delayed(const Duration(seconds: 2), () => getx.Get.offAllNamed(Routes.login));
}
}
break;
case DioExceptionType.cancel:
message = '请求已取消';
break;
case DioExceptionType.connectionError:
message = '当前无网络,请重试';
break;
default:
message = '请求错误';
}
ToastUtils.showError(message);
return handler.next(error);
}
}