import 'dart:io'; import 'package:dio/dio.dart'; /// 全局接口异常 class ApiException implements Exception { final String result; final String message; ApiException(this.result, this.message); @override String toString() => 'ApiException($result): $message'; } /// HTTP 方法枚举 enum Method { get, post, put, delete } /// HTTP 管理器 单例 class HttpManager { HttpManager._internal() { _dio = Dio(BaseOptions( connectTimeout: const Duration(milliseconds: 10000), receiveTimeout: const Duration(milliseconds: 10000), headers: { 'Content-Type': Headers.formUrlEncodedContentType, }, )); _initInterceptors(); } static final HttpManager _instance = HttpManager._internal(); factory HttpManager() => _instance; late final Dio _dio; void _initInterceptors() { _dio.interceptors ..add(LogInterceptor(request: true, responseBody: true, error: true)) ..add(InterceptorsWrapper(onError: (err, handler) { // 全局错误处理,可根据 err.response?.statusCode 或 err.type 做不同处理 handler.next(err); })); } /// 通用请求方法,返回完整后台 JSON Future> request( String baseUrl, String path, { Method method = Method.post, Map? data, Map? params, CancelToken? cancelToken, }) async { Response resp; final url = baseUrl + path; final options = Options( method: method.name.toUpperCase(), contentType: Headers.formUrlEncodedContentType, ); try { switch (method) { case Method.get: resp = await _dio.get( url, queryParameters: params, cancelToken: cancelToken, options: options, ); break; case Method.put: resp = await _dio.put( url, data: data, queryParameters: params, cancelToken: cancelToken, options: options, ); break; case Method.delete: resp = await _dio.delete( url, queryParameters: params, cancelToken: cancelToken, options: options, ); break; case Method.post: resp = await _dio.post( url, data: data, queryParameters: params, cancelToken: cancelToken, options: options, ); } } on DioException catch (e) { // 网络或服务器错误 throw ApiException('network_error', e.message ?? e.toString()); } // 解析返回 JSON final json = resp.data is Map ? resp.data as Map : {}; final result = json['result'] as String?; final msg = json['msg'] as String? ?? json['message'] as String? ?? ''; if (result != 'success') { // 非 success 都抛异常 throw ApiException(result ?? 'unknown', msg); } return json; } } /// 上传图片扩展 extension HttpManagerUpload on HttpManager { Future> uploadFaceImage({ required String baseUrl, required String path, required Map fromData, CancelToken? cancelToken, }) async { final form = FormData.fromMap(fromData); try { final resp = await _dio.post( baseUrl + path, data: form, cancelToken: cancelToken, options: Options( method: Method.post.name.toUpperCase(), contentType: 'multipart/form-data', ), ); final json = resp.data is Map ? resp.data as Map : {}; return json; } on DioException catch (e) { throw ApiException('network_error', e.message ?? e.toString()); } } }