7.1 KiB
首页数据看板真实化与统计策略规划
1. 文档定位
本文用于记录 Admin 首页数据看板从原型静态数据接入真实业务数据时的技术规划。本文是后续开发的边界和决策输入,不代表接口、缓存或预聚合已经实现。
适用页面:apps/admin-web/src/modules/dashboard/。
2. 当前状态
2.1 前端
当前首页仍是原型占位页面,指标、趋势、状态分布、TOP10 航线、收入构成和待办事项均由页面常量提供,页面明确标记为“静态演示数据”。当前 Dashboard 模块没有正式 API、store 或后端 DTO。
2.2 后端已有能力
| 领域 | 当前已有能力 | 当前查询特征 |
|---|---|---|
| 订单 | 客户累计及本月已提交运单统计;订单列表和正式状态 | 请求到达时直接查询 ord_order,暂无平台首页聚合 |
| 货柜/在途 | 单客户在途柜量和 TEU 统计 | 直接查询货柜、订舱、装柜计划并去重 |
| 财务 | 单客户正式结算汇总 | 直接查询 fin_settlement;缺正式表时存在零值保护回退 |
| 客户 | 客户分页和状态查询 | 没有首页级客户活跃度聚合 |
| 清关 | 货柜和清关资料/状态业务数据 | 没有首页级待清关聚合 |
| 待办 | 各业务模块分别存在列表或待处理状态 | 没有统一待办汇总 |
2.3 缓存和预聚合现状
当前公共配置提供 Redis,但代码中的 Redis 主要用于登录会话、Token 校验和防重放。未发现 Dashboard 业务缓存、@Cacheable、业务 CacheManager、Caffeine、指标快照表或统计定时刷新任务。
现有 @Scheduled 任务主要用于 Outbox、通知、文件、审计等投递,不属于数据看板统计机制。
因此,当前真实统计能力应描述为“已有部分请求时实时 SQL 聚合”,不能描述为“已有缓存统计”。
3. 目标架构
Dashboard 不应让浏览器循环调用客户列表、订单列表和财务列表再自行计算。建议提供一个面向页面的只读聚合接口:
GET /api/platform/v1/dashboard/overview?zoneId=Asia/Shanghai&days=30
聚合层负责并行调用各领域的内部统计能力,不能跨服务直接 Join 其他服务数据库。响应需要返回统一的 asOf、各区块数据、模块状态和 partialFailures,让单个领域暂时不可用时其他区块仍可展示。
建议分层:
Admin Dashboard
|
v
Dashboard 聚合接口
+-- Order 统计
+-- Firstleg 货柜/清关统计
+-- Finance 财务统计
+-- IAM 客户统计
+-- 待办统计
4. 实时、短缓存和预聚合边界
4.1 第一阶段优先实时查询
以下数据需要较新状态,且可以通过时间/状态索引控制查询成本:
- 今日新运单;
- 当前运单状态分布;
- 待清关柜量;
- 待办数量。
实时的定义是请求时读取业务数据库的已提交事务数据,不承诺跨服务事件已经在同一毫秒内收敛。
4.2 第一阶段短时缓存
以下数据变化频率较低,适合按 platform + zoneId + days 做 30 秒至 2 分钟的 Redis 短缓存:
- 在途柜量和 TEU;
- 近 30 天趋势;
- 活跃客户数;
- 海运 TOP10 航线。
缓存必须携带生成时间和口径版本。业务状态发生重大变更时可主动删除相关 key,但不能把缓存当作业务事实源。
4.3 短缓存或定时预聚合
以下数据跨领域聚合成本较高,建议先短缓存;只有在查询耗时、并发或数据规模验证不满足要求时,再设计按日/按月预聚合:
- 本月财务金额;
- 收入构成;
- 跨服务综合看板快照。
当前不直接引入永久指标表、数据仓库或复杂 MQ 指标链路。是否预聚合必须有实际查询耗时和并发证据。
5. 指标口径初稿
以下是技术实现前需要冻结的口径,不冻结前不得把原型文案直接当成正式指标:
| 页面指标 | 建议口径 | 需要确认 |
|---|---|---|
| 今日新运单 | submittedAt 按 Asia/Shanghai 自然日统计;对比昨日完整自然日 |
是,确认是否只统计 MASTER 根运单 |
| 在途柜量 | 沿用已确认的柜次去重和 TEU 规则;未知箱型单独返回 | 是,确认是否要求实际开船后才算在途 |
| 本月营收 | 必须指定应收结算、实际回款或已发布费用来源之一 | 是,未确认前不得继续使用“营收”文案 |
| 活跃客户 | 建议为近 30 天有已提交运单的去重客户数 | 是,不能用前端拉客户列表后估算 |
| 待清关 | 建议改为“待清关柜量”,统计真实柜次且清关未完成 | 是,确认“即将超期”的截止字段 |
| 30 天趋势 | 服务端按天返回完整日期序列,无数据日期补零;按运输方式聚合 | 是,确认是否拆分海运 FCL/LCL |
| 状态分布 | 使用统一订单正式状态,不沿用旧原型混合节点 | 是,确认展示映射文案 |
| TOP10 航线 | 第一版只做海运,使用稳定起运港/目的港快照并按 TEU 排序 | 是 |
| 收入构成 | 与金额卡片使用同一财务事实源和时间口径,未分类单列其他 | 是 |
| 待办 | 只返回已有业务事实和固定页面路由,不返回任意前端 URL | 是 |
6. 建议响应结构
{
"asOf": "2026-08-14T10:00:00+08:00",
"zoneId": "Asia/Shanghai",
"metrics": {},
"orderTrend": [],
"orderStatusDistribution": [],
"topRoutes": [],
"revenueComposition": [],
"todoSummary": [],
"partialFailures": []
}
每个区块应能表达 loading、empty、unavailable 和 forbidden。Finance 缺表或查询异常不能静默显示为真实的零金额,应区分“真实零值”和“数据源不可用”。
7. 实施顺序
- 冻结指标口径、时区、权限和 Dashboard DTO。
- 为 Order、Firstleg、Finance、IAM 分别补充领域内部聚合接口,保持服务数据库边界。
- 实现 Dashboard 聚合层,先实时查询,加入部分失败和
asOf。 - 仅对经查询耗时验证的区块增加 Redis 短缓存。
- Admin API/store/page 接入,删除静态常量和演示文案。
- 增加契约测试、聚合测试、缓存失效测试和真实只读验收。
- 只有性能证据显示短缓存仍不足时,才另立预聚合方案。
8. 验收要求
- 页面不再出现静态演示数据、演示快照或“待接入”按钮。
- 每个区块能单独展示真实数据、空态、错误态、无权限态。
- 响应返回
asOf和统计口径版本,缓存命中不能改变数据归属。 - 同一请求不会让前端循环调用所有客户详情接口。
- 缓存命中、过期、主动失效和服务不可用均有可追踪日志。
- Finance 缺表、模块超时和部分失败不能伪装成零值成功。
- 首页真实验收保留请求、响应、业务码、
requestId、traceId和数据断言。
9. 暂不纳入
- 不在本规划中修改全局导航、权限初始化 SQL 或统一增量 SQL。
- 不在没有数据规模和性能证据前新增统计数据仓库、永久快照表或复杂实时指标平台。
- 不把原型中的旧状态名称、营收口径或超期规则直接视为正式业务契约。