fix: KPI统计跟随筛选条件变化+客户筛选修正+部门排序

- KPI统计(总里程/平均单车/监控台数)改为基于筛选后数据计算
- 移除不需要的 onlineCount 字段
- 快捷筛选"按客户"和全屏表格"客户"列改为真正的客户筛选
- 删除混乱的 projects 变量映射
- 部门列表按 一部→二部→三部 顺序排序

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-01 23:29:31 +08:00
parent c73e20bacf
commit 66de41d50b
3 changed files with 24 additions and 13 deletions

View File

@@ -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,