diff --git a/code/app/MEAL_ORDER_DESIGN.md b/code/app/MEAL_ORDER_DESIGN.md index 34b6cd61..8c64c3a2 100644 --- a/code/app/MEAL_ORDER_DESIGN.md +++ b/code/app/MEAL_ORDER_DESIGN.md @@ -1,17 +1,16 @@ -# 家庭点菜与餐食安排子模块设计文档 +# 家庭菜单与餐食安排子模块设计文档 ## 1. 背景 -在现有家庭 App 中新增「点菜」子模块,用于维护家庭共享的菜品库,并支持家庭成员快速安排今日/明日餐食、发起点菜、处理点菜、驳回点菜、标记完成等协作流程。 +在现有家庭 App 中新增「餐食」子模块,用于维护家庭共享的菜品库,并支持家庭成员快速设置今天、明天或指定日期每个餐段吃什么。 -本模块先按 App 内工具设计,不做营销页。界面重点应是菜品查找顺手、点菜动作明确、待处理状态清晰。 +本模块先按 App 内工具设计,不做营销页。界面重点应是菜品查找顺手、餐食安排直观、家人能快速看懂今天和明天吃什么。 ## 2. 目标 - 录入菜品,形成家庭共享的菜品库。 - 给菜品维护分类、标签、图片、食材、做法等信息。 -- 家庭成员可以从菜品库中点菜,形成待处理点菜记录。 -- 点菜支持通过、驳回、取消、标记完成等状态流转。 +- 家庭成员可以从菜品库中选择一道或多道菜,直接安排到某天某餐。 - 可以快速设置今天、明天或指定日期的餐食安排,餐段由家庭自定义,方便家庭备餐。 - 后续可扩展到一周餐食计划、采购清单、菜品偏好统计。 @@ -27,6 +26,9 @@ - 自动营养分析和热量计算。 - 库存扣减和复杂采购管理。 - 严格厨师/管理员权限模型。 +- 审批、通过、驳回、处理流。 +- 想吃列表、投票、不想吃。 +- 手动标记完成。 - 菜品复杂 SKU,例如大小份、辣度、加料价格。 这些能力可以作为后续扩展,不进入第一版主流程。 @@ -39,26 +41,23 @@ - 作为用户,我可以按分类、标签、关键词筛选菜品。 - 作为用户,我可以编辑或删除已录入的菜品。 - 作为用户,我可以停用不常做的菜,而不是必须删除。 -- 作为用户,我可以收藏或置顶常吃菜,方便快速点菜。 +- 作为用户,我可以收藏或置顶常吃菜,方便快速安排餐食。 -### 点菜管理 +### 餐食安排 -- 作为用户,我可以从菜品库中选择一道或多道菜发起点菜。 -- 作为用户,我可以填写期望日期、餐段、份数、备注。 -- 作为用户,我可以查看自己点过的菜和当前处理状态。 -- 作为处理人,我可以通过点菜申请。 -- 作为处理人,我可以驳回点菜申请,并填写驳回原因。 -- 作为处理人,我可以把已通过的点菜标记为已完成。 -- 作为点菜人,我可以在未处理前取消自己的点菜。 +- 作为用户,我可以选择今天、明天或指定日期。 +- 作为用户,我可以按家庭餐段查看每顿饭安排了哪些菜。 +- 作为用户,我可以从菜品库选择一道或多道菜加入某顿饭。 +- 作为用户,我可以从某顿饭移除不打算做的菜。 +- 作为用户,我可以给某顿饭填写备注或做饭人。 ### 餐食安排视图 -- 作为用户,我可以查看今天点了哪些菜。 +- 作为用户,我可以查看今天安排了哪些菜。 - 作为用户,我可以直接设置今天每个餐段吃什么。 - 作为用户,我可以直接切到明天,设置明天各餐段的餐食安排。 -- 作为用户,我可以查看待处理、已通过、已驳回、已完成的点菜记录。 - 作为用户,我可以按日期查看历史餐食安排。 -- 作为用户,我可以从历史餐食安排中再次点菜。 +- 作为用户,我可以从历史餐食安排中再次安排同样的菜。 ### 分类/标签管理 @@ -69,80 +68,70 @@ ## 5. 信息架构 -建议一级入口叫「点菜」或「餐食」。技术命名使用 `meal`,避免使用 `menu` 造成概念和路由冲突。 +建议一级入口叫「餐食」。如果产品文案想保留“点菜”,它只作为按钮动作出现,例如“点菜/加菜”,不作为复杂流程。技术命名使用 `meal`,避免使用 `menu` 造成概念和路由冲突。 -模块内建议 4 个主视图: +模块内建议 3 个主视图: -- 菜品:菜品列表、筛选、录入入口。 - 今日:按今天/明天和家庭自定义餐段快速设置餐食安排。 -- 点菜:查看待处理点菜、处理通过或驳回。 -- 管理:菜品分类、父子标签维护。 +- 菜品:菜品列表、筛选、录入入口。 +- 管理:菜品分类、父子标签、餐段维护。 -第一期建议把「今日」作为默认首页,优先展示家庭当天餐食安排。用户进入模块后先看到当天启用的餐段卡片,可以一键加菜或调整。点菜处理放在第二入口,避免主流程过重。 +第一期建议把「今日」作为默认首页,优先展示家庭当天餐食安排。用户进入模块后先看到当天启用的餐段卡片,可以一键加菜或调整。 ## 5.1 已确认/暂定规则 - 子模块默认是家庭共享,不做个人私有餐食安排。 - 数据保存优先使用现有公共接口,例如 `data/loadData`、`data/saveData`。 -- 不新增点菜专用后端接口;只有通用接口明显无法覆盖一致性或事务要求时,再单独讨论。 +- 不新增餐食专用后端接口;只有通用接口明显无法覆盖一致性或事务要求时,再单独讨论。 - 所有业务数据必须关联 `family_id`。 - 菜品图片必须上传,不允许无图菜品。 - 菜品食材建议保存为结构化明细,支持食材名、数量、单位、规格和备注。 - 食材明细第一版选填,不阻塞菜品保存。 -- 做法第一版仍可使用文本保存,避免录入过重。 +- 做法保存为步骤明细,每一步可以上传图片、填写描述,图片和描述至少填写一个。 - 分类由用户自行创建,不做强制默认初始化。 - 分类保持单层,不做父子结构。 - 标签由用户自行创建,支持两级父子结构。 - 父标签用于分组,例如口味、食材、烹饪方式、适合人群;子标签用于实际标记菜品。 - 菜品可以没有分类和标签。 -- 点菜记录必须关联菜品。 -- 点菜记录可以包含期望日期,默认是当天。 -- 餐段由家庭自定义,不写死为上午/中午/晚上。 -- 系统可以在首次进入时提供建议餐段,例如早餐、午餐、晚餐;用户确认后一键创建,后续可以修改、排序、停用或新增。 +- 餐食安排必须关联日期和餐段。 +- 一顿饭可以安排多道菜,也可以先发起餐食安排不选菜,待其他家庭成员后续添加。 +- 餐段由家庭自定义,存储在 `b_meal_slot` 表中。系统可以在首次进入时提供建议餐段(早餐、午餐、晚餐),当创建家庭的时候默认创建几个,后续可以修改、排序、停用或新增。 - 餐食日期入口优先提供今天、明天两个快捷选项,再提供日期选择。 -- 快速设置今天/明天餐食安排时,不进入审批,直接生成已安排记录。 -- 明确从“点菜”入口提交的记录才进入待处理,支持通过、驳回、取消。 -- 一次点菜允许选择多道菜。 -- 点菜记录支持设置做饭人 `cook_by`。 +- 从菜品库加菜时,直接加入某天某餐,不进入待处理或想吃状态。 +- 一次可以选择多道菜加入同一顿饭。 +- 餐食安排支持设置做饭人 `cook_by`。 - 不做预计用餐人数字段。 -- 支持从点菜或已完成记录通过小按钮进入记账模块,快速记录食材/餐饮支出。 -- 点菜状态第一期使用固定状态流转。 -- 第一版不做严格权限;家庭成员都可以处理点菜。后续如果家庭角色完善,再限制为家庭管理员或指定处理人。 -- 驳回点菜时必须填写驳回原因。 -- 删除菜品时,如果存在点菜历史,默认软删除或停用菜品,不物理删除历史引用。 +- 支持从餐食安排进入记账模块,快速记录食材/餐饮支出。 +- 第一版不做状态流转。 +- 第一版不区分操作权限;家庭成员都可以添加、移除和调整餐食安排。 +- 第一版不处理“某个人不想吃”的场景。 +- 第一版不做投票。 +- 第一版不做审批。 +- 删除菜品时,如果存在历史餐食安排,默认软删除或停用菜品,不物理删除历史引用。 +- 每次安排餐食、加菜、移除菜、设置做饭人、留下备注时,向 `b_meal_plan_log` 写入一条对应类型的记录。 +- 加菜(type=2)和留下备注(type=4)两个动作需要触发家庭动态,调用 `recordFeed()`;其余操作不触发。 +- 备注(type=4)仅允许 `create_by` 本人删除,不可编辑;操作日志(type≠4)不暴露删除入口。 +- 活动日志按 `create_time` 升序展示,形成每顿饭的互动时间轴。 +- 餐食安排通过 `source_type` 区分来源:`1` 在家做饭,`2` 外出就餐;后续如需外卖或跳过某餐,再扩展枚举。 +- 外出就餐时,`location` 字段可填餐厅或地点名称,选填。 +- 外出就餐时,`cook_by`(做饭人)字段隐藏不展示。 +- 餐食明细统一保存到 `b_meal_plan_item`,不为外出就餐单独建明细表。 +- 在家做饭时,`b_meal_plan_item.dish_id` 必填,菜名和图片来自菜品库。 +- 外出就餐可以只记录地点,不强制填写具体菜品;如果填写外出菜品明细,则 `b_meal_plan_item.dish_name` 必填,`dish_id` 为空,`image_file_key` 选填。 +- 在家做饭时,`dish_id` 可以为空,即发起一顿饭但不指定菜品,等待其他家庭成员添加。 +- 第一版不单独建餐厅表。只有后续需要复用餐厅、收藏餐厅、统计常去餐厅、人均消费或地图定位时,再新增 `b_meal_restaurant` 并从 `b_meal_plan` 关联。 ## 5.2 简化操作原则 -点菜模块以家庭日常使用为中心,第一版优先保证操作少、入口直观: +餐食模块以家庭日常使用为中心,第一版优先保证操作少、入口直观: - 首页默认展示「今天」,顶部提供「今天 / 明天」快捷切换。 - 每天按家庭启用的餐段展示餐食区块。 - 每个区块直接提供“加菜”入口,不要求用户先进入复杂表单。 - 选择菜品后默认数量为 1,可以直接保存。 -- 点菜备注、数量、驳回原因等字段只在需要时展开。 +- 餐食备注、数量等字段只在需要时展开。 - 菜品录入必须填写菜名并上传图片,食材、做法、标签可以后续补充。 -- 分类和标签管理放到管理页,不打断日常点菜和排餐。 - -## 5.3 点菜状态流转 - -第一版状态建议: - -- `0` 草稿:预留状态,第一版可以不暴露。 -- `1` 待处理:用户提交点菜后进入此状态。 -- `2` 已通过/已安排:处理人确认可以做,或用户直接设置到餐食安排。 -- `3` 已驳回:处理人驳回,需要记录驳回原因。 -- `4` 已完成:菜已经做完或已安排完成。 -- `5` 已取消:点菜人主动取消。 - -推荐流转: - -- 待处理 -> 已通过。 -- 待处理 -> 已驳回。 -- 待处理 -> 已取消。 -- 已通过/已安排 -> 已完成。 -- 已通过/已安排 -> 已取消。 - -第一版不建议支持从已驳回、已完成回退状态,避免历史记录混乱。后续如果需要,可以通过新增操作日志表达更复杂的撤回和重开。 +- 分类和标签管理放到管理页,不打断日常加菜和排餐。 ## 6. 数据对象草案 @@ -156,7 +145,6 @@ - image_file_key - category_id - ingredient_summary -- steps - cooking_time_minutes - difficulty - remark @@ -173,7 +161,6 @@ - `image_file_key`:菜品图片,走现有 S3 规则。 - `image_file_key` 必填。 - `ingredient_summary`:食材摘要,选填,用于列表或详情快速展示;真正的食材和规格保存到 `b_meal_dish_ingredient`。 -- `steps`:做法说明,第一版可用文本保存。 - `cooking_time_minutes`:预计用时,单位分钟,选填。 - `difficulty`:难度,建议 1 简单、2 普通、3 复杂。 - `status`:建议 1 启用,0 停用。 @@ -228,6 +215,31 @@ - 第一版不做库存扣减。 - 后续生成采购清单时,可以按 `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 字段草案: @@ -236,7 +248,7 @@ - family_id - parent_id - name -- icon +- color - sort_number - status - create_time @@ -250,7 +262,7 @@ - `parent_id` 指向父标签时表示子标签,例如微辣、牛肉、蒸、儿童友好。 - 第一版只支持两级结构,不做无限层级。 - 菜品一般关联子标签;如果用户只建了父标签,也允许直接关联父标签,降低操作门槛。 -- `icon` 第一版可选,用于保存 iconfont/lucide 图标名;不建议用表情作为主要 UI 图标。 +- `color` 第一版可选,建议保存十六进制颜色值,例如 `#EF4444`,用于标签背景、文字或边框展示。 ### 菜品标签关联 b_meal_dish_tag @@ -270,23 +282,18 @@ - 一道菜可以有多个标签。 - 查询菜品列表时可以通过该表做标签筛选。 -### 点菜记录 b_meal_order +### 餐食安排 b_meal_plan 字段草案: - id - family_id -- source_type -- order_date +- plan_date - meal_slot_id -- status +- source_type +- location - remark -- reject_reason -- requested_by - cook_by -- handled_by -- handled_time -- completed_time - create_time - update_time - create_by @@ -294,17 +301,13 @@ 说明: -- `source_type`:来源类型,建议 0 快速排餐、1 点菜申请。 -- `order_date`:期望吃这顿的日期,默认当天。 +- `plan_date`:餐食日期,例如今天、明天或用户选择的日期。 - `meal_slot_id`:餐段 ID,指向 `b_meal_slot`。 -- `status`:点菜记录状态。 -- `remark`:点菜人备注。 -- `reject_reason`:驳回原因,仅驳回时必填。 -- `requested_by`:点菜人,通常等于 `create_by`,单独保存便于查询。 -- `cook_by`:做饭人,选填,指向家庭成员用户。 -- `handled_by`:通过或驳回的人。 -- `handled_time`:通过或驳回时间。 -- `completed_time`:标记完成时间。 +- 同一个家庭、同一天、同一个餐段建议只有一条餐食安排。 +- `source_type`:餐食来源,1=在家做饭(默认),2=外出就餐。 +- `location`:餐厅或地点名称,选填,仅外出就餐时有意义,例如「海底捞」「外婆家」。 +- `remark`:这顿饭的备注,选填。 +- `cook_by`:做饭人,选填,仅在家就餐时展示,指向家庭成员用户。 ### 餐段 b_meal_slot @@ -329,14 +332,16 @@ - 不强制初始化默认数据;没有餐段时,前端提供“创建推荐餐段”快捷操作。 - 如果后续需要按时间自动推荐餐段,可以再增加 `start_time`、`end_time`。 -### 点菜明细 b_meal_order_item +### 餐食安排明细 b_meal_plan_item 字段草案: - id - family_id -- order_id +- plan_id - dish_id +- dish_name +- image_file_key - quantity - remark - sort_number @@ -347,22 +352,22 @@ 说明: -- 一个点菜记录可以包含多道菜。 +- 统一保存一顿饭的菜品明细,不区分在家或外出明细表。 +- 在家做饭时,`dish_id` 必填,指向 `b_meal_dish`,图片和菜名从菜品库取;`dish_name` 和 `image_file_key` 可以为空。 +- 外出就餐明细可选;如果填写明细,则 `dish_id` 为空,`dish_name` 必填,自由文本,例如「红烧肉」「海底捞牛肉卷」;`image_file_key` 选填,拍照上传,走现有 S3 规则。 - `quantity` 第一版表示份数或数量,默认 1。 -- 明细独立保存,方便一次点多道菜。 +- 明细独立保存,方便一顿饭安排多道菜,也方便从餐段区块移除单道菜。 -### 点菜操作记录 b_meal_order_log +### 餐食活动日志 b_meal_plan_log 字段草案: - id - family_id -- order_id -- action -- from_status -- to_status -- reason -- operator_id +- plan_id +- type +- content +- ref_id - create_time - update_time - create_by @@ -370,15 +375,25 @@ 说明: -- `action` 建议记录 submit、approve、reject、cancel、complete。 -- 第一版可以先建表并写入关键操作,方便后续做时间线。 -- 如果第一期工期紧,可以暂缓页面展示操作记录,但保存记录仍有价值。 +- 统一记录每顿餐食安排上的操作和互动,用于时间轴展示。 +- `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. 进入「点菜」的「菜品」页。 +1. 进入「餐食」的「菜品」页。 2. 点击新增。 3. 填写菜名并上传图片。 4. 可选填写分类、标签、食材明细、做法、预计用时、备注。 @@ -394,24 +409,27 @@ - 食材明细可以为空。 - 预计用时如果填写,必须大于 0。 -### 快速设置餐食安排 +### 设置餐食安排 1. 进入「今日」页。 2. 默认选中今天。 -3. 页面按家庭启用餐段展示餐食区块。 -4. 点击某个区块的加菜。 -5. 从菜品库选择一道或多道菜。 +3. 页面按家庭启用餐段展示餐食区块,每个区块底部展示该餐的活动时间轴(操作记录 + 备注)。 +4. 点击某个区块的加菜,默认按在家做饭处理。 +5. 从菜品库选择一道或多道菜;如果切换为外出就餐,则填写餐厅或地点,并可选填写临时菜名。 6. 直接保存到该日期和餐段。 -7. 可选设置做饭人。 -8. 切换到明天,可以用同样方式设置明天餐食。 +7. 保存成功后:向 `b_meal_plan_log` 写入 type=2 记录(每道菜一条);调用 `recordFeed()` 触发家庭动态。 +8. 可选设置做饭人;设置后写入 type=5 记录。 +9. 切换到明天,可以用同样方式设置明天餐食。 校验规则: -- 至少选择 1 道菜。 +- 在家做饭时至少选择 1 道菜。 - 日期默认今天,也可以快捷切换明天。 - 餐段必填,来自家庭自定义餐段。 +- 来源默认在家做饭;外出就餐时不展示做饭人。 +- 外出就餐时至少填写餐厅或地点、临时菜名二者之一;如果填写临时菜名,每道菜名不能为空。 - 数量默认 1,不强制用户填写。 -- 快速设置餐食生成 `source_type = 0` 的记录,状态直接为已通过/已安排。 +- 保存时生成或更新 `b_meal_plan` 和 `b_meal_plan_item`;同步写入 `b_meal_plan_log`。 ### 新增菜品并加入餐食安排 @@ -428,69 +446,25 @@ - 分类可以为空。 - 标签可以为空。 -### 发起点菜 - -1. 进入菜品列表。 -2. 选择一道或多道菜。 -3. 点击点菜。 -4. 默认选择今天和当前推荐餐段,也可以切到明天或其他餐段。 -5. 可选填写份数、做饭人和备注。 -6. 提交后生成点菜记录和点菜明细。 -7. 点菜记录状态为待处理。 - -校验规则: - -- 至少选择 1 道菜。 -- 期望日期必填,默认当天。 -- 餐段必填,默认选择当前推荐餐段或第一个启用餐段。 -- 每个明细数量必须大于 0。 -- 点菜申请生成 `source_type = 1` 的记录,状态为待处理。 - -### 处理点菜 - -1. 进入「点菜」或「今日」页。 -2. 查看待处理点菜。 -3. 点击通过,状态变为已通过。 -4. 点击驳回,需要填写驳回原因,状态变为已驳回。 -5. 已通过的点菜可以标记完成。 - -校验规则: - -- 驳回原因必填。 -- 已驳回、已完成的点菜不允许再次处理。 -- 操作后写入点菜操作记录。 - -### 取消点菜 - -1. 点菜人进入自己的点菜记录。 -2. 对待处理或已通过的点菜点击取消。 -3. 状态变为已取消。 -4. 写入点菜操作记录。 - -校验规则: - -- 已完成的点菜不允许取消。 -- 已驳回的点菜不需要取消。 - ### 今日/明日餐食安排 1. 进入「今日」页。 2. 默认按家庭启用餐段展示今天餐食安排。 3. 顶部切换到明天,按同样餐段展示明天餐食安排。 4. 支持继续打开日期选择器查看其他日期。 -5. 每个餐段区块支持加菜、移除菜、再次点菜。 -6. 可从历史记录中再次点菜。 +5. 每个餐段区块支持加菜、移除菜、复制历史餐食。 +6. 可从历史记录中再次安排同样的菜。 ### 快速记账 -1. 在点菜详情或已完成记录上点击记账按钮。 +1. 在某顿餐食安排上点击记账按钮。 2. 弹出或跳转到现有记账新增能力。 3. 默认带入菜品名称、餐段和备注,例如“餐食:番茄炒蛋、排骨汤”。 -4. 保存成功后返回点菜详情或今日页。 +4. 保存成功后返回今日页。 校验规则: -- 记账入口只是快捷入口,不强制每条点菜记录都记账。 +- 记账入口只是快捷入口,不强制每顿饭都记账。 - 记账保存逻辑复用现有记账模块。 ## 8. MVP 范围建议 @@ -505,13 +479,11 @@ - 菜品列表关键词、分类、标签筛选。 - 今天/明天餐食快捷设置。 - 家庭自定义餐段。 -- 发起点菜,支持一次选择多道菜。 -- 点菜支持设置做饭人。 -- 点菜待处理列表。 -- 点菜通过、驳回、取消、完成。 +- 餐食安排支持一次选择多道菜。 +- 餐食安排支持设置做饭人。 +- 餐食安排支持记录外出就餐,外出就餐不单独维护餐厅档案。 - 今日/明日餐食视图。 -- 点菜操作记录保存。 -- 点菜详情或已完成记录提供快速记账按钮。 +- 餐食安排提供快速记账按钮。 第一期暂缓: @@ -522,29 +494,31 @@ - 严格权限控制。 - 菜品评分和偏好统计。 - 菜品复杂 SKU。 -- 点菜消息推送。 +- 餐食消息提醒。 - 餐段开始/结束时间和自动提醒。 +- 想吃列表、审批状态流转和对应操作日志。 +- 餐厅档案、常去餐厅统计、地图定位。 ## 9. 剩余待确认问题 -- 「点菜」是否需要只有家庭管理员或指定成员才能通过/驳回? -- 是否需要把通过后的点菜自动加入一周餐食计划? +- 是否需要后续扩展一周餐食计划? ## 10. 初步技术建议 - 数据库建议新增独立表,全部使用 `b_meal_` 前缀。 - 所有新业务表都包含审计字段,符合项目现有规则。 -- 菜品、食材明细、分类、父子标签、餐段、点菜记录、点菜明细、操作记录保存优先复用 `data/saveData`。 +- 菜品、食材明细、分类、父子标签、餐段、餐食安排、餐食安排明细保存优先复用 `data/saveData`。 - 查询优先使用 `data/loadData` 和 `data/loadDataPage`。 -- 今日/明日餐食可以用 `loadDataBySql` 做菜品、点菜记录、明细的聚合查询;第一版也可以前端分别查询后组合。 -- 删除菜品时优先软删除,避免破坏历史点菜记录。 -- 点菜通过/驳回/完成建议在前端用一次 `saveData` 批量更新点菜记录并插入操作日志。 -- 如果后续要求状态流转强一致和权限校验,再考虑增加通用状态流转 helper,不做点菜专用接口。 +- 今日/明日餐食可以用 `loadDataBySql` 做菜品、餐食安排、明细的聚合查询;第一版也可以前端分别查询后组合。 +- 删除菜品时优先软删除,避免破坏历史餐食安排。 +- 保存餐食安排建议在前端用一次 `saveData` 批量保存 `b_meal_plan` 和 `b_meal_plan_item`。 +- 外出就餐先作为 `b_meal_plan.source_type = 2` 处理,不新增餐厅表;后续确实需要餐厅复用和统计时,再加 `b_meal_restaurant`。 +- 如果后续要求状态流转、想吃列表或权限校验,再单独设计,不放入第一版。 - 图片上传复用现有 S3 上传接口。 -- 前端状态可以新增 `meal` store,负责菜品、分类、标签、点菜记录缓存。 -- 快速记账按钮复用现有记账模块新增能力,不在点菜模块内重复实现记账逻辑。 +- 前端状态可以新增 `meal` store,负责菜品、分类、标签、餐食安排缓存。 +- 快速记账按钮复用现有记账模块新增能力,不在餐食模块内重复实现记账逻辑。 - UI 使用 HeroUI Native、lucide-react-native、@legendapp/list、sonner-native;样式使用 Uniwind `className`。 -- 保存、处理、驳回、取消、完成等异步操作统一使用 `useLoading + LoadingOverlay`。 +- 保存、加菜、移除菜等异步操作统一使用 `useLoading + LoadingOverlay`。 ## 11. 页面建议 @@ -552,32 +526,28 @@ - `app-rn/src/app/meal/(tabs)/_layout.tsx` - `app-rn/src/app/meal/(tabs)/home/index.tsx` -- `app-rn/src/app/meal/(tabs)/orders/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/order/edit/index.tsx` -- `app-rn/src/app/meal/order/detail/[id]/index.tsx` +- `app-rn/src/app/meal/plan/edit/index.tsx` 说明: -- `home`:菜品库。 -- `today`:可以作为 `home` 页顶部默认区域,展示今天/明天餐食安排。 -- `orders`:点菜处理列表。 +- `home`:今天/明天餐食安排。 +- `dishes`:菜品库。 - `manage`:分类和标签维护。 - `dish/edit`:新增/编辑菜品。 -- `order/edit`:发起点菜。 -- `order/detail`:查看状态、通过、驳回、取消、完成。 +- `plan/edit`:编辑某天某餐的菜品。 ## 12. 下一步 下一步可以进入: -1. 确认点菜处理权限。 -2. 数据库表结构设计。 -3. 页面与交互流程设计。 -4. 公共接口调用方案设计。 -5. 第一版任务拆分。 +1. 数据库表结构设计。 +2. 页面与交互流程设计。 +3. 公共接口调用方案设计。 +4. 第一版任务拆分。 ## 13. 实施计划 @@ -591,14 +561,15 @@ - [ ] 设计 `b_meal_dish` 表结构。 - [ ] 设计 `b_meal_dish_ingredient` 表结构,保存食材名称、数量、单位、规格。 +- [ ] 设计 `b_meal_dish_step` 表结构,保存步骤描述和步骤图片。 - [ ] 设计 `b_meal_category` 表结构。 - [ ] 设计 `b_meal_tag` 表结构,包含 `parent_id` 支持父子标签。 - [ ] 设计 `b_meal_dish_tag` 表结构。 - [ ] 设计 `b_meal_slot` 表结构,支持家庭自定义餐段。 -- [ ] 设计 `b_meal_order` 表结构,包含 `source_type`、`meal_slot_id`、`cook_by`。 -- [ ] 设计 `b_meal_order_item` 表结构。 -- [ ] 设计 `b_meal_order_log` 表结构。 -- [ ] 补充索引设计,例如 `family_id/status/order_date/meal_slot_id/sort_number`。 +- [ ] 设计 `b_meal_plan` 表结构,包含 `plan_date`、`meal_slot_id`、`cook_by`、`source_type`、`location`。 +- [ ] 设计 `b_meal_plan_item` 表结构,统一保存餐食明细;在家做饭用 `dish_id`,外出就餐用临时 `dish_name` 和可选 `image_file_key`。 +- [ ] 设计 `b_meal_plan_log` 表结构,包含 `plan_id`、`type`、`content`、`ref_id`,统一记录操作和备注。 +- [ ] 补充索引设计,例如 `family_id/plan_date/meal_slot_id/sort_number`。 - [ ] 生成 SQL 文件并确认命名、字段类型、默认值。 - [ ] 执行 SQL 到 dev 数据库并验证表已创建。 @@ -610,16 +581,14 @@ - 表名全部使用 `b_meal_` 前缀。 - 所有业务表包含审计字段。 -- 点菜历史不会因为菜品删除而丢失。 +- 历史餐食安排不会因为菜品删除而丢失。 - 食材明细可以支持后续采购清单生成。 -- 状态字段能覆盖待处理、已通过、已驳回、已完成、已取消。 -- 快速排餐可以不经过审批,直接进入已通过/已安排状态。 - 餐段可以按家庭自定义、排序和停用。 ### 阶段 2:前端基础模型与公共接口封装 -- [ ] 新增菜品、食材明细、分类、父子标签、餐段、点菜记录、点菜明细、操作记录 TypeScript 类型。 -- [ ] 新增 `meal` store,管理点菜模块缓存。 +- [ ] 新增菜品、食材明细、分类、父子标签、餐段、餐食安排、统一餐食安排明细、活动日志 TypeScript 类型。 +- [ ] 新增 `meal` store,管理餐食模块缓存。 - [ ] 在 `meal` store 中封装基于公共接口的查询方法。 - [ ] 在 `meal` store 中封装基于公共接口的保存方法。 - [ ] 在 `meal` store 中封装图片上传复用逻辑。 @@ -640,10 +609,10 @@ ### 阶段 3:子应用入口与基础导航 -- [ ] 新增点菜应用图标。 -- [ ] 在 `app-rn/src/configs/pages.ts` 注册点菜子应用。 +- [ ] 新增餐食应用图标。 +- [ ] 在 `app-rn/src/configs/pages.ts` 注册餐食子应用。 - [ ] 新增 `meal/(tabs)/_layout.tsx`。 -- [ ] 新增菜品、点菜、管理底部 Tab,菜品页默认展示今天/明天餐食入口。 +- [ ] 新增今日、菜品、管理底部 Tab,今日页默认展示今天/明天餐食安排。 - [ ] 确认子模块使用 `ModuleLayout`。 产出文件: @@ -655,8 +624,8 @@ 验收标准: -- 首页工具列表可以进入点菜模块。 -- 点菜模块底部 Tab 能正常切换。 +- 首页工具列表可以进入餐食模块。 +- 餐食模块底部 Tab 能正常切换。 ### 阶段 4:菜品管理 @@ -672,7 +641,7 @@ - [ ] 支持创建或选择父子标签。 - [ ] 支持编辑菜品。 - [ ] 支持停用或删除菜品。 -- [ ] 删除已有点菜历史的菜品时使用软删除。 +- [ ] 删除已有餐食安排历史的菜品时使用软删除。 产出文件: @@ -687,7 +656,7 @@ - 无图菜品不能保存。 - 食材明细选填,但如果填写则食材名称必填。 - 菜品列表筛选结果正确。 -- 删除菜品不会破坏历史点菜记录。 +- 删除菜品不会破坏历史餐食安排。 ### 阶段 5:分类、父子标签管理 @@ -725,58 +694,41 @@ 验收标准: - 餐段由家庭自定义,不写死。 -- 停用餐段后,不影响历史点菜记录展示。 +- 停用餐段后,不影响历史餐食安排展示。 - 没有餐段时,引导用户先创建餐段。 -### 阶段 6:发起点菜 +### 阶段 6:餐食安排编辑 -- [ ] 支持从菜品列表选择单道菜点菜。 -- [ ] 支持多选菜品后批量点菜。 -- [ ] 新增点菜编辑页或 BottomSheet。 +- [ ] 支持从菜品列表选择单道菜加入餐食。 +- [ ] 支持多选菜品后批量加入餐食。 +- [ ] 新增餐食安排编辑页或 BottomSheet。 - [ ] 支持今天/明天快捷选择。 - [ ] 支持选择家庭自定义餐段。 +- [ ] 支持选择餐食来源:在家做饭或外出就餐。 - [ ] 支持填写每道菜数量。 - [ ] 支持选择做饭人。 -- [ ] 支持填写点菜备注。 -- [ ] 提交后创建点菜记录和点菜明细。 -- [ ] 提交后写入点菜操作记录。 +- [ ] 外出就餐时支持填写餐厅或地点名称,并支持录入临时菜名。 +- [ ] 支持填写餐食备注。 +- [ ] 提交后创建或更新餐食安排和餐食安排明细。 +- [ ] 安排餐食时写入 type=1 日志记录。 +- [ ] 加菜时写入 type=2 日志记录,并调用 `recordFeed()` 触发家庭动态。 +- [ ] 移除菜时写入 type=3 日志记录。 +- [ ] 设置做饭人时写入 type=5 日志记录。 +- [ ] 支持在餐食安排上留下备注(type=4),写入日志并调用 `recordFeed()`。 +- [ ] 备注仅允许 `create_by` 本人删除,不可编辑;操作日志不暴露删除入口。 产出文件: -- `app-rn/src/app/meal/order/edit/index.tsx` +- `app-rn/src/app/meal/plan/edit/index.tsx` 验收标准: -- 至少选择一道菜才能提交。 +- 在家做饭时至少选择一道菜才能提交。 +- 外出就餐时至少填写餐厅或地点、临时菜名二者之一;如果填写多道临时菜名,则每道菜名不能为空。 - 数量必须大于 0。 -- 新提交点菜状态为待处理。 - 保存中有 LoadingOverlay。 -### 阶段 7:点菜处理 - -- [ ] 新增点菜列表页。 -- [ ] 支持按状态筛选。 -- [ ] 支持按日期筛选。 -- [ ] 新增点菜详情页。 -- [ ] 支持通过点菜。 -- [ ] 支持驳回点菜。 -- [ ] 驳回时必须填写原因。 -- [ ] 支持取消点菜。 -- [ ] 支持标记完成。 -- [ ] 所有状态操作写入点菜操作记录。 - -产出文件: - -- `app-rn/src/app/meal/(tabs)/orders/index.tsx` -- `app-rn/src/app/meal/order/detail/[id]/index.tsx` - -验收标准: - -- 状态流转符合文档规则。 -- 已驳回、已完成记录不允许重复处理。 -- 驳回原因能在详情页展示。 - -### 阶段 8:今日/明日餐食安排 +### 阶段 7:今日/明日餐食安排 - [ ] 新增今日/明日餐食区。 - [ ] 默认展示今天餐食安排。 @@ -784,8 +736,12 @@ - [ ] 支持打开日期选择器查看其他日期。 - [ ] 支持按家庭自定义餐段分组展示。 - [ ] 支持在每个餐段区块直接加菜。 -- [ ] 支持从餐段区块移除菜。 -- [ ] 支持从历史餐食安排再次点菜。 +- [ ] 支持把某个餐段切换为外出就餐,并展示餐厅或地点名称。 +- [ ] 支持在每个餐段区块移除菜。 +- [ ] 支持从历史餐食安排再次安排同样的菜。 +- [ ] 每个餐段区块下方展示活动时间轴,按 `create_time` 升序列出操作记录和备注。 +- [ ] 时间轴条目根据 `type` 拼接展示文案:「xxx 安排了这顿饭」「xxx 加了 [菜名]」「xxx 移除了 [菜名]」「xxx 留下了一条备注:[content]」「xxx 设置了做饭人」。 +- [ ] 备注条目(type=4)在当前用户为作者时显示删除按钮;其余条目不显示。 - [ ] 支持空状态。 产出文件: @@ -796,29 +752,46 @@ - 今天和明天餐食安排能按家庭自定义餐段清晰展示。 - 切换日期后数据正确刷新。 -- 再次点菜能复用原菜品生成新点菜记录。 +- 再次安排能复用原菜品生成新的餐食安排明细。 +- 外出就餐能在同一餐段区块展示,不需要进入独立餐厅或外出明细页面。 -### 阶段 8.5:快速记账入口 +### 阶段 8:历史餐食与复用 -- [ ] 在点菜详情或已完成记录上增加记账按钮。 -- [ ] 点击后复用现有记账新增能力。 -- [ ] 默认带入菜品名称、餐段和备注。 -- [ ] 保存成功后返回点菜详情或今日页。 +- [ ] 支持按日期查看历史餐食安排。 +- [ ] 支持复制某顿历史餐食到今天或明天。 +- [ ] 支持从历史餐食进入相关菜品详情。 产出文件: -- `app-rn/src/app/meal/order/detail/[id]/index.tsx` +- `app-rn/src/app/meal/(tabs)/home/index.tsx` 验收标准: -- 快速记账不影响点菜记录状态。 +- 历史餐食不会因为菜品停用而无法展示。 +- 复制历史餐食后能正确生成新的餐食安排。 +- 复制外出就餐时复用临时菜名和地点,不要求创建餐厅档案。 + +### 阶段 8.5:快速记账入口 + +- [ ] 在餐食安排上增加记账按钮。 +- [ ] 点击后复用现有记账新增能力。 +- [ ] 默认带入菜品名称、餐段和备注。 +- [ ] 保存成功后返回今日页。 + +产出文件: + +- `app-rn/src/app/meal/(tabs)/home/index.tsx` + +验收标准: + +- 快速记账不影响餐食安排。 - 记账保存逻辑与现有记账模块一致。 ### 阶段 9:收尾与体验优化 - [ ] 补充空状态。 - [ ] 补充加载状态。 -- [ ] 补充保存中、处理中状态。 +- [ ] 补充保存中状态。 - [ ] 补充错误提示。 - [ ] 检查移动端小屏布局。 - [ ] 检查图片加载失败兜底。 @@ -829,7 +802,7 @@ 验收标准: -- 核心流程从新增菜品到发起点菜、通过/驳回、完成可完整走通。 +- 核心流程从新增菜品到设置今天/明天餐食可完整走通。 - 异常状态有明确反馈。 - 文档计划状态和代码实现保持一致。 @@ -839,10 +812,10 @@ - [ ] 采购清单生成。 - [ ] 菜品评分和家庭偏好统计。 - [ ] 家庭角色权限控制。 -- [ ] 点菜消息推送。 +- [ ] 餐食消息提醒。 - [ ] AI 菜谱或餐食推荐。 验收标准: -- 后置功能不影响第一版点菜主流程。 +- 后置功能不影响第一版餐食安排主流程。 - 每个后置功能开始前先单独确认范围。 diff --git a/code/app/app-go/db/meal.sql b/code/app/app-go/db/meal.sql new file mode 100644 index 00000000..27ef42ff --- /dev/null +++ b/code/app/app-go/db/meal.sql @@ -0,0 +1,18 @@ +drop table if exists b_meal_dish_step; + +create table b_meal_dish_step ( + id bigint primary key, + family_id bigint not null, + dish_id bigint not null, + step_number int not null, + description varchar(1024) default '', + image_file_key varchar(512) default '', + sort_number int not null default 0, + create_time timestamp, + update_time timestamp, + create_by bigint, + update_by bigint +); + +create index idx_b_meal_dish_step_dish + on b_meal_dish_step (family_id, dish_id, sort_number, step_number, id);