You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.8 KiB
162 lines
4.8 KiB
import 'package:dio/dio.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart' hide Response;
|
|
import 'dart:convert';
|
|
import 'package:crypto/crypto.dart';
|
|
|
|
import 'package:get_storage/get_storage.dart';
|
|
import 'entity/base_entity.dart';
|
|
|
|
class AuthInterceptor extends Interceptor {
|
|
final GetStorage _storage = GetStorage();
|
|
final String _signKey = '@214%67g15q4*67m17#4l67!'; // 替换为实际的密钥
|
|
|
|
bool _shouldSuppressErrorSnackbar(DioException err) {
|
|
final path = err.requestOptions.path;
|
|
return path == '/api/home/user_getinfo';
|
|
}
|
|
|
|
bool _shouldSuppressBusinessErrorSnackbar(RequestOptions options) {
|
|
final path = options.path;
|
|
return path == '/api/home/user_getinfo';
|
|
}
|
|
|
|
String _mapBadResponseMessage(DioException err) {
|
|
final statusCode = err.response?.statusCode;
|
|
final statusMessage = (err.response?.statusMessage ?? '').toLowerCase();
|
|
|
|
if (statusCode == 401 || statusCode == 403) {
|
|
return 'loginExpiredPleaseRelogin'.tr;
|
|
}
|
|
|
|
if (statusCode == 404 || statusMessage.contains('record not found')) {
|
|
return 'requestedResourceNotFound'.tr;
|
|
}
|
|
|
|
if (statusCode != null && statusCode >= 500) {
|
|
return 'serverTemporarilyUnavailable'.tr;
|
|
}
|
|
|
|
return 'unknownError'.tr;
|
|
}
|
|
|
|
@override
|
|
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
|
var jsonString = _storage.read<String>("logintoken");
|
|
options.headers['Authorization'] = jsonString;
|
|
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
|
|
options.headers['Ts'] = timestamp;
|
|
options.headers['Sign'] = _generateSign(timestamp);
|
|
handler.next(options);
|
|
}
|
|
|
|
String _generateSign(String timestamp) {
|
|
// 按照“MD5(私钥 + 时间戳)”生成签名,与 Go 端保持一致
|
|
final signStr = 'ts=${timestamp}key=${_signKey}';
|
|
print("signStr: $signStr");
|
|
return md5.convert(utf8.encode(signStr)).toString();
|
|
}
|
|
|
|
@override
|
|
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
|
BaseEntity entity = BaseEntity.fromJson(response.data);
|
|
if (entity.code == 0) {
|
|
response.data = entity.data ?? {};
|
|
handler.resolve(response);
|
|
} else {
|
|
response.data = null;
|
|
handler.next(response);
|
|
|
|
if (_shouldSuppressBusinessErrorSnackbar(response.requestOptions)) {
|
|
return;
|
|
}
|
|
|
|
final rawMessage = entity.message ?? '';
|
|
final lowerMessage = rawMessage.toLowerCase();
|
|
final displayMessage = lowerMessage.contains('record not found')
|
|
? 'requestedResourceNotFound'.tr
|
|
: (entity.message ?? 'unknownError'.tr);
|
|
|
|
Get.snackbar(
|
|
'error'.tr, // 错误
|
|
displayMessage,
|
|
snackPosition: SnackPosition.TOP,
|
|
backgroundColor: Colors.red.withOpacity(0.1),
|
|
colorText: Colors.red,
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void onError(DioException err, ErrorInterceptorHandler handler) {
|
|
switch (err.type) {
|
|
case DioExceptionType.cancel:
|
|
{
|
|
Get.snackbar(
|
|
'error'.tr, // 错误
|
|
'requestCancellation'.tr,
|
|
snackPosition: SnackPosition.TOP,
|
|
backgroundColor: Colors.red.withOpacity(0.1),
|
|
colorText: Colors.red,
|
|
);
|
|
}
|
|
case DioExceptionType.connectionTimeout:
|
|
{
|
|
Get.snackbar(
|
|
'error'.tr, // 错误
|
|
'connectionTimeout'.tr,
|
|
snackPosition: SnackPosition.TOP,
|
|
backgroundColor: Colors.red.withOpacity(0.1),
|
|
colorText: Colors.red,
|
|
);
|
|
}
|
|
case DioExceptionType.sendTimeout:
|
|
{
|
|
Get.snackbar(
|
|
'error'.tr, // 错误
|
|
'requestTimeout'.tr,
|
|
snackPosition: SnackPosition.TOP,
|
|
backgroundColor: Colors.red.withOpacity(0.1),
|
|
colorText: Colors.red,
|
|
);
|
|
}
|
|
case DioExceptionType.receiveTimeout:
|
|
{
|
|
Get.snackbar(
|
|
'error'.tr, // 错误
|
|
'responseTimeout'.tr,
|
|
snackPosition: SnackPosition.TOP,
|
|
backgroundColor: Colors.red.withOpacity(0.1),
|
|
colorText: Colors.red,
|
|
);
|
|
}
|
|
case DioExceptionType.badResponse:
|
|
{
|
|
if (_shouldSuppressErrorSnackbar(err)) {
|
|
handler.next(err);
|
|
return;
|
|
}
|
|
|
|
Get.snackbar(
|
|
'error'.tr, // 错误
|
|
_mapBadResponseMessage(err),
|
|
snackPosition: SnackPosition.TOP,
|
|
backgroundColor: Colors.red.withOpacity(0.1),
|
|
colorText: Colors.red,
|
|
);
|
|
}
|
|
default:
|
|
{
|
|
Get.snackbar(
|
|
'error'.tr, // 错误
|
|
err.message ?? 'unknownError'.tr,
|
|
snackPosition: SnackPosition.TOP,
|
|
backgroundColor: Colors.red.withOpacity(0.1),
|
|
colorText: Colors.red,
|
|
);
|
|
}
|
|
}
|
|
handler.next(err);
|
|
}
|
|
}
|
|
|