diff --git a/vehicle-data-platform/apps/web/src/v2/pages/VehiclePage.tsx b/vehicle-data-platform/apps/web/src/v2/pages/VehiclePage.tsx
index 7ca9fa0c..f8b08134 100644
--- a/vehicle-data-platform/apps/web/src/v2/pages/VehiclePage.tsx
+++ b/vehicle-data-platform/apps/web/src/v2/pages/VehiclePage.tsx
@@ -16,7 +16,7 @@ import { formatZhNumber, vehicleOperationStatusLabels } from '../domain/formatte
import { protocolDisplayLabel, protocolSourceLabel } from '../domain/protocols';
import { isValidAMapCoordinate } from '../../integrations/amap';
import { FleetMap } from '../map/FleetMap';
-import { InlineError, PageLoading, PanelEmpty } from '../shared/AsyncState';
+import { InlineError, PageLoading, PanelEmpty, PanelLoading } from '../shared/AsyncState';
import { MonitorReturnBar } from '../shared/MonitorReturnBar';
import { PlatformTime } from '../shared/PlatformTime';
import { ProtocolTag } from '../shared/ProtocolTag';
@@ -280,7 +280,7 @@ function TelemetryPanel({ data, pending, error }: { data?: LatestTelemetryRespon
{ title: '数据来源', dataIndex: 'protocol', width: 180, render: (_: unknown, item: LatestTelemetryValue) => }
], []);
const state = pending
- ?
正在读取最新遥测按协议整理最新标量证据…
+ ?
: error
? 最新遥测不可用{error}
: visibleMetrics.length === 0
diff --git a/vehicle-data-platform/apps/web/src/v2/pages/VehicleSearchWorkspace.tsx b/vehicle-data-platform/apps/web/src/v2/pages/VehicleSearchWorkspace.tsx
index 73d801ef..02ba91e5 100644
--- a/vehicle-data-platform/apps/web/src/v2/pages/VehicleSearchWorkspace.tsx
+++ b/vehicle-data-platform/apps/web/src/v2/pages/VehicleSearchWorkspace.tsx
@@ -10,7 +10,7 @@ import { canAdminister } from '../auth/session';
import { formatZhNumber } from '../domain/formatters';
import { useMobileLayout } from '../hooks/useMobileLayout';
import { QUERY_MEMORY, queryScopeKey, retainPreviousPageWithinScope } from '../queryPolicy';
-import { PanelEmpty } from '../shared/AsyncState';
+import { PanelEmpty, PanelLoading } from '../shared/AsyncState';
import { MobileFilterToggle } from '../shared/MobileFilterToggle';
import { MobileFilterSheet, MobileFilterSheetSection } from '../shared/MobileFilterSheet';
import { ProtocolTag } from '../shared/ProtocolTag';
@@ -328,7 +328,7 @@ export default function VehicleSearchWorkspace() {
}
/>
{candidates.isFetching && !candidates.data
- ? 正在读取授权车辆…
+ ?
: candidates.isError
? {candidates.error instanceof Error ? candidates.error.message : '授权车辆加载失败'}
: pageVehicles.length
@@ -418,6 +418,6 @@ export default function VehicleSearchWorkspace() {
/>}
{total > 0 ? : null}
- {syncOpen ? 正在加载主档同步工具…}> setSyncOpen(false)} /> : null}
+ {syncOpen ? }> setSyncOpen(false)} /> : null}
;
}
diff --git a/vehicle-data-platform/apps/web/src/v2/productionEntry.test.ts b/vehicle-data-platform/apps/web/src/v2/productionEntry.test.ts
index 95cdeaed..a67b80a9 100644
--- a/vehicle-data-platform/apps/web/src/v2/productionEntry.test.ts
+++ b/vehicle-data-platform/apps/web/src/v2/productionEntry.test.ts
@@ -110,6 +110,7 @@ describe('V2 production entry', () => {
expect(corePageSources.VehiclePage).toContain(' {
expect(corePageSources.VehiclePage).not.toContain(' import('./VehicleProfileSyncPanel'))");
+ expect(vehicleSearchSource).toContain(' {
expect(corePageSources.MonitorPage).toContain('| 车辆 | ');
- expect(sourceEvidenceSource).toContain("import { Button, Card, Input, Spin, Tag } from '@douyinfe/semi-ui'");
+ expect(sourceEvidenceSource).toContain("import { Button, Card, Input, Tag } from '@douyinfe/semi-ui'");
expect(sourceEvidenceSource).toContain(' {
vi.mocked(useMobileLayout).mockReturnValue(false);
});
-test('loads all source evidence only after the user expands it', async () => {
+test('loads all source evidence in a Semi right SideSheet without reflowing the desktop record', async () => {
const sourceEvidence = vi.spyOn(api, 'vehicleSourceEvidence').mockResolvedValue(evidence);
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
@@ -57,10 +57,16 @@ test('loads all source evidence only after the user expands it', async () => {
fireEvent.click(screen.getByRole('button', { name: '查看全部来源' }));
await waitFor(() => expect(sourceEvidence).toHaveBeenCalledTimes(1));
expect(await screen.findByText('北斗平台')).toBeInTheDocument();
- expect(view.container.querySelectorAll('.v2-source-evidence-card.semi-card')).toHaveLength(3);
+ expect(view.container.querySelector('.v2-source-evidence > .semi-card-body > .v2-source-evidence-body')).not.toBeInTheDocument();
+ expect(document.querySelector('.v2-source-evidence-sidesheet')).toHaveClass('v2-workspace-detail-sidesheet');
+ expect(document.querySelector('.v2-source-evidence-sidesheet .semi-sidesheet-inner')).toHaveStyle({ width: 'min(680px, calc(100vw - 24px))' });
+ expect(document.querySelectorAll('.v2-source-evidence-sidesheet .v2-source-evidence-card.semi-card')).toHaveLength(3);
expect(screen.getAllByText('当前推荐').every((item) => item.closest('.semi-tag'))).toBe(true);
expect(screen.getAllByText('当前推荐').length).toBeGreaterThan(0);
expect(screen.queryByText('13307795425')).not.toBeInTheDocument();
+
+ fireEvent.click(screen.getByRole('button', { name: '关闭来源证据' }));
+ await waitFor(() => expect(view.container.querySelector('.v2-source-evidence')).not.toHaveClass('is-open'));
client.clear();
});
diff --git a/vehicle-data-platform/apps/web/src/v2/shared/VehicleSourceEvidencePanel.tsx b/vehicle-data-platform/apps/web/src/v2/shared/VehicleSourceEvidencePanel.tsx
index e2fce3df..6e5b8954 100644
--- a/vehicle-data-platform/apps/web/src/v2/shared/VehicleSourceEvidencePanel.tsx
+++ b/vehicle-data-platform/apps/web/src/v2/shared/VehicleSourceEvidencePanel.tsx
@@ -1,13 +1,13 @@
import { useQuery } from '@tanstack/react-query';
import { IconSearch } from '@douyinfe/semi-icons';
-import { Button, Card, Input, Spin, Tag } from '@douyinfe/semi-ui';
+import { Button, Card, Input, 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 { useMobileLayout } from '../hooks/useMobileLayout';
import { QUERY_MEMORY } from '../queryPolicy';
-import { PanelEmpty } from './AsyncState';
+import { PanelEmpty, PanelLoading } from './AsyncState';
import { WorkspaceDetailSideSheet } from './WorkspaceDetailSideSheet';
function today() {
@@ -117,7 +117,7 @@ export function VehicleSourceEvidencePanel({
终端已脱敏;推荐结果来自后台选举,不改动原始证据。
- {query.isPending ? 正在读取全部来源证据…
: null}
+ {query.isPending ? : null}
{query.isError ? {query.error instanceof Error ? query.error.message : '来源证据读取失败'}
: null}
{query.data ? <>
@@ -138,13 +138,13 @@ export function VehicleSourceEvidencePanel({
位置与里程来源{description}
- {expanded && !mobileLayout ? evidenceBody : null}
- {mobileLayout ?
setExpanded(false)}
>
{evidenceBody}
- : null}
+
>;
}
diff --git a/vehicle-data-platform/apps/web/src/v2/styles/workspace.css b/vehicle-data-platform/apps/web/src/v2/styles/workspace.css
index 8b658e38..8e585c06 100644
--- a/vehicle-data-platform/apps/web/src/v2/styles/workspace.css
+++ b/vehicle-data-platform/apps/web/src/v2/styles/workspace.css
@@ -18338,6 +18338,58 @@
flex: none;
}
+@media (min-width: 681px) {
+ .v2-source-evidence-sidesheet .semi-sidesheet-inner {
+ border-radius: 16px 0 0 16px;
+ box-shadow: -18px 0 48px rgba(25, 45, 72, .18);
+ }
+
+ .v2-source-evidence-sidesheet .semi-sidesheet-header {
+ min-height: 76px;
+ padding: 13px 18px;
+ }
+
+ .v2-source-evidence-sidesheet .v2-source-evidence-sheet-body > .v2-source-evidence-body {
+ padding: 14px 14px 28px;
+ }
+
+ .v2-source-evidence-sidesheet .v2-source-evidence-toolbar {
+ margin: -14px -14px 14px;
+ padding: 12px 16px;
+ }
+
+ .v2-source-evidence-sidesheet .v2-source-evidence-group > div {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px;
+ }
+}
+
+.v2-source-evidence-sidesheet .v2-source-evidence-loading.v2-state-surface {
+ min-height: 190px;
+ margin-top: 10px;
+ border-color: #d9e3ee;
+ background: #fff;
+}
+
+.v2-vehicle-directory-v3 .v2-vehicle-directory-loading.v2-state-surface {
+ min-height: 220px;
+ flex: 1 1 auto;
+ margin: 10px;
+}
+
+.v2-vehicle-record-v3 .v2-telemetry-loading.v2-state-surface {
+ min-height: 190px;
+ margin: 10px;
+ border-color: #dce5ef;
+ background: #fbfdff;
+}
+
+.v2-profile-sync-loading .v2-state-surface {
+ min-height: 180px;
+ border: 0;
+ box-shadow: none;
+}
+
.v2-vehicle-record-v3.v2-vehicle-record-page {
display: flex;
width: 100%;
|---|