2022-06-27 09:51:30 +08:00
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
import 'package:dio/adapter.dart';
|
|
|
|
|
import 'package:dio/dio.dart';
|
|
|
|
|
import 'package:package_info/package_info.dart';
|
|
|
|
|
|
|
|
|
|
import 'log_interceptor.dart';
|
|
|
|
|
|
|
|
|
|
export 'http_helper.dart';
|
|
|
|
|
|
|
|
|
|
class DioUtils {
|
|
|
|
|
Dio _dio;
|
|
|
|
|
|
|
|
|
|
// 工厂模式
|
|
|
|
|
factory DioUtils() => _getInstance();
|
|
|
|
|
|
|
|
|
|
static DioUtils get instance => _getInstance();
|
|
|
|
|
static DioUtils _instance;
|
|
|
|
|
|
|
|
|
|
//配置代理标识 false 不配置
|
|
|
|
|
bool isProxy = false;
|
|
|
|
|
|
|
|
|
|
//网络代理地址
|
2022-06-30 17:01:04 +08:00
|
|
|
|
String proxyIp = "10.0.2.2";
|
2022-06-27 09:51:30 +08:00
|
|
|
|
|
|
|
|
|
//网络代理端口
|
2022-06-30 17:01:04 +08:00
|
|
|
|
String proxyPort = "7890";
|
2022-06-27 09:51:30 +08:00
|
|
|
|
|
|
|
|
|
DioUtils._internal() {
|
|
|
|
|
BaseOptions options = new BaseOptions();
|
|
|
|
|
//请求时间
|
|
|
|
|
options.connectTimeout = 20000;
|
|
|
|
|
options.receiveTimeout = 2 * 60 * 1000;
|
|
|
|
|
options.sendTimeout = 2 * 60 * 1000;
|
|
|
|
|
// 初始化
|
|
|
|
|
_dio = new Dio(options);
|
|
|
|
|
//当App运行在Release环境时,inProduction为true;
|
|
|
|
|
// 当App运行在Debug和Profile环境时,inProduction为false。
|
|
|
|
|
bool inProduction = bool.fromEnvironment("dart.vm.product");
|
|
|
|
|
if (!inProduction) {
|
|
|
|
|
debugFunction();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static DioUtils _getInstance() {
|
|
|
|
|
_instance ??= DioUtils._internal();
|
|
|
|
|
return _instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void debugFunction() {
|
|
|
|
|
// 添加log
|
|
|
|
|
_dio.interceptors.add(LogsInterceptors());
|
|
|
|
|
//配置代理
|
|
|
|
|
if (isProxy) {
|
|
|
|
|
_setupPROXY();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 配置代理
|
|
|
|
|
void _setupPROXY() {
|
|
|
|
|
(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
|
|
|
|
|
(HttpClient client) {
|
|
|
|
|
client.findProxy = (uri) {
|
|
|
|
|
//proxyIp 地址 proxyPort 端口
|
|
|
|
|
return 'PROXY $proxyIp : $proxyPort';
|
|
|
|
|
};
|
|
|
|
|
client.badCertificateCallback =
|
|
|
|
|
(X509Certificate cert, String host, int port) {
|
|
|
|
|
//忽略证书
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// get 请求
|
|
|
|
|
///[url]请求链接
|
|
|
|
|
///[queryParameters]请求参数
|
|
|
|
|
///[cancelTag] 取消网络请求的标识
|
|
|
|
|
Future<ResponseInfo> getRequest({
|
|
|
|
|
String url,
|
|
|
|
|
Map<String, dynamic> queryParameters,
|
|
|
|
|
CancelToken cancelTag,
|
|
|
|
|
}) async {
|
|
|
|
|
//发起get请求
|
|
|
|
|
try {
|
|
|
|
|
_dio.options = await buildOptions(_dio.options);
|
|
|
|
|
_dio.options.headers["content-type"] = "application/json";
|
|
|
|
|
Response response = await _dio.get(url,
|
|
|
|
|
queryParameters: queryParameters, cancelToken: cancelTag);
|
|
|
|
|
//响应数据
|
|
|
|
|
dynamic responseData = response.data;
|
|
|
|
|
//数据解析
|
|
|
|
|
if (responseData is Map<String, dynamic>) {
|
|
|
|
|
//转换
|
|
|
|
|
Map<String, dynamic> responseMap = responseData;
|
|
|
|
|
//
|
|
|
|
|
int code = responseMap["code"];
|
|
|
|
|
if (code == 200) {
|
|
|
|
|
//业务代码处理正常
|
|
|
|
|
//获取数据
|
|
|
|
|
dynamic data = responseMap["data"];
|
|
|
|
|
return ResponseInfo(data: data);
|
|
|
|
|
} else {
|
|
|
|
|
//业务代码异常
|
|
|
|
|
return ResponseInfo.error(
|
|
|
|
|
code: responseMap["code"], message: responseMap["message"]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return ResponseInfo.error(code: 503, message: "数据格式无法识别");
|
|
|
|
|
}
|
|
|
|
|
} catch (e, s) {
|
|
|
|
|
//异常
|
|
|
|
|
return errorController(e, s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// post 请求
|
|
|
|
|
///[url]请求链接
|
|
|
|
|
///[formDataMap]formData 请求参数
|
|
|
|
|
///[jsonMap] JSON 格式
|
|
|
|
|
Future<ResponseInfo> postRequest({
|
|
|
|
|
String url,
|
|
|
|
|
Map<String, dynamic> formDataMap,
|
|
|
|
|
Map<String, dynamic> jsonMap,
|
|
|
|
|
CancelToken cancelTag,
|
|
|
|
|
}) async {
|
|
|
|
|
FormData form;
|
|
|
|
|
if (formDataMap != null) {
|
|
|
|
|
form = FormData.fromMap(formDataMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dio.options = await buildOptions(_dio.options);
|
|
|
|
|
_dio.options.headers["content-type"] = "application/json";
|
|
|
|
|
|
|
|
|
|
// _dio.options.headers["content-type"]="multipart/form-data";
|
|
|
|
|
//发起post请求
|
|
|
|
|
try {
|
2022-06-30 17:01:04 +08:00
|
|
|
|
Response response =
|
|
|
|
|
await _dio.post(url, data: form ?? jsonMap, cancelToken: cancelTag);
|
2022-06-27 09:51:30 +08:00
|
|
|
|
//响应数据
|
|
|
|
|
dynamic responseData = response.data;
|
|
|
|
|
|
|
|
|
|
if (responseData is Map<String, dynamic>) {
|
|
|
|
|
Map<String, dynamic> responseMap = responseData;
|
|
|
|
|
int code = responseMap["code"];
|
|
|
|
|
if (code == 200) {
|
|
|
|
|
//业务代码处理正常
|
|
|
|
|
//获取数据
|
|
|
|
|
dynamic data = responseMap["data"];
|
|
|
|
|
return ResponseInfo(data: data);
|
|
|
|
|
} else {
|
|
|
|
|
//业务代码异常
|
|
|
|
|
return ResponseInfo.error(
|
|
|
|
|
code: responseMap["code"], message: responseMap["message"]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return ResponseInfo.error(code: 503, message: "数据格式无法识别");
|
|
|
|
|
}
|
|
|
|
|
} catch (e, s) {
|
|
|
|
|
return errorController(e, s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<ResponseInfo> errorController(e, StackTrace s) {
|
|
|
|
|
ResponseInfo responseInfo = ResponseInfo();
|
|
|
|
|
responseInfo.success = false;
|
|
|
|
|
|
|
|
|
|
//网络处理错误
|
|
|
|
|
if (e is DioError) {
|
|
|
|
|
DioError dioError = e;
|
|
|
|
|
switch (dioError.type) {
|
|
|
|
|
case DioErrorType.connectTimeout:
|
|
|
|
|
responseInfo.message = "连接超时";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.sendTimeout:
|
|
|
|
|
responseInfo.message = "请求超时";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.receiveTimeout:
|
|
|
|
|
responseInfo.message = "响应超时";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.response:
|
|
|
|
|
// 响应错误
|
|
|
|
|
responseInfo.message = "响应错误";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.cancel:
|
|
|
|
|
// 取消操作
|
|
|
|
|
responseInfo.message = "已取消";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.other:
|
|
|
|
|
// 默认自定义其他异常
|
|
|
|
|
responseInfo.message = "网络请求异常";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//其他错误
|
|
|
|
|
responseInfo.message = "未知错误";
|
|
|
|
|
}
|
|
|
|
|
responseInfo.success = false;
|
|
|
|
|
return Future.value(responseInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<LoginInfo> loginRequest({
|
|
|
|
|
String url,
|
|
|
|
|
Map<String, dynamic> formDataMap,
|
|
|
|
|
Map<String, dynamic> jsonMap,
|
|
|
|
|
CancelToken cancelTag,
|
|
|
|
|
}) async {
|
|
|
|
|
FormData form;
|
|
|
|
|
if (formDataMap != null) {
|
|
|
|
|
form = FormData.fromMap(formDataMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dio.options = await buildOptions(_dio.options);
|
|
|
|
|
_dio.options.headers["content-type"] = "application/json";
|
|
|
|
|
|
|
|
|
|
// _dio.options.headers["content-type"]="multipart/form-data";
|
|
|
|
|
//发起post请求
|
|
|
|
|
try {
|
2022-06-30 17:01:04 +08:00
|
|
|
|
Response response =
|
|
|
|
|
await _dio.post(url, data: form ?? jsonMap, cancelToken: cancelTag);
|
2022-06-27 09:51:30 +08:00
|
|
|
|
//响应数据
|
|
|
|
|
dynamic responseData = response.data;
|
|
|
|
|
|
|
|
|
|
if (responseData is Map<String, dynamic>) {
|
|
|
|
|
Map<String, dynamic> responseMap = responseData;
|
|
|
|
|
int code = responseMap["code"];
|
|
|
|
|
if (code == 200) {
|
|
|
|
|
//业务代码处理正常
|
|
|
|
|
//获取数据
|
|
|
|
|
dynamic token = responseMap["token"];
|
|
|
|
|
return LoginInfo(token: token);
|
|
|
|
|
} else {
|
|
|
|
|
//业务代码异常
|
|
|
|
|
return LoginInfo.error(
|
2022-06-28 16:56:03 +08:00
|
|
|
|
code: responseMap["code"], msg: responseMap["msg"]);
|
2022-06-27 09:51:30 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return LoginInfo.error(code: 503, msg: "数据格式无法识别");
|
|
|
|
|
}
|
|
|
|
|
} catch (e, s) {
|
|
|
|
|
return errorCtl(e, s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<LoginInfo> errorCtl(e, StackTrace s) {
|
|
|
|
|
LoginInfo loginInfo = LoginInfo();
|
|
|
|
|
loginInfo.success = false;
|
|
|
|
|
|
|
|
|
|
//网络处理错误
|
|
|
|
|
if (e is DioError) {
|
|
|
|
|
DioError dioError = e;
|
|
|
|
|
switch (dioError.type) {
|
|
|
|
|
case DioErrorType.connectTimeout:
|
|
|
|
|
loginInfo.msg = "连接超时";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.sendTimeout:
|
|
|
|
|
loginInfo.msg = "请求超时";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.receiveTimeout:
|
|
|
|
|
loginInfo.msg = "响应超时";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.response:
|
2022-06-30 17:01:04 +08:00
|
|
|
|
// 响应错误
|
2022-06-27 09:51:30 +08:00
|
|
|
|
loginInfo.msg = "响应错误";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.cancel:
|
2022-06-30 17:01:04 +08:00
|
|
|
|
// 取消操作
|
2022-06-27 09:51:30 +08:00
|
|
|
|
loginInfo.msg = "已取消";
|
|
|
|
|
break;
|
|
|
|
|
case DioErrorType.other:
|
2022-06-30 17:01:04 +08:00
|
|
|
|
// 默认自定义其他异常
|
2022-06-27 09:51:30 +08:00
|
|
|
|
loginInfo.msg = "网络请求异常";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//其他错误
|
|
|
|
|
loginInfo.msg = "未知错误";
|
|
|
|
|
}
|
|
|
|
|
loginInfo.success = false;
|
|
|
|
|
return Future.value(loginInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<BaseOptions> buildOptions(BaseOptions options) async {
|
|
|
|
|
///请求header的配置
|
|
|
|
|
options.headers["productId"] = Platform.isAndroid ? "Android" : "IOS";
|
|
|
|
|
options.headers["application"] = "coalx";
|
|
|
|
|
|
|
|
|
|
//获取当前App的版本信息
|
|
|
|
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
|
|
|
|
String appName = packageInfo.appName;
|
|
|
|
|
String packageName = packageInfo.packageName;
|
|
|
|
|
String version = packageInfo.version;
|
|
|
|
|
String buildNumber = packageInfo.buildNumber;
|
|
|
|
|
options.headers["appVersion"] = "$version";
|
|
|
|
|
|
|
|
|
|
return Future.value(options);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ResponseInfo {
|
|
|
|
|
bool success;
|
|
|
|
|
int code;
|
|
|
|
|
String message;
|
|
|
|
|
dynamic data;
|
|
|
|
|
|
|
|
|
|
ResponseInfo(
|
|
|
|
|
{this.success = true, this.code = 200, this.data, this.message = "请求成功"});
|
|
|
|
|
|
|
|
|
|
ResponseInfo.error(
|
|
|
|
|
{this.success = false, this.code = 201, this.message = "请求异常"});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class LoginInfo {
|
|
|
|
|
bool success;
|
|
|
|
|
int code;
|
|
|
|
|
String msg;
|
|
|
|
|
String token;
|
|
|
|
|
|
2022-06-30 17:01:04 +08:00
|
|
|
|
LoginInfo(
|
|
|
|
|
{this.success = true, this.code = 200, this.token, this.msg = "登陆成功"});
|
|
|
|
|
|
|
|
|
|
LoginInfo.error({this.success = false, this.code = 201, this.msg = "请求异常"});
|
2022-06-27 09:51:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class RegisterInfo {
|
|
|
|
|
bool success;
|
|
|
|
|
int code;
|
|
|
|
|
String msg;
|
|
|
|
|
|
2022-06-30 17:01:04 +08:00
|
|
|
|
RegisterInfo({this.success = true, this.code = 200, this.msg = "注册成功"});
|
2022-06-27 09:51:30 +08:00
|
|
|
|
|
2022-06-30 17:01:04 +08:00
|
|
|
|
RegisterInfo.error(
|
|
|
|
|
{this.success = false, this.code = 201, this.msg = "请求异常"});
|
2022-06-27 09:51:30 +08:00
|
|
|
|
}
|