diff --git a/src/App.vue b/src/App.vue index b92ea37..b9f28fb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -18,6 +18,333 @@ export default { return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE } } + }, + data() { + return { + // WebSocket相关 + websocket: null, + websocketUrl: 'ws://119.45.202.115:7181/ws', + isWebSocketConnected: false, + reconnectTimer: null, + reconnectAttempts: 0, + maxReconnectAttempts: 5, + + // 告警队列管理 + alarmQueue: [], // 告警队列 + isProcessingAlarm: false, // 是否正在处理告警 + maxQueueSize: 50, // 最大队列长度 + alarmTimeout: 300000, // 5分钟自动超时 + currentAlarmTimer: null, + + // 统计信息 + totalAlarmsReceived: 0, + totalAlarmsProcessed: 0, + totalAlarmsDropped: 0 + } + }, + mounted() { + console.log('App mounted - 初始化全局WebSocket连接') + this.initGlobalWebSocket() + + // 监听路由变化,确保WebSocket连接状态 + this.$router.afterEach(() => { + this.checkWebSocketConnection() + }) + }, + beforeDestroy() { + console.log('App beforeDestroy - 清理WebSocket连接') + this.cleanup() + }, + methods: { + // 初始化全局WebSocket连接 + initGlobalWebSocket() { + console.log('正在建立全局WebSocket连接...') + try { + this.websocket = new WebSocket(this.websocketUrl) + + this.websocket.onopen = this.onWebSocketOpen + this.websocket.onmessage = this.onWebSocketMessage + this.websocket.onclose = this.onWebSocketClose + this.websocket.onerror = this.onWebSocketError + + } catch (error) { + console.error('WebSocket连接失败:', error) + this.handleReconnect() + } + }, + + // WebSocket连接成功 + onWebSocketOpen(event) { + console.log('全局WebSocket连接已建立') + this.isWebSocketConnected = true + this.reconnectAttempts = 0 + + // 清除重连定时器 + if (this.reconnectTimer) { + clearInterval(this.reconnectTimer) + this.reconnectTimer = null + } + + // 通知所有组件WebSocket已连接 + this.$bus.$emit('websocket-connected') + }, + + // WebSocket接收消息 + onWebSocketMessage(event) { + try { + const data = JSON.parse(event.data) + console.log('收到全局WebSocket数据:', data) + + if (data.deviceParam) { + // 通过事件总线转发设备数据到需要的组件 + this.$bus.$emit('websocket-device-data', data) + } + + if (data.isFlag === 1 && data.alarmRules && data.alarmContents) { + // 处理告警数据 - 加入队列管理 + this.handleAlarmData(data) + } + + } catch (error) { + console.error('解析WebSocket数据失败:', error) + } + }, + + // WebSocket连接关闭 + onWebSocketClose(event) { + console.log('全局WebSocket连接已关闭', event) + this.isWebSocketConnected = false + + if (event.code !== 1000) { // 非正常关闭 + console.log('WebSocket异常关闭,尝试重连...') + this.handleReconnect() + } + + // 通知所有组件WebSocket已断开 + this.$bus.$emit('websocket-disconnected') + }, + + // WebSocket连接错误 + onWebSocketError(event) { + console.error('全局WebSocket连接错误:', event) + this.isWebSocketConnected = false + this.handleReconnect() + }, + + // 处理重连 + handleReconnect() { + if (this.reconnectAttempts >= this.maxReconnectAttempts) { + console.log('达到最大重连次数,停止重连') + this.$bus.$emit('websocket-max-retries-reached') + return + } + + this.reconnectAttempts++ + console.log(`第${this.reconnectAttempts}次重连尝试...`) + + this.reconnectTimer = setTimeout(() => { + this.initGlobalWebSocket() + }, 3000 * this.reconnectAttempts) // 递增延迟重连 + }, + + // 检查WebSocket连接状态 + checkWebSocketConnection() { + if (!this.isWebSocketConnected && this.reconnectAttempts < this.maxReconnectAttempts) { + console.log('检测到WebSocket未连接,尝试重新连接...') + this.handleReconnect() + } + }, + + // 处理告警数据 - 队列管理 + handleAlarmData(alarmData) { + this.totalAlarmsReceived++ + + // 检查队列是否已满 + if (this.alarmQueue.length >= this.maxQueueSize) { + console.warn('告警队列已满,丢弃最旧的告警数据') + this.alarmQueue.shift() // 移除最旧的告警 + this.totalAlarmsDropped++ + } + + // 添加时间戳和优先级 + const enrichedAlarmData = { + ...alarmData, + timestamp: new Date(), + id: this.generateAlarmId(), + priority: this.calculateAlarmPriority(alarmData), + processed: false + } + + // 添加到队列 + this.alarmQueue.push(enrichedAlarmData) + console.log(`告警已加入队列,当前队列长度: ${this.alarmQueue.length}`) + + // 如果当前没有在处理告警,开始处理队列 + if (!this.isProcessingAlarm) { + this.processAlarmQueue() + } + + // 打印统计信息 + this.printAlarmStatistics() + }, + + // 处理告警队列 + async processAlarmQueue() { + if (this.alarmQueue.length === 0 || this.isProcessingAlarm) { + return + } + + this.isProcessingAlarm = true + + // 按优先级排序(高优先级在前) + this.alarmQueue.sort((a, b) => b.priority - a.priority) + + // 取出最高优先级的告警 + const currentAlarm = this.alarmQueue[0] + + console.log('开始处理告警:', currentAlarm.id, '优先级:', currentAlarm.priority) + + // 通过事件总线发送告警到Navbar组件 + this.$bus.$emit('websocket-alarm-with-callback', { + alarm: currentAlarm, + onProcessed: this.onAlarmProcessed, + onTimeout: this.onAlarmTimeout + }) + + // 设置自动超时 + this.currentAlarmTimer = setTimeout(() => { + this.onAlarmTimeout(currentAlarm) + }, this.alarmTimeout) + }, + + // 告警处理完成回调 + onAlarmProcessed(alarmId, status) { + console.log('告警处理完成:', alarmId, '状态:', status) + + // 清除超时定时器 + if (this.currentAlarmTimer) { + clearTimeout(this.currentAlarmTimer) + this.currentAlarmTimer = null + } + + // 从队列中移除已处理的告警 + this.alarmQueue = this.alarmQueue.filter(alarm => alarm.id !== alarmId) + this.totalAlarmsProcessed++ + + this.isProcessingAlarm = false + + // 继续处理队列中的下一个告警 + setTimeout(() => { + this.processAlarmQueue() + }, 1000) // 1秒延迟,避免弹窗过于频繁 + }, + + // 告警超时处理 + onAlarmTimeout(alarm) { + console.log('告警超时未处理:', alarm.id, '自动标记为稍后处理') + + // 自动保存为未处理状态 + this.$bus.$emit('websocket-alarm-auto-save', { + alarm: alarm, + status: 1 // 1=未处理 + }) + + this.onAlarmProcessed(alarm.id, 'timeout') + }, + + // 生成唯一告警ID + generateAlarmId() { + return 'alarm_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9) + }, + + // 计算告警优先级 + calculateAlarmPriority(alarmData) { + let priority = 0 + + // 基础优先级 + priority += 1 + + // 根据告警规则数量增加优先级 + if (alarmData.alarmRules && alarmData.alarmRules.length > 0) { + priority += alarmData.alarmRules.length * 2 + } + + // 根据告警内容数量增加优先级 + if (alarmData.alarmContents && alarmData.alarmContents.length > 0) { + priority += alarmData.alarmContents.length + } + + // 根据设备参数的异常程度计算优先级(可以根据具体业务逻辑调整) + if (alarmData.deviceParam) { + // 温度异常 + if (alarmData.deviceParam.temperature && + (alarmData.deviceParam.temperature > 50 || alarmData.deviceParam.temperature < -20)) { + priority += 10 // 极端温度高优先级 + } + + // 气体浓度异常 + if (alarmData.deviceParam.concentration && alarmData.deviceParam.concentration > 100) { + priority += 15 // 危险气体浓度最高优先级 + } + + // 振动异常 + if (alarmData.deviceParam.vibrationSpeed && alarmData.deviceParam.vibrationSpeed > 50) { + priority += 8 // 严重振动高优先级 + } + } + + return priority + }, + + // 打印告警统计信息 + printAlarmStatistics() { + if (this.totalAlarmsReceived % 10 === 0) { // 每10个告警打印一次统计 + console.log('=== 告警统计信息 ===') + console.log('总接收告警数:', this.totalAlarmsReceived) + console.log('已处理告警数:', this.totalAlarmsProcessed) + console.log('丢弃告警数:', this.totalAlarmsDropped) + console.log('当前队列长度:', this.alarmQueue.length) + console.log('队列中待处理告警:', this.alarmQueue.map(a => a.id)) + console.log('================') + } + }, + + // 获取告警队列状态(供外部组件调用) + getAlarmQueueStatus() { + return { + queueLength: this.alarmQueue.length, + isProcessing: this.isProcessingAlarm, + totalReceived: this.totalAlarmsReceived, + totalProcessed: this.totalAlarmsProcessed, + totalDropped: this.totalAlarmsDropped, + isConnected: this.isWebSocketConnected + } + }, + + // 清理资源 + cleanup() { + // 清除WebSocket连接 + if (this.websocket) { + this.websocket.close(1000, '应用关闭') + this.websocket = null + } + + // 清除定时器 + if (this.reconnectTimer) { + clearInterval(this.reconnectTimer) + this.reconnectTimer = null + } + + if (this.currentAlarmTimer) { + clearTimeout(this.currentAlarmTimer) + this.currentAlarmTimer = null + } + + // 清空队列 + this.alarmQueue = [] + this.isWebSocketConnected = false + this.isProcessingAlarm = false + } } }; diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue index fc9bcb8..0e17ec7 100644 --- a/src/layout/components/Navbar.vue +++ b/src/layout/components/Navbar.vue @@ -29,6 +29,22 @@ }} + + + + + + + + + + + + + {{ alarmQueueLength }} + + + @@ -397,22 +413,53 @@ export default { // WebSocket告警相关 realtimeAlarmDialog: false, currentRealtimeAlarm: null, - alarmProcessing: false + alarmProcessing: false, + currentAlarmId: null, + alarmProcessedCallback: null, + alarmTimeoutCallback: null, + websocketStatusText: '', + websocketStatusIcon: '', + websocketStatusColor: '', + alarmQueueStatusText: '', + queueStatusColor: '', + alarmQueueLength: 0, + queueStatusTimer: null } }, created() { localStorage.setItem('this.alarmDataTotal', 0) - // 监听WebSocket告警事件 - this.$bus.$on('websocket-alarm', this.handleRealtimeAlarm) + // 监听新的队列化WebSocket告警事件 + this.$bus.$on('websocket-alarm-with-callback', this.handleQueuedRealtimeAlarm) + // 监听自动超时保存事件 + this.$bus.$on('websocket-alarm-auto-save', this.handleAutoSaveAlarm) + // 监听WebSocket连接状态变化 + this.$bus.$on('websocket-connected', this.onWebSocketConnected) + this.$bus.$on('websocket-disconnected', this.onWebSocketDisconnected) + this.$bus.$on('websocket-max-retries-reached', this.onWebSocketMaxRetriesReached) }, beforeDestroy() { - // 移除事件监听 - this.$bus.$off('websocket-alarm', this.handleRealtimeAlarm) + // 移除所有事件监听 + this.$bus.$off('websocket-alarm-with-callback', this.handleQueuedRealtimeAlarm) + this.$bus.$off('websocket-alarm-auto-save', this.handleAutoSaveAlarm) + this.$bus.$off('websocket-connected', this.onWebSocketConnected) + this.$bus.$off('websocket-disconnected', this.onWebSocketDisconnected) + this.$bus.$off('websocket-max-retries-reached', this.onWebSocketMaxRetriesReached) + + // 清理定时器 + if (this.queueStatusTimer) { + clearInterval(this.queueStatusTimer) + this.queueStatusTimer = null + } }, mounted() { // 初始获取告警数据,后续完全依赖WebSocket推送 this.getAlarmData() + + // 定期更新告警队列状态 + this.queueStatusTimer = setInterval(() => { + this.updateQueueStatus() + }, 2000) // 每2秒更新一次状态 }, components: { Breadcrumb, @@ -558,17 +605,25 @@ export default { const baseURL = process.env.VUE_APP_BASE_API || ''; return baseURL + relativePath; }, - // 处理WebSocket实时告警 - handleRealtimeAlarm(alarmData) { - console.log('收到实时告警:', alarmData) - this.currentRealtimeAlarm = alarmData + // 处理队列化的WebSocket实时告警 + handleQueuedRealtimeAlarm(data) { + console.log('收到队列化实时告警:', data) + + // 解构获取告警数据和回调函数 + const { alarm, onProcessed, onTimeout } = data + + this.currentRealtimeAlarm = alarm + this.currentAlarmId = alarm.id + this.alarmProcessedCallback = onProcessed + this.alarmTimeoutCallback = onTimeout + + // 显示告警弹窗 this.realtimeAlarmDialog = true - // 同时播放提示音(可选) + // 播放提示音 this.playAlarmSound() - // 注意:这里不立即保存,等用户操作后再保存 - // this.saveRealtimeAlarmData(alarmData) + console.log('告警弹窗已显示,告警ID:', alarm.id, '优先级:', alarm.priority) }, // 播放告警提示音 playAlarmSound() { @@ -709,6 +764,11 @@ export default { const success = await this.saveRealtimeAlarmData(this.currentRealtimeAlarm, 1) if (success) { this.$message.info('告警已记录,状态为未处理') + + // 调用回调函数通知App.vue处理完成 + if (this.alarmProcessedCallback) { + this.alarmProcessedCallback(this.currentAlarmId, 'later') + } } } catch (error) { console.error('保存告警数据失败:', error) @@ -718,8 +778,7 @@ export default { } } - this.realtimeAlarmDialog = false - this.currentRealtimeAlarm = null + this.closeAlarmDialog() }, // 确认知晓实时告警(保存为已处理状态) @@ -730,11 +789,15 @@ export default { const success = await this.saveRealtimeAlarmData(this.currentRealtimeAlarm, 0) if (success) { this.$message.success('告警已确认知晓并标记为已处理') + + // 调用回调函数通知App.vue处理完成 + if (this.alarmProcessedCallback) { + this.alarmProcessedCallback(this.currentAlarmId, 'processed') + } } // 关闭弹窗 - this.realtimeAlarmDialog = false - this.currentRealtimeAlarm = null + this.closeAlarmDialog() } catch (error) { console.error('处理告警失败:', error) this.$message.error('处理告警失败') @@ -742,6 +805,14 @@ export default { this.alarmProcessing = false } }, + // 关闭告警弹窗 + closeAlarmDialog() { + this.realtimeAlarmDialog = false + this.currentRealtimeAlarm = null + this.currentAlarmId = null + this.alarmProcessedCallback = null + this.alarmTimeoutCallback = null + }, // 格式化告警时间 formatAlarmTime(time) { if (!time) return '--' @@ -766,6 +837,95 @@ export default { 8: '气体浓度' } return fieldMap[fieldCode] || '未知字段' + }, + // 处理WebSocket连接状态变化 + onWebSocketConnected() { + console.log('WebSocket连接成功') + this.websocketStatusText = 'WebSocket连接成功' + this.websocketStatusIcon = 'el-icon-success' + this.websocketStatusColor = '#67C23A' + }, + onWebSocketDisconnected() { + console.log('WebSocket连接断开') + this.websocketStatusText = 'WebSocket连接断开' + this.websocketStatusIcon = 'el-icon-error' + this.websocketStatusColor = '#F56C6C' + }, + onWebSocketMaxRetriesReached() { + console.log('WebSocket达到最大重试次数') + this.websocketStatusText = 'WebSocket达到最大重试次数' + this.websocketStatusIcon = 'el-icon-warning' + this.websocketStatusColor = '#E6A23C' + }, + // 处理WebSocket自动超时保存事件 + handleAutoSaveAlarm(data) { + console.log('收到自动超时保存事件:', data) + const { alarm, status } = data + + // 自动保存告警数据 + this.saveRealtimeAlarmData(alarm, status).then((success) => { + if (success) { + console.log('自动超时保存成功:', alarm.id) + this.alarmQueueLength = 0 + } else { + console.error('自动超时保存失败:', alarm.id) + this.alarmQueueLength = 1 + } + }) + }, + showQueueStatus() { + // 获取告警队列状态并显示 + if (this.$root.getAlarmQueueStatus) { + const status = this.$root.getAlarmQueueStatus() + const message = ` + 告警队列状态: + • 队列长度:${status.queueLength} + • 正在处理:${status.isProcessing ? '是' : '否'} + • 总接收:${status.totalReceived} + • 已处理:${status.totalProcessed} + • 已丢弃:${status.totalDropped} + • 连接状态:${status.isConnected ? '已连接' : '已断开'} + ` + this.$alert(message, '告警队列状态', { + confirmButtonText: '确定', + type: 'info' + }) + } else { + this.$message.info('无法获取队列状态信息') + } + }, + updateQueueStatus() { + // 从App.vue获取告警队列状态 + if (this.$root.getAlarmQueueStatus) { + const status = this.$root.getAlarmQueueStatus() + + this.alarmQueueLength = status.queueLength + + // 根据队列长度设置状态 + if (status.queueLength === 0) { + this.alarmQueueStatusText = '告警队列为空' + this.queueStatusColor = '#67C23A' // 绿色 + } else if (status.queueLength < 5) { + this.alarmQueueStatusText = `告警队列:${status.queueLength}个待处理` + this.queueStatusColor = '#E6A23C' // 黄色 + } else { + this.alarmQueueStatusText = `告警队列:${status.queueLength}个待处理(队列较长)` + this.queueStatusColor = '#F56C6C' // 红色 + } + + // 初始化WebSocket状态(如果还未设置) + if (!this.websocketStatusText) { + if (status.isConnected) { + this.websocketStatusText = 'WebSocket连接正常' + this.websocketStatusIcon = 'el-icon-success' + this.websocketStatusColor = '#67C23A' + } else { + this.websocketStatusText = 'WebSocket连接断开' + this.websocketStatusIcon = 'el-icon-error' + this.websocketStatusColor = '#F56C6C' + } + } + } } } } @@ -1077,4 +1237,62 @@ export default { } } +// WebSocket状态和队列状态指示器样式 +.websocket-status { + display: inline-flex; + align-items: center; + cursor: default; + + i { + font-size: 16px; + transition: all 0.3s ease; + } +} + +.alarm-queue-status { + display: inline-flex; + align-items: center; + position: relative; + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + transform: scale(1.1); + } + + i { + font-size: 16px; + transition: all 0.3s ease; + } + + .queue-count { + position: absolute; + top: -8px; + right: -8px; + background: #ff4757; + color: white; + font-size: 10px; + padding: 2px 4px; + border-radius: 8px; + min-width: 16px; + height: 16px; + line-height: 12px; + text-align: center; + font-weight: bold; + animation: pulse 2s infinite; + } +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } + 100% { + transform: scale(1); + } +} + diff --git a/src/views/ems/base/baseMonitorInfoIOTDevice/index.vue b/src/views/ems/base/baseMonitorInfoIOTDevice/index.vue index 5b96f4c..6cc6c69 100644 --- a/src/views/ems/base/baseMonitorInfoIOTDevice/index.vue +++ b/src/views/ems/base/baseMonitorInfoIOTDevice/index.vue @@ -221,7 +221,7 @@ - + diff --git a/src/views/index.vue b/src/views/index.vue index 692b44d..e82b9f8 100644 --- a/src/views/index.vue +++ b/src/views/index.vue @@ -200,15 +200,7 @@ export default { return { loading: false, deviceList: [], - // refreshTimer: null, // 已删除:不再使用定时刷新 - // WebSocket相关 - websocket: null, - websocketUrl: 'ws://119.45.202.115:7181/ws', - isWebSocketConnected: false, - reconnectTimer: null, - reconnectAttempts: 0, - maxReconnectAttempts: 5, - + alarmRuleTotalCount: 0, alarmDataTotalCount: 0, totalDeviceCount: 0, // 设备总数 @@ -238,162 +230,19 @@ export default { mounted() { this.loadDeviceTree() this.loadStatistics() // 初始加载统计数据 - this.initWebSocket() // 初始化WebSocket连接 + + // 监听全局WebSocket事件 + this.$bus.$on('websocket-device-data', this.handleDeviceData) + this.$bus.$on('websocket-connected', this.onWebSocketConnected) + this.$bus.$on('websocket-disconnected', this.onWebSocketDisconnected) }, beforeDestroy() { - // 清理WebSocket相关定时器 - if (this.reconnectTimer) { - clearInterval(this.reconnectTimer) - } - // 关闭WebSocket连接 - this.closeWebSocket() + // 清理事件监听 + this.$bus.$off('websocket-device-data', this.handleDeviceData) + this.$bus.$off('websocket-connected', this.onWebSocketConnected) + this.$bus.$off('websocket-disconnected', this.onWebSocketDisconnected) }, methods: { - // 初始化WebSocket连接 - initWebSocket() { - console.log('正在建立WebSocket连接...') - try { - this.websocket = new WebSocket(this.websocketUrl) - - this.websocket.onopen = this.onWebSocketOpen - this.websocket.onmessage = this.onWebSocketMessage - this.websocket.onclose = this.onWebSocketClose - this.websocket.onerror = this.onWebSocketError - - } catch (error) { - console.error('WebSocket连接失败:', error) - this.handleReconnect() - } - }, - - // WebSocket连接成功 - onWebSocketOpen(event) { - console.log('WebSocket连接已建立') - this.isWebSocketConnected = true - this.reconnectAttempts = 0 - - // 清除重连定时器 - if (this.reconnectTimer) { - clearInterval(this.reconnectTimer) - this.reconnectTimer = null - } - - this.$message.success('实时数据连接已建立') - }, - - // WebSocket接收消息 - onWebSocketMessage(event) { - try { - const data = JSON.parse(event.data) - console.log('收到WebSocket数据:', data) - - if (data.deviceParam) { - // 处理实时传感器数据 - this.handleDeviceData(data) - } - - if (data.isFlag === 1 && data.alarmRules && data.alarmContents) { - // 处理告警信息 - 通过事件总线通知Navbar组件 - this.$bus.$emit('websocket-alarm', data) - - // 实时更新告警数据统计 - 根据告警规则数量增加统计 - this.alarmDataTotalCount += data.alarmRules.length - console.log('实时更新告警统计,新增告警数量:', data.alarmRules.length, '当前总数:', this.alarmDataTotalCount) - } - - } catch (error) { - console.error('解析WebSocket数据失败:', error) - } - }, - - // WebSocket连接关闭 - onWebSocketClose(event) { - console.log('WebSocket连接已关闭', event) - this.isWebSocketConnected = false - - if (event.code !== 1000) { // 非正常关闭 - this.$message.warning('实时数据连接已断开,正在尝试重连...') - this.handleReconnect() - } - }, - - // WebSocket连接错误 - onWebSocketError(event) { - console.error('WebSocket连接错误:', event) - this.isWebSocketConnected = false - this.handleReconnect() - }, - - // 处理重连 - handleReconnect() { - if (this.reconnectAttempts >= this.maxReconnectAttempts) { - console.log('达到最大重连次数,停止重连') - this.$message.error('实时数据连接失败,请刷新页面重试') - return - } - - this.reconnectAttempts++ - console.log(`第${this.reconnectAttempts}次重连尝试...`) - - this.reconnectTimer = setTimeout(() => { - this.initWebSocket() - }, 3000 * this.reconnectAttempts) // 递增延迟重连 - }, - - // 关闭WebSocket连接 - closeWebSocket() { - if (this.websocket) { - this.websocket.close(1000, '页面关闭') - this.websocket = null - } - this.isWebSocketConnected = false - }, - - // 处理实时设备数据 - handleDeviceData(data) { - const deviceParam = data.deviceParam - if (!deviceParam || !deviceParam.monitorId) { - return - } - - // 如果当前选中了节点,只更新该节点下的设备数据 - if (this.selectedNodeId !== null) { - this.updateDeviceDataInList(deviceParam) - } else { - // 如果没有选中节点,可以选择是否更新全局设备列表 - console.log('收到设备数据但未选中节点:', deviceParam.monitorId) - } - }, - - // 更新设备列表中的数据 - updateDeviceDataInList(deviceParam) { - const index = this.deviceList.findIndex(device => device.monitorId === deviceParam.monitorId) - - if (index !== -1) { - // 更新现有设备数据 - const updatedDevice = { - ...this.deviceList[index], - temperature: deviceParam.temperature, - humidity: deviceParam.humidity, - illuminance: deviceParam.illuminance, - noise: deviceParam.noise, - concentration: deviceParam.concentration, - vibrationSpeed: deviceParam.vibrationSpeed || deviceParam.VibrationSpeed, - vibrationDisplacement: deviceParam.vibrationDisplacement || deviceParam.VibrationDisplacement, - vibrationAcceleration: deviceParam.vibrationAcceleration || deviceParam.VibrationAcceleration, - vibrationTemp: deviceParam.vibrationTemp || deviceParam.VibrationTemp, - collectTime: deviceParam.collectTime, - recodeTime: deviceParam.recordTime - } - - // 使用Vue.set确保响应式更新 - this.$set(this.deviceList, index, updatedDevice) - console.log('更新设备数据:', deviceParam.monitorId) - } else { - console.log('设备不在当前节点列表中:', deviceParam.monitorId) - } - }, - async loadStatistics() { try { this.alarmDataTotalCount = await getAlarmDataTotalCount(); @@ -677,8 +526,69 @@ export default { 8: '气体浓度' } return fieldMap[fieldCode] || '未知字段' - } + }, + // 处理全局WebSocket设备数据 + handleDeviceData(data) { + const deviceParam = data.deviceParam + if (!deviceParam || !deviceParam.monitorId) { + return + } + + // 如果当前选中了节点,只更新该节点下的设备数据 + if (this.selectedNodeId !== null) { + this.updateDeviceDataInList(deviceParam) + } else { + // 如果没有选中节点,可以选择是否更新全局设备列表 + console.log('收到设备数据但未选中节点:', deviceParam.monitorId) + } + + // 如果有告警数据,更新告警统计 + if (data.isFlag === 1 && data.alarmRules && data.alarmRules.length > 0) { + this.alarmDataTotalCount += data.alarmRules.length + console.log('实时更新告警统计,新增告警数量:', data.alarmRules.length, '当前总数:', this.alarmDataTotalCount) + } + }, + + // 更新设备列表中的数据 + updateDeviceDataInList(deviceParam) { + const index = this.deviceList.findIndex(device => device.monitorId === deviceParam.monitorId) + + if (index !== -1) { + // 更新现有设备数据 + const updatedDevice = { + ...this.deviceList[index], + temperature: deviceParam.temperature, + humidity: deviceParam.humidity, + illuminance: deviceParam.illuminance, + noise: deviceParam.noise, + concentration: deviceParam.concentration, + vibrationSpeed: deviceParam.vibrationSpeed || deviceParam.VibrationSpeed, + vibrationDisplacement: deviceParam.vibrationDisplacement || deviceParam.VibrationDisplacement, + vibrationAcceleration: deviceParam.vibrationAcceleration || deviceParam.VibrationAcceleration, + vibrationTemp: deviceParam.vibrationTemp || deviceParam.VibrationTemp, + collectTime: deviceParam.collectTime, + recodeTime: deviceParam.recordTime + } + + // 使用Vue.set确保响应式更新 + this.$set(this.deviceList, index, updatedDevice) + console.log('更新设备数据:', deviceParam.monitorId) + } else { + console.log('设备不在当前节点列表中:', deviceParam.monitorId) + } + }, + + // WebSocket连接状态变化处理 + onWebSocketConnected() { + console.log('Dashboard: WebSocket连接已建立') + this.$message.success('实时数据连接已建立') + }, + + onWebSocketDisconnected() { + console.log('Dashboard: WebSocket连接已断开') + this.$message.warning('实时数据连接已断开') + }, } }