chore: snapshot production code before Apple Design UI refinement

This commit is contained in:
lingniu
2026-09-17 18:05:57 +08:00
parent 9f0a87f49e
commit f7e7176f88
90 changed files with 8990 additions and 328 deletions
@@ -0,0 +1,56 @@
# 车辆日省市、大区后台计算
## 数据流
`TDengine 当日历史定位 → 后台每分钟取车辆日最后有效定位 → 高德省市解析 → MySQL vehicle_daily_geography → 日统计 API → Excel`
导出不再查询轨迹或发起逆地理编码。API 按 VIN、北京时间自然日关联已保存的省、市、大区、定位时间和状态。
车辆跨城时,以该日最后有效定位归属为准。原始定位精度保留到小数点后六位;缓存使用同一精度的坐标,避免用附近车辆的地区替代。
API 设置 `DAILY_GEOGRAPHY_ENABLED=true` 后启动后台任务:
- 每分钟更新当天定位并解析待处理地区;每小时重查前两天,覆盖跨日、延迟上报及服务重启。
- 多 API 实例用 MySQL 连接级命名锁避免重复运行。
- 新坐标使旧解析失效;旧定位不能覆盖新定位;异步返回只更新仍匹配该坐标的记录。
- 持久化坐标解析缓存,复用 180 天内的结果,降低地图接口请求量。
- 解析失败保留 ERROR 和退避重试时间;历史任务与当日任务分开运行,批量补算不会阻塞导出。
- 历史批量结束后,API 后台继续重试历史失败记录。无历史定位记录标记 NO_LOCATION,与接口失败区别处理。
- 直辖市、省直辖县级市(例如潜江市)处理高德 city=[] 的返回。大区使用华东、华北、华中、华南、东北、西南、西北。
## 表结构与发布
先执行 `deploy/migrations/046_daily_geography.sql`,再发布 API 和 Web,开启 `DAILY_GEOGRAPHY_ENABLED=true`
旧版 API 不依赖新表,回滚可以保留已经补算的数据。线上版本为 `daily-geography-202609101620`
独立批量工具:
```sh
cd vehicle-data-platform/apps/api
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -o daily-geography ./cmd/daily-geography
# 使用与 platform-api 相同的 MYSQL_DSN、TDENGINE_*、AMAP_API_KEY 环境配置。
./daily-geography --mode backfill --from 2026-07-03 --to 2026-09-09
./daily-geography --mode resolve --from 2026-07-03 --to 2026-09-09
./daily-geography --mode status --from 2026-07-03 --to 2026-09-10
```
默认历史范围为最早氢耗记录至昨天。批量按天扫描该日各车最后定位,同时为缺少定位的氢耗车辆日建档;可重复运行,支持断点后继续解析。
`status` 返回各状态数量及尚未建档的氢耗车辆日数量,不把已尝试但失败的记录算作成功。
`resolve` 处理当前已到重试时间的记录;仍处于退避时间内的失败由常驻后台继续处理。
本次历史范围从 2026-07-03 起,覆盖已有氢耗历史。里程库还包含更早的导入数据及2000年异常日期,不将其当前位置套用为历史地区。
## 验证
单元测试覆盖历史查询失败、跨北京时间自然日、协议间最后定位选择、持久化缓存命中、地图接口限流重试、直辖市和省直辖市。
日里程 SQL 在分页后关联地区表,权限、车辆与日期筛选及总数保持原有逻辑。
线上通过真实浏览器进入氢耗视图后点击 Excel 导出,再读回下载文件:地区列值正确,导出阶段历史定位和地图解析请求数均为 0;单车示例约440毫秒完成。
## 生产补算结果(2026-09-10 16:17
2026-07-03 至 2026-09-09 共建档 41,158 个车辆日:41,091 个已解析、67 个无有效定位,待解析和失败均为 0。历史氢耗记录全部覆盖:26,372 个已解析、67 个无有效定位,未建档为 0。
最终两条设备无效坐标 `(-0.999999,-0.999999)` 已通过后台过滤后重新扫描当天历史,成功选取较早的有效点并解析。过滤在聚合查询之前执行,避免无效末点遮蔽当天有效位置。
粤A08512FLNXNEGRR2SR3166122026-08-31 地区为湖北省/武汉市/华中,定位时间 23:59:54(北京时间)。
桌面和手机真实浏览器 Excel 导出均通过;最终发布再次验证省、市、大区、修正氢耗及物理氢耗列,导出触发位置查询数为 0,浏览器错误为 0。生产常驻任务日志持续每分钟解析当天新位置。
@@ -0,0 +1,19 @@
# Apple Design 改造前回退基线
- 日期:2026-09-17Asia/Shanghai
- 生产版本:`native-alarm-details-202609171739`
- 线上应用备份:`/opt/lingniu-vehicle-platform/backups/pre-apple-design-202609171805/app.tar.gz`
- 线上配置备份:同目录 `runtime-config.tar.gz`,权限0600,仅服务器保留。
- 同目录 `SHA256SUMS` 已逐项校验成功;应用归档可完整列出。
- 本地工作区归档:`outputs/apple-design-20260917/worktree-before-ui.tar.gz`,包含1892个已跟踪及未忽略文件,权限0600。
- 工作区归档 SHA-256`d0aa0826a9ac18d90dd9774cc3f75c02c9a01f27b627b85a8c3086cee8b36824`
- Git 回退 Tag`pre-apple-design-20260917-1805`;包含当前应用源代码、测试、迁移、文档和自写运维/分析脚本。
- 原始车辆数据、截图、编译缓存、带结果的分析Notebook保留在归档,未推送为源码。
## 回退方式
源码:从上述 Tag 创建新的修复分支,避免覆盖未提交工作。
应用:将 `current` 原子指回 `/opt/lingniu-vehicle-platform/releases/native-alarm-details-202609171739`,恢复对应 `PLATFORM_RELEASE`,重启平台API及需要同步版本的消费者。此轮UI改造不应修改业务数据或降低鉴权。
备份包含运行凭证,不能提交Git或提供公开下载。当前版本目录保留,独立tar归档用于目录损坏时恢复。
@@ -0,0 +1,45 @@
# 氢耗统计与导出口径修正
百公里氢耗使用修正用氢量(`soc_balanced_consumption_kg`)除以匹配里程乘以 100。
匹配里程延续既有口径:优先氢能统计的混动里程,否则使用日纯氢里程。
每日值、车辆区间合计和车队区间汇总均使用此口径;区间效率只计质量通过且有匹配里程的车辆日。
修正用氢量缺失时不回退物理用氢量,零里程不计算效率。
物理用氢量仍保留在 Excel 独立列及计算证据中。
Excel「氢能明细」增加当天所在省、市、大区、定位时间和位置状态。
省市取北京时间该日最后一个有效历史定位点,经现有服务端高德接口解析。
跨省、市行驶以该点归属为准,不表示全天仅在该行政区活动。
无当天有效定位时标记未知;历史位置或地址接口失败时终止导出并提示重试。
位置请求限制为三个并发,支持进度显示及取消。大范围导出会增加位置查询耗时。
大区采用七区划分:华东、华北、华中、华南、东北、西南、西北;西部未合并成“华西”。
直辖市的城市字段在解析接口未返回时使用直辖市名称。
本次无需数据库迁移或历史用氢重算,依赖已有修正用氢量、历史定位数据及高德服务配置。
已同时发布 API 和 Web,版本 `hydrogen-consumption-202609100956`
保留上一版 `platform-performance-202609091012` 供回滚。
正式域名 https://vehicle.d.lnoneos.com 上抽查 200 条车辆日记录:149 条可计算,
全部符合修正口径,其中 146 条修正量与物理量不同;单车区间汇总核验通过。
当天历史位置和高德省市解析核验通过。API 服务 active,运行版本及二进制 SHA-256 与发布产物一致。
发布脚本的当前及兼容静态资源逐字节检查通过。
验收证据位于 `outputs/hydrogen-consumption-release-20260910/`
## 2026-09-10 补充修复与线上交互验收
版本 `hydrogen-consumption-202609101134` 已发布,上一版 `hydrogen-consumption-202609100956` 保留。
上次仅统一日氢耗比率,日数据主字段 `hydrogenConsumptionKg` 仍为物理量;现改为修正量,
物理量通过 `hydrogenPhysicalConsumptionKg` 单独返回。计算证据主比率字段改为修正比率,
原物理比率通过 `physicalConsumptionKgPer100Km` 保留。客户权限过滤同时屏蔽新增物理量字段。
这些改动作用于历史查询,未改写原始物理计算证据。
氢耗视图导出现在以「氢能明细」作为第一张工作表,省、市、大区移至第3~5列;
文件名明确标为车辆氢耗明细。里程视图保留里程表在首位。
正式域名通过 Playwright + 已安装 Chrome 实际点击氢耗视图、导出 Excel,并用 ExcelJS 重新打开下载文件:
浙F09968F / 2026-09-01,修正量8.714kg,物理量12.813kg,匹配里程77km
每日氢耗11.316883116883117kg/100km,地区为浙江省、嘉兴市、华东;首表、列序、数值断言通过。
桌面1440×1000页面正常、无运行时错误。未覆盖手机端导出及用户尚未提供的具体异常记录。
另外抽查2026-07-13、2026-08-11、2026-09-08各200条历史车辆日,
主用氢量与修正量字段一致,可计算比率均符合修正公式。
@@ -0,0 +1,39 @@
# GB/T 32960 原生告警进入事件中心
车辆的 0x07 报警单元直接生成安全事件,不需要建立、启用自动化规则,也不主动发送通知。事件中心桌面列表和移动卡片使用具体告警名称作为标题,来源标明“车辆原生告警”;详情逐项显示告警名称,并保留最高报警等级、通用报警标志原值,以及储能装置、驱动电机、发动机、其他四类故障码。厂商故障码保留原值,不推断其含义。
接入使用现有 GB32960 FIELDS Kafka 消费链路,支持网关以 JSON 字符串承载的故障码数组。最高等级 1–3、2016版标准定义的报警位(bit0–18)非零、非空故障码任一项成立即创建事件;等级对应 minor / major / critical,只有位图或故障码时默认 minor。连续活动告警合并为一次告警过程,详情保留首次触发证据。只有完整有效的六个字段都报告无告警时,才自动恢复未处理/处理中的事件。已手动完成或忽略的事件保留处置状态;解除后再次出现告警会创建新事件。
缺失或无效的报警单元不参与开关判断,迟到上报及时间不递增的上报不更新告警状态。VIN 状态行锁负责并发保护,事件、证据、告警状态和 Kafka 数据库消费位点在同一事务提交。查询沿用现有事件中心权限、车辆范围与处置接口。
## 发布
1. 应用 `deploy/migrations/047_native_gb32960_alarms.sql`,创建原生告警状态和证据表。
2. 发布 API、Web 和 `alert-stream-evaluator`
3. 确认消费者配置 `ALERT_STREAM_MODE=active`,订阅 `vehicle.fields.go.gb32960.v1`。disabled/shadow 模式不会写事件。
4. 用完整告警报文验证事件创建;重复上报不新增;完整无告警报文使事件恢复。检查原始来源 ID、字段和发生时间可追溯。
本次不自动回填历史报文,也不修改运行环境配置。
## 2026-09-17 生产发布
已发布版本 `native-alarms-202609171723`,保留上一版 `daily-geography-202609101620`。迁移 047 成功,API 和流式消费者均 active;沿用原有消费组 `vehicle-alert-stream-shadow-v1` 及 active 模式,无消费位点重置。
上线前完整 API 模块测试、Web 生产构建、发布脚本测试通过;候选 API 与原版固定历史窗口的事件、里程结果逐项一致。上线后正式 HTTPS 接口确认运行版本;验收时已记录 24 条原生告警,抽查 20 条事件详情的事件类型、来源 ID 和六个告警字段全部通过。消费者观察窗口内 225 批完成、失败 0 次,已出现 2 次自动恢复。当前及三代兼容静态资源检查通过。
发布产物 SHA-256、迁移、候选比较和生产检查记录位于 `outputs/native-alarms-202609171723/`。仅新增两张数据库表;回滚程序可保留这两张表及已写入的告警证据。
## 2026-09-17 具体告警解释与历史纠正
版本 `native-alarm-details-202609171739` 已上线。按 GB/T 32960.3-2016 表18解析 bit0–18,事件名称直接显示“绝缘报警”“SOC低报警”等;多个位或故障码同时发生时,详情列出全部项目。厂商故障码显示故障类别、代码和“厂商定义”,不推断没有字典的含义。仅报告非零等级但没有具体项目时,明确说明车辆未上报具体故障项。
2016版 bit19–31 是预留位:不再单独触发原生事件,也不阻止已解除的标准告警恢复;存在其他有效告警时,预留位置位信息仍在详情及原始证据中保留。新入库证据同时保留存在的 `gb32960.header.version`。V2025扩展位暂按待匹配定义的扩展位展示,不套用2016版预留位清理规则。
生产核对中,涉及的车辆原始报文使用 V2016。修复时共检查37条原生事件:24条有效记录原位修正名称(23条绝缘报警、1条SOC低报警),保留 ID、发生时间、状态、处置记录和原始证据;13条等级为0、无故障码且仅有预留位的记录删除,并清理其事件动作、证据和活动状态引用。原始车端报文不受影响。完整修改前备份在服务器 `/opt/lingniu-vehicle-platform/backups/native-alarms/before-details-202609171739.json`,权限0600。
修复命令 `cmd/native-alarm-repair` 默认只预演;`--apply --backup <新文件>` 在事务内修复、写审计记录,备份成功落盘后才执行变更。拒绝覆盖备份或自动删除已有通知关联的事件。执行写入时停止流式消费者,随后与新版程序一同启动。
正式HTTPS接口逐项核验25条详情和列表标题通过(包括发布后新建事件),再次预演无需重命名或删除。相关后端测试、修复工具备份/删除边界测试、前端56项测试、生产构建和84个当前/108个兼容静态资源检查通过。发布证据:`outputs/native-alarm-details-20260917/`
位定义依据:[GB/T 32960.3-2016,表18](https://www.sae-hk.org/wp-content/uploads/2020/12/020-GBT-32960.3-2016-电动汽车远程服务与管理系统技术规范-第3部分:通讯协议及数据格式.pdf)。