profit-waterfall API的received/consumption/discount/store_contribution 改为仅计算has_expense门店(FILTER WHERE has_expense) 修复前: received=6441万(94家) store_contribution=770万 修复后: received=6369万(92家) store_contribution=698万 现在瀑布图和指标卡的贡献利润/食材率/费用率/贡献率完全一致 同时创建数据溯源审计文档,覆盖全部页面的指标溯源和口径对比
17 KiB
全页面数据溯源审计报告
目标:逐页面、逐指标追溯显示名称 → API → SQL → 数据源表字段,标出跨页面重复指标口径是否一致。
一、页面与 API 总览
| 页面 | 文件 | 调用的 API |
|---|---|---|
| 总部驾驶舱 | DashboardPage.tsx | /overview, /overview/daily, /stores/risk, /stores/priority, /tasks/loop-health, /stores/quadrant, /platform/economics, /situational-awareness/alerts, /store-expense/overview, /overview/yoy, /overview/mom, /overview/trend, /overview/profit-trend |
| 老板驾驶舱 | BossPage.tsx | /overview, /overview/daily, /store-expense/overview, /overview/profit-waterfall, /stores/risk, /stores/priority, /cost-analysis/store-overview, /store-expense/expense-structure, /overview/store-profit-ranking, /overview/profit-opportunity |
| 门店工作台 | StorePage.tsx | /stores/risk, /stores/priority, /tasks/stores/:code/daily-card, /tasks, /stores/:code/daily, /tasks/followup, /sku/attach, /sku/abc, /stores/:code, /situational-awareness/health-score, /stores/:code/meal-period, /stores/:code/category-mix, /stores/:code/cost, /stores/:code/member, /stores/:code/anomalies, /stores/:code/staffing |
| 成本分析 | CostPage.tsx | /cost/comparison, /cost/inventory, /cost/category-benchmark |
| 成本分析(Tab) | cost-analysis/*.tsx | /cost-analysis/overview, /category-comparison, /margin-deviation, /variance-top, /menu-engineering, /profitability, /pricing, /store-overview, /store-ranking, /bom-, /packaging-, /material-, /data-quality, /unmatched- |
| 费用分析(Tab) | store-expense/*.tsx | /store-expense/overview, /expense-structure, /store-ranking, /store-contribution, /break-even, /loss-diagnosis, /delivery-commission, /rent-risk, /fixed-variable, /efficiency, /store-evaluation |
| 风险监控 | RiskPage.tsx | /risk/anomaly, /risk/zero-received, /risk/cashier |
| 会员复购 | MemberPage.tsx | /member/comparison, /member/repeat |
| SKU分析 | SKUPage.tsx | /sku/abc, /sku/category |
| 菜单工程 | MenuEngineeringPage.tsx | /analytics-enhanced/menu-engineering/actions |
| 产品生命周期 | ProductLifecyclePage.tsx | /product/products, /product/reviews/overview, /product/reviews |
| BOM穿透 | BomPenetrationPage.tsx | /central-kitchen/bom-penetration |
| 分销对账 | DistributionReconciliationPage.tsx | /distribution/reconciliation |
| 生产计划 | ProductionPlanPage.tsx | /sales-driven/production-plan |
| 任务闭环 | TasksPage.tsx | /tasks |
| 数据导入 | DataImportPage.tsx | /product/import-logs, /product/quality-rules |
| 本体浏览 | OntologyPage.tsx | /tasks/ontology/* |
二、核心指标溯源与口径对比
2.1 营业收入(消费金额)
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|---|---|---|---|---|---|
| 总部驾驶舱 | od?.consumption |
/overview | consumption |
sum(consumption) from bill_fact |
analytics.bill_fact.consumption |
| 老板驾驶舱 | od?.consumption |
/overview | consumption |
同上 | 同上 |
| 费用总览Tab | ov.total_consumption |
/store-expense/overview | total_consumption |
sum(consumption) from bill_fact CTE |
analytics.bill_fact.consumption |
口径:一致 ✅ — 三个页面均来自 analytics.bill_fact.consumption 的月度汇总。
2.2 优惠
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|---|---|---|---|---|---|
| 总部驾驶舱 | od?.discount |
/overview | discount |
sum(discount_total) from bill_fact |
analytics.bill_fact.discount_total |
| 老板驾驶舱 | od?.discount |
/overview | discount |
同上 | 同上 |
| 费用总览Tab | ov.total_discount |
/store-expense/overview | total_discount |
sum(discount_total) from bill_fact CTE |
analytics.bill_fact.discount_total |
口径:一致 ✅(已修复,BossPage 之前用 ex?.total_discount 也一致)
2.3 实收
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|---|---|---|---|---|---|
| 总部驾驶舱 | od?.received |
/overview | received |
sum(received_total) from bill_fact |
analytics.bill_fact.received_total |
| 老板驾驶舱 | od?.received |
/overview | received |
同上 | 同上 |
| 费用总览Tab | ov.total_received |
/store-expense/overview | total_received |
sum(r.received) from mv_store_risk_rating_monthly |
analytics.mv_store_risk_rating_monthly.received |
| 利润瀑布 | wf.received |
/overview/profit-waterfall | received |
sum(r.received) from mv_store_risk_rating_monthly |
analytics.mv_store_risk_rating_monthly.received |
口径:一致 ✅(已修复)— bill_fact.received_total 汇总和 mv_store_risk_rating_monthly.received 汇总结果相同(均为 64,409,339.09),因为后者物化视图就来自前者。
2.4 账单数
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|---|---|---|---|---|---|
| 总部驾驶舱 | od?.bill_count |
/overview | bill_count |
count(*) from bill_fact |
analytics.bill_fact |
| 老板驾驶舱 | ex?.total_bills |
/store-expense/overview | total_bills |
sum(bill_count) from mv_store_risk_rating_monthly |
analytics.mv_store_risk_rating_monthly.bill_count |
口径:一致 ✅ — 值均为 1,682,360。
2.5 客单价
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.avg_bill_value |
/overview | avg_bill_value |
avg(received_total) from bill_fact = 38.29 |
| 老板驾驶舱 | ex?.avg_bill_value |
/store-expense/overview | avg_bill_value |
sum(received)/sum(bill_count) = 38.29 |
口径:一致 ✅ — 数学结果相同。
2.6 优惠率
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.discount_rate_pct |
/overview | discount_rate_pct |
avg(discount_total/consumption*100) from bill_fact = 19.52% |
| 老板驾驶舱 | 无(不显示此指标) | - | - | - |
口径:N/A — 仅总部驾驶舱显示。
2.7 理论毛利率
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.theoretical_margin_pct |
/overview | theoretical_margin_pct |
sum(theoretical_profit)/sum(received)*100 from bill_fact = 61.84% |
口径:N/A — 仅总部驾驶舱显示。(已修复,之前硬编码为0)
2.8 会员占比
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.member_share_pct |
/overview | member_share_pct |
sum(received_total) FILTER(member_id非空)/sum(received_total)*100 = 14.25% |
口径:N/A — 仅总部驾驶舱显示。(已修复,之前硬编码为0)
2.9 门店贡献利润(实际)
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|---|---|---|---|---|---|
| 总部驾驶舱 | ex?.actual_net_profit |
/store-expense/overview | actual_net_profit |
sum(received) FILTER(费用匹配) - sum(food_cost) - sum(operating_expense) |
6,982,110.42 |
| 老板驾驶舱(指标卡) | ex?.actual_net_profit |
/store-expense/overview | actual_net_profit |
同上 | 6,982,110.42 |
| 老板驾驶舱(瀑布图) | wf.store_contribution |
/overview/profit-waterfall | store_contribution |
sum(received) - sum(COALESCE(food_cost,0)) - sum(COALESCE(operating_expense,0)) |
7,703,472.16 |
口径:不一致 ❌ — 瀑布图用 COALESCE(...,0) 包含2家无费用门店,导致利润虚高72万。需修复 profit-waterfall API。
2.10 贡献率(实际)
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|---|---|---|---|---|---|
| 总部驾驶舱 | ex?.actual_net_margin_pct |
/store-expense/overview | actual_net_margin_pct |
(matched_received - food_cost - operating_expense)/matched_received*100 |
10.96% |
| 老板驾驶舱(指标卡) | ex?.actual_net_margin_pct |
/store-expense/overview | actual_net_margin_pct |
同上 | 10.96% |
| 老板驾驶舱(瀑布图) | 前端计算 wf.store_contribution/wf.received*100 |
/overview/profit-waterfall | 前端除法 | 7703472/64409339*100 |
11.96% |
口径:不一致 ❌ — 同 2.9,瀑布图口径不同。
2.11 食材成本
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | ex?.total_food_cost |
/store-expense/overview | total_food_cost |
sum(actual_food_cost) from mv_store_operating_expense_monthly |
| 老板驾驶舱(瀑布图) | wf.food_cost |
/overview/profit-waterfall | food_cost |
sum(COALESCE(actual_food_cost,0)) — 含2家0值门店 |
| 费用总览Tab | ov.total_food_cost |
/store-expense/overview | total_food_cost |
同总部 |
口径:一致 ✅ — 2家无费用门店的 food_cost 为 NULL,sum(NULL) 忽略,sum(COALESCE(NULL,0)) 加0,结果相同。
2.12 食材成本率
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|---|---|---|---|---|---|
| 总部驾驶舱 | ex?.actual_food_cost_rate_pct |
/store-expense/overview | actual_food_cost_rate_pct |
sum(food_cost)/matched_received*100 |
35.26% |
| 老板驾驶舱(瀑布图) | 前端计算 wf.food_cost/wf.received*100 |
/overview/profit-waterfall | 前端除法 | 22459074/64409339*100 |
34.87% |
口径:不一致 ❌ — 分母不同(matched_received 6369万 vs all_received 6441万)。
2.13 经营费用
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | ex?.total_expense |
/store-expense/overview | total_expense |
sum(operating_expense) — NULL被sum忽略 |
| 老板驾驶舱(瀑布图) | wf.total_expense |
/overview/profit-waterfall | total_expense |
sum(COALESCE(operating_expense,0)) — 2家为0 |
| 费用总览Tab | ov.total_expense |
/store-expense/overview | total_expense |
同总部 |
口径:一致 ✅ — sum忽略NULL vs COALESCE加0,结果相同。
2.14 费用率
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|---|---|---|---|---|---|
| 总部驾驶舱 | ex?.overall_expense_rate_pct |
/store-expense/overview | overall_expense_rate_pct |
sum(operating_expense)/matched_received*100 |
53.77% |
| 老板驾驶舱(瀑布图) | 前端计算 wf.total_expense/wf.received*100 |
/overview/profit-waterfall | 前端除法 | 34246793/64409339*100 |
53.17% |
| 费用总览Tab | ov.overall_expense_rate_pct |
/store-expense/overview | overall_expense_rate_pct |
同总部 | 53.77% |
口径:不一致 ❌ — 瀑布图分母含全部94家。
2.15 人工费用 / 人工费率
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | ex?.total_wage / ex?.overall_wage_rate_pct |
/store-expense/overview | total_wage / overall_wage_rate_pct |
sum(wage_expense) / sum(wage)/matched_received*100 |
| 老板驾驶舱(瀑布图) | wf.wage |
/overview/profit-waterfall | wage |
sum(COALESCE(wage_expense,0)) |
| 费用总览Tab | ov.total_wage / ov.overall_wage_rate_pct |
/store-expense/overview | 同总部 | 同总部 |
金额口径:一致 ✅ — sum忽略NULL vs COALESCE加0结果相同。
费率口径:瀑布图不一致 ❌ — 前端用 wf.wage/wf.received*100(分母含94家)vs store-expense用 matched_received(92家)。
2.16 房租费用 / 房租费率
同 2.15,金额一致,费率瀑布图分母不一致。
2.17 水电费用 / 水电费率
同 2.15,金额一致,费率瀑布图分母不一致。
2.18 外卖佣金
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | ex?.total_commission |
/store-expense/overview | total_commission |
sum(delivery_commission_expense) |
| 老板驾驶舱(瀑布图) | wf.commission |
/overview/profit-waterfall | commission |
sum(COALESCE(delivery_commission_expense,0)) |
口径:一致 ✅ — 金额相同。
2.19 门店数
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | riskRows.length |
/stores/risk | count of rows | count(*) from mv_store_risk_rating_monthly |
| 老板驾驶舱 | ex?.total_stores |
/store-expense/overview | total_stores |
count(*) from full_scope (mv_store_risk_rating_monthly) |
口径:一致 ✅ — 均为94家。
2.20 盈利/亏损门店数
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|---|---|---|---|---|
| 总部驾驶舱 | ex?.profitable_stores / ex?.loss_stores |
/store-expense/overview | profitable_stores / loss_stores |
count(*) FILTER(actual_store_contribution>0) / count(*) FILTER(<=0 AND received>0) |
| 老板驾驶舱 | 同上 | 同上 | 同上 | 同上 |
口径:一致 ✅ — 盈利78家/亏损13家。
2.21 门店风险分布
| 页面 | 前端变量 | API | 数据源 |
|---|---|---|---|
| 总部驾驶舱 | riskSummary |
/stores/risk | analytics.mv_store_risk_rating_monthly.risk_level |
| 老板驾驶舱 | riskSummary |
/stores/risk | 同上 |
口径:一致 ✅
2.22 P0/P1 门店
| 页面 | 前端变量 | API | 数据源 |
|---|---|---|---|
| 总部驾驶舱 | priorityRows |
/stores/priority | analytics.mv_store_action_priority_deep_monthly |
| 老板驾驶舱 | priorityRows |
/stores/priority | 同上 |
口径:一致 ✅
2.23 成本异常分布
| 页面 | 前端变量 | API | 数据源 |
|---|---|---|---|
| 老板驾驶舱 | costOv.red_count 等 |
/cost-analysis/store-overview | analytics.mv_store_theoretical_actual_cost_monthly |
| 成本分析Tab | 同上 | 同上 | 同上 |
口径:一致 ✅
2.24 利润机会池
| 页面 | 前端变量 | API | 数据源 |
|---|---|---|---|
| 老板驾驶舱 | profitOpp |
/overview/profit-opportunity | analytics.mv_store_risk_rating_monthly + mv_store_operating_expense_monthly |
口径:N/A — 仅老板驾驶舱显示。
2.25 日度趋势
| 页面 | 前端变量 | API | 数据源 |
|---|---|---|---|
| 总部驾驶舱 | dailyRows |
/overview/daily | analytics.mv_overview_daily 或 bill_fact |
| 老板驾驶舱 | dailyRows |
/overview/daily | 同上 |
口径:一致 ✅
三、发现的问题汇总
问题1:利润瀑布 store_contribution 口径不一致 ❌
位置:/overview/profit-waterfall API (data.ts:1082)
现状:
round(sum(received) - sum(actual_food_cost) - sum(operating_expense), 2) AS store_contribution
sum(received)= 64,409,339(94家)sum(actual_food_cost)= 22,459,074(92家,NULL被忽略)sum(operating_expense)= 34,246,793(92家,NULL被忽略)- 结果 = 7,703,472(含2家无费用门店的实收429万作为"利润")
正确值(与 store-expense/overview 一致):6,982,110(仅92家匹配门店)
影响:BossPage 利润瀑布图和占比条显示的"门店贡献利润"比指标卡多72万,贡献率高1个百分点。
问题2:利润瀑布各项费率分母不一致 ❌
位置:BossPage.tsx 前端计算 (line 296-318)
现状:前端用 wf.received(64,409,339,94家)做分母计算食材成本率、费用率、贡献率,但 store-expense/overview 用 matched_received(63,687,977,92家)做分母。
| 指标 | 瀑布图口径 | store-expense口径 | 差异 |
|---|---|---|---|
| 食材成本率 | 34.87% | 35.26% | 0.39pp |
| 费用率 | 53.17% | 53.77% | 0.60pp |
| 贡献率 | 11.96% | 10.96% | 1.00pp |
问题3:mv_overview_monthly 刷新机制不完整 ⚠️
现状:mv_overview_monthly 是普通表(非物化视图),之前刷新脚本未包含它的更新步骤,导致数据导入后该表不更新。
已修复:刷新脚本已加入 DELETE+INSERT 步骤。
四、修复方案
修复问题1+2:统一利润瀑布口径
将 /overview/profit-waterfall 的 store_contribution 和 received 改为仅计算有费用门店,与 /store-expense/overview 保持一致。
修改文件:server/src/routes/data.ts profit-waterfall API
修改内容:
received→sum(received) FILTER (WHERE has_expense)store_contribution→sum(received) FILTER (WHERE has_expense) - sum(actual_food_cost) - sum(operating_expense)consumption和discount也改为FILTER (WHERE has_expense)保持同口径
这样瀑布图的 received、food_cost、expense、contribution 全部基于92家匹配门店,与 store-expense/overview 完全一致。