diff --git a/vehicle-data-platform/apps/web/src/v2/pages/TrackPage.tsx b/vehicle-data-platform/apps/web/src/v2/pages/TrackPage.tsx
index c6a6daa6..a7692f52 100644
--- a/vehicle-data-platform/apps/web/src/v2/pages/TrackPage.tsx
+++ b/vehicle-data-platform/apps/web/src/v2/pages/TrackPage.tsx
@@ -55,7 +55,7 @@ function number(value: number, digits = 1) {
}
function direction(value?: number) {
- if (value === undefined || !Number.isFinite(value)) return '方向 —';
+ if (value === undefined || !Number.isFinite(value)) return '—';
const normalized = ((value % 360) + 360) % 360;
const names = ['北', '东北', '东', '东南', '南', '西南', '西', '西北'];
return `${number(normalized, 0)}° ${names[Math.round(normalized / 45) % names.length]}`;
@@ -512,7 +512,7 @@ export default function TrackPage() {
速度{number(current?.speedKmh ?? 0)} km/h
方向{direction(current?.directionDeg)}
SOC{current?.socAvailable ? `${number(current.socPercent)}%` : '—'}
- 节点累计总里程{trackPointMileageAvailable(current) ? number(current?.totalMileageKm ?? 0) : '—'}{trackPointMileageAvailable(current) ? km : null}
+ 累计里程{trackPointMileageAvailable(current) ? number(current?.totalMileageKm ?? 0) : '—'}{trackPointMileageAvailable(current) ? km : 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 00d228f3..95c0db3b 100644
--- a/vehicle-data-platform/apps/web/src/v2/styles/workspace.css
+++ b/vehicle-data-platform/apps/web/src/v2/styles/workspace.css
@@ -23465,6 +23465,181 @@
}
}
+/*
+ * Semi UI replay workspace convergence.
+ * Keep the map dominant while giving the evidence rail, live point card and
+ * transport controls the same calm surface hierarchy as the migrated
+ * directory and history workspaces.
+ */
+@media (min-width: 701px) {
+ .v2-track-page {
+ grid-template-columns: 344px minmax(0, 1fr);
+ gap: 10px;
+ padding: 10px;
+ background: #f4f7fa;
+ }
+
+ .v2-track-page.is-rail-collapsed {
+ grid-template-columns: 0 minmax(0, 1fr);
+ }
+
+ .v2-track-page > .v2-monitor-return {
+ margin: -10px -10px 0;
+ }
+
+ .v2-track-rail {
+ padding: 0;
+ background: transparent;
+ box-shadow: none;
+ }
+
+ .v2-track-rail-shell.semi-card,
+ .v2-track-stage {
+ border: 1px solid #dce5ef;
+ border-radius: 14px;
+ box-shadow: 0 8px 26px rgba(31, 52, 78, .07);
+ }
+
+ .v2-track-stage {
+ overflow: hidden;
+ }
+
+ .v2-track-query-panel .v2-track-query-header.v2-workspace-command-bar {
+ min-height: 62px;
+ padding: 9px 8px 9px 13px;
+ }
+
+ .v2-track-query-header .v2-workspace-command-copy > .semi-typography:first-child {
+ font-size: 15px;
+ letter-spacing: -.01em;
+ }
+
+ .v2-track-query-panel .v2-track-query-toggle.semi-button {
+ min-width: 78px;
+ height: 32px;
+ }
+
+ .v2-track-result-metric-rail.is-queue > .semi-card-body,
+ .v2-track-result-metric-rail .v2-workspace-metric-list > span {
+ min-height: 68px;
+ }
+
+ .v2-track-result-metric-rail .v2-workspace-metric-list > span.is-primary {
+ background: #f4f8ff;
+ box-shadow: inset 0 2px #6d9ee9;
+ }
+
+ .v2-track-result-metric-rail .v2-workspace-metric-list > span > strong,
+ .v2-track-result-metric-rail .v2-workspace-metric-list > span.is-secondary > strong {
+ font-size: clamp(14px, 1.2vw, 18px);
+ font-weight: 740;
+ }
+
+ .v2-track-rail-tabs {
+ height: 44px;
+ flex-basis: 44px;
+ }
+
+ .v2-track-rail-tabs > .semi-button {
+ height: 42px;
+ }
+
+ .v2-track-current-card.semi-card {
+ top: 12px;
+ left: 12px;
+ width: min(404px, calc(100% - 350px));
+ border-radius: 13px;
+ box-shadow: 0 14px 38px rgba(26, 47, 73, .14);
+ }
+
+ .v2-track-current-card .v2-workspace-panel-header {
+ min-height: 54px;
+ }
+
+ .v2-track-current-card > .semi-card-body > .v2-track-current-metrics > span {
+ padding: 10px 11px;
+ }
+
+ .v2-track-current-card > .semi-card-body > .v2-track-current-metrics strong {
+ font-size: 15px;
+ line-height: 20px;
+ }
+
+ .v2-track-current-card > .semi-card-body > .v2-track-current-evidence {
+ min-height: 40px;
+ }
+
+ .v2-track-current-card > .semi-card-body > p {
+ min-height: 40px;
+ font-size: 11px;
+ line-height: 20px;
+ }
+
+ .v2-track-stage-tools {
+ top: 12px;
+ right: 12px;
+ }
+
+ .v2-track-playback-dock.semi-card,
+ .v2-track-playback-dock > .semi-card-body {
+ min-height: 96px;
+ }
+
+ .v2-track-playback-dock.semi-card {
+ border-top-color: #dce5ef;
+ box-shadow: 0 -8px 24px rgba(25, 43, 66, .1);
+ }
+
+ .v2-track-playback-dock > .semi-card-body {
+ gap: 14px;
+ padding: 9px 14px !important;
+ }
+
+ .v2-track-segment-rail,
+ .v2-track-segment-placeholder {
+ height: 6px;
+ }
+
+ .v2-track-progress-slider.semi-slider-wrapper {
+ margin: 7px 0 3px;
+ }
+}
+
+@media (max-width: 1180px) and (min-width: 701px) {
+ .v2-track-page {
+ grid-template-columns: 310px minmax(0, 1fr);
+ }
+
+ .v2-track-page.is-rail-collapsed {
+ grid-template-columns: 0 minmax(0, 1fr);
+ }
+}
+
+@media (max-width: 700px) {
+ .v2-track-page.is-mobile-layout {
+ background: #edf2f7;
+ }
+
+ .v2-track-current-card.semi-card,
+ .v2-track-page.is-rail-collapsed .v2-track-current-card.semi-card {
+ border-color: #d7e1ed;
+ box-shadow: 0 12px 30px rgba(25, 45, 70, .15);
+ }
+
+ .v2-track-current-card > .semi-card-body > .v2-track-current-metrics strong {
+ font-size: 13px;
+ }
+
+ .v2-track-playback-dock.semi-card {
+ border-top-color: #d9e3ee;
+ box-shadow: 0 -8px 24px rgba(24, 42, 64, .11);
+ }
+
+ .v2-track-dock-controls > .semi-button.is-primary {
+ box-shadow: 0 7px 18px rgba(0, 100, 250, .22);
+ }
+}
+
/*
* Monitor fleet summary.
* Operational state remains prominent; high-volume ingest evidence is kept