fix(assets): 区域车型分解新增「待交车」字段,并合入「其他」车型
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- typeBreakdown 之前只产 4.5T/18T/49T 且仅含 inventory 字段, 导致区域级 待交车 与车型级 待:N 不一致、操作中合计 != 区域合计 - 后端 getTypeBreakdown 计算 pending(status==='Pending'), 并把不属 4.5T/18T/49T 的车辆聚合为「其他」类型 - 前端区域 mobile/desktop 视图把「待:」从 inventory 改读 pending - 点击穿透的 category 也由 'Inventory' 改 'Pending' Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2189,7 +2189,7 @@ export default function AssetsModule() {
|
|||||||
</td>
|
</td>
|
||||||
<td className="p-2 text-center text-gray-500 cursor-pointer hover:underline" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: city.city, vehicleType: tb.type, source: 'region', title: `区域运营统计 - ${city.city} - ${tb.type}` })}>{tb.total}</td>
|
<td className="p-2 text-center text-gray-500 cursor-pointer hover:underline" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: city.city, vehicleType: tb.type, source: 'region', title: `区域运营统计 - ${city.city} - ${tb.type}` })}>{tb.total}</td>
|
||||||
<td className="p-2 text-center text-green-500 cursor-pointer hover:underline" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: city.city, vehicleType: tb.type, category: 'Operating', source: 'region', title: `区域运营统计 - ${city.city} - ${tb.type} - 正在运营` })}>{tb.operating}</td>
|
<td className="p-2 text-center text-green-500 cursor-pointer hover:underline" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: city.city, vehicleType: tb.type, category: 'Operating', source: 'region', title: `区域运营统计 - ${city.city} - ${tb.type} - 正在运营` })}>{tb.operating}</td>
|
||||||
<td className="p-2 text-center text-orange-500 cursor-pointer hover:underline" onClick={() => { setShowPlateNumbers({ batch: 'All', model: 'All', location: city.city, vehicleType: tb.type, category: 'Inventory', source: 'region', title: `区域运营统计 - ${city.city} - ${tb.type} - 库存` }); }}>{tb.inventory}</td>
|
<td className="p-2 text-center text-orange-500 cursor-pointer hover:underline" onClick={() => { setShowPlateNumbers({ batch: 'All', model: 'All', location: city.city, vehicleType: tb.type, category: 'Pending', source: 'region', title: `区域运营统计 - ${city.city} - ${tb.type} - 待交车` }); }}>{tb.pending}</td>
|
||||||
<td className="p-2 text-center text-gray-400 text-[10px] italic">{tb.customers.slice(0, 2).join(', ')}</td>
|
<td className="p-2 text-center text-gray-400 text-[10px] italic">{tb.customers.slice(0, 2).join(', ')}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
@@ -2251,9 +2251,9 @@ export default function AssetsModule() {
|
|||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="font-bold text-orange-600 cursor-pointer"
|
className="font-bold text-orange-600 cursor-pointer"
|
||||||
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: r.region, vehicleType: tb.type, category: 'Inventory', source: 'region', title: `区域运营统计 - ${r.region} - ${tb.type} - 库存` })}
|
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: r.region, vehicleType: tb.type, category: 'Pending', source: 'region', title: `区域运营统计 - ${r.region} - ${tb.type} - 待交车` })}
|
||||||
>
|
>
|
||||||
待:{tb.inventory}
|
待:{tb.pending}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ export interface RegionTypeBreakdown {
|
|||||||
total: number;
|
total: number;
|
||||||
operating: number;
|
operating: number;
|
||||||
inventory: number;
|
inventory: number;
|
||||||
|
pending: number;
|
||||||
customers: string[];
|
customers: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -793,11 +793,21 @@ app.get('/region-stats', async (c) => {
|
|||||||
cityMap.get(city)!.push(v);
|
cityMap.get(city)!.push(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTypeBreakdown = (vList: Vehicle[]) =>
|
const getTypeBreakdown = (vList: Vehicle[]) => {
|
||||||
['4.5T', '18T', '49T'].map((type) => {
|
const KNOWN = ['4.5T', '18T', '49T'] as const;
|
||||||
const tv = vList.filter((v) => v.type === type);
|
const make = (label: string, tv: Vehicle[]) => ({
|
||||||
return { type, total: tv.length, operating: tv.filter((v) => v.status === 'Operating').length, inventory: tv.filter((v) => v.status === 'Inventory').length, customers: Array.from(new Set(tv.map((v) => v.customerName).filter(Boolean))) as string[] };
|
type: label,
|
||||||
}).filter((t) => t.total > 0);
|
total: tv.length,
|
||||||
|
operating: tv.filter((v) => v.status === 'Operating').length,
|
||||||
|
inventory: tv.filter((v) => v.status === 'Inventory').length,
|
||||||
|
pending: tv.filter((v) => v.status === 'Pending').length,
|
||||||
|
customers: Array.from(new Set(tv.map((v) => v.customerName).filter(Boolean))) as string[],
|
||||||
|
});
|
||||||
|
const known = KNOWN.map((type) => make(type, vList.filter((v) => v.type === type)));
|
||||||
|
const other = vList.filter((v) => !KNOWN.includes(v.type as typeof KNOWN[number]));
|
||||||
|
if (other.length > 0) known.push(make('其他', other));
|
||||||
|
return known.filter((t) => t.total > 0);
|
||||||
|
};
|
||||||
|
|
||||||
const regionOrder = ['华东', '华南', '华北', '华中', '西南', '西北', '其他'];
|
const regionOrder = ['华东', '华南', '华北', '华中', '西南', '西北', '其他'];
|
||||||
const result = regionOrder
|
const result = regionOrder
|
||||||
|
|||||||
Reference in New Issue
Block a user