refactor: 移动 types.ts 和 api.ts 到 modules/assets/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-01 19:19:11 +08:00
parent de0320bfcd
commit be6598a940
3 changed files with 3 additions and 3 deletions

92
src/modules/assets/api.ts Normal file
View File

@@ -0,0 +1,92 @@
import type {
SummaryData,
TypeSummary,
VehicleListItem,
DeptGroup,
RegionGroup,
CustomerStats,
RegionalInventoryStats,
} from './types';
const BASE = '/api/vehicles';
async function fetchJson<T>(url: string): Promise<T> {
const res = await fetch(url);
if (!res.ok) throw new Error(`API error: ${res.status} ${res.statusText}`);
return res.json();
}
export async function fetchSummary(): Promise<SummaryData> {
return fetchJson<SummaryData>(`${BASE}/summary`);
}
export async function fetchByType(): Promise<TypeSummary[]> {
return fetchJson<TypeSummary[]>(`${BASE}/by-type`);
}
export async function fetchVehicleList(params: {
batch?: string;
model?: string;
location?: string;
status?: string;
category?: string;
vehicleType?: string;
manager?: string;
customer?: string;
isColdChain?: string;
isTrailer?: string;
department?: string;
attendance?: string;
}): Promise<VehicleListItem[]> {
const query = new URLSearchParams();
if (params.batch) query.set('batch', params.batch);
if (params.model) query.set('model', params.model);
if (params.location) query.set('location', params.location);
if (params.status) query.set('status', params.status);
if (params.category) query.set('category', params.category);
if (params.vehicleType) query.set('vehicleType', params.vehicleType);
if (params.manager) query.set('manager', params.manager);
if (params.customer) query.set('customer', params.customer);
if (params.isColdChain) query.set('isColdChain', params.isColdChain);
if (params.isTrailer) query.set('isTrailer', params.isTrailer);
if (params.department) query.set('department', params.department);
if (params.attendance) query.set('attendance', params.attendance);
return fetchJson<VehicleListItem[]>(`${BASE}/list?${query.toString()}`);
}
export interface WeeklyDetailItem {
truck_id: number;
plate_number: string;
handover_date: string | null;
contract_type: string | null;
customer_name: string | null;
}
export async function fetchDeptStats(): Promise<DeptGroup[]> {
return fetchJson<DeptGroup[]>(`${BASE}/dept-stats`);
}
export async function fetchRegionStats(params?: { customer?: string; city?: string; region?: string }): Promise<RegionGroup[]> {
const query = new URLSearchParams();
if (params?.customer) query.set('customer', params.customer);
if (params?.city) query.set('city', params.city);
if (params?.region) query.set('region', params.region);
const qs = query.toString();
return fetchJson<RegionGroup[]>(`${BASE}/region-stats${qs ? `?${qs}` : ''}`);
}
export async function fetchCustomerStats(): Promise<CustomerStats[]> {
return fetchJson<CustomerStats[]>(`${BASE}/customer-stats`);
}
export async function fetchInventoryStats(): Promise<RegionalInventoryStats[]> {
return fetchJson<RegionalInventoryStats[]>(`${BASE}/inventory-stats`);
}
export async function fetchRegionChart(groupBy: string, top = 8, source = 'realtime'): Promise<{ name: string; value: number }[]> {
return fetchJson<{ name: string; value: number }[]>(`${BASE}/region-chart?groupBy=${groupBy}&top=${top}&source=${source}`);
}
export async function fetchWeeklyDetail(type: string): Promise<WeeklyDetailItem[]> {
return fetchJson<WeeklyDetailItem[]>(`${BASE}/weekly-detail?type=${type}`);
}

191
src/modules/assets/types.ts Normal file
View File

@@ -0,0 +1,191 @@
export interface SummaryData {
totalAssets: number;
operating: {
total: number;
self: number;
leased: number;
public: number;
hanging: number;
};
inventory: {
total: number;
inStock: number;
abnormal: number;
};
pendingDelivery: number;
weeklyNew: number;
weeklyRemoved: number;
weeklyDelivered: number;
weeklyReturned: number;
weeklyReplaced: number;
}
export interface BatchSummary {
batch: string;
total: number;
inventory: number;
inventoryRegions: Record<string, number>;
pending: number;
operating: number;
weeklyDelivered: number;
weeklyReturned: number;
weeklyReplaced: number;
}
export interface ModelSummary {
model: string;
total: number;
inventory: number;
inventoryRegions: Record<string, number>;
pending: number;
operating: number;
weeklyDelivered: number;
weeklyReturned: number;
weeklyReplaced: number;
batches: BatchSummary[];
}
export interface TypeSummary {
type: string;
totalAssets: number;
totalInventory: number;
totalOperating: number;
inventoryRegions: Record<string, number>;
pending: number;
weeklyDelivered: number;
weeklyReturned: number;
weeklyReplaced: number;
models: ModelSummary[];
}
export interface BatchGroup {
batch: string;
total: number;
inventory: number;
inventoryRegions: Record<string, number>;
pending: number;
operating: number;
weeklyDelivered: number;
weeklyReturned: number;
weeklyReplaced: number;
models: {
model: string;
type: string;
total: number;
inventory: number;
inventoryRegions: Record<string, number>;
pending: number;
operating: number;
weeklyDelivered: number;
weeklyReturned: number;
weeklyReplaced: number;
}[];
}
export interface InventoryTypeSummary {
type: string;
totalAssets: number;
totalInventory: number;
models: {
model: string;
totalAssets: number;
totalInventory: number;
regions: Record<string, number>;
}[];
regionSubtotals: Record<string, number>;
}
export interface VehicleListItem {
id: number;
plateNumber: string;
vin: string;
type: string;
model: string;
location: string;
province: string | null;
city: string | null;
status: string;
ownership: string;
contractNo: string | null;
customerName: string | null;
subjectOrg: string | null;
departmentName: string | null;
customerManager: string | null;
brandLabel: string | null;
orgName: string | null;
}
export interface RegionalInventoryStats {
region: string;
city: string;
brand: string;
type: string;
model: string;
batch: string;
quantity: number;
}
export interface ManagerStats {
manager: string;
department: string;
t4_5: number;
t4_5c: number;
t18: number;
t49: number;
trailer: number;
other: number;
total: number;
}
export interface DeptGroup {
department: string;
totalAssets: number;
operatingCount: number;
idleCount: number;
attendanceRate: number;
avgMileage: number;
managers: ManagerStats[];
}
export interface RegionTypeBreakdown {
type: string;
total: number;
operating: number;
inventory: number;
customers: string[];
}
export interface RegionCityGroup {
city: string;
totalAssets: number;
operatingCount: number;
pendingCount: number;
customers: string[];
typeBreakdown: RegionTypeBreakdown[];
}
export interface RegionGroup {
region: string;
totalAssets: number;
operatingCount: number;
pendingCount: number;
customers: string[];
typeBreakdown: RegionTypeBreakdown[];
cities: RegionCityGroup[];
}
export interface CustomerStats {
customer: string;
manager: string;
brand: string;
department: string;
region: string;
city: string;
t4_5: number;
t4_5c: number;
t18: number;
t49: number;
trailer: number;
other: number;
total: number;
}