2026-10-20-ops-cockpit-design.md 6.3 KB

经营驾驶舱 · 设计文档

  • 日期:2026-10-20
  • 分支:dev
  • 状态:待评审
  • 范围:新增独立菜单「经营驾驶舱」,面向经营总览(不含履约、营销专块)

1. 背景

「店铺运营」现在是明细表 + 卡片,适合逐店核对,但不适合一眼看经营大盘。需要一屏看清:今天做了多少、比昨天好还是差、哪家店在拖后腿、转化在哪一环掉。

数据源:上传的运营明细(平台导出全字段 + 人工统计表),已按「日期 + 门店」合并去重。

2. 首屏内容

经营驾驶舱                         日期 [10.18] ~ [10.19]   学校 ▾   店铺 ▾
┌──────────┬──────────┬──────────┬──────────┬───────────┬─────────┐
│ 营业额    │ 有效订单  │ 客单价    │ 曝光人数  │ 进店转化率 │ 店铺评分 │
│ 2,363.73 │    86    │  27.49   │  6,775   │   8.6%    │  4.62   │
│ ↓ 7.2%   │  ↓12.8%  │  ↑ 6.5%  │  ↓16.1%  │  ↓0.4pp   │   —     │
└──────────┴──────────┴──────────┴──────────┴───────────┴─────────┘
┌────────────────────────────┬────────────────────────────┐
│ 营业额 / 订单趋势(双轴)    │ 门店营业额 Top 10(横向条形) │
├────────────────────────────┼────────────────────────────┤
│ 转化漏斗 曝光→进店→下单      │ 收入结构:收入 / 支出 / 补贴  │
└────────────────────────────┴────────────────────────────┘

3. 指标口径(实现必须统一,不允许前端各算各的)

指标 口径 说明
营业额 Σ 营业额 平台列「营业额」;人工表映射为 revenue
有效订单 Σ 有效订单 整数
客单价 营业额 ÷ 有效订单 订单为 0 时显示 –
曝光人数 Σ 曝光人数
进店转化率 Σ 进店人数 ÷ Σ 曝光人数 不是各店转化率的算术平均
店铺评分 评分 > 0 的门店取均值 未开业/无评分(0)不参与

环比:所选区间 vs 紧邻的前一个等长区间。

  • 金额/数量:(本期 − 上期) ÷ 上期 × 100%
  • 比率:本期 − 上期,单位 pp(百分点)
  • 上期为 0 或无数据:显示 —,不显示 ∞
  • 评分不做环比(评分是存量指标,短期对比意义不大)

4. 四张图

图 形式 数据
趋势 柱(营业额,左轴)+ 线(订单,右轴) 按日聚合
门店排行 横向条形 Top 10 所选区间营业额,带数值标签
转化漏斗 漏斗图 曝光人数 → 进店人数 → 下单人数,标注各层转化率
收入结构 堆叠柱 / 瀑布 收入、支出、活动补贴、商家活动成本(按日)

配色沿用现有主题:主色 #ff6b35,辅助灰 #b8b2ad,ECharts 已在仓库内。

5. 交互

  • 顶部筛选:日期区间、学校多选、店铺多选(复用店铺运营的多选组件与状态)
  • 任一筛选变化 → 重新拉取聚合并重绘,KPI 与四张图同步
  • 图表点击:
    • 门店排行点击某店 → 跳转「店铺运营」并预选该店(可选,二期)
  • 空态:无数据时显示「所选范围没有数据」+ 清空筛选按钮
  • 加载态:KPI 与图表显示骨架/占位,避免闪烁

6. 接口

新增 GET /api/ops/dashboard(服务端聚合,保证口径一致):

?from=20261018&to=20261019&schools=浙江工商大学桐庐校区&shops=537278859

响应:

{
  "from": "20261018", "to": "20261019",
  "prev": { "from": "20261016", "to": "20261017" },
  "kpis": {
    "revenue":    { "value": 2363.73, "prev": 2544.1, "delta": -7.1, "unit": "money" },
    "orders":     { "value": 86, "prev": 99, "delta": -13.1, "unit": "int" },
    "avgTicket":  { "value": 27.49, "prev": 25.7, "delta": 7.0, "unit": "money" },
    "exposure":   { "value": 6775, "prev": 8090, "delta": -16.3, "unit": "int" },
    "conversion": { "value": 0.086, "prev": 0.09, "delta": -0.4, "unit": "pp" },
    "rating":     { "value": 4.62, "prev": null, "delta": null, "unit": "num" }
  },
  "trend": [{ "date": "20261018", "revenue": 2363.73, "orders": 86 }],
  "ranking": [{ "shopId": "...", "shopName": "...", "revenue": 750.7 }],
  "funnel": { "exposure": 6775, "visit": 585, "order": 88 },
  "structure": [{ "date": "20261018", "income": 2363.73, "expense": 747.46, "subsidy": 51.7 }]
}

实现复用 loadMergedRows()(人工 + 平台合并),不动现有表结构。

7. 页面

  • 菜单:经营分析组,新增「经营驾驶舱」,放在「店铺运营」之前
  • 视图标识 cockpit,public/cockpit.js,复用 ops-multi 组件样式
  • 图表用 ECharts(已有),自适应容器宽度,窗口 resize 重绘

8. 边界

场景 表现
无数据 空态提示 + 清空筛选
只有 1 天数据 趋势图只有一根柱;环比显示 —(没有上期)
上期为 0 环比 —,不显示 ∞
存储不可用 显示「数据暂不可用」+ 重试
店铺/学校筛选为空 与店铺运营一致:提示至少选一个

9. 测试

  • 单测:KPI 聚合(含 0 订单客单价、评分排除 0、转化率加权)、环比计算(正负、上期 0、无上期)
  • 接口:/api/ops/dashboard 空库 / 有数据 / 筛选组合
  • 冒烟:只读断言 GET /api/ops/dashboard 200
  • 手测:切日期、切学校、切店铺,KPI 与图表同步;窗口缩放不溢出

10. 待办(评审通过后实施)

  • GET /api/ops/dashboard 聚合实现(复用 loadMergedRows)
  • 前端 public/cockpit.js:筛选、KPI 卡、趋势、排行、漏斗、结构图
  • index.html 菜单与视图骨架、app.js 注册、style.css
  • 测试脚本扩展 + smoke 断言
  • README 增补