refine Semi UI track replay workspace
This commit is contained in:
@@ -195,13 +195,14 @@ const TrackRail = memo(function TrackRail({ draft, track, loading, activeStopInd
|
||||
const choosePreset = (daysBack: number) => onDraft({ ...draft, ...trackWindow(daysBack, daysBack > 0) });
|
||||
const appliedWindow = `${draft.dateFrom.replace('T', ' ').slice(5)} – ${draft.dateTo.replace('T', ' ').slice(5)}`;
|
||||
const appliedSource = draft.protocol || '自动来源';
|
||||
const contextTitle = queryCollapsed ? track?.plate || draft.keyword || '轨迹查询' : '轨迹查询';
|
||||
return <aside className="v2-track-rail">
|
||||
<Card className="v2-track-rail-shell" bodyStyle={{ padding: 0 }}>
|
||||
<section className={`v2-track-query-panel${queryCollapsed ? ' is-collapsed' : ''}`}>
|
||||
<WorkspaceCommandBar
|
||||
className="v2-track-query-header"
|
||||
ariaLabel="轨迹查询任务栏"
|
||||
title="轨迹查询"
|
||||
title={contextTitle}
|
||||
description={queryCollapsed ? `${appliedWindow} · ${appliedSource}` : '最长支持连续 7 天'}
|
||||
status={loading ? '读取中' : track ? `${track.points.length.toLocaleString('zh-CN')} 点` : '等待查询'}
|
||||
statusColor={loading ? 'blue' : track ? 'green' : 'grey'}
|
||||
@@ -219,10 +220,7 @@ const TrackRail = memo(function TrackRail({ draft, track, loading, activeStopInd
|
||||
<Button className="v2-track-rail-hide" theme="borderless" aria-label="隐藏查询与明细" icon={<IconChevronLeft />} onClick={onCollapse}><span className="v2-track-rail-hide-label">地图</span></Button>
|
||||
</>}
|
||||
/>
|
||||
{queryCollapsed ? <div className="v2-track-query-summary">
|
||||
<span><strong>{draft.keyword || '尚未选择车辆'}</strong><small>{draft.dateFrom.replace('T', ' ').slice(5)} – {draft.dateTo.replace('T', ' ').slice(5)}</small></span>
|
||||
<Tag color={draft.protocol ? 'blue' : 'grey'} type="light" size="small">{draft.protocol || '自动来源'}</Tag>
|
||||
</div> : <form className="v2-track-query" onSubmit={onSubmit}>
|
||||
{!queryCollapsed ? <form className="v2-track-query" onSubmit={onSubmit}>
|
||||
<label><span>车辆</span><VehiclePicker value={draft.keyword} onChange={(keyword) => onDraft({ ...draft, keyword })} onSelect={(vehicle) => onDraft({ ...draft, keyword: vehicle.plate || vehicle.vin })} /></label>
|
||||
<div className="v2-track-presets">
|
||||
<Button theme={activePreset === 'today' ? 'solid' : 'light'} aria-pressed={activePreset === 'today'} onClick={() => choosePreset(0)}>今天</Button>
|
||||
@@ -232,15 +230,15 @@ const TrackRail = memo(function TrackRail({ draft, track, loading, activeStopInd
|
||||
<div className="v2-track-date-grid"><label><span>开始时间</span><Input aria-label="开始时间" type="datetime-local" value={draft.dateFrom} onChange={(value) => onDraft({ ...draft, dateFrom: value })} /></label><label><span>结束时间</span><Input aria-label="结束时间" type="datetime-local" value={draft.dateTo} onChange={(value) => onDraft({ ...draft, dateTo: value })} /></label></div>
|
||||
<label><span id="track-source-label">数据来源</span><Select aria-labelledby="track-source-label" value={draft.protocol} onChange={(value) => onDraft({ ...draft, protocol: String(value) })} optionList={[{ value: '', label: '自动选择最佳来源' }, { value: 'GB32960', label: 'GB32960 · 仪表盘里程' }, { value: 'JT808', label: 'JT808 · GPS 里程' }, { value: 'YUTONG_MQTT', label: 'YUTONG · 仪表盘里程' }]} /></label>
|
||||
<Button className="v2-track-query-button" theme="solid" htmlType="submit" icon={<IconSearch />} loading={loading} disabled={!draft.keyword.trim()}>查询轨迹</Button>
|
||||
</form>}
|
||||
</form> : null}
|
||||
</section>
|
||||
|
||||
<section className="v2-track-rail-result">
|
||||
<WorkspacePanelHeader
|
||||
variant="compact"
|
||||
className="v2-track-result-header"
|
||||
title={track ? track.plate || track.vin : '轨迹证据'}
|
||||
description={track ? track.vin : '停留、事件与来源统一呈现'}
|
||||
title="轨迹证据"
|
||||
description={track ? track.plate ? `${track.plate} · ${track.vin}` : track.vin : '停留、事件与来源统一呈现'}
|
||||
meta={<Tag color={track ? 'blue' : 'grey'} type="light" size="small">{track ? `${number(track.summary.distanceKm)} km` : '等待查询'}</Tag>}
|
||||
/>
|
||||
<SegmentedTabs className="v2-track-rail-tabs" ariaLabel="轨迹明细分类" value={tab} onChange={onTab} items={[{ key: 'stops', label: '停留点', count: track?.stops.length ?? 0 }, { key: 'events', label: '事件点', count: track?.events.length ?? 0 }, { key: 'overview', label: '概览' }]} />
|
||||
@@ -428,11 +426,11 @@ export default function TrackPage() {
|
||||
{query.isError ? <div className="v2-track-error"><InlineError message={query.error instanceof Error ? query.error.message : '轨迹查询失败'} onRetry={() => query.refetch()} /></div> : null}
|
||||
|
||||
<Card className="v2-track-playback-dock" bodyStyle={{ padding: 0 }}>
|
||||
<div className="v2-track-dock-summary"><strong>{track ? `${number(track.summary.distanceKm)} km` : '等待查询'}</strong><span>{track ? `${formatDuration(track.summary.durationSeconds)} · ${track.summary.stopCount} 次停留` : '查询后可播放完整轨迹'}</span></div>
|
||||
<div className="v2-track-dock-summary"><small>行程里程</small><strong>{track ? `${number(track.summary.distanceKm)} km` : '等待查询'}</strong><span>{track ? `${formatDuration(track.summary.durationSeconds)} · ${track.summary.stopCount} 次停留` : '查询后可播放完整轨迹'}</span></div>
|
||||
<div className="v2-track-dock-progress">
|
||||
{track ? <SegmentRail track={track} /> : <div className="v2-track-segment-placeholder" />}
|
||||
<Slider key={`track-progress-${points.length}`} className="v2-track-progress-slider" aria-label="轨迹播放进度" min={0} max={Math.max(0, points.length - 1)} step={1} value={boundedIndex} onChange={(value) => selectIndex(Number(value))} disabled={!points.length} showBoundary={false} tipFormatter={(value) => `第 ${Number(value) + 1} / ${points.length} 个数据点`} />
|
||||
<div className="v2-track-progress-meta"><time>{time(current?.deviceTime)}</time><span>数据点 {points.length ? boundedIndex + 1 : 0} / {points.length}</span><time>{time(track?.summary.endTime)}</time></div>
|
||||
<div className="v2-track-progress-meta"><time>{time(current?.deviceTime)}</time><span>{playing ? '播放中' : '已暂停'} · 数据点 {points.length ? boundedIndex + 1 : 0} / {points.length}</span><time>{time(track?.summary.endTime)}</time></div>
|
||||
</div>
|
||||
<div className="v2-track-dock-controls">
|
||||
<Button theme="borderless" aria-label="上一个轨迹点" icon={<IconChevronLeft />} onClick={() => selectIndex(boundedIndex - 1)} disabled={!boundedIndex} />
|
||||
|
||||
Reference in New Issue
Block a user