|
|
@@ -0,0 +1,250 @@ |
|
|
|
import 'package:dio/dio.dart'; |
|
|
|
import 'package:dio/adapter.dart'; |
|
|
|
import 'package:zhiying_comm/util/empty_util.dart'; |
|
|
|
import 'dart:io'; |
|
|
|
import 'dart:convert'; |
|
|
|
import 'package:zhiying_comm/zhiying_comm.dart'; |
|
|
|
|
|
|
|
import 'global_config.dart'; |
|
|
|
import 'shared_prefe_util.dart'; |
|
|
|
|
|
|
|
class Api { |
|
|
|
final String path; |
|
|
|
Map<String, dynamic> params; |
|
|
|
final NetMethod method; |
|
|
|
|
|
|
|
static Dio _dio; |
|
|
|
static get _net async { |
|
|
|
if (_dio == null) { |
|
|
|
var setting = await NativeUtil.getSetting(); |
|
|
|
String domain = setting['domain']; //'http://www.hairuyi.com/'; |
|
|
|
_config(domain, proxyUrl: '192.168.0.112:8888'); |
|
|
|
} |
|
|
|
return _dio; |
|
|
|
} |
|
|
|
|
|
|
|
Api(this.path, {this.params, this.method = NetMethod.POST}) { |
|
|
|
this.params = params ?? {}; |
|
|
|
} |
|
|
|
|
|
|
|
Future<Map> onCache() async { |
|
|
|
String cacheKey = getRequestParamsCachedKey(params, path); |
|
|
|
// 读取缓存 |
|
|
|
Map<String, dynamic> cacheMap = |
|
|
|
await SharedPreferencesUtil.getNetCacheResult(cacheKey); |
|
|
|
|
|
|
|
if (!EmptyUtil.isEmpty(cacheMap) && |
|
|
|
cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) && |
|
|
|
(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
GlobalConfig.RESPONSE_SUCCESS_CODE || |
|
|
|
cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
'${GlobalConfig.RESPONSE_SUCCESS_CODE}') && |
|
|
|
!EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { |
|
|
|
return cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA]; |
|
|
|
} |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
Future<Map> onRequest() async { |
|
|
|
Map result = {}; |
|
|
|
|
|
|
|
try { |
|
|
|
Dio net = await _net; |
|
|
|
Map<String, String> headers = await _getHeaders(); |
|
|
|
var responds = await net.request(path, |
|
|
|
data: params, |
|
|
|
options: Options(method: enumToString(method), headers: headers)); |
|
|
|
|
|
|
|
result = responds.data is Map ? responds.data : jsonDecode(responds.data); |
|
|
|
|
|
|
|
String cacheKey = getRequestParamsCachedKey(params, path); |
|
|
|
_setCallBackCacheData(cacheKey, |
|
|
|
responds.data is Map ? jsonEncode(responds.data) : responds.data); |
|
|
|
} on DioError catch (e) { |
|
|
|
_formatError(e); |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取headers,headers保存各种签名认证信息 |
|
|
|
Future<Map<String, String>> _getHeaders() async { |
|
|
|
Map<String, String> headers = Map(); |
|
|
|
headers['device'] = 'wx_applet'; |
|
|
|
headers['Platform'] = 'wx_applet'; |
|
|
|
|
|
|
|
// token 读取SP缓存中的用户token |
|
|
|
String token = await SharedPreferencesUtil.getStringValue( |
|
|
|
GlobalConfig.SHARED_KEY_TOKEN) ?? |
|
|
|
''; |
|
|
|
const bool inProduction = const bool.fromEnvironment("dart.vm.product"); |
|
|
|
if (!inProduction && token != '') { |
|
|
|
token = '7f7bdb785dcb02a4536bea2ffe299eda352e127f'; |
|
|
|
} |
|
|
|
|
|
|
|
if (token != null && token != '') { |
|
|
|
headers['token'] = token; |
|
|
|
} |
|
|
|
return headers; |
|
|
|
} |
|
|
|
|
|
|
|
/// 配置网络请求,基础地址,代理地址,如:192.168.0.123:8888(代理地址生产环境无效) |
|
|
|
/// apiVersion 接口版本 |
|
|
|
static void _config(String baseUrl, {String proxyUrl}) { |
|
|
|
_dio = Dio(BaseOptions( |
|
|
|
method: "post", |
|
|
|
baseUrl: baseUrl, |
|
|
|
connectTimeout: 15000, |
|
|
|
receiveTimeout: 15000, |
|
|
|
contentType: Headers.jsonContentType, |
|
|
|
followRedirects: true, |
|
|
|
)); |
|
|
|
_dio.interceptors.add(_NetInterceptors()); |
|
|
|
// _dio.interceptors.add(LogInterceptor()); |
|
|
|
|
|
|
|
const bool inProduction = const bool.fromEnvironment("dart.vm.product"); |
|
|
|
if (proxyUrl != null && proxyUrl != '' && !inProduction) { |
|
|
|
_setProxy(proxyUrl); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 设置代理 |
|
|
|
static void _setProxy(String proxyUrl) { |
|
|
|
(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = |
|
|
|
(HttpClient client) { |
|
|
|
client.findProxy = (uri) { |
|
|
|
return "PROXY $proxyUrl"; |
|
|
|
}; |
|
|
|
client.badCertificateCallback = |
|
|
|
(X509Certificate cert, String host, int port) => true; |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取请求缓存成功的数据 |
|
|
|
static Future<void> _onCallBackCacheData( |
|
|
|
OnCache onCache, String cacheKey) async { |
|
|
|
// 读取缓存 |
|
|
|
Map<String, dynamic> cacheMap = |
|
|
|
await SharedPreferencesUtil.getNetCacheResult(cacheKey); |
|
|
|
|
|
|
|
if (!EmptyUtil.isEmpty(cacheMap) && |
|
|
|
cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) && |
|
|
|
(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
GlobalConfig.RESPONSE_SUCCESS_CODE || |
|
|
|
cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
'${GlobalConfig.RESPONSE_SUCCESS_CODE}') && |
|
|
|
!EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { |
|
|
|
onCache(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); |
|
|
|
return; |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/// 缓存请求成功的数据 |
|
|
|
static void _setCallBackCacheData(String cacheKey, String value) async { |
|
|
|
SharedPreferencesUtil.setNetCacheResult(cacheKey, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// 根据请求参数,获取缓存的数据 |
|
|
|
static Future<dynamic> getRequestCachedData(String url, |
|
|
|
{Map<String, dynamic> params}) async { |
|
|
|
Map<String, dynamic> cacheMap = |
|
|
|
await SharedPreferencesUtil.getNetCacheResult( |
|
|
|
getRequestParamsCachedKey(params, url)); |
|
|
|
if (!EmptyUtil.isEmpty(cacheMap) && |
|
|
|
cacheMap.containsKey(GlobalConfig.HTTP_RESPONSE_KEY_CODE) && |
|
|
|
(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
GlobalConfig.RESPONSE_SUCCESS_CODE || |
|
|
|
cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
'${GlobalConfig.RESPONSE_SUCCESS_CODE}') && |
|
|
|
!EmptyUtil.isEmpty(cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { |
|
|
|
return cacheMap[GlobalConfig.HTTP_RESPONSE_KEY_DATA]; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
/// 判断后台返回是否成功 |
|
|
|
static bool isSuccess(Map<String, dynamic> data) { |
|
|
|
try { |
|
|
|
if (!EmptyUtil.isEmpty(data) && |
|
|
|
(data[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
GlobalConfig.RESPONSE_SUCCESS_CODE || |
|
|
|
data[GlobalConfig.HTTP_RESPONSE_KEY_CODE] == |
|
|
|
'${GlobalConfig.RESPONSE_SUCCESS_CODE}')) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/// 根据请求参数,获取缓存的Key |
|
|
|
static String getRequestParamsCachedKey( |
|
|
|
Map<String, dynamic> map, String path) { |
|
|
|
if (EmptyUtil.isEmpty(map)) { |
|
|
|
return EncodeUtil.generateMd5(path); |
|
|
|
} |
|
|
|
return EncodeUtil.generateMd5(path + map.toString()); |
|
|
|
} |
|
|
|
|
|
|
|
/// 签名 |
|
|
|
static String signWithArray(List<String> params) { |
|
|
|
// 字母升序 |
|
|
|
params.sort(); |
|
|
|
String result = ""; |
|
|
|
// result += secret_key; |
|
|
|
params.forEach((param) { |
|
|
|
result += param; |
|
|
|
}); |
|
|
|
// result += secret_key; |
|
|
|
return EncodeUtil.generateMd5(result); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* error统一处理 |
|
|
|
*/ |
|
|
|
static void _formatError(DioError e) { |
|
|
|
if (e.type == DioErrorType.CONNECT_TIMEOUT) { |
|
|
|
Logger.error('连接超时: ${e.toString()}'); |
|
|
|
} else if (e.type == DioErrorType.SEND_TIMEOUT) { |
|
|
|
Logger.error('请求超时: ${e.toString()}'); |
|
|
|
} else if (e.type == DioErrorType.RECEIVE_TIMEOUT) { |
|
|
|
Logger.error('响应超时: ${e.toString()}'); |
|
|
|
} else if (e.type == DioErrorType.RESPONSE) { |
|
|
|
Logger.error('出现异常: ${e.toString()}'); |
|
|
|
} else if (e.type == DioErrorType.CANCEL) { |
|
|
|
Logger.error('请求取消: ${e.toString()}'); |
|
|
|
} else { |
|
|
|
Logger.error('未知错误: ${e.toString()}'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @description: 网络请求拦截器 |
|
|
|
* @param {type} |
|
|
|
* @return: |
|
|
|
*/ |
|
|
|
class _NetInterceptors extends InterceptorsWrapper { |
|
|
|
@override |
|
|
|
Future onRequest(RequestOptions options) { |
|
|
|
Logger.net(options?.uri?.toString(), data: options.data.toString()); |
|
|
|
// TODO 加密? |
|
|
|
return super.onRequest(options); |
|
|
|
} |
|
|
|
|
|
|
|
@override |
|
|
|
Future onResponse(Response response) { |
|
|
|
Logger.endNet(response?.request?.uri?.toString(), |
|
|
|
data: response?.data?.toString() ?? ''); |
|
|
|
// TODO 解密? |
|
|
|
return super.onResponse(response); |
|
|
|
} |
|
|
|
|
|
|
|
@override |
|
|
|
Future onError(DioError err) { |
|
|
|
// Logger.error(err); |
|
|
|
return super.onError(err); |
|
|
|
} |
|
|
|
} |