feat(integration): 接入 1006 辆真实车辆数据 + 24h 异常派生 + 重点品牌锚定
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

数据
- data/vehicles-real.js: 从 车辆管理-1167382387645005824.xlsx 抽取 1006 辆,含车牌/VIN/品牌/型号/部门/客户/合同等真实字段
- 接入分布按业务要求: GB32960 在线 700 / JT808 在线 950 / 完全未对接 30
- 业务规则: GB 未对接 226 辆 = 苏龙 197 + 海伯特 29(从帕力安牌中重命名 29 辆)
- DEPARTMENTS 扩展 biz5 / biz6 以匹配 xlsx 部门
- fleet.js 优先使用 RAW_VEHICLES,前 12 辆叠加乍浦港地图坐标

派生状态
- integration.jsx 新增 effectiveStatus(): offline 且 lastSeen ≥ 24h → abnormal (异常)
- ConnPill 增 abnormal 红色态; 重点标记 = 双通道均 abnormal/未对接
- 筛选/KPI 全部基于派生状态实时计算(每 30s 重算)
This commit is contained in:
kkfluous
2026-04-28 15:57:14 +08:00
parent e38bd8a1d8
commit 97a2f54786
5 changed files with 141 additions and 36 deletions

View File

@@ -15,6 +15,8 @@ const DEPARTMENTS = [
{ id: "biz2", name: "业务二部", lead: "陈高伟", color: "#2E8C8C" },
{ id: "biz3", name: "业务三部", lead: "尚建华", color: "#7A8C2E" },
{ id: "biz4", name: "业务四部", lead: "刘念念", color: "#C97A3D" },
{ id: "biz5", name: "业务五部", lead: "周志强", color: "#7A4FB4" },
{ id: "biz6", name: "业务六部", lead: "金可鹏", color: "#B45F8A" },
{ id: "ops", name: "运营部", lead: "张兰", color: "#5C6E7C" },
];
@@ -211,7 +213,61 @@ const _enrich = (v, i) => {
};
};
const VEHICLES = [..._mapped, ..._extra].map(_enrich);
// ── Build VEHICLES ────────────────────────────────────────
// 优先使用 vehicles-real.js 提供的 1006 辆真实车辆数据;不存在则回退到合成数据。
let VEHICLES;
if (window.RAW_VEHICLES && window.RAW_VEHICLES.length) {
// 从 xlsx 抽取的 1006 辆真实数据
// 前 12 辆叠加乍浦港地图坐标,让总览地图保持原本的演示态
const RAW = window.RAW_VEHICLES;
const MAP_OVERLAY = [
{ x: 320, y: 180, h: 320, status: "ok", speed: 56, soc: 78 },
{ x: 460, y: 280, h: 60, status: "warn", speed: 0, soc: 24 },
{ x: 600, y: 240, h: 110, status: "ok", speed: 78, soc: 31 },
{ x: 760, y: 290, h: 200, status: "ok", speed: 64, soc: 82 },
{ x: 880, y: 410, h: 280, status: "ok", speed: 51, soc: 47 },
{ x: 240, y: 540, h: 30, status: "idle", speed: 0, soc: 96 },
{ x: 600, y: 470, h: 160, status: "ok", speed: 44, soc: 55 },
{ x: 540, y: 380, h: 240, status: "ok", speed: 38, soc: 71 },
{ x: 1000,y: 360, h: 90, status: "danger", speed: 0, soc: 9 },
{ x: 700, y: 540, h: 350, status: "ok", speed: 42, soc: 64 },
{ x: 960, y: 540, h: 70, status: "warn", speed: 0, soc: 18 },
{ x: 820, y: 470, h: 190, status: "ok", speed: 48, soc: 88 },
];
VEHICLES = RAW.map((v, i) => {
const overlay = i < MAP_OVERLAY.length ? MAP_OVERLAY[i] : { x:null, y:null, h:0, status:"ok", speed:0, soc:0 };
const dept = DEPARTMENTS.find(d => d.id === v.dept) || DEPARTMENTS[DEPARTMENTS.length-1];
// 派生氢电指标xlsx 没有这些字段)
const soc = overlay.soc || ((i * 17) % 90 + 10);
const h2 = overlay.status === "danger" ? 0.8 : +(soc / 100 * 5.6 + 0.2).toFixed(1);
const motorTemp = overlay.status === "danger" ? 102 : 58 + (i % 15);
const totalKm = 12000 + ((i * 1331) % 80000);
const lastMaintKm = totalKm - 1000 - ((i * 379) % 8000);
const nextMaintKm = lastMaintKm + 10000;
const kmToMaint = nextMaintKm - totalKm;
const lastMaintDays = 1 + ((i * 41) % 90);
return {
...v,
// overlay map fields
x: overlay.x, y: overlay.y, h: overlay.h,
status: overlay.status, // for map color (ok/warn/danger/idle)
speed: overlay.speed, soc,
// department display fields
deptName: dept.name, deptLead: dept.lead, deptColor: dept.color,
// hydrogen-electric derived
h2, h2Pressure: parseFloat(h2),
range: Math.round(soc * 6.2),
motorTemp,
totalKm, lastMaintKm, nextMaintKm, kmToMaint, lastMaintDays,
// legacy/compat
fleetCode: null,
};
});
} else {
// Fallback: 合成数据
VEHICLES = [..._mapped, ..._extra].map(_enrich);
}
// ── Aggregations for filters ──────────────────────────────
const COUNTS = {

4
data/vehicles-real.js Normal file

File diff suppressed because one or more lines are too long