Files
SBrainCO/菜品调整指导与验证体系.md
freedakgmail 3d89baf65d feat: 菜品成本分析模块 - 10个Tab + 31个分析API + 7个调整管理API
- 后端: 新增 cost-analysis.ts 路由,含31个分析端点和7个调整管理端点
- 前端: 新增 CostAnalysisPage 主页面 + 10个Tab组件
  - Tab1-9: 成本总览/菜品盈利/原料差异/BOM配方/供应链/包装耗材/数据质量/门店成本/可视化探索
  - Tab10: 调整管理(诊断快照+调整记录+效果验证)
- 修复: 毛利率和损耗率从简单平均改为加权计算
- 新增: Tabs组件、侧边栏菜单项、路由注册
- 新增: 3张数据库表(诊断快照/调整记录/验证结果)
2026-07-28 16:56:45 +08:00

17 KiB
Raw Permalink Blame History

菜品调整指导与验证体系

核心目标:从"看数据"升级为"调什么 → 怎么调 → 调完验证 → 持续优化"的闭环


一、问题分析

当前系统已具备分析能力(成本差异、毛利排名、BOM复杂度等),但缺少:

  1. 决策指导:分析结果出来后,具体应该调什么?调价?改配方?下架?
  2. 调整记录:谁在什么时候对哪个菜品做了什么调整?
  3. 效果验证:调整后效果如何?毛利提升了吗?成本下降了吗?
  4. 持续迭代:验证结果反馈到下一轮分析,形成闭环

数据限制:销售明细仅覆盖2026年4月(552万行),5月仅少量数据。菜品成本报表无月份字段。因此验证阶段需要按周/旬对比,而非按月。


二、整体架构

分析诊断 → 调整建议 → 决策记录 → 执行跟踪 → 效果验证 → 反馈迭代
   ↑                                                              |
   └──────────────────────────────────────────────────────────────┘

闭环流程

1. 系统自动生成菜品诊断报告(每周/每月)
   → 识别问题菜品:低毛利、高超耗、配方复杂、独有原料

2. 系统生成调整建议(按优先级排序)
   → 调价 / 改配方 / 减份量 / 下架 / 保持

3. 商品部/运营部在系统中确认调整方案
   → 记录:菜品、调整类型、调整前值、调整后值、执行日期、负责人

4. 执行后系统自动跟踪关键指标
   → 对比调整前后7天/14天/30天的销量、毛利、成本差异

5. 系统生成效果验证报告
   → 达标 / 未达标 / 需继续观察

6. 验证结果反馈到下一轮诊断
   → 未达标 → 重新分析原因 → 新一轮调整

三、新增数据表

3.1 菜品调整记录表

CREATE TABLE public.dish_adjustment_log (
  id              SERIAL PRIMARY KEY,
  dish_code       TEXT NOT NULL,           -- 菜品编码
  dish_name       TEXT NOT NULL,           -- 菜品名称
  adjustment_type TEXT NOT NULL,           -- 调整类型:price/recipe/portion/delisting/relaunch
  -- 调整前快照
  before_price              NUMERIC,
  before_theoretical_cost   NUMERIC,
  before_theoretical_margin NUMERIC,
  before_sales_avg_daily    NUMERIC,        -- 调整前日均销量
  before_cost_variance      NUMERIC,        -- 调整前成本差异
  -- 调整后目标
  after_price               NUMERIC,
  after_theoretical_cost    NUMERIC,
  after_target_margin       NUMERIC,        -- 目标毛利率
  target_cost_reduction     NUMERIC,        -- 目标成本降幅
  -- 执行信息
  effective_date  DATE NOT NULL,            -- 执行日期
  decided_by      TEXT,                     -- 决策人
  reason          TEXT,                     -- 调整原因
  diagnosis_id    INTEGER,                  -- 关联诊断报告ID
  status          TEXT DEFAULT 'planned',   -- planned/executing/completed/cancelled
  created_at      TIMESTAMPTZ DEFAULT now(),
  updated_at      TIMESTAMPTZ DEFAULT now()
);

3.2 调整效果验证表

