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("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); } }