refactor: 优化日志输出,仅在调试模式下启用
- 为所有 print 语句添加 kDebugMode 检查 - 更新 KRLogUtil 工具类,Release 模式下禁用日志输出 - 优化 18 个文件中的 335+ 条日志语句 - 提升 Release 版本性能并增强安全性 (cherry picked from commit 301f1510ba81fe94fb08e013ca80b3ca708a2e15)
This commit is contained in:
parent
b3ee1cc6dc
commit
4c5763647d
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../response/kr_node_list.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// 表示出站项的模型类
|
||||
class KROutboundItem {
|
||||
@ -50,14 +51,18 @@ class KROutboundItem {
|
||||
// 🔧 优先使用直接字段构建配置(新API格式)
|
||||
// 判断条件:如果有 port 和 serverAddr,说明是新格式
|
||||
if (nodeListItem.port > 0 && nodeListItem.serverAddr.isNotEmpty) {
|
||||
print('ℹ️ 节点 ${nodeListItem.name} 使用直接字段构建配置');
|
||||
if (kDebugMode) {
|
||||
print('ℹ️ 节点 ${nodeListItem.name} 使用直接字段构建配置');
|
||||
}
|
||||
_buildConfigFromFields(nodeListItem);
|
||||
return;
|
||||
}
|
||||
|
||||
// 兜底:尝试解析 config 字段(旧API格式)
|
||||
if (nodeListItem.config.isEmpty) {
|
||||
print('❌ 节点 ${nodeListItem.name} 缺少配置信息(无port或config)');
|
||||
if (kDebugMode) {
|
||||
print('❌ 节点 ${nodeListItem.name} 缺少配置信息(无port或config)');
|
||||
}
|
||||
config = {};
|
||||
return;
|
||||
}
|
||||
@ -66,8 +71,12 @@ class KROutboundItem {
|
||||
try {
|
||||
json = jsonDecode(nodeListItem.config) as Map<String, dynamic>;
|
||||
} catch (e) {
|
||||
print('❌ 节点 ${nodeListItem.name} 的 config 解析失败: $e,尝试使用直接字段');
|
||||
print('📄 Config 内容: ${nodeListItem.config}');
|
||||
if (kDebugMode) {
|
||||
print('❌ 节点 ${nodeListItem.name} 的 config 解析失败: $e,尝试使用直接字段');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 Config 内容: ${nodeListItem.config}');
|
||||
}
|
||||
_buildConfigFromFields(nodeListItem);
|
||||
return;
|
||||
}
|
||||
@ -237,14 +246,30 @@ class KROutboundItem {
|
||||
|
||||
/// 直接从节点字段构建配置(新API格式)
|
||||
void _buildConfigFromFields(KrNodeListItem nodeListItem) {
|
||||
print('🔧 开始构建节点配置 - 协议: ${nodeListItem.protocol}, 名称: ${nodeListItem.name}');
|
||||
print('📋 节点详细信息:');
|
||||
print(' - serverAddr: ${nodeListItem.serverAddr}');
|
||||
print(' - port: ${nodeListItem.port}');
|
||||
print(' - uuid: ${nodeListItem.uuid}');
|
||||
print(' - method: ${nodeListItem.method}');
|
||||
print(' - config: ${nodeListItem.config}');
|
||||
print(' - protocols: ${nodeListItem.protocols}');
|
||||
if (kDebugMode) {
|
||||
print('🔧 开始构建节点配置 - 协议: ${nodeListItem.protocol}, 名称: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📋 节点详细信息:');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - serverAddr: ${nodeListItem.serverAddr}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - port: ${nodeListItem.port}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - uuid: ${nodeListItem.uuid}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - method: ${nodeListItem.method}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - config: ${nodeListItem.config}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - protocols: ${nodeListItem.protocols}');
|
||||
}
|
||||
|
||||
// 🔧 尝试从 config 字段解析 transport 配置
|
||||
Map<String, dynamic>? transportConfig;
|
||||
@ -254,7 +279,9 @@ class KROutboundItem {
|
||||
if (nodeListItem.protocols.isNotEmpty) {
|
||||
try {
|
||||
final protocolsList = jsonDecode(nodeListItem.protocols) as List;
|
||||
print('📄 解析到 protocols 数组,共 ${protocolsList.length} 个协议');
|
||||
if (kDebugMode) {
|
||||
print('📄 解析到 protocols 数组,共 ${protocolsList.length} 个协议');
|
||||
}
|
||||
|
||||
// 查找匹配当前协议类型的配置
|
||||
Map<String, dynamic>? matchedProtocol;
|
||||
@ -263,14 +290,18 @@ class KROutboundItem {
|
||||
final type = protocolMap['type']?.toString().toLowerCase() ?? '';
|
||||
final enable = protocolMap['enable'] ?? true;
|
||||
|
||||
print(' 📋 协议: type=$type, enable=$enable');
|
||||
if (kDebugMode) {
|
||||
print(' 📋 协议: type=$type, enable=$enable');
|
||||
}
|
||||
|
||||
// 匹配协议类型(注意 hysteria 和 hysteria2 都匹配 hysteria)
|
||||
if (type == nodeListItem.protocol.toLowerCase() ||
|
||||
(nodeListItem.protocol == 'hysteria' && type == 'hysteria2') ||
|
||||
(nodeListItem.protocol == 'hysteria2' && type == 'hysteria')) {
|
||||
matchedProtocol = protocolMap;
|
||||
print(' ✅ 找到匹配的协议配置: $type');
|
||||
if (kDebugMode) {
|
||||
print(' ✅ 找到匹配的协议配置: $type');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -279,7 +310,9 @@ class KROutboundItem {
|
||||
// 提取 transport 配置
|
||||
if (matchedProtocol['network'] != null || matchedProtocol['transport'] != null) {
|
||||
final network = matchedProtocol['network'] ?? matchedProtocol['transport'];
|
||||
print(' 📡 传输协议: $network');
|
||||
if (kDebugMode) {
|
||||
print(' 📡 传输协议: $network');
|
||||
}
|
||||
|
||||
if (network == 'ws' || network == 'websocket') {
|
||||
transportConfig = {
|
||||
@ -290,20 +323,26 @@ class KROutboundItem {
|
||||
if (host != null && host.toString().isNotEmpty) {
|
||||
transportConfig['headers'] = {'Host': host.toString()};
|
||||
}
|
||||
print(' ✅ WebSocket transport: $transportConfig');
|
||||
if (kDebugMode) {
|
||||
print(' ✅ WebSocket transport: $transportConfig');
|
||||
}
|
||||
} else if (network == 'grpc') {
|
||||
transportConfig = {
|
||||
'type': 'grpc',
|
||||
'service_name': matchedProtocol['grpc_service_name'] ?? matchedProtocol['service_name'] ?? '',
|
||||
};
|
||||
print(' ✅ gRPC transport: $transportConfig');
|
||||
if (kDebugMode) {
|
||||
print(' ✅ gRPC transport: $transportConfig');
|
||||
}
|
||||
} else if (network == 'http' || network == 'h2') {
|
||||
transportConfig = {
|
||||
'type': 'http',
|
||||
'host': [matchedProtocol['http_host'] ?? matchedProtocol['host'] ?? ''],
|
||||
'path': matchedProtocol['http_path'] ?? matchedProtocol['path'] ?? '/',
|
||||
};
|
||||
print(' ✅ HTTP transport: $transportConfig');
|
||||
if (kDebugMode) {
|
||||
print(' ✅ HTTP transport: $transportConfig');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,11 +358,15 @@ class KROutboundItem {
|
||||
'allow_insecure': matchedProtocol['allow_insecure'] ?? matchedProtocol['insecure'] ?? true,
|
||||
'fingerprint': matchedProtocol['fingerprint'] ?? 'chrome',
|
||||
};
|
||||
print(' ✅ Security config: security=$security, tls_enabled=$tlsEnabled, config=$securityConfig');
|
||||
if (kDebugMode) {
|
||||
print(' ✅ Security config: security=$security, tls_enabled=$tlsEnabled, config=$securityConfig');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('⚠️ 解析 protocols 字段失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('⚠️ 解析 protocols 字段失败: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,21 +374,29 @@ class KROutboundItem {
|
||||
if (transportConfig == null && nodeListItem.config.isNotEmpty) {
|
||||
try {
|
||||
final configJson = jsonDecode(nodeListItem.config) as Map<String, dynamic>;
|
||||
print('📄 解析到 config JSON: $configJson');
|
||||
if (kDebugMode) {
|
||||
print('📄 解析到 config JSON: $configJson');
|
||||
}
|
||||
|
||||
// 提取 transport 配置
|
||||
if (configJson['transport'] != null && configJson['transport'] != 'tcp') {
|
||||
transportConfig = _buildTransport(configJson);
|
||||
print('✅ 从 config 找到 transport 配置: $transportConfig');
|
||||
if (kDebugMode) {
|
||||
print('✅ 从 config 找到 transport 配置: $transportConfig');
|
||||
}
|
||||
}
|
||||
|
||||
// 提取 security_config
|
||||
if (configJson['security_config'] != null) {
|
||||
securityConfig = configJson['security_config'] as Map<String, dynamic>;
|
||||
print('✅ 从 config 找到 security_config: $securityConfig');
|
||||
if (kDebugMode) {
|
||||
print('✅ 从 config 找到 security_config: $securityConfig');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('⚠️ 解析 config 字段失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('⚠️ 解析 config 字段失败: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,9 +415,15 @@ class KROutboundItem {
|
||||
"method": finalMethod,
|
||||
"password": nodeListItem.uuid
|
||||
};
|
||||
print('✅ Shadowsocks 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 使用加密方法: $finalMethod');
|
||||
print('📄 完整配置: $config');
|
||||
if (kDebugMode) {
|
||||
print('✅ Shadowsocks 节点配置构建成功: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 使用加密方法: $finalMethod');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: $config');
|
||||
}
|
||||
break;
|
||||
case "vless":
|
||||
// 判断是否为域名(非IP地址)
|
||||
@ -381,7 +438,9 @@ class KROutboundItem {
|
||||
|
||||
// 🔧 关键修复:根据 security_config 判断是否启用 TLS
|
||||
final bool vlessTlsEnabled = securityConfig?['tls_enabled'] ?? false;
|
||||
print('🔐 VLESS TLS 状态: enabled=$vlessTlsEnabled');
|
||||
if (kDebugMode) {
|
||||
print('🔐 VLESS TLS 状态: enabled=$vlessTlsEnabled');
|
||||
}
|
||||
|
||||
config = {
|
||||
"type": "vless",
|
||||
@ -400,8 +459,12 @@ class KROutboundItem {
|
||||
}
|
||||
}
|
||||
};
|
||||
print('✅ VLESS 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 完整配置: $config');
|
||||
if (kDebugMode) {
|
||||
print('✅ VLESS 节点配置构建成功: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: $config');
|
||||
}
|
||||
break;
|
||||
case "vmess":
|
||||
// 判断是否为域名(非IP地址)
|
||||
@ -416,7 +479,9 @@ class KROutboundItem {
|
||||
|
||||
// 🔧 关键修复:根据 security_config 判断是否启用 TLS
|
||||
final bool tlsEnabled = securityConfig?['tls_enabled'] ?? false;
|
||||
print('🔐 TLS 状态: enabled=$tlsEnabled');
|
||||
if (kDebugMode) {
|
||||
print('🔐 TLS 状态: enabled=$tlsEnabled');
|
||||
}
|
||||
|
||||
config = {
|
||||
"type": "vmess",
|
||||
@ -437,8 +502,12 @@ class KROutboundItem {
|
||||
}
|
||||
}
|
||||
};
|
||||
print('✅ VMess 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 完整配置: $config');
|
||||
if (kDebugMode) {
|
||||
print('✅ VMess 节点配置构建成功: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: $config');
|
||||
}
|
||||
break;
|
||||
case "trojan":
|
||||
// 判断是否为域名(非IP地址)
|
||||
@ -468,16 +537,28 @@ class KROutboundItem {
|
||||
}
|
||||
}
|
||||
};
|
||||
print('✅ Trojan 节点配置构建成功: ${nodeListItem.name}');
|
||||
print('📄 完整配置: $config');
|
||||
if (kDebugMode) {
|
||||
print('✅ Trojan 节点配置构建成功: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: $config');
|
||||
}
|
||||
break;
|
||||
case "hysteria":
|
||||
case "hysteria2":
|
||||
// 后端的 "hysteria" 实际上是 Hysteria2 协议
|
||||
print('🔍 构建 Hysteria2 节点: ${nodeListItem.name}');
|
||||
print(' - serverAddr: ${nodeListItem.serverAddr}');
|
||||
print(' - port: ${nodeListItem.port}');
|
||||
print(' - uuid: ${nodeListItem.uuid}');
|
||||
if (kDebugMode) {
|
||||
print('🔍 构建 Hysteria2 节点: ${nodeListItem.name}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - serverAddr: ${nodeListItem.serverAddr}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - port: ${nodeListItem.port}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - uuid: ${nodeListItem.uuid}');
|
||||
}
|
||||
|
||||
//判断是否为域名
|
||||
final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
|
||||
@ -494,11 +575,17 @@ class KROutboundItem {
|
||||
if (isDomain) "server_name": nodeListItem.serverAddr,
|
||||
}
|
||||
};
|
||||
print('✅ Hysteria2 节点配置构建成功');
|
||||
print('📄 完整配置: ${jsonEncode(config)}');
|
||||
if (kDebugMode) {
|
||||
print('✅ Hysteria2 节点配置构建成功');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📄 完整配置: ${jsonEncode(config)}');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print('⚠️ 不支持的协议类型: ${nodeListItem.protocol}');
|
||||
if (kDebugMode) {
|
||||
print('⚠️ 不支持的协议类型: ${nodeListItem.protocol}');
|
||||
}
|
||||
config = {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import 'kr_group_outbound_list.dart';
|
||||
|
||||
import '../response/kr_node_list.dart';
|
||||
import 'kr_outbound_item.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// 表示出站项列表的模型类
|
||||
class KrOutboundsList {
|
||||
@ -47,14 +48,24 @@ class KrOutboundsList {
|
||||
final KROutboundItem item = KROutboundItem(element);
|
||||
|
||||
// 🔍 调试日志:验证 country 字段传递
|
||||
print('🗺️ 构建节点: name="${element.name}", tag="${item.tag}", country="${item.country}"');
|
||||
print(' - element.country: "${element.country}"');
|
||||
print(' - item.country: "${item.country}"');
|
||||
print(' - country.isEmpty: ${item.country.isEmpty}');
|
||||
if (kDebugMode) {
|
||||
print('🗺️ 构建节点: name="${element.name}", tag="${item.tag}", country="${item.country}"');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - element.country: "${element.country}"');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - item.country: "${item.country}"');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - country.isEmpty: ${item.country.isEmpty}');
|
||||
}
|
||||
|
||||
// 检查节点配置是否有效(必须包含 type 字段)
|
||||
if (item.config.isEmpty || !item.config.containsKey('type')) {
|
||||
print('⚠️ 跳过无效节点: ${element.name},配置为空或缺少 type 字段');
|
||||
if (kDebugMode) {
|
||||
print('⚠️ 跳过无效节点: ${element.name},配置为空或缺少 type 字段');
|
||||
}
|
||||
continue; // 跳过无效节点
|
||||
}
|
||||
|
||||
@ -72,7 +83,9 @@ class KrOutboundsList {
|
||||
|
||||
configJsonList.add(item.config);
|
||||
keyList[item.tag] = item;
|
||||
print('✅ keyList["${item.tag}"] 已设置,country="${item.country}"');
|
||||
if (kDebugMode) {
|
||||
print('✅ keyList["${item.tag}"] 已设置,country="${item.country}"');
|
||||
}
|
||||
}
|
||||
|
||||
// 将标签分组转换为 KRGroupOutboundList 并添加到 groupOutboundList
|
||||
|
||||
@ -8,6 +8,7 @@ import 'package:kaer_with_panels/app/services/kr_site_config_service.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import '../../../services/kr_device_info_service.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// Crisp 聊天控制器
|
||||
class KRCrispController extends GetxController {
|
||||
@ -47,7 +48,9 @@ class KRCrispController extends GetxController {
|
||||
kr_isInitialized.value = true;
|
||||
}
|
||||
} catch (e) {
|
||||
print('初始化 Crisp 时出错: $e');
|
||||
if (kDebugMode) {
|
||||
print('初始化 Crisp 时出错: $e');
|
||||
}
|
||||
if (!_kr_isDisposed) {
|
||||
kr_isInitialized.value = false;
|
||||
}
|
||||
@ -125,9 +128,13 @@ class KRCrispController extends GetxController {
|
||||
'device_id': deviceId,
|
||||
});
|
||||
|
||||
print('Crisp 初始化完成');
|
||||
if (kDebugMode) {
|
||||
print('Crisp 初始化完成');
|
||||
}
|
||||
} catch (e) {
|
||||
print('初始化 Crisp 时出错: $e');
|
||||
if (kDebugMode) {
|
||||
print('初始化 Crisp 时出错: $e');
|
||||
}
|
||||
crispController = null;
|
||||
rethrow;
|
||||
}
|
||||
@ -155,7 +162,9 @@ class KRCrispController extends GetxController {
|
||||
kr_isLoading.value = false;
|
||||
}
|
||||
} catch (e) {
|
||||
print('清理 Crisp 资源时出错: $e');
|
||||
if (kDebugMode) {
|
||||
print('清理 Crisp 资源时出错: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@ import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||||
import 'package:kaer_with_panels/app/utils/kr_common_util.dart';
|
||||
import 'package:kaer_with_panels/app/utils/kr_secure_storage.dart';
|
||||
import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
/// 订阅服务
|
||||
@ -498,7 +499,9 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
void _bindConnectionStatus() {
|
||||
// 添加更详细的状态监听
|
||||
ever(KRSingBoxImp.instance.kr_status, (status) {
|
||||
print('🔵 Controller 收到状态变化: ${status.runtimeType}');
|
||||
if (kDebugMode) {
|
||||
print('🔵 Controller 收到状态变化: ${status.runtimeType}');
|
||||
}
|
||||
KRLogUtil.kr_i('🔄 连接状态变化: $status', tag: 'HomeController');
|
||||
KRLogUtil.kr_i('📊 当前状态类型: ${status.runtimeType}', tag: 'HomeController');
|
||||
|
||||
@ -526,7 +529,9 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
break;
|
||||
case SingboxStarted():
|
||||
KRLogUtil.kr_i('🟢 状态: 已启动', tag: 'HomeController');
|
||||
print('🔵 状态变为 Started, 当前延迟=${kr_currentNodeLatency.value}');
|
||||
if (kDebugMode) {
|
||||
print('🔵 状态变为 Started, 当前延迟=${kr_currentNodeLatency.value}');
|
||||
}
|
||||
|
||||
// 取消连接超时处理
|
||||
_cancelConnectionTimeout();
|
||||
@ -538,10 +543,14 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
|
||||
// 🔧 关键修复:如果延迟还是-1(连接中状态),立即设置为0(已连接但延迟未知)
|
||||
if (kr_currentNodeLatency.value == -1) {
|
||||
print('🔵 强制将延迟从 -1 更新为 0');
|
||||
if (kDebugMode) {
|
||||
print('🔵 强制将延迟从 -1 更新为 0');
|
||||
}
|
||||
kr_currentNodeLatency.value = 0;
|
||||
kr_currentNodeLatency.refresh(); // 强制刷新延迟值
|
||||
print('🔵 延迟值已刷新');
|
||||
if (kDebugMode) {
|
||||
print('🔵 延迟值已刷新');
|
||||
}
|
||||
}
|
||||
|
||||
// 🔧 修复:立即尝试更新延迟值
|
||||
@ -551,7 +560,9 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
kr_isConnected.refresh();
|
||||
// 强制更新UI
|
||||
update();
|
||||
print('🔵 状态更新完成,当前延迟=${kr_currentNodeLatency.value}');
|
||||
if (kDebugMode) {
|
||||
print('🔵 状态更新完成,当前延迟=${kr_currentNodeLatency.value}');
|
||||
}
|
||||
break;
|
||||
case SingboxStopping():
|
||||
KRLogUtil.kr_i('🟠 状态: 正在停止', tag: 'HomeController');
|
||||
@ -637,12 +648,16 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
final currentStatus = KRSingBoxImp.instance.kr_status.value;
|
||||
|
||||
KRLogUtil.kr_i('🔵 toggleSwitch 被调用: value=$value, currentStatus=$currentStatus', tag: 'HomeController');
|
||||
print('🔵 toggleSwitch: value=$value, currentStatus=$currentStatus');
|
||||
if (kDebugMode) {
|
||||
print('🔵 toggleSwitch: value=$value, currentStatus=$currentStatus');
|
||||
}
|
||||
|
||||
// 🔧 关键: 如果正在切换中,直接忽略(参考 hiddify-app 的 "switching status, debounce")
|
||||
if (currentStatus is SingboxStarting || currentStatus is SingboxStopping) {
|
||||
KRLogUtil.kr_i('🔄 正在切换中,忽略本次操作 (当前状态: $currentStatus)', tag: 'HomeController');
|
||||
print('🔵 忽略操作:正在切换中');
|
||||
if (kDebugMode) {
|
||||
print('🔵 忽略操作:正在切换中');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -650,17 +665,23 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
if (value) {
|
||||
// 开启连接
|
||||
KRLogUtil.kr_i('🔄 开始连接...', tag: 'HomeController');
|
||||
print('🔵 执行 kr_start()');
|
||||
if (kDebugMode) {
|
||||
print('🔵 执行 kr_start()');
|
||||
}
|
||||
await KRSingBoxImp.instance.kr_start();
|
||||
KRLogUtil.kr_i('✅ 连接命令已发送', tag: 'HomeController');
|
||||
print('🔵 kr_start() 完成');
|
||||
if (kDebugMode) {
|
||||
print('🔵 kr_start() 完成');
|
||||
}
|
||||
|
||||
// 🔧 修复: 等待状态更新,最多3秒
|
||||
await _waitForStatus(SingboxStarted, maxSeconds: 3);
|
||||
} else {
|
||||
// 关闭连接
|
||||
KRLogUtil.kr_i('🛑 开始断开连接...', tag: 'HomeController');
|
||||
print('🔵 执行 kr_stop()');
|
||||
if (kDebugMode) {
|
||||
print('🔵 执行 kr_stop()');
|
||||
}
|
||||
await KRSingBoxImp.instance.kr_stop().timeout(
|
||||
const Duration(seconds: 10),
|
||||
onTimeout: () {
|
||||
@ -669,32 +690,44 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
},
|
||||
);
|
||||
KRLogUtil.kr_i('✅ 断开命令已发送', tag: 'HomeController');
|
||||
print('🔵 kr_stop() 完成');
|
||||
if (kDebugMode) {
|
||||
print('🔵 kr_stop() 完成');
|
||||
}
|
||||
|
||||
// 🔧 修复: 等待状态更新,最多2秒
|
||||
await _waitForStatus(SingboxStopped, maxSeconds: 2);
|
||||
}
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('❌ 切换失败: $e', tag: 'HomeController');
|
||||
print('🔵 切换失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('🔵 切换失败: $e');
|
||||
}
|
||||
// 发生错误时强制同步状态
|
||||
kr_forceSyncConnectionStatus();
|
||||
}
|
||||
|
||||
print('🔵 toggleSwitch 完成,当前 kr_isConnected=${kr_isConnected.value}');
|
||||
if (kDebugMode) {
|
||||
print('🔵 toggleSwitch 完成,当前 kr_isConnected=${kr_isConnected.value}');
|
||||
}
|
||||
}
|
||||
|
||||
/// 🔧 等待状态达到预期值
|
||||
Future<void> _waitForStatus(Type expectedType, {int maxSeconds = 3}) async {
|
||||
print('🔵 等待状态变为: $expectedType');
|
||||
if (kDebugMode) {
|
||||
print('🔵 等待状态变为: $expectedType');
|
||||
}
|
||||
final startTime = DateTime.now();
|
||||
|
||||
while (DateTime.now().difference(startTime).inSeconds < maxSeconds) {
|
||||
final currentStatus = KRSingBoxImp.instance.kr_status.value;
|
||||
print('🔵 当前状态: ${currentStatus.runtimeType}');
|
||||
if (kDebugMode) {
|
||||
print('🔵 当前状态: ${currentStatus.runtimeType}');
|
||||
}
|
||||
|
||||
if (currentStatus.runtimeType == expectedType) {
|
||||
print('🔵 状态已达到: $expectedType');
|
||||
if (kDebugMode) {
|
||||
print('🔵 状态已达到: $expectedType');
|
||||
}
|
||||
// 强制同步确保 kr_isConnected 正确
|
||||
kr_forceSyncConnectionStatus();
|
||||
return;
|
||||
@ -703,7 +736,9 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
}
|
||||
|
||||
print('🔵 等待超时,强制同步状态');
|
||||
if (kDebugMode) {
|
||||
print('🔵 等待超时,强制同步状态');
|
||||
}
|
||||
kr_forceSyncConnectionStatus();
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart';
|
||||
import 'package:kaer_with_panels/singbox/model/singbox_status.dart';
|
||||
import '../controllers/kr_home_controller.dart';
|
||||
import '../models/kr_home_views_status.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class KRHomeConnectionInfoView extends GetView<KRHomeController> {
|
||||
const KRHomeConnectionInfoView({super.key});
|
||||
@ -82,7 +83,9 @@ class KRHomeConnectionInfoView extends GetView<KRHomeController> {
|
||||
// 🔧 修复:使用 Obx 包裹确保国旗响应式更新
|
||||
Obx(() {
|
||||
final countryCode = controller.kr_getCurrentNodeCountry();
|
||||
print('🌍 ConnectionInfo 更新,国家代码: $countryCode');
|
||||
if (kDebugMode) {
|
||||
print('🌍 ConnectionInfo 更新,国家代码: $countryCode');
|
||||
}
|
||||
return KRCountryFlag(
|
||||
countryCode: countryCode,
|
||||
);
|
||||
@ -104,7 +107,9 @@ class KRHomeConnectionInfoView extends GetView<KRHomeController> {
|
||||
children: [
|
||||
Obx(() {
|
||||
final delay = controller.kr_currentNodeLatency.value;
|
||||
print('🔵 UI延迟显示更新: delay=$delay');
|
||||
if (kDebugMode) {
|
||||
print('🔵 UI延迟显示更新: delay=$delay');
|
||||
}
|
||||
|
||||
// 获取延迟颜色
|
||||
Color getLatencyColor(int delay) {
|
||||
@ -227,7 +232,9 @@ class KRHomeConnectionInfoView extends GetView<KRHomeController> {
|
||||
final isSwitching = status is SingboxStarting || status is SingboxStopping;
|
||||
|
||||
// 🔧 调试日志
|
||||
print('🔵 Switch UI 更新: status=${status.runtimeType}, isConnected=$isConnected, isSwitching=$isSwitching');
|
||||
if (kDebugMode) {
|
||||
print('🔵 Switch UI 更新: status=${status.runtimeType}, isConnected=$isConnected, isSwitching=$isSwitching');
|
||||
}
|
||||
|
||||
return CupertinoSwitch(
|
||||
value: isConnected,
|
||||
@ -235,7 +242,9 @@ class KRHomeConnectionInfoView extends GetView<KRHomeController> {
|
||||
onChanged: isSwitching
|
||||
? null
|
||||
: (bool value) {
|
||||
print('🔵 Switch onChanged 触发: 请求=$value, 当前状态=$status');
|
||||
if (kDebugMode) {
|
||||
print('🔵 Switch onChanged 触发: 请求=$value, 当前状态=$status');
|
||||
}
|
||||
controller.kr_toggleSwitch(value);
|
||||
},
|
||||
activeColor: Colors.blue,
|
||||
|
||||
@ -16,6 +16,7 @@ import 'package:kaer_with_panels/app/widgets/kr_network_image.dart';
|
||||
import '../../../widgets/kr_simple_loading.dart';
|
||||
|
||||
import '../../../../singbox/model/singbox_proxy_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// 节点列表视图组件
|
||||
/// 用于展示所有节点相关的列表视图
|
||||
@ -281,7 +282,9 @@ class KRHomeNodeListView extends GetView<KRHomeController> {
|
||||
// 🔧 修复:改为 async,等待节点切换完成后再关闭列表
|
||||
onTap: () async {
|
||||
try {
|
||||
print('🔄 用户点击节点: ${server.tag}');
|
||||
if (kDebugMode) {
|
||||
print('🔄 用户点击节点: ${server.tag}');
|
||||
}
|
||||
// 使用统一的节点切换方法,等待完成
|
||||
final success = await controller
|
||||
.kr_performNodeSwitch(server.tag);
|
||||
@ -290,12 +293,18 @@ class KRHomeNodeListView extends GetView<KRHomeController> {
|
||||
if (success) {
|
||||
controller.kr_currentListStatus.value =
|
||||
KRHomeViewsListStatus.kr_none;
|
||||
print('✅ 节点切换成功,关闭列表');
|
||||
if (kDebugMode) {
|
||||
print('✅ 节点切换成功,关闭列表');
|
||||
}
|
||||
} else {
|
||||
print('❌ 节点切换失败,列表保持打开');
|
||||
if (kDebugMode) {
|
||||
print('❌ 节点切换失败,列表保持打开');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('❌ 节点切换异常: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ 节点切换异常: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('节点切换异常: $e',
|
||||
tag: 'NodeListView');
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:latlong2/latlong.dart';
|
||||
import '../../../utils/kr_fm_tc.dart';
|
||||
import '../controllers/kr_home_controller.dart';
|
||||
import '../../../utils/kr_log_util.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// 首页地图视图组件
|
||||
class KRHomeMapView extends GetView<KRHomeController> {
|
||||
@ -187,12 +188,16 @@ return GetBuilder<KRHomeController>(
|
||||
|
||||
/// 构建样式化的标记
|
||||
Marker _buildStyledMarker(dynamic node) {
|
||||
print("原始Marker:${node}");
|
||||
if (kDebugMode) {
|
||||
print("原始Marker:${node}");
|
||||
}
|
||||
int type = 0;
|
||||
MaterialColor markerColor = Colors.grey;
|
||||
//如果没订阅过,就是灰色
|
||||
bool status = controller.kr_isConnected.value;
|
||||
print("连接状态:$status");
|
||||
if (kDebugMode) {
|
||||
print("连接状态:$status");
|
||||
}
|
||||
if(status){
|
||||
if (node.urlTestDelay.value == 0) {
|
||||
// 延迟为0时使用默认颜色
|
||||
|
||||
@ -11,6 +11,7 @@ import 'package:kaer_with_panels/app/widgets/hi_help_entrance.dart';
|
||||
import 'package:kaer_with_panels/app/common/app_run_data.dart';
|
||||
import 'package:kaer_with_panels/app/modules/kr_home/controllers/kr_home_controller.dart';
|
||||
import 'package:kaer_with_panels/app/services/kr_site_config_service.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class KRLoginView extends GetView<KRLoginController> {
|
||||
const KRLoginView({super.key});
|
||||
|
||||
@ -10,6 +10,7 @@ import '../../../utils/kr_event_bus.dart';
|
||||
import '../../../utils/kr_common_util.dart';
|
||||
import '../../../localization/app_translations.dart';
|
||||
import '../../../utils/kr_log_util.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// 订单状态控制器(参考 Tauri 项目实现)
|
||||
class KROrderStatusController extends GetxController {
|
||||
@ -71,12 +72,24 @@ class KROrderStatusController extends GetxController {
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
print('═══════════════════════════════════════');
|
||||
print('📊 订单状态页面初始化');
|
||||
print(' 订单号: $kr_order');
|
||||
print(' 支付方式: $kr_paymentType');
|
||||
print(' Checkout类型: $kr_checkoutType');
|
||||
print('═══════════════════════════════════════');
|
||||
if (kDebugMode) {
|
||||
print('═══════════════════════════════════════');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📊 订单状态页面初始化');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' 订单号: $kr_order');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' 支付方式: $kr_paymentType');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' Checkout类型: $kr_checkoutType');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('═══════════════════════════════════════');
|
||||
}
|
||||
|
||||
// 立即查询一次订单状态,获取创建时间
|
||||
kr_checkPaymentStatus();
|
||||
@ -92,7 +105,9 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
print('🔚 订单状态页面关闭,清理定时器');
|
||||
if (kDebugMode) {
|
||||
print('🔚 订单状态页面关闭,清理定时器');
|
||||
}
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
super.onClose();
|
||||
@ -100,7 +115,9 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
/// 开始检查支付状态(参考 Tauri 项目:5秒轮询一次)
|
||||
void kr_startCheckingPaymentStatus() {
|
||||
print('🔄 启动支付状态轮询(每5秒检查一次)');
|
||||
if (kDebugMode) {
|
||||
print('🔄 启动支付状态轮询(每5秒检查一次)');
|
||||
}
|
||||
|
||||
// 状态轮询:每5秒检查一次订单状态
|
||||
kr_timer = Timer.periodic(const Duration(seconds: 5), (timer) {
|
||||
@ -118,7 +135,9 @@ class KROrderStatusController extends GetxController {
|
||||
if (kr_orderCreatedAt == null) {
|
||||
// 订单创建时间还未获取,显示默认倒计时
|
||||
kr_formattedCountdown.value = '15:00';
|
||||
print('⏱️ 倒计时更新: 等待订单创建时间...');
|
||||
if (kDebugMode) {
|
||||
print('⏱️ 倒计时更新: 等待订单创建时间...');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -128,12 +147,24 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
final timeLeft = targetTime - now;
|
||||
|
||||
print('⏱️ 倒计时调试信息:');
|
||||
print(' 当前时间(ms): $now');
|
||||
print(' 创建时间(ms): $createdAt');
|
||||
print(' 目标时间(ms): $targetTime');
|
||||
print(' 剩余时间(ms): $timeLeft');
|
||||
print(' 剩余时间(秒): ${(timeLeft / 1000).floor()}');
|
||||
if (kDebugMode) {
|
||||
print('⏱️ 倒计时调试信息:');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' 当前时间(ms): $now');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' 创建时间(ms): $createdAt');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' 目标时间(ms): $targetTime');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' 剩余时间(ms): $timeLeft');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' 剩余时间(秒): ${(timeLeft / 1000).floor()}');
|
||||
}
|
||||
|
||||
if (timeLeft > 0) {
|
||||
kr_countdown.value = timeLeft;
|
||||
@ -141,7 +172,9 @@ class KROrderStatusController extends GetxController {
|
||||
final minutes = (timeLeft / 60000).floor();
|
||||
final seconds = ((timeLeft % 60000) / 1000).floor();
|
||||
kr_formattedCountdown.value = '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
print(' 格式化倒计时: ${kr_formattedCountdown.value}');
|
||||
if (kDebugMode) {
|
||||
print(' 格式化倒计时: ${kr_formattedCountdown.value}');
|
||||
}
|
||||
} else {
|
||||
// 倒计时结束,订单超时
|
||||
kr_countdown.value = 0;
|
||||
@ -149,7 +182,9 @@ class KROrderStatusController extends GetxController {
|
||||
kr_countdownTimer?.cancel();
|
||||
kr_timer?.cancel();
|
||||
|
||||
print('⏱️ 订单支付超时(15分钟)');
|
||||
if (kDebugMode) {
|
||||
print('⏱️ 订单支付超时(15分钟)');
|
||||
}
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.closedTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.timeoutMessage;
|
||||
kr_isLoading.value = false;
|
||||
@ -161,14 +196,18 @@ class KROrderStatusController extends GetxController {
|
||||
final now = DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
try {
|
||||
print('🔍 检查订单状态 [${kr_order}]');
|
||||
if (kDebugMode) {
|
||||
print('🔍 检查订单状态 [${kr_order}]');
|
||||
}
|
||||
|
||||
// 使用公开接口查询订单状态
|
||||
final result = await kr_subscribeApi.kr_queryOrderStatus(kr_order);
|
||||
|
||||
result.fold(
|
||||
(error) {
|
||||
print('❌ 查询失败: ${error.msg}');
|
||||
if (kDebugMode) {
|
||||
print('❌ 查询失败: ${error.msg}');
|
||||
}
|
||||
KRLogUtil.kr_e('检查支付状态失败: ${error.msg}', tag: 'OrderStatusController');
|
||||
kr_isLoading.value = false;
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.checkFailedTitle;
|
||||
@ -186,13 +225,23 @@ class KROrderStatusController extends GetxController {
|
||||
isMilliseconds ? timestamp : timestamp * 1000
|
||||
);
|
||||
|
||||
print('📅 订单创建时间: ${kr_orderCreatedAt}');
|
||||
print('📅 原始时间戳: $timestamp');
|
||||
print('📅 时间戳类型: ${isMilliseconds ? "毫秒级" : "秒级"}');
|
||||
print('📅 转换后时间戳(ms): ${kr_orderCreatedAt!.millisecondsSinceEpoch}');
|
||||
if (kDebugMode) {
|
||||
print('📅 订单创建时间: ${kr_orderCreatedAt}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📅 原始时间戳: $timestamp');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📅 时间戳类型: ${isMilliseconds ? "毫秒级" : "秒级"}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📅 转换后时间戳(ms): ${kr_orderCreatedAt!.millisecondsSinceEpoch}');
|
||||
}
|
||||
}
|
||||
|
||||
print('📊 订单状态: ${kr_orderStatus.kr_status} (${_getStatusName(kr_orderStatus.kr_status)})');
|
||||
if (kDebugMode) {
|
||||
print('📊 订单状态: ${kr_orderStatus.kr_status} (${_getStatusName(kr_orderStatus.kr_status)})');
|
||||
}
|
||||
|
||||
switch (kr_orderStatus.kr_status) {
|
||||
case kr_statusPending:
|
||||
@ -204,7 +253,9 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
case kr_statusPaid:
|
||||
// 已支付状态,继续轮询直到完成
|
||||
print('✅ 订单已支付,等待确认...');
|
||||
if (kDebugMode) {
|
||||
print('✅ 订单已支付,等待确认...');
|
||||
}
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.paidTitle;
|
||||
kr_statusDescription.value = AppTranslations.kr_orderStatus.paidDescription;
|
||||
kr_statusIcon.value = 'payment_success';
|
||||
@ -212,7 +263,9 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
case kr_statusFinished:
|
||||
// 订单完成
|
||||
print('🎉 订单完成!停止轮询');
|
||||
if (kDebugMode) {
|
||||
print('🎉 订单完成!停止轮询');
|
||||
}
|
||||
kr_isPaymentSuccess.value = true;
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
@ -226,7 +279,9 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
case kr_statusClose:
|
||||
// 订单已关闭
|
||||
print('❌ 订单已关闭');
|
||||
if (kDebugMode) {
|
||||
print('❌ 订单已关闭');
|
||||
}
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
@ -237,7 +292,9 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
case kr_statusFailed:
|
||||
// 支付失败
|
||||
print('❌ 支付失败');
|
||||
if (kDebugMode) {
|
||||
print('❌ 支付失败');
|
||||
}
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
@ -248,7 +305,9 @@ class KROrderStatusController extends GetxController {
|
||||
|
||||
default:
|
||||
// 未知状态
|
||||
print('⚠️ 未知状态: ${kr_orderStatus.kr_status}');
|
||||
if (kDebugMode) {
|
||||
print('⚠️ 未知状态: ${kr_orderStatus.kr_status}');
|
||||
}
|
||||
kr_isLoading.value = false;
|
||||
kr_timer?.cancel();
|
||||
kr_countdownTimer?.cancel();
|
||||
@ -262,7 +321,9 @@ class KROrderStatusController extends GetxController {
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
print('❌ 异常: $error');
|
||||
if (kDebugMode) {
|
||||
print('❌ 异常: $error');
|
||||
}
|
||||
KRLogUtil.kr_e('检查支付状态失败: $error', tag: 'OrderStatusController');
|
||||
kr_isLoading.value = false;
|
||||
kr_statusTitle.value = AppTranslations.kr_orderStatus.checkFailedTitle;
|
||||
|
||||
@ -13,6 +13,7 @@ import '../../../model/response/kr_payment_methods.dart';
|
||||
import '../../../routes/app_pages.dart';
|
||||
import '../../../services/api_service/kr_api.user.dart';
|
||||
import '../../../utils/kr_event_bus.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// 会员购买控制器
|
||||
/// 负责处理会员套餐选择、支付方式选择和订阅流程
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:kaer_with_panels/app/common/app_run_data.dart';
|
||||
import 'package:kaer_with_panels/app/common/app_config.dart';
|
||||
@ -30,27 +31,33 @@ class BaseResponse<T> {
|
||||
|
||||
if (shouldDecrypt && cipherText.isNotEmpty && nonce.isNotEmpty) {
|
||||
try {
|
||||
print('═══════════════════════════════════════');
|
||||
print('🔐 检测到加密响应,开始解密...');
|
||||
print('📥 加密数据长度: ${cipherText.length} 字符');
|
||||
print('⏰ 时间戳: $nonce');
|
||||
if (kDebugMode) {
|
||||
print('═══════════════════════════════════════');
|
||||
print('🔐 检测到加密响应,开始解密...');
|
||||
print('📥 加密数据长度: ${cipherText.length} 字符');
|
||||
print('⏰ 时间戳: $nonce');
|
||||
}
|
||||
|
||||
final decrypted = KRAesUtil.decryptData(cipherText, nonce, AppConfig.kr_encryptionKey);
|
||||
body = jsonDecode(decrypted);
|
||||
|
||||
print('✅ 解密成功');
|
||||
print('');
|
||||
print('📦 解密后的完整数据:');
|
||||
// 格式化打印 JSON,方便调试
|
||||
final bodyStr = JsonEncoder.withIndent(' ').convert(body);
|
||||
print(bodyStr);
|
||||
print('═══════════════════════════════════════');
|
||||
if (kDebugMode) {
|
||||
print('✅ 解密成功');
|
||||
print('');
|
||||
print('📦 解密后的完整数据:');
|
||||
// 格式化打印 JSON,方便调试
|
||||
final bodyStr = JsonEncoder.withIndent(' ').convert(body);
|
||||
print(bodyStr);
|
||||
print('═══════════════════════════════════════');
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('🔓 解密成功', tag: 'BaseResponse');
|
||||
} catch (e) {
|
||||
print('❌ 解密失败: $e');
|
||||
print('⚠️ 将使用原始数据');
|
||||
print('═══════════════════════════════════════');
|
||||
if (kDebugMode) {
|
||||
print('❌ 解密失败: $e');
|
||||
print('⚠️ 将使用原始数据');
|
||||
print('═══════════════════════════════════════');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ 解密失败: $e', tag: 'BaseResponse');
|
||||
body = dataMap;
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import 'package:loggy/loggy.dart';
|
||||
|
||||
import '../utils/kr_aes_util.dart';
|
||||
import '../utils/kr_log_util.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
// import 'package:video/app/utils/common_util.dart';
|
||||
// import 'package:video/app/utils/log_util.dart';
|
||||
@ -316,31 +317,47 @@ class HttpUtil {
|
||||
class MyInterceptor extends Interceptor {
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
print('>>> Request │ ${options.method} │ ${options.uri}');
|
||||
if (kDebugMode) {
|
||||
print('>>> Request │ ${options.method} │ ${options.uri}');
|
||||
}
|
||||
if (options.data != null) {
|
||||
print('Body: ${options.data}');
|
||||
if (kDebugMode) {
|
||||
print('Body: ${options.data}');
|
||||
}
|
||||
}
|
||||
handler.next(options);
|
||||
}
|
||||
|
||||
@override
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
print('<<< Response │ ${response.requestOptions.method} │ ${response.statusCode} ${response.statusMessage} │ ${response.requestOptions.uri}');
|
||||
if (kDebugMode) {
|
||||
print('<<< Response │ ${response.requestOptions.method} │ ${response.statusCode} ${response.statusMessage} │ ${response.requestOptions.uri}');
|
||||
}
|
||||
if (response.data != null) {
|
||||
print('Body: ${response.data}');
|
||||
if (kDebugMode) {
|
||||
print('Body: ${response.data}');
|
||||
}
|
||||
}
|
||||
handler.next(response);
|
||||
}
|
||||
|
||||
@override
|
||||
void onError(DioException err, ErrorInterceptorHandler handler) {
|
||||
print('<<< Error │ ${err.requestOptions.method} │ ${err.requestOptions.uri}');
|
||||
print('Error Type: ${err.type}');
|
||||
if (kDebugMode) {
|
||||
print('<<< Error │ ${err.requestOptions.method} │ ${err.requestOptions.uri}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('Error Type: ${err.type}');
|
||||
}
|
||||
if (err.message != null) {
|
||||
print('Error Message: ${err.message}');
|
||||
if (kDebugMode) {
|
||||
print('Error Message: ${err.message}');
|
||||
}
|
||||
}
|
||||
if (err.response?.data != null) {
|
||||
print('Response Data: ${err.response?.data}');
|
||||
if (kDebugMode) {
|
||||
print('Response Data: ${err.response?.data}');
|
||||
}
|
||||
}
|
||||
handler.next(err);
|
||||
}
|
||||
@ -350,17 +367,25 @@ class MyInterceptor extends Interceptor {
|
||||
class _KRSimpleHttpInterceptor extends Interceptor {
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
print('>>> Request │ ${options.method} │ ${options.uri}');
|
||||
if (kDebugMode) {
|
||||
print('>>> Request │ ${options.method} │ ${options.uri}');
|
||||
}
|
||||
if (options.data != null) {
|
||||
print('Body: ${options.data}');
|
||||
if (kDebugMode) {
|
||||
print('Body: ${options.data}');
|
||||
}
|
||||
|
||||
// 检查是否是加密数据(包含 data 和 time 字段)
|
||||
if (options.data is Map<String, dynamic>) {
|
||||
final data = options.data as Map<String, dynamic>;
|
||||
if (data.containsKey('data') && data.containsKey('time')) {
|
||||
try {
|
||||
print('');
|
||||
print('🔐 检测到加密请求,正在解密...');
|
||||
if (kDebugMode) {
|
||||
print('');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('🔐 检测到加密请求,正在解密...');
|
||||
}
|
||||
// 尝试解密并打印原始数据
|
||||
final encryptedData = data['data'] as String;
|
||||
final nonce = data['time'] as String;
|
||||
@ -369,17 +394,25 @@ class _KRSimpleHttpInterceptor extends Interceptor {
|
||||
nonce,
|
||||
AppConfig.kr_encryptionKey,
|
||||
);
|
||||
print('🔓 解密后的原始请求数据:');
|
||||
if (kDebugMode) {
|
||||
print('🔓 解密后的原始请求数据:');
|
||||
}
|
||||
// 尝试格式化 JSON
|
||||
try {
|
||||
final jsonData = jsonDecode(decrypted);
|
||||
final prettyJson = JsonEncoder.withIndent(' ').convert(jsonData);
|
||||
print(prettyJson);
|
||||
if (kDebugMode) {
|
||||
print(prettyJson);
|
||||
}
|
||||
} catch (_) {
|
||||
print(decrypted);
|
||||
if (kDebugMode) {
|
||||
print(decrypted);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('⚠️ 请求解密失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('⚠️ 请求解密失败: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -389,9 +422,13 @@ class _KRSimpleHttpInterceptor extends Interceptor {
|
||||
|
||||
@override
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
print('<<< Response │ ${response.requestOptions.method} │ ${response.statusCode} ${response.statusMessage} │ ${response.requestOptions.uri}');
|
||||
if (kDebugMode) {
|
||||
print('<<< Response │ ${response.requestOptions.method} │ ${response.statusCode} ${response.statusMessage} │ ${response.requestOptions.uri}');
|
||||
}
|
||||
if (response.data != null) {
|
||||
print('Body: ${response.data}');
|
||||
if (kDebugMode) {
|
||||
print('Body: ${response.data}');
|
||||
}
|
||||
|
||||
// 检查响应是否是加密数据(包含 data 和 time 字段)
|
||||
if (response.data is Map<String, dynamic>) {
|
||||
@ -403,8 +440,12 @@ class _KRSimpleHttpInterceptor extends Interceptor {
|
||||
nestedData.containsKey('data') &&
|
||||
nestedData.containsKey('time')) {
|
||||
try {
|
||||
print('');
|
||||
print('🔐 检测到加密响应,正在解密...');
|
||||
if (kDebugMode) {
|
||||
print('');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('🔐 检测到加密响应,正在解密...');
|
||||
}
|
||||
// 尝试解密并打印原始响应数据
|
||||
final encryptedData = nestedData['data'] as String;
|
||||
final nonce = nestedData['time'] as String;
|
||||
@ -413,17 +454,25 @@ class _KRSimpleHttpInterceptor extends Interceptor {
|
||||
nonce,
|
||||
AppConfig.kr_encryptionKey,
|
||||
);
|
||||
print('🔓 解密后的原始响应数据: ${response.requestOptions.uri}');
|
||||
if (kDebugMode) {
|
||||
print('🔓 解密后的原始响应数据:');
|
||||
}
|
||||
// 尝试格式化 JSON
|
||||
try {
|
||||
final jsonData = jsonDecode(decrypted);
|
||||
final prettyJson = JsonEncoder.withIndent(' ').convert(jsonData);
|
||||
print(prettyJson);
|
||||
if (kDebugMode) {
|
||||
print(prettyJson);
|
||||
}
|
||||
} catch (_) {
|
||||
print(decrypted);
|
||||
if (kDebugMode) {
|
||||
print(decrypted);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('⚠️ 响应解密失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('⚠️ 响应解密失败: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -433,13 +482,21 @@ class _KRSimpleHttpInterceptor extends Interceptor {
|
||||
|
||||
@override
|
||||
void onError(DioException err, ErrorInterceptorHandler handler) {
|
||||
print('<<< Error │ ${err.requestOptions.method} │ ${err.requestOptions.uri}');
|
||||
print('Error Type: ${err.type}');
|
||||
if (kDebugMode) {
|
||||
print('<<< Error │ ${err.requestOptions.method} │ ${err.requestOptions.uri}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('Error Type: ${err.type}');
|
||||
}
|
||||
if (err.message != null) {
|
||||
print('Error Message: ${err.message}');
|
||||
if (kDebugMode) {
|
||||
print('Error Message: ${err.message}');
|
||||
}
|
||||
}
|
||||
if (err.response?.data != null) {
|
||||
print('Response Data: ${err.response?.data}');
|
||||
if (kDebugMode) {
|
||||
print('Response Data: ${err.response?.data}');
|
||||
}
|
||||
}
|
||||
handler.next(err);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import 'dart:io';
|
||||
import 'dart:io' as io;
|
||||
import 'dart:math';
|
||||
import 'dart:convert';
|
||||
|
||||
@ -21,6 +21,8 @@ import '../kr_device_info_service.dart';
|
||||
import '../kr_site_config_service.dart';
|
||||
import '../../common/app_config.dart';
|
||||
import 'package:dio/dio.dart' as dio;
|
||||
import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class KRAuthApi {
|
||||
/// 检查账号是否已注册(仅支持邮箱)
|
||||
@ -465,17 +467,17 @@ class KRAuthApi {
|
||||
}
|
||||
|
||||
String _kr_getUserAgent() {
|
||||
if (Platform.isAndroid) {
|
||||
if (io.Platform.isAndroid) {
|
||||
return 'android';
|
||||
} else if (Platform.isIOS) {
|
||||
} else if (io.Platform.isIOS) {
|
||||
return 'ios';
|
||||
} else if (Platform.isMacOS) {
|
||||
} else if (io.Platform.isMacOS) {
|
||||
return 'mac';
|
||||
} else if (Platform.isWindows) {
|
||||
} else if (io.Platform.isWindows) {
|
||||
return 'windows';
|
||||
} else if (Platform.isLinux) {
|
||||
} else if (io.Platform.isLinux) {
|
||||
return 'linux';
|
||||
} else if (Platform.isFuchsia) {
|
||||
} else if (io.Platform.isFuchsia) {
|
||||
return 'harmony';
|
||||
} else {
|
||||
return 'unknown';
|
||||
|
||||
@ -27,26 +27,32 @@ class KRDeviceInfoService {
|
||||
/// 初始化设备信息
|
||||
Future<void> initialize() async {
|
||||
try {
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
print('📱 开始初始化设备信息服务');
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
if (kDebugMode) {
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
print('📱 开始初始化设备信息服务');
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 开始初始化设备信息', tag: 'KRDeviceInfoService');
|
||||
|
||||
_deviceId = await _getDeviceId();
|
||||
_deviceDetails = await _getDeviceDetails();
|
||||
|
||||
print('✅ 设备信息初始化成功');
|
||||
print('📱 设备ID: $_deviceId');
|
||||
print('📱 设备平台: ${getPlatformName()}');
|
||||
print('📱 设备型号: ${getDeviceModel()}');
|
||||
print('📱 系统版本: ${getOSVersion()}');
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
if (kDebugMode) {
|
||||
print('✅ 设备信息初始化成功');
|
||||
print('📱 设备ID: $_deviceId');
|
||||
print('📱 设备平台: ${getPlatformName()}');
|
||||
print('📱 设备型号: ${getDeviceModel()}');
|
||||
print('📱 系统版本: ${getOSVersion()}');
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('✅ 设备信息初始化成功', tag: 'KRDeviceInfoService');
|
||||
KRLogUtil.kr_i('📱 设备ID - $_deviceId', tag: 'KRDeviceInfoService');
|
||||
KRLogUtil.kr_i('📱 设备详情 - $_deviceDetails', tag: 'KRDeviceInfoService');
|
||||
} catch (e) {
|
||||
print('❌ 设备信息初始化失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ 设备信息初始化失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ 设备信息初始化失败 - $e', tag: 'KRDeviceInfoService');
|
||||
}
|
||||
}
|
||||
@ -79,7 +85,9 @@ class KRDeviceInfoService {
|
||||
|
||||
return identifier;
|
||||
} catch (e) {
|
||||
print('❌ 获取设备ID失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ 获取设备ID失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ 获取设备ID失败 - $e', tag: 'KRDeviceInfoService');
|
||||
// 如果获取失败,返回存储的或生成新的ID
|
||||
return await _getOrCreateStoredDeviceId();
|
||||
@ -119,12 +127,16 @@ class KRDeviceInfoService {
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 Android多因子ID生成 - 因子数: ${factors.where((f) => f != null && f.isNotEmpty).length}');
|
||||
if (kDebugMode) {
|
||||
print('📱 Android多因子ID生成 - 因子数: ${factors.where((f) => f != null && f.isNotEmpty).length}');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 Android多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ Android设备ID获取失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ Android设备ID获取失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ Android设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
@ -157,12 +169,16 @@ class KRDeviceInfoService {
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 iOS多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
if (kDebugMode) {
|
||||
print('📱 iOS多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 iOS多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ iOS设备ID获取失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ iOS设备ID获取失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ iOS设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
@ -193,12 +209,16 @@ class KRDeviceInfoService {
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 macOS多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
if (kDebugMode) {
|
||||
print('📱 macOS多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 macOS多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ macOS设备ID获取失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ macOS设备ID获取失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ macOS设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
@ -229,12 +249,16 @@ class KRDeviceInfoService {
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 Windows多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
if (kDebugMode) {
|
||||
print('📱 Windows多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 Windows多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ Windows设备ID获取失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ Windows设备ID获取失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ Windows设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
@ -265,12 +289,16 @@ class KRDeviceInfoService {
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 Linux多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
if (kDebugMode) {
|
||||
print('📱 Linux多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 Linux多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ Linux设备ID获取失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ Linux设备ID获取失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ Linux设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
@ -288,16 +316,22 @@ class KRDeviceInfoService {
|
||||
// 生成新的UUID
|
||||
storedId = _generateUniqueId();
|
||||
await storage.kr_saveData(key: key, value: storedId);
|
||||
print('📱 生成新的设备ID: $storedId');
|
||||
if (kDebugMode) {
|
||||
print('📱 生成新的设备ID: $storedId');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 生成新的设备ID - $storedId', tag: 'KRDeviceInfoService');
|
||||
} else {
|
||||
print('📱 使用存储的设备ID: $storedId');
|
||||
if (kDebugMode) {
|
||||
print('📱 使用存储的设备ID: $storedId');
|
||||
}
|
||||
KRLogUtil.kr_i('📱 使用存储的设备ID - $storedId', tag: 'KRDeviceInfoService');
|
||||
}
|
||||
|
||||
return storedId;
|
||||
} catch (e) {
|
||||
print('❌ 获取存储的设备ID失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ 获取存储的设备ID失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ 获取存储的设备ID失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return _generateUniqueId();
|
||||
}
|
||||
@ -383,7 +417,9 @@ class KRDeviceInfoService {
|
||||
'platform': 'unknown',
|
||||
};
|
||||
} catch (e) {
|
||||
print('❌ 获取设备详情失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('❌ 获取设备详情失败: $e');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ 获取设备详情失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return {
|
||||
'platform': 'unknown',
|
||||
|
||||
@ -47,33 +47,53 @@ class KRSiteConfigService extends ChangeNotifier {
|
||||
/// 初始化站点配置
|
||||
Future<bool> initialize() async {
|
||||
try {
|
||||
print('🔧 KRSiteConfigService.initialize() 开始执行');
|
||||
if (kDebugMode) {
|
||||
print('🔧 KRSiteConfigService.initialize() 开始执行');
|
||||
}
|
||||
KRLogUtil.kr_i('🔧 开始初始化网站配置', tag: 'KRSiteConfigService');
|
||||
|
||||
// Debug 模式下使用固定地址
|
||||
final baseUrl = AppConfig().baseUrl;
|
||||
print('📍 baseUrl = $baseUrl');
|
||||
if (kDebugMode) {
|
||||
print('📍 baseUrl = $baseUrl');
|
||||
}
|
||||
final url = '$baseUrl/v1/common/site/config';
|
||||
print('📍 完整URL = $url');
|
||||
if (kDebugMode) {
|
||||
print('📍 完整URL = $url');
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('📤 请求网站配置 - $url', tag: 'KRSiteConfigService');
|
||||
print('📤 准备发送 GET 请求到: $url');
|
||||
print('⏱️ 超时配置: connectTimeout=10s, sendTimeout=10s, receiveTimeout=10s');
|
||||
if (kDebugMode) {
|
||||
print('📤 准备发送 GET 请求到: $url');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('⏱️ 超时配置: connectTimeout=10s, sendTimeout=10s, receiveTimeout=10s');
|
||||
}
|
||||
|
||||
print('⏳ 开始发送请求...');
|
||||
if (kDebugMode) {
|
||||
print('⏳ 开始发送请求...');
|
||||
}
|
||||
final startTime = DateTime.now();
|
||||
final response = await _dio.get(url);
|
||||
final endTime = DateTime.now();
|
||||
final duration = endTime.difference(startTime).inMilliseconds;
|
||||
print('⏱️ 请求耗时: ${duration}ms');
|
||||
if (kDebugMode) {
|
||||
print('⏱️ 请求耗时: ${duration}ms');
|
||||
}
|
||||
|
||||
print('✅ 请求完成,状态码: ${response.statusCode}');
|
||||
if (kDebugMode) {
|
||||
print('✅ 请求完成,状态码: ${response.statusCode}');
|
||||
}
|
||||
KRLogUtil.kr_i('📥 响应状态码 - ${response.statusCode}', tag: 'KRSiteConfigService');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseData = response.data;
|
||||
print('📥 响应数据类型: ${responseData.runtimeType}');
|
||||
print('📥 响应数据: $responseData');
|
||||
if (kDebugMode) {
|
||||
print('📥 响应数据类型: ${responseData.runtimeType}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📥 响应数据: $responseData');
|
||||
}
|
||||
KRLogUtil.kr_i('📥 响应数据 - $responseData', tag: 'KRSiteConfigService');
|
||||
|
||||
if (responseData['code'] == 200) {
|
||||
@ -96,24 +116,46 @@ class KRSiteConfigService extends ChangeNotifier {
|
||||
return false;
|
||||
}
|
||||
} on DioException catch (e, stackTrace) {
|
||||
print('❌ Dio请求异常: ${e.type}');
|
||||
print('❌ 错误信息: ${e.message}');
|
||||
print('❌ 请求URL: ${e.requestOptions.uri}');
|
||||
print('❌ 连接超时: ${e.requestOptions.connectTimeout}');
|
||||
print('❌ 发送超时: ${e.requestOptions.sendTimeout}');
|
||||
print('❌ 接收超时: ${e.requestOptions.receiveTimeout}');
|
||||
if (e.response != null) {
|
||||
print('❌ 响应状态码: ${e.response?.statusCode}');
|
||||
print('❌ 响应数据: ${e.response?.data}');
|
||||
if (kDebugMode) {
|
||||
print('❌ Dio请求异常: ${e.type}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('❌ 错误信息: ${e.message}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('❌ 请求URL: ${e.requestOptions.uri}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('❌ 连接超时: ${e.requestOptions.connectTimeout}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('❌ 发送超时: ${e.requestOptions.sendTimeout}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('❌ 接收超时: ${e.requestOptions.receiveTimeout}');
|
||||
}
|
||||
if (e.response != null) {
|
||||
if (kDebugMode) {
|
||||
print('❌ 响应状态码: ${e.response?.statusCode}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('❌ 响应数据: ${e.response?.data}');
|
||||
}
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📚 堆栈跟踪: $stackTrace');
|
||||
}
|
||||
print('📚 堆栈跟踪: $stackTrace');
|
||||
|
||||
KRLogUtil.kr_e('❌ Dio异常 - ${e.type}: ${e.message}', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
|
||||
return false;
|
||||
} catch (e, stackTrace) {
|
||||
print('❌ 未知异常: $e');
|
||||
print('📚 堆栈跟踪: $stackTrace');
|
||||
if (kDebugMode) {
|
||||
print('❌ 未知异常: $e');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print('📚 堆栈跟踪: $stackTrace');
|
||||
}
|
||||
KRLogUtil.kr_e('❌ 初始化失败 - $e', tag: 'KRSiteConfigService');
|
||||
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
|
||||
return false;
|
||||
|
||||
@ -22,6 +22,7 @@ import '../../utils/kr_country_util.dart';
|
||||
import '../../utils/kr_log_util.dart';
|
||||
import '../../utils/kr_secure_storage.dart';
|
||||
import '../../common/app_run_data.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
enum KRConnectionType {
|
||||
global,
|
||||
@ -549,14 +550,18 @@ class KRSingBoxImp {
|
||||
/// 订阅状态变化流
|
||||
/// 参考 hiddify-app: 监听 libcore 发送的状态事件来自动更新 UI
|
||||
void _kr_subscribeToStatus() {
|
||||
print('🔵 _kr_subscribeToStatus 被调用,重新订阅状态流');
|
||||
if (kDebugMode) {
|
||||
print('🔵 _kr_subscribeToStatus 被调用,重新订阅状态流');
|
||||
}
|
||||
KRLogUtil.kr_i('🔵 _kr_subscribeToStatus 被调用', tag: 'SingBox');
|
||||
|
||||
// 取消之前的状态订阅
|
||||
for (var sub in _kr_subscriptions) {
|
||||
if (sub.hashCode.toString().contains('Status')) {
|
||||
sub.cancel();
|
||||
print('🔵 已取消旧的状态订阅');
|
||||
if (kDebugMode) {
|
||||
print('🔵 已取消旧的状态订阅');
|
||||
}
|
||||
}
|
||||
}
|
||||
_kr_subscriptions
|
||||
@ -565,19 +570,25 @@ class KRSingBoxImp {
|
||||
_kr_subscriptions.add(
|
||||
kr_singBox.watchStatus().listen(
|
||||
(status) {
|
||||
print('🔵 收到 Native 状态更新: ${status.runtimeType}');
|
||||
if (kDebugMode) {
|
||||
print('🔵 收到 Native 状态更新: ${status.runtimeType}');
|
||||
}
|
||||
KRLogUtil.kr_i('📡 收到状态更新: $status', tag: 'SingBox');
|
||||
kr_status.value = status;
|
||||
},
|
||||
onError: (error) {
|
||||
print('🔵 状态流错误: $error');
|
||||
if (kDebugMode) {
|
||||
print('🔵 状态流错误: $error');
|
||||
}
|
||||
KRLogUtil.kr_e('📡 状态流错误: $error', tag: 'SingBox');
|
||||
},
|
||||
cancelOnError: false,
|
||||
),
|
||||
);
|
||||
|
||||
print('🔵 状态流订阅完成');
|
||||
if (kDebugMode) {
|
||||
print('🔵 状态流订阅完成');
|
||||
}
|
||||
}
|
||||
|
||||
/// 订阅统计数据流
|
||||
@ -1141,7 +1152,9 @@ class KRSingBoxImp {
|
||||
final selectedNode = await KRSecureStorage().kr_readData(key: _keySelectedNode);
|
||||
if (selectedNode != null && selectedNode.isNotEmpty) {
|
||||
KRLogUtil.kr_i('🎯 恢复用户选择的节点: $selectedNode', tag: 'SingBox');
|
||||
print('🔵 启动后恢复节点选择: $selectedNode');
|
||||
if (kDebugMode) {
|
||||
print('🔵 启动后恢复节点选择: $selectedNode');
|
||||
}
|
||||
|
||||
// 延迟500ms确保sing-box完全启动
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
@ -1150,18 +1163,26 @@ class KRSingBoxImp {
|
||||
try {
|
||||
await kr_selectOutbound(selectedNode);
|
||||
KRLogUtil.kr_i('✅ 节点已切换到用户选择: $selectedNode', tag: 'SingBox');
|
||||
print('🔵 节点切换成功: $selectedNode');
|
||||
if (kDebugMode) {
|
||||
print('🔵 节点切换成功: $selectedNode');
|
||||
}
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('❌ 节点切换失败: $e', tag: 'SingBox');
|
||||
print('🔵 节点切换失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('🔵 节点切换失败: $e');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
KRLogUtil.kr_i('ℹ️ 没有保存的节点选择,使用默认配置', tag: 'SingBox');
|
||||
print('🔵 没有保存的节点选择,使用默认');
|
||||
if (kDebugMode) {
|
||||
print('🔵 没有保存的节点选择,使用默认');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('❌ 恢复节点选择失败: $e', tag: 'SingBox');
|
||||
print('🔵 恢复节点选择失败: $e');
|
||||
if (kDebugMode) {
|
||||
print('🔵 恢复节点选择失败: $e');
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (e, stackTrace) {
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:loggy/loggy.dart';
|
||||
|
||||
/// 日志工具类
|
||||
/// 🔒 Release模式下所有日志都不会输出,确保生产环境的性能和安全
|
||||
class KRLogUtil {
|
||||
static final KRLogUtil _instance = KRLogUtil._internal();
|
||||
factory KRLogUtil() => _instance;
|
||||
@ -8,38 +10,59 @@ class KRLogUtil {
|
||||
|
||||
/// 初始化日志
|
||||
static void kr_init() {
|
||||
Loggy.initLoggy(
|
||||
logPrinter: PrettyPrinter(),
|
||||
);
|
||||
// 只在 Debug 模式下初始化日志
|
||||
if (kDebugMode) {
|
||||
Loggy.initLoggy(
|
||||
logPrinter: PrettyPrinter(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 调试日志
|
||||
/// 🔒 只在 Debug 模式下输出
|
||||
static void kr_d(String message, {String? tag}) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').debug(message);
|
||||
if (kDebugMode) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').debug(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// 信息日志
|
||||
/// 🔒 只在 Debug 模式下输出
|
||||
static void kr_i(String message, {String? tag}) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').info(message);
|
||||
if (kDebugMode) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').info(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// 警告日志
|
||||
/// 🔒 只在 Debug 模式下输出
|
||||
static void kr_w(String message, {String? tag}) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').warning(message);
|
||||
if (kDebugMode) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').warning(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// 错误日志
|
||||
/// 🔒 只在 Debug 模式下输出
|
||||
static void kr_e(String message, {String? tag, Object? error, StackTrace? stackTrace}) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').error(message, error, stackTrace);
|
||||
if (kDebugMode) {
|
||||
Loggy('${tag ?? 'KRLogUtil'}').error(message, error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// 网络日志
|
||||
/// 🔒 只在 Debug 模式下输出
|
||||
static void kr_network(String message, {String? tag}) {
|
||||
Loggy('${tag ?? 'Network'}').info(message);
|
||||
if (kDebugMode) {
|
||||
Loggy('${tag ?? 'Network'}').info(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// 性能日志
|
||||
/// 🔒 只在 Debug 模式下输出
|
||||
static void kr_performance(String message, {String? tag}) {
|
||||
Loggy('${tag ?? 'Performance'}').info(message);
|
||||
if (kDebugMode) {
|
||||
Loggy('${tag ?? 'Performance'}').info(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:country_flags/country_flags.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class KRCountryFlag extends StatelessWidget {
|
||||
final String countryCode;
|
||||
@ -38,17 +39,29 @@ class KRCountryFlag extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 🔍 调试日志
|
||||
print('🏳️ KRCountryFlag.build 被调用');
|
||||
print(' - 原始 countryCode: "$countryCode"');
|
||||
print(' - countryCode.isEmpty: ${countryCode.isEmpty}');
|
||||
print(' - countryCode.length: ${countryCode.length}');
|
||||
if (kDebugMode) {
|
||||
print('🏳️ KRCountryFlag.build 被调用');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - 原始 countryCode: "$countryCode"');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - countryCode.isEmpty: ${countryCode.isEmpty}');
|
||||
}
|
||||
if (kDebugMode) {
|
||||
print(' - countryCode.length: ${countryCode.length}');
|
||||
}
|
||||
|
||||
final processedCode = _getCountryCode(countryCode);
|
||||
print(' - 处理后 code: "$processedCode"');
|
||||
if (kDebugMode) {
|
||||
print(' - 处理后 code: "$processedCode"');
|
||||
}
|
||||
|
||||
// 如果国家代码为空,显示占位符
|
||||
if (countryCode.isEmpty) {
|
||||
print(' ❌ 国家代码为空,显示占位符');
|
||||
if (kDebugMode) {
|
||||
print(' ❌ 国家代码为空,显示占位符');
|
||||
}
|
||||
return Container(
|
||||
width: width ?? 50.w,
|
||||
height: height ?? 50.w,
|
||||
@ -65,7 +78,9 @@ class KRCountryFlag extends StatelessWidget {
|
||||
final double actualWidth = width ?? 50.w;
|
||||
final double actualHeight = maintainSize ? actualWidth : (height ?? 50.w);
|
||||
|
||||
print(' ✅ 尝试加载国旗: $processedCode');
|
||||
if (kDebugMode) {
|
||||
print(' ✅ 尝试加载国旗: $processedCode');
|
||||
}
|
||||
|
||||
Widget flagWidget = CountryFlag.fromCountryCode(
|
||||
processedCode,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user