Files
msh-system/.cursor/plans/计算器结果保存食谱_f149b3dc.plan.md

7.1 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
计算器结果保存食谱 在用户采纳营养计划时,将食谱计算器的配餐方案提取并保存到 v2_recipes 食谱表,并在首页"精选食谱"中混合展示用户自己的食谱(排在前面)。
id content status
db-migration 新建 SQL 变更文件v2_recipes 表新增 source 和 source_id 字段 completed
id content status
entity-update V2Recipe.java 实体类新增 source 和 sourceId 属性 completed
id content status
adopt-save-recipe ToolCalculatorServiceImpl.adopt() 中新增保存食谱到 v2_recipes 的逻辑(含幂等检查) completed
id content status
home-mix-recipes ToolHomeServiceImpl.getRecommendedRecipes() 混入当前用户的计算器食谱 completed
id content status
home-return-fields 推荐食谱接口返回字段补充 description、source、totalProtein completed
id content status
frontend-recipe-card 首页 index.vue 食谱卡片展示适配tag、desc 等字段映射) completed
false

食谱计算器结果保存到食谱表

整体流程

sequenceDiagram
    participant User as 用户
    participant FE as 前端
    participant Ctrl as ToolController
    participant CalcSvc as ToolCalculatorServiceImpl
    participant RecipeDao as V2RecipeDao
    participant HomeSvc as ToolHomeServiceImpl

    User->>FE: 点击"采纳计划"
    FE->>Ctrl: POST /calculator/adopt
    Ctrl->>CalcSvc: adopt(resultId)
    CalcSvc->>CalcSvc: 创建营养计划 (已有逻辑)
    CalcSvc->>RecipeDao: 保存一条食谱到 v2_recipes
    CalcSvc-->>FE: 返回 adoptResponse
    Note over FE: 首页刷新时
    FE->>Ctrl: GET /home/recipes
    Ctrl->>HomeSvc: getRecommendedRecipes()
    HomeSvc->>RecipeDao: 查询推荐食谱 + 用户自己的食谱
    HomeSvc-->>FE: 返回混合列表

1. 数据库变更 - v2_recipes 新增字段

需要新增两个字段以追踪食谱来源:

ALTER TABLE v2_recipes
  ADD COLUMN source VARCHAR(20) DEFAULT 'manual' COMMENT '来源manual(手动)/calculator(计算器)/ai(AI生成)' AFTER sort_order,
  ADD COLUMN source_id BIGINT DEFAULT NULL COMMENT '来源ID如计算器结果ID' AFTER source;

同时新增一个变更 SQL 文件记录此次 DDL。

2. 后端 - 实体类更新

文件: V2Recipe.java

新增两个字段:

@ApiModelProperty(value = "来源manual/calculator/ai")
private String source;

@ApiModelProperty(value = "来源ID计算器结果ID等")
private Long sourceId;

3. 后端 - 采纳时保存食谱

文件: ToolCalculatorServiceImpl.java

adopt() 方法中,步骤 5创建营养计划之后新增步骤"保存食谱到 v2_recipes"

  • 注入 V2RecipeDao
  • V2CalculatorResult 中解析 mealPlanJson 得到 MealPlan
  • 构建 V2Recipe 对象:
    • userId = 当前用户ID
    • name = "每日营养配餐 - {ckdStage}",如 "每日营养配餐 - CKD 5期"
    • description = "蛋白质 {proteinIntake}g/天 | 能量 {energyIntake}kcal/天"
    • coverImage = 取午餐第一道菜的图片 URL最具代表性
    • mealType = null整日配餐非单餐
    • category = "营养配餐"
    • tagsJson = ["AI配餐", "{ckdStage}"]
    • ingredientsJson = 聚合三餐所有食材
    • stepsJson = 存放完整 mealPlanJson早/午/晚餐详情),复用此字段存储配餐详情
    • totalProtein = result.getProteinIntake()
    • totalEnergy = result.getEnergyIntake()
    • suitableStagesJson = ["{ckdStage}"]
    • suitableDialysis = result.getHasDialysis()
    • status = "published"
    • isRecommend = 0不进入官方推荐通过 source + userId 查询)
    • isOfficial = 0
    • source = "calculator"
    • sourceId = resultId
  • 幂等处理:先检查是否已存在 source='calculator' AND source_id=resultId 的记录,避免重复

4. 后端 - 首页推荐食谱混入用户食谱

文件: ToolHomeServiceImpl.java

修改 getRecommendedRecipes() 方法:

  1. 如果用户已登录,先查询该用户的食谱(user_id = currentUserId AND status = 'published' AND source = 'calculator',按 created_at DESC,取最新 1 条)
  2. 再查询官方推荐食谱(现有逻辑,is_recommend = 1
  3. 将用户食谱排在前面,官方推荐排在后面,合并后返回
  4. 总数仍控制在 limit 范围内(如用户有 1 条自己的食谱,则官方推荐取 limit-1 条)
  5. 缓存 key 需要区分用户(登录用户的缓存 key 加上 userId

5. 后端 - 推荐食谱接口返回字段补充

文件: ToolHomeServiceImpl.java

在返回数据 map 中增加字段,使前端能够区分并展示更多信息:

map.put("id", recipe.getRecipeId());
map.put("name", recipe.getName());
map.put("coverImage", recipe.getCoverImage());
map.put("totalEnergy", recipe.getTotalEnergy());
map.put("description", recipe.getDescription());  // 新增
map.put("source", recipe.getSource());            // 新增:标记来源
map.put("totalProtein", recipe.getTotalProtein()); // 新增

6. 前端 - 首页食谱展示适配

文件: index.vue (首页)

调整食谱卡片展示逻辑:

  • item.tag:如果 source === 'calculator' 显示 "我的配餐",否则显示 "推荐"
  • item.tagClass:根据来源使用不同样式(如用户食谱用不同颜色)
  • item.desc:使用 description 字段(如 "蛋白质 75.6g/天 | 能量 2205kcal/天"
  • item.time:可不显示或显示 "每日配餐"
  • item.views:使用 viewCount 或隐藏

修改 loadData 中对 recipeList 的处理逻辑,将后端返回的数据映射为前端需要的格式。

7. 前端 - 食谱详情页适配

点击首页食谱卡片跳转到 recipe-detail 页面,需要确认该页面能正确显示来自计算器的食谱内容(特别是 stepsJson 中存储的 mealPlan 数据)。如果需要特殊处理,在详情页根据 source 字段做渲染分支。

涉及文件清单

层级 文件 改动
SQL docs/sql/v2_recipes_add_source.sql(新建) 新增 source、source_id 字段
Entity V2Recipe.java 新增 source、sourceId 字段
Service ToolCalculatorServiceImpl.java adopt() 中新增保存食谱逻辑
Service ToolHomeServiceImpl.java getRecommendedRecipes() 混入用户食谱
Frontend msh_single_uniapp/pages/tool_main/index.vue 食谱卡片展示适配