const { createApp } = Vue const API = '' createApp({ data() { return { connecting: false, agvConnected: false, armConnected: false, cameraOpened: false, armCameraOpened: false, mapLoaded: false, mapConfig: {}, pointsCount: 0, currentState: 'idle', // 摄像头轮询 agvCameraSrc: '/api/camera/refresh?t=' + Date.now(), armCameraSrc: '/api/camera/arm_preview?t=' + Date.now(), agvCameraError: false, hasAgvCamera: false, // AGV 车体是否有可用相机 armCameraError: false, reconnectingDevice: null, // 环境切换 testMode: true, } }, computed: { allReady() { return this.agvConnected && this.armConnected && this.cameraOpened && this.mapLoaded }, statusClass() { return this.currentState }, statusText() { const map = { idle: '空闲', setting: '设置模式', running: '运行中', paused: '已暂停' } return map[this.currentState] || '未知' } }, mounted() { this.refresh() this.refreshCameraCapabilities() this.loadEnvMode() setInterval(this.refreshStatus, 3000) this.refreshCams() setInterval(() => this.refreshCams(), 2000) }, methods: { refreshCams() { this.agvCameraSrc = '/api/camera/refresh?t=' + Date.now() if (!this.armCameraSrc.startsWith('/api/camera/arm_preview')) { this.armCameraSrc = '/api/camera/arm_preview?t=' + Date.now() } }, async refreshCameraCapabilities() { try { const res = await fetch(API + '/api/camera/capabilities') const data = await res.json() this.hasAgvCamera = data.has_agv_camera } catch (e) { this.hasAgvCamera = false } }, refreshAgvCamera() { this.agvCameraSrc = '/api/camera/refresh?t=' + Date.now() this.agvCameraError = false }, async refresh() { await this.refreshStatus() await this.loadPoints() }, async refreshStatus() { try { const res = await fetch(API + '/api/status') const data = await res.json() this.agvConnected = data.agv_connected this.armConnected = data.arm_connected this.cameraOpened = data.camera_opened // 尝试从后端获取摄像头能力,若无字段则保持默认 false if (data.has_agv_camera !== undefined) { this.hasAgvCamera = data.has_agv_camera } this.armCameraOpened = data.arm_camera_opened this.mapLoaded = data.map_loaded this.currentState = data.state || 'idle' if (data.map_loaded && data.map) { this.mapConfig = data.map } } catch (e) { console.error(e) } }, async loadPoints() { try { const res = await fetch(API + '/api/points/list') const data = await res.json() this.pointsCount = data.points ? data.points.length : 0 } catch (e) {} }, async connectAll() { this.connecting = true try { const res = await fetch(API + '/api/system/connect', { method: 'POST' }) const data = await res.json() if (data.errors && data.errors.length) { alert('部分连接失败:\n' + data.errors.join('\n')) } await this.refreshStatus() } finally { this.connecting = false } }, async disconnectAll() { await fetch(API + '/api/system/disconnect', { method: 'POST' }) await this.refreshStatus() }, async connectDevice(device) { if (this.connecting) return this.reconnectingDevice = device try { const res = await fetch(API + '/api/device/connect', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({device}) }) const data = await res.json() if (!data.ok && data.error) { alert(data.device + ' 重连失败: ' + data.error) } await this.refreshStatus() } finally { this.reconnectingDevice = null } }, async goRunning() { if (!this.allReady) { alert('请先连接所有设备并加载地图') } else { window.location.href = '/running' } }, async loadEnvMode() { try { const res = await fetch(API + '/api/config/mode') const data = await res.json() if (data.ok) { this.testMode = data.test_mode } } catch (e) { console.error('加载环境配置失败:', e) } }, async toggleEnvMode() { const newMode = !this.testMode try { const res = await fetch(API + '/api/config/mode', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({test_mode: newMode}) }) const data = await res.json() if (data.ok) { this.testMode = data.test_mode alert('已切换至: ' + data.label) } else { alert('切换失败: ' + (data.error || '未知错误')) } } catch (e) { alert('切换请求失败: ' + e.message) } }, } }).mount('#app')