diff --git a/lib/app/modules/kr_home/views/kr_home_view.dart b/lib/app/modules/kr_home/views/kr_home_view.dart index a621679..6c1280b 100755 --- a/lib/app/modules/kr_home/views/kr_home_view.dart +++ b/lib/app/modules/kr_home/views/kr_home_view.dart @@ -157,8 +157,8 @@ class _KRHomeViewState extends State { children: [ // 1. 自定义 Checkbox 的方框外观 Container( - width: 20.w, - height: 20.w, + width: 20, + height: 20, decoration: BoxDecoration( color: controller .isQuickConnectEnabled.value @@ -176,18 +176,18 @@ class _KRHomeViewState extends State { .isQuickConnectEnabled.value ? Icon( Icons.check, - size: 14.w, + size: 14, color: Colors.black, ) : null, ), - SizedBox(width: 8.w), + SizedBox(width: 8), // 2. “闪连”标签 Text( '闪连', style: TextStyle( color: Colors.white, - fontSize: 20.sp, + fontSize: 20, fontWeight: FontWeight.w600, ), ), @@ -196,7 +196,7 @@ class _KRHomeViewState extends State { ), ), // --- 问号图标和点击弹窗区域 --- - SizedBox(width: 6.w), // 文字和问号图标之间的间距 + SizedBox(width: 6), // 文字和问号图标之间的间距 GestureDetector( onTap: () { HIDialog.show( @@ -208,8 +208,8 @@ class _KRHomeViewState extends State { child: KrLocalImage( imageName: 'question-icon', // 图片名称 imageType: ImageType.svg, // 图片类型 - width: 24.w, - height: 24.w, + width: 24, + height: 24, color: Colors.white, // 让图标颜色与边框协调 ), ), diff --git a/lib/app/modules/kr_invite/views/kr_invite_view.dart b/lib/app/modules/kr_invite/views/kr_invite_view.dart index 0e26002..d9774e1 100755 --- a/lib/app/modules/kr_invite/views/kr_invite_view.dart +++ b/lib/app/modules/kr_invite/views/kr_invite_view.dart @@ -34,6 +34,7 @@ class KRInviteView extends GetView { children: [ // 🟢 第一行:奖励说明 Container( + width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.w), decoration: BoxDecoration( color: Theme.of(context).primaryColor, @@ -41,7 +42,7 @@ class KRInviteView extends GetView { ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, // 由内容撑开 + mainAxisSize: MainAxisSize.max, children: [ KrLocalImage( imageName: 'hi-home-logo', @@ -204,4 +205,4 @@ class KRInviteView extends GetView { ), ); } -} \ No newline at end of file +} 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 1f718f5..4557d16 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 @@ -15,9 +15,6 @@ import 'package:kaer_with_panels/app/widgets/dialogs/kr_dialog.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; import 'package:kaer_with_panels/app/utils/kr_log_util.dart'; import 'dart:convert'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; - - /// 购买会员页面视图 class KRPurchaseMembershipView extends GetView { @@ -34,7 +31,7 @@ class KRPurchaseMembershipView extends GetView { return Stack( children: [ Padding( - padding: EdgeInsets.only(bottom: 80.w), + padding: EdgeInsets.only(bottom: 80.0), child: SingleChildScrollView( child: Column( children: [ @@ -67,52 +64,15 @@ class KRPurchaseMembershipView extends GetView { ) else Container( - margin: EdgeInsets.symmetric(horizontal: 40.r), + margin: EdgeInsets.symmetric(horizontal: 40.0), child: Column( children: [ // 套餐选择部分 Container( - padding: EdgeInsets.all(0.r), + padding: EdgeInsets.all(0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // if (controller.kr_plans.length > 1) - // Container( - // height: 32.h, - // child: ListView.builder( - // scrollDirection: Axis.horizontal, - // padding: EdgeInsets.zero, - // itemCount: controller.kr_plans.length, - // itemBuilder: (context, index) { - // final plan = controller.kr_plans[index]; - // final isSelected = index == controller.kr_selectedPlanIndex.value; - // return GestureDetector( - // onTap: () => controller.kr_selectPlan(index), - // child: Container( - // margin: EdgeInsets.only(right: 8.w), - // padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 4.h), - // decoration: BoxDecoration( - // color: isSelected ? Colors.white : Theme.of(context).cardColor, - // borderRadius: BorderRadius.circular(16.r), - // border: Border.all( - // color: isSelected ? Colors.white : Colors.grey.withOpacity(0.3), - // width: 1, - // ), - // ), - // child: Center( - // child: Text( - // plan.kr_name, - // style: KrAppTextStyle( - // fontSize: 13, - // color: isSelected ? Colors.white : Theme.of(context).textTheme.bodyMedium?.color, - // ), - // ), - // ), - // ), - // ); - // }, - // ), - // ), Column( // 使用 List.generate 动态创建卡片列表 children: List.generate( @@ -130,12 +90,9 @@ class KRPurchaseMembershipView extends GetView { // 使用 Padding 来为每个卡片添加底部的间距,模拟 mainAxisSpacing return Padding( padding: - EdgeInsets.only(bottom: 8.h), - // 👇 核心改动:父节点 SizedBox 决定了卡片的高度 - child: ConstrainedBox( - constraints: BoxConstraints( - minHeight: 100.h, // 设置最小高度为 100.h - ), + EdgeInsets.only(bottom: 8.0), + child: SizedBox( + height: 140.0, child: _kr_buildPlanOptionCard( plan, controller @@ -152,394 +109,15 @@ class KRPurchaseMembershipView extends GetView { ], ), ), - /* SizedBox(height: 16.h), - // 套餐描述部分 - Container( - padding: EdgeInsets.all(16.r), - decoration: BoxDecoration( - color: Theme.of(context).cardColor, - borderRadius: BorderRadius.circular(16.r), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 10, - offset: Offset(0, 4), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppTranslations.kr_purchaseMembership.packageDescription, - style: KrAppTextStyle( - fontSize: 15, - fontWeight: FontWeight.w500, - color: Theme.of(context).textTheme.bodyMedium?.color, - ), - ), - SizedBox(height: 16.h), - Obx(() { - final featureLabels = controller.kr_getSelectedPlanFeatureLabels(); - final features = controller.kr_getSelectedPlanFeatures(); - final isExpanded = controller.kr_isDescriptionExpanded.value; - final selectedPlan = controller.kr_plans[controller.kr_selectedPlanIndex.value]; - - // 添加流量和设备限制信息 - final trafficAndDeviceInfo = Padding( - padding: EdgeInsets.only(bottom: 8.h), - child: Container( - width: double.infinity, - padding: EdgeInsets.symmetric( - horizontal: 12.w, - vertical: 8.h, - ), - decoration: BoxDecoration( - color: Theme.of(context).cardColor, - borderRadius: BorderRadius.circular(12.r), - border: Border.all( - color: Colors.grey.withOpacity(0.2), - ), - ), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '${AppTranslations.kr_purchaseMembership.trafficLimit}:${controller.kr_getTrafficLimitText(selectedPlan)}', - style: KrAppTextStyle( - fontSize: 13, - color: Theme.of(context).textTheme.bodyMedium?.color, - ), - ), - SizedBox(height: 4.h), - Text( - '${AppTranslations.kr_purchaseMembership.deviceLimit}:${controller.kr_getDeviceLimitText(selectedPlan)}', - style: KrAppTextStyle( - fontSize: 13, - color: Theme.of(context).textTheme.bodyMedium?.color, - ), - ), - ], - ), - ), - ], - ), - ), - ); - - // if (featureLabels.isEmpty) { - // return Column( - // children: [ - // trafficAndDeviceInfo, - // Center( - // child: Padding( - // padding: EdgeInsets.symmetric(vertical: 16.h), - // child: Text( - // AppTranslations.kr_purchaseMembership.noData, - // style: KrAppTextStyle( - // fontSize: 14, - // color: Theme.of(context).textTheme.bodySmall?.color, - // ), - // ), - // ), - // ), - // ], - // ); - // } - - final displayCount = isExpanded ? featureLabels.length : (featureLabels.length > 3 ? 3 : featureLabels.length); - - return Column( - children: [ - trafficAndDeviceInfo, - ...List.generate(displayCount, (index) { - final feature = features[index]; - return Padding( - padding: EdgeInsets.only(bottom: 8.h), - child: GestureDetector( - onTap: () { - Get.dialog( - Dialog( - backgroundColor: Theme.of(Get.context!).cardColor, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16.r), - ), - child: Padding( - padding: EdgeInsets.all(16.r), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - feature.kr_label, - style: KrAppTextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(Get.context!).textTheme.bodyMedium?.color, - ), - ), - SizedBox(height: 8.h), - if (feature.kr_details.isNotEmpty) - ...feature.kr_details.map((detail) => Padding( - padding: EdgeInsets.only(bottom: 8.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (detail.kr_label.isNotEmpty) ...[ - Text( - detail.kr_label, - style: KrAppTextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Theme.of(Get.context!).textTheme.bodyMedium?.color, - ), - ), - SizedBox(height: 4.h), - ], - Text( - detail.kr_description, - style: KrAppTextStyle( - fontSize: 14, - color: Theme.of(Get.context!).textTheme.bodySmall?.color, - ), - ), - ], - ), - )).toList(), - SizedBox(height: 16.h), - Align( - alignment: Alignment.centerRight, - child: TextButton( - onPressed: () => Get.back(), - child: Text( - AppTranslations.kr_dialog.kr_ok, - style: KrAppTextStyle( - fontSize: 14, - color: Colors.white, - ), - ), - ), - ), - ], - ), - ), - ), - ); - }, - child: Container( - width: double.infinity, - padding: EdgeInsets.symmetric( - horizontal: 12.w, - vertical: 8.h, - ), - decoration: BoxDecoration( - color: Theme.of(Get.context!).cardColor, - borderRadius: BorderRadius.circular(12.r), - border: Border.all( - color: Colors.grey.withOpacity(0.2), - ), - ), - child: Row( - children: [ - Expanded( - child: Text( - featureLabels[index], - style: KrAppTextStyle( - fontSize: 13, - color: Theme.of(Get.context!).textTheme.bodyMedium?.color, - ), - ), - ), - Container( - padding: EdgeInsets.all(4.r), - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.1), - shape: BoxShape.circle, - ), - child: Icon( - Icons.info_outline, - size: 16.r, - color: Colors.white, - ), - ), - ], - ), - ), - ), - ); - }), - if (featureLabels.length > 3) - GestureDetector( - onTap: () => controller.kr_toggleDescriptionExpanded(), - child: Padding( - padding: EdgeInsets.symmetric(vertical: 4.h), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - isExpanded - ? AppTranslations.kr_purchaseMembership.collapse - : AppTranslations.kr_purchaseMembership.expand, - style: KrAppTextStyle( - fontSize: 13, - color: Colors.white, - ), - ), - SizedBox(width: 4.w), - Icon( - isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, - size: 16.r, - color: Colors.white, - ), - ], - ), - ), - ), - ], - ); - }), - ], - ), - ), - SizedBox(height: 16.h), - // 支付方式选择部分 - Container( - padding: EdgeInsets.all(16.r), - decoration: BoxDecoration( - color: Theme.of(context).cardColor, - borderRadius: BorderRadius.circular(16.r), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 10, - offset: Offset(0, 4), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppTranslations.kr_purchaseMembership.paymentMethod, - style: KrAppTextStyle( - fontSize: 15, - fontWeight: FontWeight.w500, - color: Theme.of(context).textTheme.bodyMedium?.color, - ), - ), - SizedBox(height: 16.h), - Obx(() => ListView.separated( - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: controller.kr_paymentMethods.length, - separatorBuilder: (context, index) => Divider( - height: 1.w, - indent: 44.w, - color: Theme.of(context).dividerColor.withOpacity(0.1), - ), - itemBuilder: (context, index) { - final paymentMethod = controller.kr_paymentMethods[index]; - return InkWell( - onTap: () => controller.kr_selectPaymentMethod(index), - child: Container( - padding: EdgeInsets.symmetric(vertical: 12.r, horizontal: 16.r), - child: Row( - children: [ - Container( - width: 32.w, - height: 32.w, - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.1), - shape: BoxShape.circle, - ), - child: Center( - child: paymentMethod.icon.isNotEmpty - ? KRNetworkImage( - kr_imageUrl: paymentMethod.icon, - kr_width: 20.w, - kr_height: 20.w, - kr_placeholder: SizedBox( - width: 20.w, - height: 20.w, - child: CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - ), - kr_errorWidget: Icon( - Icons.payment_rounded, - size: 20.w, - color: Colors.white, - ), - ) - : Icon( - Icons.payment_rounded, - size: 20.w, - color: Colors.white, - ), - ), - ), - SizedBox(width: 12.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - controller.kr_getPaymentMethodTitle(paymentMethod), - style: KrAppTextStyle( - fontSize: 14, - color: Theme.of(context).textTheme.bodyMedium?.color, - ), - ), - ], - ), - ), - Obx(() { - final isSelected = index == controller.kr_selectedPaymentMethodIndex.value; - return Container( - width: 24.w, - height: 24.w, - decoration: BoxDecoration( - color: isSelected ? Colors.white : Colors.transparent, - shape: BoxShape.circle, - border: Border.all( - color: isSelected ? Colors.white : Colors.grey.withOpacity(0.3), - width: 1.5, - ), - ), - child: isSelected - ? Icon( - Icons.check, - color: Colors.white, - size: 16.r, - ) - : null, - ); - }), - ], - ), - ), - ); - }, - )), - ], - ), - ),*/ ], ), ), ], ), )), - - Positioned( - top: 160.w, // 距离顶部的距离 - right: 10.w, // 固定在右侧 20.w 的位置 + top: 160.0, // 距离顶部的距离 + right: 10.0, // 固定在右侧 20.w 的位置 child: KrLocalImage( imageName: 'purchase_slogan', imageType: ImageType.svg, @@ -572,12 +150,12 @@ class KRPurchaseMembershipView extends GetView { ), const Spacer(), Obx(() => Text( - controller.kr_userEmail.value, - style: KrAppTextStyle( - fontSize: 14, - color: Theme.of(context).textTheme.bodySmall?.color, - ), - )), + controller.kr_userEmail.value, + style: KrAppTextStyle( + fontSize: 14, + color: Theme.of(context).textTheme.bodySmall?.color, + ), + )), ], ), ); @@ -585,11 +163,12 @@ class KRPurchaseMembershipView extends GetView { // 套餐选项卡片 Widget _kr_buildPlanOptionCard( - KRPackageListItem plan, - int planIndex, - int? discountIndex, - BuildContext context, - bool isFirst,) { + KRPackageListItem plan, + int planIndex, + int? discountIndex, + BuildContext context, + bool isFirst, + ) { // 由于移除了 Obx,isSelected 的值在构建时就固定了。 // 它将不再响应用户的点击事件来改变UI。 // 根据您的要求,isSelected 的值与 isFirst 相反。 @@ -606,25 +185,27 @@ class KRPurchaseMembershipView extends GetView { padding: EdgeInsets.all(5), // 边框宽度 decoration: BoxDecoration( color: Colors.black, // 边框颜色 - borderRadius: BorderRadius.circular(43.r), // 外部圆角 = 内部圆角 + 边框宽度 + borderRadius: BorderRadius.circular(43.0), // 外部圆角 = 内部圆角 + 边框宽度 ), child: ClipRRect( - borderRadius: BorderRadius.circular(38.r), // 内部圆角 + borderRadius: BorderRadius.circular(38.0), // 内部圆角 child: Container( - padding: EdgeInsets.fromLTRB(45.w, 10.w, 0.w, 10.w), + padding: EdgeInsets.fromLTRB(45.0, 10.0, 0.0, 10.0), decoration: BoxDecoration( color: isSelected ? Colors.black : Theme.of(context).primaryColor, - borderRadius: BorderRadius.circular(38.r), + borderRadius: BorderRadius.circular(38.0), ), child: Stack( clipBehavior: Clip.none, children: [ - Column( mainAxisSize: MainAxisSize.min, + Column( + mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - controller.kr_getTimeStr(plan, discountIndex: discountIndex), + controller.kr_getTimeStr(plan, + discountIndex: discountIndex), style: TextStyle( fontSize: 24, fontWeight: FontWeight.w600, @@ -642,8 +223,7 @@ class KRPurchaseMembershipView extends GetView { color: isSelected ? Colors.white : Theme.of(context).textTheme.bodyMedium?.color, - ) - ), + )), Text( '约¥${controller.kr_getDayPlanPrice(plan, discountIndex: discountIndex).toStringAsFixed(2)}/天', style: TextStyle( @@ -652,12 +232,9 @@ class KRPurchaseMembershipView extends GetView { color: isSelected ? Colors.white : Theme.of(context).textTheme.bodyMedium?.color, - ) - ), - ] - ), - - if(!isFirst) + )), + ]), + if (!isFirst) Positioned( top: 0, right: 0, @@ -665,9 +242,9 @@ class KRPurchaseMembershipView extends GetView { angle: 0.785398, // 45度角 (π/4) child: Container( // 调整位置,让标签的一部分显示在容器外 - transform: Matrix4.translationValues(19.w, -12.w, 0), - width: 92.w, // 适当的宽度 - height: 16.w, // 固定高度 + transform: Matrix4.translationValues(30, -10, 0), + width: 130, // 适当的宽度 + height: 20, // 固定高度 decoration: BoxDecoration( color: Theme.of(context).primaryColor, // 使用主题色作为背景 ), @@ -685,47 +262,6 @@ class KRPurchaseMembershipView extends GetView { ), ), ), - - /* if (discountIndex != null && plan.kr_discount.isNotEmpty) ...[ - Container( - padding: EdgeInsets.symmetric( - horizontal: 8.w, - vertical: 2.h - ), - decoration: BoxDecoration( - color: plan.kr_discount[discountIndex].kr_discount < 100 - ? Colors.red.withOpacity(0.08) - : Colors.transparent, - borderRadius: BorderRadius.circular(4.r), - border: plan.kr_discount[discountIndex].kr_discount < 100 - ? Border.all( - color: Colors.red.withOpacity(0.2), - width: 1, - ) - : null, - boxShadow: plan.kr_discount[discountIndex].kr_discount < 100 - ? [ - BoxShadow( - color: Colors.red.withOpacity(0.05), - blurRadius: 4, - offset: Offset(0, 2), - spreadRadius: 0, - ), - ] - : null, - ), - child: Text( - controller.kr_getDiscountText(plan, discountIndex), - style: KrAppTextStyle( - fontSize: 10, - fontWeight: FontWeight.w500, - color: plan.kr_discount[discountIndex].kr_discount < 100 - ? Colors.red.withOpacity(0.9) - : Colors.transparent, - ), - ), - ), - ],*/ ], ), ), @@ -733,56 +269,4 @@ class KRPurchaseMembershipView extends GetView { ), ); } - - // 底部部分 - Widget _kr_buildBottomSection(BuildContext context) { - // 如果正在加载或没有数据,不显示底部按钮 - if (controller.kr_isLoading.value || controller.kr_plans.isEmpty || controller.kr_paymentMethods.isEmpty) { - return SizedBox.shrink(); - } - - return Container( - padding: EdgeInsets.all(16.r), - decoration: BoxDecoration( - color: Theme.of(context).scaffoldBackgroundColor, - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - offset: Offset(0, -2), - blurRadius: 8, - ), - ], - ), - child: SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: () { - KRDialog.show( - title: AppTranslations.kr_purchaseMembership.confirmPurchase, - message: AppTranslations.kr_purchaseMembership.confirmPurchaseDesc, - cancelText: AppTranslations.kr_dialog.kr_cancel, - confirmText: AppTranslations.kr_dialog.kr_confirm, - onConfirm: () => controller.kr_startSubscription(), - ); - }, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - foregroundColor: Colors.white, - padding: EdgeInsets.symmetric(vertical: 12.h), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.r), - ), - ), - child: Text( - controller.kr_getSubscribeButtonText(), - style: KrAppTextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.white, - ), - ), - ), - ), - ); - } } diff --git a/lib/app/utils/kr_secure_storage.dart b/lib/app/utils/kr_secure_storage.dart index d28c22f..fabe6b5 100755 --- a/lib/app/utils/kr_secure_storage.dart +++ b/lib/app/utils/kr_secure_storage.dart @@ -16,7 +16,7 @@ class KRSecureStorage { // 存储箱名称 static const String _boxName = 'kaer_secure_storage'; - + // 加密密钥 static const String _encryptionKey = 'kaer_secure_storage_key'; @@ -27,19 +27,19 @@ class KRSecureStorage { if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) { final baseDir = await getApplicationSupportDirectory(); KRLogUtil.kr_i('初始化 Hive,路径: ${baseDir.path}', tag: 'SecureStorage'); - + // 确保目录存在 if (!baseDir.existsSync()) { await baseDir.create(recursive: true); KRLogUtil.kr_i('已创建 Hive 目录: ${baseDir.path}', tag: 'SecureStorage'); } - + await Hive.initFlutter(baseDir.path); } else { // Android 和 iOS 使用默认路径 await Hive.initFlutter(); } - + // 使用加密适配器 final key = HiveAesCipher(_generateKey()); await Hive.openBox(_boxName, encryptionCipher: key); @@ -48,14 +48,14 @@ class KRSecureStorage { KRLogUtil.kr_e('初始化 Hive 失败: $e', tag: 'SecureStorage'); KRLogUtil.kr_e('错误类型: ${e.runtimeType}', tag: 'SecureStorage'); KRLogUtil.kr_e('错误堆栈: $stackTrace', tag: 'SecureStorage'); - + // 对于 Windows 和 Linux,如果初始化失败,尝试删除旧文件并重试 if (Platform.isWindows || Platform.isLinux) { try { KRLogUtil.kr_i('尝试清理并重新初始化 Hive', tag: 'SecureStorage'); final baseDir = await getApplicationSupportDirectory(); final hiveDir = Directory(baseDir.path); - + // 查找并删除相关的 Hive 文件 if (hiveDir.existsSync()) { final files = hiveDir.listSync(); @@ -63,8 +63,8 @@ class KRSecureStorage { if (entity is File) { final fileName = entity.path.split(Platform.pathSeparator).last; // 删除 Hive 数据库文件(通常是 .hive 或 .lock 文件) - if (fileName.startsWith(_boxName) || - fileName.endsWith('.hive') || + if (fileName.startsWith(_boxName) || + fileName.endsWith('.hive') || fileName.endsWith('.lock')) { try { await entity.delete(); @@ -76,7 +76,7 @@ class KRSecureStorage { } } } - + // 重新初始化 await Hive.initFlutter(baseDir.path); final key = HiveAesCipher(_generateKey()); @@ -116,8 +116,15 @@ class KRSecureStorage { try { final box = await _ensureBoxOpen(); await box.put(key, value); + + // 🔧 关键修复:强制将数据立即写入磁盘,确保持久化 + // 不调用 flush() 时,数据只在内存缓冲区中,应用关闭后会丢失! + await box.flush(); + + print('💾 [SecureStorage] 数据已保存并刷新到磁盘: $key'); KRLogUtil.kr_i('✅ 数据已保存: $key', tag: 'SecureStorage'); } catch (e) { + print('❌ [SecureStorage] 存储数据失败: $e'); KRLogUtil.kr_e('❌ 存储数据失败: $e', tag: 'SecureStorage'); rethrow; // 重新抛出异常,让调用者知道保存失败 } @@ -210,4 +217,4 @@ class KRSecureStorage { return null; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/lib/app/utils/kr_window_manager.dart b/lib/app/utils/kr_window_manager.dart index 61e6218..00fa4d2 100755 --- a/lib/app/utils/kr_window_manager.dart +++ b/lib/app/utils/kr_window_manager.dart @@ -53,7 +53,7 @@ class KRWindowManager with WindowListener, TrayListener { // 阻止窗口关闭 await windowManager.setPreventClose(true); } else { - await windowManager.setTitle('Kaer VPN'); + await windowManager.setTitle('HiFastVPN'); await windowManager.setSize(const Size(800, 668)); await windowManager.setMinimumSize(const Size(400, 334)); await windowManager.center(); @@ -94,7 +94,7 @@ class KRWindowManager with WindowListener, TrayListener { /// 初始化平台通道 void _initPlatformChannel() { if (Platform.isMacOS) { - const platform = MethodChannel('kaer_vpn/terminate'); + const platform = MethodChannel('hifast_vpn/terminate'); platform.setMethodCallHandler((call) async { if (call.method == 'onTerminate') { KRLogUtil.kr_i('收到应用终止通知'); diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index efce263..bae8743 100755 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -571,11 +571,10 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; - CODE_SIGN_STYLE = Manual; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB; + DEVELOPMENT_TEAM = NJRRF427XB; ENABLE_HARDENED_RUNTIME = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN; @@ -586,7 +585,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SWIFT_VERSION = 5.0; }; name = Profile; @@ -706,11 +704,10 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; - CODE_SIGN_STYLE = Manual; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB; + DEVELOPMENT_TEAM = NJRRF427XB; ENABLE_HARDENED_RUNTIME = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN; @@ -721,7 +718,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; }; @@ -735,11 +731,10 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; - CODE_SIGN_STYLE = Manual; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB; + DEVELOPMENT_TEAM = NJRRF427XB; ENABLE_HARDENED_RUNTIME = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN; @@ -750,7 +745,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SWIFT_VERSION = 5.0; }; name = Release; diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index beaf03e..bc893ed 100755 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -37,7 +37,7 @@ class AppDelegate: FlutterAppDelegate { // 通知 Flutter 端应用即将终止 if let controller = NSApp.windows.first?.contentViewController as? FlutterViewController { - let channel = FlutterMethodChannel(name: "kaer_vpn/terminate", binaryMessenger: controller.engine.binaryMessenger) + let channel = FlutterMethodChannel(name: "hifast_vpn/terminate", binaryMessenger: controller.engine.binaryMessenger) channel.invokeMethod("onTerminate", arguments: nil) } }