Files
lingniu-vehicle-ingest/vehicle-data-platform/apps/web/src/api/client.ts
2026-07-04 13:31:36 +08:00

113 lines
4.5 KiB
TypeScript

import type {
ApiEnvelope,
DailyMileageRow,
DashboardSummary,
HistoryLocationRow,
MileageSummary,
OpsHealth,
QualityNotificationPlan,
Page,
QualitySummary,
QualityIssueRow,
RawFrameRow,
RealtimeLocationRow,
VehicleRealtimeRow,
VehicleCoverageRow,
VehicleCoverageSummary,
VehicleDetail,
VehicleIdentityResolution,
VehicleServiceOverview,
VehicleServiceSummary,
VehicleRow
} from './types';
export type RawFrameQuery = {
keyword?: string;
vin?: string;
protocol?: string;
dateFrom?: string;
dateTo?: string;
fields?: string[];
includeFields?: boolean;
limit?: number;
offset?: number;
};
export type VehicleOverviewBatchQuery = {
keywords: string[];
protocol?: string;
limit?: number;
offset?: number;
};
type ApiErrorEnvelope = {
error?: {
code?: string;
message?: string;
detail?: string;
};
traceId?: string;
};
async function request<T>(path: string, init?: RequestInit): Promise<T> {
const response = await fetch(path, init);
if (!response.ok) {
throw new Error(await responseErrorMessage(response));
}
const envelope = (await response.json()) as ApiEnvelope<T>;
return envelope.data;
}
async function responseErrorMessage(response: Response) {
try {
const envelope = (await response.json()) as ApiErrorEnvelope;
const message = envelope.error?.message?.trim();
const detail = envelope.error?.detail?.trim();
const traceID = envelope.traceId?.trim();
if (message && detail) {
return withTraceID(`${message}: ${detail}`, traceID);
}
if (message) {
return withTraceID(message, traceID);
}
} catch {
// Fall back to status when the server does not return the platform envelope.
}
return `request failed ${response.status}`;
}
function withTraceID(message: string, traceID?: string) {
return traceID ? `${message} (traceId: ${traceID})` : message;
}
export const api = {
dashboardSummary: () => request<DashboardSummary>('/api/dashboard/summary'),
vehicles: (params = new URLSearchParams()) => request<Page<VehicleRow>>(`/api/vehicles?${params.toString()}`),
vehicleResolve: (params = new URLSearchParams()) => request<VehicleIdentityResolution>(`/api/vehicles/resolve?${params.toString()}`),
vehicleCoverage: (params = new URLSearchParams()) => request<Page<VehicleCoverageRow>>(`/api/vehicles/coverage?${params.toString()}`),
vehicleCoverageSummary: (params = new URLSearchParams()) => request<VehicleCoverageSummary>(`/api/vehicles/coverage/summary?${params.toString()}`),
vehicleDetail: (params = new URLSearchParams()) => request<VehicleDetail>(`/api/vehicle-service?${params.toString()}`),
vehicleServiceSummary: () => request<VehicleServiceSummary>('/api/vehicle-service/summary'),
vehicleServiceOverview: (params = new URLSearchParams()) => request<VehicleServiceOverview>(`/api/vehicle-service/overview?${params.toString()}`),
vehicleServiceOverviews: (query: VehicleOverviewBatchQuery) => request<Page<VehicleServiceOverview>>('/api/vehicle-service/overviews', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(query)
}),
vehicleRealtime: (params = new URLSearchParams()) => request<Page<VehicleRealtimeRow>>(`/api/realtime/vehicles?${params.toString()}`),
realtimeLocations: (params = new URLSearchParams()) => request<Page<RealtimeLocationRow>>(`/api/realtime/locations?${params.toString()}`),
historyLocations: (params = new URLSearchParams()) => request<Page<HistoryLocationRow>>(`/api/history/locations?${params.toString()}`),
rawFrames: (params = new URLSearchParams()) => request<Page<RawFrameRow>>(`/api/history/raw-frames?${params.toString()}`),
rawFramesQuery: (query: RawFrameQuery) => request<Page<RawFrameRow>>('/api/history/raw-frames/query', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(query)
}),
mileageSummary: (params = new URLSearchParams()) => request<MileageSummary>(`/api/mileage/summary?${params.toString()}`),
dailyMileage: (params = new URLSearchParams()) => request<Page<DailyMileageRow>>(`/api/mileage/daily?${params.toString()}`),
qualitySummary: (params = new URLSearchParams()) => request<QualitySummary>(`/api/quality/summary?${params.toString()}`),
qualityIssues: (params = new URLSearchParams()) => request<Page<QualityIssueRow>>(`/api/quality/issues?${params.toString()}`),
qualityNotificationPlan: (params = new URLSearchParams()) => request<QualityNotificationPlan>(`/api/quality/notification-plan?${params.toString()}`),
opsHealth: () => request<OpsHealth>('/api/ops/health')
};