152 lines
5.9 KiB
Dart
152 lines
5.9 KiB
Dart
import 'dart:convert';
|
||
import 'package:get/get.dart' as Get;
|
||
import 'package:dio/dio.dart';
|
||
import 'package:sk_base_mobile/models/base_response.dart';
|
||
import 'package:sk_base_mobile/util/logger_util.dart';
|
||
import 'package:sk_base_mobile/config.dart';
|
||
import 'package:sk_base_mobile/services/storage.service.dart';
|
||
import 'package:sk_base_mobile/store/auth.store.dart';
|
||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||
|
||
import '../constants/constants.dart';
|
||
|
||
class DioService extends Get.GetxService {
|
||
static DioService get to => Get.Get.find();
|
||
static Dio get dio => _dio;
|
||
static late Dio _dio;
|
||
List<String> whiteList = [Urls.login];
|
||
BaseOptions dioBaseOptions = BaseOptions(
|
||
connectTimeout: const Duration(seconds: 20),
|
||
baseUrl: '${GloablConfig.BASE_URL}',
|
||
followRedirects: true);
|
||
|
||
late CancelToken cancelToken;
|
||
|
||
/// Initialize the dio instance
|
||
Future<DioService> init() async {
|
||
_dio = Dio(dioBaseOptions);
|
||
_dio.interceptors.add(InterceptorsWrapper(
|
||
onRequest: onRequest, onResponse: onResponse, onError: onError));
|
||
cancelToken = CancelToken();
|
||
return this;
|
||
}
|
||
|
||
void onError(DioException e, ErrorInterceptorHandler handler) async {
|
||
if (whiteList.contains(e.requestOptions.path)) {
|
||
return handler.next(e);
|
||
}
|
||
if (GloablConfig.DEBUG) {
|
||
LoggerUtil().info(
|
||
"[Service-dio] Error found on ${e.requestOptions.method} ${e.requestOptions.uri}");
|
||
}
|
||
if (e.type == DioExceptionType.connectionTimeout) {
|
||
// It occurs when url is opened timeout.
|
||
await SnackBarUtil().error(TextEnum.serverErrorMsg);
|
||
} else if (e.type == DioExceptionType.connectionError) {
|
||
// It occurs when url is opened timeout.
|
||
await SnackBarUtil().error(TextEnum.serverErrorMsg);
|
||
} else if (e.type == DioExceptionType.sendTimeout) {
|
||
// It occurs when url is sent timeout.
|
||
// await SnackBarUtil().error(
|
||
// 'The server is busy, please try again.',
|
||
// );
|
||
} else if (e.type == DioExceptionType.receiveTimeout) {
|
||
//It occurs when receiving timeout
|
||
// await SnackBarUtil().error(
|
||
// 'The server is busy, please try again.',
|
||
// );
|
||
} else if (e.type == DioErrorType.badResponse) {
|
||
// When the server response, but with a incorrect status, such as 404, 503...
|
||
if (e.response?.statusCode == 400) {
|
||
await SnackBarUtil().error(
|
||
e.response?.data['message'],
|
||
);
|
||
} else if (e.response?.statusCode == 401) {
|
||
await SnackBarUtil().error('请重新登录');
|
||
// dio.lock();
|
||
LoggerUtil().error('[Service-dio] logout:${e.response}');
|
||
await AuthStore().logout(force: true);
|
||
} else if (e.response?.statusCode == 403) {
|
||
await SnackBarUtil().error(
|
||
'${e.response?.data['message']}.',
|
||
);
|
||
// await AuthStore().logout(force: true);
|
||
} else if (e.response?.statusCode == 409) {
|
||
await SnackBarUtil().error(e.response?.data['message']);
|
||
} else if (e.response?.statusCode == 500) {
|
||
await SnackBarUtil()
|
||
.error('The server is busy, please try again later');
|
||
} else if (e.response?.statusCode == 404) {
|
||
LoggerUtil().error('[Service-dio] logout:${e.response}');
|
||
// await AuthStore().logout(force: true);
|
||
} else if (e.response?.statusCode == 422) {
|
||
await SnackBarUtil().error(e.response?.data['message']);
|
||
}
|
||
} else if (e.type == DioErrorType.cancel) {
|
||
// When the request is cancelled, dio will throw a error with this type.
|
||
LoggerUtil().error("[Service-dio] 请求取消");
|
||
} else {
|
||
//DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
|
||
LoggerUtil().error("[Service-dio] 未知错误:$e");
|
||
if ((e.error?.toString() ?? '')
|
||
.toString()
|
||
.contains("HandshakeException")) {
|
||
// Just a network failure
|
||
} else {
|
||
await SnackBarUtil().error(e.error.toString());
|
||
// AuthStore().logout(force: true);
|
||
}
|
||
}
|
||
return handler.next(e);
|
||
}
|
||
|
||
whiteListFilter(String url) => url.endsWith('_allow_anonymous=true');
|
||
|
||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||
if (!whiteList.contains(options.path)) {
|
||
String? token =
|
||
StorageService.to.getString(CacheKeys.token, isWithUser: false);
|
||
if (options.headers['Authorization'] == null && token != null) {
|
||
options.headers["Authorization"] = "Bearer $token";
|
||
}
|
||
options.headers['device-id'] = StorageService.to.getString(
|
||
CacheKeys.deviceUUID,
|
||
isWithUser: false); // 设备id或者udid,保证当前设备唯一值。
|
||
options.headers["platform"] = "iOS";
|
||
options.headers['model'] = StorageService.to
|
||
.getString(CacheKeys.deviceModel, isWithUser: false); // 设备型号
|
||
}
|
||
if (GloablConfig.DEBUG && (options.data is! FormData)) {
|
||
LoggerUtil().info('[Service-dio] url: ${options.path}' +
|
||
', params: ${jsonEncode(options.queryParameters)}' +
|
||
', body: ${jsonEncode(options.data)}, Header:${jsonEncode(options.headers)}');
|
||
}
|
||
|
||
handler.next(options);
|
||
}
|
||
|
||
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
||
/* LoggerUtil().info('[Service-dio] ${response.data}'); */
|
||
if (whiteList.contains(response.requestOptions.path)) {
|
||
handler.next(response);
|
||
return;
|
||
}
|
||
if (response.data != null) {
|
||
if (response.data['code'] == 200) {
|
||
if (GloablConfig.DEBUG) LoggerUtil().info(response.data['data']);
|
||
response.data = response.data['data'];
|
||
// 分页数据处理
|
||
if (response.data != null &&
|
||
response.data is Map &&
|
||
response.data['meta'] != null &&
|
||
response.data['items'] != null) {
|
||
response.data = PaginationData.fromJson(response.data);
|
||
}
|
||
} else {
|
||
await SnackBarUtil().error(response.data['message']);
|
||
}
|
||
}
|
||
handler.next(response);
|
||
}
|
||
}
|