feat(monitor): preserve investigation context

This commit is contained in:
lingniu
2026-07-16 17:08:54 +08:00
parent 38b056f5f1
commit 1cfc9c2bdd
17 changed files with 426 additions and 37 deletions

View File

@@ -7,9 +7,11 @@ import type { HistoryDataResponse, HistoryDataRow, HistoryExportRequest, History
import { buildHistorySeriesPanels, formatExportFileSize, formatHistoryValue, formatSeriesGrain, historyExportPollInterval, parseHistoryKeywords } from '../domain/history';
import { downloadBlob } from '../domain/download';
import { InlineError } from '../shared/AsyncState';
import { MonitorReturnBar } from '../shared/MonitorReturnBar';
import { LIVE_QUERY_POLICY, QUERY_MEMORY, retainPreviousPageWithinScope } from '../queryPolicy';
import { usePlatformSession } from '../auth/AuthGate';
import { canOperate } from '../auth/session';
import { monitorReturnFromParams, preserveMonitorReturn } from '../routing/monitorContext';
const historyAxisTimeFormatter = new Intl.DateTimeFormat('zh-CN', { timeZone: 'Asia/Shanghai', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false });
@@ -112,6 +114,7 @@ export default function HistoryPage() {
const { session } = usePlatformSession();
const exportAllowed = canOperate(session) || session.role === 'customer';
const [searchParams, setSearchParams] = useSearchParams();
const monitorReturn = monitorReturnFromParams(searchParams);
const today = useMemo(currentHistoryWindow, []);
const initial = { keywords: searchParams.get('vin') || searchParams.get('keywords') || '', dateFrom: searchParams.get('dateFrom') || today.dateFrom, dateTo: searchParams.get('dateTo') || today.dateTo, category: searchParams.get('category') || 'location', protocol: searchParams.get('protocol') || '' };
const [draft, setDraft] = useState(initial);
@@ -176,9 +179,9 @@ export default function HistoryPage() {
if (next.dateFrom) url.set('dateFrom', next.dateFrom);
if (next.dateTo) url.set('dateTo', next.dateTo);
if (next.protocol) url.set('protocol', next.protocol);
setSearchParams(url, { replace: true });
setSearchParams(preserveMonitorReturn(url, monitorReturn), { replace: true });
};
const reset = () => { const next = { keywords: '', ...currentHistoryWindow(), category: 'location', protocol: '' }; setDraft(next); setCriteria(next); setOffset(0); setSearchParams({}, { replace: true }); };
const reset = () => { const next = { keywords: '', ...currentHistoryWindow(), category: 'location', protocol: '' }; setDraft(next); setCriteria(next); setOffset(0); setSearchParams(preserveMonitorReturn(new URLSearchParams(), monitorReturn), { replace: true }); };
const toggleMetric = (key: string) => setVisibleByCategory((current) => {
const baseline = current[criteria.category] ?? allMetrics.filter((metric) => metric.defaultVisible).map((metric) => metric.key);
const next = baseline.includes(key) ? baseline.filter((item) => item !== key) : [...baseline, key];
@@ -189,6 +192,7 @@ export default function HistoryPage() {
const page = Math.floor(offset / limit) + 1;
return <div className="v2-history-page">
<MonitorReturnBar />
<button type="button" className="v2-mobile-filter-toggle" aria-expanded={!filtersCollapsed} onClick={() => setFiltersCollapsed((value) => !value)}><span><b></b><small>{keywords.length ? `${keywords.length} 辆 · ${criteria.category === 'location' ? '位置数据' : criteria.category === 'raw' ? '原始报文' : '日里程'}` : '请选择车辆'}</small></span><em>{filtersCollapsed ? '修改' : '收起'}</em></button>
<form className={`v2-history-toolbar${filtersCollapsed ? ' is-mobile-collapsed' : ''}`} onSubmit={submit}>
<label className="v2-history-vehicles"><span> 5 </span><div><IconSearch /><input value={draft.keywords} onChange={(event) => setDraft((value) => ({ ...value, keywords: event.target.value }))} placeholder="车牌 / VIN多台用逗号分隔" /></div></label>