feat(platform): consolidate production vehicle data workflows
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { MONITOR_REFRESH, monitorMapQueryParams, monitorQueryParams } from './useMonitorData';
|
||||
import { MAX_MONITOR_SEARCH_TERMS, MONITOR_REFRESH, monitorMapQueryParams, monitorQueryParams, parseMonitorSearchTerms } from './useMonitorData';
|
||||
|
||||
describe('monitor query params', () => {
|
||||
it('keeps server-owned status filters and bounded list size', () => {
|
||||
@@ -20,6 +20,14 @@ describe('monitor query params', () => {
|
||||
expect(monitorMapQueryParams({ keyword: '粤A1', protocol: '', status: '' }, viewport).has('bounds')).toBe(false);
|
||||
expect(monitorMapQueryParams({ keyword: '', protocol: '', status: '' }, viewport).get('bounds')).toBe(viewport.bounds);
|
||||
});
|
||||
|
||||
it('normalizes pasted plates, removes duplicates, and sends one batch parameter', () => {
|
||||
expect(parseMonitorSearchTerms('粤ag18312\n川AHTWO1,粤AG18312 京A00001')).toEqual(['粤AG18312', '川AHTWO1', '京A00001']);
|
||||
const params = monitorQueryParams({ keyword: '粤AG18312\n川AHTWO1,粤AG18312', protocol: '', status: '' }, 200);
|
||||
expect(params.get('keywords')).toBe('粤AG18312,川AHTWO1');
|
||||
expect(params.get('keyword')).toBeNull();
|
||||
expect(parseMonitorSearchTerms(Array.from({ length: MAX_MONITOR_SEARCH_TERMS + 5 }, (_, index) => `粤A${index}`).join('\n'))).toHaveLength(MAX_MONITOR_SEARCH_TERMS);
|
||||
});
|
||||
});
|
||||
|
||||
describe('monitor refresh cadence', () => {
|
||||
|
||||
@@ -20,9 +20,28 @@ export const MONITOR_REFRESH = {
|
||||
alerts: 15_000
|
||||
} as const;
|
||||
|
||||
export const MAX_MONITOR_SEARCH_TERMS = 100;
|
||||
|
||||
export function parseMonitorSearchTerms(value: string) {
|
||||
const terms: string[] = [];
|
||||
const seen = new Set<string>();
|
||||
for (const raw of value.split(/[\s,,、;;]+/)) {
|
||||
const term = raw.trim();
|
||||
if (!term) continue;
|
||||
const key = term.toLocaleUpperCase();
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
terms.push(term.toLocaleUpperCase());
|
||||
if (terms.length === MAX_MONITOR_SEARCH_TERMS) break;
|
||||
}
|
||||
return terms;
|
||||
}
|
||||
|
||||
export function monitorQueryParams(filters: MonitorFilters, limit: number) {
|
||||
const params = new URLSearchParams({ limit: String(limit) });
|
||||
if (filters.keyword.trim()) params.set('keyword', filters.keyword.trim());
|
||||
const terms = parseMonitorSearchTerms(filters.keyword);
|
||||
if (terms.length === 1) params.set('keyword', terms[0]);
|
||||
if (terms.length > 1) params.set('keywords', terms.join(','));
|
||||
if (filters.protocol) params.set('protocol', filters.protocol);
|
||||
if (filters.status) params.set('status', filters.status);
|
||||
if (filters.status === 'online' || filters.status === 'offline') params.set('online', filters.status);
|
||||
@@ -32,11 +51,11 @@ export function monitorQueryParams(filters: MonitorFilters, limit: number) {
|
||||
export function monitorMapQueryParams(filters: MonitorFilters, viewport: MonitorViewport) {
|
||||
const params = monitorQueryParams(filters, 10_000);
|
||||
params.set('zoom', String(viewport.zoom));
|
||||
if (viewport.bounds && !filters.keyword.trim()) params.set('bounds', viewport.bounds);
|
||||
if (viewport.bounds && parseMonitorSearchTerms(filters.keyword).length === 0) params.set('bounds', viewport.bounds);
|
||||
return params;
|
||||
}
|
||||
|
||||
export function useMonitorData(filters: MonitorFilters, viewport: MonitorViewport, selectedVin: string) {
|
||||
export function useMonitorData(filters: MonitorFilters, viewport: MonitorViewport, selectedVin: string, mapEnabled = true, vehicleEnabled = true) {
|
||||
const params = monitorQueryParams(filters, 200);
|
||||
const mapParams = monitorMapQueryParams(filters, viewport);
|
||||
|
||||
@@ -48,12 +67,15 @@ export function useMonitorData(filters: MonitorFilters, viewport: MonitorViewpor
|
||||
const vehicles = useQuery({
|
||||
queryKey: ['monitor', 'vehicles', params.toString()],
|
||||
queryFn: () => api.vehicleRealtime(params),
|
||||
enabled: vehicleEnabled,
|
||||
placeholderData: (previous) => previous,
|
||||
refetchInterval: MONITOR_REFRESH.fleet
|
||||
});
|
||||
|
||||
const map = useQuery({
|
||||
queryKey: ['monitor', 'map', mapParams.toString()],
|
||||
queryFn: () => api.monitorMap(mapParams),
|
||||
enabled: mapEnabled,
|
||||
placeholderData: (previous) => previous,
|
||||
staleTime: 5_000,
|
||||
refetchInterval: MONITOR_REFRESH.fleet
|
||||
|
||||
Reference in New Issue
Block a user