# 三大运营统计模块设计 从 lnoneos 原型迁移到 ln-bi 生产项目,使用真实 MySQL 数据。 ## 架构决策 - **数据源**:复用现有 `getVehicles()` 缓存(~1000 辆,内存聚合无性能问题) - **跳过**:出勤率、日均里程(无数据源),QR Code - **新增图标**:`Search`, `Filter`, `ArrowRightLeft` (lucide-react,已安装) ## 模块 1:部门运营统计 ### 后端 API **`GET /api/vehicles/dept-stats`** — 返回 `DeptGroup[]` 聚合逻辑:按 `Vehicle.departmentName` 分组,每个部门下按 `Vehicle.customerManager` 分组。每个业务员统计车型分布: | 车型类别 | 过滤条件 | |---|---| | t4_5 | type=4.5T 且 model 不含"冷链" | | t4_5c | type=4.5T 且 model 含"冷链" | | t18 | type=18T | | t49 | type=49T | | trailer | model 含"挂车" | | other | 以上都不是 | 部门级别额外字段:`totalAssets`(运营中的)、`operatingCount`(status=Operating)、`idleCount`(status=Inventory 或 Abnormal)。 ### 后端:扩展 `/api/vehicles/list` 新增查询参数: - `manager` — 按客户经理筛选 - `customer` — 按客户名称筛选 - `isColdChain` — true/false,筛选冷链/非冷链 - `isTrailer` — true/false,筛选挂车/非挂车 ### 前端类型 ```typescript interface ManagerStats { manager: string; department: string; t4_5: number; t4_5c: number; t18: number; t49: number; trailer: number; other: number; total: number; } interface DeptGroup { department: string; totalAssets: number; operatingCount: number; idleCount: number; managers: ManagerStats[]; } ``` ### 前端 UI 参照 lnoneos 1362-1880 行: - 顶部深色汇总条(总资产/运营中/闲置中,跳过平均出勤) - 按部门/按业务员切换 - 桌面表格 + 移动端卡片 - 展开部门显示业务员卡片,展开业务员显示 6 个车型格子(可点击下钻到车牌列表) ## 模块 2:区域运营统计 ### 后端 API **`GET /api/vehicles/region-stats`** — 返回 `RegionGroup[]` 新增大区映射函数(province/city → 华东/华南/华北/华中/西南/西北/其他)。按大区分组,每个区域下统计: - 按车型(4.5T/18T/49T)的资产/运营/库存数 - 列出区域内的客户列表 ```typescript interface RegionGroup { region: string; // 华东、华南等 totalAssets: number; operatingCount: number; inventoryCount: number; customers: string[]; typeBreakdown: { type: string; total: number; operating: number; inventory: number; customers: string[] }[]; } ``` ### 前端 UI 参照 lnoneos 1882-2174 行: - 筛选弹出框(客户搜索/区域/城市下拉) - 可展开区域行,展开后显示车型子行 - 桌面表格 + 移动端卡片 ## 模块 3:客户运营统计 ### 后端 API **`GET /api/vehicles/customer-stats`** — 返回 `CustomerStats[]` 按 `Vehicle.customerName` 分组(只统计 status=Operating 的车辆),每个客户统计: - 关联业务员(customerManager)、品牌(brandLabel)、部门(departmentName) - 大区(从 province/city 映射)、城市 - 6 个车型分列计数 + 合计 ```typescript interface CustomerStats { customer: string; manager: string; brand: string; department: string; region: string; city: string; t4_5: number; t4_5c: number; t18: number; t49: number; trailer: number; other: number; total: number; } ``` ### 前端 UI 参照 lnoneos 2176-2496 行: - 筛选弹出框(客户名/业务员搜索,品牌/部门/区域下拉) - 翡翠绿色主题表头 - 客户表格,各车型列可点击下钻 - 展开后显示 4 个详情卡片(客户详情/主要车型/运营状态/资产占比) - 桌面表格 + 移动端卡片 ## 文件变更清单 | 文件 | 变更 | |---|---| | `src/server/routes/vehicles.ts` | 新增 3 个 API 端点 + 扩展 `/list` 的过滤参数 + 大区映射函数 | | `src/types.ts` | 新增 `DeptGroup`, `ManagerStats`, `CustomerStats`, `RegionGroup` 接口 | | `src/server/types.ts` | 同步新增后端类型 | | `src/api.ts` | 新增 `fetchDeptStats`, `fetchRegionStats`, `fetchCustomerStats` | | `src/App.tsx` | 新增 3 个 section + 相关 state/toggle/filter 逻辑 + 扩展 showPlateNumbers 类型 | ## 实现顺序 1. 后端:大区映射 + 3 个 API + 扩展 list 过滤 2. 前端类型 + API 客户端 3. 部门运营统计 UI 4. 区域运营统计 UI 5. 客户运营统计 UI 6. 验证构建通过