From a8266b78ebc484fb857f207079ac62fcd0c90762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=9A=93?= <1736436516@qq.com> Date: Fri, 22 Nov 2024 17:33:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=A4=E4=BA=92=E5=BC=8F=E5=BC=80=E5=85=B3?= =?UTF-8?q?=E5=92=8C=E5=93=8D=E5=BA=94=E5=BC=8F=E5=BC=B9=E7=AA=97=E6=80=BB?= =?UTF-8?q?=E7=BA=BF=E6=95=B0=E6=8D=AE=E7=9B=91=E5=90=AC=E5=92=8C=E4=BC=A0?= =?UTF-8?q?=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/useGlobalWebSocket.ts | 119 +++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 42 deletions(-) diff --git a/src/utils/useGlobalWebSocket.ts b/src/utils/useGlobalWebSocket.ts index a2a0fb1..e5b1b5a 100644 --- a/src/utils/useGlobalWebSocket.ts +++ b/src/utils/useGlobalWebSocket.ts @@ -1,34 +1,59 @@ import { ref } from 'vue'; import { ElMessage, ElNotification } from 'element-plus'; import eventBus from '@/utils/eventBus'; +import dayjs from 'dayjs'; +import { BoxApi } from '@/utils/boxApi'; +const apiInstance = new BoxApi(); -const websocket = ref(null); -const isWebSocketConnected = ref(false); -let heartbeatInterval: number | null = null; +const algorithmMap = ref(new Map()); +// 加载算法映射表 +const loadAlgorithms = async () => { + const token = localStorage.getItem('alertToken'); + if (token) { + const algorithms = await apiInstance.getAlgorithms(token); + algorithmMap.value = new Map( + algorithms.map((algo: { code_name: string; name: string }) => [algo.code_name, algo.name]) + ); + } else { + console.error('Token 未找到,请登录'); + } +}; + +const websocket = ref(null); // WebSocket 实例 +const isWebSocketConnected = ref(false); // WebSocket 连接状态 +let heartbeatInterval: number | null = null; // 心跳定时器 +const formatDateTime = (isoString: string): string => dayjs(isoString).format('YYYY-MM-DD HH:mm:ss'); // 连接 WebSocket const connectWebSocket = () => { - websocket.value = new WebSocket(`ws://192.168.28.33:8080/ws/event`); - websocket.value.onopen = () => { - ElMessage.success('全局 WebSocket 连接成功'); - isWebSocketConnected.value = true; - }; - websocket.value.onmessage = (event) => { - const data = JSON.parse(event.data); + const rememberedAddress = localStorage.getItem('rememberedAddress'); // 获取存储的主机地址 + if (rememberedAddress) { + websocket.value = new WebSocket(`ws://${rememberedAddress}:8080/ws/event`); + // websocket.value = new WebSocket(`ws://192.168.28.33:8080/ws/event`); + loadAlgorithms(); + websocket.value.onopen = () => { + ElMessage.success('全局 WebSocket 连接成功'); + isWebSocketConnected.value = true; - // 显示通知,并在点击时通过 eventBus 触发全局弹窗事件 - showNotification(data); - }; - websocket.value.onclose = handleClose; - websocket.value.onerror = handleError; + }; + websocket.value.onmessage = (event) => { + const data = JSON.parse(event.data); // 解析收到的数据 + handlePopupNotification(data); // 根据模式处理弹窗通知 + }; + websocket.value.onclose = handleClose; // 处理连接关闭 + websocket.value.onerror = handleError; // 处理连接错误 + } else { + ElMessage.error('主机地址获取失败,请重新登录'); + } }; // 关闭 WebSocket const closeWebSocket = () => { if (websocket.value) { websocket.value.close(); + websocket.value = null; ElMessage.info('全局 WebSocket 已关闭'); - stopHeartbeat(); + stopHeartbeat(); // 停止心跳 isWebSocketConnected.value = false; } }; @@ -38,7 +63,7 @@ const startHeartbeat = () => { if (heartbeatInterval) return; heartbeatInterval = window.setInterval(() => { if (websocket.value && websocket.value.readyState === WebSocket.OPEN) { - websocket.value.send('ping'); + websocket.value.send('ping'); // 发送心跳数据 } }, 5000); }; @@ -55,42 +80,52 @@ const stopHeartbeat = () => { const handleClose = () => { ElMessage.warning('WebSocket 连接已关闭'); isWebSocketConnected.value = false; - stopHeartbeat(); + stopHeartbeat(); // 停止心跳 }; -// 处理错误 +// 处理连接错误 const handleError = () => { ElMessage.error('WebSocket 连接出错'); isWebSocketConnected.value = false; - stopHeartbeat(); + stopHeartbeat(); // 停止心跳 }; -// 显示自定义通知 -const showNotification = (data: any) => { - ElNotification({ - title: '新告警', - message: ` -
-

告警编号:${data.id || '未知'}

-

摄像头编号:${data.camera_id || '未知'}

-

摄像头名称:${data.camera.name || '未知'}

-
- `, - dangerouslyUseHTMLString: true, - duration: 5000, - customClass: 'custom-notification', - onClick: () => { - // 触发全局事件总线的 showDialog 事件 - eventBus.emit('showDialog', data); - } - }); +// 根据弹窗模式处理通知 +const handlePopupNotification = (data: any) => { + const isInteractive = localStorage.getItem('isInteractivePopupEnabled') === 'true'; // 是否为交互式弹窗 + const isResponsive = localStorage.getItem('isResponsivePopupEnabled') === 'true'; // 是否为响应式弹窗 + + if (isResponsive) { + // 响应式模式:直接显示对话框 + eventBus.emit('showDialog', data); + } else if (isInteractive) { + + const formattedTime = formatDateTime(data.started_at); + ElNotification({ + title: '新告警', + message: ` +
+

告警编号:${data.id || '未知'}

+

告警点位:${data.camera?.name|| '未知'}

+

告警类型:${algorithmMap.value.get(data.types) || '未知'}

+

告警时间:${formattedTime || '未知'}

+
+ `, + dangerouslyUseHTMLString: true, + duration: 5000, + customClass: 'custom-notification', + onClick: () => { + eventBus.emit('showDialog', data); // 点击通知触发对话框 + } + }); + } }; // 导出类型和方法 export interface GlobalWebSocket { - connectWebSocket: () => void; - closeWebSocket: () => void; - isWebSocketConnected: typeof isWebSocketConnected; + connectWebSocket: () => void; // 连接 WebSocket + closeWebSocket: () => void; // 关闭 WebSocket + isWebSocketConnected: typeof isWebSocketConnected; // WebSocket 连接状态 } export const useGlobalWebSocket = (): GlobalWebSocket => ({