Files
lingniu-vehicle-ingest/docs/vehicle-data-platform-analysis.md

18 KiB
Raw Permalink Blame History

车辆数据中台一期现状分析与总体方案

结论日期2026-07-14 范围:只完成现状分析和方案设计,不进入 V2 功能开发或 ECS 部署。 代码依据:/Users/lingniu/project/ai-coding/ln-bivehicle-data-platformgo/vehicle-gateway,以及 docs/architecturedocs/ops 中的生产说明。

1. 结论摘要

当前数据接入链路已经具备可用的生产底座GB32960、JT808、YUTONG_MQTT 经 NATS/Kafka 分流后,分别形成 Redis 当前态、TDengine RAW/位置历史、MySQL 身份/实时/日里程投影;现有平台 BFF 也已提供车辆、实时位置、轨迹点、RAW、里程、质量和运维健康等只读接口。

但现有前端不是可直接扩展的一期产品:生产入口加载的是约 6000 行的 PrototypeApp.tsx,仍混有 mock 数据和“接口缺失时展示能力边界”的原型逻辑;另一个模块化 App.tsx 并非当前入口。现有地图每次最多创建 500 个普通 Marker没有聚合、MassMarks/Canvas 图层和视口查询,无法满足 1 万辆级监控。所谓告警接口实际上是质量问题接口的别名,没有规则、事件、处理记录和通知持久化。

建议丢弃现有原型页面的产品实现,但保留经验证的数据适配、领域工具、测试、运行时配置和部署脚手架,建立独立 V2。前端沿用 React + TypeScript + Vite吸收 ln-bi 的视觉语言、壳层、鉴权思想和基础组件,但采用正式路由、查询缓存、虚拟表格和独立地图 SDK 层。后端保留现有接入链路,通过平台 BFF 和新增的告警/导出 worker 补齐业务能力,不让浏览器直接访问 Redis、TDengine 或 MySQL。

2. 当前前端技术栈与目录

2.1 ln-bi 参考项目

项目 当前实现 评价
框架 React 19、React DOM 19、TypeScript 5.8、Vite 6.2 可作为 V2 目标栈参考;不建议仅为对齐版本立刻升级已有平台依赖
样式 Tailwind CSS 4、少量 CSS 变量 视觉语言清晰,但业务组件 class 较分散,需要提炼 token 和组件配方
图标/动效 lucide-react、Motion 可复用设计语言;监控页面动效应克制并支持 reduced motion
图表 Recharts 3.8 适合常规 BI百万点、多 Y 轴时序更推荐现平台已有 ECharts 5
地图 @amap/amap-jsapi-loader + AMap JS API 2.0 加载和实例生命周期可借鉴;目前只是热力图业务组件,不是通用地图 SDK
API 原生 fetch + JWT 注入 可借鉴鉴权流程;错误类型、超时、重试、取消、缓存仍不足
服务端 Hono、MySQL/Postgres、JWT、XLSX 属于 ln-bi 自身 BFF不应直接搬入车辆接入 Go 数据面
路由 pathname + hash + replaceState 手写 适合少量模块,不适合可分享查询、详情层级和权限路由
状态 React 本地状态/Context 未使用全局状态库或服务端查询缓存

主要目录:

ln-bi/src/
├── App.tsx                     # 模块注册、权限门禁、懒加载
├── auth/                       # jumpToken -> JWT、fetch token 注入
├── components/
│   ├── Shell.tsx               # 桌面侧栏、移动底栏、模块切换、水印
│   ├── SearchSelect.tsx
│   ├── MultiSearchSelect.tsx
│   └── ui/surface.tsx          # PageFrame、SurfaceCard、MetricTile、状态组件
├── modules/
│   ├── vehicle-heatmap/        # AMap 热力图和筛选/详情面板
│   ├── hydrogen-heatmap/
│   ├── mileage/                # 表格、详情弹窗、XLSX 导出
│   └── ...
├── server/                     # Hono BFF、认证、DB 查询
├── shared/auth/roles.ts        # 角色判断
└── index.css                   # Tailwind、主题变量、地图控件样式

2.2 当前车辆平台前端

目录为 vehicle-data-platform/apps/web,使用 React 18.3、TypeScript 5.7、Vite 6、Semi UI 2.71、ECharts 5.6。当前入口 src/main.tsx 加载 PrototypeApp,不是 src/App.tsx

