// Author: fengshengxiong // Date: 2024/5/9 // Description: dio封装 import 'package:dio/dio.dart'; import 'package:pretty_dio_logger/pretty_dio_logger.dart'; import 'package:hello_wallpaper/common/components/easy_loading.dart'; import 'package:hello_wallpaper/common/network/base_error.dart'; import 'package:hello_wallpaper/common/network/dio_interceptor.dart'; import 'package:hello_wallpaper/common/utils/log_print.dart'; import 'package:hello_wallpaper/generated/json/base/json_convert_content.dart'; import 'package:hello_wallpaper/models/base_resp_model.dart'; class DioClient { static final DioClient _instance = DioClient._internal(); factory DioClient() => _instance; late Dio _dio; DioClient._internal() { _dio = Dio(); final baseOptions = BaseOptions( baseUrl: '', connectTimeout: const Duration(seconds: 15), receiveTimeout: const Duration(seconds: 10), ); _dio.options = baseOptions; _dio.interceptors.add(DioInterceptor()); _dio.interceptors.add(PrettyDioLogger( requestHeader: true, requestBody: true, compact: false, )); } /// 请求 Future request( String path, { required RequestMethod requestMethod, dynamic data, Map? queryParameters, CancelToken? cancelToken, Options? options, bool isFormData = false, bool showLoading = false, bool showToast = true, required Function(T? result) success, Function(BaseError baseError)? fail, }) async { try { loading(show: showLoading); Response response = await _dio.request( path, data: isFormData ? FormData.fromMap(data) : data, queryParameters: queryParameters, cancelToken: cancelToken, options: _getOptions(requestMethod, options), ); dismiss(dismiss: showLoading); BaseRespModel baseRespModel = response.data; if (baseRespModel.code == 200) { success(JsonConvert.fromJsonAsT(baseRespModel.data)); } else { toast(baseRespModel.message, show: showToast); if (fail != null) { fail(OtherError( statusCode: baseRespModel.code, statusMessage: baseRespModel.message, )); } } } on DioException catch (e) { BaseError error = getError(e); if (fail != null) fail(error); toast(error.message, show: showToast); } catch (e) { LogPrint.e(e.toString()); toast(e.toString(), show: showToast); } } Options? _getOptions(RequestMethod requestMethod, Options? options) { options ??= Options(); options.method = requestMethod.method; return options; } /// 下载 Future download( String urlPath, dynamic savePath, { ProgressCallback? onReceiveProgress, Map? queryParameters, CancelToken? cancelToken, data, Options? options, required Function() success, Function(String? err)? fail, }) async { try { await _dio.download( urlPath, savePath, onReceiveProgress: onReceiveProgress, queryParameters: queryParameters, cancelToken: cancelToken, data: data, options: Options(receiveTimeout: const Duration(seconds: 0)), ); success(); } on DioException catch (e) { BaseError error = getError(e); toast(error.message); if (fail != null) fail(error.message); } catch (e) { LogPrint.e(e.toString()); toast(e.toString()); if (fail != null) fail(e.toString()); } } BaseError getError(DioException e) { if (e.runtimeType == DioException) { switch (e.type) { case DioExceptionType.connectionTimeout: return OtherError(statusCode: -1, statusMessage: 'connection timed out'); case DioExceptionType.sendTimeout: return OtherError(statusCode: -1, statusMessage: 'send timeout'); case DioExceptionType.receiveTimeout: return OtherError(statusCode: -1, statusMessage: 'receive timeout'); case DioExceptionType.badCertificate: return OtherError(statusCode: -1, statusMessage: 'certificate error'); case DioExceptionType.cancel: return OtherError(statusCode: -1, statusMessage: 'request canceled'); case DioExceptionType.connectionError: return OtherError(statusCode: -1, statusMessage: 'connection error'); case DioExceptionType.unknown: return OtherError(statusCode: -1, statusMessage: 'unknown error'); case DioExceptionType.badResponse: final response = e.response; if (response!.statusCode == 401) { return NeedLogin(); } else if (response.statusCode == 403) { return NeedAuth(); } else { return OtherError( statusCode: response.statusCode, statusMessage: response.statusMessage, ); } } } return OtherError(statusCode: -1, statusMessage: 'unknown error'); } } enum RequestMethod { get('GET'), post('POST'), put('PUT'), head('HEAD'), delete('DELETE'), patch('PATCH'); const RequestMethod( this.method, ); final String method; }