feat: unify vehicle live metric rail
This commit is contained in:
@@ -23,6 +23,7 @@ import { ProtocolTag } from '../shared/ProtocolTag';
|
||||
import { SegmentedTabs } from '../shared/SegmentedTabs';
|
||||
import { VehicleSourceEvidencePanel } from '../shared/VehicleSourceEvidencePanel';
|
||||
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||
import { WorkspaceMetricRail, type WorkspaceQueueMetricRailItem } from '../shared/WorkspaceMetricRail';
|
||||
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
|
||||
import { WorkspaceSideSheet, type WorkspaceSideSheetBadgeColor } from '../shared/WorkspaceSideSheet';
|
||||
import { monitorReturnFromParams, withMonitorReturn } from '../routing/monitorContext';
|
||||
@@ -466,6 +467,46 @@ function VehicleRecord({ detail, liveRealtime, telemetry, telemetryPending, tele
|
||||
...(hasMenu(session, 'statistics') ? [{ key: 'statistics', label: '里程查询', icon: <IconClock />, to: withMonitorReturn(`/statistics?vins=${encodeURIComponent(detail.vin)}`, monitorReturn), type: 'tertiary' as const }] : []),
|
||||
...(hasMenu(session, 'alerts') ? [{ key: 'alerts', label: '告警事件', icon: <IconAlarm />, to: `/alerts?vin=${encodeURIComponent(detail.vin)}`, type: 'tertiary' as const }] : [])
|
||||
];
|
||||
const liveMetrics: WorkspaceQueueMetricRailItem[] = [
|
||||
{
|
||||
label: '速度',
|
||||
value: <>{availableMetric(realtime?.speedKmh, realtime?.speedAvailable)}<em className="v2-vehicle-live-unit">km/h</em></>,
|
||||
note: '实时车速',
|
||||
tone: 'primary',
|
||||
emphasis: 'primary'
|
||||
},
|
||||
{
|
||||
label: 'SOC',
|
||||
value: <>{availableMetric(realtime?.socPercent, realtime?.socAvailable)}<em className="v2-vehicle-live-unit">%</em></>,
|
||||
note: '剩余电量',
|
||||
tone: 'success',
|
||||
emphasis: 'secondary'
|
||||
},
|
||||
{
|
||||
label: '总里程',
|
||||
value: <>{availableMetric(realtime?.totalMileageKm, realtime?.mileageAvailable)}<em className="v2-vehicle-live-unit">km</em></>,
|
||||
note: <span className="v2-vehicle-live-action-note">推荐口径<IconChevronRight /></span>,
|
||||
emphasis: 'secondary',
|
||||
ariaLabel: '查看总里程全部来源',
|
||||
onClick: () => setSourceEvidenceOpen(true)
|
||||
},
|
||||
{
|
||||
label: '当日里程',
|
||||
value: <>{availableMetric(realtime?.todayMileageKm, realtime?.todayMileageAvailable)}<em className="v2-vehicle-live-unit">km</em></>,
|
||||
note: <span className="v2-vehicle-live-action-note">今日累计<IconChevronRight /></span>,
|
||||
tone: 'primary',
|
||||
emphasis: 'primary',
|
||||
ariaLabel: '查看当日里程全部来源',
|
||||
onClick: () => setSourceEvidenceOpen(true)
|
||||
},
|
||||
{
|
||||
label: '来源状态',
|
||||
value: <>{realtime?.onlineSourceCount ?? 0}<em className="v2-vehicle-live-unit">/ {detail.sourceStatus.length}</em></>,
|
||||
note: '在线来源 / 全部',
|
||||
tone: (realtime?.onlineSourceCount ?? 0) > 0 ? 'success' : 'neutral',
|
||||
emphasis: 'secondary'
|
||||
}
|
||||
];
|
||||
useLayoutEffect(() => {
|
||||
const root = recordRootRef.current;
|
||||
if (!root) return;
|
||||
@@ -529,14 +570,17 @@ function VehicleRecord({ detail, liveRealtime, telemetry, telemetryPending, tele
|
||||
description="关键运行指标与推荐数据来源"
|
||||
meta={<span className="v2-live-report-meta"><i className={realtime?.online ? 'is-online' : ''} />{realtime?.online ? '实时在线' : '当前离线'} · <IconClock /><PlatformTime value={realtime?.lastSeen || identity?.lastSeen} /></span>}
|
||||
/>
|
||||
<div className="v2-live-grid" role="list" aria-label="车辆实时指标">
|
||||
<div className="v2-live-metric is-speed" role="listitem"><small>速度</small><strong>{availableMetric(realtime?.speedKmh, realtime?.speedAvailable)}<em>km/h</em></strong><span>实时车速</span></div>
|
||||
<div className="v2-live-metric is-soc" role="listitem"><small>SOC</small><strong>{availableMetric(realtime?.socPercent, realtime?.socAvailable)}<em>%</em></strong><span>剩余电量</span></div>
|
||||
<div className="v2-live-metric is-mileage" role="listitem"><small>总里程</small><Button theme="borderless" type="tertiary" className="v2-live-source-link" title="展开全部里程来源" aria-label="查看总里程全部来源" onClick={() => setSourceEvidenceOpen(true)}><span>{availableMetric(realtime?.totalMileageKm, realtime?.mileageAvailable)}<em>km</em></span><IconChevronRight /></Button><span>推荐口径</span></div>
|
||||
<div className="v2-live-metric is-today-mileage" role="listitem"><small>当日里程</small><Button theme="borderless" type="tertiary" className="v2-live-source-link" title="展开全部里程来源" aria-label="查看当日里程全部来源" onClick={() => setSourceEvidenceOpen(true)}><span>{availableMetric(realtime?.todayMileageKm, realtime?.todayMileageAvailable)}<em>km</em></span><IconChevronRight /></Button><span>今日累计</span></div>
|
||||
<div className="v2-live-metric is-source" role="listitem"><small>推荐来源</small><ProtocolTag protocol={realtime?.primaryProtocol} className="v2-live-primary-protocol" /><span title={realtime?.locationSource}>{protocolSourceLabel(realtime?.locationSource) || '当前最优来源'}</span></div>
|
||||
<div className="v2-live-metric is-source-status" role="listitem"><small>来源状态</small><strong>{realtime?.onlineSourceCount ?? 0}<em> / {detail.sourceStatus.length}</em></strong><span>在线来源 / 全部</span></div>
|
||||
</div>
|
||||
<WorkspaceMetricRail
|
||||
variant="queue"
|
||||
className="v2-vehicle-live-metric-rail"
|
||||
ariaLabel="车辆实时指标"
|
||||
items={liveMetrics}
|
||||
context={<span className="v2-vehicle-live-source-context">
|
||||
<small>推荐来源</small>
|
||||
<strong><ProtocolTag protocol={realtime?.primaryProtocol} className="v2-live-primary-protocol" compact /></strong>
|
||||
<em title={realtime?.locationSource}>{protocolSourceLabel(realtime?.locationSource) || '当前最优来源'}</em>
|
||||
</span>}
|
||||
/>
|
||||
<CurrentVehicleAddress vehicle={realtime} fallback={identity?.locationText} />
|
||||
</section>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user