import React, { useState, useEffect, useCallback } from 'react'; import { Truck, Warehouse, Activity, PlusCircle, MinusCircle, History, ChevronDown, ChevronRight, Info, Loader2, Search, Filter, ArrowRightLeft, } from 'lucide-react'; import { motion, AnimatePresence } from 'motion/react'; import type { SummaryData, TypeSummary, VehicleListItem, DeptGroup, RegionGroup, CustomerStats } from './types'; import { fetchSummary, fetchByType, fetchVehicleList, fetchWeeklyDetail, fetchDeptStats, fetchRegionStats, fetchCustomerStats } from './api'; import type { WeeklyDetailItem } from './api'; export default function App() { const [theme, setTheme] = useState<'soft' | 'minimal' | 'vibrant'>('soft'); const [expandedModels, setExpandedModels] = useState>(new Set()); const [expandedAssetTypes, setExpandedAssetTypes] = useState>(new Set()); const [showPlateNumbers, setShowPlateNumbers] = useState<{ batch: string; model: string; location: string; category?: 'Inventory' | 'Pending' | 'Delivered' | 'Returned' | 'Replaced' | 'Operating'; vehicleType?: string; manager?: string; customer?: string; isColdChain?: boolean; isTrailer?: boolean; type?: string; source?: string; } | null>(null); // Data state const [summary, setSummary] = useState(null); const [processedData, setProcessedData] = useState([]); const [modalVehicles, setModalVehicles] = useState([]); const [modalWeeklyDetail, setModalWeeklyDetail] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [lastUpdate, setLastUpdate] = useState(''); const [modalLoading, setModalLoading] = useState(false); // Dept/Region/Customer data const [deptData, setDeptData] = useState([]); const [regionData, setRegionData] = useState([]); const [customerData, setCustomerData] = useState([]); // Dept section state const [deptViewMode, setDeptViewMode] = useState<'department' | 'manager'>('department'); const [expandedDepts, setExpandedDepts] = useState>(new Set()); const [expandedManagerDetails, setExpandedManagerDetails] = useState>(new Set()); const [selectedManager, setSelectedManager] = useState('All'); // Region section state const [expandedRegions, setExpandedRegions] = useState>(new Set()); const [regionFilters, setRegionFilters] = useState({ region: '', city: '', customer: '' }); const [isRegionFilterOpen, setIsRegionFilterOpen] = useState(false); // Customer section state const [expandedCustomers, setExpandedCustomers] = useState>(new Set()); const [customerFilters, setCustomerFilters] = useState({ customer: '', brand: '', department: '', manager: '', region: '' }); const [isCustomerFilterOpen, setIsCustomerFilterOpen] = useState(false); const loadData = useCallback(async () => { try { setLoading(true); setError(null); const [s, byType, dept, region, cust] = await Promise.all([ fetchSummary(), fetchByType(), fetchDeptStats(), fetchRegionStats(), fetchCustomerStats(), ]); setSummary(s); setProcessedData(byType); setDeptData(dept); setRegionData(region); setCustomerData(cust); setLastUpdate(new Date().toLocaleString('zh-CN')); } catch (e) { setError(e instanceof Error ? e.message : '数据加载失败'); } finally { setLoading(false); } }, []); useEffect(() => { loadData(); const interval = setInterval(loadData, 60 * 1000); return () => clearInterval(interval); }, [loadData]); // Load modal vehicles useEffect(() => { if (!showPlateNumbers) { setModalVehicles([]); setModalWeeklyDetail([]); return; } setModalLoading(true); const cat = showPlateNumbers.category; // Weekly categories use the dedicated weekly-detail endpoint const weeklyTypes: Record = { Delivered: 'delivered', Returned: 'returned', Replaced: 'replaced', Pending: 'pending' }; if (cat && weeklyTypes[cat]) { setModalVehicles([]); fetchWeeklyDetail(weeklyTypes[cat]) .then(setModalWeeklyDetail) .catch(() => setModalWeeklyDetail([])) .finally(() => setModalLoading(false)); return; } // Normal vehicle list setModalWeeklyDetail([]); const params: Record = {}; if (showPlateNumbers.vehicleType) params.vehicleType = showPlateNumbers.vehicleType; if (showPlateNumbers.batch !== 'All') params.batch = showPlateNumbers.batch; if (showPlateNumbers.model !== 'All') params.model = showPlateNumbers.model; if (showPlateNumbers.location !== 'All') params.location = showPlateNumbers.location; if (cat === 'Inventory') params.status = 'Inventory'; if (cat === 'Operating') params.category = 'Operating'; if (showPlateNumbers.manager) params.manager = showPlateNumbers.manager; if (showPlateNumbers.customer) params.customer = showPlateNumbers.customer; if (!showPlateNumbers.type) { if (showPlateNumbers.isColdChain !== undefined) params.isColdChain = String(showPlateNumbers.isColdChain); if (showPlateNumbers.isTrailer !== undefined) params.isTrailer = String(showPlateNumbers.isTrailer); } // Map prototype's type field to backend vehicleType if (showPlateNumbers.type) { if (showPlateNumbers.type === '4.5T') { if (showPlateNumbers.isColdChain === true) { params.vehicleType = '4.5T冷链'; } else if (showPlateNumbers.isColdChain === false) { params.vehicleType = '4.5T普货'; } } else if (showPlateNumbers.type === '18T') { params.vehicleType = '18T'; } else if (showPlateNumbers.type === '49T') { params.vehicleType = '49T'; } else if (showPlateNumbers.type === '其他车型') { if (showPlateNumbers.isTrailer === true) { params.isTrailer = 'true'; } else if (showPlateNumbers.isTrailer === false) { params.vehicleType = '其他'; } } } fetchVehicleList(params) .then(setModalVehicles) .catch(() => setModalVehicles([])) .finally(() => setModalLoading(false)); }, [showPlateNumbers]); const allTypesExpanded = processedData.length > 0 && processedData.every((t) => expandedAssetTypes.has(t.type)); const toggleAllAssetTypes = () => { if (allTypesExpanded) { setExpandedAssetTypes(new Set()); } else { setExpandedAssetTypes(new Set(processedData.map((t) => t.type))); } }; const toggleAssetType = (type: string) => { const newSet = new Set(expandedAssetTypes); if (newSet.has(type)) newSet.delete(type); else newSet.add(type); setExpandedAssetTypes(newSet); }; const toggleModel = (model: string) => { const newSet = new Set(expandedModels); if (newSet.has(model)) newSet.delete(model); else newSet.add(model); setExpandedModels(newSet); }; const toggleDept = (dept: string) => { const newSet = new Set(expandedDepts); if (newSet.has(dept)) newSet.delete(dept); else newSet.add(dept); setExpandedDepts(newSet); }; const toggleManagerDetails = (manager: string) => { const newSet = new Set(expandedManagerDetails); if (newSet.has(manager)) newSet.delete(manager); else newSet.add(manager); setExpandedManagerDetails(newSet); }; const toggleRegion = (region: string) => { const newSet = new Set(expandedRegions); if (newSet.has(region)) newSet.delete(region); else newSet.add(region); setExpandedRegions(newSet); }; const toggleCustomer = (customer: string) => { const newSet = new Set(expandedCustomers); if (newSet.has(customer)) newSet.delete(customer); else newSet.add(customer); setExpandedCustomers(newSet); }; // Derived data for dept section const allManagersList = deptData.flatMap((d) => d.managers.map((m) => m.manager)).filter((v, i, a) => a.indexOf(v) === i).sort(); const managerStats = deptData .flatMap((d) => d.managers) .filter((m) => selectedManager === 'All' || m.manager === selectedManager) .sort((a, b) => b.total - a.total); // Derived data for customer section const filteredCustomerStats = customerData.filter((s) => { const mc = !customerFilters.customer || s.customer.toLowerCase().includes(customerFilters.customer.toLowerCase()); const mb = !customerFilters.brand || s.brand === customerFilters.brand; const md = !customerFilters.department || s.department === customerFilters.department; const mm = !customerFilters.manager || s.manager.toLowerCase().includes(customerFilters.manager.toLowerCase()); const mr = !customerFilters.region || s.region === customerFilters.region; return mc && mb && md && mm && mr; }); const uniqueBrands = Array.from(new Set(customerData.map((s) => s.brand).filter(Boolean))); const uniqueDepts = Array.from(new Set(customerData.map((s) => s.department).filter(Boolean))); const uniqueRegions = Array.from(new Set(customerData.map((s) => s.region))); const uniqueCities = Array.from(new Set(customerData.map((s) => s.city).filter(Boolean))); // Derived data for region section const filteredRegionData = regionData.filter((r) => !regionFilters.region || r.region === regionFilters.region); if (loading && !summary) { return (
正在加载数据...
); } if (error && !summary) { return (
加载失败
{error}
); } const SUMMARY = summary!; return (
{/* Main Title and Global Descriptions */}

羚牛氢能车辆资产

最后更新: {lastUpdate}
每分钟更新
{loading && (
刷新中...
)}
{/* Theme Switcher */}
{/* Header Summary - Ultra Compact */}
{/* Total Assets */}
资产总数
{SUMMARY.totalAssets.toLocaleString()}
{/* Operating */}
总运营
{SUMMARY.operating.total} 自{SUMMARY.operating.self} 租{SUMMARY.operating.leased}
{/* Inventory */}
总库存
{SUMMARY.inventory.total} 库{SUMMARY.inventory.inStock} 异{SUMMARY.inventory.abnormal}
{/* Pending */}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending' })}>
待交车
{SUMMARY.pendingDelivery}
{/* Dynamics */}
本周动态
上周六-本周五
{SUMMARY.weeklyNew} 新增
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Delivered' })}> {SUMMARY.weeklyDelivered} 交车
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Returned' })}> {SUMMARY.weeklyReturned} 还车
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Replaced' })}> {SUMMARY.weeklyReplaced} 替换
{/* Main Content Area */}
{/* Asset Summary Table with Dimension Switch */}

资产数据实时汇总

点击车型展开品牌型号明细
{/* Desktop View Table */}
{['嘉兴', '广东', '北京', '新疆', '其他'].map((reg) => { const val = processedData.reduce((s, t) => s + (t.inventoryRegions?.[reg] || 0), 0); return ( ); })} {processedData.map((typeGroup) => ( {/* Category Header Row */} toggleAssetType(typeGroup.type)} > {expandedAssetTypes.has(typeGroup.type) ? ( ) : ( <> {['嘉兴', '广东', '北京', '新疆', '其他'].map((reg) => ( ))} )} {expandedAssetTypes.has(typeGroup.type) && typeGroup.models.map((model) => ( toggleModel(model.model)} > {['嘉兴', '广东', '北京', '新疆', '其他'].map((reg) => ( ))} ))} ))}
品牌型号 车辆总资产 库存总数 库存-江浙沪 库存-广东 库存-北京 库存-新疆 库存-其他 待交车 当前在运营 本周交车 本周还车 本周替换
总计 {val > 0 ? ( ) : ''} {processedData.reduce((s, t) => s + t.pending, 0) > 0 ? ( ) : ''} {processedData.reduce((s, t) => s + t.weeklyDelivered, 0) > 0 ? ( ) : ''} {processedData.reduce((s, t) => s + t.weeklyReturned, 0) > 0 ? ( ) : ''} {processedData.reduce((s, t) => s + t.weeklyReplaced, 0) > 0 ? ( ) : ''}
{typeGroup.type}
{typeGroup.type}
小计 {(typeGroup.inventoryRegions?.[reg] || 0) > 0 ? ( ) : ''} {typeGroup.pending > 0 ? ( ) : ''} {typeGroup.weeklyDelivered > 0 ? ( ) : ''} {typeGroup.weeklyReturned > 0 ? ( ) : ''} {typeGroup.weeklyReplaced > 0 ? ( ) : ''}
{typeGroup.type} {expandedModels.has(model.model) ? ( ) : ( )} {model.model} {model.inventory > 0 ? ( ) : model.inventory} {(model.inventoryRegions[reg] || 0) > 0 ? ( ) : ( '' )} {model.pending > 0 ? ( ) : ( '' )} {model.weeklyDelivered > 0 ? ( ) : ( '' )} {model.weeklyReturned > 0 ? ( ) : ( '' )} {model.weeklyReplaced > 0 ? ( ) : ( '' )}
{/* Mobile View Cards for Asset Summary */}
{processedData.map((typeGroup) => (
toggleAssetType(typeGroup.type)} >
{expandedAssetTypes.has(typeGroup.type) ? ( ) : ( )} {typeGroup.type}
资产 {typeGroup.totalAssets} 库存{' '} {typeGroup.totalInventory} 运营{' '} {typeGroup.totalOperating}
{expandedAssetTypes.has(typeGroup.type) && ( {typeGroup.models.map((model) => (
toggleModel(model.model)} >
{expandedModels.has(model.model) ? ( ) : ( )} {model.model}
运营 {model.operating}
{expandedModels.has(model.model) && (
setShowPlateNumbers({ batch: 'All', model: model.model, location: 'All', category: 'Inventory' })} > 总库存 {model.inventory}
setShowPlateNumbers({ batch: 'All', model: model.model, location: 'All', category: 'Pending' }) } > 待交车 {model.pending}
{['嘉兴', '广东', '北京', '新疆', '其他'].map((reg) => (
{reg === '嘉兴' ? '江浙沪' : reg}
{(model.inventoryRegions[reg] || 0) > 0 ? ( ) : (
-
)}
))}
setShowPlateNumbers({ batch: 'All', model: model.model, location: 'All', category: 'Delivered' }) } > 本周已交车 {model.weeklyDelivered}
setShowPlateNumbers({ batch: 'All', model: model.model, location: 'All', category: 'Returned' }) } > 已还车 {model.weeklyReturned}
setShowPlateNumbers({ batch: 'All', model: model.model, location: 'All', category: 'Replaced' }) } > 已替换 {model.weeklyReplaced}
)}
))}
)}
))}
{/* Department Operations Statistics */}

