|
|
|
|
@@ -446,7 +446,7 @@ const BatchMultiSelect = ({
|
|
|
|
|
export default function MonitoringView() {
|
|
|
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
|
|
|
const [filterDept, setFilterDept] = useState('All');
|
|
|
|
|
const [sortBy, setSortBy] = useState<'today' | 'total'>('today');
|
|
|
|
|
const [sortBy, setSortBy] = useState<'today' | 'total' | 'statisticTime'>('today');
|
|
|
|
|
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
|
|
|
|
|
const [isFilterOpen, setIsFilterOpen] = useState(false);
|
|
|
|
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
|
|
|
@@ -786,7 +786,7 @@ export default function MonitoringView() {
|
|
|
|
|
<span className="text-slate-700">|</span>
|
|
|
|
|
<span className="text-slate-500">车辆 <span className="text-white font-black">{fullscreenStats.vehicleCount}</span> 台</span>
|
|
|
|
|
<span className="text-slate-700">|</span>
|
|
|
|
|
<span className="text-slate-500">均 <span className="text-white font-black">{(fullscreenStats.vehicleCount > 0 ? (sortBy === 'today' ? fullscreenStats.totalToday : fullscreenStats.totalAll) / fullscreenStats.vehicleCount : 0).toFixed(0)}</span> <span className="text-blue-400">km</span></span>
|
|
|
|
|
<span className="text-slate-500">均 <span className="text-white font-black">{(fullscreenStats.vehicleCount > 0 ? (sortBy === 'total' ? fullscreenStats.totalAll : fullscreenStats.totalToday) / fullscreenStats.vehicleCount : 0).toFixed(0)}</span> <span className="text-blue-400">km</span></span>
|
|
|
|
|
<span className="text-slate-700">|</span>
|
|
|
|
|
<span className="text-slate-500">
|
|
|
|
|
来源 <span className="text-white font-black">
|
|
|
|
|
@@ -1047,16 +1047,21 @@ export default function MonitoringView() {
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={handleManualRefresh}
|
|
|
|
|
disabled={manualRefreshing}
|
|
|
|
|
className="flex h-7 items-center gap-1 rounded-lg border border-blue-100 bg-blue-50 px-2 text-[9px] font-bold text-blue-600 disabled:cursor-wait disabled:opacity-60"
|
|
|
|
|
title="仅刷新当前筛选结果"
|
|
|
|
|
className="flex h-7 items-center gap-1 whitespace-nowrap rounded-lg border border-blue-100 bg-blue-50 px-2 text-[9px] font-bold text-blue-600 disabled:cursor-wait disabled:opacity-60"
|
|
|
|
|
title="局部刷新当前筛选数据"
|
|
|
|
|
>
|
|
|
|
|
<RefreshCw size={11} className={manualRefreshing ? 'animate-spin' : ''} />
|
|
|
|
|
<span className="hidden sm:inline">{manualRefreshing ? '刷新中' : '刷新'}</span>
|
|
|
|
|
<span>{manualRefreshing ? '刷新中' : '刷新数据'}</span>
|
|
|
|
|
</button>
|
|
|
|
|
<div className="flex items-center gap-1 rounded-lg bg-slate-100 p-0.5">
|
|
|
|
|
<button onClick={() => setSortBy('today')} className={`rounded-md px-2 py-1 text-[9px] font-bold transition-all ${sortBy === 'today' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400'}`}>区间</button>
|
|
|
|
|
<button onClick={() => setSortBy('total')} className={`rounded-md px-2 py-1 text-[9px] font-bold transition-all ${sortBy === 'total' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400'}`}>累计</button>
|
|
|
|
|
<button onClick={() => setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc')} className="rounded-md p-1 text-blue-600 transition-all hover:bg-white">
|
|
|
|
|
<button onClick={() => setSortBy('statisticTime')} className={`rounded-md px-2 py-1 text-[9px] font-bold transition-all ${sortBy === 'statisticTime' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400'}`}>统计时间</button>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc')}
|
|
|
|
|
className="rounded-md p-1 text-blue-600 transition-all hover:bg-white"
|
|
|
|
|
title={sortOrder === 'desc' ? '当前倒序,点击切换正序' : '当前正序,点击切换倒序'}
|
|
|
|
|
>
|
|
|
|
|
{sortOrder === 'desc' ? <ArrowDown size={12} /> : <ArrowUp size={12} />}
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
@@ -1369,15 +1374,15 @@ export default function MonitoringView() {
|
|
|
|
|
<div className="sticky top-[44px] z-20 bg-[var(--app-bg)] pt-1 pb-1 space-y-2">
|
|
|
|
|
<div className={`grid grid-cols-4 gap-2 transition-opacity ${pageLoading ? 'opacity-60' : ''}`}>
|
|
|
|
|
<div className="relative col-span-2 flex min-h-[68px] flex-col justify-center overflow-hidden rounded-xl bg-slate-900 p-2.5 text-white">
|
|
|
|
|
<div className="text-[7px] font-bold text-slate-500 uppercase tracking-wider">{sortBy === 'today' ? (isRangeMode ? '区间' : '当日') : '累计'}总里程</div>
|
|
|
|
|
<div className="text-[7px] font-bold text-slate-500 uppercase tracking-wider">{sortBy === 'total' ? '累计' : (isRangeMode ? '区间' : '当日')}总里程</div>
|
|
|
|
|
<div className="text-lg font-black tracking-tighter leading-tight flex items-baseline gap-1">
|
|
|
|
|
{pageLoading ? <div className="h-5 w-20 bg-slate-700 rounded animate-pulse"></div> : <>{Math.round(sortBy === 'today' ? stats.totalToday : stats.totalAll).toLocaleString()} <span className="text-[8px] text-slate-400">km</span></>}
|
|
|
|
|
{pageLoading ? <div className="h-5 w-20 bg-slate-700 rounded animate-pulse"></div> : <>{Math.round(sortBy === 'total' ? stats.totalAll : stats.totalToday).toLocaleString()} <span className="text-[8px] text-slate-400">km</span></>}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="mt-0.5 truncate text-[8px] font-bold text-slate-500">{rangeLabel}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex min-h-[68px] flex-col justify-center rounded-xl border border-gray-100 bg-white p-2.5 shadow-sm">
|
|
|
|
|
<div className="text-[7px] font-bold text-slate-400 uppercase">平均单车</div>
|
|
|
|
|
<div className="text-sm font-black text-slate-800 leading-tight">{pageLoading ? <div className="h-4 w-8 bg-slate-100 rounded animate-pulse"></div> : (stats.vehicleCount > 0 ? (sortBy === 'today' ? stats.totalToday : stats.totalAll) / stats.vehicleCount : 0).toFixed(0)}</div>
|
|
|
|
|
<div className="text-sm font-black text-slate-800 leading-tight">{pageLoading ? <div className="h-4 w-8 bg-slate-100 rounded animate-pulse"></div> : (stats.vehicleCount > 0 ? (sortBy === 'total' ? stats.totalAll : stats.totalToday) / stats.vehicleCount : 0).toFixed(0)}</div>
|
|
|
|
|
<div className="text-[7px] text-slate-400">km/台</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex min-h-[68px] flex-col justify-center rounded-xl border border-gray-100 bg-white p-2.5 shadow-sm">
|
|
|
|
|
|