diff --git a/src/styles/prototype.css b/src/styles/prototype.css index e05de03..761535c 100644 --- a/src/styles/prototype.css +++ b/src/styles/prototype.css @@ -226,6 +226,8 @@ svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: .metric-grid strong small { font-size: 11px; margin-left: 2px; color: var(--muted); } .metric-grid .success { color: var(--green); font-size: 14px; } .mission-state { padding: 3px 6px; border-radius: 3px; background: #e7f0fc; color: #2568b5 !important; } +.mission-progress .table-empty { min-height: 42px; display: grid; place-items: center; color: var(--muted); font-size: 11px; } + .mission-name { display: flex; align-items: center; justify-content: space-between; }.mission-name > span { display: flex; flex-direction: column; gap: 3px; }.mission-name strong { font-size: 13px; }.mission-name small { color: var(--muted); font-size: 10px; }.mission-name > b { color: var(--blue); font-size: 16px; } .progress-track { height: 5px; margin-top: 10px; overflow: hidden; border-radius: 3px; background: #e7ebef; }.progress-track i { display: block; width: 50%; height: 100%; background: var(--blue); }.progress-meta { margin-top: 8px; display: flex; justify-content: space-between; color: var(--muted); font-size: 10px; } .return-action { background: #176b61; }.return-action:hover { background: #10584f; } @@ -760,6 +762,12 @@ svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: .metric-grid strong { font-size: 15px; } .metric-grid .success { font-size: 13px; } .environment-row strong { font-size: 11px; } + .mission-name strong { font-size: 12px; } + .mission-name small { font-size: 9px; } + .mission-name > b { font-size: 14px; } + .progress-track { margin-top: 8px; } + .progress-meta { margin-top: 6px; font-size: 9px; } + .mission-progress .table-empty { min-height: 36px; font-size: 10px; } .workflow-actions { gap: 6px; } .workflow-action { min-height: 44px; padding: 0 8px; gap: 6px; } .workflow-action > svg { width: 17px; } diff --git a/src/views/MonitorView/MonitorView.vue b/src/views/MonitorView/MonitorView.vue index 844d597..28d52c7 100644 --- a/src/views/MonitorView/MonitorView.vue +++ b/src/views/MonitorView/MonitorView.vue @@ -250,6 +250,29 @@ +
+
+

当前任务

+ +
+ +
暂无任务
+
+
@@ -763,6 +786,60 @@ const doorSummary = computed(() => { const dockControlMode = computed(() => record.value?.mode || displayValue(rt('controlMode'))) +function formatDuration(seconds) { + const total = Math.max(0, Math.floor(Number(seconds) || 0)) + if (!Number.isFinite(total) || total <= 0) return '--' + const mm = String(Math.floor(total / 60)).padStart(2, '0') + const ss = String(total % 60).padStart(2, '0') + return `${mm}:${ss}` +} + +function formatDistance(meters) { + const value = Number(meters) + if (!Number.isFinite(value) || value < 0) return '--' + if (value >= 1000) return `${(value / 1000).toFixed(1)} km` + return `${Math.round(value)} m` +} + +const missionDetail = computed(() => { + const rec = record.value + const nameRaw = rec?.mission || rt('missionName', 'mission') + const name = nameRaw && nameRaw !== '--' && nameRaw !== '无' ? String(nameRaw) : '' + const route = displayValue(rt('routeName', 'routeCode', 'route')) + const progressRaw = rt('missionProgress', 'progressPercent', 'progress') + const progressNum = Number(progressRaw) + const hasProgress = Number.isFinite(progressNum) + const currentWp = rt('currentWaypoint', 'waypointIndex', 'waypoint') + const totalWp = rt('waypointCount', 'totalWaypoints', 'waypoints') + const elapsed = rt('missionElapsed', 'elapsed', 'flightDuration', 'elapsedSeconds') + const distance = rt('distanceToHome', 'distanceFromDock', 'homeDistance', 'distance') + const taskId = rt('taskId', 'missionId') || rec?.taskId || null + const active = !!name || rec?.statusClass === 'mission' + return { + hasMission: active, + name: name || (rec?.statusClass === 'mission' ? (rec.status || '执行中任务') : '暂无任务'), + route: route === '--' ? '航线 --' : `航线 ${route}`, + progressText: hasProgress ? `${Math.max(0, Math.min(100, Math.round(progressNum)))}%` : '--', + progressWidth: hasProgress ? `${Math.max(0, Math.min(100, progressNum))}%` : '0%', + waypointText: (currentWp != null || totalWp != null) + ? `航点 ${displayValue(currentWp)} / ${displayValue(totalWp)}` + : '航点 -- / --', + elapsedText: `已飞行 ${formatDuration(elapsed)}`, + distanceText: `距离机巢 ${formatDistance(distance)}`, + taskId, + } +}) + +function goMissionDetail() { + const id = missionDetail.value.taskId + if (!id) { + ui.toast('暂无任务详情') + return + } + router.push({ name: 'tasks', query: { taskId: String(id) } }) +} + + const isAutoMode = computed(() => { const mode = String(rt('controlMode') || record.value?.mode || '').toLowerCase()