部门运营统计

实时更新部门运营核心指标

{/* Overall Total Summary (Compact) - Moved to Top */}
总资产 {deptData.reduce((s, d) => s + d.totalAssets, 0)}
运营中 {deptData.reduce((acc, d) => acc + d.operatingCount, 0)}
闲置中 {deptData.reduce((acc, d) => acc + d.idleCount, 0)}
平均出勤 {'—'}
{/* Controls Row: Toggles Left, Filter Right */}
{deptViewMode === 'manager' && (
)}
{/* Desktop Table View */}
{deptViewMode === 'manager' && } {deptViewMode === 'department' && ( <> )} {deptViewMode === 'manager' && ( <> )} {deptViewMode === 'department' ? ( deptData.map((dept) => { const isExpanded = expandedDepts.has(dept.department); return ( toggleDept(dept.department)} > {isExpanded && ( )} ); }) ) : ( managerStats.map((m) => { const isManagerExpanded = expandedManagerDetails.has(m.manager); return ( toggleManagerDetails(m.manager)} > {isManagerExpanded && ( )} ); }) )}
{deptViewMode === 'department' ? '部门名称' : '业务员'}所属部门{deptViewMode === 'department' ? '出勤率' : '合计资产'}资产总数 日均里程 运营中 闲置中4.5T 冷链 18T 49T 挂车 其他详情
{dept.department} {'—'} {dept.totalAssets}
{'—'} km
{dept.operatingCount} {dept.idleCount} {isExpanded ? : }
{dept.managers.map(m => { const isManagerExpanded = expandedManagerDetails.has(m.manager); return (
toggleManagerDetails(m.manager)} >
{isManagerExpanded ? : } {m.manager}
{isManagerExpanded && (
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })} >
4.5T
{m.t4_5}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })} >
冷链
{m.t4_5c}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })} >
18T
{m.t18}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })} >
49T
{m.t49}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })} >
挂车
{m.trailer}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })} >
其他
{m.other}
)}
); })}
{isManagerExpanded ? : } {m.manager} {m.department} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, source: 'department' }); }} > {m.total} - - - - - -
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })}> 4.5T {m.t4_5}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })}> 冷链 {m.t4_5c}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })}> 18T {m.t18}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })}> 49T {m.t49}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })}> 挂车 {m.trailer}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })}> 其他 {m.other}
{/* Mobile Card View */}
{deptViewMode === 'department' ? ( deptData.map((dept) => { const isExpanded = expandedDepts.has(dept.department); return (
toggleDept(dept.department)} >

{dept.department}

出勤率: —
资产
{dept.totalAssets}
里程
{'—'}
运营
{dept.operatingCount}
闲置
{dept.idleCount}
{isExpanded ? : }
{isExpanded && (
{dept.managers.map(m => { const isManagerExpanded = expandedManagerDetails.has(m.manager); return (
toggleManagerDetails(m.manager)} >
{isManagerExpanded ? : } {m.manager}
{isManagerExpanded && (
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })} >
4.5T
{m.t4_5}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })} >
冷链
{m.t4_5c}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })} >
18T
{m.t18}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })} >
49T
{m.t49}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })} >
挂车
{m.trailer}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })} >
其他
{m.other}
)}
); })}
)}
); }) ) : ( managerStats.map((m) => { const isManagerExpanded = expandedManagerDetails.has(m.manager); return (
toggleManagerDetails(m.manager)} >
{isManagerExpanded ? : }

{m.manager}

{m.department}
{ e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, source: 'department' }); }} > 资产: {m.total}
{isManagerExpanded && (
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })} >
4.5T
{m.t4_5}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })} >
冷链
{m.t4_5c}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })} >
18T
{m.t18}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })} >
49T
{m.t49}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })} >
挂车
{m.trailer}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })} >
其他
{m.other}
)}
); }) )}
{/* Region - Vehicle - Customer Section */}

