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

File diff suppressed because it is too large Load Diff

View File

@ -52,9 +52,6 @@ class KRAppRunData {
///
final RxInt kr_commission = 0.obs;
///
KRLoginType? kr_loginType;
/// ID
String? deviceId;
@ -72,6 +69,14 @@ class KRAppRunData {
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() {
@ -87,7 +92,8 @@ class KRAppRunData {
// JWT格式检查: header.payload.signature (.)
final parts = token.split('.');
if (parts.length != 3) {
KRLogUtil.kr_w('❌ Token格式无效分段数不对 (${parts.length} != 3)', tag: 'AppRunData');
KRLogUtil.kr_w('❌ Token格式无效分段数不对 (${parts.length} != 3)',
tag: 'AppRunData');
return false;
}
@ -185,8 +191,7 @@ class KRAppRunData {
Future<void> kr_saveUserInfo(
String token,
String account,
KRLoginType loginType,
String? areaCode) async {
) async {
KRLogUtil.kr_i('开始保存用户信息', tag: 'AppRunData');
try {
@ -197,19 +202,15 @@ class KRAppRunData {
//
kr_token = token;
kr_account.value = accountText;
kr_loginType = loginType;
kr_areaCode = areaCode;
final Map<String, dynamic> userInfo = {
'token': token,
'account': accountText,
'loginType': loginType.value,
'areaCode': areaCode ?? "",
};
KRLogUtil.kr_i('准备保存用户信息到存储', tag: 'AppRunData');
await KRSecureStorage().kr_saveData(
key: _keyUserInfo,
value: jsonEncode(userInfo),
@ -230,11 +231,11 @@ class KRAppRunData {
kr_isLogin.value = true;
KRLogUtil.kr_i('用户信息-kr_isLogin$kr_isLogin', tag: 'AppRunData');
// 🔧 refer_code
KRLogUtil.kr_i('🔍 [AppRunData] 检查登录模式: account=$account', tag: 'AppRunData');
KRLogUtil.kr_i('🔍 [AppRunData] 检查登录模式: account=$account',
tag: 'AppRunData');
await _fetchUserInfo();
// userinfo接口返回
_fetchUserInfo();
} catch (e) {
KRLogUtil.kr_e('保存用户信息失败: $e', tag: 'AppRunData');
//
@ -246,88 +247,89 @@ class KRAppRunData {
/// 退()
Future<void> kr_loginOut() async {
HIDialog.show(
message: '当前登录已过期,请重新登录',
preventBackDismiss: true,
confirmText: '确定',
autoClose: false,
onConfirm: () async{
// false
kr_isLogin.value = false;
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'AppRunData');
KRLogUtil.kr_i('开始重新进行设备登录', tag: 'AppRunData');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'AppRunData');
// === VPN ===
try {
// SingBox
if (KRSingBoxImp.instance.kr_status.value is SingboxStarted) {
await KRSingBoxImp.instance.kr_stop();
KRLogUtil.kr_i('VPN 服务已停止', tag: 'Logout');
message: '当前登录已过期,请重新登录',
preventBackDismiss: true,
confirmText: '确定',
autoClose: false,
onConfirm: () async {
// false
kr_isLogin.value = false;
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'AppRunData');
KRLogUtil.kr_i('开始重新进行设备登录', tag: 'AppRunData');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'AppRunData');
// === VPN ===
try {
// SingBox
if (KRSingBoxImp.instance.kr_status.value is SingboxStarted) {
await KRSingBoxImp.instance.kr_stop();
KRLogUtil.kr_i('VPN 服务已停止', tag: 'Logout');
}
} catch (e) {
KRLogUtil.kr_e('停止 VPN 服务失败: $e', tag: 'Logout');
}
} catch (e) {
KRLogUtil.kr_e('停止 VPN 服务失败: $e', tag: 'Logout');
}
// Socket
await _kr_disconnectSocket();
// Socket
await _kr_disconnectSocket();
//
kr_token = null;
kr_account.value = null;
kr_userId.value = null;
kr_loginType = null;
kr_areaCode = null;
//
kr_token = null;
kr_account.value = null;
kr_userId.value = null;
kr_areaCode = null;
//
await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
//
await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
// 🔧 4: - 访
try {
final subscribeService = Get.find<dynamic>(tag: 'KRSubscribeService');
if (subscribeService != null && subscribeService is KRSubscribeService) {
KRLogUtil.kr_i('🧹 清理订阅服务数据...', tag: 'AppRunData');
await subscribeService.kr_logout();
KRLogUtil.kr_i('✅ 订阅服务数据已清理', tag: 'AppRunData');
// 🔧 4: - 访
try {
final subscribeService =
Get.find<dynamic>(tag: 'KRSubscribeService');
if (subscribeService != null &&
subscribeService is KRSubscribeService) {
KRLogUtil.kr_i('🧹 清理订阅服务数据...', tag: 'AppRunData');
await subscribeService.kr_logout();
KRLogUtil.kr_i('✅ 订阅服务数据已清理', tag: 'AppRunData');
}
} catch (e) {
//
KRLogUtil.kr_d('⚠️ 无法获取订阅服务,跳过清理: $e', tag: 'AppRunData');
}
} catch (e) {
//
KRLogUtil.kr_d('⚠️ 无法获取订阅服务,跳过清理: $e', tag: 'AppRunData');
}
// 5
final success = await kr_checkAndPerformDeviceLogin();
// 5
final success = await kr_checkAndPerformDeviceLogin();
if (!success) {
//
HIDialog.show(
message: '设备登录失败,请检查网络或重试',
confirmText: '重试',
preventBackDismiss: true,
onConfirm: () async {
await kr_loginOut(); //
},
);
return; //
}
if (!success) {
//
HIDialog.show(
message: '设备登录失败,请检查网络或重试',
confirmText: '重试',
preventBackDismiss: true,
onConfirm: () async {
await kr_loginOut(); //
},
);
return; //
}
//
await Future.delayed(const Duration(milliseconds: 300));
//
await Future.delayed(const Duration(milliseconds: 300));
//
KRLogUtil.kr_i('🔄 开始刷新订阅信息...', tag: 'DeviceManagement');
try {
await KRSubscribeService().kr_refreshAll();
KRLogUtil.kr_i('✅ 订阅信息刷新成功', tag: 'DeviceManagement');
} catch (e) {
KRLogUtil.kr_e('订阅信息刷新失败: $e', tag: 'DeviceManagement');
}
//
KRLogUtil.kr_i('🔄 开始刷新订阅信息...', tag: 'DeviceManagement');
try {
await KRSubscribeService().kr_refreshAll();
KRLogUtil.kr_i('✅ 订阅信息刷新成功', tag: 'DeviceManagement');
} catch (e) {
KRLogUtil.kr_e('订阅信息刷新失败: $e', tag: 'DeviceManagement');
}
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();
// false
kr_isLogin.value = false;
@ -353,13 +355,11 @@ class KRAppRunData {
kr_token = null;
kr_account.value = null;
kr_userId.value = null;
kr_loginType = null;
kr_areaCode = null;
//
await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
// 🔧 4: - 访
try {
final subscribeService = Get.find<dynamic>(tag: 'KRSubscribeService');
@ -413,35 +413,41 @@ class KRAppRunData {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🔍 开始执行设备登录...');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
_logStepTiming('设备登录开始');
//
await KRDeviceInfoService().initialize();
_logStepTiming('初始化设备信息完成');
KRLogUtil.kr_i('🔐 开始执行设备登录', tag: 'AppRunData');
//
_logStepTiming('开始设备登录请求');
final authApi = KRAuthApi();
final result = await authApi.kr_deviceLogin();
_logStepTiming('设备登录请求完成');
return await result.fold(
(error) {
(error) {
print('❌ 设备登录失败: ${error.msg}');
KRLogUtil.kr_e('❌ 设备登录失败: ${error.msg}', tag: 'SplashController');
_logStepTiming('设备登录完成');
return false;
},
(token) async {
(token) async {
print('✅ 设备登录成功Token: $token');
KRLogUtil.kr_i('✅ 设备登录成功', tag: 'SplashController');
final deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
_logStepTiming('开始保存用户信息');
await kr_saveUserInfo(
token,
'device_$deviceId', //
KRLoginType.kr_email,
null, //
);
_logStepTiming('保存用户信息完成');
kr_isLogin.value = true;
print('✅ 已标记为登录状态');
_logStepTiming('设备登录完成');
return true;
},
);
@ -456,37 +462,34 @@ class KRAppRunData {
///
Future<void> kr_initializeUserInfo() async {
KRLogUtil.kr_i('开始初始化用户信息', tag: 'AppRunData');
try {
try {
deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
final String? userInfoString =
await KRSecureStorage().kr_readData(key: _keyUserInfo);
if (userInfoString != null && userInfoString.isNotEmpty) {
KRLogUtil.kr_i('找到存储的用户信息,开始解析', tag: 'AppRunData');
try {
final Map<String, dynamic> userInfo = jsonDecode(userInfoString);
kr_token = userInfo['token'];
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
if (kr_token != null && kr_token!.isNotEmpty) {
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有效性和账号信息完整性
//
if (kr_token != null && kr_token!.isNotEmpty && _kr_isValidToken(kr_token!)) {
if (kr_token != null &&
kr_token!.isNotEmpty &&
_kr_isValidToken(kr_token!)) {
// token格式验证通过JWT格式检查
if (kr_account.value != null && kr_account.value!.isNotEmpty) {
//
@ -502,7 +505,9 @@ class KRAppRunData {
// Token无效或格式错误
KRLogUtil.kr_w('⚠️ Token验证失败或格式错误清理该条用户数据', tag: 'AppRunData');
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();
}
@ -518,7 +523,7 @@ class KRAppRunData {
KRLogUtil.kr_e('初始化用户信息过程出错: $e', tag: 'AppRunData');
kr_isLogin.value = false;
}
KRLogUtil.kr_i('用户信息初始化完成,登录状态: ${kr_isLogin.value}', tag: 'AppRunData');
}
@ -558,7 +563,8 @@ class KRAppRunData {
///
void _kr_handleConnectionState(bool isConnected) {
KRLogUtil.kr_i('WebSocket 连接状态: ${isConnected ? "已连接" : "已断开"}', tag: 'AppRunData');
KRLogUtil.kr_i('WebSocket 连接状态: ${isConnected ? "已连接" : "已断开"}',
tag: 'AppRunData');
}
/// Socket
@ -569,42 +575,57 @@ class KRAppRunData {
///
Future<void> _fetchUserInfo() async {
try {
KRLogUtil.kr_i('📞 [AppRunData] 开始调用用户信息接口 /v1/public/user/info ...', tag: 'AppRunData');
KRLogUtil.kr_i('🔐 [AppRunData] 当前 Token: ${kr_token ?? "null"}', tag: 'AppRunData');
KRLogUtil.kr_i('📞 [AppRunData] 开始调用用户信息接口 /v1/public/user/info ...',
tag: 'AppRunData');
KRLogUtil.kr_i('🔐 [AppRunData] 当前 Token: ${kr_token ?? "null"}',
tag: 'AppRunData');
final result = await KRUserApi.kr_getUserInfo();
result.fold(
(error) {
KRLogUtil.kr_e('❌ [AppRunData] 获取用户信息失败: ${error.msg} (code: ${error.code})', tag: 'AppRunData');
(error) {
KRLogUtil.kr_e(
'❌ [AppRunData] 获取用户信息失败: ${error.msg} (code: ${error.code})',
tag: 'AppRunData');
},
(userInfo) {
final authType = userInfo.authMethods.isNotEmpty
? userInfo.authMethods[0].authType
: null;
final authIdentifier = userInfo.authMethods.isNotEmpty
? userInfo.authMethods[0].authIdentifier
: null;
(userInfo) {
final authType = userInfo.authMethods.isNotEmpty
? userInfo.authMethods[0].authType
: null;
final authIdentifier = userInfo.authMethods.isNotEmpty
? userInfo.authMethods[0].authIdentifier
: null;
KRLogUtil.kr_i('✅ [AppRunData] 获取用户信息成功', tag: 'AppRunData');
KRLogUtil.kr_i('📋 [AppRunData] refer_code: "${userInfo.referCode}"', tag: 'AppRunData');
KRLogUtil.kr_i('💰 [AppRunData] balance: ${userInfo.balance}', tag: 'AppRunData');
KRLogUtil.kr_i('💵 [AppRunData] commission: ${userInfo.commission}', 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');
KRLogUtil.kr_i('📋 [AppRunData] refer_code: "${userInfo.referCode}"',
tag: 'AppRunData');
KRLogUtil.kr_i('💰 [AppRunData] balance: ${userInfo.balance}',
tag: 'AppRunData');
KRLogUtil.kr_i('💵 [AppRunData] commission: ${userInfo.commission}',
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_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_commission.value = userInfo.commission;
KRLogUtil.kr_i('💾 [AppRunData] 用户信息已保存到全局状态:', tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_referCode: "${kr_referCode.value}"', tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_refererId: ${kr_refererId.value}', tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_balance: ${kr_balance.value}', tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_commission: ${kr_commission.value}', tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_referCode: "${kr_referCode.value}"',
tag: 'AppRunData');
KRLogUtil.kr_i(' - kr_refererId: ${kr_refererId.value}',
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) {

View File

@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:convert';
import 'package:package_info_plus/package_info_plus.dart';
import '../../utils/kr_log_util.dart';
@ -41,7 +42,6 @@ class KRConfigData {
///
final String kr_invitation_link;
final String kr_website_id;
KRConfigData({
this.kr_config = '',
@ -56,16 +56,21 @@ class KRConfigData {
this.kr_official_telegram = '',
this.kr_official_telephone = '',
this.kr_invitation_link = '',
this.kr_website_id = '',
}) : this.kr_domains = kr_domains ?? [],
this.kr_update_application =
kr_update_application ?? KRUpdateApplication();
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(
kr_config: _krConfigString,
kr_invitation_link: json['invitation_link'] ?? '',
kr_config: json['kr_config'] ?? '',
kr_encryption_key: json['encryption_key'] ?? '',
kr_encryption_method: json['encryption_method'] ?? '',
kr_domains: List<String>.from(json['domains'] ?? []),
@ -77,7 +82,6 @@ class KRConfigData {
kr_official_website: json['official_website'] ?? '',
kr_official_telegram: json['official_telegram'] ?? '',
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 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
try {
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 'dart:io';
import 'dart:math';
import 'dart:convert';
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/common/app_config.dart';
class HIUserInfoController extends GetxController {
///
@ -32,6 +34,7 @@ class HIUserInfoController extends GetxController {
void onInit() {
super.onInit();
_initDeviceId();
_initDeviceLimit();
loadDeviceList();
}
@ -55,13 +58,13 @@ class HIUserInfoController extends GetxController {
final result = await KRUserApi().kr_getUserDevices();
result.fold(
(error) {
(error) {
KRLogUtil.kr_e('加载设备列表失败: ${error.msg}', tag: 'DeviceManagement');
KRSnackBarUtil.show(AppTranslations.kr_dialog.error, error.msg);
},
(deviceList) {
KRLogUtil.kr_i('获取到 ${deviceList.length} 个设备', tag: 'DeviceManagement');
(deviceList) {
KRLogUtil.kr_i('获取到 ${deviceList.length} 个设备',
tag: 'DeviceManagement');
//
devices.value = deviceList.map((device) {
@ -89,7 +92,8 @@ class HIUserInfoController extends GetxController {
} catch (e, stackTrace) {
KRLogUtil.kr_e('加载设备列表异常: $e', 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 {
isLoading.value = false;
}
@ -99,24 +103,26 @@ class HIUserInfoController extends GetxController {
Future<bool> deleteDevice(String id) async {
try {
final device = devices.firstWhere(
(d) => d['id'] == id,
(d) => d['id'] == id,
orElse: () => {},
);
if (device.isEmpty) return 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);
bool success = false;
result.fold(
(error) {
(error) {
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');
success = true;
@ -127,7 +133,8 @@ class HIUserInfoController extends GetxController {
await _reloginWithDevice();
} else {
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) {
KRLogUtil.kr_e('删除设备异常: $e', 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;
}
}
/// 使
Future<void> _reloginWithDevice() async {
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');
// kr_loginOut
final appRunData = KRAppRunData.getInstance();
@ -166,26 +175,27 @@ class HIUserInfoController extends GetxController {
final result = await authApi.kr_deviceLogin();
result.fold(
(error) {
(error) {
//
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();
},
(token) async {
(token) async {
//
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';
await appRunData.kr_saveUserInfo(
token,
'device_$deviceId',
KRLoginType.kr_email,
null,
);
KRLogUtil.kr_i('✅ 设备重新登录成功,已更新用户信息', tag: 'DeviceManagement');
@ -209,35 +219,53 @@ class HIUserInfoController extends GetxController {
} catch (e, stackTrace) {
KRLogUtil.kr_e('设备重新登录异常: $e', 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();
}
}
Future<void> _initDeviceLimit() async {
await KRSiteConfigService().fetchSiteConfig();
}
///
Map<String, dynamic> getDeviceTypeInfo(String userAgent) {
String deviceType = AppTranslations.kr_deviceManagement.deviceTypeUnknown;
String iconName = 'devices';
if (userAgent.contains('Android') || userAgent.toLowerCase().contains('android')) {
deviceType = 'Android' ;// AppTranslations.kr_deviceManagement.deviceTypeAndroid;
if (userAgent.contains('Android') ||
userAgent.toLowerCase().contains('android')) {
deviceType =
'Android'; // AppTranslations.kr_deviceManagement.deviceTypeAndroid;
iconName = 'phone_android';
} else if (userAgent.contains('iOS') || userAgent.contains('iPhone') || userAgent.toLowerCase().contains('ios')) {
deviceType = 'iPhone'; // AppTranslations.kr_deviceManagement.deviceTypeIos;
} else if (userAgent.contains('iOS') ||
userAgent.contains('iPhone') ||
userAgent.toLowerCase().contains('ios')) {
deviceType =
'iPhone'; // AppTranslations.kr_deviceManagement.deviceTypeIos;
iconName = 'phone_iphone';
} else if (userAgent.contains('iPad')) {
deviceType = 'iPad';// AppTranslations.kr_deviceManagement.deviceTypeIpad;
deviceType =
'iPad'; // AppTranslations.kr_deviceManagement.deviceTypeIpad;
iconName = 'tablet';
} else if (userAgent.contains('macOS') || userAgent.contains('Mac') || userAgent.toLowerCase().contains('mac')) {
deviceType = 'Mac';// AppTranslations.kr_deviceManagement.deviceTypeMacos;
} else if (userAgent.contains('macOS') ||
userAgent.contains('Mac') ||
userAgent.toLowerCase().contains('mac')) {
deviceType =
'Mac'; // AppTranslations.kr_deviceManagement.deviceTypeMacos;
iconName = 'desktop_mac';
} else if (userAgent.contains('Windows') || userAgent.toLowerCase().contains('windows')) {
deviceType = 'Windows'; //AppTranslations.kr_deviceManagement.deviceTypeWindows;
} else if (userAgent.contains('Windows') ||
userAgent.toLowerCase().contains('windows')) {
deviceType =
'Windows'; //AppTranslations.kr_deviceManagement.deviceTypeWindows;
iconName = 'computer';
} else if (userAgent.contains('Linux') || userAgent.toLowerCase().contains('linux')) {
deviceType = 'Linux';//AppTranslations.kr_deviceManagement.deviceTypeLinux;
} else if (userAgent.contains('Linux') ||
userAgent.toLowerCase().contains('linux')) {
deviceType =
'Linux'; //AppTranslations.kr_deviceManagement.deviceTypeLinux;
iconName = 'computer';
}
@ -247,8 +275,6 @@ class HIUserInfoController extends GetxController {
};
}
@override
void onReady() {
super.onReady();

View File

@ -55,7 +55,7 @@ class KRCrispController extends GetxController {
// SDK
_nativeConfig = native_crisp.CrispConfig(
websiteID: AppConfig.getInstance().kr_website_id,
websiteID: '47fcc1ac-9674-4ab1-9e3c-6b5666f59a38',
user: native_crisp.User(
email: null,
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: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/account_guard.dart';
import 'package:kaer_with_panels/app/services/iap/iap_service.dart';
class KRHomeController extends GetxController with WidgetsBindingObserver {
// 🔧
@ -44,7 +41,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
///
final KRSubscribeService kr_subscribeService = KRSubscribeService();
/// ,
final Rx<KRHomeViewsStatus> kr_currentViewStatus =
KRHomeViewsStatus.kr_notLoggedIn.obs;
@ -52,25 +48,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
///
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;
@ -223,6 +200,23 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
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();
final selectedAfter =
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
void onInit() async {
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();
//
@ -320,7 +278,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
//
Future.delayed(const Duration(milliseconds: 500), () {
kr_forceSyncConnectionStatus(true);
kr_forceSyncConnectionStatus();
});
// 🔧 Android 15 5
@ -372,14 +330,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
} catch (_) {}
}
///
void _kr_initBottomPanelHeight() {
ever(kr_currentListStatus, (status) {
kr_updateBottomPanelHeight();
KRLogUtil.kr_i(status.toString(), tag: "_kr_initBottomPanelHeight");
});
}
void _kr_initLoginStatus() {
_initLog.log('开始初始化登录状态处理', tag: 'Home');
KRLogUtil.kr_i('初始化登录状态', tag: 'HomeController');
@ -392,10 +342,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
KRLogUtil.kr_w('⏱️ 订阅服务初始化超时(8秒),强制设置为无数据状态', tag: 'HomeController');
// 🔧 Android 15 none error
kr_currentListStatus.value = KRHomeViewsListStatus.kr_none;
//
kr_updateBottomPanelHeight();
_initLog.log('已强制切换到默认视图, 底部面板高度: ${kr_bottomPanelHeight.value}',
tag: 'Subscribe');
KRLogUtil.kr_i('✅ 已强制切换到默认视图', tag: 'HomeController');
}
});
@ -458,8 +405,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
_initLog.logSuccess('用户已登录,准备加载订阅数据', tag: 'Home');
KRLogUtil.kr_i('设置为已登录状态', tag: 'HomeController');
// splash
_kr_ensureSubscribeServiceInitialized();
KRLogUtil.kr_i('订阅服务已在启动页初始化,跳过重复初始化', tag: 'HomeController');
} else {
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
@ -517,6 +463,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
throw TimeoutException('订阅服务初始化超时');
},
).then((_) async {
_checkQuickConnectAutoStart();
final elapsed = DateTime.now().difference(startTime).inMilliseconds;
_initLog.logSuccess('订阅服务初始化完成, 耗时: ${elapsed}ms', tag: 'Subscribe');
_initLog.log('最终列表状态: ${kr_currentListStatus.value}',
@ -594,7 +541,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
KRLogUtil.kr_i('登录状态变化:设置为已登录', tag: 'HomeController');
// splash
KRLogUtil.kr_i('订阅服务已在启动页初始化,跳过重复初始化', tag: 'HomeController');
} else {
@ -681,7 +627,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
} else {
// kr_updateBottomPanelHeight();
}
_checkQuickConnectAutoStart();
_kr_testLatencyWithoutVpn();
break;
case KRSubscribeServiceStatus.kr_none:
@ -1872,18 +1817,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
@override
void 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
@ -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() {
@ -2436,7 +2277,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
}
///
void kr_forceSyncConnectionStatus([bool? isQuickConnect]) {
void kr_forceSyncConnectionStatus() {
try {
KRLogUtil.kr_i('🔄 强制同步连接状态...', tag: 'HomeController');
@ -2479,10 +2320,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
// UI
update();
print('isQuickConnect$isQuickConnect');
if (isQuickConnect == true) {
_checkQuickConnectAutoStart();
}
KRLogUtil.kr_i('✅ 连接状态同步完成', tag: 'HomeController');
} catch (e) {
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/singbox_imp/kr_sing_box_imp.dart';
import 'package:kaer_with_panels/singbox/model/singbox_status.dart';
import 'package:kaer_with_panels/app/utils/account_guard.dart';
DateTime? _hiConnectBtnNextAllowedAt;
const Duration _hiConnectBtnDebounce = Duration(milliseconds: 800);
@ -93,8 +92,6 @@ class HIAnimatedConnectButton extends GetView<KRHomeController> {
child: InkWell(
onTap: () async {
HapticFeedback.lightImpact();
final ok = await ensureAccountExists();
if (!ok) return;
final _now = DateTime.now();
if (_hiConnectBtnNextAllowedAt != null &&
_now.isBefore(_hiConnectBtnNextAllowedAt!)) {

View File

@ -8,7 +8,6 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../controllers/kr_home_controller.dart';
import '../../../routes/app_pages.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 () =======================
class CircularClipper extends CustomClipper<Path> {
@ -175,8 +174,6 @@ class _HISubscriptionCornerButtonState extends State<HISubscriptionCornerButton>
Widget build(BuildContext context) {
return GestureDetector(
onTap: () async {
final ok = await ensureAccountExists();
if (!ok) return;
_startCircularTransition(context);
},
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/swipe_config.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 {
const KRHomeView({super.key});
@ -26,16 +25,10 @@ class KRHomeView extends StatefulWidget implements HasSwipeConfig {
enableLeft: true,
enableRight: true,
onLeft: () {
ensureAccountExists().then((ok) {
if (!ok) return;
Get.toNamed(Routes.HI_MENU);
});
Get.toNamed(Routes.HI_MENU);
},
onRight: () {
ensureAccountExists().then((ok) {
if (!ok) return;
GlobalOverlayService.instance.triggerSubscriptionAnimation();
});
GlobalOverlayService.instance.triggerSubscriptionAnimation();
},
);
@ -109,43 +102,37 @@ class _KRHomeViewState extends State<KRHomeView> {
);
// 3.
if (currentSubscribe == null) {
// --- 1: ---
content = Text(
'尚未购买套餐',
style: highlightStyle,
);
final listStatus =
controller.kr_currentListStatus.value;
if (listStatus == KRHomeViewsListStatus.kr_loading) {
content = Text('加载订阅中', style: normalStyle);
} else {
// --- 2: ---
final now = DateTime.now();
DateTime? expireDateTime;
try {
expireDateTime =
DateTime.parse(currentSubscribe.expireTime);
} catch (e) {
//
}
if (expireDateTime != null &&
expireDateTime.isBefore(now)) {
// --- 2.1: ---
final formattedExpireDate =
'${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}';
// 使 \n Text
content = Text(
'您的套餐已于 $formattedExpireDate 到期\n请前往购买新套餐',
style: highlightStyle,
);
if (currentSubscribe == null) {
content = Text('尚未购买套餐', style: highlightStyle);
} else {
// --- 2.2: ---
final formattedExpireTime = expireDateTime != null
final now = DateTime.now();
DateTime? expireDateTime;
try {
expireDateTime =
DateTime.parse(currentSubscribe.expireTime);
} catch (e) {}
if (expireDateTime != null &&
expireDateTime.isBefore(now)) {
final formattedExpireDate =
'${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}';
content = Text(
'您的套餐已于 $formattedExpireDate 到期\n请前往购买新套餐',
style: highlightStyle);
} else {
final formattedExpireTime = expireDateTime !=
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')}'
: '未知';
// 使 \n Text
content = Text(
'套餐到期时间:$formattedExpireTime\n${controller.kr_isConnected.value ? '当前线路:${controller.kr_getRealConnectedNodeCountry()}' : '未连接'}',
style: normalStyle,
);
}
}
}
@ -233,7 +220,7 @@ class _KRHomeViewState extends State<KRHomeView> {
10.w,
);
}
HIDialog.show(
title: '闪连功能',
message:

View File

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

View File

@ -35,10 +35,10 @@ class KRSplashController extends GetxController {
final _initLog = KRInitLogCollector();
//
final RxBool kr_isLoading = true.obs;
//
final RxBool kr_hasError = false.obs;
//
final RxString kr_errorMessage = ''.obs;
@ -65,14 +65,8 @@ class KRSplashController extends GetxController {
_stepStartTime = _startTime;
// 使 print
print('[SPLASH_TIMING] ═══════════════════════════════════════');
print('[SPLASH_TIMING] 🎬 KRSplashController onInit 被调用了!');
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模式下清理旧数据
// DEBUG模式下执行
@ -85,15 +79,6 @@ class KRSplashController extends GetxController {
print('🧹 清理域名检测状态...');
KRDomain.kr_resetDomainState();
// 🔧 P2优化
// print('🌐 启动后台任务:网站配置加载...');
// KRLogUtil.kr_i('🌐 后台任务:网站配置和设备登录', tag: 'SplashController');
// _kr_initSiteConfig(); // _kr_continueInitialization
// 🔧
if (kDebugMode) {
print('🔧 初始化日志收集器...');
}
_initializeAndStart();
}
@ -130,21 +115,15 @@ class KRSplashController extends GetxController {
final totalMs = totalDuration.inMilliseconds;
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; //
}
///
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 {
// 🔧 Android 15 2520 + 5
await Future.any([
@ -162,116 +141,20 @@ class KRSplashController extends GetxController {
}
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
tag: 'SplashController');
}
///
Future<void> _executeSiteConfigInit() async {
print('📞 准备调用 KRSiteConfigService().initialize()...');
final success = await KRSiteConfigService().initialize();
final crispId = await KRSiteConfigService().getCrispId();
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');
}
print('📞 准备调用 KRDomain.kr_loadBaseDomain()...');
await KRDomain.kr_loadBaseDomain();
print('📞 KRDomain.kr_loadBaseDomain() 完成');
}
///
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 {
try {
_initLog.logPhaseStart('主初始化流程');
_initLog.log('开始执行 _kr_initialize', tag: 'Splash');
KRLogUtil.kr_i('🔧 开始执行 _kr_initialize', tag: 'SplashController');
// 🔧 Android 15 15
@ -304,7 +187,8 @@ class KRSplashController extends GetxController {
_handleError('网络连接失败', '请检查您的网络连接是否正常,然后重试。');
} on DioException catch (e) {
// 🔧 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);
_handleError('服务请求失败', errorMsg);
} catch (e) {
@ -328,10 +212,13 @@ class KRSplashController extends GetxController {
// 1.
try {
_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];
_initLog.logSuccess('设置默认域名: ${KRDomain.kr_currentDomain}', tag: 'Minimal');
KRLogUtil.kr_i('✅ 设置默认域名: ${KRDomain.kr_currentDomain}', tag: 'SplashController');
_initLog.logSuccess('设置默认域名: ${KRDomain.kr_currentDomain}',
tag: 'Minimal');
KRLogUtil.kr_i('✅ 设置默认域名: ${KRDomain.kr_currentDomain}',
tag: 'SplashController');
if (kDebugMode) {
print('✅ 设置默认域名: ${KRDomain.kr_currentDomain}');
}
@ -509,21 +396,15 @@ class KRSplashController extends GetxController {
Future<void> _kr_continueInitialization() async {
try {
_initLog.logSeparator();
_initLog.log('🚀 启动页主流程开始', tag: 'Continue');
_initLog.logSeparator();
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('🚀 启动页主流程开始...', tag: 'SplashController');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
// 🔧 Android 15
if (Platform.isIOS || Platform.isAndroid) {
_initLog.log('📱 检查网络连接状态超时5秒', tag: 'Continue');
KRLogUtil.kr_i('📱 检查网络连接...', tag: 'SplashController');
try {
// 5
final bool isConnected = await KRNetworkCheck.kr_checkNetworkConnection().timeout(
final bool isConnected =
await KRNetworkCheck.kr_checkNetworkConnection().timeout(
const Duration(seconds: 5),
onTimeout: () {
_initLog.logWarning('网络连接检查超时5秒继续初始化', tag: 'Continue');
@ -550,8 +431,6 @@ class KRSplashController extends GetxController {
KRLogUtil.kr_i('💻 桌面平台,跳过网络连接检查', tag: 'SplashController');
}
//
// 🔧
// initSiteConfig
// 使
@ -561,7 +440,8 @@ class KRSplashController extends GetxController {
_logStepTiming('开始设备登录检查');
// 5
final success = await KRAppRunData.getInstance().kr_checkAndPerformDeviceLogin();
final success =
await KRAppRunData.getInstance().kr_checkAndPerformDeviceLogin();
if (!success) {
//
@ -582,7 +462,7 @@ class KRSplashController extends GetxController {
// AppConfig().initConfig主要是做AppConfig层面的配置加载
// AppConfig().initConfig API
// AppConfig().initConfig 使)
_initLog.log('⚙️ 开始初始化应用配置(域名加载等)', tag: 'Continue');
KRLogUtil.kr_i('⚙️ 开始初始化应用配置...', tag: 'SplashController');
await AppConfig().initConfig(
@ -605,12 +485,7 @@ class KRSplashController extends GetxController {
//
Future<void> _kr_continueAfterConfig() async {
try {
//
print('[SPLASH_TIMING] 🔄 开始初始化订阅服务...');
KRLogUtil.kr_i('[SPLASH_TIMING] 🔄 开始初始化订阅服务', tag: 'SplashController');
_kr_ensureSubscribeServiceInitialized();
// SingBox
// SingBox
_logStepTiming('开始SingBox初始化');
await KRSingBoxImp.instance.init();
_logStepTiming('SingBox初始化完成');
@ -620,20 +495,12 @@ class KRSplashController extends GetxController {
final token = KRAppRunData.getInstance().kr_token;
final hasToken = token != null && token.isNotEmpty;
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🎯 准备进入主页');
print('📊 最终登录状态: $loginStatus');
print('🎫 Token存在: $hasToken');
if (hasToken) {
print('🎫 Token前缀: ${token.substring(0, min(20, token.length))}...');
}
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('🎯 准备进入主页', tag: 'SplashController');
KRLogUtil.kr_i('📊 最终登录状态: $loginStatus', tag: 'SplashController');
KRLogUtil.kr_i('🎫 Token存在: $hasToken', tag: 'SplashController');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
// 🔧
_initLog.logSeparator();
@ -652,12 +519,13 @@ class KRSplashController extends GetxController {
//
_logStepTiming('开始页面导航');
if(loginStatus) {
if (loginStatus) {
//
Get.offAllNamed(Routes.KR_HOME);
}else {
} else {
kr_hasError.value = true;
kr_errorMessage.value = '登录:${AppTranslations.kr_splash.kr_initializationFailed}';
kr_errorMessage.value =
'登录:${AppTranslations.kr_splash.kr_initializationFailed}';
}
_logStepTiming('页面导航完成');
} catch (e) {
@ -667,63 +535,22 @@ class KRSplashController extends GetxController {
final totalMs = totalDuration.inMilliseconds;
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);
KRLogUtil.kr_e('启动初始化失败: $e', tag: 'SplashController');
KRLogUtil.kr_e('⏰ 启动失败总耗时: ${totalMs}ms', tag: 'SplashController');
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(); //
}
}
///
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() {
kr_hasError.value = false;
@ -749,15 +576,15 @@ class KRSplashController extends GetxController {
///
Future<void> _kr_clearOldLocalData() async {
try {
KRLogUtil.kr_i('🧹 开始清理旧本地存储数据...', tag: 'SplashController');
// KRLogUtil.kr_i('🧹 开始清理旧本地存储数据...', tag: 'SplashController');
//
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');
KRLogUtil.kr_i('✅ 已清理DEVICE_INFO', tag: 'SplashController');
// KRLogUtil.kr_i('✅ 已清理DEVICE_INFO', tag: 'SplashController');
KRLogUtil.kr_i('✅ 旧本地存储数据已全部清理', tag: 'SplashController');
} catch (e) {
@ -775,4 +602,4 @@ class KRSplashController extends GetxController {
void onClose() {
super.onClose();
}
}
}

View File

@ -25,15 +25,14 @@ class BaseResponse<T> {
final dataMap = json['data'] ?? Map<String, dynamic>();
final cipherText = dataMap['data'] ?? "";
final nonce = dataMap['time'] ?? "";
print('明文${cipherText}');
// enable_security
if (cipherText.isNotEmpty && nonce.isNotEmpty) {
try {
if (kDebugMode) {
// print('═══════════════════════════════════════');
// print('🔐 检测到加密响应,开始解密...');
print('📥 加密数据长度: ${cipherText.length} 字符');
print('⏰ 时间戳: $nonce');
// print('📥 加密数据长度: ${cipherText.length} 字符');
// print('⏰ 时间戳: $nonce');
}
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_log_util.dart';
import 'package:flutter/foundation.dart';
// import 'package:video/app/utils/common_util.dart';
// import 'package:video/app/utils/log_util.dart';
@ -144,70 +143,11 @@ class HttpUtil {
}
var map = <String, dynamic>{};
// enable_security
final shouldEncrypt = KRSiteConfigService().isDeviceSecurityEnabled();
if (shouldEncrypt) {
KRLogUtil.kr_i('🔐 需要加密请求数据', tag: 'HttpUtil');
final plainText = jsonEncode(params);
map = KRAesUtil.encryptData(plainText, AppConfig.kr_encryptionKey);
} else {
map = params;
}
final plainText = jsonEncode(params);
map = KRAesUtil.encryptData(plainText, AppConfig.kr_encryptionKey);
//
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;
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
class _KRSimpleHttpInterceptor extends Interceptor {
///
static const bool KR_HTTP_PRINT = true;
final Dio _dio;
_KRSimpleHttpInterceptor(this._dio);
static String? _lastPath;
static int _lastTsMs = 0;
@override
///
///
///
///
/// - options: data queryParameters
/// - handler:
/// void
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (kDebugMode) {
if (KR_HTTP_PRINT) {
print('>>> Request │ ${options.method}${options.uri}');
}
if (options.data != null) {
if (kDebugMode) {
print('Body: ${options.data}');
}
// data time
if (KR_HTTP_PRINT) {
Map<String, dynamic>? m;
if (options.data is Map<String, dynamic>) {
final data = options.data as Map<String, dynamic>;
if (data.containsKey('data') && data.containsKey('time')) {
try {
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');
}
}
}
m = options.data as Map<String, dynamic>;
} else if (options.queryParameters.isNotEmpty) {
m = options.queryParameters;
}
if (m != null) {
final decrypted = _tryDecryptFromMap(m);
_printDecryptedOrFallback(
phase: 'Request', raw: m, decrypted: decrypted);
}
}
handler.next(options);
}
@override
///
///
///
///
/// - response: Map
/// - handler:
/// void
void onResponse(Response response, ResponseInterceptorHandler handler) {
if (kDebugMode) {
if (KR_HTTP_PRINT) {
print(
'<<< Response │ ${response.requestOptions.method}${response.statusCode} ${response.statusMessage}${response.requestOptions.uri}');
}
if (response.data != null) {
if (kDebugMode) {
print('Body: ${response.data}');
}
// data time
if (response.data is Map<String, dynamic>) {
final dataMap = response.data as Map<String, dynamic>;
// data
final nestedData = dataMap['data'];
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');
}
}
}
if (KR_HTTP_PRINT && response.data is Map<String, dynamic>) {
final dataMap = response.data as Map<String, dynamic>;
String? decrypted = _tryDecryptFromMap(dataMap);
if (decrypted == null && dataMap['data'] is Map<String, dynamic>) {
decrypted = _tryDecryptFromMap(dataMap['data'] as Map<String, dynamic>);
}
_printDecryptedOrFallback(
phase: 'Response', raw: dataMap, decrypted: decrypted);
}
handler.next(response);
}
@override
///
///
/// Unknown
///
/// - err: Dio
/// - handler:
/// void
void onError(DioException err, ErrorInterceptorHandler handler) {
if (kDebugMode) {
if (KR_HTTP_PRINT) {
print(
'<<< Error │ ${err.requestOptions.method}${err.requestOptions.uri}');
}
if (kDebugMode) {
if (KR_HTTP_PRINT) {
print('Error Type: ${err.type}');
}
if (err.message != null) {
if (kDebugMode) {
if (KR_HTTP_PRINT) {
print('Error Message: ${err.message}');
}
}
if (err.response?.data != null) {
if (kDebugMode) {
if (KR_HTTP_PRINT) {
print('Response Data: ${err.response?.data}');
}
}
@ -545,4 +385,53 @@ class _KRSimpleHttpInterceptor extends Interceptor {
}
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');
//
final siteConfigService = KRSiteConfigService();
final needEncryption = siteConfigService.isDeviceSecurityEnabled();
print('🔒 是否需要加密: $needEncryption');
KRLogUtil.kr_i('🔒 是否需要加密: $needEncryption', tag: 'KRAuthApi');
final needEncryption = true;
String? requestBody;
if (needEncryption) {
//
print('🔐 加密请求数据...');
final encrypted = KRAesUtil.encryptJson(data, AppConfig.kr_encryptionKey);
requestBody = '{"data":"${encrypted['data']}","time":"${encrypted['time']}"}';
print('🔐 加密后请求体: $requestBody');
KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
// print('🔐 加密后请求体: $requestBody');
// KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
} else {
// 使
requestBody = jsonEncode(data);
print('📝 明文请求体: $requestBody');
}
@ -439,10 +431,10 @@ class KRAuthApi {
),
);
print('📥 响应状态码: ${response.statusCode}');
print('📥 响应数据: ${response.data}');
KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
// print('📥 响应状态码: ${response.statusCode}');
// print('📥 响应数据: ${response.data}');
// KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
// KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
if (response.statusCode == 200) {
Map<String, dynamic> responseData = response.data as Map<String, dynamic>;

View File

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

View File

@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:flutter/foundation.dart';
@ -7,6 +8,7 @@ import '../common/app_config.dart';
import '../utils/kr_log_util.dart';
import '../utils/kr_http_adapter_util.dart';
import 'singbox_imp/kr_sing_box_imp.dart';
import 'api_service/kr_api.user.dart';
///
class KRSiteConfigService extends ChangeNotifier {
@ -18,15 +20,6 @@ class KRSiteConfigService extends ChangeNotifier {
_dio.options.sendTimeout = const Duration(seconds: 20);
_dio.options.receiveTimeout = const Duration(seconds: 20);
// 🔧 使
// SingBox
//
// DioExceptionType.unknown
KRLogUtil.kr_i(
'🌐 网站配置服务:使用直连模式(不通过代理)',
tag: 'KRSiteConfigService',
);
// 🔧 SSL
_dio.httpClientAdapter = KRHttpAdapterUtil.createAdapter(
useSingBoxProxy: false,
@ -49,190 +42,126 @@ class KRSiteConfigService extends ChangeNotifier {
///
bool get isInitialized => _isInitialized;
///
Future<bool> initialize() async {
int retryCount = 0;
const int maxRetries = 5;
return await initializeDomains();
}
while (retryCount < maxRetries) {
try {
if (kDebugMode) {
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;
final config = AppConfig.getInstance();
config.kr_website_id = getCrispId();
config.device_limit = getDeviceLimit();
//
_printConfigInfo();
//
notifyListeners();
return true;
} else {
KRLogUtil.kr_e('❌ API返回错误 - ${responseData['msg']}', tag: 'KRSiteConfigService');
// API
return false;
}
} else {
KRLogUtil.kr_e('❌ HTTP错误 - ${response.statusCode}', tag: 'KRSiteConfigService');
// HTTP 404, 500
// catch
throw DioException(
requestOptions: response.requestOptions,
response: response,
type: DioExceptionType.badResponse,
error: 'HTTP Error ${response.statusCode}',
);
}
} 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;
}
}
//
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;
}
Future<bool> initializeDomains() async {
try {
await KRDomain.kr_loadBaseDomain();
_isInitialized = true;
notifyListeners();
return true;
} catch (_) {
return false;
}
}
Future<bool> fetchSiteConfig() async {
try {
final result = await KRUserApi().kr_config();
return await result.fold(
(error) async {
return false;
},
(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 (_) {
return false;
}
KRLogUtil.kr_e('❌ 达到最大重试次数 ($maxRetries),初始化失败', tag: 'KRSiteConfigService');
return false;
}
///
void _printConfigInfo() {
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('🏠 站点名称: ${_siteConfig!.site.siteName}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点描述: ${_siteConfig!.site.siteDesc}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点域名: ${_siteConfig!.site.host}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('💬 Crisp ID: ${_siteConfig!.site.crispId}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点名称: ${_siteConfig!.site.siteName}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点描述: ${_siteConfig!.site.siteDesc}',
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(' ✓ 开放注册: ${isRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 手机号注册: ${isMobileRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 邮箱注册: ${isEmailRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 设备登录: ${isDeviceLoginEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 开放注册: ${isRegisterEnabled() ? "" : ""}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 手机号注册: ${isMobileRegisterEnabled() ? "" : ""}',
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(' ✓ 邮箱验证: ${isEmailVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 手机验证: ${isMobileVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 登录验证: ${isLoginVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 注册验证: ${isRegisterVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 重置密码验证: ${isResetPasswordVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 邮箱验证: ${isEmailVerificationEnabled() ? "" : ""}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 手机验证: ${isMobileVerificationEnabled() ? "" : ""}',
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(' ✓ 强制邀请码: ${isForcedInvite() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 推荐比例: ${_siteConfig!.invite.referralPercentage}%', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 强制邀请码: ${isForcedInvite() ? "" : ""}',
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(' ✓ 货币单位: ${_siteConfig!.currency.currencyUnit}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 货币符号: ${_siteConfig!.currency.currencySymbol}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 货币单位: ${_siteConfig!.currency.currencyUnit}',
tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 货币符号: ${_siteConfig!.currency.currencySymbol}',
tag: 'KRSiteConfigService');
// OAuth
if (_siteConfig!.oauthMethods.isNotEmpty) {
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🔑 OAuth 方法: ${_siteConfig!.oauthMethods.join(", ")}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
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');
}
///
@ -352,10 +281,12 @@ class KRSiteConfigService extends ChangeNotifier {
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();
return allowedDomains.any((domain) => emailDomain.endsWith(domain.toLowerCase()));
return allowedDomains
.any((domain) => emailDomain.endsWith(domain.toLowerCase()));
}
/// 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;
}
final websiteId = AppConfig.getInstance().kr_website_id;
final websiteId = '47fcc1ac-9674-4ab1-9e3c-6b5666f59a38'; // AppConfig.getInstance().kr_website_id;
if (websiteId.isEmpty) {
HIDialog.show(
title: '提示',

View File

@ -31,7 +31,7 @@ class KRHttpAdapterUtil {
client.findProxy = (url) {
try {
final proxyConfig = KRSingBoxImp.instance.kr_buildProxyRule();
KRLogUtil.kr_i('🔍 请求使用代理: $proxyConfig, url: $url', tag: 'KRHttpAdapterUtil');
// KRLogUtil.kr_i('🔍 请求使用代理: $proxyConfig, url: $url', tag: 'KRHttpAdapterUtil');
return proxyConfig;
} catch (e) {
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: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/utils/account_guard.dart';
/// 🔹 HIBaseScaffold
///
@ -114,8 +113,6 @@ class HIBaseScaffold extends StatelessWidget {
if (showMenuButton) {
return GestureDetector(
onTap: () async {
final ok = await ensureAccountExists();
if (!ok) return;
Get.toNamed(Routes.HI_MENU);
},
child: Container(

View File

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