From d6c31dd2b67e36383d9a5b019f0c12cd8ea45ce9 Mon Sep 17 00:00:00 2001 From: kkfluous Date: Wed, 15 Apr 2026 10:22:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=9E=E6=97=B6=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E7=B4=AF=E8=AE=A1=E6=80=BB=E9=87=8C=E7=A8=8B=E5=B0=91=E7=AE=97?= =?UTF-8?q?=EF=BC=8CG7S=20=E6=95=B0=E6=8D=AE=E6=BA=90=20total=5Fkm=20?= =?UTF-8?q?=E4=B8=BA=20NULL=20=E6=97=B6=E7=94=A8=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E5=BA=93=20vehicle=5Ftotal=5Fmileage=20=E5=85=9C=E5=BA=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- src/server/routes/mileage/cache.ts | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/server/routes/mileage/cache.ts b/src/server/routes/mileage/cache.ts index 63945ef..b88352f 100644 --- a/src/server/routes/mileage/cache.ts +++ b/src/server/routes/mileage/cache.ts @@ -49,10 +49,26 @@ interface MileageRow { source: string; } +async function fetchBizTotalMileageMap(): Promise> { + // v_vehicle_daily_stats.total_km 对 G7S 数据源常为 NULL(G7 只回传日增量), + // 业务库 tab_mileage_assessment_vehicle.vehicle_total_mileage 是累加后的权威累计值, + // 用它兜底保证 totalKm 汇总完整。 + const [rows] = await pool.execute( + 'SELECT plate_number, vehicle_total_mileage FROM tab_mileage_assessment_vehicle WHERE is_deleted = 0' + ) as [{ plate_number: string; vehicle_total_mileage: string | number | null }[], unknown]; + const map = new Map(); + for (const r of rows) { + const km = Number(r.vehicle_total_mileage); + if (Number.isFinite(km) && km > 0) map.set(r.plate_number, km); + } + return map; +} + function mergeVehicles( mileageRows: MileageRow[], infoMap: Map, yesterdayMap: Map, + bizTotalMap: Map, ): CachedVehicle[] { const mileageMap = new Map(); for (const row of mileageRows) { @@ -66,11 +82,13 @@ function mergeVehicles( const info = infoMap.get(m.plate); const dailyKm = Number(m.daily_km) || 0; const source = m.source || 'NONE'; + const gpsTotal = m.total_km !== null ? Number(m.total_km) : null; + const bizTotal = bizTotalMap.get(m.plate); return { plate: m.plate, vin: m.vin, dailyKm, - totalKm: m.total_km !== null ? Number(m.total_km) : null, + totalKm: gpsTotal !== null ? gpsTotal : (bizTotal ?? null), source, isOnline: source !== 'NONE' && dailyKm > 0, isDataSynced: source !== 'NONE', @@ -91,7 +109,7 @@ export async function refreshMonitoringCache(): Promise { console.log('[mileage] refreshing monitoring cache...'); const start = Date.now(); - const [mileageRows, yesterdayMap, infoMap, targetRows] = await Promise.all([ + const [mileageRows, yesterdayMap, infoMap, targetRows, bizTotalMap] = await Promise.all([ (async () => { const [dateRows] = await mileagePool.execute( 'SELECT MAX(stat_date) as latest FROM v_vehicle_daily_stats' @@ -124,6 +142,7 @@ export async function refreshMonitoringCache(): Promise { JOIN tab_mileage_assessment_vehicle v ON v.target_id = t.id AND v.is_deleted = 0 WHERE t.is_deleted = 0` ).then(([rows]) => rows as { id: number; target_name: string; plate_number: string }[]), + fetchBizTotalMileageMap(), ]); const targetPlatesMap = new Map>(); @@ -134,7 +153,7 @@ export async function refreshMonitoringCache(): Promise { } const targetNames = Array.from(targetPlatesMap.keys()); - const vehicles = mergeVehicles(mileageRows, infoMap, yesterdayMap); + const vehicles = mergeVehicles(mileageRows, infoMap, yesterdayMap, bizTotalMap); const totalToday = vehicles.reduce((sum, v) => sum + v.dailyKm, 0); const totalAll = vehicles.reduce((sum, v) => sum + (v.totalKm || 0), 0); @@ -153,7 +172,7 @@ export async function refreshMonitoringCache(): Promise { } export async function queryDateMileage(dateStr: string): Promise { - const [mileageRows, yesterdayRows, infoMap] = await Promise.all([ + const [mileageRows, yesterdayRows, infoMap, bizTotalMap] = await Promise.all([ mileagePool.execute( 'SELECT plate, vin, daily_km, total_km, source FROM v_vehicle_daily_stats WHERE stat_date = ?', [dateStr] @@ -163,6 +182,7 @@ export async function queryDateMileage(dateStr: string): Promise r as { plate: string; daily_km: string }[]), fetchVehicleInfoMap(), + fetchBizTotalMileageMap(), ]); const yesterdayMap = new Map(); @@ -172,7 +192,7 @@ export async function queryDateMileage(dateStr: string): Promise existing) yesterdayMap.set(r.plate, km); } - return mergeVehicles(mileageRows, infoMap, yesterdayMap); + return mergeVehicles(mileageRows, infoMap, yesterdayMap, bizTotalMap); } export function buildDateFilters(vehicles: CachedVehicle[]): MonitoringFilters {