Files
docs/首页数据看板真实化与统计策略规划.md
T
2026-08-14 19:59:30 +08:00

152 lines
7.1 KiB
Markdown
Raw 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.
# 首页数据看板真实化与统计策略规划
## 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 不应让浏览器循环调用客户列表、订单列表和财务列表再自行计算。建议提供一个面向页面的只读聚合接口:
```http
GET /api/platform/v1/dashboard/overview?zoneId=Asia/Shanghai&days=30
```
聚合层负责并行调用各领域的内部统计能力,不能跨服务直接 Join 其他服务数据库。响应需要返回统一的 `asOf`、各区块数据、模块状态和 `partialFailures`,让单个领域暂时不可用时其他区块仍可展示。
建议分层:
```text
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. 建议响应结构
```json
{
"asOf": "2026-08-14T10:00:00+08:00",
"zoneId": "Asia/Shanghai",
"metrics": {},
"orderTrend": [],
"orderStatusDistribution": [],
"topRoutes": [],
"revenueComposition": [],
"todoSummary": [],
"partialFailures": []
}
```
每个区块应能表达 `loading`、`empty`、`unavailable` 和 `forbidden`。Finance 缺表或查询异常不能静默显示为真实的零金额,应区分“真实零值”和“数据源不可用”。
## 7. 实施顺序
1. 冻结指标口径、时区、权限和 Dashboard DTO。
2. 为 Order、Firstleg、Finance、IAM 分别补充领域内部聚合接口,保持服务数据库边界。
3. 实现 Dashboard 聚合层,先实时查询,加入部分失败和 `asOf`。
4. 仅对经查询耗时验证的区块增加 Redis 短缓存。
5. Admin API/store/page 接入,删除静态常量和演示文案。
6. 增加契约测试、聚合测试、缓存失效测试和真实只读验收。
7. 只有性能证据显示短缓存仍不足时,才另立预聚合方案。
## 8. 验收要求
- 页面不再出现静态演示数据、演示快照或“待接入”按钮。
- 每个区块能单独展示真实数据、空态、错误态、无权限态。
- 响应返回 `asOf` 和统计口径版本,缓存命中不能改变数据归属。
- 同一请求不会让前端循环调用所有客户详情接口。
- 缓存命中、过期、主动失效和服务不可用均有可追踪日志。
- Finance 缺表、模块超时和部分失败不能伪装成零值成功。
- 首页真实验收保留请求、响应、业务码、`requestId`、`traceId` 和数据断言。
## 9. 暂不纳入
- 不在本规划中修改全局导航、权限初始化 SQL 或统一增量 SQL。
- 不在没有数据规模和性能证据前新增统计数据仓库、永久快照表或复杂实时指标平台。
- 不把原型中的旧状态名称、营收口径或超期规则直接视为正式业务契约。