CREATE TABLE public.dish_adjustment_result (
  id              SERIAL PRIMARY KEY,
  adjustment_id   INTEGER NOT NULL REFERENCES public.dish_adjustment_log(id),
  -- 验证周期
  period_type     TEXT NOT NULL,            -- 7d/14d/30d
  period_start    DATE NOT NULL,
  period_end      DATE NOT NULL,
  -- 调整后实际值
  actual_sales_avg_daily    NUMERIC,        -- 实际日均销量
  actual_sales_change_pct   NUMERIC,        -- 销量变化率
  actual_margin             NUMERIC,        -- 实际毛利率
  actual_margin_change      NUMERIC,        -- 毛利率变化(百分点)
  actual_cost_variance      NUMERIC,        -- 实际成本差异
  actual_cost_change_pct    NUMERIC,        -- 成本变化率
  -- 评估
  target_achieved  BOOLEAN,                 -- 是否达标
  assessment       TEXT,                    -- 达标/未达标/需继续观察
  notes            TEXT,                    -- 备注
  created_at       TIMESTAMPTZ DEFAULT now()
);

3.3 菜品诊断快照表

CREATE TABLE public.dish_diagnosis_snapshot (
  id              SERIAL PRIMARY KEY,
  diagnosis_date  DATE NOT NULL,
  dish_code       TEXT NOT NULL,
  dish_name       TEXT NOT NULL,
  -- 诊断指标快照
  category_l1              TEXT,
  sales_amount             NUMERIC,
  sales_quantity           NUMERIC,
  theoretical_margin_pct   NUMERIC,
  actual_margin_pct        NUMERIC,
  cost_variance_amount     NUMERIC,
  cost_tier                TEXT,            -- 正常/关注/整改/紧急/数据异常
  bom_complexity_score     NUMERIC,
  unique_material_count    INTEGER,
  waste_rate_avg           NUMERIC,
  -- 诊断结论
  diagnosis_type   TEXT,                    -- low_margin/high_variance/over_complex/data_anomaly/unique_material_risk
  diagnosis_detail TEXT,                    -- 详细诊断描述
  suggested_action TEXT,                    -- 建议动作:price_up/price_down/recipe_optimize/portion_reduce/delist/fix_data/monitor
  priority         TEXT,                    -- P0/P1/P2/P3
  created_at       TIMESTAMPTZ DEFAULT now()
);

四、调整建议引擎

4.1 自动诊断规则

系统根据分析数据自动生成诊断和建议:

