553 lines
14 KiB
Markdown
553 lines
14 KiB
Markdown
# 车辆数据管理中台设计 Spec
|
||
|
||
## 目标
|
||
|
||
建设一套独立的车辆数据管理中台,放在新项目目录 `vehicle-data-platform`。中台包含前端和后端,前端使用 Semi UI,整体风格高级、简洁、接近大厂数据控制台;后端使用 Go BFF 聚合现有车辆接入链路的数据能力。系统一期目标是让业务和运营人员可以稳定完成查车、看实时状态、查历史、追溯 RAW、看里程和定位数据质量问题,同时给平台运维提供只读链路健康态势。
|
||
|
||
## 产品定位更新:一个车辆服务
|
||
|
||
中台的第一性原则是“一个车辆服务”。GB32960、JT808、宇通 MQTT 是同一辆车的数据来源证据,不是三个并列的业务产品。所有主页面都应先回答车辆层面的问题,再在需要排障、对账、追溯时下钻到协议来源。
|
||
|
||
用户输入 VIN、车牌、手机号或来源标识后,系统需要尽量解析到同一个车辆上下文,并在实时监控、轨迹回放、历史查询、告警事件、统计分析之间保持这个上下文。协议只作为来源标签、可信度解释和 RAW 证据入口出现。
|
||
|
||
## 一期定位
|
||
|
||
一期优先服务运营、业务和数据质量人员,核心问题是:
|
||
|
||
- 车辆是否在线。
|
||
- 车辆在哪里。
|
||
- 最新状态是什么。
|
||
- 最近是否断链。
|
||
- 每日和区间里程是否可信。
|
||
- 原始报文和解析字段是否可追溯。
|
||
- 告警事件是否能追到影响车辆和证据。
|
||
- VIN、车牌、手机号、OEM 绑定是否正确。
|
||
|
||
链路运维能力作为辅助模块内嵌,展示 Gateway、NATS、Kafka、Redis、TDengine、MySQL 和 capacity-check 的关键健康状态,但一期不做复杂监控平台和告警工单闭环。
|
||
|
||
## 非目标
|
||
|
||
一期不做以下内容:
|
||
|
||
- 复杂多租户权限体系。
|
||
- 自定义大屏编排。
|
||
- 复杂工单闭环。
|
||
- 任意字段计算平台。
|
||
- 完整 BI 报表系统。
|
||
- 复杂三维轨迹或大屏动画。
|
||
- 对现有 Go gateway、NATS bridge、history writer、stat writer、realtime API 做破坏性改造。
|
||
|
||
## 项目结构
|
||
|
||
新建项目目录:
|
||
|
||
```text
|
||
vehicle-data-platform/
|
||
apps/
|
||
web/
|
||
api/
|
||
docs/
|
||
product-spec.md
|
||
api-contract.md
|
||
deployment.md
|
||
deploy/
|
||
systemd/
|
||
nginx/
|
||
scripts/
|
||
```
|
||
|
||
### 前端技术栈
|
||
|
||
- React
|
||
- TypeScript
|
||
- Vite
|
||
- Semi UI
|
||
- ECharts
|
||
- 地图组件,一期可先用轻量地图封装,后续再替换为正式地图供应商
|
||
|
||
### 后端技术栈
|
||
|
||
- Go
|
||
- 标准库 HTTP 或轻量路由
|
||
- MySQL driver
|
||
- Redis client
|
||
- TDengine driver
|
||
- HTTP client 聚合现有 health、metrics、capacity-check 输出
|
||
|
||
后端作为 BFF,不让前端直接连接 MySQL、Redis、TDengine 或现有 realtime API。
|
||
|
||
## 信息架构
|
||
|
||
左侧导航围绕车辆服务组织,一期可以先保留现有 7 个一级模块,但命名和内容要向以下目标靠拢。
|
||
|
||
### 1. 运营总览
|
||
|
||
路径:`/dashboard`
|
||
|
||
能力:
|
||
|
||
- 在线车辆数。
|
||
- 今日活跃车辆。
|
||
- 今日上报量。
|
||
- 异常车辆数。
|
||
- Kafka lag。
|
||
- 链路健康状态。
|
||
- 车辆服务状态分布:健康、降级、离线、身份缺失、暂无来源。
|
||
- 来源覆盖分布:单源车辆、多源车辆、暂无来源车辆。
|
||
- 最新车辆分布地图小窗。
|
||
- 最近异常列表:断链、未绑定、里程异常、解析失败、跨来源不一致。
|
||
|
||
### 2. 车辆服务
|
||
|
||
路径:`/vehicles`
|
||
|
||
能力:
|
||
|
||
- 表格展示车牌、VIN、手机号、OEM、来源证据、在线来源数、车辆服务状态、最后上报、最近位置、绑定完整度。
|
||
- 支持 VIN、车牌、手机号、OEM 搜索。
|
||
- 支持服务状态、来源覆盖、在线状态、绑定完整度筛选。
|
||
- 支持查看详情、导出。
|
||
- 支持导入绑定入口的一期展示:提供导入说明和模板下载按钮,不提交数据;正式写入流程不纳入一期验收。
|
||
|
||
### 3. 实时监控
|
||
|
||
路径:`/realtime`
|
||
|
||
能力:
|
||
|
||
- 表格视图和地图视图切换。
|
||
- 展示 VIN、车牌、来源证据、速度、SOC、总里程、最后上报时间、位置。
|
||
- 地图按车辆服务状态和在线状态分色,协议只用于点位详情里的来源证据。
|
||
- 支持只看在线车辆、异常车辆、断链车辆和多源不一致车辆。
|
||
- 点击车辆后打开右侧抽屉展示最新实时字段摘要、来源新鲜度和跳转入口。
|
||
|
||
### 4. 车辆详情
|
||
|
||
路径:`/vehicles/:vin`
|
||
|
||
能力:
|
||
|
||
- 顶部身份卡:车牌、VIN、OEM、协议、在线状态。
|
||
- Tabs:
|
||
- 最新状态。
|
||
- 历史位置。
|
||
- RAW 报文。
|
||
- 里程统计。
|
||
- 数据质量。
|
||
- 多协议对比:同一车辆在 GB32960、JT808、YUTONG_MQTT 下的最新时间、字段完整度、里程差异。
|
||
|
||
### 5. 轨迹回放
|
||
|
||
路径:`/history`
|
||
|
||
能力:
|
||
|
||
- 查询条件:VIN/车牌/手机号、时间范围、来源筛选。
|
||
- 地图轨迹播放,支持起点、终点、当前播放点和速度。
|
||
- 表格与地图联动:点击点位能看到该点时间、位置、速度、里程和来源。
|
||
- 可跳转 RAW 证据、统计分析和告警事件。
|
||
|
||
### 6. 历史查询
|
||
|
||
路径:`/history`
|
||
|
||
能力:
|
||
|
||
- Tab:历史位置、RAW 报文、解析字段。
|
||
- 查询条件:VIN、协议、时间范围、消息类型、字段筛选。
|
||
- RAW 支持分页、字段裁剪、是否包含 payload、JSON 详情查看。
|
||
- 解析字段使用扁平化字段名,支持选择字段缩小响应体。
|
||
|
||
### 7. 告警事件
|
||
|
||
路径:`/quality`,后续可独立为 `/alerts`
|
||
|
||
能力:
|
||
|
||
- 展示来源断链、未绑定、无 VIN、无车牌、无手机号、RAW 解析失败、里程突变、跨来源不一致。
|
||
- 每条告警必须能跳回车辆详情、轨迹回放、历史 RAW 或统计证据。
|
||
- 一期支持人工确认和状态展示,通知发送作为后续阶段。
|
||
|
||
### 8. 统计分析
|
||
|
||
路径:`/mileage`
|
||
|
||
能力:
|
||
|
||
- 日里程查询。
|
||
- 区间里程查询。
|
||
- 协议来源对比。
|
||
- 异常标记:总里程倒退、突增、缺失、跨协议不一致。
|
||
- 在线率、数据完整率和来源一致性作为后续统计卡片。
|
||
|
||
### 9. 运维质量
|
||
|
||
路径:`/quality`
|
||
|
||
能力:
|
||
|
||
- 断链车辆。
|
||
- 未绑定车辆。
|
||
- 无 VIN、无车牌、无手机号车辆。
|
||
- RAW 解析失败。
|
||
- capacity-check 结果。
|
||
- Kafka/NATS/TDengine/Redis/MySQL 关键状态。
|
||
|
||
## 高德地图设计
|
||
|
||
地图供应商使用高德地图。用户提供了 Web JS 和 API 服务两类 key,系统实现时需要按用途分开:
|
||
|
||
- Web JS key 只通过前端运行时配置注入,例如 `window.__LINGNIU_PLATFORM_CONFIG__.amap.webJsKey`,不写死在 TypeScript 源码。
|
||
- 安全密钥或代理服务地址同样通过运行时配置注入。
|
||
- API 服务 key 放在后端或 ECS 环境变量中,只用于后端地理编码、行政区划或后续服务端地图能力。
|
||
- 前端没有拿到可用 key 时,`VehicleMap` 使用坐标预览降级,不阻塞查车、查轨迹和查告警。
|
||
|
||
地图一期覆盖三类业务场景:
|
||
|
||
- 实时监控:多车点位、在线状态、异常状态、点位详情。
|
||
- 轨迹回放:折线、起终点、当前播放点、表格联动。
|
||
- 告警事件:告警车辆定位和影响范围提示。
|
||
|
||
## 跨页面车辆上下文
|
||
|
||
全局搜索解析到车辆后,需要把 VIN、车牌、手机号、来源和服务状态作为页面上下文:
|
||
|
||
- 车辆服务行可以跳转车辆档案。
|
||
- 实时监控车辆可以跳转轨迹回放、历史查询、统计分析和告警事件。
|
||
- 轨迹点可以跳转同日里程统计和 RAW 证据。
|
||
- 里程异常可以跳转对应日期轨迹和 RAW 证据。
|
||
- 告警事件可以跳转车辆档案、历史证据和统计证据。
|
||
|
||
这一点是产品一致性的硬约束。页面之间不应只靠用户手动复制 VIN。
|
||
|
||
## 视觉与交互设计
|
||
|
||
整体视觉使用 Semi UI 原生组件为基础,避免大屏炫技风。目标是云控制台、数据控制台、飞书后台一类的专业感。
|
||
|
||
### 设计原则
|
||
|
||
- 灰白背景,深色正文,蓝青强调色。
|
||
- 红橙只用于异常、告警、风险。
|
||
- 表格优先,不用卡片堆满页面。
|
||
- KPI 卡片少而准。
|
||
- 右侧抽屉承载详情,不频繁跳整页。
|
||
- RAW 和 parsed JSON 使用代码查看器或结构化 JSON Tree。
|
||
- 地图是业务辅助,不作为首页背景。
|
||
- 所有列表页都有稳定筛选区、刷新时间和导出入口。
|
||
|
||
### 页面骨架
|
||
|
||
- 顶部栏:系统名、全局车辆搜索、环境状态、刷新时间、用户入口。
|
||
- 左侧栏:7 个一级导航。
|
||
- 主体区:页面标题、筛选/操作区、数据区。
|
||
- 右侧抽屉:车辆摘要、RAW 详情、异常解释。
|
||
|
||
## 后端 BFF 设计
|
||
|
||
后端统一暴露 `/api/*`,并托管前端静态文件。
|
||
|
||
### API 响应格式
|
||
|
||
成功:
|
||
|
||
```json
|
||
{
|
||
"data": {},
|
||
"traceId": "string",
|
||
"timestamp": 1783080000000
|
||
}
|
||
```
|
||
|
||
分页:
|
||
|
||
```json
|
||
{
|
||
"data": {
|
||
"items": [],
|
||
"total": 100,
|
||
"limit": 50,
|
||
"offset": 0
|
||
},
|
||
"traceId": "string",
|
||
"timestamp": 1783080000000
|
||
}
|
||
```
|
||
|
||
错误:
|
||
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": "QUERY_FAILED",
|
||
"message": "查询失败",
|
||
"detail": "具体错误"
|
||
},
|
||
"traceId": "string",
|
||
"timestamp": 1783080000000
|
||
}
|
||
```
|
||
|
||
### 后端模块
|
||
|
||
#### vehicle
|
||
|
||
职责:
|
||
|
||
- 车辆台账。
|
||
- 身份绑定。
|
||
- VIN、车牌、手机号、OEM 查询。
|
||
|
||
数据源:
|
||
|
||
- MySQL `vehicle_identity_binding`。
|
||
- MySQL `vehicle_realtime_snapshot` 和 `vehicle_realtime_location` 用于补充在线状态和最新上报。
|
||
|
||
#### realtime
|
||
|
||
职责:
|
||
|
||
- 实时位置。
|
||
- 实时快照。
|
||
- 单车当前状态。
|
||
- 单车协议 realtime raw 摘要。
|
||
|
||
数据源:
|
||
|
||
- MySQL `vehicle_realtime_snapshot`。
|
||
- MySQL `vehicle_realtime_location`。
|
||
- Redis `vehicle:realtime-raw:{protocol}:{vin}`。
|
||
- Redis online key 族。
|
||
|
||
#### history
|
||
|
||
职责:
|
||
|
||
- 历史位置。
|
||
- RAW frame 查询。
|
||
- RAW 字段过滤。
|
||
|
||
数据源:
|
||
|
||
- TDengine `vehicle_locations`。
|
||
- TDengine `raw_frames`。
|
||
- TDengine `raw_frame_payload_chunks`。
|
||
|
||
#### mileage
|
||
|
||
职责:
|
||
|
||
- 日里程。
|
||
- 区间里程。
|
||
- 里程异常解释。
|
||
|
||
数据源:
|
||
|
||
- MySQL `vehicle_daily_mileage`。
|
||
|
||
#### quality
|
||
|
||
职责:
|
||
|
||
- 无 VIN。
|
||
- 无车牌。
|
||
- 无手机号。
|
||
- 长时间未上报。
|
||
- 里程突变。
|
||
- 解析失败。
|
||
|
||
数据源:
|
||
|
||
- MySQL identity 和 realtime 表。
|
||
- TDengine raw_frames。
|
||
- Redis online。
|
||
|
||
#### ops
|
||
|
||
职责:
|
||
|
||
- capacity-check。
|
||
- 服务 readyz。
|
||
- Kafka/NATS/Redis/TDengine/MySQL 状态摘要。
|
||
|
||
数据源:
|
||
|
||
- 现有本机 health endpoint。
|
||
- 现有 metrics endpoint。
|
||
- `/opt/lingniu-go-native/current/capacity-check` 输出。
|
||
|
||
## 一期 API
|
||
|
||
### Dashboard
|
||
|
||
- `GET /api/dashboard/summary`
|
||
|
||
返回:
|
||
|
||
- 车辆在线数。
|
||
- 今日活跃数。
|
||
- 今日上报量。
|
||
- 协议分布。
|
||
- 异常计数。
|
||
- 链路健康摘要。
|
||
|
||
### Vehicles
|
||
|
||
- `GET /api/vehicles`
|
||
- `GET /api/vehicles/:vin`
|
||
- `GET /api/vehicles/:vin/realtime`
|
||
- `GET /api/vehicles/:vin/protocols`
|
||
|
||
### Realtime
|
||
|
||
- `GET /api/realtime/locations`
|
||
- `GET /api/realtime/snapshots`
|
||
- `GET /api/realtime/raw/:protocol/:vin`
|
||
|
||
### History
|
||
|
||
- `GET /api/history/locations`
|
||
- `POST /api/history/raw-frames/query`
|
||
|
||
RAW query 使用 POST,避免字段过滤数组导致 URL 过长。
|
||
|
||
### Mileage
|
||
|
||
- `GET /api/mileage/daily`
|
||
- `GET /api/mileage/range`
|
||
|
||
### Quality
|
||
|
||
- `GET /api/quality/issues`
|
||
- `GET /api/quality/unbound-vehicles`
|
||
- `GET /api/quality/offline-vehicles`
|
||
|
||
### Ops
|
||
|
||
- `GET /api/ops/health`
|
||
- `GET /api/ops/capacity`
|
||
|
||
## 数据源映射
|
||
|
||
### MySQL
|
||
|
||
- `vehicle_identity_binding`:车辆身份事实表。
|
||
- `vehicle_realtime_snapshot`:每协议每 VIN 最新轻量快照。
|
||
- `vehicle_realtime_location`:每协议每 VIN 最新位置。
|
||
- `vehicle_daily_mileage`:每日里程统计。
|
||
- `jt808_registration`:JT808 注册与鉴权辅助信息。
|
||
|
||
### Redis
|
||
|
||
- `vehicle:realtime-raw:{protocol}:{vin}`:最新完整协议 parsed 状态。
|
||
- `vehicle:online:*`:在线状态。
|
||
- `vehicle:last_seen`:最近活跃排序。
|
||
- `vehicle:rt-kv:*`:扁平化实时字段。
|
||
|
||
### TDengine
|
||
|
||
- `raw_frames`:RAW 证据层。
|
||
- `raw_frame_payload_chunks`:超长 payload 分片。
|
||
- `vehicle_locations`:历史位置。
|
||
|
||
## 权限设计
|
||
|
||
一期做轻量鉴权:
|
||
|
||
- 登录页。
|
||
- 单一管理员账号或配置文件 token。
|
||
- 前端请求带 bearer token。
|
||
- 后端校验 token。
|
||
|
||
后续再扩展 RBAC:
|
||
|
||
- 业务只读。
|
||
- 运维只读。
|
||
- 管理员。
|
||
|
||
## 部署设计
|
||
|
||
ECS 部署:
|
||
|
||
- 后端端口:`20300`。
|
||
- 后端托管前端静态文件。
|
||
- `/api/*` 是后端接口。
|
||
- `/` 和前端路由返回静态入口。
|
||
- systemd unit:`lingniu-vehicle-platform.service`。
|
||
|
||
访问地址:
|
||
|
||
```text
|
||
http://115.29.187.205:20300
|
||
```
|
||
|
||
## 环境变量
|
||
|
||
后端需要:
|
||
|
||
- `HTTP_ADDR=:20300`
|
||
- `MYSQL_DSN`
|
||
- `REDIS_ADDR`
|
||
- `REDIS_USERNAME`
|
||
- `REDIS_PASSWORD`
|
||
- `REDIS_DB`
|
||
- `TDENGINE_DSN`
|
||
- `TDENGINE_DATABASE=lingniu_vehicle_ts`
|
||
- `CAPACITY_CHECK_BIN=/opt/lingniu-go-native/current/capacity-check`
|
||
- `AUTH_TOKEN`
|
||
|
||
## 验收标准
|
||
|
||
一期完成时必须满足:
|
||
|
||
1. 新项目目录 `vehicle-data-platform` 存在。
|
||
2. 前端使用 Semi UI。
|
||
3. UI 有完整导航、统一布局、统一视觉规范。
|
||
4. 可以查看车辆台账。
|
||
5. 可以查询实时位置和实时状态。
|
||
6. 可以进入单车详情。
|
||
7. 可以查询历史位置。
|
||
8. 可以查询 RAW frame,并支持字段裁剪。
|
||
9. 可以查看日里程和区间里程。
|
||
10. 可以查看数据质量问题。
|
||
11. 可以查看链路健康状态。
|
||
12. 后端 API 返回统一响应结构。
|
||
13. 前端核心列表、详情和查询来自真实后端 API。
|
||
14. ECS 部署后可通过 `http://115.29.187.205:20300` 访问。
|
||
15. 后端 systemd 服务健康。
|
||
16. 浏览器验证主要页面可访问、筛选可用、详情抽屉可用。
|
||
|
||
## 测试策略
|
||
|
||
### 后端
|
||
|
||
- API handler 单元测试。
|
||
- query 参数解析测试。
|
||
- response envelope 测试。
|
||
- 数据源 repository 测试。
|
||
- 健康检查测试。
|
||
|
||
### 前端
|
||
|
||
- TypeScript build。
|
||
- 页面 smoke test。
|
||
- API client 测试。
|
||
- 主要页面空态、加载态、错误态检查。
|
||
|
||
### 部署
|
||
|
||
- 本地前端 build。
|
||
- 后端 go test。
|
||
- ECS systemd 启动。
|
||
- `/api/ops/health` 返回正常。
|
||
- 浏览器打开首页、车辆台账、实时监控、历史查询。
|
||
|
||
## 后续演进
|
||
|
||
- RBAC 权限。
|
||
- 车辆绑定导入写入流程。
|
||
- 告警通知。
|
||
- 轨迹回放。
|
||
- BI 报表。
|
||
- 自定义字段分析。
|
||
- 运维监控大盘。
|