feat: 更新鸿蒙应用配置与功能优化
- 添加鸿蒙分层图标配置和生成脚本 - 修复数据导出JSON解析问题 - 优化关于页面和团队信息展示 - 更新应用版本至1.4.1 - 清理代码警告和冗余文件 - 添加字体和二维码测试脚本 - 完善鸿蒙适配文档和指南
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
* 作用: 交友软件风格左右滑动浏览菜品,支持分类筛选/搜索/收藏/全屏查看/分享
|
||||
* 创建: 2026-04-14
|
||||
* 更新: 2026-04-14 引入flutter_card_swiper重构滑动系统,移除自定义手势/动画控制器
|
||||
* 更新: 2026-04-25 清理5个unnecessary_underscores警告(双下划线→单下划线)
|
||||
*/
|
||||
|
||||
import 'dart:async';
|
||||
@@ -845,7 +846,7 @@ class _MiniCardPageState extends State<MiniCardPage> {
|
||||
horizontal: DesignTokens.space4,
|
||||
),
|
||||
itemCount: _searchResults.length,
|
||||
separatorBuilder: (_, __) => const SizedBox(height: 4),
|
||||
separatorBuilder: (_, _) => const SizedBox(height: 4),
|
||||
itemBuilder: (context, index) {
|
||||
final recipe = _searchResults[index];
|
||||
final catInfo = _meta?.categories[recipe.category];
|
||||
@@ -877,14 +878,14 @@ class _MiniCardPageState extends State<MiniCardPage> {
|
||||
memCacheHeight: 96,
|
||||
maxWidthDiskCache: 200,
|
||||
maxHeightDiskCache: 200,
|
||||
errorWidget: (_, __, _) => Container(
|
||||
errorWidget: (_, _, _) => Container(
|
||||
color: DesignTokens.background,
|
||||
child: const Icon(
|
||||
CupertinoIcons.photo,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
progressIndicatorBuilder: (_, __, _) =>
|
||||
progressIndicatorBuilder: (_, _, _) =>
|
||||
Container(
|
||||
color: DesignTokens.background,
|
||||
child: const CupertinoActivityIndicator(
|
||||
@@ -947,7 +948,7 @@ class _MiniCardPageState extends State<MiniCardPage> {
|
||||
maxHeightDiskCache: 800,
|
||||
fadeInDuration: const Duration(milliseconds: 300),
|
||||
fadeInCurve: Curves.easeOut,
|
||||
errorWidget: (_, __, _) => Container(
|
||||
errorWidget: (_, _, _) => Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
@@ -966,7 +967,7 @@ class _MiniCardPageState extends State<MiniCardPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
progressIndicatorBuilder: (_, __, _) => Container(
|
||||
progressIndicatorBuilder: (_, _, _) => Container(
|
||||
color: DesignTokens.background,
|
||||
child: const Center(child: CupertinoActivityIndicator()),
|
||||
),
|
||||
|
||||
@@ -281,7 +281,7 @@ class _StatsDashboardPageState extends State<StatsDashboardPage> {
|
||||
_formatNumber(nutritionRecords),
|
||||
DesignTokens.teal,
|
||||
isDark,
|
||||
subtitle: '$nutritionTypes 项日志',
|
||||
subtitle: '$nutritionTypes 项日志(归档)',
|
||||
),
|
||||
),
|
||||
const SizedBox(width: DesignTokens.space2),
|
||||
|
||||
@@ -20,6 +20,7 @@ import 'package:cute_kitchen/src/pages/profile/info/learn_us_page.dart';
|
||||
import 'package:cute_kitchen/src/pages/profile/info/privacy_policy_page.dart';
|
||||
import 'package:cute_kitchen/src/pages/profile/tools/permission_page.dart';
|
||||
import 'package:cute_kitchen/src/pages/profile/info/references_page.dart';
|
||||
import 'package:cute_kitchen/src/utils/platform_utils.dart';
|
||||
import 'package:cute_kitchen/src/services/core/app_info_service.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
@@ -251,13 +252,7 @@ class AboutPage extends StatelessWidget {
|
||||
title: '评价应用',
|
||||
subtitle: '在应用商店给我们评分',
|
||||
isDark: isDark,
|
||||
onTap: () {
|
||||
Get.snackbar(
|
||||
'提示',
|
||||
'未找到应用商店链接',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
},
|
||||
onTap: () => _onRateApp(context, isDark),
|
||||
),
|
||||
_buildDivider(isDark),
|
||||
_buildActionTile(
|
||||
@@ -448,6 +443,67 @@ class AboutPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _onRateApp(BuildContext context, bool isDark) {
|
||||
if (PlatformUtils().isHarmonyOS) {
|
||||
showCupertinoDialog(
|
||||
context: context,
|
||||
builder: (ctx) => CupertinoAlertDialog(
|
||||
title: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text('⭐', style: TextStyle(fontSize: 24)),
|
||||
SizedBox(width: 8),
|
||||
Text('给个五星好评吧'),
|
||||
],
|
||||
),
|
||||
content: const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text('如果您喜欢小妈厨房,请给我们一个好评!'),
|
||||
Text(
|
||||
'您的支持是我们前进的动力 💪',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: CupertinoColors.secondaryLabel,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Text('⭐⭐⭐⭐⭐', style: TextStyle(fontSize: 28))],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
isDestructiveAction: true,
|
||||
child: const Text('下次再说'),
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
isDefaultAction: true,
|
||||
onPressed: () {
|
||||
Navigator.pop(ctx);
|
||||
launchUrl(
|
||||
Uri.parse(
|
||||
'https://appgallery.huawei.com/app/detail?id=cute.major.kitchen',
|
||||
),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
},
|
||||
child: const Text('去评价 ⭐'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
Get.snackbar('提示', '未找到应用商店链接', snackPosition: SnackPosition.BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
void _showEmailSheet(BuildContext context, bool isDark) {
|
||||
final emails = [
|
||||
_ContactEmail(
|
||||
@@ -471,6 +527,11 @@ class AboutPage extends StatelessWidget {
|
||||
icon: '📬',
|
||||
),
|
||||
_ContactEmail(address: '5147662@qq.com', label: '任意邮箱均可联系', icon: '📬'),
|
||||
_ContactEmail(
|
||||
address: 'lzy20010304@gmail.com',
|
||||
label: '任意邮箱均可联系',
|
||||
icon: '📧',
|
||||
),
|
||||
];
|
||||
|
||||
showCupertinoModalPopup(
|
||||
|
||||
@@ -391,7 +391,8 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
String buildSdk = 'Unknown';
|
||||
try {
|
||||
final platform = PlatformUtils();
|
||||
if (platform.isHarmonyOS || defaultTargetPlatform == TargetPlatform.ohos) {
|
||||
if (platform.isHarmonyOS ||
|
||||
defaultTargetPlatform == TargetPlatform.ohos) {
|
||||
buildSdk = 'Deveco API 23';
|
||||
} else if (platform.isAndroid) {
|
||||
buildSdk = 'Android Target 36';
|
||||
@@ -629,13 +630,7 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
_buildDivider(isDark),
|
||||
_buildInfoItem('Web 服务器', 'Nginx', CupertinoIcons.globe, isDark),
|
||||
_buildDivider(isDark),
|
||||
_buildCopyableItem(
|
||||
'App 在线版(Beta测试)',
|
||||
'https://www.wktyl.com/app',
|
||||
CupertinoIcons.link,
|
||||
isDark,
|
||||
primaryColor,
|
||||
),
|
||||
_buildWebAppItem(isDark, primaryColor),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -795,16 +790,21 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
children: [
|
||||
_buildUpdateItem(
|
||||
'版本 ${AppConfig.appVersion}',
|
||||
'2026-04-23',
|
||||
['升级鸿蒙api 23', '优化关于页面布局与交互体验'],
|
||||
'2026-04-25',
|
||||
[
|
||||
'修复鸿蒙端数据导入问题',
|
||||
|
||||
'现在,你从APP导出的备份数据,在小妈厨房 android,Harmony,Web,Windows 可直接导入了',
|
||||
'现已支持将菜品导出为PDF,Word (实验)',
|
||||
],
|
||||
isDark,
|
||||
primaryColor,
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space3),
|
||||
_buildUpdateItem(
|
||||
'版本 0.99.6',
|
||||
'2026-04-18',
|
||||
['工具中心', '工具下拉页面使用new UI ,旧版ui停止维护'],
|
||||
'版本 1.0.1',
|
||||
'2026-04-20',
|
||||
['优化工具中心下拉动画', '工具中心暂时归档,不再增加功能'],
|
||||
isDark,
|
||||
primaryColor,
|
||||
),
|
||||
@@ -1232,6 +1232,107 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildWebAppItem(bool isDark, Color primaryColor) {
|
||||
return GestureDetector(
|
||||
onTap: () => _showWebAppDialog(isDark),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignTokens.space4,
|
||||
vertical: DesignTokens.space3,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
CupertinoIcons.link,
|
||||
size: 20,
|
||||
color: isDark ? DarkDesignTokens.text3 : DesignTokens.text3,
|
||||
),
|
||||
const SizedBox(width: DesignTokens.space3),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'App 在线版(Beta测试)',
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontMd,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isDark
|
||||
? DarkDesignTokens.text1
|
||||
: DesignTokens.text1,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'https://www.wktyl.com/app',
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontSm,
|
||||
color: isDark
|
||||
? DarkDesignTokens.text3
|
||||
: DesignTokens.text3,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
CupertinoIcons.arrow_up_right_circle,
|
||||
size: 16,
|
||||
color: primaryColor.withValues(alpha: 0.6),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showWebAppDialog(bool isDark) {
|
||||
showCupertinoDialog(
|
||||
context: Get.context!,
|
||||
builder: (ctx) => CupertinoAlertDialog(
|
||||
title: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text('🌐', style: TextStyle(fontSize: 22)),
|
||||
SizedBox(width: 8),
|
||||
Text('打开在线版'),
|
||||
],
|
||||
),
|
||||
content: const Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 8),
|
||||
Text('首次打开需要加载资源,预计等待'),
|
||||
Text(
|
||||
'30~60 秒',
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
|
||||
),
|
||||
Text('请耐心等待,后续访问会明显加快 🚀'),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
isDestructiveAction: true,
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text('取消'),
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
isDefaultAction: true,
|
||||
onPressed: () {
|
||||
Navigator.pop(ctx);
|
||||
launchUrl(
|
||||
Uri.parse('https://www.wktyl.com/app'),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
},
|
||||
child: const Text('确认打开'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCopyableItem(
|
||||
String title,
|
||||
String value,
|
||||
|
||||
@@ -394,7 +394,7 @@ class LearnUsPage extends StatelessWidget {
|
||||
children: [
|
||||
_buildTeamMember('💻', '程序设计', '纯情小妈', '喜欢发呆', isDark),
|
||||
_buildDivider(isDark),
|
||||
_buildTeamMember('🎨', 'UI/UX/Testing', 'Freetime', '关于你的风景。', isDark),
|
||||
_buildTeamMember('🎨', 'UI/UX/Tools', 'Freetime', '关于你的风景。', isDark),
|
||||
_buildDivider(isDark),
|
||||
_buildTeamMember('⚙️', '后端开发', '伯乐不相马', '还是做不到吗?', isDark),
|
||||
_buildDivider(isDark),
|
||||
@@ -830,6 +830,11 @@ class LearnUsPage extends StatelessWidget {
|
||||
icon: '📬',
|
||||
),
|
||||
_ContactEmail(address: '5147662@qq.com', label: '任意邮箱均可联系', icon: '📬'),
|
||||
_ContactEmail(
|
||||
address: 'lzy20010304@gmail.com',
|
||||
label: '任意邮箱均可联系',
|
||||
icon: '📧',
|
||||
),
|
||||
];
|
||||
|
||||
showCupertinoModalPopup(
|
||||
|
||||
290
lib/src/pages/profile/known_issues_sheet.dart
Normal file
290
lib/src/pages/profile/known_issues_sheet.dart
Normal file
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
* 文件: known_issues_sheet.dart
|
||||
* 名称: 已知问题底部弹出面板
|
||||
* 作用: 展示应用已知问题与说明的独立组件,从 profile_settings.dart 分流提取
|
||||
* 创建: 2026-04-25
|
||||
* 更新: 2026-04-25 从 profile_settings.dart 提取,降低主文件体积
|
||||
*/
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:cute_kitchen/src/config/design_tokens.dart';
|
||||
|
||||
enum IssueLevel { important, warning, info }
|
||||
|
||||
class KnownIssueItem {
|
||||
final String icon;
|
||||
final String title;
|
||||
final IssueLevel level;
|
||||
final String description;
|
||||
|
||||
const KnownIssueItem({
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.level,
|
||||
required this.description,
|
||||
});
|
||||
}
|
||||
|
||||
class KnownIssuesSheet {
|
||||
static List<KnownIssueItem> get issues => [
|
||||
KnownIssueItem(
|
||||
icon: '🌐',
|
||||
title: 'VPN/代理环境部分功能异常',
|
||||
level: IssueLevel.warning,
|
||||
description: '使用代理或 VPN 时,部分接口请求可能超时或失败,建议在直连环境或者国内网络环境下使用以获得最佳体验。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '🧊',
|
||||
title: 'Win10/11端 页面返回问题',
|
||||
level: IssueLevel.warning,
|
||||
description: '部分页面未设置返回逻辑,需使用快捷键 同时按下 ALT+方向左键/Escape(Esc键) 返回上一页。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '📂',
|
||||
title: '分类列表默认显示前20项',
|
||||
level: IssueLevel.info,
|
||||
description:
|
||||
'为节省服务器资源,大部分分类(菜系、标签等)默认只展示前20条。低于20条的分类会显示全部数量。后续将支持"加载更多"。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '🔑',
|
||||
title: 'Key 码获取方式',
|
||||
level: IssueLevel.important,
|
||||
description: '当前暂未开放注册登录,需通过邀请获取 Key 码激活。后续版本将开放付费购买渠道。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '🧊',
|
||||
title: '液态玻璃效果 GPU 占用较高',
|
||||
level: IssueLevel.warning,
|
||||
description:
|
||||
'液态玻璃(Liquid Glass)效果对 GPU 要求较高,长时间使用可能出现轻微发热。低性能设备建议在设置中关闭毛玻璃效果。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '🚧',
|
||||
title: '开发中功能免费,完成后可能收费',
|
||||
level: IssueLevel.important,
|
||||
description: '当前处于开发阶段的功能均可免费使用。功能开发完成并稳定后,部分高级功能可能转为付费订阅制。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '📱',
|
||||
title: '大部分页面横屏适配未完成',
|
||||
level: IssueLevel.info,
|
||||
description: '当前主要针对竖屏优化,横屏或折叠屏展开状态下部分页面布局可能不够理想,后续版本将逐步适配。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '🖼️',
|
||||
title: '图片加载偶现延迟',
|
||||
level: IssueLevel.info,
|
||||
description:
|
||||
'服务器带宽6MB/s,换算后加载资源每秒约500Kb,首次加载可能较慢。高并发时段服务器会触发自我保护机制,限制单连接速率;带宽达到上限时也会出现加载缓慢或失败。已访问过的图片会自动缓存,命中缓存加载将显著加快。后续会增加无图模式。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '📧',
|
||||
title: '邮箱发送受限说明',
|
||||
level: IssueLevel.warning,
|
||||
description:
|
||||
'邮箱发送功能仅支持国内网络环境。使用代理、VPN或在海外网络下无法发送,即使显示发送成功也会失败。路由器端代理同样会导致发送失败。部分WiFi环境下可能因服务商拦截而无法发送,可切换移动数据重试。建议在稳定的国内网络下使用此功能。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '🔍',
|
||||
title: 'web端 部分功能未开放',
|
||||
level: IssueLevel.info,
|
||||
description: '由于服务器占用较大,部分功能在线版暂未开放,无法加载。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '💾',
|
||||
title: '离线模式功能有限',
|
||||
level: IssueLevel.warning,
|
||||
description: '无网络时仅可查看已缓存的菜谱和分类数据,筛选、推荐等需要联网的功能暂不可用。后续将增强离线体验。',
|
||||
),
|
||||
KnownIssueItem(
|
||||
icon: '📄',
|
||||
title: '部分平台导出文件后缀重复',
|
||||
level: IssueLevel.warning,
|
||||
description:
|
||||
'已知鸿蒙端导出文件后缀会出现重复(如 xxx.pdf.pdf、xxx.json.json ....),此为系统文件选择器自动追加后缀导致。当前问题排查中,暂无修复计划。用户可在导出页面手动删除多余后缀。',
|
||||
),
|
||||
];
|
||||
|
||||
static void show(BuildContext context, bool isDark) {
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (ctx) => Container(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(ctx).size.height * 0.75,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? DarkDesignTokens.card : DesignTokens.card,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(DesignTokens.radiusXl),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: DesignTokens.space2),
|
||||
Container(
|
||||
width: 36,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: (isDark ? DarkDesignTokens.text3 : DesignTokens.text3)
|
||||
.withValues(alpha: 0.3),
|
||||
borderRadius: DesignTokens.borderRadiusSm,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space3),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignTokens.space4,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Text('⚠️', style: TextStyle(fontSize: 20)),
|
||||
const SizedBox(width: DesignTokens.space2),
|
||||
Text(
|
||||
'已知问题与说明',
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontLg,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isDark
|
||||
? DarkDesignTokens.text1
|
||||
: DesignTokens.text1,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.pop(ctx),
|
||||
child: Container(
|
||||
width: 28,
|
||||
height: 28,
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
(isDark
|
||||
? DarkDesignTokens.text3
|
||||
: DesignTokens.text3)
|
||||
.withValues(alpha: 0.12),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
CupertinoIcons.xmark,
|
||||
size: 14,
|
||||
color: isDark
|
||||
? DarkDesignTokens.text2
|
||||
: DesignTokens.text2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space3),
|
||||
Flexible(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignTokens.space4,
|
||||
),
|
||||
itemCount: issues.length,
|
||||
separatorBuilder: (_, __) =>
|
||||
const SizedBox(height: DesignTokens.space2),
|
||||
itemBuilder: (_, index) =>
|
||||
_buildIssueCard(issues[index], isDark),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space4),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignTokens.space4,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: CupertinoButton(
|
||||
borderRadius: DesignTokens.borderRadiusLg,
|
||||
color: DesignTokens.primaryLight,
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: Text(
|
||||
'我知道了',
|
||||
style: TextStyle(
|
||||
color: DesignTokens.dynamicPrimary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(ctx).padding.bottom + DesignTokens.space3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildIssueCard(KnownIssueItem issue, bool isDark) {
|
||||
final levelColor = switch (issue.level) {
|
||||
IssueLevel.important => CupertinoColors.destructiveRed,
|
||||
IssueLevel.warning => CupertinoColors.activeOrange,
|
||||
IssueLevel.info => DesignTokens.dynamicPrimary,
|
||||
};
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(DesignTokens.space3),
|
||||
decoration: BoxDecoration(
|
||||
color: levelColor.withValues(alpha: 0.06),
|
||||
borderRadius: DesignTokens.borderRadiusLg,
|
||||
border: Border.all(color: levelColor.withValues(alpha: 0.15)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(issue.icon, style: const TextStyle(fontSize: 16)),
|
||||
const SizedBox(width: DesignTokens.space2),
|
||||
Expanded(
|
||||
child: Text(
|
||||
issue.title,
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontMd,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: isDark ? DarkDesignTokens.text1 : DesignTokens.text1,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: levelColor.withValues(alpha: 0.12),
|
||||
borderRadius: DesignTokens.borderRadiusSm,
|
||||
),
|
||||
child: Text(
|
||||
switch (issue.level) {
|
||||
IssueLevel.important => '重要',
|
||||
IssueLevel.warning => '注意',
|
||||
IssueLevel.info => '提示',
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: levelColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space2),
|
||||
Text(
|
||||
issue.description,
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontXs,
|
||||
height: 1.5,
|
||||
color: isDark ? DarkDesignTokens.text2 : DesignTokens.text2,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* 文件: profile_settings.dart
|
||||
* 名称: 个人中心设置标签
|
||||
* 作用: iOS 26 风格的设置选项,使用 DesignTokens 和 GlassSettingsTile
|
||||
@@ -19,6 +19,7 @@ import 'package:cute_kitchen/src/pages/tools/cooking/cooking_note_page.dart';
|
||||
import 'package:cute_kitchen/src/pages/profile/social/footprints_page.dart';
|
||||
import 'package:cute_kitchen/src/pages/profile/data/cache_manage_page.dart';
|
||||
import 'package:cute_kitchen/src/pages/profile/tools/data_export_page.dart';
|
||||
import 'package:cute_kitchen/src/pages/profile/known_issues_sheet.dart';
|
||||
|
||||
class ProfileSettingsTab extends StatelessWidget {
|
||||
const ProfileSettingsTab({super.key});
|
||||
@@ -94,7 +95,7 @@ class ProfileSettingsTab extends StatelessWidget {
|
||||
icon: CupertinoIcons.exclamationmark_triangle,
|
||||
title: '已知问题 ⚠️',
|
||||
isDark: isDark,
|
||||
onTap: () => _showKnownIssuesSheet(context, isDark),
|
||||
onTap: () => KnownIssuesSheet.show(context, isDark),
|
||||
),
|
||||
// _buildTile(
|
||||
// icon: CupertinoIcons.flame,
|
||||
@@ -481,277 +482,6 @@ class ProfileSettingsTab extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showKnownIssuesSheet(BuildContext context, bool isDark) {
|
||||
final issues = [
|
||||
_KnownIssue(
|
||||
icon: '🌐',
|
||||
title: 'VPN/代理环境部分功能异常',
|
||||
level: _IssueLevel.warning,
|
||||
description: '使用代理或 VPN 时,部分接口请求可能超时或失败,建议在直连环境或者国内网络环境下使用以获得最佳体验。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '🧊',
|
||||
title: 'Win10/11端 页面返回问题',
|
||||
level: _IssueLevel.warning,
|
||||
description: '部分页面未设置返回逻辑,需使用快捷键 同时按下 ALT+方向左键/Escape(Esc键) 返回上一页。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '📂',
|
||||
title: '分类列表默认显示前20项',
|
||||
level: _IssueLevel.info,
|
||||
description:
|
||||
'为节省服务器资源,大部分分类(菜系、标签等)默认只展示前20条。低于20条的分类会显示全部数量。后续将支持"加载更多"。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '🔑',
|
||||
title: 'Key 码获取方式',
|
||||
level: _IssueLevel.important,
|
||||
description: '当前暂未开放注册登录,需通过邀请获取 Key 码激活。后续版本将开放付费购买渠道。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '🧊',
|
||||
title: '液态玻璃效果 GPU 占用较高',
|
||||
level: _IssueLevel.warning,
|
||||
description:
|
||||
'液态玻璃(Liquid Glass)效果对 GPU 要求较高,长时间使用可能出现轻微发热。低性能设备建议在设置中关闭毛玻璃效果。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '🚧',
|
||||
title: '开发中功能免费,完成后可能收费',
|
||||
level: _IssueLevel.important,
|
||||
description: '当前处于开发阶段的功能均可免费使用。功能开发完成并稳定后,部分高级功能可能转为付费订阅制。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '📱',
|
||||
title: '大部分页面横屏适配未完成',
|
||||
level: _IssueLevel.info,
|
||||
description: '当前主要针对竖屏优化,横屏或折叠屏展开状态下部分页面布局可能不够理想,后续版本将逐步适配。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '🖼️',
|
||||
title: '图片加载偶现延迟',
|
||||
level: _IssueLevel.info,
|
||||
description:
|
||||
'服务器带宽6MB/s,换算后加载资源每秒约500Kb,首次加载可能较慢。高并发时段服务器会触发自我保护机制,限制单连接速率;带宽达到上限时也会出现加载缓慢或失败。已访问过的图片会自动缓存,命中缓存加载将显著加快。后续会增加无图模式。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '📧',
|
||||
title: '邮箱发送受限说明',
|
||||
level: _IssueLevel.warning,
|
||||
description:
|
||||
'邮箱发送功能仅支持国内网络环境。使用代理、VPN或在海外网络下无法发送,即使显示发送成功也会失败。路由器端代理同样会导致发送失败。部分WiFi环境下可能因服务商拦截而无法发送,可切换移动数据重试。建议在稳定的国内网络下使用此功能。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '🔍',
|
||||
title: 'web端 部分功能未开放',
|
||||
level: _IssueLevel.info,
|
||||
description: '由于服务器占用较大,部分功能在线版暂未开放,无法加载。',
|
||||
),
|
||||
_KnownIssue(
|
||||
icon: '💾',
|
||||
title: '离线模式功能有限',
|
||||
level: _IssueLevel.warning,
|
||||
description: '无网络时仅可查看已缓存的菜谱和分类数据,筛选、推荐等需要联网的功能暂不可用。后续将增强离线体验。',
|
||||
),
|
||||
];
|
||||
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (ctx) => Container(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(ctx).size.height * 0.75,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? DarkDesignTokens.card : DesignTokens.card,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(DesignTokens.radiusXl),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: DesignTokens.space2),
|
||||
Container(
|
||||
width: 36,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: (isDark ? DarkDesignTokens.text3 : DesignTokens.text3)
|
||||
.withValues(alpha: 0.3),
|
||||
borderRadius: DesignTokens.borderRadiusSm,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space3),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignTokens.space4,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Text('⚠️', style: TextStyle(fontSize: 20)),
|
||||
const SizedBox(width: DesignTokens.space2),
|
||||
Text(
|
||||
'已知问题与说明',
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontLg,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isDark
|
||||
? DarkDesignTokens.text1
|
||||
: DesignTokens.text1,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.pop(ctx),
|
||||
child: Container(
|
||||
width: 28,
|
||||
height: 28,
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
(isDark
|
||||
? DarkDesignTokens.text3
|
||||
: DesignTokens.text3)
|
||||
.withValues(alpha: 0.12),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
CupertinoIcons.xmark,
|
||||
size: 14,
|
||||
color: isDark
|
||||
? DarkDesignTokens.text2
|
||||
: DesignTokens.text2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space3),
|
||||
Flexible(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignTokens.space4,
|
||||
),
|
||||
itemCount: issues.length,
|
||||
separatorBuilder: (_, __) =>
|
||||
const SizedBox(height: DesignTokens.space2),
|
||||
itemBuilder: (_, index) =>
|
||||
_buildIssueCard(issues[index], isDark),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space4),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignTokens.space4,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: CupertinoButton(
|
||||
borderRadius: DesignTokens.borderRadiusLg,
|
||||
color: DesignTokens.primaryLight,
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: Text(
|
||||
'我知道了',
|
||||
style: TextStyle(
|
||||
color: DesignTokens.dynamicPrimary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(ctx).padding.bottom + DesignTokens.space3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIssueCard(_KnownIssue issue, bool isDark) {
|
||||
final levelColor = switch (issue.level) {
|
||||
_IssueLevel.important => CupertinoColors.destructiveRed,
|
||||
_IssueLevel.warning => CupertinoColors.activeOrange,
|
||||
_IssueLevel.info => DesignTokens.dynamicPrimary,
|
||||
};
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(DesignTokens.space3),
|
||||
decoration: BoxDecoration(
|
||||
color: levelColor.withValues(alpha: 0.06),
|
||||
borderRadius: DesignTokens.borderRadiusLg,
|
||||
border: Border.all(color: levelColor.withValues(alpha: 0.15)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(issue.icon, style: const TextStyle(fontSize: 16)),
|
||||
const SizedBox(width: DesignTokens.space2),
|
||||
Expanded(
|
||||
child: Text(
|
||||
issue.title,
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontMd,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: isDark ? DarkDesignTokens.text1 : DesignTokens.text1,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: levelColor.withValues(alpha: 0.12),
|
||||
borderRadius: DesignTokens.borderRadiusSm,
|
||||
),
|
||||
child: Text(
|
||||
switch (issue.level) {
|
||||
_IssueLevel.important => '重要',
|
||||
_IssueLevel.warning => '注意',
|
||||
_IssueLevel.info => '提示',
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: levelColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: DesignTokens.space2),
|
||||
Text(
|
||||
issue.description,
|
||||
style: TextStyle(
|
||||
fontSize: DesignTokens.fontXs,
|
||||
height: 1.5,
|
||||
color: isDark ? DarkDesignTokens.text2 : DesignTokens.text2,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum _IssueLevel { important, warning, info }
|
||||
|
||||
class _KnownIssue {
|
||||
final String icon;
|
||||
final String title;
|
||||
final _IssueLevel level;
|
||||
final String description;
|
||||
|
||||
const _KnownIssue({
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.level,
|
||||
required this.description,
|
||||
});
|
||||
}
|
||||
|
||||
enum _PlanStatus { coming, dev, plan }
|
||||
|
||||
@@ -388,7 +388,10 @@ class _DataExportPageState extends State<DataExportPage> {
|
||||
final lastBracket = content.lastIndexOf(']');
|
||||
if (lastBracket >= 0 && lastBracket < content.length - 1) {
|
||||
final trailing = content.substring(lastBracket + 1).trim();
|
||||
if (trailing.isNotEmpty) {
|
||||
if (trailing.isNotEmpty &&
|
||||
!trailing.startsWith(',') &&
|
||||
!trailing.startsWith('}') &&
|
||||
!trailing.startsWith(']')) {
|
||||
debugPrint('🧹 检测到尾部脏数据(${trailing.length}字符),已截取有效JSON');
|
||||
content = content.substring(0, lastBracket + 1);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,10 @@ class DataExportService extends GetxService {
|
||||
final lastBracket = content.lastIndexOf(']');
|
||||
if (lastBracket >= 0 && lastBracket < content.length - 1) {
|
||||
final trailing = content.substring(lastBracket + 1).trim();
|
||||
if (trailing.isNotEmpty) {
|
||||
if (trailing.isNotEmpty &&
|
||||
!trailing.startsWith(',') &&
|
||||
!trailing.startsWith('}') &&
|
||||
!trailing.startsWith(']')) {
|
||||
debugPrint(
|
||||
'DataExportService: 检测到尾部脏数据(${trailing.length}字符),已截取有效JSON',
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user