基础库
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

net_util.dart 20 KiB

4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
4年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. import 'dart:collection';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'dart:ui';
  5. import 'package:device_info/device_info.dart';
  6. import 'package:dio/adapter.dart';
  7. import 'package:dio/dio.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:flutter_alibc/flutter_alibc.dart';
  10. import 'package:fluttertoast/fluttertoast.dart';
  11. import 'package:package_info/package_info.dart';
  12. import 'package:provider/provider.dart';
  13. import 'package:zhiying_comm/util/empty_util.dart';
  14. import 'package:zhiying_comm/zhiying_comm.dart';
  15. import 'encode_util.dart';
  16. import 'global_config.dart';
  17. import 'shared_prefe_util.dart';
  18. import 'time_util.dart';
  19. typedef OnSuccess = dynamic Function(dynamic data);
  20. typedef OnError = dynamic Function(String e);
  21. typedef OnCache = dynamic Function(dynamic data);
  22. final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
  23. enum NetMethod {
  24. GET,
  25. POST,
  26. PUT,
  27. DELETE,
  28. OPTIONS,
  29. PATCH,
  30. UPDATE,
  31. HEAD,
  32. }
  33. class NetUtil {
  34. Dio _dio;
  35. NetUtil._();
  36. static NetUtil _instance;
  37. static NetUtil getInstance() {
  38. if (_instance == null) {
  39. _instance = NetUtil._();
  40. }
  41. return _instance;
  42. }
  43. get dio async {
  44. if (_dio == null) {
  45. var setting = await NativeUtil.getSetting();
  46. String domain = setting['domain']; //'http://www.hairuyi.com/';
  47. _config(domain, proxyUrl: ''); // 192.168.0.66:8866
  48. }
  49. return _dio;
  50. }
  51. /// 配置网络请求,基础地址,代理地址,如:192.168.0.123:8888(代理地址生产环境无效)
  52. /// apiVersion 接口版本
  53. void _config(String baseUrl, {String proxyUrl}) {
  54. _dio = Dio(BaseOptions(
  55. method: "post",
  56. baseUrl: baseUrl,
  57. connectTimeout: 15000,
  58. receiveTimeout: 15000,
  59. contentType: Headers.jsonContentType,
  60. followRedirects: true,
  61. // headers: {'device': 'wx_applet', 'Platform': 'wx_applet'},
  62. validateStatus: (_) {
  63. return true;
  64. }));
  65. _dio.interceptors.add(_NetInterceptors());
  66. // _dio.interceptors.add(LogInterceptor());
  67. const bool inProduction = const bool.fromEnvironment("dart.vm.product");
  68. if (proxyUrl != null && proxyUrl != '' && !inProduction) {
  69. _setProxy(proxyUrl);
  70. }
  71. }
  72. /// 设置代理
  73. void _setProxy(String proxyUrl) {
  74. (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (HttpClient client) {
  75. client.findProxy = (uri) {
  76. return "PROXY $proxyUrl";
  77. };
  78. client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
  79. };
  80. }
  81. static Map<String, dynamic> headParam;
  82. /// 同步请求
  83. static Future<dynamic> post(String path,
  84. {Map<String, dynamic> params, Map<String, dynamic> queryParameters, NetMethod method = NetMethod.POST, bool cache = false, bool showToast = true}) async {
  85. var paramsData = {'postData': params ?? {}, 'queryParameters': queryParameters ?? {}};
  86. // 根据请求参数,获取缓存的Key
  87. String cacheKey = getRequestParamsCachedKey(paramsData, path);
  88. // 参数签名 TODO 加密?
  89. // post请求的参数
  90. Map<String, dynamic> bodyParams = params;
  91. ///只拿一次头部数据
  92. if (NetUtil.headParam == null) {
  93. NetUtil.headParam = await _getMustHeadParams();
  94. }
  95. // token 读取SP缓存中的用户token
  96. String token = await SharedPreferencesUtil.getStringValue(GlobalConfig.SHARED_KEY_TOKEN);
  97. if (EmptyUtil.isEmpty(token) && !bool.fromEnvironment("dart.vm.product")) {
  98. try {
  99. Map setting = await NativeUtil.getSetting();
  100. token = setting['token'];
  101. } catch (e, s) {
  102. print(s);
  103. print(e);
  104. }
  105. }
  106. if (!EmptyUtil.isEmpty(token)) {
  107. // params['token'] = token;
  108. NetUtil.headParam['Authorization'] = 'Bearer ' + token;
  109. }
  110. if (NetUtil.headParam['token'] == null) {}
  111. // 请求头参数
  112. Map<String, dynamic> headParam = NetUtil.headParam;
  113. Response response;
  114. try {
  115. Dio dio = await NetUtil.getInstance().dio;
  116. response = await dio.request(
  117. path,
  118. data: !EmptyUtil.isEmpty(bodyParams) ? bodyParams : null,
  119. options: Options(method: enumToString(method), headers: headParam),
  120. queryParameters: !EmptyUtil.isEmpty(queryParameters) ? queryParameters : null,
  121. );
  122. } on DioError catch (e) {
  123. _formatError(e);
  124. }
  125. try {
  126. var result = response.data is Map ? response.data : jsonDecode(response.data);
  127. // TODO 解密?
  128. if (isSuccess(result)) {
  129. // 缓存成功的数据
  130. if (cache) {
  131. _setCallBackCacheData(cacheKey, response.data is Map ? jsonEncode(response.data) : response.data);
  132. }
  133. return result;
  134. // 缓存返回的数据
  135. } else {
  136. Logger.error('error: ' + result[GlobalConfig.HTTP_RESPONSE_KEY_MSG]);
  137. ///
  138. /// 401000 验证用户失败(不提示Toast)
  139. /// 404004 没有找到对应模块(跳空页面,不提示toast)
  140. ///
  141. if (result[GlobalConfig.HTTP_RESPONSE_KEY_CODE] != 401000 && result[GlobalConfig.HTTP_RESPONSE_KEY_CODE] != 404004) {
  142. if (showToast) {
  143. Fluttertoast.showToast(
  144. msg: result[GlobalConfig.HTTP_RESPONSE_KEY_MSG],
  145. toastLength: Toast.LENGTH_SHORT,
  146. gravity: ToastGravity.BOTTOM,
  147. );
  148. }
  149. }
  150. ///
  151. /// 401003 用户被逼下线
  152. /// 退出登陆(清理token等用户信息)
  153. ///
  154. if (result[GlobalConfig.HTTP_RESPONSE_KEY_CODE]?.toString() == '401003') {
  155. try {
  156. Future.delayed(Duration(seconds: 0)).then((onValue) {
  157. BuildContext context = navigatorKey.currentState.overlay.context;
  158. Provider.of<UserInfoNotifier>(context, listen: false).unLogin();
  159. });
  160. } catch (e, s) {
  161. Logger.error(e, s);
  162. }
  163. }
  164. ///非法用户
  165. if (result[GlobalConfig.HTTP_RESPONSE_KEY_CODE]?.toString() == '401000') {
  166. try {
  167. Future.delayed(Duration(seconds: 0)).then((onValue) async {
  168. String token = await SharedPreferencesUtil.getStringValue(GlobalConfig.SHARED_KEY_TOKEN);
  169. if (token != null && token.length > 2) {
  170. BuildContext context = navigatorKey.currentState.overlay.context;
  171. Provider.of<UserInfoNotifier>(context, listen: false).unLogin();
  172. }
  173. });
  174. } catch (e, s) {
  175. Logger.error(e, s);
  176. }
  177. }
  178. ///
  179. /// 403028 账号被冻结
  180. /// 403029 账号被禁用
  181. /// 提示并且退出登录
  182. ///
  183. if (result[GlobalConfig.HTTP_RESPONSE_KEY_CODE]?.toString() == '403028' || result[GlobalConfig.HTTP_RESPONSE_KEY_CODE]?.toString() == '403029') {
  184. try {
  185. // 提示
  186. Fluttertoast.showToast(
  187. msg: result[GlobalConfig.HTTP_RESPONSE_KEY_MSG],
  188. toastLength: Toast.LENGTH_SHORT,
  189. gravity: ToastGravity.BOTTOM,
  190. );
  191. // 退出登录
  192. Future.delayed(Duration(seconds: 0)).then((onValue) {
  193. BuildContext context = navigatorKey.currentState.overlay.context;
  194. Provider.of<UserInfoNotifier>(context, listen: false).unLogin();
  195. });
  196. } catch (e, s) {
  197. Logger.error(e, s);
  198. }
  199. }
  200. return result;
  201. }
  202. } catch (e) {
  203. return null;
  204. }
  205. }
  206. /// 异步请求
  207. static void request(String path,
  208. {NetMethod method = NetMethod.GET,
  209. Map<String, dynamic> params,
  210. Map<String, dynamic> queryParameters,
  211. OnSuccess onSuccess,
  212. OnError onError,
  213. OnCache onCache,
  214. bool showToast = true}) async {
  215. var paramsData = {'postData': params ?? {}, 'queryParameters': queryParameters ?? {}};
  216. // 根据请求参数,获取缓存的Key
  217. String cacheKey = getRequestParamsCachedKey(paramsData, path);
  218. print("缓存Key" + cacheKey);
  219. // // 读取缓存回调
  220. if (onCache != null) {
  221. await _onCallBackCacheData(onCache, cacheKey);
  222. }
  223. try {
  224. Map result = await NetUtil.post(path, method: method, params: params, queryParameters: queryParameters, showToast: showToast, cache: onCache != null);
  225. // TODO 解密?
  226. if (isSuccess(result)) {
  227. if (onSuccess != null) {
  228. onSuccess(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]);
  229. }
  230. return;
  231. }
  232. if (onError != null) {
  233. onError(!EmptyUtil.isEmpty(result)
  234. ? !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_MSG])
  235. ? result[GlobalConfig.HTTP_RESPONSE_KEY_MSG]
  236. : '未知错误'
  237. : '未知错误');
  238. }
  239. } catch (e) {
  240. Logger.error('error: ' + e.toString());
  241. if (onError != null) {
  242. onError(e?.toString() ?? '未知错误');
  243. }
  244. }
  245. return;
  246. }
  247. /// 统一添加必要的参数
  248. // static Future<Map<String, dynamic>> signParams(Map<String, dynamic> params) async {
  249. // // 应用信息
  250. // PackageInfo packageInfo = await PackageInfo.fromPlatform();
  251. // // 原生传的信息
  252. // Map setting = await NativeUtil.getSetting();
  253. //
  254. // if (Platform.isIOS) {
  255. // IosDeviceInfo iosInfo = await DeviceInfoPlugin().iosInfo;
  256. // // 设备
  257. // params["platform"] = "ios";
  258. // // 设备系统版本
  259. // params["system_version"] = iosInfo?.systemVersion;
  260. // // 设备型号 如:iPhone 11pro
  261. // params['device_model'] = iosInfo?.name;
  262. // // 设备型号,如:MLMF2LL/A
  263. // // params['device_number'] = iosInfo?.model;
  264. // // 设备ID
  265. // params['device_id'] = iosInfo?.identifierForVendor;
  266. // } else if (Platform.isAndroid) {
  267. // AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo;
  268. // // 设备
  269. // params["platform"] = "android";
  270. // // 设备系统版本
  271. // params["system_version"] = "Android ${androidInfo?.version?.release}";
  272. // // 设备型号 如:iPhone 11pro
  273. // params['device_model'] = androidInfo?.model;
  274. // // 设备型号,如:MLMF2LL/A
  275. // // params['device_number'] = androidInfo?.id;
  276. // // 设备Id
  277. // params['device_id'] = androidInfo?.androidId;
  278. // }
  279. // // 应用版本号
  280. // params["app_version_name"] = packageInfo.version;
  281. // params["app_version"] = -1 ;// packageInfo.buildNumber;
  282. // // 分辨率
  283. // params["solution"] =
  284. // "${window.physicalSize.width.floor()}*${window.physicalSize.height.floor()}";
  285. //
  286. // // 站长ID
  287. // String masterId = setting['master_id'];
  288. // if (null != masterId &&
  289. // masterId != '' &&
  290. // (!params.containsKey('master_id') || params['master_id'] == '')) {
  291. // params['master_id'] = masterId;
  292. // }
  293. //
  294. // // secret_key
  295. // params['secret_key'] = setting['secret_key'];
  296. //
  297. // // token 读取SP缓存中的用户token
  298. // String token = await SharedPreferencesUtil.getStringValue(
  299. // GlobalConfig.SHARED_KEY_TOKEN);
  300. // if (!EmptyUtil.isEmpty(token)) {
  301. // params['token'] = token;
  302. // }
  303. //
  304. // // 当前时间戳:秒
  305. // params["time"] = TimeUtil.getNowTime();
  306. //
  307. // // 过滤空字段,过滤首尾空格
  308. // Map<String, dynamic> filters = Map<String, dynamic>();
  309. // params.forEach((key, value) {
  310. // if (key != '' && value != '') {
  311. // filters[key] = (value is String) ? value.trim() : value;
  312. // }
  313. // });
  314. // params = filters;
  315. //
  316. // List<String> list = List<String>();
  317. // params.forEach((key, value) {
  318. // list.add(key.toString() + value.toString());
  319. // });
  320. // params["sign"] = signWithArray(list);
  321. // return params;
  322. // }
  323. /// 获取必须的请求参数(用于请求头部)
  324. static Future<Map<String, String>> _getMustHeadParams() async {
  325. Map<String, String> params = new HashMap<String, String>();
  326. // 应用信息
  327. PackageInfo packageInfo = await PackageInfo.fromPlatform();
  328. // 原生传的信息
  329. Map setting = await NativeUtil.getSetting();
  330. if (Platform.isIOS) {
  331. IosDeviceInfo iosInfo = await DeviceInfoPlugin().iosInfo;
  332. // 设备
  333. params["platform"] = "ios";
  334. // 设备系统版本
  335. params["os_version"] = iosInfo?.systemVersion?.toString();
  336. // 设备型号 如:iPhone 11pro
  337. params['device_model'] = EncodeUtil.encodeBase64(iosInfo?.name?.toString() ?? '');
  338. // 设备ID
  339. params['device_id'] = iosInfo?.identifierForVendor?.toString();
  340. // idfa
  341. params['idfa'] = iosInfo?.identifierForVendor?.toString();
  342. } else if (Platform.isAndroid) {
  343. AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo;
  344. // 设备
  345. params["platform"] = "android";
  346. // 设备系统版本
  347. params["os_version"] = "Android ${androidInfo?.version?.release}";
  348. // 设备型号 如:iPhone 11pro
  349. params['device_model'] = androidInfo?.model?.toString();
  350. // 设备Id
  351. params['device_id'] = androidInfo?.androidId?.toString();
  352. }
  353. // 应用版本号
  354. params["app_version_name"] = packageInfo.version?.toString();
  355. params["AppVersionName"] = packageInfo.version?.toString();
  356. params["app_version"] = packageInfo.buildNumber?.toString();
  357. // 分辨率
  358. params["solution"] = "${window.physicalSize.width.floor()}*${window.physicalSize.height.floor()}";
  359. // 站长ID
  360. String masterId = setting['master_id'];
  361. if (null != masterId && masterId != '' && (!params.containsKey('master_id') || params['master_id'] == '')) {
  362. params['master_id'] = masterId; //!EmptyUtil.isEmpty(masterId) ? masterId : 'template_database';
  363. params['MasterId'] = masterId; //!EmptyUtil.isEmpty(masterId) ? masterId : 'template_database';
  364. }
  365. // token 读取SP缓存中的用户token
  366. String token = await SharedPreferencesUtil.getStringValue(GlobalConfig.SHARED_KEY_TOKEN);
  367. if (EmptyUtil.isEmpty(token) && !bool.fromEnvironment("dart.vm.product")) {
  368. try {
  369. token = setting['token'];
  370. } catch (e, s) {
  371. print(s);
  372. print(e);
  373. }
  374. }
  375. if (!EmptyUtil.isEmpty(token)) {
  376. // params['token'] = token;
  377. params['Authorization'] = 'Bearer ' + token;
  378. }
  379. // secret_key
  380. params['secret_key'] = setting['secret_key'] ?? '';
  381. // 当前时间戳:秒
  382. params["time"] = TimeUtil.getNowTime();
  383. // 过滤空字段,过滤首尾空格
  384. Map<String, String> filters = Map<String, String>();
  385. params.forEach((key, value) {
  386. if (key != '' && value != '') {
  387. filters[key] = (value is String) ? value.trim() : value;
  388. }
  389. });
  390. params = filters;
  391. List<String> list = List<String>();
  392. params.forEach((key, value) {
  393. list.add(key.toString() + '=' + value.toString() + '&');
  394. });
  395. params["sign"] = signWithArray(list);
  396. params.remove('secret_key');
  397. return params;
  398. }
  399. /// 获取Android imei
  400. static Future<String> _getImei() async {
  401. try {
  402. return await FlutterAlibc.getUdid();
  403. } catch (e, s) {
  404. Logger.error(e, s);
  405. }
  406. return null;
  407. }
  408. /// 获取请求缓存成功的数据
  409. static Future<void> _onCallBackCacheData(OnCache onCache, String cacheKey) async {
  410. // 读取缓存
  411. Map<String, dynamic> cacheMap = await SharedPreferencesUtil.getNetCacheResult(cacheKey);
  412. if (!EmptyUtil.isEmpty(cacheMap) &&
  413. cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) &&
  414. (cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == GlobalConfig.RESPONSE_SUCCESS_CODE ||
  415. cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == '${GlobalConfig.RESPONSE_SUCCESS_CODE}') &&
  416. !EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
  417. onCache(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA]);
  418. return;
  419. }
  420. return;
  421. }
  422. /// 缓存请求成功的数据
  423. static void _setCallBackCacheData(String cacheKey, String value) async {
  424. SharedPreferencesUtil.setNetCacheResult(cacheKey, value);
  425. }
  426. /// 根据请求参数,获取缓存的数据
  427. static Future<dynamic> getRequestCachedData(String url, {Map<String, dynamic> params, Map<String, dynamic> queryParameters}) async {
  428. var paramsData = {'postData': params ?? {}, 'queryParameters': queryParameters ?? {}};
  429. Map<String, dynamic> cacheMap = await SharedPreferencesUtil.getNetCacheResult(getRequestParamsCachedKey(paramsData, url));
  430. if (!EmptyUtil.isEmpty(cacheMap) &&
  431. cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) &&
  432. (cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == GlobalConfig.RESPONSE_SUCCESS_CODE ||
  433. cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == '${GlobalConfig.RESPONSE_SUCCESS_CODE}') &&
  434. !EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
  435. return cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA];
  436. }
  437. return null;
  438. }
  439. /// 判断后台返回是否成功
  440. static bool isSuccess(Map<String, dynamic> data) {
  441. try {
  442. if (!EmptyUtil.isEmpty(data) &&
  443. (data[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == GlobalConfig.RESPONSE_SUCCESS_CODE ||
  444. data[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == '${GlobalConfig.RESPONSE_SUCCESS_CODE}')) {
  445. return true;
  446. }
  447. } catch (e) {
  448. return false;
  449. }
  450. return false;
  451. }
  452. /// 根据请求参数,获取缓存的Key
  453. static String getRequestParamsCachedKey(Map<String, dynamic> map, String path) {
  454. String key;
  455. if (EmptyUtil.isEmpty(map)) {
  456. key = EncodeUtil.generateMd5(path);
  457. } else {
  458. key = EncodeUtil.generateMd5(path + map.toString());
  459. }
  460. return key;
  461. }
  462. // 七牛云文件上传
  463. static Future uploadFile(String url, File file, {String method = 'POST', Map<String, dynamic> params, OnSuccess onSuccess, OnError onError}) async {
  464. if (params == null) {
  465. params = {};
  466. }
  467. Dio dio = Dio(BaseOptions(
  468. method: "post",
  469. connectTimeout: 15000,
  470. receiveTimeout: 15000,
  471. contentType: Headers.jsonContentType,
  472. followRedirects: true,
  473. ));
  474. params['file'] = await MultipartFile.fromFile(file.path);
  475. FormData format = FormData.fromMap(params);
  476. return dio.request(url, data: format, options: Options(method: method));
  477. }
  478. /// 签名
  479. static String signWithArray(List<String> params) {
  480. // 字母升序
  481. params.sort();
  482. String result = "";
  483. params.forEach((param) {
  484. result += param;
  485. });
  486. result = result.substring(0, result.length - 1);
  487. return EncodeUtil.generateMd5(result);
  488. }
  489. /*
  490. * error统一处理
  491. */
  492. static void _formatError(DioError e) {
  493. if (e.type == DioErrorType.CONNECT_TIMEOUT) {
  494. Logger.error('连接超时: ${e.toString()}');
  495. } else if (e.type == DioErrorType.SEND_TIMEOUT) {
  496. Logger.error('请求超时: ${e.toString()}');
  497. } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
  498. Logger.error('响应超时: ${e.toString()}');
  499. } else if (e.type == DioErrorType.RESPONSE) {
  500. Logger.error('出现异常: ${e.toString()}');
  501. } else if (e.type == DioErrorType.CANCEL) {
  502. Logger.error('请求取消: ${e.toString()}');
  503. } else {
  504. Logger.error('未知错误: ${e.toString()}');
  505. }
  506. }
  507. static void getImei() async {
  508. if (!NetUtil.headParam.containsKey('imei')) {
  509. String imei = await _getImei();
  510. print("获取到udid"+imei??"");
  511. if (imei != null) {
  512. NetUtil.headParam['imei'] = imei;
  513. }
  514. }
  515. }
  516. }
  517. /**
  518. * @description: 网络请求拦截器
  519. * @param {type}
  520. * @return:
  521. */
  522. class _NetInterceptors extends InterceptorsWrapper {
  523. @override
  524. Future onRequest(RequestOptions options) {
  525. Logger.net(options?.uri?.toString(), data: options.data.toString());
  526. // TODO 加密?
  527. return super.onRequest(options);
  528. }
  529. @override
  530. Future onResponse(Response response) {
  531. Logger.endNet(response?.request?.uri?.toString(), data: response?.data?.toString() ?? '');
  532. // TODO 解密?
  533. return super.onResponse(response);
  534. }
  535. @override
  536. Future onError(DioError err) {
  537. // Logger.error(err);
  538. return super.onError(err);
  539. }
  540. }