diff --git a/src/App.tsx b/src/App.tsx index 78bcd0a..97921bd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -508,7 +508,7 @@ export default function App() { const [customerProvinceData, setCustomerProvinceData] = useState<{ name: string; value: number }[]>([]); useEffect(() => { if (customerChartView === 'province') { - fetchRegionChart('province', 5).then(setCustomerProvinceData).catch(() => setCustomerProvinceData([])); + fetchRegionChart('province', 5, 'vehicle').then(setCustomerProvinceData).catch(() => setCustomerProvinceData([])); } }, [customerChartView]); @@ -1456,6 +1456,8 @@ export default function App() { + *说明:当天里程>0即为出勤。 +
{deptViewMode === 'manager' && (
diff --git a/src/api.ts b/src/api.ts index 52a1fda..be568e8 100644 --- a/src/api.ts +++ b/src/api.ts @@ -83,8 +83,8 @@ export async function fetchInventoryStats(): Promise { return fetchJson(`${BASE}/inventory-stats`); } -export async function fetchRegionChart(groupBy: string, top = 8): Promise<{ name: string; value: number }[]> { - return fetchJson<{ name: string; value: number }[]>(`${BASE}/region-chart?groupBy=${groupBy}&top=${top}`); +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 { diff --git a/src/server/routes/vehicles.ts b/src/server/routes/vehicles.ts index e1eb6fe..a823db7 100644 --- a/src/server/routes/vehicles.ts +++ b/src/server/routes/vehicles.ts @@ -1035,22 +1035,31 @@ app.get('/region-chart', async (c) => { const vehicles = await getVehicles(); const operating = vehicles.filter((v) => v.status === 'Operating'); const groupBy = c.req.query('groupBy') || 'region'; // 'region' | 'province' + const source = c.req.query('source') || 'realtime'; // 'realtime' | 'vehicle' const top = Number(c.req.query('top')) || 8; let counts: Map; if (groupBy === 'province') { - // Get realtime province data - const [rows] = await pool.query(`SELECT plate_number, province FROM tab_truck_remote_sync_realtime_info WHERE is_deleted = 0 AND plate_number IS NOT NULL`); - const plateProvince = new Map(); - for (const row of rows as any[]) { - const plate = (row.plate_number || '').trim(); - const prov = (row.province || '').replace(/省|市$/, '').trim(); - if (plate && prov) plateProvince.set(plate, prov); - } counts = new Map(); - for (const v of operating) { - const prov = plateProvince.get(v.plateNumber) || '未知'; - counts.set(prov, (counts.get(prov) || 0) + 1); + if (source === 'vehicle') { + // Use vehicle table's own province field + for (const v of operating) { + const prov = (v.province || '').replace(/省|市$/, '').trim() || '未知'; + counts.set(prov, (counts.get(prov) || 0) + 1); + } + } else { + // Use realtime table province + const [rows] = await pool.query(`SELECT plate_number, province FROM tab_truck_remote_sync_realtime_info WHERE is_deleted = 0 AND plate_number IS NOT NULL`); + const plateProvince = new Map(); + for (const row of rows as any[]) { + const plate = (row.plate_number || '').trim(); + const prov = (row.province || '').replace(/省|市$/, '').trim(); + if (plate && prov) plateProvince.set(plate, prov); + } + for (const v of operating) { + const prov = plateProvince.get(v.plateNumber) || '未知'; + counts.set(prov, (counts.get(prov) || 0) + 1); + } } } else { counts = new Map();