const { createApp } = Vue const API = '' createApp({ delimiters: ['[[', ']]'], data() { return { missionState: 'idle', currentPoint: 0, totalPoints: 0, report: null, previewUrl: API + '/api/camera/preview', polling: null } }, computed: { missionStateText() { const map = { idle: '空闲', running: '任务运行中', paused: '已暂停', completed: '已完成' } return map[this.missionState] || '未知' }, progressPercent() { if (!this.totalPoints) return 0 return Math.round((this.currentPoint / this.totalPoints) * 100) } }, mounted() { this.poll() }, beforeUnmount() { if (this.polling) clearInterval(this.polling) }, methods: { poll() { this.refresh() this.polling = setInterval(this.refresh, 2000) }, async refresh() { try { const res = await fetch(API + '/api/mission/state') const data = await res.json() this.missionState = data.state || 'idle' if (this.missionState === 'running') { const reportRes = await fetch(API + '/api/mission/report') const reportData = await reportRes.json() if (reportData.report) { this.totalPoints = reportData.report.total_points || 0 this.currentPoint = reportData.report.details?.length || 0 this.report = reportData.report } } else if (this.missionState === 'idle') { const reportRes = await fetch(API + '/api/mission/report') const reportData = await reportRes.json() if (reportData.report) { this.report = reportData.report this.totalPoints = reportData.report.total_points || 0 this.currentPoint = reportData.report.details?.length || 0 } } } catch (e) {} }, async startMission() { if (this.missionState !== 'idle') return await fetch(API + '/api/mission/start', { method: 'POST' }) this.missionState = 'running' }, async pauseMission() { await fetch(API + '/api/mission/pause', { method: 'POST' }) this.missionState = 'paused' }, async stopMission() { await fetch(API + '/api/mission/stop', { method: 'POST' }) this.missionState = 'idle' }, onPreviewError(e) { e.target.style.display = 'none' } } }).mount('#app')