诊断类型 触发条件 建议动作 优先级
低毛利-定价偏低 理论毛利率 < 30% 且实际毛利率 > 理论 涨价(上调10-20% P1
低毛利-成本偏高 理论毛利率 < 50% 且实际 < 理论 优化BOM/换供应商 P1
高超耗-份量超标 成本差异 > 0 且损耗率 > 20% 减份量/加强操作规范 P0
高超耗-物料分摊 成本差异 > 0 且损耗率 > 100% 先修复数据分摊 P0
配方复杂-低销量 物料数 > 15 且日销 < 5份 简化配方或下架 P2
独有原料-低收入 独有原料数 > 3 且月收入 < 5000 评估下架 P2
数据异常-成本率>100% 实际毛利率 < 0 先修复BOM/单位/分摊 P0
负毛利菜品 理论毛利率 < 0 重新核算成本或涨价 P0
正常但可优化 实际超理论 0-10% 监控,暂不调整 P3

4.2 调整建议模板

每种建议动作对应一个模板:

涨价建议

菜品:{dish_name}
当前售价:{price}元 → 建议售价:{price * 1.15}元
当前理论毛利率:{margin}% → 预期毛利率:{expected_margin}%
预计月增收:{(new_price - old_price) * monthly_sales}元
风险:销量可能下降5-15%
建议:先在3-5家门店试调,观察2周销量变化

减份量建议

菜品:{dish_name}
超标原料:{material_name}
理论用量:{theoretical_qty} → 建议标准用量:{reduced_qty}
当前损耗率:{waste_rate}% → 预期损耗率:{target_waste_rate}%
预计月节省:{savings}元
风险:顾客感知,需同步调整售价或保持不变
建议:先在1-2家门店试调,收集顾客反馈

下架建议

菜品:{dish_name}
月销售额:{sales}元(排名 bottom 10%
独有原料:{unique_materials}种
下架后可释放:{releasable_materials}种物料
月收入影响:{sales}元
月毛利影响:{profit}元(可能为正,因为亏损菜品)
库存处置:需处理{inventory_value}元独有原料库存
建议:先评估是否有替代菜品可消化独有原料

五、验证方法

5.1 对比维度

维度 调整前 调整后 对比方法
日均销量 调整前7天均值 调整后7天/14天均值 变化率 = (后-前)/前
毛利率 调整前理论/实际毛利率 调整后理论/实际毛利率 变化 = 后 - 前(百分点)
成本差异 调整前成本差异额 调整后成本差异额 变化率 = (后-前)/前
物料损耗率 调整前损耗率 调整后损耗率 变化 = 后 - 前
顾客反馈 差评/投诉数 定性评估

5.2 验证周期

周期 适用场景 说明
7天 涨价/减份量 快速验证销量变化
14天 配方优化 验证成本差异变化
30天 下架/上新 验证整体收入影响

5.3 达标标准

调整类型 达标标准
涨价 销量下降 < 15% 且毛利额增加
减份量 成本差异下降 > 30% 且无顾客投诉
配方优化 实际成本率下降 > 3个百分点
下架 独有原料库存清理完成且总收入影响 < 预期
数据修复 成本率回归合理区间(0-80%

5.4 数据来源

指标 数据来源 频率
销量/销售额 dish_sales_details 每日
理论/实际成本 dish_cost_analysis_summary(需多次导入) 每月
物料损耗 dish_cost_analysis_material_detail(需多次导入) 每月
成本差异 v_store_theoretical_actual_cost_april 每月

关键限制:菜品成本报表目前为单次导入,无月份维度。要实现持续验证,需要每月定期导入新的成本报表,并打上月份标签。


六、前端展现

新增Tab:调整管理

在菜品成本分析页面新增第10个Tab

┌─────────────────────────────────────────────────────────┐
│  调整管理                                                 │
├─────────────────────────────────────────────────────────┤
│  [子Tab] 待处理建议 | 执行中 | 已完成 | 效果验证          │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ── 待处理建议 ──                                        │
│  [MetricCard] P0紧急  [MetricCard] P1重点                │
│  [MetricCard] P2改善   [MetricCard] P3监控               │
│                                                          │
│  DataTable: 菜品 | 诊断类型 | 建议动作 | 优先级(Badge)    │
│             | 当前毛利率 | 预期效果 | [确认调整] [忽略]   │
│                                                          │
│  点击"确认调整" → 弹出调整表单:                          │
│    调整类型: [下拉] 涨价/减份量/改配方/下架               │
│    调整前值: (自动填充)                                   │
│    调整后值: [输入]                                      │
│    执行日期: [日期选择]                                   │
│    负责人: [输入]                                        │
│    备注: [文本框]                                        │
│    [提交] → 保存到 dish_adjustment_log                   │
│                                                          │
│  ── 执行中 ──                                            │
│  DataTable: 菜品 | 调整类型 | 执行日期 | 已执行天数        │
│             | 调整前销量 | 当前销量 | 变化率              │
│             | [查看详情] [标记完成]                      │
│                                                          │
│  ── 已完成 ──                                            │
│  DataTable: 菜品 | 调整类型 | 执行日期 | 完成日期          │
│             | 调整前毛利率 | 调整后毛利率 | 变化           │
│             | 达标状态(Badge) | [查看验证报告]            │
│                                                          │
│  ── 效果验证 ──                                          │
│  选中菜品后展示:                                         │
│  ┌──────────────────────────────────────────┐           │
│  │ LineChart: X轴=日期, Y轴=日均销量          │           │
│  │ 竖线标注: 调整执行日期                      │           │
│  │ 双线: 销量 + 毛利率                         │           │
│  └──────────────────────────────────────────┘           │
│  [MetricCard] 销量变化  [MetricCard] 毛利变化             │
│  [MetricCard] 成本差异变化  [MetricCard] 达标状态         │
│  DataTable: 验证周期 | 销量 | 毛利率 | 成本差异 | 评估     │
└─────────────────────────────────────────────────────────┘

新增API端点

端点 方法 说明
/api/cost-analysis/diagnosis GET 获取最新诊断建议列表
/api/cost-analysis/diagnosis/generate POST 触发生成诊断快照
/api/cost-analysis/adjustment GET 获取调整记录列表
/api/cost-analysis/adjustment POST 创建调整记录
/api/cost-analysis/adjustment/:id PUT 更新调整状态
/api/cost-analysis/adjustment/:id/verify GET 获取验证数据
/api/cost-analysis/adjustment/:id/result POST 提交验证结果

七、完整闭环示例

示例:酱烧琵琶鸡腿饭(实际毛利率-246.50%)

第1步:诊断
  → 系统识别:实际毛利率-246.50%,成本差异+33.6万
  → 诊断类型:data_anomaly(成本率异常)
  → 建议动作:fix_data(先修复BOM/单位/分摊)
  → 优先级:P0

第2步:排查
  → 商品部核查发现:物料分摊错误,鸡腿用量归属到米饭而非鸡腿饭
  → 修复BOM:调整物料归属

第3步:记录调整
  → 调整类型:recipe(配方修复)
  → 执行日期:2026-08-01
  → 调整前:实际毛利率-246.50%,成本差异+33.6万
  → 目标:实际毛利率回归50-70%

第4步:验证(2026-08-087天后)
  → 对比8月1-7日 vs 7月25-31日销量
  → 等待8月成本报表导入后对比毛利率
  → 验证结果:待数据

第5步:反馈
  → 如果毛利率回归正常 → 标记达标 → 闭环结束
  → 如果仍然异常 → 重新诊断 → 新一轮调整

示例:草原游牧羔羊肉串(超耗33.1万)

第1步:诊断
  → 系统识别:实际毛利率51.10% vs 理论61.12%,成本差异+33.1万
  → 诊断类型:high_variance(高超耗)
  → 建议动作:recipe_optimize(优化BOM/加强操作规范)
  → 优先级:P0

第2步:分析原料差异
  → 拆解:羔羊肉理论用量 vs 实际用量
  → 发现:实际用量超理论15%,损耗率-15%
  → 原因:份量超标或切割损耗大

第3步:调整方案
  → 方案A:加强操作规范,标准份量控制在±5%
  → 方案B:更换供应商,降低采购规格偏差
  → 选择方案A,先在TOP10超耗门店试执行

第4步:记录调整
  → 调整类型:portion(份量控制)
  → 执行日期:2026-08-01
  → 调整前:成本差异+33.1万/月
  → 目标:成本差异降至+10万/月以内

第5步:验证(2026-08-1514天后)
  → 对比8月1-14日 vs 7月18-31日
  → 销量变化:观察是否因份量控制影响顾客体验
  → 成本变化:等待8月成本报表导入

第6步:反馈
  → 达标 → 推广到全部门店
  → 未达标 → 升级为方案B(换供应商)

八、数据补充需求

要实现持续验证闭环,需要补充以下数据:

数据 当前状态 需要做什么 优先级
菜品成本报表(按月) 仅4月1次 每月定期导入,增加月份字段 最高
物料采购单价 导入采购系统数据
门店级菜品成本 菜品成本报表增加门店维度
BOM版本变更历史 仅v1.0 每次BOM修改记录版本
顾客反馈/差评 对接评价系统
促销活动记录 记录促销菜品/时间/力度

最小可行闭环(MVP

仅基于现有数据可实现的闭环:

诊断(现有数据)
→ 生成建议(规则引擎)
→ 人工确认调整(调整记录表)
→ 销量验证(dish_sales_details,按周对比)
→ 等待下月成本报表导入后验证成本

销量验证可以立即做,成本验证需要等下次成本报表导入。


九、落地计划

阶段 内容 依赖
阶段1 创建3张表 + 诊断规则引擎 + 诊断API
阶段2 调整记录CRUD + 前端调整管理Tab 阶段1
阶段3 销量验证(基于dish_sales_details按周对比) 阶段2
阶段4 成本验证(需多次导入成本报表) 成本报表按月导入
阶段5 自动化反馈迭代 阶段3+4