vehicle-data-platform/apps/web/src/
├── main.tsx                    # 当前生产入口 -> PrototypeApp
├── PrototypeApp.tsx            # 大型原型单体,真实接口与 mock 逻辑混合
├── App.tsx                     # 未作为入口的模块化旧实现
├── api/                        # 统一响应信封、类型和调用方法
├── components/                 # VehicleMap、状态标签、空状态等
├── config/                     # API/高德运行时配置
├── domain/                     # 路由、导出、车辆查询等纯函数
├── integrations/amap.ts        # AMap loader、坐标校验、逆地理编码
├── layout/AppShell.tsx
├── pages/                      # 旧模块化页面
├── prototype/                  # mock、真实数据适配、view model、字段映射
└── styles/                     # token、全局样式、原型样式

V2 的原则是“页面重建、能力甄别复用”:不复制 PrototypeApp.tsxprototype.css;保留可独立测试的 apidomainintegrations、真实数据归一化逻辑及其测试,再按新接口契约重构。

3. 可复用能力清单

能力 来源 复用决策 说明
80px 深色侧栏、顶部面包屑、水印、移动底栏 ln-bi/components/Shell.tsx 设计复用、代码重构 V2 桌面优先,应改为正式路由和可折叠侧栏
PageFrame、SurfaceCard、MetricTile、SegmentedNav ln-bi/components/ui/surface.tsx 可迁移后组件化 统一 token、尺寸和可访问性后复用
SearchSelect、MultiSearchSelect ln-bi/components 交互参考 当前仅接收字符串数组缺少远程搜索、虚拟列表、label/value 和键盘完整性
加载、空、错误状态 两项目 合并重构 建立统一 AsyncState,禁止页面各自拼接
JWT/jumpToken 门禁、角色判断 ln-bi/authshared/auth 复用认证协议思想 token 仍应保存在 session权限改为路由/操作级声明,后端必须二次校验
AMap loader、实例销毁、运行时密钥 两项目 合并为通用 SDK 统一 loader promise、插件注册、安全代理和错误状态
热力图数据归一化 ln-bi/vehicle-heatmap 可复用算法 log1p/sqrt 强度变换适合密度层,不等于车辆状态点图层
表格/详情弹窗/XLSX ln-bi/mileage 交互与导出格式参考 一期大数据导出必须后端异步,不能沿用浏览器全量 XLSX
ECharts 当前车辆平台 保留 更适合多 Y 轴、dataZoom、断点、阶梯线和大数据采样
api/client.ts 响应信封和 traceId 当前车辆平台 扩展复用 增加鉴权、AbortSignal、超时、错误码、幂等键和查询缓存
车辆 lookup、字段归一化、CSV 纯函数及测试 当前车辆平台 审核后复用 去掉 mock fallback统一到 V2 DTO/领域模型
Semi UI 页面组件 当前车辆平台 暂不作为 V2 默认 ln-bi Tailwind 视觉体系并存会形成双设计系统V2 启动前只选一套基础组件策略

不存在可直接复用的“通用图表组件”或“通用高性能表格组件”。ln-bi 的 Recharts 与页面耦合,当前平台的 ECharts 也需要建立 TimeSeriesChart、轴/单位/空值策略和采样契约;表格需新增服务端分页、列配置、固定列和虚拟滚动封装。

4. 高德地图当前封装方式

4.1 ln-bi

AmapHeatmapCanvas.tsx 动态导入 @amap/amap-jsapi-loader,写入 _AMapSecurityConfig.securityJsCode,加载 AMap 2.0 的 HeatMap、ToolBar、Scale 插件;创建白色地图和 HeatMap点击地图回传经纬度数据变化时调用 setDataSet,焦点变化时计算 bounds卸载时销毁实例。

优点是 loader 官方、生命周期完整、地图与侧面板分屏清楚。限制是车辆和加氢模块各有近似实现,密钥直接下发前端,未封装 Marker/聚合/信息窗/轨迹/播放,也没有实例共享和视口事件节流。

4.2 当前车辆平台

integrations/amap.ts 自行加载 https://webapi.amap.com/loader.js,按插件集合缓存 Promise支持 Scale、Geocoder、坐标合法性检查、URI Marker 链接和浏览器逆地理编码;appConfig.tswindow.__LINGNIU_APP_CONFIG__ 或 Vite 环境变量读取 Web JS key、安全代码/代理和 API base URL。

VehicleMap.tsx 在组件内创建 Map、Marker、Polyline重绘时清除 overlay最多截取 500 个点,并在未配置地图时提供坐标预览。它适合验证和小规模页面,不适合一期:每点 HTML button、没有聚合、状态图层、InfoWindow 管理、车辆朝向、轨迹抽稀/播放或视口查询。

4.3 V2 建议封装

