801 lines
27 KiB
Markdown
801 lines
27 KiB
Markdown
# 家庭菜单与餐食安排子模块设计文档
|
||
|
||
## 1. 背景
|
||
|
||
在现有家庭 App 中新增「餐食」子模块,用于维护家庭共享的菜品库,并支持家庭成员快速设置今天、明天或指定日期每个餐段吃什么。
|
||
|
||
本模块先按 App 内工具设计,不做营销页。界面重点应是菜品查找顺手、餐食安排直观、家人能快速看懂今天和明天吃什么。
|
||
|
||
## 2. 目标
|
||
|
||
- 录入菜品,形成家庭共享的菜品库。
|
||
- 给菜品维护分类、标签、图片、食材、做法等信息。
|
||
- 家庭成员可以从菜品库中选择一道或多道菜,直接安排到某天某餐。
|
||
- 可以快速设置今天、明天或指定日期的餐食安排,餐段由家庭自定义,方便家庭备餐。
|
||
- 后续可扩展到一周餐食计划、采购清单、菜品偏好统计。
|
||
|
||
## 3. 非目标
|
||
|
||
第一期暂不做:
|
||
|
||
- 外卖/餐厅下单。
|
||
- 在线支付。
|
||
- 商家、桌台、排队叫号。
|
||
- 多家庭公开餐食分享。
|
||
- AI 自动生成菜谱。
|
||
- 自动营养分析和热量计算。
|
||
- 库存扣减和复杂采购管理。
|
||
- 严格厨师/管理员权限模型。
|
||
- 审批、通过、驳回、处理流。
|
||
- 想吃列表、投票、不想吃。
|
||
- 手动标记完成。
|
||
- 菜品复杂 SKU,例如大小份、辣度、加料价格。
|
||
|
||
这些能力可以作为后续扩展,不进入第一版主流程。
|
||
|
||
## 4. 核心用户故事
|
||
|
||
### 菜品管理
|
||
|
||
- 作为用户,我可以新增一道菜,上传图片,填写名称、分类、标签、食材、做法和备注。
|
||
- 作为用户,我可以按分类、标签、关键词筛选菜品。
|
||
- 作为用户,我可以编辑或删除已录入的菜品。
|
||
- 作为用户,我可以停用不常做的菜,而不是必须删除。
|
||
- 作为用户,我可以收藏或置顶常吃菜,方便快速安排餐食。
|
||
|
||
### 餐食安排
|
||
|
||
- 作为用户,我可以选择今天、明天或指定日期。
|
||
- 作为用户,我可以按家庭餐段查看每顿饭安排了哪些菜。
|
||
- 作为用户,我可以从菜品库选择一道或多道菜加入某顿饭。
|
||
- 作为用户,我可以从某顿饭移除不打算做的菜。
|
||
- 作为用户,我可以给某顿饭填写备注或做饭人。
|
||
|
||
### 餐食安排视图
|
||
|
||
- 作为用户,我可以查看今天安排了哪些菜。
|
||
- 作为用户,我可以直接设置今天每个餐段吃什么。
|
||
- 作为用户,我可以直接切到明天,设置明天各餐段的餐食安排。
|
||
- 作为用户,我可以按日期查看历史餐食安排。
|
||
- 作为用户,我可以从历史餐食安排中再次安排同样的菜。
|
||
|
||
### 分类/标签管理
|
||
|
||
- 作为用户,我可以维护菜品分类,例如家常菜、汤、主食、早餐、甜品、饮品。
|
||
- 作为用户,我可以维护父子标签,例如父标签“口味”下有“微辣、清淡”,父标签“食材”下有“牛肉、鸡蛋”。
|
||
- 作为用户,我可以给菜品添加多个标签,例如微辣、牛肉、蒸、儿童友好、快手菜。
|
||
- 分类保持单层,标签支持两级父子结构。
|
||
|
||
## 5. 信息架构
|
||
|
||
建议一级入口叫「餐食」。如果产品文案想保留“点菜”,它只作为按钮动作出现,例如“点菜/加菜”,不作为复杂流程。技术命名使用 `meal`,避免使用 `menu` 造成概念和路由冲突。
|
||
|
||
模块内建议 3 个主视图:
|
||
|
||
- 今日:按今天/明天和家庭自定义餐段快速设置餐食安排。
|
||
- 菜品:菜品列表、筛选、录入入口。
|
||
- 管理:菜品分类、父子标签、餐段维护。
|
||
|
||
第一期建议把「今日」作为默认首页,优先展示家庭当天餐食安排。用户进入模块后先看到当天启用的餐段卡片,可以一键加菜或调整。
|
||
|
||
## 5.1 已确认/暂定规则
|
||
|
||
- 子模块默认是家庭共享,不做个人私有餐食安排。
|
||
- 数据保存优先使用现有公共接口,例如 `data/loadData`、`data/saveData`。
|
||
- 不新增餐食专用后端接口;只有通用接口明显无法覆盖一致性或事务要求时,再单独讨论。
|
||
- 所有业务数据必须关联 `family_id`。
|
||
- 菜品图片必须上传,不允许无图菜品。
|
||
- 菜品食材建议保存为结构化明细,支持食材名、数量、单位、规格和备注。
|
||
- 食材明细第一版选填,不阻塞菜品保存。
|
||
- 做法保存为步骤明细,每一步可以上传图片、填写描述,图片和描述至少填写一个。
|
||
- 分类由用户自行创建,不做强制默认初始化。
|
||
- 分类保持单层,不做父子结构。
|
||
- 标签由用户自行创建,支持两级父子结构。
|
||
- 父标签用于分组,例如口味、食材、烹饪方式、适合人群;子标签用于实际标记菜品。
|
||
- 菜品可以没有分类和标签。
|
||
- 餐食安排必须关联日期和餐段。
|
||
- 一顿饭可以安排多道菜,也可以先发起餐食安排不选菜,待其他家庭成员后续添加。
|
||
- 餐段由家庭自定义,存储在 `b_meal_slot` 表中。系统可以在首次进入时提供建议餐段(早餐、午餐、晚餐),当创建家庭的时候默认创建几个,后续可以修改、排序、停用或新增。
|
||
- 餐食日期入口优先提供今天、明天两个快捷选项,再提供日期选择。
|
||
- 从菜品库加菜时,直接加入某天某餐,不进入待处理或想吃状态。
|
||
- 一次可以选择多道菜加入同一顿饭。
|
||
- 餐食安排支持设置做饭人 `cook_by`。
|
||
- 不做预计用餐人数字段。
|
||
- 支持从餐食安排进入记账模块,快速记录食材/餐饮支出。
|
||
- 第一版不做状态流转。
|
||
- 第一版不区分操作权限;家庭成员都可以添加、移除和调整餐食安排。
|
||
- 第一版不处理“某个人不想吃”的场景。
|
||
- 第一版不做投票。
|
||
- 第一版不做审批。
|
||
- 删除菜品时,如果存在历史餐食安排,默认软删除或停用菜品,不物理删除历史引用。
|
||
- 每次安排餐食、加菜、移除菜、设置做饭人、留下备注时,向 `b_meal_plan_log` 写入一条对应类型的记录。
|
||
- 加菜(type=2)和留下备注(type=4)两个动作需要触发家庭动态,调用 `recordFeed()`;其余操作不触发。
|
||
- 备注(type=4)仅允许 `create_by` 本人删除,不可编辑;操作日志(type≠4)不暴露删除入口。
|
||
- 活动日志按 `create_time` 升序展示,形成每顿饭的互动时间轴。
|
||
- 餐食安排统一视为在家做饭,`dish_id` 可以为空,即发起一顿饭但不指定菜品,等待其他家庭成员添加。
|
||
|
||
## 5.2 简化操作原则
|
||
|
||
餐食模块以家庭日常使用为中心,第一版优先保证操作少、入口直观:
|
||
|
||
- 首页默认展示「今天」,顶部提供「今天 / 明天」快捷切换。
|
||
- 每天按家庭启用的餐段展示餐食区块。
|
||
- 每个区块直接提供“加菜”入口,不要求用户先进入复杂表单。
|
||
- 选择菜品后默认数量为 1,可以直接保存。
|
||
- 餐食备注、数量等字段只在需要时展开。
|
||
- 菜品录入必须填写菜名并上传图片,食材、做法、标签可以后续补充。
|
||
- 分类和标签管理放到管理页,不打断日常加菜和排餐。
|
||
|
||
## 6. 数据对象草案
|
||
|
||
### 菜品 b_meal_dish
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- name
|
||
- image_file_key
|
||
- category_id
|
||
- ingredient_summary
|
||
- cooking_time_minutes
|
||
- difficulty
|
||
- remark
|
||
- status
|
||
- sort_number
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- `family_id`:菜品属于家庭空间。
|
||
- `image_file_key`:菜品图片,走现有 S3 规则。
|
||
- `image_file_key` 必填。
|
||
- `ingredient_summary`:食材摘要,选填,用于列表或详情快速展示;真正的食材和规格保存到 `b_meal_dish_ingredient`。
|
||
- `cooking_time_minutes`:预计用时,单位分钟,选填。
|
||
- `difficulty`:难度,建议 1 简单、2 普通、3 复杂。
|
||
- `status`:建议 1 启用,0 停用。
|
||
|
||
### 菜品分类 b_meal_category
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- name
|
||
- sort_number
|
||
- status
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- 分类只用于菜品。
|
||
- 分类保持单层,不设置 `parent_id`。
|
||
- 示例:家常菜、汤、主食、早餐、甜品、饮品。
|
||
|
||
### 菜品食材 b_meal_dish_ingredient
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- dish_id
|
||
- name
|
||
- quantity
|
||
- unit
|
||
- spec
|
||
- remark
|
||
- sort_number
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- 一道菜可以维护多条食材。
|
||
- `name`:食材名称,例如土豆、牛肉、鸡蛋。
|
||
- `quantity`:数量,选填,建议用 `NUMERIC`,例如 2、300、0.5。
|
||
- `unit`:单位,选填,例如 个、克、斤、勺、适量。
|
||
- `spec`:规格,选填,例如 去皮、切块、五花肉、带骨、约 200g/个。
|
||
- `remark`:补充说明,选填,例如 可替换成鸡腿肉。
|
||
- 第一版不做独立食材库,不要求把“土豆”维护成主数据,减少录入成本。
|
||
- 第一版不做库存扣减。
|
||
- 后续生成采购清单时,可以按 `name + unit + spec` 聚合,再由用户手动确认合并。
|
||
|
||
### 菜品步骤 b_meal_dish_step
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- dish_id
|
||
- step_number
|
||
- description
|
||
- image_file_key
|
||
- sort_number
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- 一道菜可以维护多条做菜步骤。
|
||
- `step_number`:步骤序号,从 1 开始,用于展示“第几步”。
|
||
- `description`:步骤描述,选填。
|
||
- `image_file_key`:步骤图片,选填,走现有 S3 规则。
|
||
- `description` 和 `image_file_key` 至少填写一个;第一版在应用层校验。
|
||
- `sort_number`:用于拖拽排序或手动调整顺序,默认可以和 `step_number` 保持一致。
|
||
|
||
### 标签 b_meal_tag
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- parent_id
|
||
- name
|
||
- color
|
||
- sort_number
|
||
- status
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- `parent_id` 为空表示父标签,例如口味、食材、烹饪方式、适合人群。
|
||
- `parent_id` 指向父标签时表示子标签,例如微辣、牛肉、蒸、儿童友好。
|
||
- 第一版只支持两级结构,不做无限层级。
|
||
- 菜品一般关联子标签;如果用户只建了父标签,也允许直接关联父标签,降低操作门槛。
|
||
- `color` 第一版可选,建议保存十六进制颜色值,例如 `#EF4444`,用于标签背景、文字或边框展示。
|
||
|
||
### 菜品标签关联 b_meal_dish_tag
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- dish_id
|
||
- tag_id
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- 一道菜可以有多个标签。
|
||
- 查询菜品列表时可以通过该表做标签筛选。
|
||
|
||
### 餐食安排 b_meal_plan
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- plan_date
|
||
- meal_slot_id
|
||
- remark
|
||
- cook_by
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- `plan_date`:餐食日期,例如今天、明天或用户选择的日期。
|
||
- `meal_slot_id`:餐段 ID,指向 `b_meal_slot`。
|
||
- 同一个家庭、同一天、同一个餐段建议只有一条餐食安排。
|
||
- `remark`:这顿饭的备注,选填。
|
||
- `cook_by`:做饭人,选填,指向家庭成员用户。
|
||
|
||
### 餐段 b_meal_slot
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- name
|
||
- sort_number
|
||
- status
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- 餐段属于家庭空间,可自定义。
|
||
- 示例:早餐、午餐、晚餐、夜宵、加餐、周末早午餐。
|
||
- `status`:建议 1 启用,0 停用。
|
||
- 第一版不要求设置开始/结束时间,只按排序展示。
|
||
- 不强制初始化默认数据;没有餐段时,前端提供“创建推荐餐段”快捷操作。
|
||
- 如果后续需要按时间自动推荐餐段,可以再增加 `start_time`、`end_time`。
|
||
|
||
### 餐食安排明细 b_meal_plan_item
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- plan_id
|
||
- dish_id
|
||
- quantity
|
||
- remark
|
||
- sort_number
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- 统一保存一顿饭的菜品明细。
|
||
- `dish_id` 必填,指向 `b_meal_dish`,菜名和图片从菜品库取。
|
||
- `quantity` 第一版表示份数或数量,默认 1。
|
||
- 明细独立保存,方便一顿饭安排多道菜,也方便从餐段区块移除单道菜。
|
||
|
||
### 餐食活动日志 b_meal_plan_log
|
||
|
||
字段草案:
|
||
|
||
- id
|
||
- family_id
|
||
- plan_id
|
||
- type
|
||
- content
|
||
- ref_id
|
||
- create_time
|
||
- update_time
|
||
- create_by
|
||
- update_by
|
||
|
||
说明:
|
||
|
||
- 统一记录每顿餐食安排上的操作和互动,用于时间轴展示。
|
||
- `type` 枚举值:
|
||
- `1` 安排了餐食(创建 b_meal_plan 时写入)
|
||
- `2` 加了菜(新增 b_meal_plan_item 时写入)
|
||
- `3` 移除了菜(删除 b_meal_plan_item 时写入)
|
||
- `4` 留下了备注(用户主动填写文字时写入)
|
||
- `5` 设置了做饭人(更新 cook_by 时写入)
|
||
- `content`:type=4 时为备注正文;其余类型可为空,前端根据 type 拼接展示文案。
|
||
- `ref_id`:type=2/3 时指向对应的 `b_meal_plan_item.id`,便于展示菜名;type=4 时为空。
|
||
- type=4(备注)允许 `create_by` 本人删除,不可编辑。
|
||
- type≠4 的操作记录由系统自动写入,不暴露用户删除入口。
|
||
- 删除 plan_item(移除菜)时写入 type=3 记录,不删除历史 type=2 记录,保留操作轨迹。
|
||
- 前端展示时按 `create_time` 升序排列,形成从上到下的时间轴。
|
||
|
||
## 7. 第一版流程
|
||
|
||
### 新增菜品
|
||
|
||
1. 进入「餐食」的「菜品」页。
|
||
2. 点击新增。
|
||
3. 填写菜名并上传图片。
|
||
4. 可选填写分类、标签、食材明细、做法、预计用时、备注。
|
||
5. 保存菜品。
|
||
6. 返回菜品列表并刷新。
|
||
|
||
校验规则:
|
||
|
||
- 菜名必填。
|
||
- 图片必填。
|
||
- 分类可以为空。
|
||
- 标签可以为空。
|
||
- 食材明细可以为空。
|
||
- 预计用时如果填写,必须大于 0。
|
||
|
||
### 设置餐食安排
|
||
|
||
1. 进入「今日」页。
|
||
2. 默认选中今天。
|
||
3. 页面按家庭启用餐段展示餐食区块,每个区块底部展示该餐的活动时间轴(操作记录 + 备注)。
|
||
4. 点击某个区块的加菜。
|
||
5. 从菜品库选择一道或多道菜。
|
||
6. 直接保存到该日期和餐段。
|
||
7. 保存成功后:向 `b_meal_plan_log` 写入 type=2 记录(每道菜一条);调用 `recordFeed()` 触发家庭动态。
|
||
8. 可选设置做饭人;设置后写入 type=5 记录。
|
||
9. 切换到明天,可以用同样方式设置明天餐食。
|
||
|
||
校验规则:
|
||
|
||
- 至少选择 1 道菜。
|
||
- 日期默认今天,也可以快捷切换明天。
|
||
- 餐段必填,来自家庭自定义餐段。
|
||
- 数量默认 1,不强制用户填写。
|
||
- 保存时生成或更新 `b_meal_plan` 和 `b_meal_plan_item`;同步写入 `b_meal_plan_log`。
|
||
|
||
### 新增菜品并加入餐食安排
|
||
|
||
1. 在某个日期/餐段区块点击加菜。
|
||
2. 如果菜品库里没有目标菜,可以点击新增菜品。
|
||
3. 填写菜名并上传图片。
|
||
4. 保存菜品。
|
||
5. 新菜品自动加入当前日期/餐段餐食安排。
|
||
|
||
校验规则:
|
||
|
||
- 菜名必填。
|
||
- 图片必填。
|
||
- 分类可以为空。
|
||
- 标签可以为空。
|
||
|
||
### 今日/明日餐食安排
|
||
|
||
1. 进入「今日」页。
|
||
2. 默认按家庭启用餐段展示今天餐食安排。
|
||
3. 顶部切换到明天,按同样餐段展示明天餐食安排。
|
||
4. 支持继续打开日期选择器查看其他日期。
|
||
5. 每个餐段区块支持加菜、移除菜、复制历史餐食。
|
||
6. 可从历史记录中再次安排同样的菜。
|
||
|
||
### 快速记账
|
||
|
||
1. 在某顿餐食安排上点击记账按钮。
|
||
2. 弹出或跳转到现有记账新增能力。
|
||
3. 默认带入菜品名称、餐段和备注,例如“餐食:番茄炒蛋、排骨汤”。
|
||
4. 保存成功后返回今日页。
|
||
|
||
校验规则:
|
||
|
||
- 记账入口只是快捷入口,不强制每顿饭都记账。
|
||
- 记账保存逻辑复用现有记账模块。
|
||
|
||
## 8. MVP 范围建议
|
||
|
||
第一期建议做:
|
||
|
||
- 菜品 CRUD。
|
||
- 菜品分类自定义。
|
||
- 菜品父子标签自定义。
|
||
- 菜品图片上传,图片必填。
|
||
- 菜品食材明细维护,支持数量、单位、规格。
|
||
- 菜品列表关键词、分类、标签筛选。
|
||
- 今天/明天餐食快捷设置。
|
||
- 家庭自定义餐段。
|
||
- 餐食安排支持一次选择多道菜。
|
||
- 餐食安排支持设置做饭人。
|
||
- 餐食安排支持设置做饭人。
|
||
- 今日/明日餐食视图。
|
||
- 餐食安排提供快速记账按钮。
|
||
|
||
第一期暂缓:
|
||
|
||
- AI 菜谱生成。
|
||
- 一周餐食自动规划。
|
||
- 采购清单生成和食材合并。
|
||
- 营养、热量、过敏原分析。
|
||
- 严格权限控制。
|
||
- 菜品评分和偏好统计。
|
||
- 菜品复杂 SKU。
|
||
- 餐食消息提醒。
|
||
- 餐段开始/结束时间和自动提醒。
|
||
- 想吃列表、审批状态流转和对应操作日志。
|
||
- 餐厅档案、常去餐厅统计、地图定位。
|
||
|
||
## 9. 剩余待确认问题
|
||
|
||
- 是否需要后续扩展一周餐食计划?
|
||
|
||
## 10. 初步技术建议
|
||
|
||
- 数据库建议新增独立表,全部使用 `b_meal_` 前缀。
|
||
- 所有新业务表都包含审计字段,符合项目现有规则。
|
||
- 菜品、食材明细、分类、父子标签、餐段、餐食安排、餐食安排明细保存优先复用 `data/saveData`。
|
||
- 查询优先使用 `data/loadData` 和 `data/loadDataPage`。
|
||
- 今日/明日餐食可以用 `loadDataBySql` 做菜品、餐食安排、明细的聚合查询;第一版也可以前端分别查询后组合。
|
||
- 删除菜品时优先软删除,避免破坏历史餐食安排。
|
||
- 保存餐食安排建议在前端用一次 `saveData` 批量保存 `b_meal_plan` 和 `b_meal_plan_item`。
|
||
- 餐食安排统一视为在家做饭。
|
||
- 如果后续要求状态流转、想吃列表或权限校验,再单独设计,不放入第一版。
|
||
- 图片上传复用现有 S3 上传接口。
|
||
- 前端状态可以新增 `meal` store,负责菜品、分类、标签、餐食安排缓存。
|
||
- 快速记账按钮复用现有记账模块新增能力,不在餐食模块内重复实现记账逻辑。
|
||
- UI 使用 HeroUI Native、lucide-react-native、@legendapp/list、sonner-native;样式使用 Uniwind `className`。
|
||
- 保存、加菜、移除菜等异步操作统一使用 `useLoading + LoadingOverlay`。
|
||
|
||
## 11. 页面建议
|
||
|
||
建议路由:
|
||
|
||
- `app-rn/src/app/meal/(tabs)/_layout.tsx`
|
||
- `app-rn/src/app/meal/(tabs)/home/index.tsx`
|
||
- `app-rn/src/app/meal/(tabs)/dishes/index.tsx`
|
||
- `app-rn/src/app/meal/(tabs)/manage/index.tsx`
|
||
- `app-rn/src/app/meal/dish/edit/index.tsx`
|
||
- `app-rn/src/app/meal/dish/detail/[id]/index.tsx`
|
||
- `app-rn/src/app/meal/plan/edit/index.tsx`
|
||
|
||
说明:
|
||
|
||
- `home`:今天/明天餐食安排。
|
||
- `dishes`:菜品库。
|
||
- `manage`:分类和标签维护。
|
||
- `dish/edit`:新增/编辑菜品。
|
||
- `plan/edit`:编辑某天某餐的菜品。
|
||
|
||
## 12. 下一步
|
||
|
||
下一步可以进入:
|
||
|
||
1. 数据库表结构设计。
|
||
2. 页面与交互流程设计。
|
||
3. 公共接口调用方案设计。
|
||
4. 第一版任务拆分。
|
||
|
||
## 13. 实施计划
|
||
|
||
说明:
|
||
|
||
- 每一步完成后,把 `[ ]` 改成 `[x]`。
|
||
- 严格按阶段推进,前一阶段没有确认前,不进入下一阶段。
|
||
- 默认优先使用通用接口;遇到通用接口明显无法覆盖的场景,再单独讨论是否增加通用 helper。
|
||
|
||
### 阶段 1:数据库表结构 ✅
|
||
|
||
- [x] 设计 `b_meal_dish` 表结构。
|
||
- [x] 设计 `b_meal_dish_ingredient` 表结构,保存食材名称、数量、单位、规格。
|
||
- [x] 设计 `b_meal_dish_step` 表结构,保存步骤描述和步骤图片。
|
||
- [x] 设计 `b_meal_category` 表结构。
|
||
- [x] 设计 `b_meal_tag` 表结构,包含 `parent_id` 支持父子标签。
|
||
- [x] 设计 `b_meal_dish_tag` 表结构。
|
||
- [x] 设计 `b_meal_slot` 表结构,支持家庭自定义餐段。
|
||
- [x] 设计 `b_meal_plan` 表结构,包含 `plan_date`、`meal_slot_id`、`cook_by`。
|
||
- [x] 设计 `b_meal_plan_item` 表结构,`dish_id` 指向菜品库。
|
||
- [x] 设计 `b_meal_plan_log` 表结构,包含 `plan_id`、`type`、`content`、`ref_id`,统一记录操作和备注。
|
||
- [x] 补充索引设计,例如 `family_id/plan_date/meal_slot_id/sort_number`。
|
||
- [x] 生成 SQL 文件并确认命名、字段类型、默认值。
|
||
- [x] 执行 SQL 到 dev 数据库并验证表已创建。
|
||
|
||
产出文件:
|
||
|
||
- `app-go/db/meal.sql`
|
||
|
||
验收标准:
|
||
|
||
- 表名全部使用 `b_meal_` 前缀。
|
||
- 所有业务表包含审计字段。
|
||
- 历史餐食安排不会因为菜品删除而丢失。
|
||
- 食材明细可以支持后续采购清单生成。
|
||
- 餐段可以按家庭自定义、排序和停用。
|
||
|
||
### 阶段 2:前端基础模型与公共接口封装 ✅
|
||
|
||
- [x] 新增菜品、食材明细、分类、父子标签、餐段、餐食安排、统一餐食安排明细、活动日志 TypeScript 类型。
|
||
- [x] 新增 `meal` store,管理餐食模块缓存。
|
||
- [x] 在 `meal` store 中封装基于公共接口的查询方法。
|
||
- [x] 在 `meal` store 中封装基于公共接口的保存方法。
|
||
- [x] 在 `meal` store 中封装图片上传复用逻辑。
|
||
- [x] 在 `app-rn/src/store/index.ts` 导出 `meal` store。
|
||
- [x] 不新增 services 层,避免重复封装。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/types/meal.ts`
|
||
- `app-rn/src/store/meal.ts`
|
||
- `app-rn/src/store/index.ts`
|
||
|
||
验收标准:
|
||
|
||
- 前端类型和数据库字段一致。
|
||
- 查询和保存优先使用现有 `loadData`、`loadDataPage`、`saveData`。
|
||
- 所有查询都按 `family_id` 过滤。
|
||
|
||
### 阶段 3:子应用入口与基础导航 ✅
|
||
|
||
- [x] 新增餐食应用图标。
|
||
- [x] 在 `app-rn/src/configs/pages.ts` 注册餐食子应用。
|
||
- [x] 新增 `meal/(tabs)/_layout.tsx`。
|
||
- [x] 新增今日、菜品、管理底部 Tab,今日页默认展示今天/明天餐食安排。
|
||
- [x] 确认子模块使用 `ModuleLayout`。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/components/iconfont/IconAppMeal.tsx`
|
||
- `app-rn/src/components/iconfont/index.tsx`
|
||
- `app-rn/src/configs/pages.ts`
|
||
- `app-rn/src/app/meal/(tabs)/_layout.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 首页工具列表可以进入餐食模块。
|
||
- 餐食模块底部 Tab 能正常切换。
|
||
|
||
### 阶段 4:菜品管理 ✅
|
||
|
||
- [x] 新增菜品列表页。
|
||
- [x] 支持关键词搜索。
|
||
- [x] 支持按分类筛选。
|
||
- [x] 支持按标签筛选。
|
||
- [x] 新增菜品编辑页。
|
||
- [x] 支持菜品图片上传,图片必填。
|
||
- [x] 支持维护菜品食材明细。
|
||
- [x] 食材明细支持名称、数量、单位、规格、备注。
|
||
- [x] 支持创建或选择分类。
|
||
- [x] 支持创建或选择父子标签。
|
||
- [x] 支持编辑菜品。
|
||
- [x] 支持停用或删除菜品。
|
||
- [x] 删除已有餐食安排历史的菜品时使用软删除。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/app/meal/(tabs)/home/index.tsx`
|
||
- `app-rn/src/app/meal/dish/edit/index.tsx`
|
||
- `app-rn/src/app/meal/dish/detail/[id]/index.tsx`
|
||
- `app-rn/src/components/meal/MealDishImage.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 菜名必填。
|
||
- 无图菜品不能保存。
|
||
- 食材明细选填,但如果填写则食材名称必填。
|
||
- 菜品列表筛选结果正确。
|
||
- 删除菜品不会破坏历史餐食安排。
|
||
|
||
### 阶段 5:分类、父子标签管理 ✅
|
||
|
||
- [x] 在菜品编辑流程中支持快速新建分类。
|
||
- [x] 在菜品编辑流程中支持快速新建父标签。
|
||
- [x] 在菜品编辑流程中支持在父标签下新建子标签。
|
||
- [x] 独立管理页支持维护分类。
|
||
- [x] 独立管理页支持维护父标签。
|
||
- [x] 独立管理页支持维护子标签。
|
||
- [x] 支持父标签无子标签时直接用于菜品标记。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/app/meal/(tabs)/manage/index.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 分类单层。
|
||
- 标签支持两级父子结构。
|
||
- 停用分类或标签后,不影响历史菜品展示。
|
||
|
||
### 阶段 5.5:餐段管理 ✅
|
||
|
||
- [x] 独立管理页支持维护餐段。
|
||
- [x] 支持新增餐段。
|
||
- [x] 支持编辑餐段名称。
|
||
- [x] 支持调整餐段排序。
|
||
- [x] 支持停用餐段。
|
||
- [x] 今日页按启用餐段排序展示(fetchSlots 已按 sort_number 排序并过滤已启用)。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/app/meal/(tabs)/manage/index.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 餐段由家庭自定义,不写死。
|
||
- 停用餐段后,不影响历史餐食安排展示。
|
||
- 没有餐段时,引导用户先创建餐段。
|
||
|
||
### 阶段 6:餐食安排编辑 ✅
|
||
|
||
- [x] 支持从菜品列表选择单道菜加入餐食。
|
||
- [x] 支持多选菜品后批量加入餐食。
|
||
- [x] 新增餐食安排编辑页或 BottomSheet。
|
||
- [x] 支持今天/明天快捷选择。
|
||
- [x] 支持选择家庭自定义餐段。
|
||
- [x] 支持填写每道菜数量。
|
||
- [x] 支持选择做饭人。
|
||
- [x] 支持填写餐食备注。
|
||
- [x] 提交后创建或更新餐食安排和餐食安排明细。
|
||
- [x] 安排餐食时写入 type=1 日志记录。
|
||
- [x] 加菜时写入 type=2 日志记录,并调用 `recordFeed()` 触发家庭动态。
|
||
- [x] 移除菜时写入 type=3 日志记录。
|
||
- [x] 设置做饭人时写入 type=5 日志记录。
|
||
- [x] 支持在餐食安排上留下备注(type=4),写入日志并调用 `recordFeed()`。
|
||
- [x] 备注仅允许 `create_by` 本人删除,不可编辑;操作日志不暴露删除入口。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/app/meal/plan/edit/index.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 至少选择一道菜才能提交。
|
||
- 数量必须大于 0。
|
||
- 保存中有 LoadingOverlay。
|
||
|
||
### 阶段 7:今日/明日餐食安排 ✅
|
||
|
||
- [x] 新增今日/明日餐食区。
|
||
- [x] 默认展示今天餐食安排。
|
||
- [x] 支持今天/明天快捷切换。
|
||
- [x] 支持打开日期选择器查看其他日期。
|
||
- [x] 支持按家庭自定义餐段分组展示。
|
||
- [x] 支持在每个餐段区块直接加菜。
|
||
- [x] 支持在每个餐段区块移除菜。
|
||
- [x] 支持从历史餐食安排再次安排同样的菜。(阶段 8 已补完)
|
||
- [x] 每个餐段区块下方展示活动时间轴,按 `create_time` 升序列出操作记录和备注。
|
||
- [x] 时间轴条目根据 `type` 拼接展示文案。
|
||
- [x] 备注条目(type=4)在当前用户为作者时显示删除按钮;其余条目不显示。
|
||
- [x] 支持空状态。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/app/meal/(tabs)/home/index.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 今天和明天餐食安排能按家庭自定义餐段清晰展示。
|
||
- 切换日期后数据正确刷新。
|
||
- 再次安排能复用原菜品生成新的餐食安排明细。
|
||
|
||
### 阶段 8:历史餐食与复用 ✅
|
||
|
||
- [x] 支持按日期查看历史餐食安排。
|
||
- [x] 支持复制某顿历史餐食到今天或明天。
|
||
- [x] 支持从历史餐食进入相关菜品详情。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/app/meal/(tabs)/home/index.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 历史餐食不会因为菜品停用而无法展示。
|
||
- 复制历史餐食后能正确生成新的餐食安排。
|
||
- 复制外出就餐时复用临时菜名和地点,不要求创建餐厅档案。
|
||
|
||
### 阶段 8.5:快速记账入口
|
||
|
||
- [ ] 在餐食安排上增加记账按钮。(暂缓,后续迭代)
|
||
- [ ] 点击后复用现有记账新增能力。
|
||
- [ ] 默认带入菜品名称、餐段和备注。
|
||
- [ ] 保存成功后返回今日页。
|
||
|
||
产出文件:
|
||
|
||
- `app-rn/src/app/meal/(tabs)/home/index.tsx`
|
||
|
||
验收标准:
|
||
|
||
- 快速记账不影响餐食安排。
|
||
- 记账保存逻辑与现有记账模块一致。
|
||
|
||
### 阶段 9:收尾与体验优化 ✅
|
||
|
||
- [x] 补充空状态。
|
||
- [x] 补充加载状态。
|
||
- [x] 补充保存中状态。
|
||
- [x] 补充错误提示。
|
||
- [x] 检查移动端小屏布局。
|
||
- [x] 检查图片加载失败兜底。
|
||
- [x] 跑 `pnpm exec oxfmt --check`。(通过)
|
||
- [ ] 跑 `pnpm lint`。(环境中 ESLint 未安装,需 `npx expo lint` 初始化配置)
|
||
- [x] 跑 `pnpm exec tsc --noEmit`。(通过,0 错误)
|
||
- [x] 根据实际结果更新本文档完成状态。
|
||
|
||
验收标准:
|
||
|
||
- 核心流程从新增菜品到设置今天/明天餐食可完整走通。
|
||
- 异常状态有明确反馈。
|
||
- 文档计划状态和代码实现保持一致。
|
||
|
||
### 阶段 10:后置功能
|
||
|
||
- [ ] 一周餐食计划。
|
||
- [ ] 采购清单生成。
|
||
- [ ] 菜品评分和家庭偏好统计。
|
||
- [ ] 家庭角色权限控制。
|
||
- [ ] 餐食消息提醒。
|
||
- [ ] AI 菜谱或餐食推荐。
|
||
|
||
验收标准:
|
||
|
||
- 后置功能不影响第一版餐食安排主流程。
|
||
- 每个后置功能开始前先单独确认范围。
|