dio_utils.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import 'dart:convert';
  2. import 'package:dio/dio.dart';
  3. import 'package:flustars/flustars.dart';
  4. import 'package:flutter/foundation.dart';
  5. import 'package:liftmanager/common/common.dart';
  6. import 'package:liftmanager/utils/log_utils.dart';
  7. import 'package:rxdart/rxdart.dart';
  8. import 'base_entity.dart';
  9. import 'error_handle.dart';
  10. import 'intercept.dart';
  11. /// @weilu https://github.com/simplezhli
  12. class DioUtils {
  13. static final DioUtils _singleton = DioUtils._internal();
  14. static DioUtils get instance => DioUtils();
  15. factory DioUtils() {
  16. return _singleton;
  17. }
  18. static Dio _dio;
  19. Dio getDio(){
  20. return _dio;
  21. }
  22. DioUtils._internal(){
  23. var options = BaseOptions(
  24. connectTimeout: 15000,
  25. receiveTimeout: 15000,
  26. responseType: ResponseType.plain,
  27. validateStatus: (status){
  28. // 不使用http状态码判断状态,使用AdapterInterceptor来处理(适用于标准REST风格)
  29. return true;
  30. },
  31. baseUrl: "https://app.edtyun.com:8443"
  32. // baseUrl: "http://111.47.6.224:20227"
  33. // baseUrl: "http://172.16.24.142:10227",
  34. // baseUrl: "http://121.40.99.234",
  35. // contentType: ContentType('application', 'x-www-form-urlencoded', charset: 'utf-8'),
  36. );
  37. _dio = Dio(options);
  38. /// Fiddler抓包代理配置 https://www.jianshu.com/p/d831b1f7c45b
  39. // (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
  40. // (HttpClient client) {
  41. // client.findProxy = (uri) {
  42. // //proxy all request to localhost:8888
  43. // return "PROXY 10.41.0.132:8888";
  44. // };
  45. // client.badCertificateCallback =
  46. // (X509Certificate cert, String host, int port) => true;
  47. // };
  48. /// 统一添加身份验证请求头
  49. _dio.interceptors.add(AuthInterceptor());
  50. /// 刷新Token
  51. // _dio.interceptors.add(TokenInterceptor());
  52. /// 打印Log(生产模式去除)
  53. if (!Constant.inProduction){
  54. _dio.interceptors.add(LoggingInterceptor());
  55. }
  56. /// 适配数据(根据自己的数据结构,可自行选择添加)
  57. _dio.interceptors.add(AdapterInterceptor());
  58. }
  59. // 数据返回格式统一,统一处理异常
  60. Future<BaseEntity<T>> _request<T>(String method, String url,{
  61. T Function(Map<String, dynamic>) objectFromJson,
  62. dynamic data, Map<String, dynamic> queryParameters,
  63. CancelToken cancelToken, Options options
  64. }) async {
  65. var response = await _dio.request(url, data: data, queryParameters: queryParameters, options: _checkOptions(method, options), cancelToken: cancelToken);
  66. try {
  67. /// 集成测试无法使用 isolate
  68. Map<String, dynamic> _map = Constant.isTest ? parseData(response.data.toString()) : await compute(parseData, response.data.toString());
  69. return BaseEntity.fromJsonMap(_map,objectFromJson);
  70. }catch(e){
  71. return BaseEntity(ExceptionHandle.parse_error, "数据解析错误${e}", null);
  72. }
  73. }
  74. Options _checkOptions(method, options) {
  75. if (options == null) {
  76. options = new Options();
  77. }
  78. options.method = method;
  79. return options;
  80. }
  81. Future requestNetwork<T>(Method method, String url, {
  82. T Function(Map<String, dynamic>) objectFromJson,
  83. Function(T t) onSuccess,
  84. Function(List<T> list) onSuccessList,
  85. Function(int code, String msg) onError,
  86. dynamic params, Map<String, dynamic> queryParameters,
  87. CancelToken cancelToken, Options options, bool isList : false
  88. }) async {
  89. if(url.contains(":20230")){
  90. url = url.replaceAll(":20230", "/system");
  91. }else if(url.contains(":20231")){
  92. url = url.replaceAll(":20231", "/batch");
  93. }else if(url.contains(":20232")){
  94. url = url.replaceAll(":20232", "/quan");
  95. }else if(url.contains(":20229")){
  96. url = url.replaceAll(":20229", "/enterprise");
  97. }else if(url.contains(":20227")){
  98. url = url.replaceAll(":20227", "/business");
  99. }
  100. String m = _getRequestMethod(method);
  101. return await _request<T>(m, url,
  102. objectFromJson: objectFromJson,
  103. data: params,
  104. queryParameters: queryParameters,
  105. options: options,
  106. cancelToken: cancelToken).then((BaseEntity<T> result){
  107. if (result.statusCode == 1 || result.statusCode == 9){
  108. if (isList){
  109. if (onSuccessList != null){
  110. onSuccessList(result.listData);
  111. }
  112. }else{
  113. if (onSuccess != null){
  114. onSuccess(result.data);
  115. }
  116. }
  117. }else{
  118. _onError(result.statusCode, result.message, onError);
  119. }
  120. }, onError: (e, _){
  121. _cancelLogPrint(e, url);
  122. NetError error = ExceptionHandle.handleException(e);
  123. _onError(error.code, error.msg, onError);
  124. });
  125. }
  126. /// 统一处理(onSuccess返回T对象,onSuccessList返回List<T>)
  127. asyncRequestNetwork<T>(Method method, String url, {
  128. Function(T t) onSuccess,
  129. Function(List<T> list) onSuccessList,
  130. Function(int code, String msg) onError,
  131. dynamic params, Map<String, dynamic> queryParameters,
  132. CancelToken cancelToken, Options options, bool isList : false
  133. }){
  134. String m = _getRequestMethod(method);
  135. Observable.fromFuture(_request<T>(m, url, data: params, queryParameters: queryParameters, options: options, cancelToken: cancelToken))
  136. .asBroadcastStream()
  137. .listen((result){
  138. if (result.statusCode == 1 || result.statusCode == 9){
  139. if (isList){
  140. if (onSuccessList != null){
  141. onSuccessList(result.listData);
  142. }
  143. }else{
  144. if (onSuccess != null){
  145. onSuccess(result.data);
  146. }
  147. }
  148. }else{
  149. _onError(result.statusCode, result.message, onError);
  150. }
  151. }, onError: (e){
  152. _cancelLogPrint(e, url);
  153. NetError error = ExceptionHandle.handleException(e);
  154. _onError(error.code, error.msg, onError);
  155. });
  156. }
  157. _cancelLogPrint(dynamic e, String url){
  158. if (e is DioError && CancelToken.isCancel(e)){
  159. Log.e("取消请求接口: $url");
  160. }
  161. }
  162. _onError(int code, String msg, Function(int code, String mag) onError){
  163. if (code == null){
  164. code = ExceptionHandle.unknown_error;
  165. msg = "未知异常";
  166. }
  167. Log.e("接口请求异常: code: $code, mag: $msg");
  168. if (onError != null) {
  169. onError(code, msg);
  170. }
  171. }
  172. String _getRequestMethod(Method method){
  173. String m;
  174. switch(method){
  175. case Method.get:
  176. m = "GET";
  177. break;
  178. case Method.post:
  179. m = "POST";
  180. break;
  181. case Method.put:
  182. m = "PUT";
  183. break;
  184. case Method.patch:
  185. m = "PATCH";
  186. break;
  187. case Method.delete:
  188. m = "DELETE";
  189. break;
  190. case Method.head:
  191. m = "HEAD";
  192. break;
  193. }
  194. return m;
  195. }
  196. }
  197. Map<String, dynamic> parseData(String data){
  198. return json.decode(data);
  199. }
  200. enum Method {
  201. get,
  202. post,
  203. put,
  204. patch,
  205. delete,
  206. head
  207. }