perf: reuse mileage target snapshots

This commit is contained in:
kkfluous
2026-08-07 17:46:51 +08:00
parent 2de417e109
commit 8a7ce7eccf
4 changed files with 113 additions and 5 deletions
@@ -0,0 +1,70 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { targetVehicleMileageFromMonitoringCache } from './target-vehicle-cache.js';
import type { CachedVehicle, MonitoringCache } from './types.js';
function vehicle(plate: string, overrides: Partial<CachedVehicle> = {}): CachedVehicle {
return {
plate,
vin: '',
dailyKm: 12.3,
totalKm: 456.7,
source: 'ONEOS_API',
sourceProtocol: 'GB32960',
sourceCategory: 'INSTRUMENT',
dataTime: '2026-08-07T10:00:00+08:00',
calculatedAt: null,
updatedAt: null,
isOnline: true,
isDataSynced: true,
customer: null,
department: null,
manager: null,
managerId: null,
rentStatus: null,
entity: null,
project: null,
region: null,
brand: null,
targetNames: [],
yesterdayKm: 0,
...overrides,
};
}
function cache(vehicles: CachedVehicle[]): MonitoringCache {
return {
vehicles,
stats: { totalToday: 0, totalAll: 0, vehicleCount: vehicles.length },
filters: {
departments: [], customers: [], plates: [], projects: [], entities: [],
rentStatuses: [], platePrefixes: [], targetNames: [], regions: [], brands: [],
},
targetPlatesMap: new Map(),
updatedAt: '2026-08-07T10:00:00+08:00',
};
}
test('reuses only the current-day monitoring snapshot and filters target plates', () => {
const monitoringCache = cache([
vehicle('粤A1'),
vehicle('粤A2', { dailyKm: -1, totalKm: null, isOnline: false }),
]);
const result = targetVehicleMileageFromMonitoringCache(
monitoringCache,
'2026-08-07',
'2026-08-07',
['粤A2'],
);
assert.deepEqual(Array.from(result || []), [['粤A2', {
dailyKm: 0,
totalKm: null,
isOnline: false,
}]]);
assert.equal(
targetVehicleMileageFromMonitoringCache(monitoringCache, '2026-08-06', '2026-08-07', ['粤A2']),
null,
);
assert.equal(targetVehicleMileageFromMonitoringCache(null, '2026-08-07', '2026-08-07', ['粤A2']), null);
});
@@ -0,0 +1,27 @@
import type { MonitoringCache } from './types.js';
export interface TargetVehicleMileageSnapshot {
dailyKm: number;
totalKm: number | null;
isOnline: boolean;
}
export function targetVehicleMileageFromMonitoringCache(
cache: MonitoringCache | null,
requestedDate: string,
today: string,
plates: string[],
): Map<string, TargetVehicleMileageSnapshot> | null {
if (!cache || !requestedDate || requestedDate !== today) return null;
const selected = new Set(plates);
return new Map(
cache.vehicles
.filter(vehicle => selected.has(vehicle.plate))
.map(vehicle => [vehicle.plate, {
dailyKm: Math.max(0, Number(vehicle.dailyKm) || 0),
totalKm: vehicle.totalKm == null ? null : Math.max(0, Number(vehicle.totalKm) || 0),
isOnline: vehicle.isOnline,
}]),
);
}
+15 -4
View File
@@ -4,6 +4,8 @@ import { getCache } from './cache.js';
import { fetchOneOsDailyMileage } from './oneos-api.js';
import { fetchVehicleInfoByPlates } from './vehicle-info.js';
import { filterByPermission, maskCustomerNames } from '../../auth/permissions.js';
import { shanghaiDate } from './monitoring-cache-policy.js';
import { targetVehicleMileageFromMonitoringCache } from './target-vehicle-cache.js';
const app = new Hono();
@@ -252,11 +254,20 @@ app.get('/:id/vehicles', async (c) => {
) as [any[], unknown];
const plates: string[] = rows.map((r: any) => r.plate_number);
const infoMap = await fetchVehicleInfoByPlates(plates);
const cachedDateMileageMap = targetVehicleMileageFromMonitoringCache(
getCache(),
date,
shanghaiDate(),
plates,
);
const [infoMap, mileageRows] = await Promise.all([
fetchVehicleInfoByPlates(plates),
date && !cachedDateMileageMap ? fetchOneOsDailyMileage(date, plates) : Promise.resolve([]),
]);
const dateMileageMap = new Map<string, { dailyKm: number; totalKm: number | null; isOnline: boolean }>();
if (date && plates.length > 0) {
const mileageRows = await fetchOneOsDailyMileage(date, plates);
const dateMileageMap = cachedDateMileageMap
|| new Map<string, { dailyKm: number; totalKm: number | null; isOnline: boolean }>();
if (!cachedDateMileageMap && date && plates.length > 0) {
for (const m of mileageRows) {
const existing = dateMileageMap.get(m.plateNumber);
const dailyKm = m.status === 'NORMAL' ? (Number(m.dailyMileageKm) || 0) : 0;