区域运营统计

*按区域—车型—客户维度统计

{isRegionFilterOpen && ( <>
setIsRegionFilterOpen(false)} />

区域筛选

setRegionFilters(prev => ({ ...prev, customer: e.target.value }))} />
)}
{uniqueRegions.filter(r => !regionFilters.region || r === regionFilters.region).map((region) => { const regionStats = customerData.filter(s => { const matchRegion = s.region === region; const matchCity = !regionFilters.city || s.city === regionFilters.city; const matchCustomer = !regionFilters.customer || s.customer.toLowerCase().includes(regionFilters.customer.toLowerCase()); return matchRegion && matchCity && matchCustomer; }); const totalAssets = regionStats.reduce((acc, s) => acc + s.total, 0); if (totalAssets === 0) return null; const isExpanded = expandedRegions.has(region); return ( toggleRegion(region)} > {isExpanded && ['4.5T', '18T', '49T'].map(type => { const typeTotal = regionStats.reduce((acc, s) => { if (type === '4.5T') return acc + s.t4_5 + s.t4_5c; if (type === '18T') return acc + s.t18; if (type === '49T') return acc + s.t49; return acc; }, 0); if (typeTotal === 0) return null; return ( ); })} ); })}
区域 / 车型 / 客户 资产总数 运营中 待交车 主要客户
{isExpanded ? : } {region}区域 {totalAssets} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Operating', source: 'asset' }); }} > {Math.floor(totalAssets * 0.8)} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending', source: 'asset' }); }} > {Math.floor(totalAssets * 0.05)} {regionStats.slice(0, 2).map(s => s.customer).join(', ')}
{type} 车型
{typeTotal} setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Operating', source: 'asset' })} > {Math.floor(typeTotal * 0.8)} setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Pending', source: 'asset' })} > {Math.floor(typeTotal * 0.05)} {regionStats.filter(s => { if (type === '4.5T') return (s.t4_5 + s.t4_5c) > 0; if (type === '18T') return s.t18 > 0; if (type === '49T') return s.t49 > 0; return false; }).map(s => s.customer).join(', ')}
{/* Mobile View (Region) */}
{uniqueRegions.filter(r => !regionFilters.region || r === regionFilters.region).map((region) => { const regionStats = customerData.filter(s => { const matchRegion = s.region === region; const matchCity = !regionFilters.city || s.city === regionFilters.city; const matchCustomer = !regionFilters.customer || s.customer.toLowerCase().includes(regionFilters.customer.toLowerCase()); return matchRegion && matchCity && matchCustomer; }); const totalAssets = regionStats.reduce((acc, s) => acc + s.total, 0); if (totalAssets === 0) return null; const isExpanded = expandedRegions.has(region); return (
toggleRegion(region)} >
{isExpanded ? : } {region}区域
资产: {totalAssets}
{isExpanded && ( <>
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Operating', source: 'asset' })} >
运营中
{Math.floor(totalAssets * 0.8)}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending', source: 'asset' })} >
待交车
{Math.floor(totalAssets * 0.05)}
{['4.5T', '18T', '49T'].map(type => { const typeTotal = regionStats.reduce((acc, s) => { if (type === '4.5T') return acc + s.t4_5 + s.t4_5c; if (type === '18T') return acc + s.t18; if (type === '49T') return acc + s.t49; return acc; }, 0); if (typeTotal === 0) return null; return (
{type} 车型
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Operating', source: 'asset' })} > 运:{Math.floor(typeTotal * 0.8)} setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Pending', source: 'asset' })} > 待:{Math.floor(typeTotal * 0.05)}
); })}
)}
); })}
{/* Customer Operations Statistics Section */}

