diff --git a/android/gradle.properties b/android/gradle.properties index fd02741..e3e9041 100755 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xlint:-options +org.gradle.jvmargs=-Xmx4048m -Dfile.encoding=UTF-8 android.useAndroidX=true android.enableJetifier=true # org.gradle.java.home=/Users/mac/Library/Java/JavaVirtualMachines/ms-17.0.16/Contents/Home diff --git a/assets/translations/strings_zh.i18n.json b/assets/translations/strings_zh.i18n.json index d7d2cea..a6ab661 100755 --- a/assets/translations/strings_zh.i18n.json +++ b/assets/translations/strings_zh.i18n.json @@ -75,7 +75,7 @@ "codeSentCountdown": "验证码已发送 {seconds}s", "and": "和", "enterInviteCode": "请输入邀请码", - "registerSuccess": "注册成功" + "registerSuccess": "注册成功", "search": "搜索", "selectOtherRegion": "选择其他地区" }, diff --git a/lib/app/modules/kr_home/views/kr_home_bottom_panel.dart b/lib/app/modules/kr_home/views/kr_home_bottom_panel.dart index 4c70cd1..36dbfa3 100755 --- a/lib/app/modules/kr_home/views/kr_home_bottom_panel.dart +++ b/lib/app/modules/kr_home/views/kr_home_bottom_panel.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../../localization/app_translations.dart'; import '../../../widgets/kr_app_text_style.dart'; import '../../../widgets/kr_loading_animation.dart'; @@ -13,6 +12,8 @@ import '../widgets/kr_subscription_card.dart'; import 'kr_home_trial_card.dart'; import 'kr_home_last_day_card.dart'; import '../../../utils/kr_log_util.dart'; +import 'dart:io'; +import 'package:path_provider/path_provider.dart'; class KRHomeBottomPanel extends GetView { const KRHomeBottomPanel({super.key}); @@ -107,6 +108,26 @@ class KRHomeBottomPanel extends GetView { // 未订阅(包括未登录):始终显示订阅卡片 Builder(builder: (context) { KRLogUtil.kr_i('🔹 渲染订阅卡片,margin: top=${12}, left=${12}, right=${12}', tag: 'HomeBottomPanel'); + + // 🔧 紧急诊断:异步写文件确认订阅卡片被渲染(不阻塞UI) + Future.microtask(() async { + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/SUBSCRIPTION_CARD_RENDER_DEBUG.txt'); + await debugFile.writeAsString( + '=' * 60 + '\n' + '🔹 订阅卡片正在渲染!\n' + '时间: ${DateTime.now()}\n' + '版本标识: Android15_Fix_v5\n' + '=' * 60 + '\n', + mode: FileMode.append, + ); + print('🔹 [BottomPanel] ✅ 订阅卡片渲染日志已写入文件: ${debugFile.path}'); + } catch (e) { + print('🔹 [BottomPanel] ❌ 写入订阅卡片渲染日志失败: $e'); + } + }); + return Container( margin: EdgeInsets.only(top: 12, left: 12, right: 12), child: const KRSubscriptionCard(), @@ -160,7 +181,7 @@ class KRHomeBottomPanel extends GetView { padding: EdgeInsets.all(16), decoration: BoxDecoration( color: Get.context!.theme.cardColor, - borderRadius: BorderRadius.circular(12.r), + borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), @@ -180,7 +201,7 @@ class KRHomeBottomPanel extends GetView { Text( '正在加载...', style: TextStyle( - fontSize: 14.sp, + fontSize: 14, color: Get.context!.theme.textTheme.bodyMedium?.color, ), ), @@ -233,7 +254,7 @@ class KRHomeBottomPanel extends GetView { foregroundColor: Theme.of(context).colorScheme.onPrimary, elevation: 0, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.r), + borderRadius: BorderRadius.circular(8), ), ), child: Text( diff --git a/lib/app/modules/kr_home/views/kr_home_connection_info_view.dart b/lib/app/modules/kr_home/views/kr_home_connection_info_view.dart index 6fc8bbb..b76324a 100755 --- a/lib/app/modules/kr_home/views/kr_home_connection_info_view.dart +++ b/lib/app/modules/kr_home/views/kr_home_connection_info_view.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../../widgets/kr_simple_loading.dart'; import 'package:kaer_with_panels/app/widgets/kr_country_flag.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; diff --git a/lib/app/modules/kr_home/views/kr_home_connection_options_view.dart b/lib/app/modules/kr_home/views/kr_home_connection_options_view.dart index 7093540..df0f6b2 100755 --- a/lib/app/modules/kr_home/views/kr_home_connection_options_view.dart +++ b/lib/app/modules/kr_home/views/kr_home_connection_options_view.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; diff --git a/lib/app/modules/kr_home/widgets/kr_subscription_card.dart b/lib/app/modules/kr_home/widgets/kr_subscription_card.dart index 83a1e4b..5fc0238 100755 --- a/lib/app/modules/kr_home/widgets/kr_subscription_card.dart +++ b/lib/app/modules/kr_home/widgets/kr_subscription_card.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; +import 'dart:io'; +import 'package:path_provider/path_provider.dart'; import 'package:kaer_with_panels/app/routes/app_pages.dart'; import 'package:kaer_with_panels/app/utils/kr_subscribe_navigation_util.dart'; @@ -29,7 +30,6 @@ class KRSubscriptionCard extends StatelessWidget { print('🎴 [SubscriptionCard] 卡片颜色: ${Theme.of(context).cardColor}'); print('🎴 [SubscriptionCard] 主题亮度: ${Theme.of(context).brightness}'); print('🎴 [SubscriptionCard] 文本颜色: ${Theme.of(context).textTheme.bodyMedium?.color}'); - print('🎴 [SubscriptionCard] ScreenUtil 测试 - 12.w=${12.w}, 16.h=${16.h}, 44.w=${44.w}'); // 🔧 关键修复:完全移除 ScreenUtil,使用固定像素值避免缩放问题 return Container( @@ -82,8 +82,36 @@ class KRSubscriptionCard extends StatelessWidget { height: 46, child: ElevatedButton( onPressed: () { - print('🎴 [SubscriptionCard] 订阅按钮被点击'); - KRSubscribeNavigationUtil.navigateToPurchase(tag: 'SubscriptionCard'); + print('🎴 [SubscriptionCard] ========== 订阅按钮被点击 =========='); + print('🎴 [SubscriptionCard] 当前时间: ${DateTime.now()}'); + print('🎴 [SubscriptionCard] 准备调用导航方法...'); + + // 🔧 关键修复:文件写入改为非阻塞,不影响主流程 + Future(() async { + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/SUBSCRIBE_BUTTON_DEBUG.txt'); + await debugFile.writeAsString( + '=' * 60 + '\n' + '🎴 订阅按钮被点击!\n' + '时间: ${DateTime.now()}\n' + '版本标识: Android15_Fix_v5\n' + '=' * 60 + '\n', + mode: FileMode.append, + ); + print('🎴 [SubscriptionCard] ✅ 按钮点击日志已写入文件: ${debugFile.path}'); + } catch (e) { + print('🎴 [SubscriptionCard] ❌ 写入按钮点击日志失败: $e'); + } + }); + + try { + KRSubscribeNavigationUtil.navigateToPurchase(tag: 'SubscriptionCard'); + print('🎴 [SubscriptionCard] 导航方法调用成功'); + } catch (e, stackTrace) { + print('🎴 [SubscriptionCard] ❌ 导航方法调用失败: $e'); + print('🎴 [SubscriptionCard] StackTrace: $stackTrace'); + } }, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, @@ -114,10 +142,10 @@ class KRSubscriptionCard extends StatelessWidget { bool addBottomPadding = true, }) { return Container( - margin: margin ?? EdgeInsets.symmetric(horizontal: 16.w), + margin: margin ?? EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Theme.of(context).cardColor, - borderRadius: BorderRadius.circular(12.w), + borderRadius: BorderRadius.circular(12), ), child: IntrinsicWidth( child: child, diff --git a/lib/app/modules/kr_purchase_membership/controllers/kr_purchase_membership_controller.dart b/lib/app/modules/kr_purchase_membership/controllers/kr_purchase_membership_controller.dart index 5275d4e..253f718 100755 --- a/lib/app/modules/kr_purchase_membership/controllers/kr_purchase_membership_controller.dart +++ b/lib/app/modules/kr_purchase_membership/controllers/kr_purchase_membership_controller.dart @@ -5,6 +5,8 @@ import 'package:kaer_with_panels/app/utils/kr_common_util.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/utils/kr_log_util.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'dart:io'; +import 'package:path_provider/path_provider.dart'; import '../../../common/app_run_data.dart'; import '../../../common/app_config.dart'; @@ -13,6 +15,7 @@ import '../../../model/response/kr_payment_methods.dart'; import '../../../routes/app_pages.dart'; import '../../../services/api_service/kr_api.user.dart'; import '../../../utils/kr_event_bus.dart'; +import '../../../network/http_util.dart'; import 'package:flutter/foundation.dart'; /// 会员购买控制器 @@ -47,8 +50,28 @@ class KRPurchaseMembershipController extends GetxController { RxInt _kr_balance = 0.obs; @override - void onInit() { + void onInit() async { super.onInit(); + print('💳 [PurchaseMembership] ========== Controller.onInit 被调用 =========='); + print('💳 [PurchaseMembership] 当前时间: ${DateTime.now()}'); + + // 🔧 紧急诊断:写文件确认购买页面Controller被初始化 + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/PURCHASE_CONTROLLER_DEBUG.txt'); + await debugFile.writeAsString( + '=' * 60 + '\n' + '💳 PurchaseMembershipController.onInit 被调用!\n' + '时间: ${DateTime.now()}\n' + '版本标识: Android15_Fix_v5\n' + '=' * 60 + '\n', + mode: FileMode.append, + ); + print('💳 [PurchaseMembership] ✅ 调试日志已写入文件: ${debugFile.path}'); + } catch (e) { + print('💳 [PurchaseMembership] ❌ 写入调试日志失败: $e'); + } + kr_initializeData(); } @@ -60,14 +83,24 @@ class KRPurchaseMembershipController extends GetxController { /// 初始化数据 Future kr_initializeData() async { + print('💳 [PurchaseMembership] initializeData 开始'); kr_userEmail.value = KRAppRunData.getInstance().kr_account.toString(); - await kr_getPackageList(); + print('💳 [PurchaseMembership] 用户邮箱: ${kr_userEmail.value}'); + + // 🔧 关键修复:不要在 onInit 中 await,让页面先显示,数据异步加载 + // 这样可以避免 API 请求卡住导致页面无法显示 + print('💳 [PurchaseMembership] 开始异步加载套餐数据...'); + kr_getPackageList().catchError((e) { + print('💳 [PurchaseMembership] ❌ 加载套餐数据异常: $e'); + KRLogUtil.kr_e('加载套餐数据失败: $e', tag: 'PurchaseMembership'); + }); // 监听所有支付相关消息 _kr_eventWorker = KREventBus().kr_listenMessages( [KRMessageType.kr_payment, KRMessageType.kr_subscribe_update], _kr_handleMessage, ); + print('💳 [PurchaseMembership] initializeData 完成'); } /// 处理消息 @@ -94,23 +127,102 @@ class KRPurchaseMembershipController extends GetxController { /// 获取套餐列表和支付方式 Future kr_getPackageList() async { + print('💳 [PurchaseMembership] ========== 开始获取套餐列表 =========='); + print('💳 [PurchaseMembership] 当前时间: ${DateTime.now()}'); + kr_isLoading.value = true; kr_selectedPlanIndex.value = 0; // 重置套餐选择 kr_selectedDiscountIndex.value = -1; // 重置折扣选择 kr_selectedPaymentMethodIndex.value = -1; // 重置支付方式选择 - await _iniUserInfo(); - await kr_getAlreadySubscribe(); - await kr_fetchPackages(); - // await kr_fetchPaymentMethods(); // ⚠️ 后端暂未实现 /v1/app/payment/methods 接口 + try { + // 🔧 添加超时保护,避免 API 请求卡死 + print('💳 [PurchaseMembership] 步骤1: 开始初始化用户信息...'); + await _iniUserInfo().timeout( + const Duration(seconds: 5), + onTimeout: () { + print('💳 [PurchaseMembership] ⚠️ 初始化用户信息超时'); + KRLogUtil.kr_w('初始化用户信息超时', tag: 'PurchaseMembership'); + }, + ); + print('💳 [PurchaseMembership] ✓ 步骤1完成'); - // 获取公开的支付方式 - await _kr_fetchPublicPaymentMethods(); + print('💳 [PurchaseMembership] 步骤2: 开始获取已订阅套餐...'); + await kr_getAlreadySubscribe().timeout( + const Duration(seconds: 5), + onTimeout: () { + print('💳 [PurchaseMembership] ⚠️ 获取已订阅套餐超时'); + KRLogUtil.kr_w('获取已订阅套餐超时', tag: 'PurchaseMembership'); + }, + ); + print('💳 [PurchaseMembership] ✓ 步骤2完成'); - // 根据套餐数量决定是否显示套餐选择器 - kr_showPlanSelector.value = kr_plans.length > 1; + print('💳 [PurchaseMembership] 步骤3: 开始获取套餐列表...'); + await kr_fetchPackages().timeout( + const Duration(seconds: 8), + onTimeout: () { + print('💳 [PurchaseMembership] ❌ 获取套餐列表超时'); + KRLogUtil.kr_e('获取套餐列表超时', tag: 'PurchaseMembership'); + KRCommonUtil.kr_showToast('获取套餐列表超时,请检查网络'); + }, + ); + print('💳 [PurchaseMembership] ✓ 步骤3完成,套餐数量: ${kr_plans.length}'); - kr_isLoading.value = false; + // 获取公开的支付方式 + print('💳 [PurchaseMembership] 步骤4: 开始获取支付方式...'); + await _kr_fetchPublicPaymentMethods().timeout( + const Duration(seconds: 5), + onTimeout: () { + print('💳 [PurchaseMembership] ⚠️ 获取支付方式超时'); + KRLogUtil.kr_w('获取支付方式超时', tag: 'PurchaseMembership'); + }, + ); + print('💳 [PurchaseMembership] ✓ 步骤4完成,支付方式数量: ${kr_paymentMethods.length}'); + + // 根据套餐数量决定是否显示套餐选择器 + kr_showPlanSelector.value = kr_plans.length > 1; + print('💳 [PurchaseMembership] ========== 所有步骤完成 =========='); + } catch (e, stackTrace) { + print('💳 [PurchaseMembership] ❌❌❌ 获取套餐数据失败: $e'); + print('💳 [PurchaseMembership] StackTrace: $stackTrace'); + KRLogUtil.kr_e('获取套餐数据失败: $e', tag: 'PurchaseMembership'); + + // 🔧 关键修复:API失败时,尝试切换域名并重试 + print('💳 [PurchaseMembership] 🔄 尝试切换域名并重试...'); + bool domainSwitched = await KRDomain.kr_switchToNextDomain(); + + if (domainSwitched) { + print('💳 [PurchaseMembership] ✓ 域名切换成功,当前域名: ${KRDomain.kr_currentDomain}'); + print('💳 [PurchaseMembership] 🔄 使用新域名重试...'); + + // 更新 HttpUtil 的 baseUrl + HttpUtil.getInstance().updateBaseUrl(); + + // 等待500ms让域名生效 + await Future.delayed(const Duration(milliseconds: 500)); + + // 重试一次 + try { + await kr_fetchPackages().timeout( + const Duration(seconds: 8), + onTimeout: () { + print('💳 [PurchaseMembership] ❌ 使用新域名后仍然超时'); + KRLogUtil.kr_e('使用新域名后仍然超时', tag: 'PurchaseMembership'); + }, + ); + print('💳 [PurchaseMembership] ✓ 使用新域名重试成功,套餐数量: ${kr_plans.length}'); + } catch (retryError) { + print('💳 [PurchaseMembership] ❌ 使用新域名重试仍然失败: $retryError'); + kr_errorMessage.value = '网络连接失败,请检查网络设置'; + } + } else { + print('💳 [PurchaseMembership] ❌ 域名切换失败,所有域名都不可用'); + kr_errorMessage.value = '无法连接服务器,请稍后重试'; + } + } finally { + kr_isLoading.value = false; + print('💳 [PurchaseMembership] 加载状态设置为: false'); + } } /// 初始化用户信息 diff --git a/lib/app/modules/kr_purchase_membership/views/kr_purchase_membership_view.dart b/lib/app/modules/kr_purchase_membership/views/kr_purchase_membership_view.dart index dcc950c..5afebee 100755 --- a/lib/app/modules/kr_purchase_membership/views/kr_purchase_membership_view.dart +++ b/lib/app/modules/kr_purchase_membership/views/kr_purchase_membership_view.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; diff --git a/lib/app/modules/kr_splash/controllers/kr_splash_controller.dart b/lib/app/modules/kr_splash/controllers/kr_splash_controller.dart index c1cfaf6..6835ed5 100755 --- a/lib/app/modules/kr_splash/controllers/kr_splash_controller.dart +++ b/lib/app/modules/kr_splash/controllers/kr_splash_controller.dart @@ -28,7 +28,7 @@ import 'package:kaer_with_panels/app/modules/kr_home/controllers/kr_home_control import 'package:kaer_with_panels/app/modules/kr_home/models/kr_home_views_status.dart'; import 'dart:async'; 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'; class KRSplashController extends GetxController { // 🔧 新增:初始化日志收集器 @@ -311,6 +311,115 @@ class KRSplashController extends GetxController { } } + /// 🔧 Android 15 新增:最小化初始化(降级策略) + /// 确保即使网络失败,应用也能启动到可用状态 + Future _executeMinimalInitialization() async { + try { + _initLog.logPhaseStart('降级初始化(Minimal Initialization)'); + _initLog.logWarning('网络初始化失败,执行降级策略', tag: 'Splash'); + KRLogUtil.kr_i('🛡️ 执行最小化初始化(降级模式)', tag: 'SplashController'); + if (kDebugMode) { + print('🛡️ 执行最小化初始化(降级模式)'); + } + + // 1. 设置默认域名(确保应用有可用域名) + try { + _initLog.log('步骤1: 设置默认域名', tag: 'Minimal'); + 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'); + if (kDebugMode) { + print('✅ 设置默认域名: ${KRDomain.kr_currentDomain}'); + } + } else { + _initLog.log('当前域名: ${KRDomain.kr_currentDomain}', tag: 'Minimal'); + } + } catch (e) { + _initLog.logError('设置默认域名失败', tag: 'Minimal', error: e); + KRLogUtil.kr_w('⚠️ 设置默认域名失败: $e', tag: 'SplashController'); + } + + // 2. 初始化 SingBox(核心功能,不依赖网络) + try { + _initLog.log('步骤2: 初始化 SingBox', tag: 'Minimal'); + await KRSingBoxImp.instance.init().timeout( + const Duration(seconds: 3), + onTimeout: () { + _initLog.logWarning('SingBox 初始化超时(3秒)', tag: 'Minimal'); + KRLogUtil.kr_w('SingBox 初始化超时', tag: 'SplashController'); + if (kDebugMode) { + print('⏱️ SingBox 初始化超时'); + } + }, + ); + _initLog.logSuccess('SingBox 初始化完成', tag: 'Minimal'); + KRLogUtil.kr_i('✅ SingBox 初始化完成', tag: 'SplashController'); + if (kDebugMode) { + print('✅ SingBox 初始化完成'); + } + } catch (e) { + _initLog.logError('SingBox 初始化失败', tag: 'Minimal', error: e); + KRLogUtil.kr_w('⚠️ SingBox 初始化失败: $e', tag: 'SplashController'); + if (kDebugMode) { + print('⚠️ SingBox 初始化失败: $e'); + } + } + + // 3. 尝试加载本地用户信息(不依赖网络) + try { + _initLog.log('步骤3: 加载本地用户信息', tag: 'Minimal'); + await KRAppRunData.getInstance().kr_initializeUserInfo().timeout( + const Duration(seconds: 2), + onTimeout: () { + _initLog.logWarning('用户信息加载超时(2秒)', tag: 'Minimal'); + KRLogUtil.kr_w('用户信息加载超时', tag: 'SplashController'); + if (kDebugMode) { + print('⏱️ 用户信息加载超时'); + } + }, + ); + _initLog.logSuccess('本地用户信息加载完成', tag: 'Minimal'); + KRLogUtil.kr_i('✅ 本地用户信息加载完成', tag: 'SplashController'); + if (kDebugMode) { + print('✅ 本地用户信息加载完成'); + } + } catch (e) { + _initLog.logError('用户信息加载失败', tag: 'Minimal', error: e); + KRLogUtil.kr_w('⚠️ 用户信息加载失败: $e', tag: 'SplashController'); + if (kDebugMode) { + print('⚠️ 用户信息加载失败: $e'); + } + } + + _initLog.logPhaseEnd('降级初始化(Minimal Initialization)', success: true); + _initLog.log('应用将以降级模式启动,用户将看到基本UI', tag: 'Minimal'); + _initLog.log('预期显示:订阅卡片 + 连接选项', tag: 'Minimal'); + + KRLogUtil.kr_i('✅ 最小化初始化完成,应用将以降级模式启动', tag: 'SplashController'); + if (kDebugMode) { + print('✅ 最小化初始化完成,应用将以降级模式启动'); + } + if (kDebugMode) { + print('📱 用户将看到基本UI(订阅卡片 + 连接选项)'); + } + + // 🔧 最小化初始化也不关闭日志 + // await _initLog.finalize(); // ❌ 注释掉 + if (kDebugMode && _initLog.getLogFilePath() != null) { + print('📁 初始化日志文件(保持打开): ${_initLog.getLogFilePath()}'); + } + } catch (e) { + _initLog.logError('最小化初始化也失败', tag: 'Minimal', error: e); + KRLogUtil.kr_e('❌ 最小化初始化也失败: $e', tag: 'SplashController'); + if (kDebugMode) { + print('❌ 最小化初始化也失败: $e'); + } + // 即使降级初始化失败也不关闭日志 + // await _initLog.finalize(); // ❌ 注释掉 + } + } + /// 处理错误并显示 void _handleError(String title, String message) { kr_hasError.value = true; diff --git a/lib/app/utils/kr_log_util.dart b/lib/app/utils/kr_log_util.dart index ccfc476..fb629a0 100755 --- a/lib/app/utils/kr_log_util.dart +++ b/lib/app/utils/kr_log_util.dart @@ -2,16 +2,20 @@ import 'package:flutter/foundation.dart'; import 'package:loggy/loggy.dart'; /// 日志工具类 -/// 🔒 Release模式下所有日志都不会输出,确保生产环境的性能和安全 +/// 🔧 Android 15 诊断模式:临时允许 Release 模式下输出关键日志用于问题诊断 class KRLogUtil { static final KRLogUtil _instance = KRLogUtil._internal(); factory KRLogUtil() => _instance; KRLogUtil._internal(); + /// 🔧 临时启用 Release 日志用于 Android 15 问题诊断 + /// ⚠️ 生产环境修复后应该改回 false + static const bool _forceEnableReleaseLogging = true; + /// 初始化日志 static void kr_init() { - // 只在 Debug 模式下初始化日志 - if (kDebugMode) { + // Debug 模式或强制启用时初始化日志 + if (kDebugMode || _forceEnableReleaseLogging) { Loggy.initLoggy( logPrinter: PrettyPrinter(), ); @@ -19,49 +23,49 @@ class KRLogUtil { } /// 调试日志 - /// 🔒 只在 Debug 模式下输出 + /// 🔧 Debug 模式或强制启用时输出 static void kr_d(String message, {String? tag}) { - if (kDebugMode) { + if (kDebugMode || _forceEnableReleaseLogging) { Loggy('${tag ?? 'KRLogUtil'}').debug(message); } } /// 信息日志 - /// 🔒 只在 Debug 模式下输出 + /// 🔧 Debug 模式或强制启用时输出 static void kr_i(String message, {String? tag}) { - if (kDebugMode) { + if (kDebugMode || _forceEnableReleaseLogging) { Loggy('${tag ?? 'KRLogUtil'}').info(message); } } /// 警告日志 - /// 🔒 只在 Debug 模式下输出 + /// 🔧 Debug 模式或强制启用时输出 static void kr_w(String message, {String? tag}) { - if (kDebugMode) { + if (kDebugMode || _forceEnableReleaseLogging) { Loggy('${tag ?? 'KRLogUtil'}').warning(message); } } /// 错误日志 - /// 🔒 只在 Debug 模式下输出 + /// 🔧 Debug 模式或强制启用时输出 static void kr_e(String message, {String? tag, Object? error, StackTrace? stackTrace}) { - if (kDebugMode) { + if (kDebugMode || _forceEnableReleaseLogging) { Loggy('${tag ?? 'KRLogUtil'}').error(message, error, stackTrace); } } /// 网络日志 - /// 🔒 只在 Debug 模式下输出 + /// 🔧 Debug 模式或强制启用时输出 static void kr_network(String message, {String? tag}) { - if (kDebugMode) { + if (kDebugMode || _forceEnableReleaseLogging) { Loggy('${tag ?? 'Network'}').info(message); } } /// 性能日志 - /// 🔒 只在 Debug 模式下输出 + /// 🔧 Debug 模式或强制启用时输出 static void kr_performance(String message, {String? tag}) { - if (kDebugMode) { + if (kDebugMode || _forceEnableReleaseLogging) { Loggy('${tag ?? 'Performance'}').info(message); } } diff --git a/lib/app/utils/kr_subscribe_navigation_util.dart b/lib/app/utils/kr_subscribe_navigation_util.dart index cc1ed18..fbb7740 100644 --- a/lib/app/utils/kr_subscribe_navigation_util.dart +++ b/lib/app/utils/kr_subscribe_navigation_util.dart @@ -4,6 +4,8 @@ import 'package:kaer_with_panels/app/widgets/dialogs/kr_dialog.dart'; import 'package:kaer_with_panels/app/routes/app_pages.dart'; import 'package:kaer_with_panels/app/utils/kr_log_util.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; +import 'dart:io'; +import 'package:path_provider/path_provider.dart'; /// 订阅导航工具类 /// 用于统一处理订阅相关的导航逻辑 @@ -14,17 +16,62 @@ class KRSubscribeNavigationUtil { /// /// [tag] 调用来源标签,用于日志记录 static void navigateToPurchase({String tag = 'Subscribe'}) { + print('🔔 [NavigationUtil] ========== navigateToPurchase 被调用 =========='); + print('🔔 [NavigationUtil] Tag: $tag'); + print('🔔 [NavigationUtil] 当前时间: ${DateTime.now()}'); + + // 🔧 先获取关键信息并打印 final appRunData = KRAppRunData.getInstance(); final isDeviceLogin = appRunData.isDeviceLogin(); final account = appRunData.kr_account.value; + print('🔔 [NavigationUtil] 账号: $account'); + print('🔔 [NavigationUtil] 是否设备登录: $isDeviceLogin'); + KRLogUtil.kr_i('=== 订阅按钮点击 ===', tag: tag); KRLogUtil.kr_i('账号: $account', tag: tag); KRLogUtil.kr_i('是否设备登录: $isDeviceLogin', tag: tag); + // 🔧 文件写入改为非阻塞,放在后面 + Future(() async { + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/NAVIGATION_DEBUG.txt'); + await debugFile.writeAsString( + '=' * 60 + '\n' + '🔔 navigateToPurchase 被调用!\n' + '时间: ${DateTime.now()}\n' + '来源: $tag\n' + '账号: $account\n' + '是否设备登录: $isDeviceLogin\n' + '版本标识: Android15_Fix_v5\n' + '=' * 60 + '\n', + mode: FileMode.append, + ); + } catch (e) { + print('🔔 [NavigationUtil] ❌ 写入导航日志失败: $e'); + } + }); + if (isDeviceLogin) { // 设备登录用户需要绑定账号 + print('🔔 [NavigationUtil] ⚠️ 检测到设备登录,将显示绑定提示对话框'); KRLogUtil.kr_i('检测到设备登录,显示绑定提示', tag: tag); + + // 🔧 记录显示对话框 + Future(() async { + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/NAVIGATION_DEBUG.txt'); + await debugFile.writeAsString( + '⚠️ 用户是设备登录,显示绑定提示对话框\n' + '时间: ${DateTime.now()}\n' + '-' * 60 + '\n', + mode: FileMode.append, + ); + } catch (e) { /* 忽略 */ } + }); + KRDialog.show( title: AppTranslations.kr_dialog.deviceLoginBindingTitle, message: AppTranslations.kr_dialog.deviceLoginBindingMessage, @@ -41,13 +88,68 @@ class KRSubscribeNavigationUtil { ); } else { // 正常流程 - 跳转到购买页面 + print('🔔 [NavigationUtil] ✅ 普通用户,准备跳转到购买页面'); KRLogUtil.kr_i('普通用户,跳转到购买页面', tag: tag); + // 🔧 立即记录准备跳转 + Future(() async { + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/NAVIGATION_DEBUG.txt'); + await debugFile.writeAsString( + '✅ 普通用户,准备调用 Get.toNamed\n' + '路由: ${Routes.KR_PURCHASE_MEMBERSHIP}\n' + '时间: ${DateTime.now()}\n' + '-' * 60 + '\n', + mode: FileMode.append, + ); + } catch (e) { /* 忽略 */ } + }); + try { // 🔧 添加加载保护,避免页面跳转时卡死 - Get.toNamed(Routes.KR_PURCHASE_MEMBERSHIP); + print('🔔 [NavigationUtil] 📍 步骤1: 正在调用 Get.toNamed(${Routes.KR_PURCHASE_MEMBERSHIP})...'); + final result = Get.toNamed(Routes.KR_PURCHASE_MEMBERSHIP); + print('🔔 [NavigationUtil] 📍 步骤2: Get.toNamed 调用完成,返回值: $result'); + + // 🔧 文件写入改为非阻塞 + Future(() async { + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/NAVIGATION_DEBUG.txt'); + await debugFile.writeAsString( + '✅ Get.toNamed 执行完成\n' + '路由: ${Routes.KR_PURCHASE_MEMBERSHIP}\n' + '返回值: $result\n' + '时间: ${DateTime.now()}\n' + '-' * 60 + '\n', + mode: FileMode.append, + ); + } catch (e) { + print('🔔 [NavigationUtil] ❌ 写入跳转完成日志失败: $e'); + } + }); } catch (e) { KRLogUtil.kr_e('跳转购买页面失败: $e', tag: tag); + print('🔔 [NavigationUtil] ❌❌❌ 跳转异常: $e'); + + // 🔧 文件写入改为非阻塞 + Future(() async { + try { + final dir = await getApplicationDocumentsDirectory(); + final debugFile = File('${dir.path}/NAVIGATION_DEBUG.txt'); + await debugFile.writeAsString( + '❌ Get.toNamed 执行失败\n' + '异常: $e\n' + '时间: ${DateTime.now()}\n' + '-' * 60 + '\n', + mode: FileMode.append, + ); + } catch (e) { + print('🔔 [NavigationUtil] ❌ 写入跳转失败日志失败: $e'); + } + }); + // 如果跳转失败,显示错误提示 KRDialog.show( title: AppTranslations.kr_dialog.error,