建立 features/map-sdk,分为:

  • AMapProvider/useAMap:唯一 loader、插件按需加载、实例注册、resize/destroy。
  • BaseMap:纯地图容器,只接收中心、缩放、样式和事件。
  • VehiclePointLayer:小规模用 Marker规模化优先 MarkerCluster/LabelsLayer/MassMarks 或 Canvas/WebGL 能力;详情卡只保留一个 InfoWindow。
  • TrackLayerPolyline、起终点、停车/告警节点和移动标记;播放状态在业务 hook不绑入地图实例。
  • HeatmapLayerGeocoderServiceMapControls:独立能力。
  • 视口查询使用 bounds + zoom + filterHash;移动结束后防抖请求服务器聚合结果,前端不一次拉取全量 1 万点 DOM。

高德 Web JS key 可由运行时配置下发,但安全密钥优先使用服务端安全代理;逆地理编码优先走现有 /api/map/reverse-geocode,避免泄露 REST key并便于限流/缓存。

5. 当前车辆相关接口

现有平台 BFF 的有效能力如下;详细缺口见 vehicle-data-platform-api-gap.md

领域 接口 当前用途
总览 GET /api/dashboard/summary 在线、今日活跃、帧数、问题数、协议/服务/链路统计
车辆 GET /api/vehicles/api/vehicles/resolve/api/vehicles/coverage/summary 车辆列表、VIN/车牌/手机号解析、来源覆盖
单车 GET /api/vehicle-service/summary/overviewPOST /overviews 聚合身份、实时、历史、RAW、里程、质量证据
实时 GET /api/realtime/vehicles/api/realtime/locations VIN 聚合实时状态和每协议最新位置
历史 GET /api/history/locationsGET/POST /api/history/raw-frames TDengine 位置点和 RAW 证据分页
里程 GET /api/mileage/summary/api/mileage/daily MySQL 日里程统计
在线 GET /api/statistics/online-summary/online-vehicles 当前固定口径的在线统计和车辆状态
数据质量 GET /api/quality/summary/issues/notification-plan 由当前数据推导的质量信号和静态通知方案
告警兼容 GET /api/alert-events/summary/alert-events/notification-plan 实际是上述质量接口别名,不是业务告警事件
地图 GET /api/map/reverse-geocode 服务端高德逆地理编码
运维 GET /api/ops/health/source-readiness 数据源可写性、Kafka lag、连接/Redis key、发布版本和接入准备度

同时Go realtime-api 还提供面向底层表的查询接口和 OpenAPI但 V2 浏览器应统一访问平台 BFF避免前端绑定多个端口与底层存储模型。

6. 数据职责概览

  • TDengine lingniu_vehicle_tsraw_frames 是原始接收与扁平解析证据,raw_frame_payload_chunks 保存超长 payloadvehicle_locations 保存 VIN 级位置、速度、方向、告警标志和总里程历史。它不是车辆档案或告警业务库。
  • Redis DB 50vehicle:latest:*vehicle:realtime-raw:*vehicle:rt-kv:*vehicle:online:*vehicle:protocols:*vehicle:last_seen 提供可过期、可重建的当前态。它不能作为历史、告警或导出任务事实源。
  • MySQL lingniu_vehicle_data:保存 vehicle、多标识映射、JT808 注册鉴权、每协议实时快照/位置、来源配置和日里程事实/结果。现有 vehicle 档案很轻,只含 VIN、车牌、OEM、启用状态尚不足以支撑车型、公司、车辆类型等产品字段。

统一模型及新增模型详见 vehicle-data-platform-data-model.md

7. 一期缺口结论

必须新增或升级的核心能力:

  1. 完整车辆档案、组织/车型/协议/接入厂家字典与首次接入事实。
  2. 地图聚合查询、组合筛选、状态统计和可配置在线口径。
  3. 包含方向、SOC、告警标志、停车点、异常点过滤和抽稀元数据的轨迹接口。
  4. 动态指标目录,以及多车、多指标、聚合/抽稀、分页的通用时序查询。
  5. MySQL 持久化告警规则、告警事件、处理记录、站内通知和告警计算 worker。
  6. MySQL 异步导出任务、对象/本地文件存储、worker、进度与下载授权。
  7. 接入状态字段:首次/最近上报、事件时间与接收时间延迟、最近消息类型、最近错误、动态在线阈值。
  8. 真正的认证、菜单/操作权限审计;现车辆平台 BFF 尚未呈现完整权限体系。

8. 推荐一期路由与菜单

/
├── /monitor                         全局监控(默认首页)
├── /vehicles                        车辆查询
│   └── /vehicles/:vin               单车数字档案
├── /tracks                          轨迹查询与回放
├── /history                         历史数据分析
│   └── /history/exports             导出任务
├── /alerts
│   ├── /alerts/events               告警事件
│   ├── /alerts/rules                告警规则
│   └── /alerts/inbox                站内通知
├── /access                          车辆接入状态
└── /operations                      运维质量(管理员)

