import 'dart:convert'; import 'dart:io'; import 'package:dio/adapter.dart'; import 'package:dio/dio.dart'; import 'package:flustars/flustars.dart'; import 'package:flutter/foundation.dart'; import 'package:liftmanager/common/common.dart'; import 'package:liftmanager/net/api_service.dart'; import 'package:liftmanager/net/mock_data.dart'; import 'package:liftmanager/utils/log_utils.dart'; import 'package:rxdart/rxdart.dart'; import 'base_entity.dart'; import 'error_handle.dart'; import 'intercept.dart'; import 'package:liftmanager/utils/log_util.dart' as logg; import 'package:liftmanager/utils/url.dart'; /// @weilu https://github.com/simplezhli class DioUtils { static final DioUtils _singleton = DioUtils._internal(); static DioUtils get instance => DioUtils(); factory DioUtils() { return _singleton; } static Dio _dio; Dio getDio() { return _dio; } DioUtils._internal() { var options = BaseOptions( connectTimeout: 150000, receiveTimeout: 15000, responseType: ResponseType.plain, validateStatus: (status) { // 不使用http状态码判断状态,使用AdapterInterceptor来处理(适用于标准REST风格) return true; }, // baseUrl: "http://192.168.31.100:20250", // baseUrl: "http://192.168.1.4:20226", // baseUrl: "http://192.168.0.110:20250", // baseUrl: "http://192.168.31.112:20226", // baseUrl: "http://lift.whlhcx.com", // baseUrl: "http://111.47.6.224:10227", baseUrl: baseUrl, // baseUrl: "http://221.234.44.30:10227", // baseUrl: "http://192.168.1.16", // contentType: ContentType('application', 'x-www-form-urlencoded', charset: 'utf-8'), ); _dio = Dio(options); /// Fiddler抓包代理配置 https://www.jianshu.com/p/d831b1f7c45b // (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = // (HttpClient client) { // client.findProxy = (uri) { // //proxy all request to localhost:8888 // return "PROXY 192.168.31.72:8686"; // }; // client.badCertificateCallback = // (X509Certificate cert, String host, int port) => true; // }; /// 统一添加身份验证请求头 _dio.interceptors.add(AuthInterceptor()); /// 刷新Token // _dio.interceptors.add(TokenInterceptor()); /// 打印Log(生产模式去除) if (!Constant.inProduction) { // _dio.interceptors.add(LoggingInterceptor()); _dio.interceptors.add( InterceptorsWrapper( onRequest: (RequestOptions options) { print("\n================================= 请求数据 ================================="); print("method = ${options.method.toString()}"); print("url = ${options.uri.toString()}"); print("headers = ${options.headers}"); // print("params = ${options.queryParameters}"); print("paramsData = ${options.data}"); }, onResponse: (Response response) { print("\n================================= 响应数据开始 ================================="); print("StatusCode = ${response.statusCode}"); logg.LogUtil.d("data = ${response.data}"); }, onError: (DioError e) { print("\n=================================错误响应数据 ================================="); print("type = ${e.type}"); print("message = ${e.message}"); print("\n"); }, ), ); } /// 适配数据(根据自己的数据结构,可自行选择添加) _dio.interceptors.add(AdapterInterceptor()); } // 数据返回格式统一,统一处理异常 Future> _request(String method, String url, {T Function(Map) objectFromJson, dynamic data, Map queryParameters, CancelToken cancelToken, Options options}) async { var response = await _dio.request(url, data: data, queryParameters: queryParameters, options: _checkOptions(method, options), cancelToken: cancelToken); try { /// 集成测试无法使用 isolate Map _map = Constant.isTest ? parseData(response.data.toString()) : await compute(parseData, response.data.toString()); return BaseEntity.fromJson(_map, objectFromJson); } catch (e, s) { return BaseEntity(ExceptionHandle.parse_error, "数据解析错误${e}\n${s}", null); } } Options _checkOptions(method, options) { if (options == null) { options = new Options(); } options.method = method; return options; } Future requestNetwork(Method method, String url, {T Function(Map) objectFromJson, Function(T t) onSuccess, Function(List list) onSuccessList, Function(int code, String msg) onError, dynamic params, Map queryParameters, CancelToken cancelToken, Options options, bool isList: false}) async { String m = _getRequestMethod(method); return await _request(m, url, objectFromJson: objectFromJson, data: params, queryParameters: queryParameters, options: options, cancelToken: cancelToken) .then((BaseEntity result) { // logg.LogUtil.d(params); if (result.statusCode == 1 || result.statusCode == 9) { if (isList) { if (onSuccessList != null) { onSuccessList(result.listData); } } else { if (onSuccess != null) { onSuccess(result.data); } } } else { _onError(result.statusCode, result.message, onError); } }, onError: (e, _) { _cancelLogPrint(e, url); NetError error = ExceptionHandle.handleException(e); _onError(error.code, error.msg, onError); }); } /// 统一处理(onSuccess返回T对象,onSuccessList返回List) asyncRequestNetwork(Method method, String url, {Function(T t) onSuccess, Function(List list) onSuccessList, Function(int code, String msg) onError, dynamic params, Map queryParameters, CancelToken cancelToken, Options options, bool isList: false}) { String m = _getRequestMethod(method); Observable.fromFuture(_request(m, url, data: params, queryParameters: queryParameters, options: options, cancelToken: cancelToken)) .asBroadcastStream() .listen((result) { if (result.statusCode == 1 || result.statusCode == 9) { if (isList) { if (onSuccessList != null) { onSuccessList(result.listData); } } else { if (onSuccess != null) { onSuccess(result.data); } } } else { _onError(result.statusCode, result.message, onError); } }, onError: (e) { _cancelLogPrint(e, url); NetError error = ExceptionHandle.handleException(e); _onError(error.code, error.msg, onError); }); } _cancelLogPrint(dynamic e, String url) { if (e is DioError && CancelToken.isCancel(e)) { Log.e("取消请求接口: $url"); } } _onError(int code, String msg, Function(int code, String mag) onError) { if (code == null) { code = ExceptionHandle.unknown_error; msg = "未知异常"; } Log.e("接口请求异常: code: $code, mag: $msg"); if (onError != null) { onError(code, msg); } } String _getRequestMethod(Method method) { String m; switch (method) { case Method.get: m = "GET"; break; case Method.post: m = "POST"; break; case Method.put: m = "PUT"; break; case Method.patch: m = "PATCH"; break; case Method.delete: m = "DELETE"; break; case Method.head: m = "HEAD"; break; } return m; } } Map parseData(String data) { return json.decode(data); } enum Method { get, post, put, patch, delete, head }