From 66de41d50b8b58bc36fc784c502021619eca952a Mon Sep 17 00:00:00 2001 From: kkfluous Date: Wed, 1 Apr 2026 23:29:31 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20KPI=E7=BB=9F=E8=AE=A1=E8=B7=9F=E9=9A=8F?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=9D=A1=E4=BB=B6=E5=8F=98=E5=8C=96+?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AD=9B=E9=80=89=E4=BF=AE=E6=AD=A3+?= =?UTF-8?q?=E9=83=A8=E9=97=A8=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - KPI统计(总里程/平均单车/监控台数)改为基于筛选后数据计算 - 移除不需要的 onlineCount 字段 - 快捷筛选"按客户"和全屏表格"客户"列改为真正的客户筛选 - 删除混乱的 projects 变量映射 - 部门列表按 一部→二部→三部 顺序排序 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/modules/mileage/MonitoringView.tsx | 11 +++++------ src/modules/mileage/types.ts | 1 - src/server/routes/mileage.ts | 25 +++++++++++++++++++------ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/modules/mileage/MonitoringView.tsx b/src/modules/mileage/MonitoringView.tsx index d76f279..87d2ca4 100644 --- a/src/modules/mileage/MonitoringView.tsx +++ b/src/modules/mileage/MonitoringView.tsx @@ -106,7 +106,7 @@ export default function MonitoringView() { const [appliedMileageRange, setAppliedMileageRange] = useState({ min: '', max: '' }); const [vehicles, setVehicles] = useState([]); - const [stats, setStats] = useState({ totalToday: 0, totalAll: 0, onlineCount: 0, vehicleCount: 0 }); + const [stats, setStats] = useState({ totalToday: 0, totalAll: 0, vehicleCount: 0 }); const [filterOptions, setFilterOptions] = useState({ departments: [], customers: [], plates: [], projects: [], entities: [] }); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); @@ -119,7 +119,6 @@ export default function MonitoringView() { const departments = filterOptions.departments; const plateNumbers = filterOptions.plates; - const projects = filterOptions.customers; // 加载首页数据 const loadFirstPage = useCallback(() => { @@ -327,14 +326,14 @@ export default function MonitoringView() { 在线状态
- 客户项目 + 客户
diff --git a/src/modules/mileage/types.ts b/src/modules/mileage/types.ts index 7aa656c..3f82294 100644 --- a/src/modules/mileage/types.ts +++ b/src/modules/mileage/types.ts @@ -17,7 +17,6 @@ export interface MonitoringVehicle { export interface MonitoringStats { totalToday: number; totalAll: number; - onlineCount: number; vehicleCount: number; } diff --git a/src/server/routes/mileage.ts b/src/server/routes/mileage.ts index a773947..2d72dc1 100644 --- a/src/server/routes/mileage.ts +++ b/src/server/routes/mileage.ts @@ -43,7 +43,7 @@ interface CachedVehicle { interface MonitoringCache { vehicles: CachedVehicle[]; - stats: { totalToday: number; totalAll: number; onlineCount: number; vehicleCount: number }; + stats: { totalToday: number; totalAll: number; vehicleCount: number }; filters: { departments: string[]; customers: string[]; plates: string[]; projects: string[]; entities: string[] }; updatedAt: string; } @@ -113,10 +113,16 @@ async function refreshMonitoringCache() { // 预计算统计信息 const totalToday = vehicles.reduce((sum, v) => sum + v.dailyKm, 0); const totalAll = vehicles.reduce((sum, v) => sum + (v.totalKm || 0), 0); - const onlineCount = vehicles.filter(v => v.isOnline).length; + // 预提取筛选选项 - const departments = Array.from(new Set(vehicles.map(v => v.department).filter(Boolean))) as string[]; + const deptOrder = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']; + const departments = (Array.from(new Set(vehicles.map(v => v.department).filter(Boolean))) as string[]) + .sort((a, b) => { + const ai = deptOrder.findIndex(d => a.includes(d)); + const bi = deptOrder.findIndex(d => b.includes(d)); + return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi); + }); const customers = Array.from(new Set(vehicles.map(v => v.customer).filter(Boolean))) as string[]; const plates = vehicles.map(v => v.plate); const projects = Array.from(new Set(vehicles.map(v => v.project).filter(Boolean))) as string[]; @@ -124,7 +130,7 @@ async function refreshMonitoringCache() { monitoringCache = { vehicles, - stats: { totalToday, totalAll, onlineCount, vehicleCount: vehicles.length }, + stats: { totalToday, totalAll, vehicleCount: vehicles.length }, filters: { departments, customers, plates, projects, entities }, updatedAt: new Date().toISOString(), }; @@ -142,7 +148,7 @@ setInterval(refreshMonitoringCache, 2 * 60 * 1000); // GET /monitoring — 从缓存取数据,支持筛选/排序/分页 app.get('/monitoring', (c) => { if (!monitoringCache) { - return c.json({ vehicles: [], stats: { totalToday: 0, totalAll: 0, onlineCount: 0, vehicleCount: 0 }, filters: { departments: [], customers: [], plates: [], projects: [], entities: [] }, total: 0, page: 1, totalPages: 1, updatedAt: new Date().toISOString() }); + return c.json({ vehicles: [], stats: { totalToday: 0, totalAll: 0, vehicleCount: 0 }, filters: { departments: [], customers: [], plates: [], projects: [], entities: [] }, total: 0, page: 1, totalPages: 1, updatedAt: new Date().toISOString() }); } const sortBy = c.req.query('sortBy') || 'today'; @@ -179,6 +185,13 @@ app.get('/monitoring', (c) => { const total = vehicles.length; + // 基于筛选后的数据计算统计 + const filteredStats = { + totalToday: vehicles.reduce((sum, v) => sum + v.dailyKm, 0), + totalAll: vehicles.reduce((sum, v) => sum + (v.totalKm || 0), 0), + vehicleCount: vehicles.length, + }; + // 排序 vehicles = [...vehicles].sort((a, b) => { const valA = sortBy === 'today' ? a.dailyKm : (a.totalKm || 0); @@ -192,7 +205,7 @@ app.get('/monitoring', (c) => { return c.json({ vehicles: paged, - stats: monitoringCache.stats, + stats: filteredStats, filters: monitoringCache.filters, total, page,