侧栏一级菜单保持 6 个业务入口:全局监控、车辆中心、轨迹回放、历史分析、告警中心、接入管理;导出任务挂在历史分析二级菜单,运维质量按权限置底。详情、告警、轨迹之间用带 returnTo 的上下文跳转,查询条件同步 URL浏览器返回可恢复筛选、时间和选中车辆。

9. 推荐前后端整体架构

flowchart LR
  UI["V2 React Web"] --> BFF["Platform API / BFF"]
  BFF --> RT["Redis 当前态"]
  BFF --> TS["TDengine 时序与 RAW"]
  BFF --> DB["MySQL 业务事实"]
  BFF --> MAP["高德 REST / 安全代理"]
  ING["Gateway + NATS + Kafka Writers"] --> RT
  ING --> TS
  ING --> DB
  K["Kafka fields/raw"] --> AW["Alert evaluator"]
  AW --> DB
  BFF --> EQ["Export queue"]
  EQ --> EW["Export worker"]
  EW --> TS
  EW --> DB
  EW --> FS["文件/对象存储"]

前端按 app/routersharedentities/vehiclefeaturespages 分层。服务端状态使用查询缓存库统一取消、去重、失效和后台刷新;少量 UI 状态用 React Context/局部 store。地图、图表、表格均只接收领域 DTO不直接处理协议字段名。

平台 BFF 负责统一鉴权、参数校验、分页、在线状态计算、跨源聚合、字段目录、限流、traceId 和 DTO禁止让前端分别拼 Redis/MySQL/TDengine。已有接入 writer 保持不变,新告警 worker 消费可重放 fields/raw 流,异步导出 worker 读取 TDengine/MySQL 并把任务状态写 MySQL。

10. 运维与最终 ECS 部署边界

已查阅 docs/ops/vehicle-ingest-runbook.mddocs/ops/go-vehicle-ingest-memory.mddocs/architecture/production-data-plane-inventory.mdvehicle-data-platform/docs/deployment.md。当前接入数据面采用 systemd 裸机 release 目录与 current 软链,平台使用 /opt/lingniu-vehicle-platform/{releases,current,env}HTTP 端口 20300部署后应验证 /api/ops/health、车辆查询和运行时配置。

V2 最终仍部署到当前 ECS但不应在分析阶段执行。实施完成后的发布顺序应是数据库向前兼容迁移 -> 新 worker默认禁用规则-> BFF -> 静态 Web -> 小流量健康验证 -> 启用告警/导出 worker。每一步保留旧 release 和可回滚软链;密钥只进 ECS 环境文件,不进仓库或构建产物。完整发布验收纳入路线图最后阶段。

11. 风险与待确认事项

优先级 风险/待确认 影响与建议
P0 vehicle 档案缺车型、类型、公司、接入厂家等 先确定主数据来源和维护责任,不要从实时 JSON 猜档案
P0 现有告警接口名与真实语义不符 V2 使用 /api/v2/alerts/* 新契约,旧别名标记 deprecated避免误把质量信号当已处理事件
P0 动态指标没有目录、单位、类型和协议映射 先落指标元数据;否则图表、规则和导出会各自硬编码
P0 用户/角色来源尚未确认 明确复用 ln-bi jumpToken/JWT还是接入统一 SSO后端权限不可只靠菜单隐藏
P1 在线阈值是全局、协议级还是车辆级 建议全局默认 + 协议覆盖;一期暂不做单车覆盖
P1 轨迹异常过滤可能隐藏原始证据 API 同时返回 raw/filtered 计数和算法版本,允许关闭过滤
P1 TDengine raw_frames.parsed_json 是动态字段唯一历史来源 通用指标查询先从 JSON 提取会有成本;高频稳定指标应按使用量逐步物化,而非一期全列化
P1 单 ECS 同时承担接入、查询、告警和导出 导出/重查询必须有并发、时间范围、行数和资源配额;压测后再定 worker 并发
P1 地图 1 万辆的插件/授权与浏览器性能 先完成 1k/10k 基准,确定 MarkerCluster、MassMarks 或 Canvas 方案和高德配额
P1 站内通知实时方式 一期可 SSE + 轮询降级;若 ECS 反代不适合长连接,先使用增量轮询
P2 Semi UI 与 Tailwind 双设计系统 V2 启动前确认唯一基础组件策略;建议 Tailwind token + 无样式/轻量基础组件ECharts 保留
P2 导出文件存储位置与保留期 确认 OSS 或 ECS 本地盘;推荐 OSS/兼容对象存储,任务和文件设过期清理策略

12. 本阶段完成定义

本阶段仅交付本分析、路线图、API 缺口和数据模型四份文档。V2 代码、数据库迁移、告警/导出 worker、ECS 发布均须在确认 P0 项后按路线图进入下一阶段。