feat(mileage): 接入区间汇总并复用查询结果
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
shishengliang
2026-10-29 09:11:21 +08:00
parent 8afe13c9a3
commit e2f932232f
33 changed files with 1056 additions and 172 deletions
@@ -11,8 +11,13 @@ type SortBy = 'today' | 'total' | 'statisticTime';
type SortOrder = 'asc' | 'desc';
export default function MonitoringToolbar({
onQuery,
queryDisabled,
hasPendingChanges,
resultsDisabled,
onToggleFullscreen,
onDownload,
onDownloadDetails,
exporting,
lastRefreshedAt,
onManualRefresh,
@@ -44,8 +49,13 @@ export default function MonitoringToolbar({
onApplyRangePreset,
rangeLabel,
}: {
onQuery: () => void;
queryDisabled: boolean;
hasPendingChanges: boolean;
resultsDisabled: boolean;
onToggleFullscreen: () => void;
onDownload: () => void;
onDownloadDetails: () => void;
exporting: boolean;
lastRefreshedAt: Date | null;
onManualRefresh: () => void;
@@ -88,9 +98,13 @@ export default function MonitoringToolbar({
<button onClick={onToggleFullscreen} className="p-1 text-slate-300 transition-colors hover:text-blue-600" title="全屏视图">
<Maximize2 size={14} />
</button>
<button onClick={onDownload} disabled={exporting} className="p-1 text-slate-300 transition-colors hover:text-blue-600 disabled:text-slate-200" title="下载当前筛选结果">
{exporting ? <RotateCcw size={14} className="animate-spin" /> : <Download size={14} />}
</button>
<details className="relative">
<summary aria-label="导出" className="cursor-pointer list-none p-1 text-slate-400">{exporting ? <RotateCcw size={14} className="animate-spin" /> : <Download size={14} />}</summary>
<div className="absolute left-0 top-full z-40 w-36 rounded-lg border border-slate-200 bg-white p-1 shadow-lg">
<button onClick={onDownload} disabled={exporting || resultsDisabled} className="block w-full rounded p-2 text-left text-xs hover:bg-slate-50 disabled:opacity-50">导出区间汇总</button>
<button onClick={onDownloadDetails} disabled={exporting || resultsDisabled} className="block w-full rounded p-2 text-left text-xs hover:bg-slate-50 disabled:opacity-50">导出逐日明细</button>
</div>
</details>
</div>
<div className="mt-1 flex items-center gap-1.5">
<span className="h-1.5 w-1.5 rounded-full bg-blue-500" />
@@ -100,15 +114,15 @@ export default function MonitoringToolbar({
</div>
<div className="flex flex-shrink-0 items-center gap-1.5">
<span className="hidden text-[9px] font-bold tabular-nums text-slate-400 sm:inline">
<span title="查询结果获取时间" className="hidden text-[9px] font-bold tabular-nums text-slate-400 sm:inline">
{lastRefreshedAt ? lastRefreshedAt.toLocaleTimeString('zh-CN', { hour12: false }) : '--:--:--'}
</span>
<button
type="button"
onClick={onManualRefresh}
disabled={manualRefreshing}
disabled={manualRefreshing || resultsDisabled}
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="局部刷新当前筛选数据"
title="重新获取当前筛选数据"
>
<RefreshCw size={11} className={manualRefreshing ? 'animate-spin' : ''} />
<span>{manualRefreshing ? '刷新中' : '刷新数据'}</span>
@@ -145,7 +159,8 @@ export default function MonitoringToolbar({
</button>
</div>
<div className="flex items-center gap-1.5 overflow-x-auto no-scrollbar">
<div className="flex items-center gap-1.5">
<div className="flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto no-scrollbar">
{([
['today', '今天'],
['yesterday', '昨天'],
@@ -166,7 +181,10 @@ export default function MonitoringToolbar({
</button>
);
})}
<span className="ml-auto shrink-0 rounded-lg bg-slate-50 px-2 py-1 text-[10px] font-bold text-slate-400">{rangeLabel}</span>
</div>
<button type="button" onClick={onQuery} disabled={queryDisabled} className="shrink-0 rounded-lg bg-blue-600 px-3 py-1.5 text-xs font-bold text-white disabled:opacity-50">查询</button>
{hasPendingChanges && <span role="status" className="shrink-0 text-[10px] text-amber-700">待查询</span>}
<span className="hidden shrink-0 rounded-lg sm:block bg-slate-50 px-2 py-1 text-[10px] font-bold text-slate-400">{rangeLabel}</span>
</div>
</div>
);