feat: unify detail side sheets

This commit is contained in:
lingniu
2026-07-19 05:38:17 +08:00
parent 7eca5ae352
commit 63b50732cb
15 changed files with 273 additions and 42 deletions

View File

@@ -12,7 +12,7 @@ import { usePlatformSession } from '../auth/AuthGate';
import { canAdminister, hasMenu } from '../auth/session';
import { LIVE_QUERY_POLICY, QUERY_MEMORY } from '../queryPolicy';
import { formatTelemetryTime, formatTelemetryValue, telemetryQualityColor, telemetryQualityLabel, telemetryValueTypeLabel } from '../domain/telemetry';
import { formatZhNumber } from '../domain/formatters';
import { formatZhNumber, vehicleOperationStatusLabels } from '../domain/formatters';
import { protocolDisplayLabel, protocolSourceLabel } from '../domain/protocols';
import { isValidAMapCoordinate } from '../../integrations/amap';
import { FleetMap } from '../map/FleetMap';
@@ -34,7 +34,6 @@ function availableMetric(value: number | undefined, available?: boolean) { retur
function issueTone(issue: QualityIssueRow) { return issue.severity === 'error' ? 'error' : 'warning'; }
function durationHours(seconds?: number | null) { return seconds == null ? '—' : `${formatZhNumber(seconds / 3600, 1)} 小时`; }
function localDateTime(value?: string) { return value ? value.slice(0, 16) : ''; }
const operationStatusLabels = { unknown: '待维护', active: '运营中', inactive: '停运', maintenance: '维保中', retired: '已退役' } as const;
const SINGLE_VEHICLE_REFRESH_MS = 10_000;
const VehicleSearch = lazy(() => import('./VehicleSearchWorkspace'));
const VehicleActions = lazy(() => import('./VehicleActions'));
@@ -101,7 +100,7 @@ function Archive({ detail, editable, onUpdated }: { detail: VehicleDetail; edita
<label><span></span><Input maxLength={128} value={draft.modelName} onChange={(value) => setDraft({ ...draft, modelName: value })} /></label>
<label><span></span><Input maxLength={64} value={draft.vehicleType} onChange={(value) => setDraft({ ...draft, vehicleType: value })} /></label>
<label><span></span><Input maxLength={128} value={draft.companyName} onChange={(value) => setDraft({ ...draft, companyName: value })} /></label>
<label><span></span><Select value={draft.operationStatus} onChange={(value) => setDraft({ ...draft, operationStatus: String(value) })} optionList={Object.entries(operationStatusLabels).map(([value, label]) => ({ value, label }))} /></label>
<label><span></span><Select value={draft.operationStatus} onChange={(value) => setDraft({ ...draft, operationStatus: String(value) })} optionList={Object.entries(vehicleOperationStatusLabels).map(([value, label]) => ({ value, label }))} /></label>
<label><span></span><Input maxLength={128} value={draft.accessProvider} onChange={(value) => setDraft({ ...draft, accessProvider: value })} /></label>
<label><span></span><Input aria-label="首次接入" type="datetime-local" value={draft.firstAccessAt} onChange={(value) => setDraft({ ...draft, firstAccessAt: value })} /></label>
<label><span></span><Input type="number" min="0" step="0.1" value={draft.runtimeHours} onChange={(value) => setDraft({ ...draft, runtimeHours: value })} /></label>
@@ -110,7 +109,7 @@ function Archive({ detail, editable, onUpdated }: { detail: VehicleDetail; edita
{ key: '车辆品牌', value: fmt(profile?.brandName) },
{ key: '车型 / 类型', value: [profile?.modelName, profile?.vehicleType].filter(Boolean).join(' / ') || '—' },
{ key: '所属企业', value: fmt(profile?.companyName) },
{ key: '运营状态', value: <Tag color={profile?.operationStatus === 'active' ? 'green' : profile?.operationStatus === 'maintenance' ? 'orange' : 'grey'} type="light" size="small">{operationStatusLabels[profile?.operationStatus ?? 'unknown']}</Tag> },
{ key: '运营状态', value: <Tag color={profile?.operationStatus === 'active' ? 'green' : profile?.operationStatus === 'maintenance' ? 'orange' : 'grey'} type="light" size="small">{vehicleOperationStatusLabels[profile?.operationStatus ?? 'unknown']}</Tag> },
{ key: '接入服务商', value: fmt(profile?.accessProvider) },
{ key: '首次接入', value: fmt(profile?.firstAccessAt) },
{ key: '累计运行', value: durationHours(profile?.runtimeSeconds) }