refine Semi UI vehicle evidence
This commit is contained in:
@@ -3,6 +3,7 @@ import { Button, Card, Empty, Input, Spin, Tag } from '@douyinfe/semi-ui';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { api } from '../../api/client';
|
||||
import type { VehicleLocationSourceEvidence, VehicleMileageSourceEvidence } from '../../api/types';
|
||||
import { protocolDisplayLabel, protocolSourceLabel } from '../domain/protocols';
|
||||
import { QUERY_MEMORY } from '../queryPolicy';
|
||||
|
||||
function today() {
|
||||
@@ -37,9 +38,15 @@ function sourceBadges(source: Pick<VehicleLocationSourceEvidence, 'recommended'
|
||||
</>;
|
||||
}
|
||||
|
||||
function evidenceSourceLabel(sourceLabel: string | undefined, protocol: string) {
|
||||
const normalized = sourceLabel?.trim();
|
||||
if (!normalized || normalized === protocol) return protocolDisplayLabel(protocol);
|
||||
return protocolSourceLabel(normalized);
|
||||
}
|
||||
|
||||
function LocationSourceCard({ source }: { source: VehicleLocationSourceEvidence }) {
|
||||
return <Card className={`v2-source-evidence-card is-${evidenceTone(source)}`} bodyStyle={{ padding: 0 }}>
|
||||
<header><div><strong>{source.sourceLabel || source.protocol}</strong><span>{source.protocol}{source.terminalLabel ? ` · ${source.terminalLabel}` : ''}</span></div><aside>{sourceBadges(source)}</aside></header>
|
||||
<header><div><strong>{evidenceSourceLabel(source.sourceLabel, source.protocol)}</strong><span>{protocolDisplayLabel(source.protocol)}{source.terminalLabel ? ` · ${source.terminalLabel}` : ''}</span></div><aside>{sourceBadges(source)}</aside></header>
|
||||
<dl>
|
||||
<div><dt>坐标</dt><dd>{coordinate(source)}</dd></div>
|
||||
<div><dt>速度</dt><dd>{source.speedKmh == null ? '—' : `${number(source.speedKmh)} km/h`}</dd></div>
|
||||
@@ -55,7 +62,7 @@ function LocationSourceCard({ source }: { source: VehicleLocationSourceEvidence
|
||||
function MileageSourceCard({ source }: { source: VehicleMileageSourceEvidence }) {
|
||||
const comparable = { ...source, online: true };
|
||||
return <Card className={`v2-source-evidence-card is-${evidenceTone(comparable)}`} bodyStyle={{ padding: 0 }}>
|
||||
<header><div><strong>{source.sourceLabel || source.protocol}</strong><span>{source.protocol}{source.terminalLabel ? ` · ${source.terminalLabel}` : ''}</span></div><aside>{sourceBadges(comparable)}</aside></header>
|
||||
<header><div><strong>{evidenceSourceLabel(source.sourceLabel, source.protocol)}</strong><span>{protocolDisplayLabel(source.protocol)}{source.terminalLabel ? ` · ${source.terminalLabel}` : ''}</span></div><aside>{sourceBadges(comparable)}</aside></header>
|
||||
<dl>
|
||||
<div><dt>当日里程</dt><dd>{source.dailyMileageKm == null ? '—' : `${number(source.dailyMileageKm)} km`}</dd></div>
|
||||
<div><dt>最新总里程</dt><dd>{source.latestTotalMileageKm == null ? '—' : `${number(source.latestTotalMileageKm)} km`}</dd></div>
|
||||
@@ -96,7 +103,7 @@ export function VehicleSourceEvidencePanel({
|
||||
});
|
||||
const sourceCount = (query.data?.locationSources.length ?? 0) + (query.data?.mileageSources.length ?? 0);
|
||||
const description = useMemo(() => {
|
||||
if (!query.data) return '按需读取,不影响车辆列表和地图刷新性能';
|
||||
if (!query.data) return '按需读取,不影响实时刷新';
|
||||
if (sourceCount <= 2) return '当前车辆来源较少,仅展示实际存在的证据';
|
||||
return `已读取 ${query.data.locationSources.length} 个位置来源、${query.data.mileageSources.length} 个里程来源`;
|
||||
}, [query.data, sourceCount]);
|
||||
@@ -109,13 +116,13 @@ export function VehicleSourceEvidencePanel({
|
||||
{expanded ? <div className="v2-source-evidence-body">
|
||||
<div className="v2-source-evidence-toolbar">
|
||||
<label><span>里程日期</span><Input aria-label="里程日期" type="date" value={date} max={today()} onChange={setDate} /></label>
|
||||
<small>终端标识已脱敏;推荐结果来自后台选举,展开不会改变原始证据。</small>
|
||||
<small>终端已脱敏;推荐结果来自后台选举,不改动原始证据。</small>
|
||||
</div>
|
||||
{query.isPending ? <div className="v2-source-evidence-state" role="status"><Spin size="small" />正在读取全部来源证据…</div> : null}
|
||||
{query.isError ? <div className="v2-source-evidence-state is-error"><span>{query.error instanceof Error ? query.error.message : '来源证据读取失败'}</span><Button theme="borderless" type="danger" size="small" onClick={() => void query.refetch()}>重试</Button></div> : null}
|
||||
{query.data ? <>
|
||||
<div className="v2-source-evidence-summary">
|
||||
<div><small>推荐位置来源</small><strong>{query.data.recommendedLocationLabel || query.data.recommendedLocationProtocol || '—'}</strong></div>
|
||||
<div><small>推荐位置来源</small><strong>{evidenceSourceLabel(query.data.recommendedLocationLabel, query.data.recommendedLocationProtocol)}</strong></div>
|
||||
<div><small>最大位置差</small><strong>{number(query.data.comparison.locationMaxDistanceM)}<em>m</em></strong></div>
|
||||
<div><small>总里程差</small><strong>{number(query.data.comparison.totalMileageDeltaKm)}<em>km</em></strong></div>
|
||||
<div><small>上报时间差</small><strong>{number(query.data.comparison.reportTimeDeltaSeconds, 0)}<em>s</em></strong></div>
|
||||
|
||||
Reference in New Issue
Block a user