hi-client/lib/app/modules/kr_splash/controllers/kr_splash_controller.dart
speakeloudest fc4ecf874b
Some checks failed
Build Android APK / 编译 libcore.aar (push) Has been cancelled
Build Android APK / 编译 Android APK (release) (push) Has been cancelled
Build Android APK / 创建 GitHub Release (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Android) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Windows) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (macOS) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Linux) (push) Has been cancelled
Build Multi-Platform / 构建 Android APK (push) Has been cancelled
Build Multi-Platform / 构建 Windows (push) Has been cancelled
Build Multi-Platform / 构建 macOS (push) Has been cancelled
Build Multi-Platform / 构建 Linux (push) Has been cancelled
Build Multi-Platform / 创建 Release (push) Has been cancelled
Build Windows / build (push) Has been cancelled
feat: 更新代码仓库全部修改
2025-10-30 23:31:05 -07:00

389 lines
18 KiB
Dart
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:get/get.dart';
import 'dart:convert';
import 'dart:io' show Platform;
import 'dart:math';
import 'package:kaer_with_panels/app/utils/kr_network_check.dart';
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
import 'package:kaer_with_panels/app/routes/app_pages.dart';
import 'package:kaer_with_panels/app/common/app_config.dart';
import 'package:kaer_with_panels/app/common/app_run_data.dart';
import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart';
import 'package:kaer_with_panels/app/services/kr_site_config_service.dart';
import 'package:kaer_with_panels/app/services/kr_device_info_service.dart';
import 'package:kaer_with_panels/app/services/api_service/kr_auth_api.dart';
import 'package:kaer_with_panels/app/model/enum/kr_request_type.dart';
import 'package:kaer_with_panels/app/utils/kr_secure_storage.dart';
import 'package:kaer_with_panels/app/services/kr_subscribe_service.dart';
import 'package:kaer_with_panels/app/widgets/dialogs/hi_dialog.dart';
import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart';
import 'package:flutter/material.dart';
import 'package:kaer_with_panels/app/localization/app_translations.dart';
import 'package:kaer_with_panels/app/modules/kr_home/controllers/kr_home_controller.dart';
import 'package:kaer_with_panels/app/modules/kr_home/models/kr_home_views_status.dart';
import 'dart:async';
class KRSplashController extends GetxController {
// 加载状态
final RxBool kr_isLoading = true.obs;
// 错误状态
final RxBool kr_hasError = false.obs;
// 错误信息
final RxString kr_errorMessage = ''.obs;
/// 订阅服务
final KRSubscribeService kr_subscribeService = KRSubscribeService();
// 倒计时
// final count = 0.obs;
// 是否正在加载
final isLoading = true.obs;
// // 是否初始化成功
// final isInitialized = false.obs;
// 启动开始时间(用于计算总耗时)
late final DateTime _startTime;
late DateTime _stepStartTime;
@override
void onInit() {
super.onInit();
// 记录启动开始时间
_startTime = DateTime.now();
_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');
// 异步初始化网站配置
_kr_initSiteConfig().then((_) {
print('🔧 网站配置完成,开始调用 _kr_initialize...');
_kr_initialize();
});
}
// 记录步骤耗时的辅助方法
void _logStepTiming(String stepName) {
final now = DateTime.now();
final stepDuration = now.difference(_stepStartTime);
final totalDuration = now.difference(_startTime);
final stepMs = stepDuration.inMilliseconds;
final totalMs = totalDuration.inMilliseconds;
print('[SPLASH_TIMING] ⏱️ $stepName 耗时: ${stepMs}ms | 累计: ${totalMs}ms');
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 {
print('📞 准备调用 KRSiteConfigService().initialize()...');
final success = await KRSiteConfigService().initialize();
final crispId = await KRSiteConfigService().getCrispId();
print('📞 KRSiteConfigService().initialize() 返回: $success');
if (success) {
final config = AppConfig.getInstance();
config.kr_website_id = crispId;
print('📞 KRSiteConfigService().initialize() 返回: $crispId');
print('AppConfig website_id 已更新为: ${config.kr_website_id}');
print('[SPLASH_TIMING] ✅ 网站配置初始化成功');
KRLogUtil.kr_i('[SPLASH_TIMING] ✅ 网站配置初始化成功', tag: 'SplashController');
} else {
print('⚠️ 网站配置初始化失败,将使用默认配置');
KRLogUtil.kr_w('⚠️ 网站配置初始化失败,将使用默认配置', tag: 'SplashController');
}
} catch (e) {
print('❌ 网站配置初始化异常: $e');
KRLogUtil.kr_e('❌ 网站配置初始化异常: $e', tag: 'SplashController');
}
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
}
Future<void> _kr_initialize() async {
try {
_logStepTiming('开始主要初始化流程');
KRLogUtil.kr_i('[SPLASH_TIMING] 🔧 开始执行 _kr_initialize', tag: 'SplashController');
// 只在手机端检查网络权限
if (Platform.isIOS || Platform.isAndroid) {
_logStepTiming('开始网络权限检查');
KRLogUtil.kr_i('[SPLASH_TIMING] 📱 移动平台,检查网络权限...', tag: 'SplashController');
final bool hasNetworkPermission = await KRNetworkCheck.kr_initialize(
Get.context!,
onPermissionGranted: () async {
_logStepTiming('网络权限检查完成');
await _kr_continueInitialization();
},
);
if (!hasNetworkPermission) {
// 计算网络权限失败时的总耗时
final endTime = DateTime.now();
final totalDuration = endTime.difference(_startTime);
final totalMs = totalDuration.inMilliseconds;
print('❌ 网络权限失败时间: ${endTime.toIso8601String()}');
print('🕐 网络权限失败总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)');
kr_hasError.value = true;
kr_errorMessage.value = AppTranslations.kr_splash.kr_networkPermissionFailed;
KRLogUtil.kr_e('❌ 网络权限检查失败', tag: 'SplashController');
KRLogUtil.kr_e('⏰ 网络权限失败总耗时: ${totalMs}ms', tag: 'SplashController');
return;
}
} else {
// 非手机端直接继续初始化
_logStepTiming('桌面平台跳过权限检查');
KRLogUtil.kr_i('[SPLASH_TIMING] 💻 桌面平台,直接执行初始化', tag: 'SplashController');
await _kr_continueInitialization();
}
} catch (e) {
// 计算初始化异常时的总耗时
final endTime = DateTime.now();
final totalDuration = endTime.difference(_startTime);
final totalMs = totalDuration.inMilliseconds;
print('❌ 初始化异常时间: ${endTime.toIso8601String()}');
print('🕐 初始化异常总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)');
KRLogUtil.kr_e('❌ _kr_initialize 异常: $e', tag: 'SplashController');
KRLogUtil.kr_e('⏰ 初始化异常总耗时: ${totalMs}ms', tag: 'SplashController');
kr_hasError.value = true;
kr_errorMessage.value = '${AppTranslations.kr_splash.kr_initializationFailed}$e';
}
}
Future<void> _kr_continueInitialization() async {
try {
_logStepTiming('开始继续初始化流程');
KRLogUtil.kr_i('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] 🚀 启动页主流程开始...', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
// 只在手机端检查网络连接
if (Platform.isIOS || Platform.isAndroid) {
_logStepTiming('开始网络连接检查');
KRLogUtil.kr_i('[SPLASH_TIMING] 📱 检查网络连接...', tag: 'SplashController');
final bool isConnected = await KRNetworkCheck.kr_checkNetworkConnection();
if (!isConnected) {
// 计算网络连接失败时的总耗时
final endTime = DateTime.now();
final totalDuration = endTime.difference(_startTime);
final totalMs = totalDuration.inMilliseconds;
print('❌ 网络连接失败时间: ${endTime.toIso8601String()}');
print('🕐 网络连接失败总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)');
kr_hasError.value = true;
kr_errorMessage.value = AppTranslations.kr_splash.kr_networkConnectionFailed;
KRLogUtil.kr_e('❌ 网络连接失败', tag: 'SplashController');
KRLogUtil.kr_e('⏰ 网络连接失败总耗时: ${totalMs}ms', tag: 'SplashController');
return;
}
_logStepTiming('网络连接检查完成');
KRLogUtil.kr_i('[SPLASH_TIMING] ✅ 网络连接正常', tag: 'SplashController');
} else {
_logStepTiming('桌面平台跳过网络检查');
KRLogUtil.kr_i('[SPLASH_TIMING] 💻 桌面平台,跳过网络连接检查', tag: 'SplashController');
}
// 网络检查完成后执行设备登录(始终支持)
_logStepTiming('开始设备登录检查');
// 5⃣ 执行设备登录
final success = await KRAppRunData.getInstance().kr_checkAndPerformDeviceLogin();
if (!success) {
// 设备登录失败 → 提示用户重试
HIDialog.show(
message: '设备登录失败,请检查网络或重试',
confirmText: '重试',
preventBackDismiss: true,
onConfirm: () async {
await _kr_initialize(); // 递归重试
},
);
return;
}
_logStepTiming('设备登录检查完成');
// 初始化配置
await AppConfig().initConfig(
onSuccess: () async {
// 配置初始化成功,没有配置
KRLogUtil.kr_i('[SPLASH_TIMING] ⚙️ 初始化应用配置...', tag: 'SplashController');
await _kr_continueAfterConfig();
},
);
} catch (e) {
// 计算配置初始化异常时的总耗时
final endTime = DateTime.now();
final totalDuration = endTime.difference(_startTime);
final totalMs = totalDuration.inMilliseconds;
print('❌ 配置初始化异常时间: ${endTime.toIso8601String()}');
print('🕐 配置初始化异常总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)');
// 配置初始化失败,显示错误信息
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';
}
}
// 配置初始化成功后的后续步骤
Future<void> _kr_continueAfterConfig() async {
try {
// 用户信息初始化完成后,立即初始化订阅服务
print('[SPLASH_TIMING] 🔄 开始初始化订阅服务...');
KRLogUtil.kr_i('[SPLASH_TIMING] 🔄 开始初始化订阅服务', tag: 'SplashController');
_kr_ensureSubscribeServiceInitialized();
// 初始化SingBox
_logStepTiming('开始SingBox初始化');
await KRSingBoxImp.instance.init();
_logStepTiming('SingBox初始化完成');
// 验证登录状态是否已正确设置
final loginStatus = KRAppRunData.getInstance().kr_isLogin.value;
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('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
// 计算总耗时
final endTime = DateTime.now();
final totalDuration = endTime.difference(_startTime);
final totalMs = totalDuration.inMilliseconds;
print('[SPLASH_TIMING] ⏰ 启动结束时间: ${endTime.toIso8601String()}');
print('[SPLASH_TIMING] 🕐 启动总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)');
KRLogUtil.kr_i('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] 🎯 准备进入主页', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] 📊 最终登录状态: $loginStatus', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] 🎫 Token存在: $hasToken', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] ⏰ 启动总耗时: ${totalMs}ms', tag: 'SplashController');
KRLogUtil.kr_i('[SPLASH_TIMING] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'SplashController');
// 直接导航到主页(无论是否登录,主页会根据登录状态显示不同内容)
_logStepTiming('开始页面导航');
if(loginStatus) {
// 直接导航到主页
Get.offAllNamed(Routes.KR_HOME);
}else {
kr_hasError.value = true;
kr_errorMessage.value = '登录:${AppTranslations.kr_splash.kr_initializationFailed}';
}
_logStepTiming('页面导航完成');
} catch (e) {
// 计算错误时的总耗时
final endTime = DateTime.now();
final totalDuration = endTime.difference(_startTime);
final totalMs = totalDuration.inMilliseconds;
print('❌ 启动失败时间: ${endTime.toIso8601String()}');
print('🕐 启动失败总耗时: ${totalMs}ms (${totalDuration.inSeconds}.${(totalMs % 1000).toString().padLeft(3, '0')}s)');
// 后续步骤失败,显示错误信息
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';
}
}
/// 确保订阅服务初始化
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;
kr_errorMessage.value = '';
_kr_initialize();
}
@override
void onReady() {
super.onReady();
}
@override
void onClose() {
super.onClose();
}
}