Files
ln-bi/docs/superpowers/specs/2026-03-27-three-modules-design.md
kkfluous 253cc2f2c0 fix(scheduling): fix vehicle type classification and algorithm candidate matching
- classifyVehicleType now parses dic_type.dic_name (e.g. "4.5吨冷链车") instead of raw model code
- Remove overly strict completionRate >= 0.8 filter for hopeless candidates
- Use vehicle's yearTarget as fallback when inventory has no assessment target
- Filter out suggestions with no candidates (not actionable)
- estimatedGain counts rescue_hopeless suggestions as potential gains

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 20:31:44 +08:00

154 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 三大运营统计模块设计
从 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. 验证构建通过