fix: replace 3 operations sections with exact prototype code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-03-28 15:09:19 +08:00
parent df1ab64c97
commit 752208da02

View File

@@ -33,6 +33,8 @@ export default function App() {
customer?: string; customer?: string;
isColdChain?: boolean; isColdChain?: boolean;
isTrailer?: boolean; isTrailer?: boolean;
type?: string;
source?: string;
} | null>(null); } | null>(null);
// Data state // Data state
@@ -128,8 +130,30 @@ export default function App() {
if (cat === 'Operating') params.category = 'Operating'; if (cat === 'Operating') params.category = 'Operating';
if (showPlateNumbers.manager) params.manager = showPlateNumbers.manager; if (showPlateNumbers.manager) params.manager = showPlateNumbers.manager;
if (showPlateNumbers.customer) params.customer = showPlateNumbers.customer; if (showPlateNumbers.customer) params.customer = showPlateNumbers.customer;
if (!showPlateNumbers.type) {
if (showPlateNumbers.isColdChain !== undefined) params.isColdChain = String(showPlateNumbers.isColdChain); if (showPlateNumbers.isColdChain !== undefined) params.isColdChain = String(showPlateNumbers.isColdChain);
if (showPlateNumbers.isTrailer !== undefined) params.isTrailer = String(showPlateNumbers.isTrailer); 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) fetchVehicleList(params)
.then(setModalVehicles) .then(setModalVehicles)
.catch(() => setModalVehicles([])) .catch(() => setModalVehicles([]))
@@ -860,8 +884,9 @@ export default function App() {
</div> </div>
</div> </div>
{/* Department Operations Statistics */} {/* Department Operations Statistics */}
<section className="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden mb-6"> <section className="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden mb-6">
<div className="p-3 sm:p-4 border-b border-gray-50 flex items-center justify-between gap-4"> <div className="p-3 sm:p-4 border-b border-gray-50 flex items-center justify-between gap-4">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-1.5 h-6 bg-blue-600 rounded-full"></div> <div className="w-1.5 h-6 bg-blue-600 rounded-full"></div>
@@ -873,7 +898,7 @@ export default function App() {
</div> </div>
<div className="p-0 sm:p-2 bg-gray-50/30"> <div className="p-0 sm:p-2 bg-gray-50/30">
{/* Overall Total Summary (Compact) */} {/* Overall Total Summary (Compact) - Moved to Top */}
<div className="m-2 bg-slate-800 rounded-xl p-3 text-white shadow-lg"> <div className="m-2 bg-slate-800 rounded-xl p-3 text-white shadow-lg">
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4"> <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
<div className="flex flex-col"> <div className="flex flex-col">
@@ -894,7 +919,9 @@ export default function App() {
</div> </div>
<div className="flex flex-col"> <div className="flex flex-col">
<span className="text-[9px] opacity-50 uppercase font-bold tracking-widest mb-0.5 text-blue-400"></span> <span className="text-[9px] opacity-50 uppercase font-bold tracking-widest mb-0.5 text-blue-400"></span>
<span className="text-xl font-black text-blue-400"></span> <span className="text-xl font-black text-blue-400">
{'—'}
</span>
</div> </div>
</div> </div>
</div> </div>
@@ -980,11 +1007,20 @@ export default function App() {
<td className="p-2 border-r border-gray-100 font-bold text-gray-800"> <td className="p-2 border-r border-gray-100 font-bold text-gray-800">
{dept.department} {dept.department}
</td> </td>
<td className="p-2 border-r border-gray-100 text-center"><span className="bg-blue-50 text-blue-600 text-[10px] font-bold px-2 py-0.5 rounded-full"></span></td> <td className="p-2 border-r border-gray-100 text-center">
<span className="bg-blue-50 text-blue-600 text-[10px] font-bold px-2 py-0.5 rounded-full">
{'—'}
</span>
</td>
<td className="p-2 border-r border-gray-100 text-center font-black text-gray-800 text-sm"> <td className="p-2 border-r border-gray-100 text-center font-black text-gray-800 text-sm">
{dept.totalAssets} {dept.totalAssets}
</td> </td>
<td className="p-2 border-r border-gray-100 text-center"><div className="flex items-baseline justify-center gap-1"><span className="font-black text-gray-400 text-sm"></span></div></td> <td className="p-2 border-r border-gray-100 text-center">
<div className="flex items-baseline justify-center gap-1">
<span className="font-black text-gray-800 text-sm">{'—'}</span>
<span className="text-[9px] text-gray-400 font-bold">km</span>
</div>
</td>
<td className="p-2 border-r border-gray-100 text-center font-black text-green-500 text-sm"> <td className="p-2 border-r border-gray-100 text-center font-black text-green-500 text-sm">
{dept.operatingCount} {dept.operatingCount}
</td> </td>
@@ -1014,7 +1050,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating', source: 'department' });
}} }}
className="text-[10px] font-bold text-blue-600 bg-blue-50 px-2 py-0.5 rounded hover:bg-blue-100 transition-colors" className="text-[10px] font-bold text-blue-600 bg-blue-50 px-2 py-0.5 rounded hover:bg-blue-100 transition-colors"
> >
@@ -1027,42 +1063,42 @@ export default function App() {
<div className="grid grid-cols-3 gap-1 mt-2"> <div className="grid grid-cols-3 gap-1 mt-2">
<div <div
className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100" className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T普货' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">4.5T</div> <div className="text-[8px] text-gray-400 uppercase">4.5T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t4_5}</div> <div className="text-[10px] font-bold text-gray-600">{m.t4_5}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100" className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T冷链' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.t4_5c}</div> <div className="text-[10px] font-bold text-gray-600">{m.t4_5c}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100" className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '18T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">18T</div> <div className="text-[8px] text-gray-400 uppercase">18T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t18}</div> <div className="text-[10px] font-bold text-gray-600">{m.t18}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100" className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '49T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">49T</div> <div className="text-[8px] text-gray-400 uppercase">49T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t49}</div> <div className="text-[10px] font-bold text-gray-600">{m.t49}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100" className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, isTrailer: true })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.trailer}</div> <div className="text-[10px] font-bold text-gray-600">{m.trailer}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100" className="text-center bg-white p-1 rounded cursor-pointer hover:bg-blue-50 transition-colors border border-gray-100"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '其他' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.other}</div> <div className="text-[10px] font-bold text-gray-600">{m.other}</div>
@@ -1098,7 +1134,7 @@ export default function App() {
className="p-2 border-r border-gray-100 text-center font-black text-blue-600 text-sm cursor-pointer hover:bg-blue-50" className="p-2 border-r border-gray-100 text-center font-black text-blue-600 text-sm cursor-pointer hover:bg-blue-50"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, source: 'department' });
}} }}
> >
{m.total} {m.total}
@@ -1113,7 +1149,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating', source: 'department' });
}} }}
className="text-blue-500 hover:text-blue-700 transition-colors" className="text-blue-500 hover:text-blue-700 transition-colors"
> >
@@ -1125,27 +1161,27 @@ export default function App() {
<tr className="bg-gray-50/50 border-b border-gray-100"> <tr className="bg-gray-50/50 border-b border-gray-100">
<td colSpan={10} className="p-0"> <td colSpan={10} className="p-0">
<div className="grid grid-cols-6 text-[10px] bg-white/50"> <div className="grid grid-cols-6 text-[10px] bg-white/50">
<div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T普货' })}> <div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })}>
<span className="text-gray-400 uppercase mb-1">4.5T</span> <span className="text-gray-400 uppercase mb-1">4.5T</span>
<span className="font-bold text-gray-600">{m.t4_5}</span> <span className="font-bold text-gray-600">{m.t4_5}</span>
</div> </div>
<div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T冷链' })}> <div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })}>
<span className="text-gray-400 uppercase mb-1"></span> <span className="text-gray-400 uppercase mb-1"></span>
<span className="font-bold text-gray-600">{m.t4_5c}</span> <span className="font-bold text-gray-600">{m.t4_5c}</span>
</div> </div>
<div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '18T' })}> <div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })}>
<span className="text-gray-400 uppercase mb-1">18T</span> <span className="text-gray-400 uppercase mb-1">18T</span>
<span className="font-bold text-gray-600">{m.t18}</span> <span className="font-bold text-gray-600">{m.t18}</span>
</div> </div>
<div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '49T' })}> <div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })}>
<span className="text-gray-400 uppercase mb-1">49T</span> <span className="text-gray-400 uppercase mb-1">49T</span>
<span className="font-bold text-gray-600">{m.t49}</span> <span className="font-bold text-gray-600">{m.t49}</span>
</div> </div>
<div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, isTrailer: true })}> <div className="p-2 border-r border-gray-100 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })}>
<span className="text-gray-400 uppercase mb-1"></span> <span className="text-gray-400 uppercase mb-1"></span>
<span className="font-bold text-gray-600">{m.trailer}</span> <span className="font-bold text-gray-600">{m.trailer}</span>
</div> </div>
<div className="p-2 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '其他' })}> <div className="p-2 flex flex-col items-center cursor-pointer hover:bg-blue-50" onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })}>
<span className="text-gray-400 uppercase mb-1"></span> <span className="text-gray-400 uppercase mb-1"></span>
<span className="font-bold text-gray-600">{m.other}</span> <span className="font-bold text-gray-600">{m.other}</span>
</div> </div>
@@ -1185,7 +1221,7 @@ export default function App() {
</div> </div>
<div className="text-center"> <div className="text-center">
<div className="text-[8px] text-gray-400 uppercase font-bold mb-0.5"></div> <div className="text-[8px] text-gray-400 uppercase font-bold mb-0.5"></div>
<div className="text-xs font-black text-gray-400"></div> <div className="text-xs font-black text-gray-800">{'—'}</div>
</div> </div>
<div className="text-center"> <div className="text-center">
<div className="text-[8px] text-green-500 uppercase font-bold mb-0.5"></div> <div className="text-[8px] text-green-500 uppercase font-bold mb-0.5"></div>
@@ -1217,7 +1253,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, source: 'department' });
}} }}
className="text-[10px] font-bold text-blue-600 bg-blue-50 px-2 py-0.5 rounded" className="text-[10px] font-bold text-blue-600 bg-blue-50 px-2 py-0.5 rounded"
> >
@@ -1229,42 +1265,42 @@ export default function App() {
<div className="p-2 border-t border-gray-50 bg-gray-50/30 grid grid-cols-3 gap-1"> <div className="p-2 border-t border-gray-50 bg-gray-50/30 grid grid-cols-3 gap-1">
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T普货' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">4.5T</div> <div className="text-[8px] text-gray-400 uppercase">4.5T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t4_5}</div> <div className="text-[10px] font-bold text-gray-600">{m.t4_5}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T冷链' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.t4_5c}</div> <div className="text-[10px] font-bold text-gray-600">{m.t4_5c}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '18T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">18T</div> <div className="text-[8px] text-gray-400 uppercase">18T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t18}</div> <div className="text-[10px] font-bold text-gray-600">{m.t18}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '49T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">49T</div> <div className="text-[8px] text-gray-400 uppercase">49T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t49}</div> <div className="text-[10px] font-bold text-gray-600">{m.t49}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, isTrailer: true })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.trailer}</div> <div className="text-[10px] font-bold text-gray-600">{m.trailer}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '其他' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.other}</div> <div className="text-[10px] font-bold text-gray-600">{m.other}</div>
@@ -1297,7 +1333,7 @@ export default function App() {
className="text-[11px] font-bold text-blue-600 whitespace-nowrap" className="text-[11px] font-bold text-blue-600 whitespace-nowrap"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, source: 'department' });
}} }}
> >
: {m.total} : {m.total}
@@ -1308,7 +1344,7 @@ export default function App() {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, category: 'Operating', source: 'department' });
}} }}
className="text-blue-500 p-1 hover:bg-blue-50 rounded transition-colors flex-shrink-0" className="text-blue-500 p-1 hover:bg-blue-50 rounded transition-colors flex-shrink-0"
> >
@@ -1320,42 +1356,42 @@ export default function App() {
<div className="p-2 border-t border-gray-50 bg-gray-50/30 grid grid-cols-3 gap-1"> <div className="p-2 border-t border-gray-50 bg-gray-50/30 grid grid-cols-3 gap-1">
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T普货' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: false, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">4.5T</div> <div className="text-[8px] text-gray-400 uppercase">4.5T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t4_5}</div> <div className="text-[10px] font-bold text-gray-600">{m.t4_5}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '4.5T冷链' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '4.5T', isColdChain: true, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.t4_5c}</div> <div className="text-[10px] font-bold text-gray-600">{m.t4_5c}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '18T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '18T', source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">18T</div> <div className="text-[8px] text-gray-400 uppercase">18T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t18}</div> <div className="text-[10px] font-bold text-gray-600">{m.t18}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '49T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '49T', source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase">49T</div> <div className="text-[8px] text-gray-400 uppercase">49T</div>
<div className="text-[10px] font-bold text-gray-600">{m.t49}</div> <div className="text-[10px] font-bold text-gray-600">{m.t49}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, isTrailer: true })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: true, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.trailer}</div> <div className="text-[10px] font-bold text-gray-600">{m.trailer}</div>
</div> </div>
<div <div
className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer" className="text-center bg-white p-1 rounded border border-gray-100 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, vehicleType: '其他' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', manager: m.manager, type: '其他车型', isTrailer: false, source: 'department' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{m.other}</div> <div className="text-[10px] font-bold text-gray-600">{m.other}</div>
@@ -1486,70 +1522,88 @@ export default function App() {
</tr> </tr>
</thead> </thead>
<tbody className="text-xs"> <tbody className="text-xs">
{filteredRegionData.map((r) => { {uniqueRegions.filter(r => !regionFilters.region || r === regionFilters.region).map((region) => {
if (r.totalAssets === 0) return null; const regionStats = customerData.filter(s => {
const isExpanded = expandedRegions.has(r.region); 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 ( return (
<React.Fragment key={r.region}> <React.Fragment key={region}>
<tr <tr
className={`border-b border-slate-100 cursor-pointer transition-colors ${isExpanded ? 'bg-slate-50' : 'bg-white hover:bg-slate-50/50'}`} className={`border-b border-slate-100 cursor-pointer transition-colors ${isExpanded ? 'bg-slate-50' : 'bg-white hover:bg-slate-50/50'}`}
onClick={() => toggleRegion(r.region)} onClick={() => toggleRegion(region)}
> >
<td className="p-2 font-bold text-slate-700 flex items-center gap-2"> <td className="p-2 font-bold text-slate-700 flex items-center gap-2">
{isExpanded ? <ChevronDown size={14} className="text-slate-400" /> : <ChevronRight size={14} className="text-slate-400" />} {isExpanded ? <ChevronDown size={14} className="text-slate-400" /> : <ChevronRight size={14} className="text-slate-400" />}
<Truck size={14} className="text-slate-400" /> <Truck size={14} className="text-slate-400" />
{r.region} {region}
</td> </td>
<td className="p-2 text-center font-bold text-slate-600">{r.totalAssets}</td> <td className="p-2 text-center font-bold text-slate-600">{totalAssets}</td>
<td <td
className="p-2 text-center text-green-600 font-bold cursor-pointer hover:bg-green-50" className="p-2 text-center text-green-600 font-bold cursor-pointer hover:bg-green-50"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Operating' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Operating', source: 'asset' });
}} }}
> >
{r.operatingCount} {Math.floor(totalAssets * 0.8)}
</td> </td>
<td <td
className="p-2 text-center text-orange-600 font-bold cursor-pointer hover:bg-orange-50" className="p-2 text-center text-orange-600 font-bold cursor-pointer hover:bg-orange-50"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending' }); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending', source: 'asset' });
}} }}
> >
{r.inventoryCount} {Math.floor(totalAssets * 0.05)}
</td> </td>
<td className="p-2 text-center text-slate-500 font-medium"> <td className="p-2 text-center text-slate-500 font-medium">
{r.customers.slice(0, 2).join(', ')} {regionStats.slice(0, 2).map(s => s.customer).join(', ')}
</td> </td>
</tr> </tr>
{isExpanded && r.typeBreakdown.map(tb => { {isExpanded && ['4.5T', '18T', '49T'].map(type => {
if (tb.total === 0) return null; const typeTotal = regionStats.reduce((acc, s) => {
const vehicleType = tb.type === '4.5T' ? '4.5T普货' : tb.type; 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 ( return (
<React.Fragment key={tb.type}> <React.Fragment key={type}>
<tr className="border-b border-gray-50 hover:bg-gray-50"> <tr className="border-b border-gray-50 hover:bg-gray-50">
<td className="p-2 pl-8 text-gray-500 flex items-center gap-2"> <td className="p-2 pl-8 text-gray-500 flex items-center gap-2">
<div className="w-1 h-1 bg-slate-300 rounded-full"></div> <div className="w-1 h-1 bg-slate-300 rounded-full"></div>
{tb.type} {type}
</td> </td>
<td className="p-2 text-center text-gray-600">{tb.total}</td> <td className="p-2 text-center text-gray-600">{typeTotal}</td>
<td <td
className="p-2 text-center text-green-600 cursor-pointer hover:bg-green-50" className="p-2 text-center text-green-600 cursor-pointer hover:bg-green-50"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', vehicleType, category: 'Operating' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Operating', source: 'asset' })}
> >
{tb.operating} {Math.floor(typeTotal * 0.8)}
</td> </td>
<td <td
className="p-2 text-center text-orange-600 cursor-pointer hover:bg-orange-50" className="p-2 text-center text-orange-600 cursor-pointer hover:bg-orange-50"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', vehicleType, category: 'Pending' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Pending', source: 'asset' })}
> >
{tb.inventory} {Math.floor(typeTotal * 0.05)}
</td> </td>
<td className="p-2 text-center text-gray-400 italic"> <td className="p-2 text-center text-gray-400 italic">
{tb.customers.join(', ')} {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(', ')}
</td> </td>
</tr> </tr>
</React.Fragment> </React.Fragment>
@@ -1564,60 +1618,73 @@ export default function App() {
{/* Mobile View (Region) */} {/* Mobile View (Region) */}
<div className="lg:hidden p-2 space-y-3"> <div className="lg:hidden p-2 space-y-3">
{filteredRegionData.map((r) => { {uniqueRegions.filter(r => !regionFilters.region || r === regionFilters.region).map((region) => {
if (r.totalAssets === 0) return null; const regionStats = customerData.filter(s => {
const isExpanded = expandedRegions.has(r.region); 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 ( return (
<div key={r.region} className="bg-slate-50/50 rounded-xl border border-slate-100 overflow-hidden"> <div key={region} className="bg-slate-50/50 rounded-xl border border-slate-100 overflow-hidden">
<div <div
className="bg-white p-3 flex justify-between items-center cursor-pointer" className="bg-white p-3 flex justify-between items-center cursor-pointer"
onClick={() => toggleRegion(r.region)} onClick={() => toggleRegion(region)}
> >
<div className="flex items-center gap-2 font-bold text-slate-700"> <div className="flex items-center gap-2 font-bold text-slate-700">
{isExpanded ? <ChevronDown size={14} className="text-slate-400" /> : <ChevronRight size={14} className="text-slate-400" />} {isExpanded ? <ChevronDown size={14} className="text-slate-400" /> : <ChevronRight size={14} className="text-slate-400" />}
<Truck size={14} className="text-slate-400" /> <Truck size={14} className="text-slate-400" />
{r.region} {region}
</div> </div>
<div className="text-xs font-bold text-slate-500">: {r.totalAssets}</div> <div className="text-xs font-bold text-slate-500">: {totalAssets}</div>
</div> </div>
{isExpanded && ( {isExpanded && (
<> <>
<div className="p-2 grid grid-cols-2 gap-2 text-center border-t border-slate-100"> <div className="p-2 grid grid-cols-2 gap-2 text-center border-t border-slate-100">
<div <div
className="bg-white p-2 rounded border border-slate-100 cursor-pointer active:bg-green-50" className="bg-white p-2 rounded border border-slate-100 cursor-pointer active:bg-green-50"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Operating' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Operating', source: 'asset' })}
> >
<div className="text-[9px] text-gray-400 uppercase"></div> <div className="text-[9px] text-gray-400 uppercase"></div>
<div className="text-xs font-bold text-green-600">{r.operatingCount}</div> <div className="text-xs font-bold text-green-600">{Math.floor(totalAssets * 0.8)}</div>
</div> </div>
<div <div
className="bg-white p-2 rounded border border-slate-100 cursor-pointer active:bg-orange-50" className="bg-white p-2 rounded border border-slate-100 cursor-pointer active:bg-orange-50"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', category: 'Pending', source: 'asset' })}
> >
<div className="text-[9px] text-gray-400 uppercase"></div> <div className="text-[9px] text-gray-400 uppercase"></div>
<div className="text-xs font-bold text-orange-600">{r.inventoryCount}</div> <div className="text-xs font-bold text-orange-600">{Math.floor(totalAssets * 0.05)}</div>
</div> </div>
</div> </div>
<div className="px-2 pb-2 space-y-1"> <div className="px-2 pb-2 space-y-1">
{r.typeBreakdown.map(tb => { {['4.5T', '18T', '49T'].map(type => {
if (tb.total === 0) return null; const typeTotal = regionStats.reduce((acc, s) => {
const vehicleType = tb.type === '4.5T' ? '4.5T普货' : tb.type; 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 ( return (
<div key={tb.type} className="flex justify-between items-center text-[10px] bg-white/80 px-2 py-1.5 rounded border border-slate-50"> <div key={type} className="flex justify-between items-center text-[10px] bg-white/80 px-2 py-1.5 rounded border border-slate-50">
<span className="text-gray-500">{tb.type} </span> <span className="text-gray-500">{type} </span>
<div className="flex gap-3"> <div className="flex gap-3">
<span <span
className="font-bold text-green-600 cursor-pointer" className="font-bold text-green-600 cursor-pointer"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', vehicleType, category: 'Operating' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Operating', source: 'asset' })}
> >
:{tb.operating} :{Math.floor(typeTotal * 0.8)}
</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: 'All', vehicleType, category: 'Pending' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', type, category: 'Pending', source: 'asset' })}
> >
:{tb.inventory} :{Math.floor(typeTotal * 0.05)}
</span> </span>
</div> </div>
</div> </div>
@@ -1804,17 +1871,17 @@ export default function App() {
<span className="bg-gray-100 px-2 py-0.5 rounded text-[10px] font-medium">{cust.region}</span> <span className="bg-gray-100 px-2 py-0.5 rounded text-[10px] font-medium">{cust.region}</span>
</td> </td>
<td className="p-2 border-r border-gray-100 text-gray-600 text-center">{cust.manager}</td> <td className="p-2 border-r border-gray-100 text-gray-600 text-center">{cust.manager}</td>
<td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '4.5T普货' }); }}>{cust.t4_5}</td> <td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' }); }}>{cust.t4_5}</td>
<td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '4.5T冷链' }); }}>{cust.t4_5c}</td> <td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' }); }}>{cust.t4_5c}</td>
<td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '18T' }); }}>{cust.t18}</td> <td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '18T', source: 'customer' }); }}>{cust.t18}</td>
<td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '49T' }); }}>{cust.t49}</td> <td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '49T', source: 'customer' }); }}>{cust.t49}</td>
<td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, isTrailer: true }); }}>{cust.trailer}</td> <td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' }); }}>{cust.trailer}</td>
<td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '其他' }); }}>{cust.other}</td> <td className="p-2 border-r border-gray-100 text-center text-gray-500 cursor-pointer hover:bg-emerald-50 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' }); }}>{cust.other}</td>
<td className="p-2 text-center font-bold bg-emerald-50 text-emerald-800 cursor-pointer hover:bg-emerald-100 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer }); }}>{cust.total}</td> <td className="p-2 text-center font-bold bg-emerald-50 text-emerald-800 cursor-pointer hover:bg-emerald-100 transition-colors" onClick={(e) => { e.stopPropagation(); setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, source: 'customer' }); }}>{cust.total}</td>
</tr> </tr>
{isExpanded && ( {isExpanded && (
<tr className="bg-gray-50/30"> <tr className="bg-gray-50/30">
<td colSpan={10} className="p-2"> <td colSpan={9} className="p-2">
<div className="grid grid-cols-4 gap-2"> <div className="grid grid-cols-4 gap-2">
<div className="bg-white p-2 rounded border border-gray-100 shadow-sm"> <div className="bg-white p-2 rounded border border-gray-100 shadow-sm">
<div className="text-[10px] text-gray-400 uppercase mb-1"></div> <div className="text-[10px] text-gray-400 uppercase mb-1"></div>
@@ -1834,7 +1901,7 @@ export default function App() {
<div className="bg-white p-2 rounded border border-gray-100 shadow-sm"> <div className="bg-white p-2 rounded border border-gray-100 shadow-sm">
<div className="text-[10px] text-gray-400 uppercase mb-1"></div> <div className="text-[10px] text-gray-400 uppercase mb-1"></div>
<div className="text-sm font-bold text-gray-700"> <div className="text-sm font-bold text-gray-700">
{((cust.total / (customerData.reduce((s, c) => s + c.total, 0) || 1)) * 100).toFixed(1)}% {((cust.total / deptData.reduce((s, d) => s + d.totalAssets, 0)) * 100).toFixed(1)}%
</div> </div>
</div> </div>
</div> </div>
@@ -1894,7 +1961,7 @@ export default function App() {
<div className="bg-gray-50 p-2 rounded border border-gray-100"> <div className="bg-gray-50 p-2 rounded border border-gray-100">
<div className="text-[8px] text-gray-400 uppercase mb-1"></div> <div className="text-[8px] text-gray-400 uppercase mb-1"></div>
<div className="text-xs font-bold text-gray-700"> <div className="text-xs font-bold text-gray-700">
{((cust.total / (customerData.reduce((s, c) => s + c.total, 0) || 1)) * 100).toFixed(1)}% {((cust.total / deptData.reduce((s, d) => s + d.totalAssets, 0)) * 100).toFixed(1)}%
</div> </div>
</div> </div>
</div> </div>
@@ -1904,42 +1971,42 @@ export default function App() {
<div className="grid grid-cols-3 gap-2"> <div className="grid grid-cols-3 gap-2">
<div <div
className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors" className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '4.5T普货' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' })}
> >
<div className="text-[8px] text-gray-400 uppercase">4.5T</div> <div className="text-[8px] text-gray-400 uppercase">4.5T</div>
<div className="text-[10px] font-bold text-gray-600">{cust.t4_5}</div> <div className="text-[10px] font-bold text-gray-600">{cust.t4_5}</div>
</div> </div>
<div <div
className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors" className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '4.5T冷链' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '4.5T', source: 'customer' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{cust.t4_5c}</div> <div className="text-[10px] font-bold text-gray-600">{cust.t4_5c}</div>
</div> </div>
<div <div
className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors" className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '18T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '18T', source: 'customer' })}
> >
<div className="text-[8px] text-gray-400 uppercase">18T</div> <div className="text-[8px] text-gray-400 uppercase">18T</div>
<div className="text-[10px] font-bold text-gray-600">{cust.t18}</div> <div className="text-[10px] font-bold text-gray-600">{cust.t18}</div>
</div> </div>
<div <div
className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors" className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '49T' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '49T', source: 'customer' })}
> >
<div className="text-[8px] text-gray-400 uppercase">49T</div> <div className="text-[8px] text-gray-400 uppercase">49T</div>
<div className="text-[10px] font-bold text-gray-600">{cust.t49}</div> <div className="text-[10px] font-bold text-gray-600">{cust.t49}</div>
</div> </div>
<div <div
className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors" className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, isTrailer: true })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{cust.trailer}</div> <div className="text-[10px] font-bold text-gray-600">{cust.trailer}</div>
</div> </div>
<div <div
className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors" className="text-center bg-gray-50 p-1 rounded cursor-pointer hover:bg-emerald-50 transition-colors"
onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, vehicleType: '其他' })} onClick={() => setShowPlateNumbers({ batch: 'All', model: 'All', location: 'All', customer: cust.customer, type: '其他车型', source: 'customer' })}
> >
<div className="text-[8px] text-gray-400 uppercase"></div> <div className="text-[8px] text-gray-400 uppercase"></div>
<div className="text-[10px] font-bold text-gray-600">{cust.other}</div> <div className="text-[10px] font-bold text-gray-600">{cust.other}</div>
@@ -1955,6 +2022,7 @@ export default function App() {
</div> </div>
</section> </section>
{/* Plate Number Modal */} {/* Plate Number Modal */}
<AnimatePresence> <AnimatePresence>
{showPlateNumbers && ( {showPlateNumbers && (