基础库
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

251 行
7.8 KiB

  1. import 'package:dio/dio.dart';
  2. import 'package:dio/adapter.dart';
  3. import 'package:zhiying_comm/util/empty_util.dart';
  4. import 'dart:io';
  5. import 'dart:convert';
  6. import 'package:zhiying_comm/zhiying_comm.dart';
  7. import 'global_config.dart';
  8. import 'shared_prefe_util.dart';
  9. class Api {
  10. final String path;
  11. Map<String, dynamic> params;
  12. final NetMethod method;
  13. static Dio _dio;
  14. static get _net async {
  15. if (_dio == null) {
  16. var setting = await NativeUtil.getSetting();
  17. String domain = setting['domain']; //'http://www.hairuyi.com/';
  18. _config(domain, proxyUrl: '192.168.0.112:8888');
  19. }
  20. return _dio;
  21. }
  22. Api(this.path, {this.params, this.method = NetMethod.POST}) {
  23. this.params = params ?? {};
  24. }
  25. Future<Map> onCache() async {
  26. String cacheKey = getRequestParamsCachedKey(params, path);
  27. // 读取缓存
  28. Map<String, dynamic> cacheMap =
  29. await SharedPreferencesUtil.getNetCacheResult(cacheKey);
  30. if (!EmptyUtil.isEmpty(cacheMap) &&
  31. cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) &&
  32. (cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  33. GlobalConfig.RESPONSE_SUCCESS_CODE ||
  34. cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  35. '${GlobalConfig.RESPONSE_SUCCESS_CODE}') &&
  36. !EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
  37. return cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA];
  38. }
  39. return {};
  40. }
  41. Future<Map> onRequest() async {
  42. Map result = {};
  43. try {
  44. Dio net = await _net;
  45. Map<String, String> headers = await _getHeaders();
  46. var responds = await net.request(path,
  47. data: params,
  48. options: Options(method: enumToString(method), headers: headers));
  49. result = responds.data is Map ? responds.data : jsonDecode(responds.data);
  50. String cacheKey = getRequestParamsCachedKey(params, path);
  51. _setCallBackCacheData(cacheKey,
  52. responds.data is Map ? jsonEncode(responds.data) : responds.data);
  53. } on DioError catch (e) {
  54. _formatError(e);
  55. }
  56. return result;
  57. }
  58. // 获取headers,headers保存各种签名认证信息
  59. Future<Map<String, String>> _getHeaders() async {
  60. Map<String, String> headers = Map();
  61. headers['device'] = 'wx_applet';
  62. headers['Platform'] = 'wx_applet';
  63. // token 读取SP缓存中的用户token
  64. String token = await SharedPreferencesUtil.getStringValue(
  65. GlobalConfig.SHARED_KEY_TOKEN) ??
  66. '';
  67. const bool inProduction = const bool.fromEnvironment("dart.vm.product");
  68. if (!inProduction && token != '') {
  69. token = '7f7bdb785dcb02a4536bea2ffe299eda352e127f';
  70. }
  71. if (token != null && token != '') {
  72. headers['token'] = token;
  73. }
  74. return headers;
  75. }
  76. /// 配置网络请求,基础地址,代理地址,如:192.168.0.123:8888(代理地址生产环境无效)
  77. /// apiVersion 接口版本
  78. static void _config(String baseUrl, {String proxyUrl}) {
  79. _dio = Dio(BaseOptions(
  80. method: "post",
  81. baseUrl: baseUrl,
  82. connectTimeout: 15000,
  83. receiveTimeout: 15000,
  84. contentType: Headers.jsonContentType,
  85. followRedirects: true,
  86. ));
  87. _dio.interceptors.add(_NetInterceptors());
  88. // _dio.interceptors.add(LogInterceptor());
  89. const bool inProduction = const bool.fromEnvironment("dart.vm.product");
  90. if (proxyUrl != null && proxyUrl != '' && !inProduction) {
  91. _setProxy(proxyUrl);
  92. }
  93. }
  94. /// 设置代理
  95. static void _setProxy(String proxyUrl) {
  96. (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
  97. (HttpClient client) {
  98. client.findProxy = (uri) {
  99. return "PROXY $proxyUrl";
  100. };
  101. client.badCertificateCallback =
  102. (X509Certificate cert, String host, int port) => true;
  103. };
  104. }
  105. /// 获取请求缓存成功的数据
  106. static Future<void> _onCallBackCacheData(
  107. OnCache onCache, String cacheKey) async {
  108. // 读取缓存
  109. Map<String, dynamic> cacheMap =
  110. await SharedPreferencesUtil.getNetCacheResult(cacheKey);
  111. if (!EmptyUtil.isEmpty(cacheMap) &&
  112. cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) &&
  113. (cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  114. GlobalConfig.RESPONSE_SUCCESS_CODE ||
  115. cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  116. '${GlobalConfig.RESPONSE_SUCCESS_CODE}') &&
  117. !EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
  118. onCache(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA]);
  119. return;
  120. }
  121. return;
  122. }
  123. /// 缓存请求成功的数据
  124. static void _setCallBackCacheData(String cacheKey, String value) async {
  125. SharedPreferencesUtil.setNetCacheResult(cacheKey, value);
  126. }
  127. /// 根据请求参数,获取缓存的数据
  128. static Future<dynamic> getRequestCachedData(String url,
  129. {Map<String, dynamic> params}) async {
  130. Map<String, dynamic> cacheMap =
  131. await SharedPreferencesUtil.getNetCacheResult(
  132. getRequestParamsCachedKey(params, url));
  133. if (!EmptyUtil.isEmpty(cacheMap) &&
  134. cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) &&
  135. (cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  136. GlobalConfig.RESPONSE_SUCCESS_CODE ||
  137. cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  138. '${GlobalConfig.RESPONSE_SUCCESS_CODE}') &&
  139. !EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
  140. return cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA];
  141. }
  142. return null;
  143. }
  144. /// 判断后台返回是否成功
  145. static bool isSuccess(Map<String, dynamic> data) {
  146. try {
  147. if (!EmptyUtil.isEmpty(data) &&
  148. (data[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  149. GlobalConfig.RESPONSE_SUCCESS_CODE ||
  150. data[GlobalConfig.HTTP_RESPONSE_KEY_CODE] ==
  151. '${GlobalConfig.RESPONSE_SUCCESS_CODE}')) {
  152. return true;
  153. }
  154. } catch (e) {
  155. return false;
  156. }
  157. return false;
  158. }
  159. /// 根据请求参数,获取缓存的Key
  160. static String getRequestParamsCachedKey(
  161. Map<String, dynamic> map, String path) {
  162. if (EmptyUtil.isEmpty(map)) {
  163. return EncodeUtil.generateMd5(path);
  164. }
  165. return EncodeUtil.generateMd5(path + map.toString());
  166. }
  167. /// 签名
  168. static String signWithArray(List<String> params) {
  169. // 字母升序
  170. params.sort();
  171. String result = "";
  172. // result += secret_key;
  173. params.forEach((param) {
  174. result += param;
  175. });
  176. // result += secret_key;
  177. return EncodeUtil.generateMd5(result);
  178. }
  179. /*
  180. * error统一处理
  181. */
  182. static void _formatError(DioError e) {
  183. if (e.type == DioErrorType.CONNECT_TIMEOUT) {
  184. Logger.error('连接超时: ${e.toString()}');
  185. } else if (e.type == DioErrorType.SEND_TIMEOUT) {
  186. Logger.error('请求超时: ${e.toString()}');
  187. } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
  188. Logger.error('响应超时: ${e.toString()}');
  189. } else if (e.type == DioErrorType.RESPONSE) {
  190. Logger.error('出现异常: ${e.toString()}');
  191. } else if (e.type == DioErrorType.CANCEL) {
  192. Logger.error('请求取消: ${e.toString()}');
  193. } else {
  194. Logger.error('未知错误: ${e.toString()}');
  195. }
  196. }
  197. }
  198. /**
  199. * @description: 网络请求拦截器
  200. * @param {type}
  201. * @return:
  202. */
  203. class _NetInterceptors extends InterceptorsWrapper {
  204. @override
  205. Future onRequest(RequestOptions options) {
  206. Logger.net(options?.uri?.toString(), data: options.data.toString());
  207. // TODO 加密?
  208. return super.onRequest(options);
  209. }
  210. @override
  211. Future onResponse(Response response) {
  212. Logger.endNet(response?.request?.uri?.toString(),
  213. data: response?.data?.toString() ?? '');
  214. // TODO 解密?
  215. return super.onResponse(response);
  216. }
  217. @override
  218. Future onError(DioError err) {
  219. // Logger.error(err);
  220. return super.onError(err);
  221. }
  222. }