feat: 1.调整项目初始化,不用等待site/config接口,仅在hi_user_info中调用;将site_config_service拆成loadDomain和获取配置,在splash中只做loadDomain

2. 优化接口拦截的解密日志
3. 调整获取订阅到kr_home,与源版一致
4. 修复闪连抖动问题,增加套餐有效期判断
This commit is contained in:
speakeloudest 2026-01-13 18:07:11 -08:00
parent 1d2a89a80a
commit ccf9a76de9
22 changed files with 737 additions and 1379 deletions

View File

@ -23,15 +23,16 @@ class KRProtocol {
/// ///
class KRDomain { class KRDomain {
static const String kr_domainKey = "kr_base_domain"; static const String kr_domainKey = "kr_base_domain";
static const String kr_domainsKey = "kr_domains_list"; static const String kr_domainsKey = "kr_domains_list";
// static List<String> kr_baseDomains = ["apicn.bearvpn.top","apibear.nsdsox.com"]; // static List<String> kr_baseDomains = ["apicn.bearvpn.top","apibear.nsdsox.com"];
// static String kr_currentDomain = "apicn.bearvpn.top"; // static String kr_currentDomain = "apicn.bearvpn.top";
static List<String> kr_baseDomains = ["api.hifast.biz", "api.airovpn.tel",]; static List<String> kr_baseDomains = [
"api.hifast.biz",
"api.airovpn.tel",
];
static String kr_currentDomain = "api.hifast.biz"; static String kr_currentDomain = "api.hifast.biz";
// //
@ -170,7 +171,8 @@ class KRDomain {
sendTimeout: Duration(seconds: 2), // 2 sendTimeout: Duration(seconds: 2), // 2
receiveTimeout: Duration(seconds: 2), receiveTimeout: Duration(seconds: 2),
// //
validateStatus: (status) => status != null && status >= 200 && status < 600, validateStatus: (status) =>
status != null && status >= 200 && status < 600,
), ),
); );
final endTime = DateTime.now(); final endTime = DateTime.now();
@ -181,10 +183,13 @@ class KRDomain {
// 404403 // 404403
if (response.statusCode != null) { if (response.statusCode != null) {
KRLogUtil.kr_i('✅ 快速检测成功,域名 $domain 可用,状态码: ${response.statusCode},响应时间: ${responseTime}ms', tag: 'KRDomain'); KRLogUtil.kr_i(
'✅ 快速检测成功,域名 $domain 可用,状态码: ${response.statusCode},响应时间: ${responseTime}ms',
tag: 'KRDomain');
return true; return true;
} else { } else {
KRLogUtil.kr_w('❌ 快速检测失败,域名 $domain 响应异常,状态码: ${response.statusCode}', tag: 'KRDomain'); KRLogUtil.kr_w('❌ 快速检测失败,域名 $domain 响应异常,状态码: ${response.statusCode}',
tag: 'KRDomain');
return false; return false;
} }
} on DioException catch (e) { } on DioException catch (e) {
@ -193,11 +198,14 @@ class KRDomain {
e.type == DioExceptionType.receiveTimeout || e.type == DioExceptionType.receiveTimeout ||
e.type == DioExceptionType.sendTimeout || e.type == DioExceptionType.sendTimeout ||
e.type == DioExceptionType.connectionError) { e.type == DioExceptionType.connectionError) {
KRLogUtil.kr_w('❌ 快速检测失败,域名 $domain 连接超时或网络错误: ${e.message}', tag: 'KRDomain'); KRLogUtil.kr_w('❌ 快速检测失败,域名 $domain 连接超时或网络错误: ${e.message}',
tag: 'KRDomain');
return false; return false;
} else { } else {
// //
KRLogUtil.kr_w('❌ 快速检测失败,域名 $domain 其他异常 (Type: ${e.type}): ${e.message}', tag: 'KRDomain'); KRLogUtil.kr_w(
'❌ 快速检测失败,域名 $domain 其他异常 (Type: ${e.type}): ${e.message}',
tag: 'KRDomain');
return false; return false;
} }
} catch (e) { } catch (e) {
@ -219,8 +227,11 @@ class KRDomain {
// 🔧 2 5000ms 10000ms // 🔧 2 5000ms 10000ms
// 使 // 使
final responseTime = _domainResponseTimes[domain]; final responseTime = _domainResponseTimes[domain];
if (responseTime != null && responseTime < 10000) { // 10 if (responseTime != null && responseTime < 10000) {
KRLogUtil.kr_i('📋 使用缓存结果,域名 $domain 可用(缓存时间: ${timeSinceLastCheck}s响应时间: ${responseTime}ms', tag: 'KRDomain'); // 10
KRLogUtil.kr_i(
'📋 使用缓存结果,域名 $domain 可用(缓存时间: ${timeSinceLastCheck}s响应时间: ${responseTime}ms',
tag: 'KRDomain');
return true; return true;
} }
} }
@ -236,7 +247,8 @@ class KRDomain {
sendTimeout: Duration(seconds: kr_domainTimeout), sendTimeout: Duration(seconds: kr_domainTimeout),
receiveTimeout: Duration(seconds: kr_domainTimeout), receiveTimeout: Duration(seconds: kr_domainTimeout),
// //
validateStatus: (status) => status != null && status >= 200 && status < 600, validateStatus: (status) =>
status != null && status >= 200 && status < 600,
), ),
); );
final endTime = DateTime.now(); final endTime = DateTime.now();
@ -248,10 +260,13 @@ class KRDomain {
// 404403 // 404403
if (response.statusCode != null) { if (response.statusCode != null) {
KRLogUtil.kr_i('✅ 域名 $domain 可用,状态码: ${response.statusCode},响应时间: ${responseTime}ms', tag: 'KRDomain'); KRLogUtil.kr_i(
'✅ 域名 $domain 可用,状态码: ${response.statusCode},响应时间: ${responseTime}ms',
tag: 'KRDomain');
return true; return true;
} else { } else {
KRLogUtil.kr_w('❌ 域名 $domain 响应异常,状态码: ${response.statusCode}', tag: 'KRDomain'); KRLogUtil.kr_w('❌ 域名 $domain 响应异常,状态码: ${response.statusCode}',
tag: 'KRDomain');
return false; return false;
} }
} on DioException catch (e) { } on DioException catch (e) {
@ -264,7 +279,8 @@ class KRDomain {
return false; return false;
} else { } else {
// //
KRLogUtil.kr_w('❌ 域名 $domain 检查异常 (Type: ${e.type}): ${e.message}', tag: 'KRDomain'); KRLogUtil.kr_w('❌ 域名 $domain 检查异常 (Type: ${e.type}): ${e.message}',
tag: 'KRDomain');
return false; return false;
} }
} catch (e) { } catch (e) {
@ -296,7 +312,9 @@ class KRDomain {
static Future<String?> kr_fastDomainSwitch() async { static Future<String?> kr_fastDomainSwitch() async {
if (kr_baseDomains.isEmpty) return null; if (kr_baseDomains.isEmpty) return null;
KRLogUtil.kr_i('🚀 开始快速域名切换,检测 ${kr_baseDomains.length} 个主域名: $kr_baseDomains', tag: 'KRDomain'); KRLogUtil.kr_i(
'🚀 开始快速域名切换,检测 ${kr_baseDomains.length} 个主域名: $kr_baseDomains',
tag: 'KRDomain');
final startTime = DateTime.now(); final startTime = DateTime.now();
// 🔧 5 // 🔧 5
@ -304,7 +322,8 @@ class KRDomain {
return await _executeFastDomainSwitch(startTime).timeout( return await _executeFastDomainSwitch(startTime).timeout(
Duration(seconds: kr_maxDomainSwitchTimeout), Duration(seconds: kr_maxDomainSwitchTimeout),
onTimeout: () { onTimeout: () {
KRLogUtil.kr_e('⏰ 域名切换总超时(${kr_maxDomainSwitchTimeout}秒)', tag: 'KRDomain'); KRLogUtil.kr_e('⏰ 域名切换总超时(${kr_maxDomainSwitchTimeout}秒)',
tag: 'KRDomain');
return null; return null;
}, },
); );
@ -316,17 +335,20 @@ class KRDomain {
/// ///
static Future<String?> _executeFastDomainSwitch(DateTime startTime) async { static Future<String?> _executeFastDomainSwitch(DateTime startTime) async {
// //
for (String domain in kr_baseDomains) { for (String domain in kr_baseDomains) {
final lastCheck = _domainLastCheck[domain]; final lastCheck = _domainLastCheck[domain];
if (lastCheck != null) { if (lastCheck != null) {
final timeSinceLastCheck = DateTime.now().difference(lastCheck).inSeconds; final timeSinceLastCheck =
DateTime.now().difference(lastCheck).inSeconds;
if (timeSinceLastCheck < _domainCacheDuration) { if (timeSinceLastCheck < _domainCacheDuration) {
final responseTime = _domainResponseTimes[domain]; final responseTime = _domainResponseTimes[domain];
// 🔧 2 2000ms 5000ms // 🔧 2 2000ms 5000ms
if (responseTime != null && responseTime < 5000) { // 5 if (responseTime != null && responseTime < 5000) {
KRLogUtil.kr_i('🎯 使用缓存结果快速切换,域名: $domain (响应时间: ${responseTime}ms)', tag: 'KRDomain'); // 5
KRLogUtil.kr_i(
'🎯 使用缓存结果快速切换,域名: $domain (响应时间: ${responseTime}ms)',
tag: 'KRDomain');
return domain; return domain;
} }
} }
@ -334,7 +356,8 @@ class KRDomain {
} }
// //
List<Future<MapEntry<String, bool>>> tasks = kr_baseDomains.map((domain) async { List<Future<MapEntry<String, bool>>> tasks =
kr_baseDomains.map((domain) async {
bool isAvailable = await kr_checkDomainAvailability(domain); bool isAvailable = await kr_checkDomainAvailability(domain);
return MapEntry(domain, isAvailable); return MapEntry(domain, isAvailable);
}).toList(); }).toList();
@ -361,7 +384,8 @@ class KRDomain {
} }
} }
KRLogUtil.kr_i('📈 主域名检测结果: $availableCount/${results.length} 可用', tag: 'KRDomain'); KRLogUtil.kr_i('📈 主域名检测结果: $availableCount/${results.length} 可用',
tag: 'KRDomain');
// //
for (MapEntry<String, bool> result in results) { for (MapEntry<String, bool> result in results) {
@ -393,7 +417,8 @@ class KRDomain {
const fallbackDomain = "api.airovpn.tel"; const fallbackDomain = "api.airovpn.tel";
// //
bool isFallbackAvailable = await kr_fastCheckDomainAvailability(fallbackDomain); bool isFallbackAvailable =
await kr_fastCheckDomainAvailability(fallbackDomain);
if (isFallbackAvailable) { if (isFallbackAvailable) {
KRLogUtil.kr_i('✅ 兜底域名可用: $fallbackDomain', tag: 'KRDomain'); KRLogUtil.kr_i('✅ 兜底域名可用: $fallbackDomain', tag: 'KRDomain');
return fallbackDomain; return fallbackDomain;
@ -401,7 +426,6 @@ class KRDomain {
KRLogUtil.kr_e('❌ 兜底域名也不可用: $fallbackDomain', tag: 'KRDomain'); KRLogUtil.kr_e('❌ 兜底域名也不可用: $fallbackDomain', tag: 'KRDomain');
return null; // null return null; // null
} catch (e) { } catch (e) {
final endTime = DateTime.now(); final endTime = DateTime.now();
final duration = endTime.difference(startTime).inMilliseconds; final duration = endTime.difference(startTime).inMilliseconds;
@ -434,7 +458,8 @@ class KRDomain {
try { try {
// //
if (kr_baseDomains.contains(kr_currentDomain)) { if (kr_baseDomains.contains(kr_currentDomain)) {
bool isCurrentAvailable = await kr_fastCheckDomainAvailability(kr_currentDomain); bool isCurrentAvailable =
await kr_fastCheckDomainAvailability(kr_currentDomain);
if (isCurrentAvailable) { if (isCurrentAvailable) {
KRLogUtil.kr_i('✅ 当前域名可用,无需切换: $kr_currentDomain', tag: 'KRDomain'); KRLogUtil.kr_i('✅ 当前域名可用,无需切换: $kr_currentDomain', tag: 'KRDomain');
return; // return; //
@ -473,7 +498,8 @@ class KRDomain {
final startTime = DateTime.now(); final startTime = DateTime.now();
// //
List<Future<List<String>>> backupTasks = kr_backupDomainUrls.map((url) async { List<Future<List<String>>> backupTasks =
kr_backupDomainUrls.map((url) async {
try { try {
KRLogUtil.kr_i('📡 从备用地址获取域名: $url', tag: 'KRDomain'); KRLogUtil.kr_i('📡 从备用地址获取域名: $url', tag: 'KRDomain');
final response = await _dio.get( final response = await _dio.get(
@ -491,7 +517,8 @@ class KRDomain {
KRLogUtil.kr_i('🔍 解析到备用域名: $domains', tag: 'KRDomain'); KRLogUtil.kr_i('🔍 解析到备用域名: $domains', tag: 'KRDomain');
return domains; return domains;
} else { } else {
KRLogUtil.kr_w('❌ 备用地址 $url 响应异常,状态码: ${response.statusCode}', tag: 'KRDomain'); KRLogUtil.kr_w('❌ 备用地址 $url 响应异常,状态码: ${response.statusCode}',
tag: 'KRDomain');
} }
} catch (e) { } catch (e) {
KRLogUtil.kr_w('❌ 备用地址 $url 获取失败: $e', tag: 'KRDomain'); KRLogUtil.kr_w('❌ 备用地址 $url 获取失败: $e', tag: 'KRDomain');
@ -500,7 +527,8 @@ class KRDomain {
}).toList(); }).toList();
try { try {
KRLogUtil.kr_i('⏱️ 等待备用地址响应,超时时间: ${kr_totalTimeout - 1}', tag: 'KRDomain'); KRLogUtil.kr_i('⏱️ 等待备用地址响应,超时时间: ${kr_totalTimeout - 1}',
tag: 'KRDomain');
List<List<String>> backupResults = await Future.wait( List<List<String>> backupResults = await Future.wait(
backupTasks, backupTasks,
).timeout(Duration(seconds: kr_totalTimeout - 1)); // 1 ).timeout(Duration(seconds: kr_totalTimeout - 1)); // 1
@ -519,10 +547,12 @@ class KRDomain {
return null; return null;
} }
KRLogUtil.kr_i('🧪 开始测试 ${allBackupDomains.length} 个备用域名', tag: 'KRDomain'); KRLogUtil.kr_i('🧪 开始测试 ${allBackupDomains.length} 个备用域名',
tag: 'KRDomain');
// //
List<Future<MapEntry<String, bool>>> testTasks = allBackupDomains.map((domain) async { List<Future<MapEntry<String, bool>>> testTasks =
allBackupDomains.map((domain) async {
bool isAvailable = await kr_checkDomainAvailability(domain); bool isAvailable = await kr_checkDomainAvailability(domain);
return MapEntry(domain, isAvailable); return MapEntry(domain, isAvailable);
}).toList(); }).toList();
@ -546,7 +576,9 @@ class KRDomain {
} }
} }
KRLogUtil.kr_i('📈 备用域名检测结果: $availableBackupCount/${testResults.length} 可用', tag: 'KRDomain'); KRLogUtil.kr_i(
'📈 备用域名检测结果: $availableBackupCount/${testResults.length} 可用',
tag: 'KRDomain');
// //
for (MapEntry<String, bool> result in testResults) { for (MapEntry<String, bool> result in testResults) {
@ -573,7 +605,6 @@ class KRDomain {
KRLogUtil.kr_w('⚠️ 所有备用域名都不可用', tag: 'KRDomain'); KRLogUtil.kr_w('⚠️ 所有备用域名都不可用', tag: 'KRDomain');
return null; return null;
} catch (e) { } catch (e) {
final endTime = DateTime.now(); final endTime = DateTime.now();
final duration = endTime.difference(startTime).inMilliseconds; final duration = endTime.difference(startTime).inMilliseconds;
@ -630,7 +661,8 @@ class KRDomain {
for (int i = 0; i < jsonList.length; i++) { for (int i = 0; i < jsonList.length; i++) {
dynamic item = jsonList[i]; dynamic item = jsonList[i];
KRLogUtil.kr_i('🔍 处理第 $i 项: $item (类型: ${item.runtimeType})', tag: 'KRDomain'); KRLogUtil.kr_i('🔍 处理第 $i 项: $item (类型: ${item.runtimeType})',
tag: 'KRDomain');
if (item is String) { if (item is String) {
// //
@ -674,7 +706,8 @@ class KRDomain {
try { try {
// JSON对象 // JSON对象
Map<String, dynamic> jsonMap = json.decode(jsonData); Map<String, dynamic> jsonMap = json.decode(jsonData);
KRLogUtil.kr_i('📋 解析为JSON对象键数量: ${jsonMap.length}', tag: 'KRDomain'); KRLogUtil.kr_i('📋 解析为JSON对象键数量: ${jsonMap.length}',
tag: 'KRDomain');
jsonMap.forEach((key, value) { jsonMap.forEach((key, value) {
KRLogUtil.kr_i('🔍 键: $key, 值: $value', tag: 'KRDomain'); KRLogUtil.kr_i('🔍 键: $key, 值: $value', tag: 'KRDomain');
@ -747,8 +780,8 @@ class KRDomain {
} }
} }
KRLogUtil.kr_i('📊 解析完成,总共提取到 ${domains.length} 个域名: $domains', tag: 'KRDomain'); KRLogUtil.kr_i('📊 解析完成,总共提取到 ${domains.length} 个域名: $domains',
tag: 'KRDomain');
} catch (e) { } catch (e) {
KRLogUtil.kr_e('❌ 解析备用域名数据失败: $e', tag: 'KRDomain'); KRLogUtil.kr_e('❌ 解析备用域名数据失败: $e', tag: 'KRDomain');
} }
@ -796,7 +829,8 @@ class KRDomain {
/// ///
static Future<void> kr_handleDomains(List<String> domains) async { static Future<void> kr_handleDomains(List<String> domains) async {
// //
List<String> extractedDomains = domains.map((url) => kr_extractDomain(url)).toList(); List<String> extractedDomains =
domains.map((url) => kr_extractDomain(url)).toList();
// 使 // 使
if (extractedDomains.isEmpty) { if (extractedDomains.isEmpty) {
@ -835,7 +869,9 @@ class KRDomain {
if (age < _domainCacheDuration && !_triedDomains.contains(domain)) { if (age < _domainCacheDuration && !_triedDomains.contains(domain)) {
kr_currentDomain = domain; kr_currentDomain = domain;
await kr_saveCurrentDomain(); await kr_saveCurrentDomain();
KRLogUtil.kr_i('✅ 使用缓存的成功域名: $kr_currentDomain (响应时间: ${responseTime}ms)', tag: 'KRDomain'); KRLogUtil.kr_i(
'✅ 使用缓存的成功域名: $kr_currentDomain (响应时间: ${responseTime}ms)',
tag: 'KRDomain');
return true; return true;
} }
} }
@ -899,7 +935,8 @@ class KRDomain {
_triedDomains.clear(); _triedDomains.clear();
// //
_retryTimer = Timer.periodic(Duration(seconds: kr_retryInterval), (timer) async { _retryTimer =
Timer.periodic(Duration(seconds: kr_retryInterval), (timer) async {
// //
bool hasNextDomain = await kr_switchToNextDomain(); bool hasNextDomain = await kr_switchToNextDomain();
if (!hasNextDomain) { if (!hasNextDomain) {
@ -978,13 +1015,15 @@ class KRDomain {
final startTime = DateTime.now(); final startTime = DateTime.now();
// //
List<Future<MapEntry<String, bool>>> tasks = kr_localBackupDomains.map((domain) async { List<Future<MapEntry<String, bool>>> tasks =
kr_localBackupDomains.map((domain) async {
bool isAvailable = await kr_checkDomainAvailability(domain); bool isAvailable = await kr_checkDomainAvailability(domain);
return MapEntry(domain, isAvailable); return MapEntry(domain, isAvailable);
}).toList(); }).toList();
try { try {
KRLogUtil.kr_i('⏱️ 等待本地备用域名检测结果,超时时间: ${kr_totalTimeout}', tag: 'KRDomain'); KRLogUtil.kr_i('⏱️ 等待本地备用域名检测结果,超时时间: ${kr_totalTimeout}',
tag: 'KRDomain');
List<MapEntry<String, bool>> results = await Future.wait( List<MapEntry<String, bool>> results = await Future.wait(
tasks, tasks,
).timeout(Duration(seconds: kr_totalTimeout)); ).timeout(Duration(seconds: kr_totalTimeout));
@ -1004,7 +1043,8 @@ class KRDomain {
} }
} }
KRLogUtil.kr_i('📈 本地备用域名检测结果: $availableCount/${results.length} 可用', tag: 'KRDomain'); KRLogUtil.kr_i('📈 本地备用域名检测结果: $availableCount/${results.length} 可用',
tag: 'KRDomain');
// //
for (MapEntry<String, bool> result in results) { for (MapEntry<String, bool> result in results) {
@ -1029,7 +1069,6 @@ class KRDomain {
KRLogUtil.kr_w('⚠️ 所有本地备用域名都不可用', tag: 'KRDomain'); KRLogUtil.kr_w('⚠️ 所有本地备用域名都不可用', tag: 'KRDomain');
return null; return null;
} catch (e) { } catch (e) {
final endTime = DateTime.now(); final endTime = DateTime.now();
final duration = endTime.difference(startTime).inMilliseconds; final duration = endTime.difference(startTime).inMilliseconds;
@ -1107,7 +1146,8 @@ class KRDomain {
} }
final totalDuration = DateTime.now().difference(startTime).inMilliseconds; final totalDuration = DateTime.now().difference(startTime).inMilliseconds;
KRLogUtil.kr_i('✅ 域名加载完成,耗时: ${totalDuration}ms当前域名: $kr_currentDomain', tag: 'KRDomain'); KRLogUtil.kr_i('✅ 域名加载完成,耗时: ${totalDuration}ms当前域名: $kr_currentDomain',
tag: 'KRDomain');
} }
/// ///
@ -1115,7 +1155,8 @@ class KRDomain {
// //
String? savedDomains = await _storage.kr_readData(key: kr_domainsKey); String? savedDomains = await _storage.kr_readData(key: kr_domainsKey);
if (savedDomains != null && savedDomains.isNotEmpty) { if (savedDomains != null && savedDomains.isNotEmpty) {
kr_baseDomains = savedDomains.split(',').where((d) => d.isNotEmpty).toList(); kr_baseDomains =
savedDomains.split(',').where((d) => d.isNotEmpty).toList();
KRLogUtil.kr_i('📋 从 Hive 加载的域名列表: $kr_baseDomains', tag: 'KRDomain'); KRLogUtil.kr_i('📋 从 Hive 加载的域名列表: $kr_baseDomains', tag: 'KRDomain');
} else { } else {
KRLogUtil.kr_w('⚠️ Hive 中没有保存的域名列表,使用默认配置', tag: 'KRDomain'); KRLogUtil.kr_w('⚠️ Hive 中没有保存的域名列表,使用默认配置', tag: 'KRDomain');
@ -1125,13 +1166,16 @@ class KRDomain {
String? savedDomain = await _storage.kr_readData(key: kr_domainKey); String? savedDomain = await _storage.kr_readData(key: kr_domainKey);
KRLogUtil.kr_i('📌 从 Hive 加载的当前域名: $savedDomain', tag: 'KRDomain'); KRLogUtil.kr_i('📌 从 Hive 加载的当前域名: $savedDomain', tag: 'KRDomain');
if (savedDomain != null && savedDomain.isNotEmpty && kr_baseDomains.contains(savedDomain)) { if (savedDomain != null &&
savedDomain.isNotEmpty &&
kr_baseDomains.contains(savedDomain)) {
// 🔧 Android 15 Hive // 🔧 Android 15 Hive
KRLogUtil.kr_i('🔍 验证 Hive 缓存域名的可用性: $savedDomain', tag: 'KRDomain'); KRLogUtil.kr_i('🔍 验证 Hive 缓存域名的可用性: $savedDomain', tag: 'KRDomain');
try { try {
// 3 // 3
bool isAvailable = await kr_fastCheckDomainAvailability(savedDomain).timeout( bool isAvailable =
await kr_fastCheckDomainAvailability(savedDomain).timeout(
const Duration(seconds: 3), const Duration(seconds: 3),
onTimeout: () { onTimeout: () {
KRLogUtil.kr_w('⏱️ 域名验证超时(3秒),视为不可用', tag: 'KRDomain'); KRLogUtil.kr_w('⏱️ 域名验证超时(3秒),视为不可用', tag: 'KRDomain');
@ -1141,7 +1185,8 @@ class KRDomain {
if (isAvailable) { if (isAvailable) {
kr_currentDomain = savedDomain; kr_currentDomain = savedDomain;
KRLogUtil.kr_i('✅ Hive 缓存域名验证通过,继续使用: $kr_currentDomain', tag: 'KRDomain'); KRLogUtil.kr_i('✅ Hive 缓存域名验证通过,继续使用: $kr_currentDomain',
tag: 'KRDomain');
return; return;
} else { } else {
KRLogUtil.kr_w('❌ Hive 缓存域名不可用: $savedDomain,需要切换', tag: 'KRDomain'); KRLogUtil.kr_w('❌ Hive 缓存域名不可用: $savedDomain,需要切换', tag: 'KRDomain');
@ -1175,7 +1220,8 @@ class KRDomain {
if (isAvailable) { if (isAvailable) {
kr_currentDomain = domain; kr_currentDomain = domain;
await kr_saveCurrentDomain(); await kr_saveCurrentDomain();
KRLogUtil.kr_i('✅ 找到可用域名: $kr_currentDomain,已保存到 Hive', tag: 'KRDomain'); KRLogUtil.kr_i('✅ 找到可用域名: $kr_currentDomain,已保存到 Hive',
tag: 'KRDomain');
return; return;
} }
} catch (e) { } catch (e) {
@ -1300,8 +1346,6 @@ class AppConfig {
/// ///
String kr_invitation_link = ""; String kr_invitation_link = "";
/// ID
String kr_website_id = "";
/// ///
String device_limit = '0'; String device_limit = '0';
@ -1323,8 +1367,6 @@ class AppConfig {
static const int kr_maxRetryCount = 2; // - static const int kr_maxRetryCount = 2; // -
AppConfig._internal() { AppConfig._internal() {
//
KRDomain.kr_loadBaseDomain();
} }
factory AppConfig() => _instance; factory AppConfig() => _instance;
@ -1342,7 +1384,7 @@ class AppConfig {
Future<void> Function()? onSuccess, Future<void> Function()? onSuccess,
}) async { }) async {
_initLog.logSeparator(); _initLog.logSeparator();
_initLog.log('🌐 开始应用配置初始化(域名加载)', tag: 'Domain'); _initLog.log('🌐 开始应用配置初始化(跳过域名加载,前置已完成', tag: 'Domain');
if (_isInitializing) { if (_isInitializing) {
_initLog.logWarning('配置初始化已在进行中,跳过重复调用', tag: 'Domain'); _initLog.logWarning('配置初始化已在进行中,跳过重复调用', tag: 'Domain');
@ -1352,149 +1394,16 @@ class AppConfig {
_isInitializing = true; _isInitializing = true;
try { try {
// 🔧 6 // _kr_initSiteConfig / KRSiteConfigService.initializeDomains
_initLog.log('开始加载基础域名配置', tag: 'Domain'); //
await KRDomain.kr_loadBaseDomain(); if (onSuccess != null) {
_initLog.logSuccess('当前使用域名: ${KRDomain.kr_currentDomain}', tag: 'Domain'); await onSuccess();
KRLogUtil.kr_i('📍 当前使用域名: ${KRDomain.kr_currentDomain}', tag: 'AppConfig'); }
//
_initLog.log('开始配置请求流程(包含重试机制)', tag: 'Domain');
KRLogUtil.kr_i('🚀 开始配置初始化', tag: 'AppConfig');
await _startAutoRetry(onSuccess);
} finally { } finally {
_isInitializing = false; _isInitializing = false;
} }
} }
Future<void> _startAutoRetry(Future<void> Function()? onSuccess) async {
_retryTimer?.cancel();
int currentRetryCount = 0;
// 🔧 P0修复
int totalAttempts = 0;
const int maxTotalAttempts = 5; // 5
Future<void> executeConfigRequest() async {
try {
// 🔧 P0修复
totalAttempts++;
if (totalAttempts > maxTotalAttempts) {
KRLogUtil.kr_e('❌ 超过最大总尝试次数($maxTotalAttempts),停止重试', tag: 'AppConfig');
// 使
if (onSuccess != null) {
await onSuccess();
}
return;
}
//
if (currentRetryCount >= kr_maxRetryCount) {
KRLogUtil.kr_w('达到最大重试次数,尝试使用备用域名', tag: 'AppConfig');
// 使
String? newDomain = await KRDomain.kr_fastDomainSwitch();
if (newDomain != null) {
KRDomain.kr_currentDomain = newDomain;
await KRDomain.kr_saveCurrentDomain();
KRLogUtil.kr_i('✅ 最终切换到备用域名: $newDomain', tag: 'AppConfig');
//
currentRetryCount = 0;
//
await executeConfigRequest();
} else {
KRLogUtil.kr_e('❌ 备用域名切换失败,使用默认配置继续', tag: 'AppConfig');
// 使
if (onSuccess != null) {
await onSuccess();
}
}
return;
}
_initLog.log('发起配置请求 API (尝试 $totalAttempts/$maxTotalAttempts)', tag: 'Domain');
final result = await _kr_userApi.kr_config();
result.fold(
(error) async {
_initLog.logError('配置请求失败 (重试 $currentRetryCount/$kr_maxRetryCount)', tag: 'Domain', error: error);
KRLogUtil.kr_e('配置初始化失败: $error', tag: 'AppConfig');
currentRetryCount++;
//
final retryDelay = (kr_retryInterval * pow(kr_backoffFactor, currentRetryCount)).toInt();
final actualDelay = max(retryDelay, 100);
_initLog.log('将在 ${actualDelay}ms 后重试', tag: 'Domain');
//
_initLog.log('尝试切换到下一个备用域名', tag: 'Domain');
await KRDomain.kr_switchToNextDomain();
_initLog.log('当前域名: ${KRDomain.kr_currentDomain}', tag: 'Domain');
//
await Future.delayed(Duration(milliseconds: actualDelay));
await executeConfigRequest();
},
(config) async {
_initLog.logSuccess('配置请求成功!', tag: 'Domain');
_initLog.log('网站ID: ${config.kr_website_id}', tag: 'Domain');
_initLog.log('官网: ${config.kr_official_website}', tag: 'Domain');
_retryTimer?.cancel();
currentRetryCount = 0;
kr_official_email = config.kr_official_email;
kr_official_website = config.kr_official_website;
kr_official_telegram = config.kr_official_telegram;
kr_official_telephone = config.kr_official_telephone;
kr_invitation_link = config.kr_invitation_link;
// kr_website_id = config.kr_website_id;
if (config.kr_domains.isNotEmpty) {
KRDomain.kr_handleDomains(config.kr_domains);
}
///
kr_is_daytime = await config.kr_update_application.kr_is_daytime() ;
KRUpdateUtil().kr_initUpdateInfo(config.kr_update_application);
if (onSuccess != null) {
onSuccess();
}
},
);
} catch (e) {
KRLogUtil.kr_e('配置初始化异常: $e', tag: 'AppConfig');
currentRetryCount++;
//
if (currentRetryCount >= kr_maxRetryCount) {
KRLogUtil.kr_w('达到最大重试次数,尝试使用备用域名', tag: 'AppConfig');
// 使
String? newDomain = await KRDomain.kr_fastDomainSwitch();
if (newDomain != null) {
KRDomain.kr_currentDomain = newDomain;
await KRDomain.kr_saveCurrentDomain();
KRLogUtil.kr_i('✅ 最终切换到备用域名: $newDomain', tag: 'AppConfig');
//
await executeConfigRequest();
}
return;
}
//
final retryDelay = (kr_retryInterval * pow(kr_backoffFactor, currentRetryCount)).toInt();
//
await KRDomain.kr_switchToNextDomain();
// 100ms避免立即重试
final actualDelay = max(retryDelay, 100);
await Future.delayed(Duration(milliseconds: actualDelay));
await executeConfigRequest();
}
}
//
await executeConfigRequest();
}
/// ///
void kr_stopAutoRetry() { void kr_stopAutoRetry() {
_retryTimer?.cancel(); _retryTimer?.cancel();

View File

@ -52,9 +52,6 @@ class KRAppRunData {
/// ///
final RxInt kr_commission = 0.obs; final RxInt kr_commission = 0.obs;
///
KRLoginType? kr_loginType;
/// ID /// ID
String? deviceId; String? deviceId;
@ -72,6 +69,14 @@ class KRAppRunData {
return _instance; return _instance;
} }
DateTime _stepStartTime = DateTime.now();
void _logStepTiming(String stepName) {
final now = DateTime.now();
final stepMs = now.difference(_stepStartTime).inMilliseconds;
KRLogUtil.kr_i('[SPLASH_TIMING] ⏱️ $stepName 耗时: ${stepMs}ms',
tag: 'AppRunData');
_stepStartTime = now;
}
/// ///
bool isDeviceLogin() { bool isDeviceLogin() {
@ -87,7 +92,8 @@ class KRAppRunData {
// JWT格式检查: header.payload.signature (.) // JWT格式检查: header.payload.signature (.)
final parts = token.split('.'); final parts = token.split('.');
if (parts.length != 3) { if (parts.length != 3) {
KRLogUtil.kr_w('❌ Token格式无效分段数不对 (${parts.length} != 3)', tag: 'AppRunData'); KRLogUtil.kr_w('❌ Token格式无效分段数不对 (${parts.length} != 3)',
tag: 'AppRunData');
return false; return false;
} }
@ -185,8 +191,7 @@ class KRAppRunData {
Future<void> kr_saveUserInfo( Future<void> kr_saveUserInfo(
String token, String token,
String account, String account,
KRLoginType loginType, ) async {
String? areaCode) async {
KRLogUtil.kr_i('开始保存用户信息', tag: 'AppRunData'); KRLogUtil.kr_i('开始保存用户信息', tag: 'AppRunData');
try { try {
@ -197,15 +202,11 @@ class KRAppRunData {
// //
kr_token = token; kr_token = token;
kr_account.value = accountText; kr_account.value = accountText;
kr_loginType = loginType;
kr_areaCode = areaCode;
final Map<String, dynamic> userInfo = { final Map<String, dynamic> userInfo = {
'token': token, 'token': token,
'account': accountText, 'account': accountText,
'loginType': loginType.value,
'areaCode': areaCode ?? "",
}; };
KRLogUtil.kr_i('准备保存用户信息到存储', tag: 'AppRunData'); KRLogUtil.kr_i('准备保存用户信息到存储', tag: 'AppRunData');
@ -230,11 +231,11 @@ class KRAppRunData {
kr_isLogin.value = true; kr_isLogin.value = true;
KRLogUtil.kr_i('用户信息-kr_isLogin$kr_isLogin', tag: 'AppRunData'); KRLogUtil.kr_i('用户信息-kr_isLogin$kr_isLogin', tag: 'AppRunData');
// 🔧 refer_code KRLogUtil.kr_i('🔍 [AppRunData] 检查登录模式: account=$account',
KRLogUtil.kr_i('🔍 [AppRunData] 检查登录模式: account=$account', tag: 'AppRunData'); tag: 'AppRunData');
await _fetchUserInfo();
// userinfo接口返回
_fetchUserInfo();
} catch (e) { } catch (e) {
KRLogUtil.kr_e('保存用户信息失败: $e', tag: 'AppRunData'); KRLogUtil.kr_e('保存用户信息失败: $e', tag: 'AppRunData');
// //
@ -250,12 +251,14 @@ class KRAppRunData {
preventBackDismiss: true, preventBackDismiss: true,
confirmText: '确定', confirmText: '确定',
autoClose: false, autoClose: false,
onConfirm: () async{ onConfirm: () async {
// false // false
kr_isLogin.value = false; kr_isLogin.value = false;
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'AppRunData'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'AppRunData');
KRLogUtil.kr_i('开始重新进行设备登录', tag: 'AppRunData'); KRLogUtil.kr_i('开始重新进行设备登录', tag: 'AppRunData');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'AppRunData'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'AppRunData');
// === VPN === // === VPN ===
try { try {
// SingBox // SingBox
@ -274,17 +277,17 @@ class KRAppRunData {
kr_token = null; kr_token = null;
kr_account.value = null; kr_account.value = null;
kr_userId.value = null; kr_userId.value = null;
kr_loginType = null;
kr_areaCode = null; kr_areaCode = null;
// //
await KRSecureStorage().kr_deleteData(key: _keyUserInfo); await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
// 🔧 4: - 访 // 🔧 4: - 访
try { try {
final subscribeService = Get.find<dynamic>(tag: 'KRSubscribeService'); final subscribeService =
if (subscribeService != null && subscribeService is KRSubscribeService) { Get.find<dynamic>(tag: 'KRSubscribeService');
if (subscribeService != null &&
subscribeService is KRSubscribeService) {
KRLogUtil.kr_i('🧹 清理订阅服务数据...', tag: 'AppRunData'); KRLogUtil.kr_i('🧹 清理订阅服务数据...', tag: 'AppRunData');
await subscribeService.kr_logout(); await subscribeService.kr_logout();
KRLogUtil.kr_i('✅ 订阅服务数据已清理', tag: 'AppRunData'); KRLogUtil.kr_i('✅ 订阅服务数据已清理', tag: 'AppRunData');
@ -323,11 +326,10 @@ class KRAppRunData {
} }
Get.offAllNamed(Routes.KR_HOME); Get.offAllNamed(Routes.KR_HOME);
} });
);
} }
Future<void> kr_loginOut_loading() async{ Future<void> kr_loginOut_loading() async {
KRCommonUtil.kr_showLoading(); KRCommonUtil.kr_showLoading();
// false // false
kr_isLogin.value = false; kr_isLogin.value = false;
@ -353,13 +355,11 @@ class KRAppRunData {
kr_token = null; kr_token = null;
kr_account.value = null; kr_account.value = null;
kr_userId.value = null; kr_userId.value = null;
kr_loginType = null;
kr_areaCode = null; kr_areaCode = null;
// //
await KRSecureStorage().kr_deleteData(key: _keyUserInfo); await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
// 🔧 4: - 访 // 🔧 4: - 访
try { try {
final subscribeService = Get.find<dynamic>(tag: 'KRSubscribeService'); final subscribeService = Get.find<dynamic>(tag: 'KRSubscribeService');
@ -413,19 +413,24 @@ class KRAppRunData {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🔍 开始执行设备登录...'); print('🔍 开始执行设备登录...');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
_logStepTiming('设备登录开始');
// //
await KRDeviceInfoService().initialize(); await KRDeviceInfoService().initialize();
_logStepTiming('初始化设备信息完成');
KRLogUtil.kr_i('🔐 开始执行设备登录', tag: 'AppRunData'); KRLogUtil.kr_i('🔐 开始执行设备登录', tag: 'AppRunData');
// //
_logStepTiming('开始设备登录请求');
final authApi = KRAuthApi(); final authApi = KRAuthApi();
final result = await authApi.kr_deviceLogin(); final result = await authApi.kr_deviceLogin();
_logStepTiming('设备登录请求完成');
return await result.fold( return await result.fold(
(error) { (error) {
print('❌ 设备登录失败: ${error.msg}'); print('❌ 设备登录失败: ${error.msg}');
KRLogUtil.kr_e('❌ 设备登录失败: ${error.msg}', tag: 'SplashController'); KRLogUtil.kr_e('❌ 设备登录失败: ${error.msg}', tag: 'SplashController');
_logStepTiming('设备登录完成');
return false; return false;
}, },
(token) async { (token) async {
@ -433,15 +438,16 @@ class KRAppRunData {
KRLogUtil.kr_i('✅ 设备登录成功', tag: 'SplashController'); KRLogUtil.kr_i('✅ 设备登录成功', tag: 'SplashController');
final deviceId = KRDeviceInfoService().deviceId ?? 'unknown'; final deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
_logStepTiming('开始保存用户信息');
await kr_saveUserInfo( await kr_saveUserInfo(
token, token,
'device_$deviceId', // 'device_$deviceId', //
KRLoginType.kr_email,
null, //
); );
_logStepTiming('保存用户信息完成');
kr_isLogin.value = true; kr_isLogin.value = true;
print('✅ 已标记为登录状态'); print('✅ 已标记为登录状态');
_logStepTiming('设备登录完成');
return true; return true;
}, },
); );
@ -458,7 +464,6 @@ class KRAppRunData {
KRLogUtil.kr_i('开始初始化用户信息', tag: 'AppRunData'); KRLogUtil.kr_i('开始初始化用户信息', tag: 'AppRunData');
try { try {
deviceId = KRDeviceInfoService().deviceId ?? 'unknown'; deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
final String? userInfoString = final String? userInfoString =
await KRSecureStorage().kr_readData(key: _keyUserInfo); await KRSecureStorage().kr_readData(key: _keyUserInfo);
@ -470,23 +475,21 @@ class KRAppRunData {
final Map<String, dynamic> userInfo = jsonDecode(userInfoString); final Map<String, dynamic> userInfo = jsonDecode(userInfoString);
kr_token = userInfo['token']; kr_token = userInfo['token'];
kr_account.value = userInfo['account']; kr_account.value = userInfo['account'];
final loginTypeValue = userInfo['loginType'];
kr_loginType = KRLoginType.values.firstWhere(
(e) => e.value == loginTypeValue,
orElse: () => KRLoginType.kr_telephone,
);
kr_areaCode = userInfo['areaCode'] ?? "";
// token中解析userId // token中解析userId
if (kr_token != null && kr_token!.isNotEmpty) { if (kr_token != null && kr_token!.isNotEmpty) {
kr_userId.value = _kr_parseUserIdFromToken(kr_token!); kr_userId.value = _kr_parseUserIdFromToken(kr_token!);
} }
KRLogUtil.kr_i('解析用户信息成功: token=${kr_token != null}, account=${kr_account.value}', tag: 'AppRunData'); KRLogUtil.kr_i(
'解析用户信息成功: token=${kr_token != null}, account=${kr_account.value}',
tag: 'AppRunData');
// 🔧 2token有效性和账号信息完整性 // 🔧 2token有效性和账号信息完整性
// //
if (kr_token != null && kr_token!.isNotEmpty && _kr_isValidToken(kr_token!)) { if (kr_token != null &&
kr_token!.isNotEmpty &&
_kr_isValidToken(kr_token!)) {
// token格式验证通过JWT格式检查 // token格式验证通过JWT格式检查
if (kr_account.value != null && kr_account.value!.isNotEmpty) { if (kr_account.value != null && kr_account.value!.isNotEmpty) {
// //
@ -502,7 +505,9 @@ class KRAppRunData {
// Token无效或格式错误 // Token无效或格式错误
KRLogUtil.kr_w('⚠️ Token验证失败或格式错误清理该条用户数据', tag: 'AppRunData'); KRLogUtil.kr_w('⚠️ Token验证失败或格式错误清理该条用户数据', tag: 'AppRunData');
if (kr_token != null && kr_token!.isNotEmpty) { if (kr_token != null && kr_token!.isNotEmpty) {
KRLogUtil.kr_w(' ❌ 可能的原因Token已过期或被污染格式: ${kr_token!.substring(0, min(30, kr_token!.length))}...', tag: 'AppRunData'); KRLogUtil.kr_w(
' ❌ 可能的原因Token已过期或被污染格式: ${kr_token!.substring(0, min(30, kr_token!.length))}...',
tag: 'AppRunData');
} }
await kr_loginOut(); await kr_loginOut();
} }
@ -558,7 +563,8 @@ class KRAppRunData {
/// ///
void _kr_handleConnectionState(bool isConnected) { void _kr_handleConnectionState(bool isConnected) {
KRLogUtil.kr_i('WebSocket 连接状态: ${isConnected ? "已连接" : "已断开"}', tag: 'AppRunData'); KRLogUtil.kr_i('WebSocket 连接状态: ${isConnected ? "已连接" : "已断开"}',
tag: 'AppRunData');
} }
/// Socket /// Socket
@ -569,14 +575,18 @@ class KRAppRunData {
/// ///
Future<void> _fetchUserInfo() async { Future<void> _fetchUserInfo() async {
try { try {
KRLogUtil.kr_i('📞 [AppRunData] 开始调用用户信息接口 /v1/public/user/info ...', tag: 'AppRunData'); KRLogUtil.kr_i('📞 [AppRunData] 开始调用用户信息接口 /v1/public/user/info ...',
KRLogUtil.kr_i('🔐 [AppRunData] 当前 Token: ${kr_token ?? "null"}', tag: 'AppRunData'); tag: 'AppRunData');
KRLogUtil.kr_i('🔐 [AppRunData] 当前 Token: ${kr_token ?? "null"}',
tag: 'AppRunData');
final result = await KRUserApi.kr_getUserInfo(); final result = await KRUserApi.kr_getUserInfo();
result.fold( result.fold(
(error) { (error) {
KRLogUtil.kr_e('❌ [AppRunData] 获取用户信息失败: ${error.msg} (code: ${error.code})', tag: 'AppRunData'); KRLogUtil.kr_e(
'❌ [AppRunData] 获取用户信息失败: ${error.msg} (code: ${error.code})',
tag: 'AppRunData');
}, },
(userInfo) { (userInfo) {
final authType = userInfo.authMethods.isNotEmpty final authType = userInfo.authMethods.isNotEmpty
@ -586,25 +596,36 @@ class KRAppRunData {
? userInfo.authMethods[0].authIdentifier ? userInfo.authMethods[0].authIdentifier
: null; : null;
KRLogUtil.kr_i('✅ [AppRunData] 获取用户信息成功', tag: 'AppRunData'); KRLogUtil.kr_i('✅ [AppRunData] 获取用户信息成功', tag: 'AppRunData');
KRLogUtil.kr_i('📋 [AppRunData] refer_code: "${userInfo.referCode}"', tag: 'AppRunData'); KRLogUtil.kr_i('📋 [AppRunData] refer_code: "${userInfo.referCode}"',
KRLogUtil.kr_i('💰 [AppRunData] balance: ${userInfo.balance}', tag: 'AppRunData'); tag: 'AppRunData');
KRLogUtil.kr_i('💵 [AppRunData] commission: ${userInfo.commission}', tag: 'AppRunData'); KRLogUtil.kr_i('💰 [AppRunData] balance: ${userInfo.balance}',
KRLogUtil.kr_i('📧 [AppRunData] 登录类型: ${authType}', tag: 'AppRunData'); tag: 'AppRunData');
KRLogUtil.kr_i('📧 [AppRunData] email: ${authIdentifier}', tag: 'AppRunData'); KRLogUtil.kr_i('💵 [AppRunData] commission: ${userInfo.commission}',
KRLogUtil.kr_i('🆔 [AppRunData] id: ${userInfo.id}', tag: 'AppRunData'); tag: 'AppRunData');
KRLogUtil.kr_i('📧 [AppRunData] 登录类型: ${authType}',
tag: 'AppRunData');
KRLogUtil.kr_i('📧 [AppRunData] email: ${authIdentifier}',
tag: 'AppRunData');
KRLogUtil.kr_i('🆔 [AppRunData] id: ${userInfo.id}',
tag: 'AppRunData');
// //
kr_referCode.value = userInfo.referCode; kr_referCode.value = userInfo.referCode;
kr_refererId.value = userInfo.refererId; kr_refererId.value = userInfo.refererId;
kr_account.value = authType == 'device' ? '9000${userInfo.id}' : authIdentifier; kr_account.value =
authType == 'device' ? '9000${userInfo.id}' : authIdentifier;
kr_balance.value = userInfo.balance; kr_balance.value = userInfo.balance;
kr_commission.value = userInfo.commission; kr_commission.value = userInfo.commission;
KRLogUtil.kr_i('💾 [AppRunData] 用户信息已保存到全局状态:', tag: 'AppRunData'); KRLogUtil.kr_i('💾 [AppRunData] 用户信息已保存到全局状态:', tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_referCode: "${kr_referCode.value}"', tag: 'AppRunData'); KRLogUtil.kr_i(' - kr_referCode: "${kr_referCode.value}"',
KRLogUtil.kr_i(' - kr_refererId: ${kr_refererId.value}', tag: 'AppRunData'); tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_balance: ${kr_balance.value}', tag: 'AppRunData'); KRLogUtil.kr_i(' - kr_refererId: ${kr_refererId.value}',
KRLogUtil.kr_i(' - kr_commission: ${kr_commission.value}', tag: 'AppRunData'); tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_balance: ${kr_balance.value}',
tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_commission: ${kr_commission.value}',
tag: 'AppRunData');
}, },
); );
} catch (e, stackTrace) { } catch (e, stackTrace) {

View File

@ -1,4 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'dart:convert';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import '../../utils/kr_log_util.dart'; import '../../utils/kr_log_util.dart';
@ -41,7 +42,6 @@ class KRConfigData {
/// ///
final String kr_invitation_link; final String kr_invitation_link;
final String kr_website_id;
KRConfigData({ KRConfigData({
this.kr_config = '', this.kr_config = '',
@ -56,16 +56,21 @@ class KRConfigData {
this.kr_official_telegram = '', this.kr_official_telegram = '',
this.kr_official_telephone = '', this.kr_official_telephone = '',
this.kr_invitation_link = '', this.kr_invitation_link = '',
this.kr_website_id = '',
}) : this.kr_domains = kr_domains ?? [], }) : this.kr_domains = kr_domains ?? [],
this.kr_update_application = this.kr_update_application =
kr_update_application ?? KRUpdateApplication(); kr_update_application ?? KRUpdateApplication();
factory KRConfigData.fromJson(Map<String, dynamic> json) { factory KRConfigData.fromJson(Map<String, dynamic> json) {
KRLogUtil.kr_e('配置数据: $json', tag: 'KRConfigData'); KRLogUtil.kr_i('配置数据: $json', tag: 'KRConfigData');
String _krConfigString = '';
try {
_krConfigString = jsonEncode(json);
} catch (_) {
_krConfigString = '';
}
return KRConfigData( return KRConfigData(
kr_config: _krConfigString,
kr_invitation_link: json['invitation_link'] ?? '', kr_invitation_link: json['invitation_link'] ?? '',
kr_config: json['kr_config'] ?? '',
kr_encryption_key: json['encryption_key'] ?? '', kr_encryption_key: json['encryption_key'] ?? '',
kr_encryption_method: json['encryption_method'] ?? '', kr_encryption_method: json['encryption_method'] ?? '',
kr_domains: List<String>.from(json['domains'] ?? []), kr_domains: List<String>.from(json['domains'] ?? []),
@ -77,7 +82,6 @@ class KRConfigData {
kr_official_website: json['official_website'] ?? '', kr_official_website: json['official_website'] ?? '',
kr_official_telegram: json['official_telegram'] ?? '', kr_official_telegram: json['official_telegram'] ?? '',
kr_official_telephone: json['official_telephone'] ?? '', kr_official_telephone: json['official_telephone'] ?? '',
kr_website_id: json['kr_website_id'] ?? '',
); );
} }
} }

View File

@ -81,17 +81,6 @@ class KRSiteInfo {
String crispId = '0'; String crispId = '0';
String deviceLimit = '0'; String deviceLimit = '0';
// custom_data kr_website_id
try {
final customDataStr = json['custom_data'] ?? '';
if (customDataStr.isNotEmpty) {
final customDataJson = jsonDecode(customDataStr) as Map<String, dynamic>;
crispId = customDataJson['kr_website_id'] ?? '0';
}
} catch (e) {
// 使
}
// custom_data deviceLimit // custom_data deviceLimit
try { try {
final customDataStr = json['custom_data'] ?? ''; final customDataStr = json['custom_data'] ?? '';

View File

@ -12,8 +12,10 @@ import 'package:kaer_with_panels/app/model/enum/kr_request_type.dart';
import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart';
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:convert';
import 'package:kaer_with_panels/utils/snackbar_util.dart'; import 'package:kaer_with_panels/utils/snackbar_util.dart';
import 'package:kaer_with_panels/app/routes/app_pages.dart'; import 'package:kaer_with_panels/app/routes/app_pages.dart';
import 'package:kaer_with_panels/app/common/app_config.dart';
class HIUserInfoController extends GetxController { class HIUserInfoController extends GetxController {
/// ///
@ -32,6 +34,7 @@ class HIUserInfoController extends GetxController {
void onInit() { void onInit() {
super.onInit(); super.onInit();
_initDeviceId(); _initDeviceId();
_initDeviceLimit();
loadDeviceList(); loadDeviceList();
} }
@ -60,8 +63,8 @@ class HIUserInfoController extends GetxController {
KRSnackBarUtil.show(AppTranslations.kr_dialog.error, error.msg); KRSnackBarUtil.show(AppTranslations.kr_dialog.error, error.msg);
}, },
(deviceList) { (deviceList) {
KRLogUtil.kr_i('获取到 ${deviceList.length} 个设备', tag: 'DeviceManagement'); KRLogUtil.kr_i('获取到 ${deviceList.length} 个设备',
tag: 'DeviceManagement');
// //
devices.value = deviceList.map((device) { devices.value = deviceList.map((device) {
@ -89,7 +92,8 @@ class HIUserInfoController extends GetxController {
} catch (e, stackTrace) { } catch (e, stackTrace) {
KRLogUtil.kr_e('加载设备列表异常: $e', tag: 'DeviceManagement'); KRLogUtil.kr_e('加载设备列表异常: $e', tag: 'DeviceManagement');
KRLogUtil.kr_e('堆栈跟踪: $stackTrace', tag: 'DeviceManagement'); KRLogUtil.kr_e('堆栈跟踪: $stackTrace', tag: 'DeviceManagement');
KRSnackBarUtil.show(AppTranslations.kr_dialog.error, AppTranslations.kr_deviceManagement.loadDeviceListFailed); KRSnackBarUtil.show(AppTranslations.kr_dialog.error,
AppTranslations.kr_deviceManagement.loadDeviceListFailed);
} finally { } finally {
isLoading.value = false; isLoading.value = false;
} }
@ -106,7 +110,8 @@ class HIUserInfoController extends GetxController {
final isCurrent = device['is_current'] ?? false; final isCurrent = device['is_current'] ?? false;
KRLogUtil.kr_i('开始解绑设备 - id: $id, isCurrent: $isCurrent', tag: 'DeviceManagement'); KRLogUtil.kr_i('开始解绑设备 - id: $id, isCurrent: $isCurrent',
tag: 'DeviceManagement');
final result = await KRUserApi().kr_unbindUserDevice(id); final result = await KRUserApi().kr_unbindUserDevice(id);
@ -114,7 +119,8 @@ class HIUserInfoController extends GetxController {
result.fold( result.fold(
(error) { (error) {
KRLogUtil.kr_e('删除设备失败: ${error.msg}', tag: 'DeviceManagement'); KRLogUtil.kr_e('删除设备失败: ${error.msg}', tag: 'DeviceManagement');
KRSnackBarUtil.show(AppTranslations.kr_dialog.error, AppTranslations.kr_deviceManagement.deleteFailed(error.msg)); KRSnackBarUtil.show(AppTranslations.kr_dialog.error,
AppTranslations.kr_deviceManagement.deleteFailed(error.msg));
}, },
(_) async { (_) async {
KRLogUtil.kr_i('设备删除成功', tag: 'DeviceManagement'); KRLogUtil.kr_i('设备删除成功', tag: 'DeviceManagement');
@ -127,7 +133,8 @@ class HIUserInfoController extends GetxController {
await _reloginWithDevice(); await _reloginWithDevice();
} else { } else {
devices.removeWhere((device) => device['id'] == id); devices.removeWhere((device) => device['id'] == id);
KRSnackBarUtil.show(AppTranslations.kr_dialog.success, AppTranslations.kr_deviceManagement.deleteSuccess); KRSnackBarUtil.show(AppTranslations.kr_dialog.success,
AppTranslations.kr_deviceManagement.deleteSuccess);
} }
}, },
); );
@ -136,18 +143,20 @@ class HIUserInfoController extends GetxController {
} catch (e, stackTrace) { } catch (e, stackTrace) {
KRLogUtil.kr_e('删除设备异常: $e', tag: 'DeviceManagement'); KRLogUtil.kr_e('删除设备异常: $e', tag: 'DeviceManagement');
KRLogUtil.kr_e('堆栈跟踪: $stackTrace', tag: 'DeviceManagement'); KRLogUtil.kr_e('堆栈跟踪: $stackTrace', tag: 'DeviceManagement');
KRSnackBarUtil.show(AppTranslations.kr_dialog.error, AppTranslations.kr_deviceManagement.deleteFailed(e.toString())); KRSnackBarUtil.show(AppTranslations.kr_dialog.error,
AppTranslations.kr_deviceManagement.deleteFailed(e.toString()));
return false; return false;
} }
} }
/// 使 /// 使
Future<void> _reloginWithDevice() async { Future<void> _reloginWithDevice() async {
try { try {
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'DeviceManagement'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'DeviceManagement');
KRLogUtil.kr_i('开始重新进行设备登录', tag: 'DeviceManagement'); KRLogUtil.kr_i('开始重新进行设备登录', tag: 'DeviceManagement');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'DeviceManagement'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'DeviceManagement');
// kr_loginOut // kr_loginOut
final appRunData = KRAppRunData.getInstance(); final appRunData = KRAppRunData.getInstance();
@ -169,7 +178,8 @@ class HIUserInfoController extends GetxController {
(error) { (error) {
// //
KRLogUtil.kr_e('设备登录失败: ${error.msg}', tag: 'DeviceManagement'); KRLogUtil.kr_e('设备登录失败: ${error.msg}', tag: 'DeviceManagement');
KRSnackBarUtil.show(AppTranslations.kr_dialog.error, AppTranslations.kr_deviceManagement.reloginFailed(error.msg)); KRSnackBarUtil.show(AppTranslations.kr_dialog.error,
AppTranslations.kr_deviceManagement.reloginFailed(error.msg));
// 退 // 退
appRunData.kr_loginOut(); appRunData.kr_loginOut();
@ -177,15 +187,15 @@ class HIUserInfoController extends GetxController {
(token) async { (token) async {
// //
KRLogUtil.kr_i('✅ 设备登录成功!', tag: 'DeviceManagement'); KRLogUtil.kr_i('✅ 设备登录成功!', tag: 'DeviceManagement');
KRLogUtil.kr_i('🎫 Token: ${token.substring(0, min(20, token.length))}...', tag: 'DeviceManagement'); KRLogUtil.kr_i(
'🎫 Token: ${token.substring(0, min(20, token.length))}...',
tag: 'DeviceManagement');
// //
final deviceId = KRDeviceInfoService().deviceId ?? 'unknown'; final deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
await appRunData.kr_saveUserInfo( await appRunData.kr_saveUserInfo(
token, token,
'device_$deviceId', 'device_$deviceId',
KRLoginType.kr_email,
null,
); );
KRLogUtil.kr_i('✅ 设备重新登录成功,已更新用户信息', tag: 'DeviceManagement'); KRLogUtil.kr_i('✅ 设备重新登录成功,已更新用户信息', tag: 'DeviceManagement');
@ -209,35 +219,53 @@ class HIUserInfoController extends GetxController {
} catch (e, stackTrace) { } catch (e, stackTrace) {
KRLogUtil.kr_e('设备重新登录异常: $e', tag: 'DeviceManagement'); KRLogUtil.kr_e('设备重新登录异常: $e', tag: 'DeviceManagement');
KRLogUtil.kr_e('堆栈跟踪: $stackTrace', tag: 'DeviceManagement'); KRLogUtil.kr_e('堆栈跟踪: $stackTrace', tag: 'DeviceManagement');
KRSnackBarUtil.show(AppTranslations.kr_dialog.error, AppTranslations.kr_deviceManagement.reloginFailedGeneric); KRSnackBarUtil.show(AppTranslations.kr_dialog.error,
AppTranslations.kr_deviceManagement.reloginFailedGeneric);
// 退 // 退
await KRAppRunData.getInstance().kr_loginOut(); await KRAppRunData.getInstance().kr_loginOut();
} }
} }
Future<void> _initDeviceLimit() async {
await KRSiteConfigService().fetchSiteConfig();
}
/// ///
Map<String, dynamic> getDeviceTypeInfo(String userAgent) { Map<String, dynamic> getDeviceTypeInfo(String userAgent) {
String deviceType = AppTranslations.kr_deviceManagement.deviceTypeUnknown; String deviceType = AppTranslations.kr_deviceManagement.deviceTypeUnknown;
String iconName = 'devices'; String iconName = 'devices';
if (userAgent.contains('Android') || userAgent.toLowerCase().contains('android')) { if (userAgent.contains('Android') ||
deviceType = 'Android' ;// AppTranslations.kr_deviceManagement.deviceTypeAndroid; userAgent.toLowerCase().contains('android')) {
deviceType =
'Android'; // AppTranslations.kr_deviceManagement.deviceTypeAndroid;
iconName = 'phone_android'; iconName = 'phone_android';
} else if (userAgent.contains('iOS') || userAgent.contains('iPhone') || userAgent.toLowerCase().contains('ios')) { } else if (userAgent.contains('iOS') ||
deviceType = 'iPhone'; // AppTranslations.kr_deviceManagement.deviceTypeIos; userAgent.contains('iPhone') ||
userAgent.toLowerCase().contains('ios')) {
deviceType =
'iPhone'; // AppTranslations.kr_deviceManagement.deviceTypeIos;
iconName = 'phone_iphone'; iconName = 'phone_iphone';
} else if (userAgent.contains('iPad')) { } else if (userAgent.contains('iPad')) {
deviceType = 'iPad';// AppTranslations.kr_deviceManagement.deviceTypeIpad; deviceType =
'iPad'; // AppTranslations.kr_deviceManagement.deviceTypeIpad;
iconName = 'tablet'; iconName = 'tablet';
} else if (userAgent.contains('macOS') || userAgent.contains('Mac') || userAgent.toLowerCase().contains('mac')) { } else if (userAgent.contains('macOS') ||
deviceType = 'Mac';// AppTranslations.kr_deviceManagement.deviceTypeMacos; userAgent.contains('Mac') ||
userAgent.toLowerCase().contains('mac')) {
deviceType =
'Mac'; // AppTranslations.kr_deviceManagement.deviceTypeMacos;
iconName = 'desktop_mac'; iconName = 'desktop_mac';
} else if (userAgent.contains('Windows') || userAgent.toLowerCase().contains('windows')) { } else if (userAgent.contains('Windows') ||
deviceType = 'Windows'; //AppTranslations.kr_deviceManagement.deviceTypeWindows; userAgent.toLowerCase().contains('windows')) {
deviceType =
'Windows'; //AppTranslations.kr_deviceManagement.deviceTypeWindows;
iconName = 'computer'; iconName = 'computer';
} else if (userAgent.contains('Linux') || userAgent.toLowerCase().contains('linux')) { } else if (userAgent.contains('Linux') ||
deviceType = 'Linux';//AppTranslations.kr_deviceManagement.deviceTypeLinux; userAgent.toLowerCase().contains('linux')) {
deviceType =
'Linux'; //AppTranslations.kr_deviceManagement.deviceTypeLinux;
iconName = 'computer'; iconName = 'computer';
} }
@ -247,8 +275,6 @@ class HIUserInfoController extends GetxController {
}; };
} }
@override @override
void onReady() { void onReady() {
super.onReady(); super.onReady();

View File

@ -55,7 +55,7 @@ class KRCrispController extends GetxController {
// SDK // SDK
_nativeConfig = native_crisp.CrispConfig( _nativeConfig = native_crisp.CrispConfig(
websiteID: AppConfig.getInstance().kr_website_id, websiteID: '47fcc1ac-9674-4ab1-9e3c-6b5666f59a38',
user: native_crisp.User( user: native_crisp.User(
email: null, email: null,
nickName: identifier, nickName: identifier,

View File

@ -33,9 +33,6 @@ import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:kaer_with_panels/app/utils/kr_init_log_collector.dart'; // 🔧 import 'package:kaer_with_panels/app/utils/kr_init_log_collector.dart'; // 🔧
import 'package:kaer_with_panels/app/utils/kr_latency_tester.dart'; // 🔧 import 'package:kaer_with_panels/app/utils/kr_latency_tester.dart'; // 🔧
import 'package:kaer_with_panels/app/utils/account_guard.dart';
import 'package:kaer_with_panels/app/services/iap/iap_service.dart';
class KRHomeController extends GetxController with WidgetsBindingObserver { class KRHomeController extends GetxController with WidgetsBindingObserver {
// 🔧 // 🔧
@ -44,7 +41,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
/// ///
final KRSubscribeService kr_subscribeService = KRSubscribeService(); final KRSubscribeService kr_subscribeService = KRSubscribeService();
/// , /// ,
final Rx<KRHomeViewsStatus> kr_currentViewStatus = final Rx<KRHomeViewsStatus> kr_currentViewStatus =
KRHomeViewsStatus.kr_notLoggedIn.obs; KRHomeViewsStatus.kr_notLoggedIn.obs;
@ -52,25 +48,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
/// ///
final kr_currentListStatus = KRHomeViewsListStatus.kr_loading.obs; final kr_currentListStatus = KRHomeViewsListStatus.kr_loading.obs;
///
static const double kr_baseHeight = 120.0; //
static const double kr_subscriptionCardHeight = 200.0; //
static const double kr_connectionInfoHeight = 126.0; //
static const double kr_trialCardHeight = 120.0; //
static const double kr_lastDayCardHeight = 120.0; //
static const double kr_nodeListHeight = 400.0; //
static const double kr_errorHeight = 100.0; //
static const double kr_loadingHeight = 100.0; //
///
static const double kr_marginTop = 12.0; //
static const double kr_marginBottom = 12.0; //
static const double kr_marginHorizontal = 16.0; //
static const double kr_marginVertical = 12.0; //
///
final kr_bottomPanelHeight = 200.0.obs;
/// ///
final kr_connectText = AppTranslations.kr_home.disconnected.obs; final kr_connectText = AppTranslations.kr_home.disconnected.obs;
@ -223,6 +200,23 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
return; return;
} }
final current = kr_subscribeService.kr_currentSubscribe.value;
if (!KRAppRunData.getInstance().kr_isLogin.value || current == null) {
KRLogUtil.kr_w('未登录或无可用订阅,阻止自动连接', tag: 'QuickConnect');
return;
}
bool isExpired = false;
if (current.expireTime.isNotEmpty) {
try {
isExpired =
DateTime.parse(current.expireTime).isBefore(DateTime.now());
} catch (_) {}
}
if (isExpired) {
KRLogUtil.kr_w('订阅不可用(过期或流量耗尽),阻止自动连接', tag: 'QuickConnect');
return;
}
await _kr_prepareCountrySelectionBeforeStart(); await _kr_prepareCountrySelectionBeforeStart();
final selectedAfter = final selectedAfter =
await KRSecureStorage().kr_readData(key: 'SELECTED_NODE_TAG'); await KRSecureStorage().kr_readData(key: 'SELECTED_NODE_TAG');
@ -260,45 +254,9 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
} }
} }
///
bool canAutoConnect() {
return isQuickConnectEnabled.value &&
KRAppRunData.getInstance().kr_isLogin.value &&
!kr_isConnected.value;
}
@override @override
void onInit() async { void onInit() async {
super.onInit(); super.onInit();
// 🔧 onInit
try {
final dir = await getApplicationDocumentsDirectory();
final debugFile = File('${dir.path}/HOME_CONTROLLER_DEBUG.txt');
await debugFile.writeAsString(
'=' * 60 +
'\n'
'HomeController.onInit 被调用!\n'
'时间: ${DateTime.now()}\n'
'实例 HashCode: ${hashCode}\n'
'线程: ${Platform.isAndroid ? "Android" : "Unknown"}\n'
'=' *
60 +
'\n',
mode: FileMode.append,
);
} catch (e) {
//
}
// 🔧 HomeController
_initLog.logPhaseStart('HomeController 初始化');
_initLog.log('KRHomeController.onInit 被调用', tag: 'Home');
// 🔧 Android 15
// kr_updateBottomPanelHeight();
///
// _kr_initBottomPanelHeight();
// //
_loadQuickConnectStatus(); _loadQuickConnectStatus();
// //
@ -320,7 +278,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
// //
Future.delayed(const Duration(milliseconds: 500), () { Future.delayed(const Duration(milliseconds: 500), () {
kr_forceSyncConnectionStatus(true); kr_forceSyncConnectionStatus();
}); });
// 🔧 Android 15 5 // 🔧 Android 15 5
@ -372,14 +330,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
} catch (_) {} } catch (_) {}
} }
///
void _kr_initBottomPanelHeight() {
ever(kr_currentListStatus, (status) {
kr_updateBottomPanelHeight();
KRLogUtil.kr_i(status.toString(), tag: "_kr_initBottomPanelHeight");
});
}
void _kr_initLoginStatus() { void _kr_initLoginStatus() {
_initLog.log('开始初始化登录状态处理', tag: 'Home'); _initLog.log('开始初始化登录状态处理', tag: 'Home');
KRLogUtil.kr_i('初始化登录状态', tag: 'HomeController'); KRLogUtil.kr_i('初始化登录状态', tag: 'HomeController');
@ -392,10 +342,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
KRLogUtil.kr_w('⏱️ 订阅服务初始化超时(8秒),强制设置为无数据状态', tag: 'HomeController'); KRLogUtil.kr_w('⏱️ 订阅服务初始化超时(8秒),强制设置为无数据状态', tag: 'HomeController');
// 🔧 Android 15 none error // 🔧 Android 15 none error
kr_currentListStatus.value = KRHomeViewsListStatus.kr_none; kr_currentListStatus.value = KRHomeViewsListStatus.kr_none;
//
kr_updateBottomPanelHeight();
_initLog.log('已强制切换到默认视图, 底部面板高度: ${kr_bottomPanelHeight.value}',
tag: 'Subscribe');
KRLogUtil.kr_i('✅ 已强制切换到默认视图', tag: 'HomeController'); KRLogUtil.kr_i('✅ 已强制切换到默认视图', tag: 'HomeController');
} }
}); });
@ -458,8 +405,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn; kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
_initLog.logSuccess('用户已登录,准备加载订阅数据', tag: 'Home'); _initLog.logSuccess('用户已登录,准备加载订阅数据', tag: 'Home');
KRLogUtil.kr_i('设置为已登录状态', tag: 'HomeController'); KRLogUtil.kr_i('设置为已登录状态', tag: 'HomeController');
_kr_ensureSubscribeServiceInitialized();
// splash
KRLogUtil.kr_i('订阅服务已在启动页初始化,跳过重复初始化', tag: 'HomeController'); KRLogUtil.kr_i('订阅服务已在启动页初始化,跳过重复初始化', tag: 'HomeController');
} else { } else {
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn; kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
@ -517,6 +463,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
throw TimeoutException('订阅服务初始化超时'); throw TimeoutException('订阅服务初始化超时');
}, },
).then((_) async { ).then((_) async {
_checkQuickConnectAutoStart();
final elapsed = DateTime.now().difference(startTime).inMilliseconds; final elapsed = DateTime.now().difference(startTime).inMilliseconds;
_initLog.logSuccess('订阅服务初始化完成, 耗时: ${elapsed}ms', tag: 'Subscribe'); _initLog.logSuccess('订阅服务初始化完成, 耗时: ${elapsed}ms', tag: 'Subscribe');
_initLog.log('最终列表状态: ${kr_currentListStatus.value}', _initLog.log('最终列表状态: ${kr_currentListStatus.value}',
@ -594,7 +541,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn; kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
KRLogUtil.kr_i('登录状态变化:设置为已登录', tag: 'HomeController'); KRLogUtil.kr_i('登录状态变化:设置为已登录', tag: 'HomeController');
// splash // splash
KRLogUtil.kr_i('订阅服务已在启动页初始化,跳过重复初始化', tag: 'HomeController'); KRLogUtil.kr_i('订阅服务已在启动页初始化,跳过重复初始化', tag: 'HomeController');
} else { } else {
@ -681,7 +627,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
} else { } else {
// kr_updateBottomPanelHeight(); // kr_updateBottomPanelHeight();
} }
_checkQuickConnectAutoStart();
_kr_testLatencyWithoutVpn(); _kr_testLatencyWithoutVpn();
break; break;
case KRSubscribeServiceStatus.kr_none: case KRSubscribeServiceStatus.kr_none:
@ -1872,18 +1817,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
@override @override
void onReady() { void onReady() {
super.onReady(); super.onReady();
Future.delayed(const Duration(milliseconds: 200), () async {
ensureAccountExists().then((ok) {
print('ok');
});
});
Future.delayed(const Duration(milliseconds: 500), () async {
if (Get.isRegistered<KRIAPService>()) {
KRIAPService.instance.setup();
}
});
} }
@override @override
@ -1958,100 +1891,8 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
}); });
} }
//
void kr_updateBottomPanelHeight() {
// 🔧 Android 15
if (kr_subscribeService.kr_currentStatus ==
KRHomeViewsListStatus.kr_loading &&
kr_currentListStatus.value != KRHomeViewsListStatus.kr_loading) {
return;
}
KRLogUtil.kr_i('更新底部面板高度', tag: 'HomeController');
KRLogUtil.kr_i('当前视图状态: ${kr_currentViewStatus.value}',
tag: 'HomeController');
KRLogUtil.kr_i('当前列表状态: ${kr_currentListStatus.value}',
tag: 'HomeController');
KRLogUtil.kr_i('是否试用: ${kr_subscribeService.kr_isTrial.value}',
tag: 'HomeController');
KRLogUtil.kr_i(
'是否最后一天: ${kr_subscribeService.kr_isLastDayOfSubscription.value}',
tag: 'HomeController');
double targetHeight = 0.0;
if (kr_currentViewStatus.value == KRHomeViewsStatus.kr_notLoggedIn) {
//
targetHeight = kr_subscriptionCardHeight +
kr_baseHeight +
kr_marginTop +
kr_marginBottom +
kr_marginVertical * 2;
KRLogUtil.kr_i('未登录状态,目标高度: $targetHeight', tag: 'HomeController');
} else if (kr_currentListStatus.value ==
KRHomeViewsListStatus.kr_serverList ||
kr_currentListStatus.value ==
KRHomeViewsListStatus.kr_countrySubscribeList ||
kr_currentListStatus.value ==
KRHomeViewsListStatus.kr_serverSubscribeList ||
kr_currentListStatus.value == KRHomeViewsListStatus.kr_subscribeList) {
targetHeight = kr_nodeListHeight + kr_marginVertical * 2;
KRLogUtil.kr_i('节点列表状态,目标高度: $targetHeight', tag: 'HomeController');
}
// 🔧 Android 15
else if (kr_currentListStatus.value == KRHomeViewsListStatus.kr_loading ||
kr_currentListStatus.value == KRHomeViewsListStatus.kr_error) {
//
targetHeight = kr_loadingHeight + kr_marginTop + kr_marginBottom;
KRLogUtil.kr_i('加载/错误状态,目标高度: $targetHeight', tag: 'HomeController');
} else {
//
targetHeight = kr_baseHeight + kr_marginTop + kr_marginBottom;
KRLogUtil.kr_i('基础高度: $targetHeight', tag: 'HomeController');
// 🔧 访
try {
if (kr_subscribeService.kr_currentSubscribe.value != null) {
targetHeight += kr_connectionInfoHeight + kr_marginTop;
KRLogUtil.kr_i('添加连接信息卡片高度: $targetHeight', tag: 'HomeController');
} else {
targetHeight += kr_subscriptionCardHeight + kr_marginTop;
KRLogUtil.kr_i('添加订阅卡片高度: $targetHeight', tag: 'HomeController');
}
//
if (kr_subscribeService.kr_isTrial.value) {
targetHeight += kr_trialCardHeight + kr_marginTop;
KRLogUtil.kr_i('添加试用卡片高度: $targetHeight', tag: 'HomeController');
}
//
else if (kr_subscribeService.kr_isLastDayOfSubscription.value) {
targetHeight += kr_lastDayCardHeight + kr_marginTop;
KRLogUtil.kr_i('添加最后一天卡片高度: $targetHeight', tag: 'HomeController');
}
} catch (e) {
// 🔧 访使
KRLogUtil.kr_e('访问订阅服务数据异常,使用默认高度: $e', tag: 'HomeController');
targetHeight += kr_subscriptionCardHeight + kr_marginTop;
KRLogUtil.kr_i('使用默认订阅卡片高度: $targetHeight', tag: 'HomeController');
}
}
// 🔧 Android 15 0
if (targetHeight < 100) {
KRLogUtil.kr_w('计算的高度过小($targetHeight),设置为最小高度', tag: 'HomeController');
targetHeight = kr_loadingHeight;
}
KRLogUtil.kr_i('最终目标高度: $targetHeight', tag: 'HomeController');
kr_bottomPanelHeight.value = targetHeight;
}
// //
void kr_moveToSelectedNode() { void kr_moveToSelectedNode() {}
}
// //
void kr_moveToLocation() { void kr_moveToLocation() {
@ -2436,7 +2277,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
} }
/// ///
void kr_forceSyncConnectionStatus([bool? isQuickConnect]) { void kr_forceSyncConnectionStatus() {
try { try {
KRLogUtil.kr_i('🔄 强制同步连接状态...', tag: 'HomeController'); KRLogUtil.kr_i('🔄 强制同步连接状态...', tag: 'HomeController');
@ -2479,10 +2320,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
// UI // UI
update(); update();
print('isQuickConnect$isQuickConnect');
if (isQuickConnect == true) {
_checkQuickConnectAutoStart();
}
KRLogUtil.kr_i('✅ 连接状态同步完成', tag: 'HomeController'); KRLogUtil.kr_i('✅ 连接状态同步完成', tag: 'HomeController');
} catch (e) { } catch (e) {
KRLogUtil.kr_e('❌ 强制同步连接状态失败: $e', tag: 'HomeController'); KRLogUtil.kr_e('❌ 强制同步连接状态失败: $e', tag: 'HomeController');

View File

@ -11,7 +11,6 @@ import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart';
import 'package:kaer_with_panels/app/services/global_overlay_service.dart'; import 'package:kaer_with_panels/app/services/global_overlay_service.dart';
import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart'; 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 'package:kaer_with_panels/singbox/model/singbox_status.dart';
import 'package:kaer_with_panels/app/utils/account_guard.dart';
DateTime? _hiConnectBtnNextAllowedAt; DateTime? _hiConnectBtnNextAllowedAt;
const Duration _hiConnectBtnDebounce = Duration(milliseconds: 800); const Duration _hiConnectBtnDebounce = Duration(milliseconds: 800);
@ -93,8 +92,6 @@ class HIAnimatedConnectButton extends GetView<KRHomeController> {
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
HapticFeedback.lightImpact(); HapticFeedback.lightImpact();
final ok = await ensureAccountExists();
if (!ok) return;
final _now = DateTime.now(); final _now = DateTime.now();
if (_hiConnectBtnNextAllowedAt != null && if (_hiConnectBtnNextAllowedAt != null &&
_now.isBefore(_hiConnectBtnNextAllowedAt!)) { _now.isBefore(_hiConnectBtnNextAllowedAt!)) {

View File

@ -8,7 +8,6 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../controllers/kr_home_controller.dart'; import '../controllers/kr_home_controller.dart';
import '../../../routes/app_pages.dart'; import '../../../routes/app_pages.dart';
import 'package:kaer_with_panels/app/services/global_overlay_service.dart'; import 'package:kaer_with_panels/app/services/global_overlay_service.dart';
import 'package:kaer_with_panels/app/utils/account_guard.dart';
// ======================= 1. Circular Clipper () ======================= // ======================= 1. Circular Clipper () =======================
class CircularClipper extends CustomClipper<Path> { class CircularClipper extends CustomClipper<Path> {
@ -175,8 +174,6 @@ class _HISubscriptionCornerButtonState extends State<HISubscriptionCornerButton>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
onTap: () async { onTap: () async {
final ok = await ensureAccountExists();
if (!ok) return;
_startCircularTransition(context); _startCircularTransition(context);
}, },
child: Container( child: Container(

View File

@ -17,7 +17,6 @@ import 'package:kaer_with_panels/app/services/global_overlay_service.dart';
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart'; import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart'; import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
import 'package:kaer_with_panels/app/routes/app_pages.dart'; import 'package:kaer_with_panels/app/routes/app_pages.dart';
import 'package:kaer_with_panels/app/utils/account_guard.dart';
class KRHomeView extends StatefulWidget implements HasSwipeConfig { class KRHomeView extends StatefulWidget implements HasSwipeConfig {
const KRHomeView({super.key}); const KRHomeView({super.key});
@ -26,16 +25,10 @@ class KRHomeView extends StatefulWidget implements HasSwipeConfig {
enableLeft: true, enableLeft: true,
enableRight: true, enableRight: true,
onLeft: () { onLeft: () {
ensureAccountExists().then((ok) {
if (!ok) return;
Get.toNamed(Routes.HI_MENU); Get.toNamed(Routes.HI_MENU);
});
}, },
onRight: () { onRight: () {
ensureAccountExists().then((ok) {
if (!ok) return;
GlobalOverlayService.instance.triggerSubscriptionAnimation(); GlobalOverlayService.instance.triggerSubscriptionAnimation();
});
}, },
); );
@ -109,45 +102,39 @@ class _KRHomeViewState extends State<KRHomeView> {
); );
// 3. // 3.
if (currentSubscribe == null) { final listStatus =
// --- 1: --- controller.kr_currentListStatus.value;
content = Text( if (listStatus == KRHomeViewsListStatus.kr_loading) {
'尚未购买套餐', content = Text('加载订阅中', style: normalStyle);
style: highlightStyle, } else {
); if (currentSubscribe == null) {
content = Text('尚未购买套餐', style: highlightStyle);
} else { } else {
// --- 2: ---
final now = DateTime.now(); final now = DateTime.now();
DateTime? expireDateTime; DateTime? expireDateTime;
try { try {
expireDateTime = expireDateTime =
DateTime.parse(currentSubscribe.expireTime); DateTime.parse(currentSubscribe.expireTime);
} catch (e) { } catch (e) {}
//
}
if (expireDateTime != null && if (expireDateTime != null &&
expireDateTime.isBefore(now)) { expireDateTime.isBefore(now)) {
// --- 2.1: ---
final formattedExpireDate = final formattedExpireDate =
'${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}'; '${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}';
// 使 \n Text
content = Text( content = Text(
'您的套餐已于 $formattedExpireDate 到期\n请前往购买新套餐', '您的套餐已于 $formattedExpireDate 到期\n请前往购买新套餐',
style: highlightStyle, style: highlightStyle);
);
} else { } else {
// --- 2.2: --- final formattedExpireTime = expireDateTime !=
final formattedExpireTime = expireDateTime != null null
? '${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')} ${expireDateTime.hour.toString().padLeft(2, '0')}:${expireDateTime.minute.toString().padLeft(2, '0')}' ? '${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')} ${expireDateTime.hour.toString().padLeft(2, '0')}:${expireDateTime.minute.toString().padLeft(2, '0')}'
: '未知'; : '未知';
// 使 \n Text
content = Text( content = Text(
'套餐到期时间:$formattedExpireTime\n${controller.kr_isConnected.value ? '当前线路:${controller.kr_getRealConnectedNodeCountry()}' : '未连接'}', '套餐到期时间:$formattedExpireTime\n${controller.kr_isConnected.value ? '当前线路:${controller.kr_getRealConnectedNodeCountry()}' : '未连接'}',
style: normalStyle, style: normalStyle,
); );
} }
} }
}
// 4. Container // 4. Container
return Container( return Container(

View File

@ -88,7 +88,6 @@ class KRLoginController extends GetxController
RxBool kr_canSendCode = true.obs; RxBool kr_canSendCode = true.obs;
/// ///
late List<KRAreaCodeItem> kr_areaCodeList = KRAreaCode.kr_getCodeList();
var kr_cutSeleteCodeIndex = 0.obs; var kr_cutSeleteCodeIndex = 0.obs;
/// ///
@ -556,8 +555,7 @@ class KRLoginController extends GetxController
KRAppRunData.getInstance().kr_saveUserInfo( KRAppRunData.getInstance().kr_saveUserInfo(
token, token,
accountController.text, accountController.text,
KRLoginType.kr_email, );
null);
kr_loginStatus.value = KRLoginProgressStatus.kr_check; kr_loginStatus.value = KRLoginProgressStatus.kr_check;
// / // /

View File

@ -65,14 +65,8 @@ class KRSplashController extends GetxController {
_stepStartTime = _startTime; _stepStartTime = _startTime;
// 使 print // 使 print
print('[SPLASH_TIMING] ═══════════════════════════════════════');
print('[SPLASH_TIMING] 🎬 KRSplashController onInit 被调用了!'); print('[SPLASH_TIMING] 🎬 KRSplashController onInit 被调用了!');
print('[SPLASH_TIMING] ⏰ 启动开始时间: ${_startTime.toIso8601String()}'); print('[SPLASH_TIMING] ⏰ 启动开始时间: ${_startTime.toIso8601String()}');
print('[SPLASH_TIMING] ═══════════════════════════════════════');
KRLogUtil.kr_i('[SPLASH_TIMING] ═══════════════════════════════════════', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] 🎬 启动页控制器 onInit', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] ═══════════════════════════════════════', tag: 'SplashController');
// 🔧 1.0 - DEBUG模式下清理旧数据 // 🔧 1.0 - DEBUG模式下清理旧数据
// DEBUG模式下执行 // DEBUG模式下执行
@ -85,15 +79,6 @@ class KRSplashController extends GetxController {
print('🧹 清理域名检测状态...'); print('🧹 清理域名检测状态...');
KRDomain.kr_resetDomainState(); KRDomain.kr_resetDomainState();
// 🔧 P2优化
// print('🌐 启动后台任务:网站配置加载...');
// KRLogUtil.kr_i('🌐 后台任务:网站配置和设备登录', tag: 'SplashController');
// _kr_initSiteConfig(); // _kr_continueInitialization
// 🔧
if (kDebugMode) {
print('🔧 初始化日志收集器...');
}
_initializeAndStart(); _initializeAndStart();
} }
@ -130,21 +115,15 @@ class KRSplashController extends GetxController {
final totalMs = totalDuration.inMilliseconds; final totalMs = totalDuration.inMilliseconds;
print('[SPLASH_TIMING] ⏱️ $stepName 耗时: ${stepMs}ms | 累计: ${totalMs}ms'); print('[SPLASH_TIMING] ⏱️ $stepName 耗时: ${stepMs}ms | 累计: ${totalMs}ms');
KRLogUtil.kr_i('[SPLASH_TIMING] ⏱️ $stepName 耗时: ${stepMs}ms | 累计: ${totalMs}ms', tag: 'SplashController'); KRLogUtil.kr_i(
'[SPLASH_TIMING] ⏱️ $stepName 耗时: ${stepMs}ms | 累计: ${totalMs}ms',
tag: 'SplashController');
_stepStartTime = now; // _stepStartTime = now; //
} }
/// ///
Future<void> _kr_initSiteConfig() async { Future<void> _kr_initSiteConfig() async {
print('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('[SPLASH_TIMING] 🌐 开始初始化网站配置...');
print('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] 🌐 初始化网站配置...', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
try { try {
// 🔧 Android 15 2520 + 5 // 🔧 Android 15 2520 + 5
await Future.any([ await Future.any([
@ -162,116 +141,20 @@ class KRSplashController extends GetxController {
} }
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'SplashController');
} }
/// ///
Future<void> _executeSiteConfigInit() async { Future<void> _executeSiteConfigInit() async {
print('📞 准备调用 KRSiteConfigService().initialize()...'); print('📞 准备调用 KRDomain.kr_loadBaseDomain()...');
final success = await KRSiteConfigService().initialize(); await KRDomain.kr_loadBaseDomain();
final crispId = await KRSiteConfigService().getCrispId(); print('📞 KRDomain.kr_loadBaseDomain() 完成');
final device_limit = await KRSiteConfigService().getDeviceLimit();
print('📞 KRSiteConfigService().initialize() 返回: $success');
if (success) {
final config = AppConfig.getInstance();
config.kr_website_id = crispId;
config.device_limit = device_limit;
print('📞 KRSiteConfigService().initialize() 返回: $crispId');
print('AppConfig website_id 已更新为: ${config.kr_website_id}');
print('AppConfig device_limit 已更新为: ${config.device_limit}');
// print('[SPLASH_TIMING] ✅ 网站配置初始化成功');
// await _kr_checkAndPerformDeviceLogin();
} else {
print('⚠️ 网站配置初始化失败,将使用默认配置');
KRLogUtil.kr_w('⚠️ 网站配置初始化失败,将使用默认配置', tag: 'SplashController');
}
} }
///
Future<void> _kr_checkAndPerformDeviceLogin() async {
try {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🔍 检查是否支持设备登录...');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
final siteConfigService = KRSiteConfigService();
//
final isDeviceLoginEnabled = siteConfigService.isDeviceLoginEnabled();
print('📱 设备登录状态: ${isDeviceLoginEnabled ? "已启用" : "未启用"}');
KRLogUtil.kr_i('📱 设备登录状态: $isDeviceLoginEnabled', tag: 'SplashController');
if (!isDeviceLoginEnabled) {
print('⚠️ 设备登录未启用,跳过自动登录');
KRLogUtil.kr_w('⚠️ 设备登录未启用', tag: 'SplashController');
return;
}
print('✅ 设备登录已启用,开始初始化设备信息...');
// 🔧 Android 15 15
await Future.any([
_executeDeviceLogin(),
Future.delayed(const Duration(seconds: 15), () {
throw TimeoutException('设备登录超时15秒');
}),
]);
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
} on TimeoutException catch (e) {
print('⏱️ 设备登录超时,应用将继续启动: $e');
KRLogUtil.kr_w('⏱️ 设备登录超时: $e', tag: 'SplashController');
} catch (e, stackTrace) {
print('❌ 设备登录检查异常: $e');
print('📚 堆栈跟踪: $stackTrace');
KRLogUtil.kr_e('❌ 设备登录检查异常: $e', tag: 'SplashController');
}
}
///
Future<void> _executeDeviceLogin() async {
//
await KRDeviceInfoService().initialize();
print('🔐 开始执行设备登录...');
KRLogUtil.kr_i('🔐 开始执行设备登录', tag: 'SplashController');
//
final authApi = KRAuthApi();
final result = await authApi.kr_deviceLogin();
result.fold(
(error) {
print('❌ 设备登录失败: ${error.msg}');
KRLogUtil.kr_e('❌ 设备登录失败: ${error.msg}', tag: 'SplashController');
},
(token) async {
print('✅ 设备登录成功!');
print('🎫 Token: ${token.substring(0, min(20, token.length))}...');
KRLogUtil.kr_i('✅ 设备登录成功', tag: 'SplashController');
// 使 saveUserInfo
// 使
final deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
await KRAppRunData.getInstance().kr_saveUserInfo(
token,
'device_$deviceId', // 使ID作为临时账号
KRLoginType.kr_email, //
null, //
);
print('💾 用户信息已保存包括Token');
print('✅ 已标记为登录状态');
KRLogUtil.kr_i('✅ 设备登录流程完成', tag: 'SplashController');
},
);
}
Future<void> _kr_initialize() async { Future<void> _kr_initialize() async {
try { try {
_initLog.logPhaseStart('主初始化流程');
_initLog.log('开始执行 _kr_initialize', tag: 'Splash');
KRLogUtil.kr_i('🔧 开始执行 _kr_initialize', tag: 'SplashController'); KRLogUtil.kr_i('🔧 开始执行 _kr_initialize', tag: 'SplashController');
// 🔧 Android 15 15 // 🔧 Android 15 15
@ -304,7 +187,8 @@ class KRSplashController extends GetxController {
_handleError('网络连接失败', '请检查您的网络连接是否正常,然后重试。'); _handleError('网络连接失败', '请检查您的网络连接是否正常,然后重试。');
} on DioException catch (e) { } on DioException catch (e) {
// 🔧 P2优化HTTP请求错误 // 🔧 P2优化HTTP请求错误
KRLogUtil.kr_e('❌ HTTP请求错误: ${e.type} - ${e.message}', tag: 'SplashController'); KRLogUtil.kr_e('❌ HTTP请求错误: ${e.type} - ${e.message}',
tag: 'SplashController');
final errorMsg = _getDioErrorMessage(e); final errorMsg = _getDioErrorMessage(e);
_handleError('服务请求失败', errorMsg); _handleError('服务请求失败', errorMsg);
} catch (e) { } catch (e) {
@ -328,10 +212,13 @@ class KRSplashController extends GetxController {
// 1. // 1.
try { try {
_initLog.log('步骤1: 设置默认域名', tag: 'Minimal'); _initLog.log('步骤1: 设置默认域名', tag: 'Minimal');
if (KRDomain.kr_currentDomain.isEmpty && KRDomain.kr_baseDomains.isNotEmpty) { if (KRDomain.kr_currentDomain.isEmpty &&
KRDomain.kr_baseDomains.isNotEmpty) {
KRDomain.kr_currentDomain = KRDomain.kr_baseDomains[0]; KRDomain.kr_currentDomain = KRDomain.kr_baseDomains[0];
_initLog.logSuccess('设置默认域名: ${KRDomain.kr_currentDomain}', tag: 'Minimal'); _initLog.logSuccess('设置默认域名: ${KRDomain.kr_currentDomain}',
KRLogUtil.kr_i('✅ 设置默认域名: ${KRDomain.kr_currentDomain}', tag: 'SplashController'); tag: 'Minimal');
KRLogUtil.kr_i('✅ 设置默认域名: ${KRDomain.kr_currentDomain}',
tag: 'SplashController');
if (kDebugMode) { if (kDebugMode) {
print('✅ 设置默认域名: ${KRDomain.kr_currentDomain}'); print('✅ 设置默认域名: ${KRDomain.kr_currentDomain}');
} }
@ -509,21 +396,15 @@ class KRSplashController extends GetxController {
Future<void> _kr_continueInitialization() async { Future<void> _kr_continueInitialization() async {
try { try {
_initLog.logSeparator();
_initLog.log('🚀 启动页主流程开始', tag: 'Continue');
_initLog.logSeparator();
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('🚀 启动页主流程开始...', tag: 'SplashController'); KRLogUtil.kr_i('🚀 启动页主流程开始...', tag: 'SplashController');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
// 🔧 Android 15 // 🔧 Android 15
if (Platform.isIOS || Platform.isAndroid) { if (Platform.isIOS || Platform.isAndroid) {
_initLog.log('📱 检查网络连接状态超时5秒', tag: 'Continue'); _initLog.log('📱 检查网络连接状态超时5秒', tag: 'Continue');
KRLogUtil.kr_i('📱 检查网络连接...', tag: 'SplashController'); KRLogUtil.kr_i('📱 检查网络连接...', tag: 'SplashController');
try { try {
// 5 // 5
final bool isConnected = await KRNetworkCheck.kr_checkNetworkConnection().timeout( final bool isConnected =
await KRNetworkCheck.kr_checkNetworkConnection().timeout(
const Duration(seconds: 5), const Duration(seconds: 5),
onTimeout: () { onTimeout: () {
_initLog.logWarning('网络连接检查超时5秒继续初始化', tag: 'Continue'); _initLog.logWarning('网络连接检查超时5秒继续初始化', tag: 'Continue');
@ -550,8 +431,6 @@ class KRSplashController extends GetxController {
KRLogUtil.kr_i('💻 桌面平台,跳过网络连接检查', tag: 'SplashController'); KRLogUtil.kr_i('💻 桌面平台,跳过网络连接检查', tag: 'SplashController');
} }
//
// 🔧 // 🔧
// initSiteConfig // initSiteConfig
// 使 // 使
@ -561,7 +440,8 @@ class KRSplashController extends GetxController {
_logStepTiming('开始设备登录检查'); _logStepTiming('开始设备登录检查');
// 5 // 5
final success = await KRAppRunData.getInstance().kr_checkAndPerformDeviceLogin(); final success =
await KRAppRunData.getInstance().kr_checkAndPerformDeviceLogin();
if (!success) { if (!success) {
// //
@ -605,12 +485,7 @@ class KRSplashController extends GetxController {
// //
Future<void> _kr_continueAfterConfig() async { Future<void> _kr_continueAfterConfig() async {
try { try {
// // SingBox
print('[SPLASH_TIMING] 🔄 开始初始化订阅服务...');
KRLogUtil.kr_i('[SPLASH_TIMING] 🔄 开始初始化订阅服务', tag: 'SplashController');
_kr_ensureSubscribeServiceInitialized();
// SingBox
_logStepTiming('开始SingBox初始化'); _logStepTiming('开始SingBox初始化');
await KRSingBoxImp.instance.init(); await KRSingBoxImp.instance.init();
_logStepTiming('SingBox初始化完成'); _logStepTiming('SingBox初始化完成');
@ -620,20 +495,12 @@ class KRSplashController extends GetxController {
final token = KRAppRunData.getInstance().kr_token; final token = KRAppRunData.getInstance().kr_token;
final hasToken = token != null && token.isNotEmpty; final hasToken = token != null && token.isNotEmpty;
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🎯 准备进入主页');
print('📊 最终登录状态: $loginStatus');
print('🎫 Token存在: $hasToken');
if (hasToken) { if (hasToken) {
print('🎫 Token前缀: ${token.substring(0, min(20, token.length))}...'); print('🎫 Token前缀: ${token.substring(0, min(20, token.length))}...');
} }
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('🎯 准备进入主页', tag: 'SplashController'); KRLogUtil.kr_i('🎯 准备进入主页', tag: 'SplashController');
KRLogUtil.kr_i('📊 最终登录状态: $loginStatus', tag: 'SplashController'); KRLogUtil.kr_i('📊 最终登录状态: $loginStatus', tag: 'SplashController');
KRLogUtil.kr_i('🎫 Token存在: $hasToken', tag: 'SplashController'); KRLogUtil.kr_i('🎫 Token存在: $hasToken', tag: 'SplashController');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
// 🔧 // 🔧
_initLog.logSeparator(); _initLog.logSeparator();
@ -652,12 +519,13 @@ class KRSplashController extends GetxController {
// //
_logStepTiming('开始页面导航'); _logStepTiming('开始页面导航');
if(loginStatus) { if (loginStatus) {
// //
Get.offAllNamed(Routes.KR_HOME); Get.offAllNamed(Routes.KR_HOME);
}else { } else {
kr_hasError.value = true; kr_hasError.value = true;
kr_errorMessage.value = '登录:${AppTranslations.kr_splash.kr_initializationFailed}'; kr_errorMessage.value =
'登录:${AppTranslations.kr_splash.kr_initializationFailed}';
} }
_logStepTiming('页面导航完成'); _logStepTiming('页面导航完成');
} catch (e) { } catch (e) {
@ -667,63 +535,22 @@ class KRSplashController extends GetxController {
final totalMs = totalDuration.inMilliseconds; final totalMs = totalDuration.inMilliseconds;
print('❌ 启动失败时间: ${endTime.toIso8601String()}'); print('❌ 启动失败时间: ${endTime.toIso8601String()}');
print('🕐 启动失败总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)'); print(
'🕐 启动失败总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)');
// //
_initLog.logError('启动初始化失败', tag: 'Splash', error: e); _initLog.logError('启动初始化失败', tag: 'Splash', error: e);
KRLogUtil.kr_e('启动初始化失败: $e', tag: 'SplashController'); KRLogUtil.kr_e('启动初始化失败: $e', tag: 'SplashController');
KRLogUtil.kr_e('⏰ 启动失败总耗时: ${totalMs}ms', tag: 'SplashController'); KRLogUtil.kr_e('⏰ 启动失败总耗时: ${totalMs}ms', tag: 'SplashController');
kr_hasError.value = true; kr_hasError.value = true;
kr_errorMessage.value = '${AppTranslations.kr_splash.kr_initializationFailed}$e'; kr_errorMessage.value =
'${AppTranslations.kr_splash.kr_initializationFailed}$e';
// 🔧 // 🔧
// await _initLog.finalize(); // // await _initLog.finalize(); //
} }
} }
///
Future<void> _kr_ensureSubscribeServiceInitialized() async {
try {
//
final currentStatus = kr_subscribeService.kr_currentStatus.value;
KRLogUtil.kr_i('订阅服务当前状态: $currentStatus', tag: 'SplashController');
if (currentStatus == KRSubscribeServiceStatus.kr_none ||
currentStatus == KRSubscribeServiceStatus.kr_error) {
KRLogUtil.kr_i(
'订阅服务未初始化或错误,开始初始化', tag: 'SplashController');
//
//
KRHomeController().kr_currentListStatus.value = KRHomeViewsListStatus.kr_loading;
try {
await kr_subscribeService.kr_refreshAll();
KRLogUtil.kr_i('订阅服务初始化完成', tag: 'SplashController');
} catch (error) {
KRLogUtil.kr_e('订阅服务初始化失败: $error', tag: 'SplashController');
//
KRHomeController().kr_currentListStatus.value = KRHomeViewsListStatus.kr_error;
rethrow;
}
} else if (currentStatus == KRSubscribeServiceStatus.kr_loading) {
KRLogUtil.kr_i('订阅服务正在初始化中', tag: 'SplashController');
//
while (kr_subscribeService.kr_currentStatus.value == KRSubscribeServiceStatus.kr_loading) {
await Future.delayed(Duration(milliseconds: 100));
}
KRLogUtil.kr_i('订阅服务加载完成,最终状态: ${kr_subscribeService.kr_currentStatus.value}', tag: 'SplashController');
KRHomeController().kr_currentListStatus.value = KRHomeViewsListStatus.kr_loading;
} else if (currentStatus == KRSubscribeServiceStatus.kr_success) {
KRHomeController().kr_currentListStatus.value = KRHomeViewsListStatus.kr_none;
KRLogUtil.kr_i('订阅服务已成功初始化', tag: 'SplashController');
}
} catch (e) {
KRLogUtil.kr_e('确保订阅服务初始化失败: $e', tag: 'SplashController');
KRHomeController().kr_currentListStatus.value = KRHomeViewsListStatus.kr_error;
rethrow;
}
}
// //
void kr_retry() { void kr_retry() {
kr_hasError.value = false; kr_hasError.value = false;
@ -749,15 +576,15 @@ class KRSplashController extends GetxController {
/// ///
Future<void> _kr_clearOldLocalData() async { Future<void> _kr_clearOldLocalData() async {
try { try {
KRLogUtil.kr_i('🧹 开始清理旧本地存储数据...', tag: 'SplashController'); // KRLogUtil.kr_i('🧹 开始清理旧本地存储数据...', tag: 'SplashController');
// //
await KRSecureStorage().kr_deleteData(key: 'USER_INFO'); await KRSecureStorage().kr_deleteData(key: 'USER_INFO');
KRLogUtil.kr_i('✅ 已清理USER_INFO', tag: 'SplashController'); // KRLogUtil.kr_i('✅ 已清理USER_INFO', tag: 'SplashController');
// //
await KRSecureStorage().kr_deleteData(key: 'DEVICE_INFO'); await KRSecureStorage().kr_deleteData(key: 'DEVICE_INFO');
KRLogUtil.kr_i('✅ 已清理DEVICE_INFO', tag: 'SplashController'); // KRLogUtil.kr_i('✅ 已清理DEVICE_INFO', tag: 'SplashController');
KRLogUtil.kr_i('✅ 旧本地存储数据已全部清理', tag: 'SplashController'); KRLogUtil.kr_i('✅ 旧本地存储数据已全部清理', tag: 'SplashController');
} catch (e) { } catch (e) {

View File

@ -25,15 +25,14 @@ class BaseResponse<T> {
final dataMap = json['data'] ?? Map<String, dynamic>(); final dataMap = json['data'] ?? Map<String, dynamic>();
final cipherText = dataMap['data'] ?? ""; final cipherText = dataMap['data'] ?? "";
final nonce = dataMap['time'] ?? ""; final nonce = dataMap['time'] ?? "";
print('明文${cipherText}');
// enable_security // enable_security
if (cipherText.isNotEmpty && nonce.isNotEmpty) { if (cipherText.isNotEmpty && nonce.isNotEmpty) {
try { try {
if (kDebugMode) { if (kDebugMode) {
// print('═══════════════════════════════════════'); // print('═══════════════════════════════════════');
// print('🔐 检测到加密响应,开始解密...'); // print('🔐 检测到加密响应,开始解密...');
print('📥 加密数据长度: ${cipherText.length} 字符'); // print('📥 加密数据长度: ${cipherText.length} 字符');
print('⏰ 时间戳: $nonce'); // print('⏰ 时间戳: $nonce');
} }
final decrypted = KRAesUtil.decryptData(cipherText, nonce, AppConfig.kr_encryptionKey); final decrypted = KRAesUtil.decryptData(cipherText, nonce, AppConfig.kr_encryptionKey);

View File

@ -24,7 +24,6 @@ import 'package:loggy/loggy.dart';
import '../utils/kr_aes_util.dart'; import '../utils/kr_aes_util.dart';
import '../utils/kr_log_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/common_util.dart';
// import 'package:video/app/utils/log_util.dart'; // import 'package:video/app/utils/log_util.dart';
@ -144,70 +143,11 @@ class HttpUtil {
} }
var map = <String, dynamic>{}; var map = <String, dynamic>{};
// enable_security
final shouldEncrypt = KRSiteConfigService().isDeviceSecurityEnabled();
if (shouldEncrypt) {
KRLogUtil.kr_i('🔐 需要加密请求数据', tag: 'HttpUtil');
final plainText = jsonEncode(params); final plainText = jsonEncode(params);
map = KRAesUtil.encryptData(plainText, AppConfig.kr_encryptionKey); map = KRAesUtil.encryptData(plainText, AppConfig.kr_encryptionKey);
} else {
map = params;
}
// //
final headers = _initHeader('signature', 'userId', 'token'); final headers = _initHeader('signature', 'userId', 'token');
int? _kr_parseUserIdFromToken(String token) {
try {
// JWT格式: header.payload.signature
final parts = token.split('.');
if (parts.length != 3) {
KRLogUtil.kr_e('JWT token格式错误', tag: 'AppRunData');
return null;
}
// payload部分base64
String payload = parts[1];
// paddingbase64要求长度是4的倍数
switch (payload.length % 4) {
case 0:
break; // padding
case 2:
payload += '==';
break;
case 3:
payload += '=';
break;
default:
KRLogUtil.kr_e('JWT payload长度无效', tag: 'AppRunData');
return null;
}
final decodedBytes = base64.decode(payload);
final decodedString = utf8.decode(decodedBytes);
// JSON
final Map<String, dynamic> payloadMap = jsonDecode(decodedString);
// UserId
if (payloadMap.containsKey('UserId')) {
final userId = payloadMap['UserId'];
KRLogUtil.kr_i('从JWT解析出userId: $userId', tag: 'AppRunData');
return userId is int ? userId : int.tryParse(userId.toString());
}
return null;
} catch (e) {
KRLogUtil.kr_e('解析JWT token失败: $e', tag: 'AppRunData');
return null;
}
}
final userId =
_kr_parseUserIdFromToken(KRAppRunData().kr_token.toString());
//
KRLogUtil.kr_i('🔍 请求头: $headers', tag: 'HttpUtil');
KRLogUtil.kr_i('🔍 请求userId: $userId', tag: 'HttpUtil');
KRLogUtil.kr_i('🔍 请求头map: $map', tag: 'HttpUtil');
Response<Map<String, dynamic>> responseTemp; Response<Map<String, dynamic>> responseTemp;
if (method == HttpMethod.GET) { if (method == HttpMethod.GET) {
@ -316,193 +256,93 @@ class HttpUtil {
} }
} }
///
class MyInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (kDebugMode) {
print('>>> Request │ ${options.method}${options.uri}');
}
if (options.data != null) {
if (kDebugMode) {
print('Body: ${options.data}');
}
}
handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
if (kDebugMode) {
print(
'<<< Response │ ${response.requestOptions.method}${response.statusCode} ${response.statusMessage}${response.requestOptions.uri}');
}
if (response.data != null) {
if (kDebugMode) {
print('Body: ${response.data}');
}
}
handler.next(response);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
if (kDebugMode) {
print(
'<<< Error │ ${err.requestOptions.method}${err.requestOptions.uri}');
}
if (kDebugMode) {
print('Error Type: ${err.type}');
}
if (err.message != null) {
if (kDebugMode) {
print('Error Message: ${err.message}');
}
}
if (err.response?.data != null) {
if (kDebugMode) {
print('Response Data: ${err.response?.data}');
}
}
handler.next(err);
}
}
/// HTTP /// HTTP
class _KRSimpleHttpInterceptor extends Interceptor { class _KRSimpleHttpInterceptor extends Interceptor {
///
static const bool KR_HTTP_PRINT = true;
final Dio _dio; final Dio _dio;
_KRSimpleHttpInterceptor(this._dio); _KRSimpleHttpInterceptor(this._dio);
static String? _lastPath; static String? _lastPath;
static int _lastTsMs = 0; static int _lastTsMs = 0;
@override @override
///
///
///
///
/// - options: data queryParameters
/// - handler:
/// void
void onRequest(RequestOptions options, RequestInterceptorHandler handler) { void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (kDebugMode) { if (KR_HTTP_PRINT) {
print('>>> Request │ ${options.method}${options.uri}'); print('>>> Request │ ${options.method}${options.uri}');
} }
if (options.data != null) { if (KR_HTTP_PRINT) {
if (kDebugMode) { Map<String, dynamic>? m;
print('Body: ${options.data}');
}
// data time
if (options.data is Map<String, dynamic>) { if (options.data is Map<String, dynamic>) {
final data = options.data as Map<String, dynamic>; m = options.data as Map<String, dynamic>;
if (data.containsKey('data') && data.containsKey('time')) { } else if (options.queryParameters.isNotEmpty) {
try { m = options.queryParameters;
if (kDebugMode) {
print('');
}
//
final encryptedData = data['data'] as String;
final nonce = data['time'] as String;
final decrypted = KRAesUtil.decryptData(
encryptedData,
nonce,
AppConfig.kr_encryptionKey,
);
if (kDebugMode) {
print('🔓 解密后的原始请求数据:');
}
// JSON
try {
final jsonData = jsonDecode(decrypted);
final prettyJson = JsonEncoder.withIndent(' ').convert(jsonData);
if (kDebugMode) {
print(prettyJson);
}
} catch (_) {
if (kDebugMode) {
print(decrypted);
}
}
} catch (e) {
if (kDebugMode) {
print('⚠️ 请求解密失败: $e');
}
}
} }
if (m != null) {
final decrypted = _tryDecryptFromMap(m);
_printDecryptedOrFallback(
phase: 'Request', raw: m, decrypted: decrypted);
} }
} }
handler.next(options); handler.next(options);
} }
@override @override
///
///
///
///
/// - response: Map
/// - handler:
/// void
void onResponse(Response response, ResponseInterceptorHandler handler) { void onResponse(Response response, ResponseInterceptorHandler handler) {
if (kDebugMode) { if (KR_HTTP_PRINT) {
print( print(
'<<< Response │ ${response.requestOptions.method}${response.statusCode} ${response.statusMessage}${response.requestOptions.uri}'); '<<< Response │ ${response.requestOptions.method}${response.statusCode} ${response.statusMessage}${response.requestOptions.uri}');
} }
if (response.data != null) { if (KR_HTTP_PRINT && response.data is Map<String, dynamic>) {
if (kDebugMode) {
print('Body: ${response.data}');
}
// data time
if (response.data is Map<String, dynamic>) {
final dataMap = response.data as Map<String, dynamic>; final dataMap = response.data as Map<String, dynamic>;
String? decrypted = _tryDecryptFromMap(dataMap);
// data if (decrypted == null && dataMap['data'] is Map<String, dynamic>) {
final nestedData = dataMap['data']; decrypted = _tryDecryptFromMap(dataMap['data'] as Map<String, dynamic>);
if (nestedData is Map<String, dynamic> &&
nestedData.containsKey('data') &&
nestedData.containsKey('time')) {
try {
if (kDebugMode) {
print('');
}
if (kDebugMode) {
print('🔐 检测到加密响应,正在解密...');
}
//
final encryptedData = nestedData['data'] as String;
final nonce = nestedData['time'] as String;
final decrypted = KRAesUtil.decryptData(
encryptedData,
nonce,
AppConfig.kr_encryptionKey,
);
if (kDebugMode) {
print('🔓 解密后的原始响应数据:');
}
// JSON
try {
// final jsonData = jsonDecode(decrypted);
// final prettyJson = JsonEncoder.withIndent(' ').convert(jsonData);
// if (kDebugMode) {
// print(prettyJson);
// }
} catch (_) {
if (kDebugMode) {
print(decrypted);
}
}
} catch (e) {
if (kDebugMode) {
print('⚠️ 响应解密失败: $e');
}
}
}
} }
_printDecryptedOrFallback(
phase: 'Response', raw: dataMap, decrypted: decrypted);
} }
handler.next(response); handler.next(response);
} }
@override @override
///
///
/// Unknown
///
/// - err: Dio
/// - handler:
/// void
void onError(DioException err, ErrorInterceptorHandler handler) { void onError(DioException err, ErrorInterceptorHandler handler) {
if (kDebugMode) { if (KR_HTTP_PRINT) {
print( print(
'<<< Error │ ${err.requestOptions.method}${err.requestOptions.uri}'); '<<< Error │ ${err.requestOptions.method}${err.requestOptions.uri}');
} }
if (kDebugMode) { if (KR_HTTP_PRINT) {
print('Error Type: ${err.type}'); print('Error Type: ${err.type}');
} }
if (err.message != null) { if (err.message != null) {
if (kDebugMode) { if (KR_HTTP_PRINT) {
print('Error Message: ${err.message}'); print('Error Message: ${err.message}');
} }
} }
if (err.response?.data != null) { if (err.response?.data != null) {
if (kDebugMode) { if (KR_HTTP_PRINT) {
print('Response Data: ${err.response?.data}'); print('Response Data: ${err.response?.data}');
} }
} }
@ -545,4 +385,53 @@ class _KRSimpleHttpInterceptor extends Interceptor {
} }
handler.next(err); handler.next(err);
} }
/// Map data/time null
String? _tryDecryptFromMap(Map<String, dynamic> m) {
final data = m['data'];
final time = m['time'];
if (data is String && time is String) {
try {
return KRAesUtil.decryptData(data, time, AppConfig.kr_encryptionKey);
} catch (_) {
return null;
}
}
return null;
}
/// JSON
String _prettyPrintJson(String s) {
try {
final jsonData = jsonDecode(s);
return JsonEncoder.withIndent(' ').convert(jsonData);
} catch (_) {
return s;
}
}
///
void _printDecryptedOrFallback({
required String phase,
required Object? raw,
required String? decrypted,
}) {
if (!KR_HTTP_PRINT) return;
if (decrypted != null) {
print('🔓 $phase 明文:');
print(_prettyPrintJson(decrypted));
} else {
print('⚠️ $phase 解密失败');
print('原文:');
if (raw is Map<String, dynamic>) {
try {
print(JsonEncoder.withIndent(' ').convert(raw));
} catch (_) {
print(raw.toString());
}
} else {
print(raw?.toString() ?? 'null');
}
}
}
} }

View File

@ -379,23 +379,15 @@ class KRAuthApi {
print('📤 原始请求数据: $data'); print('📤 原始请求数据: $data');
// final needEncryption = true;
final siteConfigService = KRSiteConfigService();
final needEncryption = siteConfigService.isDeviceSecurityEnabled();
print('🔒 是否需要加密: $needEncryption');
KRLogUtil.kr_i('🔒 是否需要加密: $needEncryption', tag: 'KRAuthApi');
String? requestBody; String? requestBody;
if (needEncryption) { if (needEncryption) {
// //
print('🔐 加密请求数据...');
final encrypted = KRAesUtil.encryptJson(data, AppConfig.kr_encryptionKey); final encrypted = KRAesUtil.encryptJson(data, AppConfig.kr_encryptionKey);
requestBody = '{"data":"${encrypted['data']}","time":"${encrypted['time']}"}'; requestBody = '{"data":"${encrypted['data']}","time":"${encrypted['time']}"}';
print('🔐 加密后请求体: $requestBody'); // print('🔐 加密后请求体: $requestBody');
KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi'); // KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
} else { } else {
// 使
requestBody = jsonEncode(data); requestBody = jsonEncode(data);
print('📝 明文请求体: $requestBody'); print('📝 明文请求体: $requestBody');
} }
@ -439,10 +431,10 @@ class KRAuthApi {
), ),
); );
print('📥 响应状态码: ${response.statusCode}'); // print('📥 响应状态码: ${response.statusCode}');
print('📥 响应数据: ${response.data}'); // print('📥 响应数据: ${response.data}');
KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi'); // KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi'); // KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> responseData = response.data as Map<String, dynamic>; Map<String, dynamic> responseData = response.data as Map<String, dynamic>;

View File

@ -28,28 +28,23 @@ class KRDeviceInfoService {
/// ///
Future<void> initialize() async { Future<void> initialize() async {
try { try {
if (kDebugMode) {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('📱 开始初始化设备信息服务');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
}
KRLogUtil.kr_i('📱 开始初始化设备信息', tag: 'KRDeviceInfoService'); KRLogUtil.kr_i('📱 开始初始化设备信息', tag: 'KRDeviceInfoService');
_deviceId = await _getDeviceId(); _deviceId = await _getDeviceId();
_deviceDetails = await _getDeviceDetails(); _deviceDetails = await _getDeviceDetails();
if (kDebugMode) { if (kDebugMode) {
print('✅ 设备信息初始化成功'); // print('✅ 设备信息初始化成功');
print('📱 设备ID: $_deviceId'); // print('📱 设备ID: $_deviceId');
print('📱 设备平台: ${getPlatformName()}'); // print('📱 设备平台: ${getPlatformName()}');
print('📱 设备型号: ${getDeviceModel()}'); // print('📱 设备型号: ${getDeviceModel()}');
print('📱 系统版本: ${getOSVersion()}'); // print('📱 系统版本: ${getOSVersion()}');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); // print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
} }
KRLogUtil.kr_i('✅ 设备信息初始化成功', tag: 'KRDeviceInfoService'); KRLogUtil.kr_i('✅ 设备信息初始化成功', tag: 'KRDeviceInfoService');
KRLogUtil.kr_i('📱 设备ID - $_deviceId', tag: 'KRDeviceInfoService'); // KRLogUtil.kr_i('📱 设备ID - $_deviceId', tag: 'KRDeviceInfoService');
KRLogUtil.kr_i('📱 设备详情 - $_deviceDetails', tag: 'KRDeviceInfoService'); // KRLogUtil.kr_i('📱 设备详情 - $_deviceDetails', tag: 'KRDeviceInfoService');
} catch (e) { } catch (e) {
if (kDebugMode) { if (kDebugMode) {
print('❌ 设备信息初始化失败: $e'); print('❌ 设备信息初始化失败: $e');

View File

@ -1,4 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:dio/io.dart'; import 'package:dio/io.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -7,6 +8,7 @@ import '../common/app_config.dart';
import '../utils/kr_log_util.dart'; import '../utils/kr_log_util.dart';
import '../utils/kr_http_adapter_util.dart'; import '../utils/kr_http_adapter_util.dart';
import 'singbox_imp/kr_sing_box_imp.dart'; import 'singbox_imp/kr_sing_box_imp.dart';
import 'api_service/kr_api.user.dart';
/// ///
class KRSiteConfigService extends ChangeNotifier { class KRSiteConfigService extends ChangeNotifier {
@ -18,15 +20,6 @@ class KRSiteConfigService extends ChangeNotifier {
_dio.options.sendTimeout = const Duration(seconds: 20); _dio.options.sendTimeout = const Duration(seconds: 20);
_dio.options.receiveTimeout = const Duration(seconds: 20); _dio.options.receiveTimeout = const Duration(seconds: 20);
// 🔧 使
// SingBox
//
// DioExceptionType.unknown
KRLogUtil.kr_i(
'🌐 网站配置服务:使用直连模式(不通过代理)',
tag: 'KRSiteConfigService',
);
// 🔧 SSL // 🔧 SSL
_dio.httpClientAdapter = KRHttpAdapterUtil.createAdapter( _dio.httpClientAdapter = KRHttpAdapterUtil.createAdapter(
useSingBoxProxy: false, useSingBoxProxy: false,
@ -49,190 +42,126 @@ class KRSiteConfigService extends ChangeNotifier {
/// ///
bool get isInitialized => _isInitialized; bool get isInitialized => _isInitialized;
///
Future<bool> initialize() async { Future<bool> initialize() async {
int retryCount = 0; return await initializeDomains();
const int maxRetries = 5; }
while (retryCount < maxRetries) { Future<bool> initializeDomains() async {
try { try {
if (kDebugMode) { await KRDomain.kr_loadBaseDomain();
print('🔧 KRSiteConfigService.initialize() 开始执行 (尝试 ${retryCount + 1}/$maxRetries)');
}
KRLogUtil.kr_i('🔧 开始初始化网站配置 (尝试 ${retryCount + 1}/$maxRetries)', tag: 'KRSiteConfigService');
// Debug 使
final baseUrl = AppConfig().baseUrl;
if (kDebugMode) {
print('📍 baseUrl = $baseUrl');
}
final url = '$baseUrl/v1/common/site/config';
if (kDebugMode) {
print('📍 完整URL = $url');
}
KRLogUtil.kr_i('📤 请求网站配置 - $url', tag: 'KRSiteConfigService');
if (kDebugMode) {
print('📤 准备发送 GET 请求到: $url');
}
if (kDebugMode) {
// 🔧
print('⏱️ 超时配置: connectTimeout=${_dio.options.connectTimeout}, sendTimeout=${_dio.options.sendTimeout}, receiveTimeout=${_dio.options.receiveTimeout}');
}
if (kDebugMode) {
print('⏳ 开始发送请求...');
}
final startTime = DateTime.now();
final response = await _dio.get(url);
final endTime = DateTime.now();
final duration = endTime.difference(startTime).inMilliseconds;
if (kDebugMode) {
print('⏱️ 请求耗时: ${duration}ms');
}
if (kDebugMode) {
print('✅ 请求完成,状态码: ${response.statusCode}');
}
KRLogUtil.kr_i('📥 响应状态码 - ${response.statusCode}', tag: 'KRSiteConfigService');
if (response.statusCode == 200) {
final responseData = response.data;
if (kDebugMode) {
print('📥 响应数据类型: ${responseData.runtimeType}');
}
if (kDebugMode) {
print('📥 响应数据: $responseData');
}
KRLogUtil.kr_i('📥 响应数据 - $responseData', tag: 'KRSiteConfigService');
if (responseData['code'] == 200) {
_siteConfig = KRSiteConfig.fromJson(responseData['data']);
_isInitialized = true; _isInitialized = true;
final config = AppConfig.getInstance();
config.kr_website_id = getCrispId();
config.device_limit = getDeviceLimit();
//
_printConfigInfo();
//
notifyListeners(); notifyListeners();
return true; return true;
} else { } catch (_) {
KRLogUtil.kr_e('❌ API返回错误 - ${responseData['msg']}', tag: 'KRSiteConfigService');
// API
return false; return false;
} }
} else { }
KRLogUtil.kr_e('❌ HTTP错误 - ${response.statusCode}', tag: 'KRSiteConfigService');
// HTTP 404, 500 Future<bool> fetchSiteConfig() async {
// catch try {
throw DioException( final result = await KRUserApi().kr_config();
requestOptions: response.requestOptions, return await result.fold(
response: response, (error) async {
type: DioExceptionType.badResponse, return false;
error: 'HTTP Error ${response.statusCode}', },
(cfg) async {
try {
if (cfg.kr_config.isNotEmpty) {
final Map<String, dynamic> root = jsonDecode(cfg.kr_config);
_siteConfig = KRSiteConfig.fromJson(root);
AppConfig.getInstance().device_limit = getDeviceLimit();
notifyListeners();
return true;
}
} catch (_) {}
return false;
},
); );
} } catch (_) {
} on DioException catch (e, stackTrace) {
if (kDebugMode) {
print('❌ Dio请求异常: ${e.type}');
}
KRLogUtil.kr_e('❌ Dio异常 - ${e.type}: ${e.message}', tag: 'KRSiteConfigService');
//
if (e.type == DioExceptionType.connectionTimeout ||
e.type == DioExceptionType.receiveTimeout ||
e.type == DioExceptionType.sendTimeout ||
e.type == DioExceptionType.connectionError ||
e.type == DioExceptionType.unknown || // unknown
e.type == DioExceptionType.badResponse) { // 503
KRLogUtil.kr_w('⚠️ 网络或服务器异常,尝试切换域名重试...', tag: 'KRSiteConfigService');
//
final switchSuccess = await KRDomain.kr_switchToNextDomain();
if (switchSuccess) {
retryCount++;
KRLogUtil.kr_i('✅ 域名切换成功,准备第 ${retryCount + 1} 次尝试', tag: 'KRSiteConfigService');
continue; //
} else {
KRLogUtil.kr_e('❌ 域名切换失败,无法继续重试', tag: 'KRSiteConfigService');
return false; return false;
} }
} }
//
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
return false;
} catch (e, stackTrace) {
if (kDebugMode) {
print('❌ 未知异常: $e');
}
KRLogUtil.kr_e('❌ 初始化失败 - $e', tag: 'KRSiteConfigService');
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
return false;
}
}
KRLogUtil.kr_e('❌ 达到最大重试次数 ($maxRetries),初始化失败', tag: 'KRSiteConfigService');
return false;
}
/// ///
void _printConfigInfo() { void _printConfigInfo() {
if (_siteConfig == null) return; if (_siteConfig == null) return;
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('📊 网站配置信息:', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('📊 网站配置信息:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
// //
KRLogUtil.kr_i('🏠 站点名称: ${_siteConfig!.site.siteName}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('🏠 站点名称: ${_siteConfig!.site.siteName}',
KRLogUtil.kr_i('🏠 站点描述: ${_siteConfig!.site.siteDesc}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点域名: ${_siteConfig!.site.host}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('🏠 站点描述: ${_siteConfig!.site.siteDesc}',
KRLogUtil.kr_i('💬 Crisp ID: ${_siteConfig!.site.crispId}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点域名: ${_siteConfig!.site.host}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('💬 Crisp ID: ${_siteConfig!.site.crispId}',
tag: 'KRSiteConfigService');
// //
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('📝 注册配置:', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('📝 注册配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 开放注册: ${isRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i(' ✓ 开放注册: ${isRegisterEnabled() ? "" : ""}',
KRLogUtil.kr_i(' ✓ 手机号注册: ${isMobileRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 邮箱注册: ${isEmailRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i(' ✓ 手机号注册: ${isMobileRegisterEnabled() ? "" : ""}',
KRLogUtil.kr_i(' ✓ 设备登录: ${isDeviceLoginEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 邮箱注册: ${isEmailRegisterEnabled() ? "" : ""}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 设备登录: ${isDeviceLoginEnabled() ? "" : ""}',
tag: 'KRSiteConfigService');
// //
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🔐 验证配置:', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('🔐 验证配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 邮箱验证: ${isEmailVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i(' ✓ 邮箱验证: ${isEmailVerificationEnabled() ? "" : ""}',
KRLogUtil.kr_i(' ✓ 手机验证: ${isMobileVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 登录验证: ${isLoginVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i(' ✓ 手机验证: ${isMobileVerificationEnabled() ? "" : ""}',
KRLogUtil.kr_i(' ✓ 注册验证: ${isRegisterVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 重置密码验证: ${isResetPasswordVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i(' ✓ 登录验证: ${isLoginVerificationEnabled() ? "" : ""}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 注册验证: ${isRegisterVerificationEnabled() ? "" : ""}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i(
' ✓ 重置密码验证: ${isResetPasswordVerificationEnabled() ? "" : ""}',
tag: 'KRSiteConfigService');
// //
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🎁 邀请配置:', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('🎁 邀请配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 强制邀请码: ${isForcedInvite() ? "" : ""}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i(' ✓ 强制邀请码: ${isForcedInvite() ? "" : ""}',
KRLogUtil.kr_i(' ✓ 推荐比例: ${_siteConfig!.invite.referralPercentage}%', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 推荐比例: ${_siteConfig!.invite.referralPercentage}%',
tag: 'KRSiteConfigService');
// //
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('💰 货币配置:', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('💰 货币配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 货币单位: ${_siteConfig!.currency.currencyUnit}', tag: 'KRSiteConfigService'); KRLogUtil.kr_i(' ✓ 货币单位: ${_siteConfig!.currency.currencyUnit}',
KRLogUtil.kr_i(' ✓ 货币符号: ${_siteConfig!.currency.currencySymbol}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 货币符号: ${_siteConfig!.currency.currencySymbol}',
tag: 'KRSiteConfigService');
// OAuth // OAuth
if (_siteConfig!.oauthMethods.isNotEmpty) { if (_siteConfig!.oauthMethods.isNotEmpty) {
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
KRLogUtil.kr_i('🔑 OAuth 方法: ${_siteConfig!.oauthMethods.join(", ")}', tag: 'KRSiteConfigService'); tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🔑 OAuth 方法: ${_siteConfig!.oauthMethods.join(", ")}',
tag: 'KRSiteConfigService');
} }
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('✅ 网站配置初始化成功', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('✅ 网站配置初始化成功', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService'); KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'KRSiteConfigService');
} }
/// ///
@ -352,10 +281,12 @@ class KRSiteConfigService extends ChangeNotifier {
return true; return true;
} }
final allowedDomains = domainSuffixList.split(',').map((d) => d.trim()).toList(); final allowedDomains =
domainSuffixList.split(',').map((d) => d.trim()).toList();
final emailDomain = email.split('@').last.toLowerCase(); final emailDomain = email.split('@').last.toLowerCase();
return allowedDomains.any((domain) => emailDomain.endsWith(domain.toLowerCase())); return allowedDomains
.any((domain) => emailDomain.endsWith(domain.toLowerCase()));
} }
/// Crisp客服系统ID /// Crisp客服系统ID

View File

@ -1,37 +0,0 @@
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';
import 'package:kaer_with_panels/app/widgets/dialogs/hi_dialog.dart';
import 'package:kaer_with_panels/app/routes/app_pages.dart';
import 'package:kaer_with_panels/app/utils/kr_common_util.dart';
import 'package:kaer_with_panels/app/services/kr_site_config_service.dart';
Future<bool> ensureAccountExists() async {
final app = KRAppRunData.getInstance();
final account = app.kr_account.value;
final isLoggedIn = app.kr_isLogin.value;
final config = AppConfig.getInstance();
if (account == null ||
account.isEmpty ||
!isLoggedIn
) {
await HIDialog.show(
message: '未检测到账号信息,请重试初始化',
confirmText: '重试',
preventBackDismiss: true,
onConfirm: () {
Get.offAllNamed(Routes.KR_SPLASH);
},
);
return false;
}
var crispId = config.kr_website_id;
var deviceLimitText = config.device_limit;
var deviceLimit = int.tryParse(deviceLimitText) ?? 0;
if ((crispId.isEmpty || crispId == '0') || deviceLimit == 0) {
KRSiteConfigService().initialize();
}
return true;
}

View File

@ -30,7 +30,7 @@ class KRCommonUtil {
return; return;
} }
final websiteId = AppConfig.getInstance().kr_website_id; final websiteId = '47fcc1ac-9674-4ab1-9e3c-6b5666f59a38'; // AppConfig.getInstance().kr_website_id;
if (websiteId.isEmpty) { if (websiteId.isEmpty) {
HIDialog.show( HIDialog.show(
title: '提示', title: '提示',

View File

@ -31,7 +31,7 @@ class KRHttpAdapterUtil {
client.findProxy = (url) { client.findProxy = (url) {
try { try {
final proxyConfig = KRSingBoxImp.instance.kr_buildProxyRule(); final proxyConfig = KRSingBoxImp.instance.kr_buildProxyRule();
KRLogUtil.kr_i('🔍 请求使用代理: $proxyConfig, url: $url', tag: 'KRHttpAdapterUtil'); // KRLogUtil.kr_i('🔍 请求使用代理: $proxyConfig, url: $url', tag: 'KRHttpAdapterUtil');
return proxyConfig; return proxyConfig;
} catch (e) { } catch (e) {
KRLogUtil.kr_w('⚠️ 获取代理配置异常,回退到 DIRECT: $e', tag: 'KRHttpAdapterUtil'); KRLogUtil.kr_w('⚠️ 获取代理配置异常,回退到 DIRECT: $e', tag: 'KRHttpAdapterUtil');

View File

@ -4,7 +4,6 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart';
import 'package:kaer_with_panels/app/routes/app_pages.dart'; import 'package:kaer_with_panels/app/routes/app_pages.dart';
import 'package:kaer_with_panels/app/utils/account_guard.dart';
/// 🔹 HIBaseScaffold /// 🔹 HIBaseScaffold
/// ///
@ -114,8 +113,6 @@ class HIBaseScaffold extends StatelessWidget {
if (showMenuButton) { if (showMenuButton) {
return GestureDetector( return GestureDetector(
onTap: () async { onTap: () async {
final ok = await ensureAccountExists();
if (!ok) return;
Get.toNamed(Routes.HI_MENU); Get.toNamed(Routes.HI_MENU);
}, },
child: Container( child: Container(

View File

@ -58,7 +58,7 @@ void main() async {
// //
await KRThemeService().init(); // await KRThemeService().init();
// //
final translations = GetxTranslations(); final translations = GetxTranslations();