|
@@ -0,0 +1,121 @@
|
|
|
+import 'dart:io';
|
|
|
+
|
|
|
+import 'package:connectivity_plus/connectivity_plus.dart';
|
|
|
+import 'package:dio/dio.dart';
|
|
|
+import 'package:flutter/cupertino.dart';
|
|
|
+
|
|
|
+//import 'custom_interceptors.dart';
|
|
|
+
|
|
|
+class DioClient {
|
|
|
+ static final DioClient _instance = DioClient._internal();
|
|
|
+ late Dio _dio;
|
|
|
+
|
|
|
+ factory DioClient() => _instance;
|
|
|
+
|
|
|
+ DioClient._internal() {
|
|
|
+ _dio = Dio(BaseOptions(
|
|
|
+ baseUrl: 'https://api.example.com', // 你的API地址
|
|
|
+ connectTimeout: 5000,
|
|
|
+ receiveTimeout: 3000,
|
|
|
+ ));
|
|
|
+
|
|
|
+ // 添加拦截器
|
|
|
+ _dio.interceptors.add(CustomInterceptors());
|
|
|
+ }
|
|
|
+
|
|
|
+ Dio get dio => _dio;
|
|
|
+}
|
|
|
+class CustomInterceptors extends Interceptor {
|
|
|
+ int _retryCount = 0;
|
|
|
+ final List<String> _backupUrls = ['备用地址1', '备用地址2'];
|
|
|
+
|
|
|
+ Future<bool> isConnected() async {
|
|
|
+ var connectivityResult = await (Connectivity().checkConnectivity());
|
|
|
+ return connectivityResult != ConnectivityResult.none;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Future<void> onError(DioError err, ErrorInterceptorHandler handler) async {
|
|
|
+ // 检查网络连接状态
|
|
|
+ bool isConnectNetWork = await isConnected();
|
|
|
+
|
|
|
+ if (!isConnectNetWork) {
|
|
|
+ // 无网络连接,设置友好的错误消息
|
|
|
+ err.error = AppException(message: "当前网络不可用,请检查您的网络");
|
|
|
+ return handler.next(err);
|
|
|
+ } else if (err.error is SocketException || err.type == DioErrorType.other) {
|
|
|
+ if (_retryCount < _backupUrls.length) {
|
|
|
+ // 有网络连接但请求失败,尝试使用备用地址
|
|
|
+ err.requestOptions.baseUrl = _backupUrls[_retryCount];
|
|
|
+ _retryCount++;
|
|
|
+ try {
|
|
|
+ final Dio dio = Dio();
|
|
|
+ final Response response = await dio.request<dynamic>(
|
|
|
+ err.requestOptions.path,
|
|
|
+ cancelToken: err.requestOptions.cancelToken,
|
|
|
+ data: err.requestOptions.data,
|
|
|
+ onReceiveProgress: err.requestOptions.onReceiveProgress,
|
|
|
+ onSendProgress: err.requestOptions.onSendProgress,
|
|
|
+ queryParameters: err.requestOptions.queryParameters,
|
|
|
+ options: Options(
|
|
|
+ method: err.requestOptions.method,
|
|
|
+ headers: err.requestOptions.headers,
|
|
|
+ contentType: err.requestOptions.contentType,
|
|
|
+ responseType: err.requestOptions.responseType,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ return handler.resolve(response);
|
|
|
+ } catch (e) {
|
|
|
+ return handler.next(err);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其他错误,统一处理
|
|
|
+ AppException appException = AppException.create(err);
|
|
|
+ debugPrint('DioError===: ${appException.toString()}');
|
|
|
+ err.error = appException;
|
|
|
+ return handler.next(err);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class AppException implements Exception {
|
|
|
+ final String message;
|
|
|
+ AppException({required this.message});
|
|
|
+
|
|
|
+ static AppException create(DioError err) {
|
|
|
+ switch (err.type) {
|
|
|
+ case DioErrorType.cancel:
|
|
|
+ return AppException(message: '请求被取消');
|
|
|
+
|
|
|
+ case DioErrorType.connectTimeout:
|
|
|
+ return AppException(message: '连接超时');
|
|
|
+
|
|
|
+ case DioErrorType.sendTimeout:
|
|
|
+ return AppException(message: '请求超时');
|
|
|
+
|
|
|
+ case DioErrorType.receiveTimeout:
|
|
|
+ return AppException(message: '响应超时');
|
|
|
+
|
|
|
+ case DioErrorType.response:
|
|
|
+ return AppException(
|
|
|
+ message: '服务器返回异常,状态码:${err.response?.statusCode}',
|
|
|
+ );
|
|
|
+
|
|
|
+ case DioErrorType.other:
|
|
|
+ return AppException(
|
|
|
+ message: '未知错误: ${err.message}',
|
|
|
+ );
|
|
|
+
|
|
|
+ default:
|
|
|
+ return AppException(
|
|
|
+ message: err.message,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ String toString() {
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+}
|