import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:flustars/flustars.dart'; import 'package:flutter/foundation.dart'; import 'package:liftmanager/common/common.dart'; import 'package:liftmanager/utils/log_utils.dart'; import 'package:rxdart/rxdart.dart'; import 'base_entity.dart'; import 'error_handle.dart'; import 'intercept.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: 15000, receiveTimeout: 15000, responseType: ResponseType.plain, validateStatus: (status){ // 不使用http状态码判断状态,使用AdapterInterceptor来处理(适用于标准REST风格) return true; }, baseUrl: "https://app.edtyun.com:8443" // baseUrl: "http://111.47.6.224:20227" // baseUrl: "http://172.16.24.142:10227", // baseUrl: "http://121.40.99.234", // 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 10.41.0.132:8888"; // }; // 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(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.fromJsonMap(_map,objectFromJson); }catch(e){ return BaseEntity(ExceptionHandle.parse_error, "数据解析错误${e}", 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 { if(url.contains(":20230")){ url = url.replaceAll(":20230", "/system"); }else if(url.contains(":20231")){ url = url.replaceAll(":20231", "/batch"); }else if(url.contains(":20232")){ url = url.replaceAll(":20232", "/quan"); }else if(url.contains(":20229")){ url = url.replaceAll(":20229", "/enterprise"); }else if(url.contains(":20227")){ url = url.replaceAll(":20227", "/business"); } String m = _getRequestMethod(method); return await _request(m, url, objectFromJson: objectFromJson, data: params, queryParameters: queryParameters, options: options, cancelToken: cancelToken).then((BaseEntity 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); }); } /// 统一处理(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 }