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

411 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 菜品调整指导与验证体系
> 核心目标:从"看数据"升级为"调什么 → 怎么调 → 调完验证 → 持续优化"的闭环
---
## 一、问题分析
当前系统已具备**分析能力**(成本差异、毛利排名、BOM复杂度等),但缺少:
1. **决策指导**:分析结果出来后,具体应该调什么?调价?改配方?下架?
2. **调整记录**:谁在什么时候对哪个菜品做了什么调整?
3. **效果验证**:调整后效果如何?毛利提升了吗?成本下降了吗?
4. **持续迭代**:验证结果反馈到下一轮分析,形成闭环
数据限制:销售明细仅覆盖2026年4月(552万行),5月仅少量数据。菜品成本报表无月份字段。因此**验证阶段需要按周/旬对比**,而非按月。
---
## 二、整体架构
```
分析诊断 → 调整建议 → 决策记录 → 执行跟踪 → 效果验证 → 反馈迭代
↑ |
└──────────────────────────────────────────────────────────────┘
```
### 闭环流程
```
1. 系统自动生成菜品诊断报告(每周/每月)
→ 识别问题菜品:低毛利、高超耗、配方复杂、独有原料
2. 系统生成调整建议(按优先级排序)
→ 调价 / 改配方 / 减份量 / 下架 / 保持
3. 商品部/运营部在系统中确认调整方案
→ 记录:菜品、调整类型、调整前值、调整后值、执行日期、负责人
4. 执行后系统自动跟踪关键指标
→ 对比调整前后7天/14天/30天的销量、毛利、成本差异
5. 系统生成效果验证报告
→ 达标 / 未达标 / 需继续观察
6. 验证结果反馈到下一轮诊断
→ 未达标 → 重新分析原因 → 新一轮调整
```
---
## 三、新增数据表
### 3.1 菜品调整记录表
```sql
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 调整效果验证表
```sql
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 菜品诊断快照表
```sql
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 |