feat: 按城市改为按省份,数据从realtime表province获取,展示前5
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

- 后端region-chart支持groupBy=province,从realtime表读取省份
- 区域柱状图和客户饼图"按城市"改为"按省份"
- 省份展示前5,其余合入"其他"
- 前端state类型从'city'改为'province'

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-03-29 09:26:54 +08:00
parent db1e37b8bf
commit e910deac51
2 changed files with 42 additions and 41 deletions

View File

@@ -1034,13 +1034,30 @@ app.get('/debug', async (c) => {
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' | 'city'
const groupBy = c.req.query('groupBy') || 'region'; // 'region' | 'province'
const top = Number(c.req.query('top')) || 8;
const counts = new Map<string, number>();
for (const v of operating) {
const key = groupBy === 'city' ? resolveCity(v.city, v.province) : mapMacroRegion(v.province, v.city);
counts.set(key, (counts.get(key) || 0) + 1);
let counts: Map<string, number>;
if (groupBy === 'province') {
// Get realtime province data
const [rows] = await pool.query<any[]>(`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<string, string>();
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<string, number>();
for (const v of operating) {
const prov = plateProvince.get(v.plateNumber) || '未知';
counts.set(prov, (counts.get(prov) || 0) + 1);
}
} else {
counts = new Map<string, number>();
for (const v of operating) {
const key = mapMacroRegion(v.province, v.city);
counts.set(key, (counts.get(key) || 0) + 1);
}
}
// 分离"其他",对非"其他"排序取 Top N剩余全部合入"其他"