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();