14 KiB
车辆数据管理中台设计 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 做破坏性改造。
项目结构
新建项目目录:
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 响应格式
成功:
{
"data": {},
"traceId": "string",
"timestamp": 1783080000000
}
分页:
{
"data": {
"items": [],
"total": 100,
"limit": 50,
"offset": 0
},
"traceId": "string",
"timestamp": 1783080000000
}
错误:
{
"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/vehiclesGET /api/vehicles/:vinGET /api/vehicles/:vin/realtimeGET /api/vehicles/:vin/protocols
Realtime
GET /api/realtime/locationsGET /api/realtime/snapshotsGET /api/realtime/raw/:protocol/:vin
History
GET /api/history/locationsPOST /api/history/raw-frames/query
RAW query 使用 POST,避免字段过滤数组导致 URL 过长。
Mileage
GET /api/mileage/dailyGET /api/mileage/range
Quality
GET /api/quality/issuesGET /api/quality/unbound-vehiclesGET /api/quality/offline-vehicles
Ops
GET /api/ops/healthGET /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。
访问地址:
http://115.29.187.205:20300
环境变量
后端需要:
HTTP_ADDR=:20300MYSQL_DSNREDIS_ADDRREDIS_USERNAMEREDIS_PASSWORDREDIS_DBTDENGINE_DSNTDENGINE_DATABASE=lingniu_vehicle_tsCAPACITY_CHECK_BIN=/opt/lingniu-go-native/current/capacity-checkAUTH_TOKEN
验收标准
一期完成时必须满足:
- 新项目目录
vehicle-data-platform存在。 - 前端使用 Semi UI。
- UI 有完整导航、统一布局、统一视觉规范。
- 可以查看车辆台账。
- 可以查询实时位置和实时状态。
- 可以进入单车详情。
- 可以查询历史位置。
- 可以查询 RAW frame,并支持字段裁剪。
- 可以查看日里程和区间里程。
- 可以查看数据质量问题。
- 可以查看链路健康状态。
- 后端 API 返回统一响应结构。
- 前端核心列表、详情和查询来自真实后端 API。
- ECS 部署后可通过
http://115.29.187.205:20300访问。 - 后端 systemd 服务健康。
- 浏览器验证主要页面可访问、筛选可用、详情抽屉可用。
测试策略
后端
- API handler 单元测试。
- query 参数解析测试。
- response envelope 测试。
- 数据源 repository 测试。
- 健康检查测试。
前端
- TypeScript build。
- 页面 smoke test。
- API client 测试。
- 主要页面空态、加载态、错误态检查。
部署
- 本地前端 build。
- 后端 go test。
- ECS systemd 启动。
/api/ops/health返回正常。- 浏览器打开首页、车辆台账、实时监控、历史查询。
后续演进
- RBAC 权限。
- 车辆绑定导入写入流程。
- 告警通知。
- 轨迹回放。
- BI 报表。
- 自定义字段分析。
- 运维监控大盘。