ar_tourism_flutter_unity/lib/utils/request.dart
2025-05-14 17:04:13 +08:00

178 lines
5.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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));
}
}