客户运营统计

*按客户维度统计资产分布

{isCustomerFilterOpen && ( <> {/* Backdrop for closing */}
setIsCustomerFilterOpen(false)} /> {/* Popover Content */}

数据筛选

setCustomerFilters(prev => ({ ...prev, customer: e.target.value }))} />
setCustomerFilters(prev => ({ ...prev, manager: e.target.value }))} />
)}
{/* Desktop Table View (Customer) */}
{filteredCustomerStats.map((cust) => { const isExpanded = expandedCustomers.has(cust.customer); return ( toggleCustomer(cust.customer)} > {isExpanded && ( )} ); })}
客户名称 所在区域 关联业务员 4.5T 4.5T冷链 18T 49T 挂车 其他 合计
{isExpanded ? : } {cust.customer} {cust.region} {cust.manager} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' }); }}>{cust.t4_5} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' }); }}>{cust.t4_5c} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '18T', source: 'customer' }); }}>{cust.t18} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '49T', source: 'customer' }); }}>{cust.t49} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' }); }}>{cust.trailer} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' }); }}>{cust.other} { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, source: 'customer' }); }}>{cust.total}
客户详情
{cust.customer}
主责业务员: {cust.manager}
主要车型
{cust.t49 > cust.t18 ? '49T 重卡' : (cust.t18 > cust.t4_5c ? '18T 货车' : '4.5T 轻卡')}
运营状态
正常运营中
资产占比
{((cust.total / deptData.reduce((s, d) => s + d.totalAssets, 0)) * 100).toFixed(1)}%
{/* Mobile Card View (Customer) */}
{filteredCustomerStats.map((cust) => { const isExpanded = expandedCustomers.has(cust.customer); return (
toggleCustomer(cust.customer)} >
{isExpanded ? : }
{cust.customer} {cust.region}区域
合计: {cust.total}
{isExpanded && (
{/* Details Cards for Mobile */}
客户详情
{cust.customer}
主责: {cust.manager}
主要车型
{cust.t49 > cust.t18 ? '49T 重卡' : (cust.t18 > cust.t4_5c ? '18T 货车' : '4.5T 轻卡')}
运营状态
正常运营中
资产占比
{((cust.total / deptData.reduce((s, d) => s + d.totalAssets, 0)) * 100).toFixed(1)}%
车型分布
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' })} >
4.5T
{cust.t4_5}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' })} >
冷链
{cust.t4_5c}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '18T', source: 'customer' })} >
18T
{cust.t18}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '49T', source: 'customer' })} >
49T
{cust.t49}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' })} >
挂车
{cust.trailer}
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' })} >
其他
{cust.other}
)}
); })}
{/* Vehicle Detail Modal */} {showPlateNumbers && (

{showPlateNumbers.manager ? `${showPlateNumbers.manager} 的${showPlateNumbers.type || ''}车辆` : showPlateNumbers.customer ? `${showPlateNumbers.customer} 的${showPlateNumbers.type || ''}车辆` : showPlateNumbers.batch === 'All' ? '全量批次' : `${showPlateNumbers.batch} 批次`} - 运营明细

{showPlateNumbers.model === 'All' ? '全量型号' : showPlateNumbers.model} | {showPlateNumbers.category === 'Pending' ? '待交车' : showPlateNumbers.category === 'Delivered' ? '本周已交车' : showPlateNumbers.category === 'Returned' ? '已还车' : showPlateNumbers.category === 'Replaced' ? '已替换' : showPlateNumbers.category === 'Inventory' ? `${showPlateNumbers.location}库存` : showPlateNumbers.category === 'Operating' ? '正在运营' : '全部状态'}

{modalLoading ? (
) : modalWeeklyDetail.length > 0 ? (
{modalWeeklyDetail.map((v, i) => ( ))}
车牌 客户名称 日期
{v.plate_number} {v.customer_name || '—'} {v.handover_date || '—'}
) : (
{showPlateNumbers.source === 'customer' ? ( <> ) : ( <> {showPlateNumbers.source !== 'asset' && ( )} )} {modalVehicles.map((v, idx) => ( {showPlateNumbers.source === 'customer' ? ( <> ) : ( <> {showPlateNumbers.source !== 'asset' && ( )} )} ))} {modalVehicles.length === 0 && ( )}
业务部门 业务负责人 品牌 车型 资产归属 客户名称 车牌 状态 提车时间 合同到期时间 运营区域 离到期 签约公司车牌客户名称品牌 车型 所在地
{'—'} {v.departmentName || '—'} {v.customerManager || '—'} {v.brandLabel || '—'} {v.type} {v.subjectOrg || '—'} {v.customerName || '—'} {v.plateNumber} {v.status === 'Operating' ? '在租' : v.status === 'Inventory' ? '库存' : '异常'} {'—'} {'—'} {v.location} {'—'} {v.orgName || '—'}{v.plateNumber}{v.customerName || '—'}{v.brandLabel || '—'} {v.type} {v.location}
暂无符合条件的车辆数据
)}
共计 {modalWeeklyDetail.length > 0 ? modalWeeklyDetail.length : modalVehicles.length} 台车辆
)}
{/* Footer / Navigation */}
); }