优化部分安卓机型可能存在连接超时等问题新增日志排查
(cherry picked from commit e0fcc27f28f27321a49115df86507e3ac55e8ef8)
This commit is contained in:
parent
b8d0417d0f
commit
dee7f0a591
@ -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
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
"codeSentCountdown": "验证码已发送 {seconds}s",
|
||||
"and": "和",
|
||||
"enterInviteCode": "请输入邀请码",
|
||||
"registerSuccess": "注册成功"
|
||||
"registerSuccess": "注册成功",
|
||||
"search": "搜索",
|
||||
"selectOtherRegion": "选择其他地区"
|
||||
},
|
||||
|
||||
@ -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<KRHomeController> {
|
||||
const KRHomeBottomPanel({super.key});
|
||||
@ -107,6 +108,26 @@ class KRHomeBottomPanel extends GetView<KRHomeController> {
|
||||
// 未订阅(包括未登录):始终显示订阅卡片
|
||||
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<KRHomeController> {
|
||||
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<KRHomeController> {
|
||||
Text(
|
||||
'正在加载...',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
fontSize: 14,
|
||||
color: Get.context!.theme.textTheme.bodyMedium?.color,
|
||||
),
|
||||
),
|
||||
@ -233,7 +254,7 @@ class KRHomeBottomPanel extends GetView<KRHomeController> {
|
||||
foregroundColor: Theme.of(context).colorScheme.onPrimary,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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] 订阅按钮被点击');
|
||||
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,
|
||||
|
||||
@ -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<void> 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<void> 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完成');
|
||||
|
||||
print('💳 [PurchaseMembership] 步骤2: 开始获取已订阅套餐...');
|
||||
await kr_getAlreadySubscribe().timeout(
|
||||
const Duration(seconds: 5),
|
||||
onTimeout: () {
|
||||
print('💳 [PurchaseMembership] ⚠️ 获取已订阅套餐超时');
|
||||
KRLogUtil.kr_w('获取已订阅套餐超时', tag: 'PurchaseMembership');
|
||||
},
|
||||
);
|
||||
print('💳 [PurchaseMembership] ✓ 步骤2完成');
|
||||
|
||||
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}');
|
||||
|
||||
// 获取公开的支付方式
|
||||
await _kr_fetchPublicPaymentMethods();
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化用户信息
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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<void> _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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user