178 lines
5.4 KiB
Dart
178 lines
5.4 KiB
Dart
|
||
import 'package:dio/dio.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:shared_preferences/shared_preferences.dart';
|
||
|
||
import '../main.dart';
|
||
|
||
/// 请求方法:枚举类型
|
||
enum DioMethod {
|
||
get,
|
||
post,
|
||
put,
|
||
delete,
|
||
patch,
|
||
head,
|
||
}
|
||
|
||
// 创建请求类:封装dio
|
||
class Request {
|
||
/// 单例模式
|
||
static Request? _instance;
|
||
|
||
// 工厂函数:执行初始化
|
||
factory Request() => _instance ?? Request._internal();
|
||
|
||
// 获取实例对象时,如果有实例对象就返回,没有就初始化
|
||
static Request? get instance => _instance ?? Request._internal();
|
||
|
||
/// Dio实例
|
||
static Dio _dio = Dio();
|
||
|
||
/// 初始化
|
||
Request._internal() {
|
||
// 初始化基本选项
|
||
BaseOptions options = BaseOptions(
|
||
// baseUrl: 'http://10.0.0.17:8081',
|
||
baseUrl: 'http://14.103.162.172:8081',
|
||
connectTimeout: const Duration(seconds: 30), // 增加到30秒
|
||
receiveTimeout: const Duration(seconds: 60), // 增加到60秒
|
||
sendTimeout: const Duration(seconds: 60));
|
||
_instance = this;
|
||
// 初始化dio
|
||
_dio = Dio(options);
|
||
// 添加拦截器
|
||
_dio.interceptors.add(InterceptorsWrapper(
|
||
onRequest: _onRequest, onResponse: _onResponse, onError: _onError));
|
||
}
|
||
|
||
/// 请求拦截器
|
||
void _onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
|
||
print("请求头之前: ${options.headers}");
|
||
print("options: ${options}");
|
||
// 检查是否需要添加 token
|
||
// if (options.extra['requiresToken'] == true) {
|
||
// final context = navigatorKey.currentContext;
|
||
// print("111111111111");
|
||
// if (context != null) {
|
||
// print("222222222222");
|
||
// final authProvider = Provider.of<AuthProvider>(context, listen: false);
|
||
// final token = authProvider.token;
|
||
// print("request界面token: $token");
|
||
|
||
// if (token != null && token.isNotEmpty) {
|
||
// options.headers['Authorization'] = "Bearer $token"; // 添加 Authorization
|
||
// }
|
||
// }
|
||
// }
|
||
// 检查是否需要添加 token
|
||
if (options.extra['requiresToken'] == true) {
|
||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||
String? token = prefs.getString('token');
|
||
print("request界面token: $token");
|
||
|
||
if (token != null && token.isNotEmpty) {
|
||
options.headers['Authorization'] = "Bearer $token";
|
||
}
|
||
}
|
||
print("请求头之后: ${options.headers}");
|
||
handler.next(options);
|
||
// super.onRequest(options, handler);
|
||
}
|
||
|
||
/// 相应拦截器
|
||
void _onResponse(Response response, ResponseInterceptorHandler handler) async {
|
||
if (response.statusCode == 200) {
|
||
// 检查业务层面的状态码
|
||
if (response.data is Map && response.data['code'] == 401) {
|
||
_handleUnauthorized();
|
||
}
|
||
} else if (response.statusCode == 401) {
|
||
_handleUnauthorized();
|
||
} else {
|
||
print("响应异常: $response");
|
||
}
|
||
handler.next(response);
|
||
}
|
||
void _handleUnauthorized() async {
|
||
// 清除本地存储的token
|
||
final prefs = await SharedPreferences.getInstance();
|
||
await prefs.remove('token');
|
||
|
||
// 使用navigatorKey进行导航
|
||
if (navigatorKey.currentContext != null) {
|
||
// 确保所有弹窗都关闭
|
||
Navigator.of(navigatorKey.currentContext!).popUntil((route) => route.isFirst);
|
||
// 跳转到登录页面,并清除所有历史路由
|
||
Navigator.of(navigatorKey.currentContext!).pushNamedAndRemoveUntil(
|
||
'/login', // 替换成你的登录页面路由名
|
||
(route) => false,
|
||
);
|
||
}
|
||
}
|
||
/// 错误处理: 网络错误等
|
||
void _onError(DioException error, ErrorInterceptorHandler handler) {
|
||
handler.next(error);
|
||
}
|
||
|
||
/// 请求类:支持异步请求操作
|
||
Future<T> request<T>(
|
||
String path, {
|
||
DioMethod method = DioMethod.get,
|
||
Map<String, dynamic>? params,
|
||
dynamic data,
|
||
Map<String, dynamic>? extra,
|
||
Map<String, dynamic>? queryParameters,
|
||
CancelToken? cancelToken,
|
||
Options? options,
|
||
ProgressCallback? onSendProgress,
|
||
ProgressCallback? onReceiveProgress,
|
||
}) async {
|
||
|
||
// 检查是否有特定的超时设置
|
||
if (extra != null && extra['timeoutOptions'] != null) {
|
||
final timeoutOptions = extra['timeoutOptions'];
|
||
_dio.options.connectTimeout = timeoutOptions['connectTimeout'] ?? _dio.options.connectTimeout;
|
||
_dio.options.receiveTimeout = timeoutOptions['receiveTimeout'] ?? _dio.options.receiveTimeout;
|
||
_dio.options.sendTimeout = timeoutOptions['sendTimeout'] ?? _dio.options.sendTimeout;
|
||
}
|
||
|
||
|
||
const _methodValues = {
|
||
DioMethod.get: 'get',
|
||
DioMethod.post: 'post',
|
||
DioMethod.put: 'put',
|
||
DioMethod.delete: 'delete',
|
||
DioMethod.patch: 'patch',
|
||
DioMethod.head: 'head'
|
||
};
|
||
// 默认配置选项
|
||
options ??= Options(method: _methodValues[method]);
|
||
if (extra != null) {
|
||
options.extra = extra;
|
||
}
|
||
try {
|
||
Response response;
|
||
// 开始发送请求
|
||
response = await _dio.request(path,
|
||
data: data,
|
||
queryParameters: queryParameters,
|
||
cancelToken: cancelToken,
|
||
options: options,
|
||
onSendProgress: onSendProgress,
|
||
onReceiveProgress: onReceiveProgress);
|
||
return response.data;
|
||
} on DioException catch (e) {
|
||
print("发送请求异常: $e");
|
||
rethrow;
|
||
}
|
||
}
|
||
|
||
/// 开启日志打印
|
||
/// 需要打印日志的接口在接口请求前 Request.instance?.openLog();
|
||
void openLog() {
|
||
_dio.interceptors
|
||
.add(LogInterceptor(responseHeader: false, responseBody: true));
|
||
}
|
||
}
|