circle_app/circle_app/lib/network/dio_manager.dart
CYH 4840ed65f9 Merge commit 'bd949a21df8d503f94d8f77fd0db7cf5416deae3' into 1.1.1
# Conflicts:
#	circle_app/android/app/build.gradle
#	circle_app/lib/app/circle/view.dart
#	circle_app/lib/app/home/view.dart
#	circle_app/lib/app/minefragment/view.dart
#	circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation.dart
#	circle_app/lib/app/msg/view.dart
#	circle_app/lib/network/dio_manager.dart
2023-08-30 15:52:31 +08:00

379 lines
11 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:convert';
import 'dart:io';
import 'package:circle_app/util/util.dart';
import 'package:dio/dio.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import '../util/SharedPreferencesHelper.dart';
import '../util/device.dart';
import 'api.dart';
import 'package:connectivity/connectivity.dart';
const String baseUrl = Api.baseUrl;
/// Dio 请求方法
enum DioMethod {
get,
post,
put,
delete,
}
class DioManager {
factory DioManager() => getInstance();
static DioManager get instance => getInstance();
static DioManager? _instance;
static DioManager getInstance() {
if (_instance == null) {
_instance = DioManager._init();
}
return _instance!;
}
Dio? _dio;
DioManager._init() {
_dio ??= Dio(BaseOptions(
// 请求基地址
baseUrl: baseUrl,
// 连接服务器超时时间,单位是毫秒
connectTimeout: const Duration(seconds: 300),
// 接收数据的最长时限
receiveTimeout: const Duration(seconds: 300),
));
_dio!.interceptors.add(LogInterceptor(responseBody: true,
));
// _dio!.interceptors.add(ConnectivityInterceptor());
}
Future download(String urlPath,String savePath,ProgressCallback progressCallback)async{
return await _dio!.download(urlPath, savePath, onReceiveProgress : progressCallback);
}
/// get请求
/// [isShowErrorToast] 出现错误的情况是否自动弹窗提示错误默认true
/// [isAddTokenInHeader] 请求头是否添加token
/// [fromJson]是将json转为model的方法
Future get<T>({
required String url,
bool isShowErrorToast = true,
bool isAddTokenInHeader = true,
Map<String, dynamic>? params,
}) async {
return await requestHttp(
url,
method: DioMethod.get,
isShowErrorToast: isShowErrorToast,
params: params,
);
}
/// post 请求
Future post<T>({required String url,
Map<String, dynamic>? params,
bool isAddTokenInHeader = true,
bool isShowErrorToast = true,
FormData? formData,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress}) async {
return await requestHttp<T>(url,
method: DioMethod.post,
isShowErrorToast: isShowErrorToast,
params: params,
formData: formData,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress);
}
/// put 请求
Future put<T>({
required String url,
Map<String, dynamic>? params,
bool isAddTokenInHeader = true,
bool isShowErrorToast = true,
FormData? formData,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
return await requestHttp<T>(
url,
method: DioMethod.put,
// 修改请求方法为 put
isShowErrorToast: isShowErrorToast,
params: params,
formData: formData,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
Future delete<T>({
required String url,
Map<String, dynamic>? params,
bool isAddTokenInHeader = true,
bool isShowErrorToast = true,
FormData? formData,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
return await requestHttp<T>(
url,
method: DioMethod.delete,
// 修改请求方法为 delete
isShowErrorToast: isShowErrorToast,
params: params,
formData: formData,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
/// Dio request 方法
Future requestHttp<T>(String url,
{DioMethod method = DioMethod.get,
Map<String, dynamic>? params,
bool isShowErrorToast = true,
bool isAddTokenInHeader = true,
FormData? formData,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress}) async {
const methodValues = {
DioMethod.get: 'get',
DioMethod.post: 'post',
DioMethod.delete: 'delete',
DioMethod.put: 'put'
};
var connectivityResult = await Connectivity().checkConnectivity();
if(connectivityResult == ConnectivityResult.none){
// showToast("");
return {'code': 404, 'msg': '请检查网络连接是否正常'};
}
try {
Response response;
var options = Options();
bool isAgreemement = await getAgreemement();
if(isAgreemement){
options = Options(
method: methodValues[method], headers: {
"Authorization": await getAuthorization(),
'VersionName': await getVersionName(),
'VersionCode': await getVersionCode(),
'Platform': Platform.isIOS ? '1' : '0',
'OsVersion': await getDeviceId(),
'Imei': await getImei(),
'Brand': await getBrand(),
});
}else{
options = Options(
method: methodValues[method], headers: {
"Authorization": await getAuthorization(),
'VersionName': await getVersionName(),
'VersionCode': await getVersionCode(),
'Platform': Platform.isIOS ? '1' : '0',
});
}
print(">>>>>$params");
/// 不同请求方法,不同的请求参数,按实际项目需求分.
/// 这里 get 是 queryParameters其它用 data. FormData 也是 data
/// 注意: 只有 post 方法支持发送 FormData.
switch (method) {
case DioMethod.get:
response =
await _dio!.request(url, queryParameters: params, options: options);
break;
case DioMethod.post:
response = await _dio!.post(
url, data: params, cancelToken: cancelToken, options: options);
break;
case DioMethod.put:
response = await _dio!.put(url, data: json.encode(params), options: options);
break;
case DioMethod.delete:
response =
await _dio!.delete(url, queryParameters: params, options: options);
break;
default:
// 如果有formData参数说明是传文件忽略params的参数
if (formData != null) {
response = await _dio!.post(url,
data: formData,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress);
} else {
response = await _dio!.request(url,
data: params, cancelToken: cancelToken, options: options);
}
}
// json转model
String jsonStr = json.encode(response.data);
Map<String, dynamic> responseMap = json.decode(jsonStr);
if (responseMap["code"] == 5003 || responseMap["code"] == 30003) {
pushLoginPage();
}
return responseMap;
// switch(responseMap["code"]){
// case 200:
// case 30503:
// return responseMap;
// case 5003:
// pushLoginPage();
// break;
//
// default:
// return {'code': responseMap["code"], 'msg': responseMap["msg"]};
// }
return responseMap;
} on DioException catch (e) {
SharedPreferencesHelper sp = await SharedPreferencesHelper.getInstance();
if (sp.getString(SharedPreferencesHelper.LOGINPHONE) == '18800000100') {
return {'code': 500, 'msg': ''};
}
// // DioError是指返回值不为200的情况
// logger.shout('DioError报错${e.type}:${e.error.toString()}');
// // 对错误进行判断
// onErrorInterceptor(e);
// // 判断是否断网了
// String? errorMsg = isNetworkConnected
// ? e.requestOptions.extra["errorMsg"]
// : "网络连接断开,请检查网络设置";
return {'code': 500, 'msg': '服务器开小差了,请重试'};
} catch (e) {
SharedPreferencesHelper sp = await SharedPreferencesHelper.getInstance();
if (sp.getString(SharedPreferencesHelper.LOGINPHONE) == '18800000100') {
return {'code': 500, 'msg': ''};
}
// 其他一些意外的报错
return {'code': 500, 'msg': '加载中...'};
}
}
//
// // 错误判断
// void onErrorInterceptor(DioError err) {
// // 异常分类
// switch (err.type) {
// // 4xx 5xx response
// case DioErrorType.response:
// err.requestOptions.extra["errorMsg"] = err.response?.data ?? "连接异常";
// break;
// case DioErrorType.connectTimeout:
// err.requestOptions.extra["errorMsg"] = "连接超时";
// break;
// case DioErrorType.sendTimeout:
// err.requestOptions.extra["errorMsg"] = "发送超时";
// break;
// case DioErrorType.receiveTimeout:
// err.requestOptions.extra["errorMsg"] = "接收超时";
// break;
// case DioErrorType.cancel:
// err.requestOptions.extra["errorMsg"] =
// err.message.isNotEmpty ? err.message : "取消连接";
// break;
// case DioErrorType.other:
// default:
// err.requestOptions.extra["errorMsg"] = "连接异常";
// break;
// }
// }
}
class BaseResponse<T> {
int code;
String msg;
dynamic? data;
BaseResponse({required this.code, required this.msg, required this.data});
isSuccess(){
return code==200;
}
factory BaseResponse.fromJson(Map<String, dynamic> json,
T Function(dynamic) fromJsonData) {
dynamic dataJson = json['data'];
T? data;
if (dataJson != null) {
if (dataJson is String) {
// 处理 dataJson 是 String 类型的情况
// 例如,可以直接将其赋值给 data 变量
data = null; // 根据你的需求修改赋值语句
} else if (dataJson is Map<String, dynamic>) {
// 处理 dataJson 是 Map<String, dynamic> 类型的情况
if (fromJsonData != null) {
data = fromJsonData(dataJson);
} else {
throw Exception('未提供 fromJsonData 函数来解析数据。');
}
} else if (dataJson is List) {
data = fromJsonData(dataJson);
}else {
throw Exception('无效的数据格式。期望是 String 或 Map<String, dynamic> 类型。');
}
}
return BaseResponse(
code: json['code'],
msg: json['msg'],
data: data,
);
}
}
class ConnectivityInterceptor extends Interceptor {
@override
Future<void> onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
if (!await isInternetAvailable()) {
showOKToast("请检查网络连接是否正常");
}
return handler.next(options);
}
Future<bool> isInternetAvailable() async {
var connectivityResult = await Connectivity().checkConnectivity();
return connectivityResult != ConnectivityResult.none;
}
}
class QnTokenData {
final String token;
final String cdnPrefix;
QnTokenData({required this.token, required this.cdnPrefix});
factory QnTokenData.fromJson(Map<String, dynamic> json) {
return QnTokenData(
token: json['token'],
cdnPrefix: json['cdn_prefix'],
);
}
}