perf(mileage): filter single-vehicle range queries
This commit is contained in:
@@ -171,7 +171,11 @@ async function requestDate(date: string): Promise<OneOsDailyMileage[]> {
|
||||
throw lastError instanceof Error ? lastError : new Error('OneOS mileage API request failed');
|
||||
}
|
||||
|
||||
async function requestRange(startDate: string, endDate: string): Promise<Map<string, OneOsDailyMileage[]>> {
|
||||
async function requestRange(
|
||||
startDate: string,
|
||||
endDate: string,
|
||||
plateNumbers: string[],
|
||||
): Promise<Map<string, OneOsDailyMileage[]>> {
|
||||
const { baseUrl, apiKey, timeoutMs } = apiConfig();
|
||||
const allRows: unknown[] = [];
|
||||
const seenCursors = new Set<string>();
|
||||
@@ -188,6 +192,7 @@ async function requestRange(startDate: string, endDate: string): Promise<Map<str
|
||||
endDate,
|
||||
pageSize: RANGE_PAGE_SIZE,
|
||||
};
|
||||
if (plateNumbers.length > 0) body.plateNumbers = plateNumbers;
|
||||
if (cursor) body.cursor = cursor;
|
||||
const response = await fetch(`${baseUrl}${RANGE_ENDPOINT}`, {
|
||||
method: 'POST',
|
||||
@@ -278,9 +283,13 @@ export async function fetchOneOsDailyMileage(
|
||||
|
||||
export async function fetchOneOsMileageDates(
|
||||
dates: string[],
|
||||
plateNumbers?: string[],
|
||||
): Promise<Map<string, OneOsDailyMileage[]>> {
|
||||
const result = new Map<string, OneOsDailyMileage[]>();
|
||||
const uniqueDates = Array.from(new Set(dates)).sort();
|
||||
const selectedPlates = Array.from(new Set(
|
||||
(plateNumbers || []).map(plate => plate.trim()).filter(Boolean),
|
||||
)).sort();
|
||||
if (uniqueDates.length === 0) return result;
|
||||
for (const date of uniqueDates) {
|
||||
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) throw new Error(`Invalid mileage date: ${date}`);
|
||||
@@ -303,10 +312,10 @@ export async function fetchOneOsMileageDates(
|
||||
await Promise.all(groups.map(async group => {
|
||||
const startDate = group[0];
|
||||
const endDate = group[group.length - 1];
|
||||
const key = `${startDate}:${endDate}`;
|
||||
const key = `${startDate}:${endDate}:${selectedPlates.length > 0 ? selectedPlates.join('\u0000') : '*'}`;
|
||||
let pending = rangeInflight.get(key);
|
||||
if (!pending) {
|
||||
pending = requestRange(startDate, endDate).finally(() => rangeInflight.delete(key));
|
||||
pending = requestRange(startDate, endDate, selectedPlates).finally(() => rangeInflight.delete(key));
|
||||
rangeInflight.set(key, pending);
|
||||
}
|
||||
const rowsByDate = await pending;
|
||||
|
||||
@@ -58,7 +58,7 @@ app.get('/:plate/recent', async (c) => {
|
||||
dates.push(fmt(dateCursor));
|
||||
dateCursor.setDate(dateCursor.getDate() + 1);
|
||||
}
|
||||
const rowsByDate = await fetchOneOsMileageDates(dates);
|
||||
const rowsByDate = await fetchOneOsMileageDates(dates, [plate]);
|
||||
|
||||
// 补全:从 start 到 end 每天一条
|
||||
const result: { date: string; dailyKm: number; isDataSynced: boolean }[] = [];
|
||||
|
||||
Reference in New Issue
Block a user