import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:skywood/global/request/api_const.dart'; import 'package:skywood/utils/tools/sky_device_info.dart'; import 'package:skywood/utils/tools/sky_time_tool.dart'; import 'package:skywood/utils/tools/app_sp.dart'; import 'package:logger/logger.dart'; import '../../utils/tools/token_manage.dart'; import '../tool/sky_encrypt.dart'; /// 网络请求拦截器 class NetworkInterceptor extends Interceptor { final bool enableLog = !kReleaseMode; final Logger _logger = Logger(); @override Future onRequest(RequestOptions options, RequestInterceptorHandler handler) async { // 添加公共请求头 await _addRequestHeaders(options); // 打印请求日志 _logInfo("🔶 REQUEST [${options.method.toUpperCase()}] ${options.uri}"); _logDebug("Headers: ${options.headers}"); if (options.data != null) { _logDebug("Payload: ${options.data}"); } handler.next(options); } @override void onResponse(Response response, ResponseInterceptorHandler handler) { _logInfo("🟢 RESPONSE [${response.statusCode}] ${response.requestOptions.uri}"); // _logDebug("Body: ${response.data}"); // 处理 401 / 402 Token 过期 if (response.statusCode == 401 || response.statusCode == 402) { // 触发 Token 刷新 TokenManager().update(); if (response.statusCode == 402) { _handleError('errorCode:${response.statusCode}', true); } handler.reject(DioException( requestOptions: response.requestOptions, response: response, type: DioExceptionType.badResponse, error: 'errorCode:${response.statusCode}', )); return; } // Release 模式解密响应体 if (kReleaseMode && response.data is String) { try { final deStr = SkyEncrypt.deStr(response.data); response.data = jsonDecode(deStr); } catch (e) { _logError("解密失败: $e"); } } handler.next(response); } @override void onError(DioException err, ErrorInterceptorHandler handler) { _logError("🔴 Error: ${err.message}"); handler.next(err); } // ============ 私有方法 ============ Future _addRequestHeaders(RequestOptions options) async { // 开发模式添加 security: false if (!kReleaseMode) { options.headers['security'] = 'false'; } // 注入 Token final tokenManager = TokenManager(); final token = tokenManager.get(); // print('查看token: $token'); if (token.isNotEmpty) { options.headers['Authorization'] = 'Bearer $token'; } // 其他公共参数 String langKey = await AppSp().getString('GLIMZO_STORE_LANGKEY') ?? 'en'; final deviceInfo = SkyDeviceInfo.instance; options.headers.addAll({ 'product-prefix': 'glimzo', 'device-id': deviceInfo.deviceId, 'system-type': deviceInfo.systemType, 'model': deviceInfo.model, 'system-version': deviceInfo.systemVersion, 'brand': deviceInfo.brand, 'app-version': deviceInfo.appVersion, 'app-name': deviceInfo.appName, 'lang-key': langKey, 'time-zone': SkyTimeTool.getTimeZone(), 'idfa': '', 'idfv': deviceInfo.idfv, 'device-gaid': '', }); // 处理 prevToken(从请求体中提取) await _handleOldToken(options); } Future _handleOldToken(RequestOptions options) async { try { if (options.data is Map) { final body = options.data as Map; final prevToken = body['prevToken']; if (prevToken != null && prevToken.toString().isNotEmpty) { options.headers['Authorization'] = prevToken.toString(); } } } catch (_) { // 非 JSON 请求跳过 } } void _logInfo(String message) { if (enableLog) _logger.i(message); } void _logDebug(String message) { if (enableLog) _logger.d('💡 $message'); } void _logError(String message) { if (enableLog) _logger.e(message); } void _handleError(dynamic e, bool error) { _logError("🔴 Error: $e"); // 这里可以根据需要处理错误提示 } }