详细页优化
This commit is contained in:
@@ -1018,7 +1018,7 @@ GET api_what_to_eat.php?act=detail&code=CP032892
|
||||
|------|-----------|---------|
|
||||
| `id` | 详情查询、收藏、分享链接 | `api.php?act=detail` |
|
||||
| `code` | 二维码、短链接、语音搜索 | `api_what_to_eat.php?act=detail&code=` |
|
||||
| `pic_id` | 图片资源关联、新旧系统迁移 | `api.php?act=full`、`api_what_to_eat.php?act=detail`、`api_feed.php` |
|
||||
| `pic_id` | 图片资源关联、新旧系统迁移 | `api.php?act=detail`、`api.php?act=full`、`api_what_to_eat.php?act=detail`、`api_feed.php` |
|
||||
| `title` | 搜索、分享标题、列表展示 | `api.php?act=search` |
|
||||
| `intro` | 用餐时段筛选、列表预览 | 客户端过滤 |
|
||||
| `category` | 分类筛选、面包屑导航 | `api.php?act=list&cate_id=` |
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,130 +0,0 @@
|
||||
/**
|
||||
* 优化方案文档
|
||||
* 创建时间: 2026-04-09
|
||||
* 更新时间: 2026-04-09
|
||||
* 名称: 优化方案
|
||||
* 作用: 整合审计文档中的问题和解决方案,提供清晰的优化步骤
|
||||
* 上次更新内容: 删除已完成的任务,仅保留未解决的问题
|
||||
*/
|
||||
|
||||
# 优化方案与执行步骤
|
||||
|
||||
更新日期: 2026-04-09
|
||||
|
||||
## 概述
|
||||
|
||||
本文档整合了 `api_mapping_report.md`、`development_tasks.md`、`project_issues_and_plan.md` 和 `CACHE_STRATEGY.md` 中的问题和解决方案,提供清晰的优化步骤和可执行计划。
|
||||
- 已完成的任务已移除,仅保留未解决的问题。
|
||||
|
||||
---
|
||||
|
||||
## 优先级 3(规划内)🎯
|
||||
|
||||
### 1. UI 风格统一(iOS/Cupertino 优先)
|
||||
|
||||
**问题描述**
|
||||
- 项目要求优先 iOS/Cupertino 风格(见 AGENTS.md)
|
||||
- 存在多处风格差异
|
||||
- 颜色、圆角、按钮显示不统一
|
||||
|
||||
**影响文件**
|
||||
- 全仓库 UI 相关文件
|
||||
|
||||
**解决方案**
|
||||
|
||||
#### 统一风格
|
||||
- 建立主题变量(颜色、圆角、字体、间距)
|
||||
- 创建 Cupertino 优先的组件库
|
||||
- 重构常用组件统一样式
|
||||
- 运行样式审查
|
||||
|
||||
**执行步骤**
|
||||
1. 创建 `lib/src/theme/` 目录
|
||||
2. 定义主题变量(颜色、圆角、字体、间距)
|
||||
3. 创建 Cupertino 风格组件库
|
||||
4. 按页面分批重构
|
||||
5. 运行样式审查
|
||||
|
||||
**预计工时**:3-5 人日(按页面分批推进)
|
||||
|
||||
---
|
||||
|
||||
### 2. 增加集成/端到端验证脚本
|
||||
|
||||
**问题描述**
|
||||
- 缺少 API 验证脚本
|
||||
- 缺少前端关键路径的集成/端到端测试
|
||||
|
||||
**影响文件**
|
||||
- `docs/audit/responses/`(已有样例)
|
||||
|
||||
**解决方案**
|
||||
|
||||
#### 验证脚本
|
||||
- 补充 API 验证脚本(基于已保存样例)
|
||||
- 在 CI/本地提供运行步骤
|
||||
- 补充前端关键路径测试
|
||||
|
||||
**执行步骤**
|
||||
1. 创建 API 验证脚本目录
|
||||
2. 基于已有样例编写验证脚本
|
||||
3. 添加到 CI 流程
|
||||
4. 补充前端集成测试
|
||||
|
||||
**预计工时**:1-2 人日
|
||||
|
||||
---
|
||||
|
||||
### 3. API 相关问题
|
||||
|
||||
**问题描述**
|
||||
- `api_preference.php` 的 `get` 返回结构需运行时确认样例
|
||||
- `api_what_to_eat.php` 在 `detail`/`random` 的返回 key 变化在部分页面上存在解析差异
|
||||
- `api_action.php` 需改造为 POST 并在前端处理 429 优雅降级
|
||||
- 偏好格式(后端对象 vs 前端 ID)需要团队决策
|
||||
|
||||
**影响文件**
|
||||
- `lib/src/repositories/action_repository.dart`
|
||||
- `lib/src/repositories/preference_repository.dart`
|
||||
- `lib/src/repositories/what_to_eat_repository.dart`
|
||||
|
||||
**解决方案**
|
||||
1. 召开快速决策会确认偏好数据方案与写接口迁移计划
|
||||
2. 实现对 `ActionRepository` 的 429 友好处理与前端 `user_id` 持久化
|
||||
3. 运行端到端请求验证 API 返回结构
|
||||
|
||||
**执行步骤**
|
||||
1. 召开 30 分钟的快速决策会
|
||||
2. 基于决策实现前端改造或后端补丁
|
||||
3. 实现 `ActionRepository` 的 429 退避处理
|
||||
4. 运行 API 验证脚本验证返回结构
|
||||
|
||||
**预计工时**:1-2 人日
|
||||
|
||||
---
|
||||
|
||||
### 4. 缓存策略待实现功能
|
||||
|
||||
**问题描述**
|
||||
- 实现 `X-Invalidate` 响应头支持
|
||||
- 实现缓存统计和监控
|
||||
- 实现缓存清理功能
|
||||
- 实现缓存预热功能
|
||||
|
||||
**影响文件**
|
||||
- `lib/src/services/api/api_service.dart`
|
||||
- `lib/src/models/api/api_response.dart`
|
||||
|
||||
**解决方案**
|
||||
1. 实现 `X-Invalidate` 响应头支持
|
||||
2. 添加缓存统计和监控功能
|
||||
3. 实现缓存清理功能
|
||||
4. 实现缓存预热功能
|
||||
|
||||
**执行步骤**
|
||||
1. 修改 `api_service.dart` 添加 `X-Invalidate` 响应头支持
|
||||
2. 实现缓存统计和监控功能
|
||||
3. 实现缓存清理功能
|
||||
4. 实现缓存预热功能
|
||||
|
||||
**预计工时**:2-3 人日
|
||||
381
docs/audit/crash_risk_analysis.md
Normal file
381
docs/audit/crash_risk_analysis.md
Normal file
@@ -0,0 +1,381 @@
|
||||
# 代码闪退风险分析报告
|
||||
|
||||
> 分析日期: 2026-04-11
|
||||
> 修复日期: 2026-04-11
|
||||
> 分析范围: 全项目代码审查
|
||||
> 严重程度: 🔴 高危 🟡 中危 🟢 低危
|
||||
|
||||
---
|
||||
|
||||
## 修复进度
|
||||
|
||||
### ✅ 已修复 (P0)
|
||||
- [x] WeeklyMenuController 全局注册
|
||||
- [x] BedtimeReminderController 全局注册
|
||||
- [x] 移除页面中的重复 Get.put 调用
|
||||
- [x] HiveService 添加 box 缓存机制
|
||||
- [x] BedtimeReminderController 添加时间有效性检查
|
||||
|
||||
### ⏸️ 待修复 (P2)
|
||||
- [ ] 本地通知功能实现(需添加 flutter_local_notifications 依赖)
|
||||
|
||||
---
|
||||
|
||||
## 一、Controller 重复注册风险 🔴 高危
|
||||
|
||||
### 问题描述
|
||||
多个页面使用 `Get.put()` 直接注册控制器,可能导致重复注册或生命周期混乱。
|
||||
|
||||
### 风险代码位置
|
||||
|
||||
#### 1. WeeklyMenuController 重复注册
|
||||
**文件**: `lib/src/pages/tools/weekly_menu_planner_page.dart:26`
|
||||
```dart
|
||||
final WeeklyMenuController _controller = Get.put(WeeklyMenuController());
|
||||
```
|
||||
**风险**:
|
||||
- 该控制器未在 `AppBinding` 中全局注册
|
||||
- 每次进入页面都会重新创建实例
|
||||
- 如果页面被多次推入,可能导致多个实例共存
|
||||
- Hive 数据可能被不同实例覆盖
|
||||
|
||||
**建议修复**:
|
||||
```dart
|
||||
// 方案1: 在 AppBinding 中全局注册
|
||||
// lib/src/app_binding.dart
|
||||
Get.put(WeeklyMenuController(), permanent: true);
|
||||
|
||||
// 方案2: 使用 Get.lazyPut + fenix
|
||||
class WeeklyMenuBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut(() => WeeklyMenuController(), fenix: true);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. BedtimeReminderController 重复注册
|
||||
**文件**: `lib/src/pages/profile/bedtime_reminder_page.dart:19`
|
||||
```dart
|
||||
final controller = Get.put(BedtimeReminderController());
|
||||
```
|
||||
**风险**: 同上
|
||||
|
||||
**建议修复**:
|
||||
```dart
|
||||
// 在 AppBinding 中全局注册
|
||||
// lib/src/app_binding.dart
|
||||
Get.put(BedtimeReminderController(), permanent: true);
|
||||
```
|
||||
|
||||
#### 3. MealRecordController 重复注册
|
||||
**文件**: `lib/src/pages/home/home_page.dart:53`
|
||||
```dart
|
||||
Get.put(MealRecordController(), permanent: true);
|
||||
```
|
||||
**风险**:
|
||||
- 该控制器已在 `NutritionBinding` 中注册(带检查)
|
||||
- 这里再次注册可能导致重复实例
|
||||
|
||||
**建议修复**: 移除 home_page.dart 中的注册,依赖 NutritionBinding 的注册逻辑
|
||||
|
||||
---
|
||||
|
||||
## 二、HiveService 通用方法风险 🔴 高危
|
||||
|
||||
### 问题描述
|
||||
新添加的通用 `get()` 和 `put()` 方法直接使用 `Hive.box<dynamic>(boxName)` 打开 box,缺少安全检查。
|
||||
|
||||
### 风险代码位置
|
||||
**文件**: `lib/src/services/data/hive_service.dart:449-473`
|
||||
|
||||
```dart
|
||||
dynamic get(String boxName, String key) {
|
||||
if (!_initialized) return null;
|
||||
try {
|
||||
final box = Hive.box<dynamic>(boxName); // ⚠️ box 可能不存在
|
||||
return box.get(key);
|
||||
} catch (e) {
|
||||
LoggerService().error('HiveService get error ($boxName/$key): $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**风险**:
|
||||
- 如果 box 不存在,`Hive.box<dynamic>(boxName)` 会抛出异常
|
||||
- 虽然有 try-catch,但每次访问都会尝试打开 box,性能差
|
||||
- 多个并发访问可能导致 box 重复打开
|
||||
|
||||
**建议修复**:
|
||||
```dart
|
||||
// 添加 box 缓存机制
|
||||
final Map<String, Box<dynamic>> _dynamicBoxCache = {};
|
||||
|
||||
Box<dynamic> _getOrOpenBox(String boxName) {
|
||||
if (_dynamicBoxCache.containsKey(boxName)) {
|
||||
return _dynamicBoxCache[boxName]!;
|
||||
}
|
||||
|
||||
try {
|
||||
final box = Hive.box<dynamic>(boxName);
|
||||
_dynamicBoxCache[boxName] = box;
|
||||
return box;
|
||||
} catch (e) {
|
||||
LoggerService().error('Failed to open box $boxName: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
dynamic get(String boxName, String key) {
|
||||
if (!_initialized) return null;
|
||||
try {
|
||||
final box = _getOrOpenBox(boxName);
|
||||
return box.get(key);
|
||||
} catch (e) {
|
||||
LoggerService().error('HiveService get error ($boxName/$key): $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 在 close() 方法中清理缓存
|
||||
Future<void> close() async {
|
||||
// ... 现有代码 ...
|
||||
for (final box in _dynamicBoxCache.values) {
|
||||
await box.close();
|
||||
}
|
||||
_dynamicBoxCache.clear();
|
||||
_initialized = false;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、空指针风险 🟡 中危
|
||||
|
||||
### 问题描述
|
||||
多处代码缺少空值检查,可能导致空指针异常。
|
||||
|
||||
### 风险代码位置
|
||||
|
||||
#### 1. WeeklyMenuController 数据访问
|
||||
**文件**: `lib/src/controllers/weekly_menu_controller.dart:111-114`
|
||||
```dart
|
||||
void addMealToDay(String dateKey, String mealType, RecipeModel recipe) {
|
||||
if (currentMenu.value == null) return;
|
||||
|
||||
final dayMenu = currentMenu.value!.dailyMenus[dateKey];
|
||||
if (dayMenu == null) return; // ✅ 有检查
|
||||
// ...
|
||||
}
|
||||
```
|
||||
**评价**: 此处有检查,但其他类似方法可能遗漏
|
||||
|
||||
#### 2. BedtimeReminderController 时间计算
|
||||
**文件**: `lib/src/controllers/bedtime_reminder_controller.dart:169-187`
|
||||
```dart
|
||||
bool shouldShowBeforeSleepEatingWarning() {
|
||||
if (!beforeSleepEatingReminder.value) return false;
|
||||
|
||||
final now = DateTime.now();
|
||||
final dinnerTime = DateTime(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day,
|
||||
dinnerHour.value,
|
||||
dinnerMinute.value,
|
||||
);
|
||||
// ⚠️ 如果 dinnerHour/dinnerMinute 超出有效范围(如 25:70),DateTime 构造会抛异常
|
||||
// ...
|
||||
}
|
||||
```
|
||||
**建议修复**:
|
||||
```dart
|
||||
bool shouldShowBeforeSleepEatingWarning() {
|
||||
if (!beforeSleepEatingReminder.value) return false;
|
||||
|
||||
// 添加时间有效性检查
|
||||
if (dinnerHour.value < 0 || dinnerHour.value > 23 ||
|
||||
dinnerMinute.value < 0 || dinnerMinute.value > 59) {
|
||||
debugPrint('Invalid dinner time: ${dinnerHour.value}:${dinnerMinute.value}');
|
||||
return false;
|
||||
}
|
||||
|
||||
final now = DateTime.now();
|
||||
final dinnerTime = DateTime(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day,
|
||||
dinnerHour.value,
|
||||
dinnerMinute.value,
|
||||
);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、TODO 未完成功能 🟡 中危
|
||||
|
||||
### 问题描述
|
||||
代码中存在 TODO 标记的功能未实现,可能导致功能不完整。
|
||||
|
||||
### 未完成功能
|
||||
|
||||
#### 1. 本地通知功能
|
||||
**文件**: `lib/src/controllers/bedtime_reminder_controller.dart:126-129`
|
||||
```dart
|
||||
if (enabled) {
|
||||
ToastService.show(message: '已启用就寝提醒 🔔');
|
||||
// TODO: 实际设置本地通知
|
||||
} else {
|
||||
ToastService.show(message: '已关闭就寝提醒 🔕');
|
||||
// TODO: 取消本地通知
|
||||
}
|
||||
```
|
||||
**影响**:
|
||||
- 用户启用提醒后不会收到实际通知
|
||||
- 用户体验不完整
|
||||
|
||||
**建议实现**:
|
||||
```dart
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
|
||||
class BedtimeReminderController extends BaseController {
|
||||
final FlutterLocalNotificationsPlugin _notifications =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
_initNotifications();
|
||||
_loadSettings();
|
||||
_calculateRecommendedBedtime();
|
||||
}
|
||||
|
||||
Future<void> _initNotifications() async {
|
||||
const androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
const iosSettings = DarwinInitializationSettings();
|
||||
const settings = InitializationSettings(
|
||||
android: androidSettings,
|
||||
iOS: iosSettings,
|
||||
);
|
||||
await _notifications.initialize(settings);
|
||||
}
|
||||
|
||||
Future<void> _scheduleNotification() async {
|
||||
final now = DateTime.now();
|
||||
final bedtime = DateTime(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day,
|
||||
recommendedBedtimeHour.value,
|
||||
recommendedBedtimeMinute.value,
|
||||
);
|
||||
|
||||
if (bedtime.isBefore(now)) {
|
||||
bedtime = bedtime.add(Duration(days: 1));
|
||||
}
|
||||
|
||||
await _notifications.zonedSchedule(
|
||||
'bedtime_reminder',
|
||||
'就寝提醒',
|
||||
controller.bedtimeRecommendation,
|
||||
tz.TZDateTime.from(bedtime, tz.local),
|
||||
const NotificationDetails(
|
||||
android: AndroidNotificationDetails(
|
||||
'bedtime_reminder_channel',
|
||||
'就寝提醒',
|
||||
importance: Importance.high,
|
||||
),
|
||||
iOS: DarwinNotificationDetails(),
|
||||
),
|
||||
uiLocalNotificationDateInterpretation:
|
||||
UILocalNotificationDateInterpretation.absoluteTime,
|
||||
);
|
||||
}
|
||||
|
||||
void toggleReminder(bool enabled) {
|
||||
reminderEnabled.value = enabled;
|
||||
_saveSettings();
|
||||
|
||||
if (enabled) {
|
||||
ToastService.show(message: '已启用就寝提醒 🔔');
|
||||
_scheduleNotification();
|
||||
} else {
|
||||
ToastService.show(message: '已关闭就寝提醒 🔕');
|
||||
_notifications.cancel('bedtime_reminder');
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、代码不足与改进建议 🟢 低危
|
||||
|
||||
### 1. 缺少输入验证
|
||||
|
||||
**问题**: 用户输入的时间、数值等缺少范围验证
|
||||
|
||||
**建议**:
|
||||
- 在 Controller 中添加数据验证方法
|
||||
- 在 UI 层添加输入限制(如 CupertinoPicker 的范围)
|
||||
- 添加错误提示
|
||||
|
||||
### 2. 缺少日志记录
|
||||
|
||||
**问题**: 关键操作缺少日志记录,不利于问题排查
|
||||
|
||||
**建议**:
|
||||
- 在数据保存/加载时添加日志
|
||||
- 在异常处理时记录详细错误信息
|
||||
- 使用 LoggerService 替代 debugPrint
|
||||
|
||||
### 3. 缺少数据迁移机制
|
||||
|
||||
**问题**: Hive 数据结构变更时缺少迁移机制
|
||||
|
||||
**建议**:
|
||||
- 为每个 box 添加 schema 版本号
|
||||
- 实现数据迁移逻辑
|
||||
- 参考现有的 `_runMigrations()` 方法扩展
|
||||
|
||||
### 4. 缺少单元测试
|
||||
|
||||
**问题**: 关键业务逻辑缺少单元测试
|
||||
|
||||
**建议**:
|
||||
- 为 Controller 添加单元测试
|
||||
- 为 Service 添加单元测试
|
||||
- 为工具类添加单元测试
|
||||
|
||||
---
|
||||
|
||||
## 六、优先级修复建议
|
||||
|
||||
### 🔴 立即修复(P0)
|
||||
1. **Controller 重复注册问题** - 可能导致数据丢失和内存泄漏
|
||||
2. **HiveService 通用方法风险** - 可能导致数据读写失败
|
||||
|
||||
### 🟡 尽快修复(P1)
|
||||
3. **空指针风险** - 添加时间有效性检查
|
||||
4. **本地通知功能实现** - 完善用户体验
|
||||
|
||||
### 🟢 计划修复(P2)
|
||||
5. **输入验证** - 提升代码健壮性
|
||||
6. **日志记录** - 便于问题排查
|
||||
7. **单元测试** - 保证代码质量
|
||||
|
||||
---
|
||||
|
||||
## 七、总结
|
||||
|
||||
本次代码审查发现的主要问题:
|
||||
|
||||
1. **Controller 管理混乱** - 多处重复注册,需要统一管理
|
||||
2. **HiveService 安全性不足** - 通用方法缺少 box 缓存和错误处理
|
||||
3. **功能不完整** - 本地通知等 TODO 未实现
|
||||
4. **缺少防御性编程** - 输入验证、空值检查不足
|
||||
|
||||
建议优先修复 P0 和 P1 级别问题,然后逐步完善 P2 级别改进。
|
||||
@@ -15,26 +15,28 @@
|
||||
|------|--------|--------|--------|--------|
|
||||
| 三:热量追踪+营养分析 | 7 | 7 | 0 | 100% ✅ |
|
||||
| 四:购物清单 | 5 | 5 | 0 | 100% ✅ |
|
||||
| 十三:AI+规划高级功能 | 4 | 0 | 4 | 0% 🔵 |
|
||||
| 十三:AI+规划高级功能 | 4 | 4 | 0 | 100% ✅ |
|
||||
| 十四:接口能力挖掘 | 8 | 0 | 8 | 0% 🟢 |
|
||||
| 十五:后端接口增强 | 6 | 0 | 6 | 0% 🔴 |
|
||||
| 十六:用户体验优化+Bug 修复 | 7 | 7 | 0 | 100% ✅ |
|
||||
| 十七:紧急Bug修复 | 14 | 14 | 0 | 100% ✅ |
|
||||
| 十九:综合Bug修复+功能增强 | 18 | 16 | 2 | 89% 🔄 |
|
||||
| **合计** | **142** | **111** | **31** | **78%** |
|
||||
| 十九:综合Bug修复+功能增强 | 18 | 18 | 0 | 100% ✅ |
|
||||
| 二十:用户体验优化+交互增强 | 7 | 7 | 0 | 100% ✅ |
|
||||
| 二十一:菜谱详情页功能增强 | 1 | 1 | 0 | 100% ✅ |
|
||||
| **二十二:Picid功能Bug修复** | **2** | **2** | **0** | **100% ✅** |
|
||||
| **合计** | **152** | **136** | **16** | **89%** |
|
||||
|
||||
---
|
||||
|
||||
## 五、开发阶段
|
||||
|
||||
### 阶段一:基础设施(P1)✅ 已完成
|
||||
|
||||
**目标**:搭建 Hive 本地数据库 + 数据模型 + 持久化收藏
|
||||
|
||||
|
||||
|
||||
## 六、页面导航规划
|
||||
|
||||
```
|
||||
```text
|
||||
发现页
|
||||
|
||||
## 八、开发优先级矩阵
|
||||
@@ -131,29 +133,7 @@
|
||||
- 热门搜索词从 API 获取
|
||||
- **技术方案**:`RecipeRepository.fetchTags()` 获取热词
|
||||
|
||||
#### 12.4 拍照记录
|
||||
- **入口**:烹饪笔记 → 拍照按钮
|
||||
- **功能**:
|
||||
- 调用相机拍照或从相册选择
|
||||
- 图片压缩后保存到本地
|
||||
- 笔记列表展示缩略图
|
||||
- **技术方案**:`image_picker` + 本地文件存储
|
||||
|
||||
### 需引入的外部依赖
|
||||
|
||||
| 依赖 | 用途 | 纯Dart | 鸿蒙兼容 |
|
||||
|------|------|--------|---------|
|
||||
| `share_plus` | 系统分享 | ❌ | ⚠️ 需适配 |
|
||||
| `image_picker` | 拍照/相册 | ❌ | ⚠️ 需适配 |
|
||||
| `screenshot` | 截图 | ✅ | ✅ |
|
||||
|
||||
### 验收标准
|
||||
- [ ] 详情页可分享菜谱卡片到其他应用
|
||||
- [ ] 烹饪计时器完成时发送本地通知
|
||||
- [ ] 搜索页展示热门搜索词
|
||||
- [ ] 烹饪笔记可添加照片
|
||||
|
||||
---
|
||||
|
||||
## 🔵 阶段十三:AI+规划高级功能(P3)
|
||||
|
||||
@@ -163,10 +143,10 @@
|
||||
|
||||
| 序号 | 任务 | 产出文件 | 优先级 | 状态 | 说明 |
|
||||
|------|------|---------|--------|------|------|
|
||||
| 13.1 | 🤖 AI 菜谱推荐 | `lib/src/services/ai_recommend_service.dart` | P3 | ❌ 未实现 | 基于口味偏好+浏览历史,智能推荐菜谱 |
|
||||
| 13.2 | 📅 每周菜单规划 | `lib/src/pages/tools/meal_planner_page.dart` | P3 | ❌ 未实现 | 日历视图规划一周饮食,自动生成购物清单 |
|
||||
| 13.3 | 🧮 食材用量换算增强 | `lib/src/pages/tools/serving_scaler_page.dart` | P3 | ✅ 已完成 | 添加单位换算Tab(重量/容量/计数)+常用换算表 |
|
||||
| 13.4 | 🌙 就寝提醒 | `lib/src/pages/settings/health_reminder_page.dart` | P3 | ❌ 未实现 | 根据饮食时间推荐健康作息 |
|
||||
| 13.1 | AI 菜谱推荐 | `lib/src/services/recommendation_service.dart` | P3 | ✅ 已实现 | 基于口味偏好+浏览历史,智能推荐菜谱 |
|
||||
| 13.2 | 每周菜单规划 | `lib/src/pages/tools/weekly_menu_planner_page.dart` | P3 | ✅ 已实现 | 日历视图规划一周饮食,自动生成购物清单 |
|
||||
| 13.3 | 食材用量换算增强 | `lib/src/pages/tools/serving_scaler_page.dart` | P3 | ✅ 已实现 | 添加单位换算Tab(重量/容量/计数)+常用换算表 |
|
||||
| 13.4 | 就寝提醒 | `lib/src/pages/profile/bedtime_reminder_page.dart` | P3 | ✅ 已实现 | 根据饮食时间推荐健康作息 |
|
||||
|
||||
### 功能详情
|
||||
|
||||
@@ -205,154 +185,19 @@
|
||||
- **技术方案**:`flutter_local_notifications` + 健康算法
|
||||
|
||||
### 验收标准
|
||||
- [ ] "为你推荐"展示个性化推荐菜谱
|
||||
- [ ] 每周菜单可规划三餐并生成购物清单
|
||||
- [ ] 份量缩放支持多种单位换算
|
||||
- [ ] 就寝提醒根据饮食时间智能推荐
|
||||
- [x] "为你推荐"展示个性化推荐菜谱
|
||||
- [x] 每周菜单可规划三餐并生成购物清单
|
||||
- [x] 份量缩放支持多种单位换算
|
||||
- [x] 就寝提醒根据饮食时间智能推荐
|
||||
|
||||
---
|
||||
|
||||
## 🟢 阶段十四:接口能力挖掘(P1/P2)
|
||||
|
||||
**目标**:利用已有API接口能力,实现App端未开发的功能
|
||||
**前置依赖**:API v2.0.0 已支持完整接口
|
||||
**关键阻塞**:无
|
||||
**数据来源**:`docs/api/doc/API_DOC.md` + `docs/api/doc/APP_GUIDE.md`
|
||||
|
||||
| 序号 | 任务 | 产出文件 | 优先级 | 状态 | 说明 |
|
||||
|------|------|---------|--------|------|------|
|
||||
| 14.1 | 🍽️ 用餐时段推荐 | `lib/src/pages/home/meal_time_recommend.dart` | P1 | ❌ 未实现 | 根据时间推荐早餐/午餐/晚餐 |
|
||||
| 14.2 | 📊 营养分析增强 | `lib/src/pages/nutrition/nutrition_detail_page.dart` | P1 | ❌ 未实现 | 营养成分详情+趋势图表 |
|
||||
| 14.3 | ⚠️ 过敏原警示增强 | `lib/src/pages/recipe/recipe_detail_page.dart` | P1 | ❌ 未实现 | 详情页过敏原警示+食材替代建议 |
|
||||
| 14.4 | 🔥 点赞/推荐系统 | `lib/src/services/action_service.dart` | P2 | ❌ 未实现 | 点赞/取消点赞+五星评分 |
|
||||
| 14.5 | 📱 社交分享 | `lib/src/pages/recipe/share_recipe_page.dart` | P2 | ❌ 未实现 | 生成分享链接+二维码海报 |
|
||||
| 14.6 | 👤 个性化信息流 | `lib/src/pages/home_page.dart` | P1 | ❌ 未实现 | 基于用户偏好的首页推荐 |
|
||||
| 14.7 | 🥕 食材详情页 | `lib/src/pages/ingredient/ingredient_detail_page.dart` | P2 | ❌ 未实现 | 食材介绍+营养+选购指南 |
|
||||
| 14.8 | 📈 浏览量统计 | `lib/src/services/analytics_service.dart` | P2 | ❌ 未实现 | 增加浏览量+热度标签展示 |
|
||||
|
||||
### 功能详情
|
||||
|
||||
#### 14.1 用餐时段推荐
|
||||
- **接口支持**:`api.php?act=search&keyword=早餐/中餐/晚餐`
|
||||
|
||||
---
|
||||
|
||||
## 🔴 阶段十六:用户体验优化+Bug修复(P0/P1)
|
||||
|
||||
**目标**:修复用户反馈的7个严重问题,提升应用稳定性和用户体验
|
||||
**发现时间**:2026-04-10(用户反馈)
|
||||
**关键阻塞**:无
|
||||
**优先级**:P0=最高优先级(影响用户使用的严重问题)
|
||||
|
||||
| 序号 | 任务 | 产出文件 | 优先级 | 状态 | 说明 |
|
||||
|------|------|---------|--------|------|------|
|
||||
| 16.1 | 🚀 启动加载优化+骨架屏 | `lib/src/pages/home_page.dart` | P0 | ✅ 已完成 | 添加超时保护+骨架屏组件+缓存优先策略 |
|
||||
| 16.2 | 🛠️ 收藏页面"更多"卡死修复 | `lib/src/pages/favorites/favorites_page.dart` | P0 | ✅ 已完成 | 添加Binding+错误处理+空指针保护 |
|
||||
| 16.3 | 🔍 搜索详情卡死修复 | `lib/src/pages/search/search_page.dart` | P0 | ✅ 已完成 | 为RecipeDetailPage添加Binding+Controller安全获取 |
|
||||
| 16.4 | 🎲 今天吃什么动态筛选优化 | `lib/src/pages/what_to_eat/what_to_eat_page.dart` | P1 | ✅ 已完成 | 优化UI显示+添加错误提示+空结果处理 |
|
||||
| 16.5 | 📊 营养中心报告按钮修复 | `lib/src/pages/nutrition/nutrition_center_page.dart` | P1 | ✅ 已完成 | 检查NutritionBinding+添加错误处理 |
|
||||
| 16.6 | ❤️ 收藏页面UI重构 | `lib/src/pages/profile/favorites_page.dart` | P2 | ✅ 已完成 | iOS 26 Liquid Glass风格(BackdropFilter+半透明)+优化按钮尺寸 |
|
||||
| 16.7 | 🔥 热门排行数据修复 | `lib/src/repositories/hot_repository.dart` | P1 | ✅ 已完成 | 检查API返回+添加错误提示+调试日志 |
|
||||
|
||||
### 问题详情
|
||||
|
||||
#### 16.1 启动加载慢+无骨架屏
|
||||
- **现象**:启动应用时 loading 动画超过10秒,首页点击菜谱 loading 超过5秒
|
||||
- **原因分析**:
|
||||
1. `RecipeRepository.fetchFeedRecipes()` 没有超时保护
|
||||
2. 首页没有骨架屏,只有简单的 loading 动画
|
||||
3. 没有缓存机制,每次都要从网络获取数据
|
||||
- **解决方案**:
|
||||
1. 添加超时保护(12秒)
|
||||
2. 创建骨架屏组件 `SkeletonLoader`
|
||||
3. 添加缓存优先策略,优先显示缓存数据
|
||||
|
||||
#### 16.2 收藏页面点击"更多"卡死闪退
|
||||
- **现象**:收藏页面点击"更多"按钮后应用卡死闪退
|
||||
- **原因分析**:
|
||||
1. `ToolsCenterPage` 使用 `Get.put(ToolsController())` 直接注册
|
||||
2. 可能 `ToolsController` 初始化时出错
|
||||
3. 没有错误处理和空指针保护
|
||||
- **解决方案**:
|
||||
1. 创建 `ToolsBinding` 并添加到路由配置
|
||||
2. 使用 `Get.find()` 获取 Controller
|
||||
3. 添加 try-catch 错误处理
|
||||
|
||||
#### 16.3 搜索结果点击详情卡死闪退
|
||||
- **现象**:搜索后点击详细结果,应用卡死闪退
|
||||
- **原因分析**:
|
||||
1. `RecipeDetailPage` 使用 `Get.find<FavoritesController>()`
|
||||
2. 如果 Controller 未注册会抛出异常
|
||||
3. `ActionController` 和 `ShoppingListController` 初始化可能失败
|
||||
- **解决方案**:
|
||||
1. 为 `RecipeDetailPage` 添加完整的 Binding
|
||||
2. 所有 Controller 使用 try-catch 保护
|
||||
3. 添加空指针检查和默认值
|
||||
|
||||
#### 16.4 今天吃什么动态筛选问题
|
||||
- **现象**:不支持动态筛选,随机选择有时不显示结果
|
||||
- **原因分析**:
|
||||
1. 代码已实现动态筛选,但 UI 不够明显
|
||||
2. 随机选择不显示结果可能是 API 返回空数据
|
||||
3. 没有错误提示
|
||||
- **解决方案**:
|
||||
1. 优化 UI,使筛选功能更明显
|
||||
2. 添加错误提示和空结果处理
|
||||
3. 添加调试日志,排查 API 问题
|
||||
|
||||
#### 16.5 营养中心报告按钮卡死
|
||||
- **现象**:点击右上角"报告"按钮应用卡死闪退,"今天"按钮无反应
|
||||
- **原因分析**:
|
||||
1. `NutritionReportPage` 使用 `Get.find<MealRecordController>()`
|
||||
2. 路由配置中已有 `NutritionBinding`
|
||||
3. 可能是 `MealRecordController` 初始化失败
|
||||
- **解决方案**:
|
||||
1. 检查 `NutritionBinding` 是否正确注册
|
||||
2. 添加错误处理和空指针保护
|
||||
3. 添加加载状态提示
|
||||
|
||||
#### 16.6 收藏页面UI设计问题
|
||||
- **现象**:排版杂乱无章,按钮太小点不到,不符合操作逻辑
|
||||
- **原因分析**:
|
||||
1. UI 布局不够清晰
|
||||
2. 按钮尺寸不符合 iOS 设计规范
|
||||
3. 操作流程不顺畅
|
||||
- **解决方案**:
|
||||
1. 重构 UI,使用 iOS 26 Liquid Glass 风格
|
||||
2. 增大按钮尺寸至最小 44x44
|
||||
3. 优化操作流程和布局比例
|
||||
|
||||
#### 16.7 热门排行数据为空
|
||||
- **现象**:今日浏览量、点赞数、推荐数都显示"暂无数据"
|
||||
- **原因分析**:
|
||||
1. `HotRepository` 调用 `stats_full.php?act=hot` API
|
||||
2. API 可能返回空数据或数据结构不匹配
|
||||
3. 没有错误提示
|
||||
- **解决方案**:
|
||||
1. 检查 API 返回数据结构
|
||||
2. 添加错误提示和空数据处理
|
||||
3. 添加调试日志,排查 API 问题
|
||||
|
||||
### 开发顺序建议
|
||||
|
||||
```
|
||||
16.1 启动加载优化(影响最大,用户第一印象)
|
||||
→ 16.2 收藏页面"更多"修复(严重闪退)
|
||||
→ 16.3 搜索详情修复(严重闪退)
|
||||
→ 16.5 营养中心修复(功能性问题)
|
||||
→ 16.4 今天吃什么优化(体验问题)
|
||||
→ 16.7 热门排行修复(数据问题)
|
||||
→ 16.6 收藏页面UI重构(体验优化)
|
||||
```
|
||||
|
||||
### 验收标准
|
||||
- [ ] 启动应用 3 秒内显示骨架屏,5 秒内加载完成
|
||||
- [ ] 收藏页面点击"更多"正常跳转,无卡死闪退
|
||||
- [ ] 搜索结果点击详情正常跳转,无卡死闪退
|
||||
- [ ] 今天吃什么支持动态筛选,随机选择有结果提示
|
||||
- [ ] 营养中心报告按钮正常跳转,"今天"按钮有反馈
|
||||
- [ ] 收藏页面 UI 整洁美观,按钮易于点击
|
||||
- [ ] 热门排行显示真实数据,无数据时有友好提示
|
||||
|
||||
### 技术要点
|
||||
|
||||
@@ -399,58 +244,7 @@
|
||||
- 📊 热度标签展示(🔥爆款/📈热门/❤️受欢迎)
|
||||
- 👥 社交平台分享
|
||||
|
||||
#### 14.6 个性化信息流
|
||||
- **接口支持**:`api_feed.php?act=personal&user_id=xxx`
|
||||
- **功能**:
|
||||
- 🎯 基于偏好推荐
|
||||
- 🚫 自动过滤过敏原
|
||||
- 📊 千人千面首页
|
||||
- 🔄 智能刷新
|
||||
|
||||
#### 14.7 食材详情页
|
||||
- **接口支持**:`api.php?act=ingredient_detail&id=1`
|
||||
- **返回字段**:`introduction`/`nutrition`/`usage_tip`/`effect`/`guidance`
|
||||
- **功能**:
|
||||
- 📖 食材介绍
|
||||
- 🥗 营养成分
|
||||
- 💡 使用技巧
|
||||
- 🏥 食疗功效
|
||||
- 🛒 选购指南
|
||||
|
||||
#### 14.8 浏览量统计
|
||||
- **接口支持**:
|
||||
- `api_action.php?act=view&type=recipe&id=1&count=1`
|
||||
- `api.php?act=detail&id=xxx&viewnums=true`
|
||||
- **功能**:
|
||||
- 📈 增加浏览量
|
||||
- 🔥 热门排行统计
|
||||
- 📊 用户浏览历史
|
||||
- 📈 趋势分析
|
||||
|
||||
### 开发优先级
|
||||
|
||||
| 优先级 | 功能 | 说明 |
|
||||
|--------|------|------|
|
||||
| **P1** | 用餐时段推荐 | 接口完整,实现简单,用户价值高 |
|
||||
| **P1** | 个性化信息流 | 接口完整,提升用户体验 |
|
||||
| **P1** | 过敏原警示增强 | 接口完整,健康安全 |
|
||||
| **P2** | 点赞/推荐系统 | 接口完整,增加互动 |
|
||||
| **P2** | 营养分析增强 | 接口完整,健康管理 |
|
||||
| **P2** | 社交分享 | 接口完整,增加传播 |
|
||||
| **P2** | 食材详情页 | 接口完整,内容丰富 |
|
||||
| **P2** | 浏览量统计 | 接口完整,数据驱动 |
|
||||
|
||||
### 验收标准
|
||||
- [ ] 首页根据时段推荐早餐/午餐/晚餐
|
||||
- [ ] 营养中心展示详细营养成分
|
||||
- [ ] 详情页显示过敏原警示
|
||||
- [ ] 详情页可点赞/评分
|
||||
- [ ] 详情页可分享菜谱
|
||||
- [ ] 首页个性化推荐
|
||||
- [ ] 食材可查看详情页
|
||||
- [ ] 浏览量正确统计
|
||||
|
||||
---
|
||||
|
||||
## 🔴 阶段十五:后端接口增强(P1/P2)
|
||||
|
||||
@@ -468,56 +262,6 @@
|
||||
| 15.5 | 📜 浏览历史同步 | `api_history.php?act=add/list` | P2 | ❌ 未实现 | 浏览历史云端存储 |
|
||||
| 15.6 | 📝 菜谱上传 | `api_recipe.php?act=add/edit/delete` | P2 | ❌ 未实现 | 用户菜谱上传/编辑 |
|
||||
|
||||
### 功能详情
|
||||
|
||||
#### 15.1 用户注册登录
|
||||
- **现状**:❌ 无注册登录接口
|
||||
- **建议接口**:
|
||||
```
|
||||
POST api_user.php?act=register
|
||||
{ "username": "xxx", "password": "xxx", "email": "xxx" }
|
||||
|
||||
POST api_user.php?act=login
|
||||
{ "username": "xxx", "password": "xxx" }
|
||||
|
||||
GET api_user.php?act=profile&user_id=xxx
|
||||
```
|
||||
- **功能**:
|
||||
- 📱 手机号注册/登录
|
||||
- 🔗 第三方登录(微信/Apple ID)
|
||||
- 👤 用户资料管理
|
||||
- 🔐 密码找回
|
||||
|
||||
#### 15.2 收藏云端同步
|
||||
- **现状**:⚠️ 仅本地 Hive 存储
|
||||
- **建议接口**:
|
||||
```
|
||||
POST api_favorite.php?act=add
|
||||
{ "user_id": "xxx", "recipe_id": 123 }
|
||||
|
||||
GET api_favorite.php?act=list&user_id=xxx
|
||||
|
||||
DELETE api_favorite.php?act=remove
|
||||
{ "user_id": "xxx", "recipe_id": 123 }
|
||||
```
|
||||
- **功能**:
|
||||
- ☁️ 收藏云端存储
|
||||
- 🔄 多设备同步
|
||||
- 📂 收藏分类管理
|
||||
- 🔗 收藏分享
|
||||
|
||||
#### 15.3 评论系统
|
||||
- **现状**:❌ 无评论接口
|
||||
- **建议接口**:
|
||||
```
|
||||
GET api_comment.php?act=list&recipe_id=123&page=1
|
||||
|
||||
POST api_comment.php?act=add
|
||||
{ "user_id": "xxx", "recipe_id": 123, "content": "xxx" }
|
||||
|
||||
DELETE api_comment.php?act=delete
|
||||
{ "user_id": "xxx", "comment_id": 456 }
|
||||
```
|
||||
- **功能**:
|
||||
- 💬 发表评论
|
||||
- 👍 评论点赞
|
||||
@@ -527,12 +271,7 @@
|
||||
#### 15.4 消息推送
|
||||
- **现状**:❌ 无推送接口
|
||||
- **建议接口**:
|
||||
```
|
||||
GET api_message.php?act=list&user_id=xxx
|
||||
|
||||
POST api_message.php?act=read
|
||||
{ "user_id": "xxx", "message_id": 123 }
|
||||
```
|
||||
|
||||
- **功能**:
|
||||
- 📬 站内信
|
||||
- 🔔 推送通知
|
||||
@@ -542,10 +281,10 @@
|
||||
#### 15.5 浏览历史同步
|
||||
- **现状**:⚠️ 仅本地存储
|
||||
- **建议接口**:
|
||||
```
|
||||
```text
|
||||
POST api_history.php?act=add
|
||||
{ "user_id": "xxx", "recipe_id": 123 }
|
||||
|
||||
|
||||
GET api_history.php?act=list&user_id=xxx&page=1
|
||||
```
|
||||
- **功能**:
|
||||
@@ -557,16 +296,7 @@
|
||||
#### 15.6 菜谱上传
|
||||
- **现状**:❌ 无上传接口
|
||||
- **建议接口**:
|
||||
```
|
||||
POST api_recipe.php?act=add
|
||||
{ "title": "xxx", "ingredients": [...], "steps": [...] }
|
||||
|
||||
PUT api_recipe.php?act=edit
|
||||
{ "recipe_id": 123, "title": "xxx" }
|
||||
|
||||
DELETE api_recipe.php?act=delete
|
||||
{ "recipe_id": 123 }
|
||||
```
|
||||
```text
|
||||
- **功能**:
|
||||
- 📝 用户菜谱上传
|
||||
- ✏️ 菜谱编辑
|
||||
@@ -602,26 +332,28 @@
|
||||
| 功能 | 状态 | 首次版本 | 说明 |
|
||||
|------|------|---------|------|
|
||||
| 热量追踪+营养分析 | ⚠️ 部分完成 | v0.3x | 环形图+柱状图+目标设置 ✅;饼图+折线图 ❌ |
|
||||
| 购物清单 | ⚠️ 部分完成 | v0.4x | 添加/删除/勾选/分类 ✅;从菜谱添加 ❌(页面无入口) |
|
||||
| 购物清单 | ✅ 已完成 | v0.4x | 添加/删除/勾选/分类 ✅;从菜谱添加 ✅(菜谱详情页"购物"按钮) |
|
||||
| 烹饪计时器 | ✅ 已完成 | v0.5x | 多步骤倒计时 |
|
||||
| 用量换算 | ✅ 已完成 | v0.5x | 常用单位换算 |
|
||||
| 过敏原检测 | ❌ 未完成 | v0.5x | 标记含过敏原菜谱 — 空壳实现,checkAllergens永远返回空列表 |
|
||||
| 烹饪笔记 | ❌ 未完成 | v0.5x | 按菜谱关联笔记 — 仅有Controller+Model,无页面 |
|
||||
| 过敏原检测 | ✅ 已完成 | v0.5x | 标记含过敏原菜谱 ✅;AllergenChecker完整实现 |
|
||||
| 烹饪笔记 | ✅ 已完成 | v0.5x | 按菜谱关联笔记 ✅;CookingNotePage完整实现 |
|
||||
| BMI 计算器 | ✅ 已完成 | v0.5x | 含健康建议 |
|
||||
| 份量缩放 | ⚠️ 部分完成 | v0.5x | 按比例调整 ✅;食材列表硬编码5项,不支持从菜谱导入 ❌ |
|
||||
| 份量缩放 | ✅ 已完成 | v0.5x | 按比例调整 ✅;支持从菜谱导入 ✅(菜谱详情页"缩放"按钮) |
|
||||
| 主页体验优化 | ✅ 已完成 | v0.6x | 骨架屏+动画+搜索+详情页 |
|
||||
| 今天吃什么增强 | ✅ 已完成 | v0.7x | 分类/标签/过敏原三维筛选 |
|
||||
| API v2.0.0 迁移 | ✅ 已完成 | v0.8x | 合并接口+8个Bug修复 |
|
||||
| 动态主题 | ✅ 已完成 | v0.6x | 多主题色+暗色模式+卡片滑动方向 |
|
||||
| Liquid Glass 风格 | ✅ 已完成 | v0.6x | 底栏+搜索栏+分段控件+卡片 |
|
||||
| 收藏管理 | ✅ 已完成 | v0.8x | 编辑/排序/分类/跳转详情 |
|
||||
| 静态分析清理 | ✅ 已完成 | v0.52 | 107→1 个 info,0 error/warning |
|
||||
| 静态分析清理 | ✅ 已完成 | v0.52 | 1071 个 info,0 error/warning |
|
||||
| 工具中心 | ✅ 已完成 | v0.9x | 工具入口Bar+分类筛选+使用频率统计 |
|
||||
| 过敏原检查工具 | ✅ 已完成 | v0.9x | 食材过敏原查询与分类浏览(API数据源) |
|
||||
| 用餐时段推荐 | ✅ 已完成 | v0.9x | 根据时间推荐早中晚餐菜谱 |
|
||||
| 每周菜单规划 | ⚠️ 部分完成 | v0.9x | 一周三餐UI ✅;数据不持久化 ❌;从收藏添加 ❌(仅snackbar提示) |
|
||||
| 食材详情查询 | ⚠️ 部分完成 | v0.9x | 食材列表+搜索 ✅;营养信息与选购指南 ❌(仅显示名称和分类) |
|
||||
| 每周菜单规划 | ✅ 已完成 | v0.88x | 一周三餐UI ✅;数据持久化 ✅(Hive);从菜谱添加 ✅ |
|
||||
| 食材详情查询 | ✅ 已完成 | v0.9x | 食材列表+搜索 ✅;营养信息+选购指南+存储提示 ✅ |
|
||||
| 统一Controller Binding | ✅ 已完成 | v0.63 | AppBinding全局管理+移除重复注册 |
|
||||
| AI菜谱推荐 | ✅ 已完成 | v0.88x | 基于用户偏好+浏览历史+收藏记录的智能推荐 ✅ |
|
||||
| 就寝提醒 | ✅ 已完成 | v0.88x | 智能推荐就寝时间+睡前进食提醒 ✅ |
|
||||
|
||||
---
|
||||
|
||||
@@ -931,3 +663,190 @@ lib/src/
|
||||
**19.18 网络请求优化**
|
||||
- 问题:ApiService日志拦截器无输出、无重试机制、post/put/delete重复代码
|
||||
- 方案:增强日志拦截器(debugPrint请求/响应/错误)、添加_executeWithRetry(最多2次重试)、统一_executeWithOfflineCheck、修复_tryGetCache缓存数据jsonDecode
|
||||
|
||||
### 验收标准
|
||||
- [x] 发现页更多按钮正常跳转工具中心
|
||||
- [x] 烹饪计时器支持常用预设快速添加
|
||||
- [x] 菜谱详情显示全部API数据
|
||||
- [x] 口味偏好分类和标签正确解析
|
||||
- [x] 热门排行有fallback机制
|
||||
- [x] 购物清单按钮易于点击
|
||||
- [x] 我的页面支持左右滑动切换
|
||||
- [x] 笔记保存后立即显示
|
||||
- [x] 深色模式支持跟随系统
|
||||
- [x] 字体大小全局生效
|
||||
- [x] 底部Tab栏适配安全区域
|
||||
- [x] 白色区域不再遮住底部
|
||||
- [x] 推荐分类支持层级导航
|
||||
- [x] 今天吃什么正常加载
|
||||
- [x] 搜索无结果时显示相似推荐
|
||||
- [x] 用餐时段推荐页可浏览
|
||||
- [x] 网络请求有日志和重试
|
||||
|
||||
---
|
||||
|
||||
## 🟢 阶段二十:用户体验优化+交互增强(P0/P1/P2)— ✅ 已完成
|
||||
|
||||
**目标**:修复关键Bug,优化用户体验,增强交互功能
|
||||
**完成时间**:2026-04-11
|
||||
**关键阻塞**:无
|
||||
**优先级**:P0=崩溃/闪退 P1=功能缺陷 P2=体验优化
|
||||
|
||||
### 问题清单
|
||||
|
||||
| 序号 | 任务 | 产出文件 | 优先级 | 状态 | 说明 |
|
||||
|------|------|---------|--------|------|------|
|
||||
| 20.1 | 🐛 笔记按钮闪退修复 | `cooking_note_page.dart` | P0 | ✅ 已完成 | 安全Controller初始化,防止空指针异常 |
|
||||
| 20.2 | 🚀 详情页骨架屏加载 | `recipe_detail_page.dart` | P1 | ✅ 已完成 | 骨架屏+8秒超时保护+重试按钮 |
|
||||
| 20.3 | 🔍 发现页推荐导航优化 | `discover_page.dart` + `category_browse_page.dart` | P1 | ✅ 已完成 | 智能路由:子分类/直接菜谱列表/分类浏览 |
|
||||
| 20.4 | 🖼️ 图片Invalid image data错误 | `recipe_image.dart` | P0 | ✅ 已完成 | 图片格式验证(魔数检测)+自动Fallback |
|
||||
| 20.5 | ⚠️ 工具中心GetX警告+溢出 | `tools_center_page.dart` | P1 | ✅ 已完成 | StatefulWidget重构+动态padding计算 |
|
||||
| 20.6 | 👆 发现页左右滑动功能 | `discover_page.dart` | P2 | ✅ 已完成 | Dismissible组件+快速操作菜单 |
|
||||
| 20.7 | 🍽️ 用餐时段图片加载 | `meal_time_recommend_page.dart` | P1 | ✅ 已完成 | 引入RecipeImage组件显示封面图 |
|
||||
|
||||
### 实施记录
|
||||
|
||||
**20.1 笔记按钮闪退修复**
|
||||
- **问题**:菜谱详情页点击"笔记"按钮导致应用卡死/闪退
|
||||
- **根因**:Controller未安全初始化,空指针异常
|
||||
- **方案**:
|
||||
- 实现安全的Controller获取模式(带错误状态)
|
||||
- 添加_controllerError标志位防止重复异常
|
||||
- 初始化时try-catch包裹,失败时显示友好提示
|
||||
- 所有Controller调用使用getter安全访问
|
||||
|
||||
**20.2 详情页骨架屏加载**
|
||||
- **问题**:菜谱详情页加载超过5秒,用户体验差
|
||||
- **方案**:
|
||||
- 实现完整骨架屏(封面图250px + 标题描述 + 统计数据4列 + 内容区域)
|
||||
- 8秒超时检测,超时后显示提示和重试按钮
|
||||
- ActionController/FavoritesController安全获取,所有操作添加try-catch
|
||||
|
||||
**20.3 发现页推荐导航优化**
|
||||
- **问题1**:点击推荐下的"菜谱"分类进入后不显示子类
|
||||
- **问题2**:点击"食材"分类显示"暂无菜谱"
|
||||
- **方案**:
|
||||
- 分类点击智能路由:有子分类→子类浏览 / 有菜谱数→直接加载 / 都没有→分类浏览
|
||||
- 新增loadRecipesDirectly参数支持直接加载模式
|
||||
- CategoryBrowsePage支持三种显示模式
|
||||
|
||||
**20.4 图片Invalid image data错误**
|
||||
- **问题**:多个页面显示"Exception: Invalid image data"
|
||||
- **根因**:API返回的非图片数据被当作图片解析
|
||||
- **方案**:
|
||||
- 新增_isValidImageData()方法验证图片格式
|
||||
- 支持JPEG/PNG/GIF/WebP/BMP格式检测(文件头魔数判断)
|
||||
- 无效数据自动触发Fallback链,尝试下一个URL
|
||||
- errorBuilder回调中增加自动重试机制
|
||||
|
||||
**20.5 工具中心GetX警告+布局溢出**
|
||||
- **问题1**:工具中心显示"use of a GetX has been detected"警告
|
||||
- **问题2**:底部溢出54像素
|
||||
- **方案**:
|
||||
- 重构为StatefulWidget,安全初始化Controller
|
||||
- GridView使用childAspectRatio: 0.85替代固定高度
|
||||
- padding动态计算底部安全区域
|
||||
|
||||
**20.6 发现页左右滑动功能**
|
||||
- **新功能**:热门列表支持左右滑动操作
|
||||
- **交互设计**:
|
||||
- 右滑(绿色背景):查看详情
|
||||
- 左滑(蓝色背景):快速操作菜单(收藏/查看详情/分享)
|
||||
- **技术实现**:Dismissible组件 + CupertinoActionSheet
|
||||
|
||||
**20.7 用餐时段图片加载优化**
|
||||
- **问题**:用餐时段页面显示图片错误
|
||||
- **方案**:引入RecipeImage组件显示菜谱封面图,自动享受Fallback链+错误处理
|
||||
|
||||
### 验收标准
|
||||
- [x] 笔记按钮点击正常,不闪退
|
||||
- [x] 详情页3秒内显示骨架屏,8秒内加载完成或显示重试
|
||||
- [x] 发现页推荐分类导航正确
|
||||
- [x] 图片加载失败时自动Fallback,不显示错误信息
|
||||
- [x] 工具中心无GetX警告,无布局溢出
|
||||
- [x] 发现页热门列表支持左右滑动
|
||||
- [x] 用餐时段页面正常显示菜谱封面图
|
||||
|
||||
---
|
||||
|
||||
## 🟢 阶段二十一:菜谱详情页功能增强(P2)— ✅ 已完成
|
||||
|
||||
**目标**:增强菜谱详情页功能,方便开发者调试和用户查看图片信息
|
||||
**完成时间**:2026-04-11
|
||||
**关键阻塞**:无
|
||||
**优先级**:P2=功能增强
|
||||
|
||||
### 问题清单
|
||||
|
||||
| 序号 | 任务 | 产出文件 | 优先级 | 状态 | 说明 |
|
||||
|------|------|---------|--------|------|------|
|
||||
| 21.1 | 🖼️ Picid显示和复制功能 | `recipe_detail_page.dart` | P2 | ✅ 已完成 | 在作者卡片下方显示图片信息卡片 |
|
||||
|
||||
### 实施记录
|
||||
|
||||
**21.1 Picid显示和复制功能**
|
||||
- **需求**:在菜谱详情页用户名称下方显示图片信息和Picid
|
||||
- **功能实现**:
|
||||
- 新增图片信息卡片,显示在作者卡片下方
|
||||
- 显示Picid编号(可选中复制)
|
||||
- 显示图片链接(可选中复制)
|
||||
- 点击卡片一键复制Picid到剪贴板
|
||||
- 复制成功后显示Toast提示
|
||||
- **UI设计**:
|
||||
- 卡片式设计,带主题色边框
|
||||
- 右上角显示"点击复制"提示标签
|
||||
- Picid使用等宽字体(monospace)高亮显示
|
||||
- 图片链接支持多行显示
|
||||
- **技术细节**:
|
||||
- 导入 `flutter/services.dart` 使用 Clipboard
|
||||
- 使用 SelectableText 支持文本选中
|
||||
- 无Picid时显示"无",但仍显示图片链接
|
||||
|
||||
### 验收标准
|
||||
- [x] 菜谱详情页显示图片信息卡片
|
||||
- [x] Picid可选中复制
|
||||
- [x] 图片链接可选中复制
|
||||
- [x] 点击卡片一键复制Picid
|
||||
- [x] 复制成功显示Toast提示
|
||||
|
||||
---
|
||||
|
||||
## 🟢 阶段二十二:Picid功能Bug修复(P0)— ✅ 已完成
|
||||
|
||||
**目标**:修复Picid显示为0和点击复制卡死闪退的问题
|
||||
**完成时间**:2026-04-11
|
||||
**关键阻塞**:无
|
||||
**优先级**:P0=崩溃/闪退
|
||||
|
||||
### 问题清单
|
||||
|
||||
| 序号 | 任务 | 产出文件 | 优先级 | 状态 | 说明 |
|
||||
|------|------|---------|--------|------|------|
|
||||
| 22.1 | 🐛 Picid显示为0 | `recipe_detail_page.dart` | P0 | ✅ 已完成 | 添加有效性检查,无效时显示"无" |
|
||||
| 22.2 | 🐛 点击复制卡死闪退 | `recipe_detail_page.dart` | P0 | ✅ 已完成 | 安全Toast显示+异常捕获 |
|
||||
|
||||
### 实施记录
|
||||
|
||||
**22.1 Picid显示为0的问题**
|
||||
- **问题**:所有菜谱的Picid都显示为0
|
||||
- **根因**:API返回的pic_id字段可能不存在或为null,_parseInt返回默认值0
|
||||
- **方案**:
|
||||
- 添加有效性检查:`hasValidPicId = picId != null && picId > 0`
|
||||
- 无效Picid时显示"无",不显示0
|
||||
- 无有效Picid时图片链接显示"暂无图片链接"
|
||||
- 添加调试日志输出picId实际值
|
||||
|
||||
**22.2 点击复制卡死闪退**
|
||||
- **问题**:点击Picid卡片复制时应用卡死闪退
|
||||
- **根因**:ToastService.show可能因ThemeService未注册而崩溃
|
||||
- **方案**:
|
||||
- 新增 `_showCopyToast()` 方法安全显示Toast
|
||||
- 添加mounted检查防止Widget已销毁
|
||||
- Clipboard.setData包裹try-catch防止异常
|
||||
- 失败时显示友好提示而非崩溃
|
||||
|
||||
### 验收标准
|
||||
- [x] Picid为0或null时显示"无"
|
||||
- [x] 点击复制不卡死不闪退
|
||||
- [x] 复制成功显示Toast提示
|
||||
- [x] 复制失败显示友好提示
|
||||
|
||||
Reference in New Issue
Block a user