import 'package:dio/dio.dart'; import 'package:food_hub_app/utils/sp_util.dart'; import 'package:food_hub_app/widgets/common/index.dart'; class HttpUtil { static final HttpUtil _instance = HttpUtil._internal(); factory HttpUtil() => _instance; late Dio _dio; String baseUrl = "http://172.29.101.108:8100/"; // 请求头配置 Map headers = { 'Content-Type': 'application/json;charset=UTF-8', 'Accept': 'application/json', }; // 超时时间 final int timeout = 5; HttpUtil._internal() { // 初始化Dio实例 BaseOptions options = BaseOptions( baseUrl: baseUrl, connectTimeout: Duration(seconds: timeout), receiveTimeout: Duration(seconds: timeout), headers: headers, ); _dio = Dio(options); // 添加请求拦截器 _dio.interceptors.add( InterceptorsWrapper( onRequest: (options, handler) { print("请求URL: ${options.uri}"); if (options.data != null) { print("请求参数: ${options.data}"); } if (SPUtil.getString('token').isNotEmpty) { options.headers['satoken'] = SPUtil.getString('token'); } return handler.next(options); }, ), ); // 添加响应拦截器 _dio.interceptors.add( InterceptorsWrapper( onResponse: (response, handler) { print("响应状态码: ${response.statusCode}"); print("响应数据: ${response.data}"); return handler.next(response); }, ), ); // 添加错误拦截器 _dio.interceptors.add( InterceptorsWrapper( onError: (DioException e, handler) { _handleError(e); return handler.next(e); }, ), ); } // 基础请求方法(处理所有类型的请求) Future _request( String path, { required String method, dynamic data, Map? queryParameters, T Function(dynamic data)? converter, }) async { try { Response response = await _dio.request( path, data: data, queryParameters: queryParameters, options: Options(method: method), ); // 处理响应数据 if (converter != null) { return converter(response.data); } // 没有转换器时尝试直接返回(可能不安全,建议提供转换器) return response.data; } catch (e) { rethrow; } } // GET请求 Future get( String path, { Map? queryParameters, T Function(dynamic data)? converter, }) => _request( path, method: "GET", queryParameters: queryParameters, converter: converter, ); // POST请求 Future post( String path, { dynamic data, Map? queryParameters, T Function(dynamic data)? converter, }) => _request( path, method: "POST", data: data, queryParameters: queryParameters, converter: converter, ); // PUT请求 Future put( String path, { dynamic data, Map? queryParameters, T Function(dynamic data)? converter, }) => _request( path, method: "PUT", data: data, queryParameters: queryParameters, converter: converter, ); // DELETE请求 Future delete( String path, { dynamic data, Map? queryParameters, T Function(dynamic data)? converter, }) => _request( path, method: "DELETE", data: data, queryParameters: queryParameters, converter: converter, ); // 文件上传 Future upload( String path, String filePath, { Map? queryParameters, }) async { try { FormData formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(filePath), }); Response response = await _dio.post( path, data: formData, queryParameters: queryParameters, ); return response.data; } catch (e) { _handleError(e); rethrow; } } // 错误处理 void _handleError(dynamic error) { String errorMessage = '未知错误'; if (error is DioException) { switch (error.type) { case DioExceptionType.connectionTimeout: errorMessage = '连接超时,请检查网络连接'; break; case DioExceptionType.sendTimeout: errorMessage = '发送超时,请检查网络连接'; break; case DioExceptionType.receiveTimeout: errorMessage = '接收超时,请检查网络连接'; break; case DioExceptionType.cancel: errorMessage = '请求已取消'; break; case DioExceptionType.badCertificate: errorMessage = '证书验证失败'; break; case DioExceptionType.badResponse: // 处理HTTP响应错误(4xx, 5xx) final statusCode = error.response?.statusCode ?? 0; final responseData = error.response?.data; if (responseData is Map && responseData.containsKey('message')) { // 服务器返回了自定义错误消息 errorMessage = responseData['message']?.toString() ?? '未知错误'; } else { errorMessage = _getHttpErrorMessage(statusCode); } break; case DioExceptionType.connectionError: errorMessage = '网络连接错误,请检查网络设置'; break; case DioExceptionType.unknown: if (error.error != null) { errorMessage = '未知错误: ${error.error.toString()}'; } errorMessage = '发生未知错误'; break; } } else { errorMessage = '非Dio错误: $error'; } print(errorMessage); showErrorToast(errorMessage); } String _getHttpErrorMessage(int statusCode) { // 根据HTTP状态码返回对应的错误消息 switch (statusCode) { case 400: return '错误请求,请检查参数'; case 401: return '未授权,请登录'; case 403: return '禁止访问,权限不足'; case 404: return '资源不存在'; case 405: return '方法不允许'; case 408: return '请求超时'; case 500: return '服务器内部错误'; case 502: return '网关错误'; case 503: return '服务不可用'; case 504: return '网关超时'; default: return 'HTTP错误: $statusCode'; } } }