交互式开关和响应式弹窗总线数据监听和传递

This commit is contained in:
龚皓 2024-11-22 17:33:57 +08:00
parent 6c39f1aa5f
commit a8266b78eb
1 changed files with 77 additions and 42 deletions

View File

@ -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<WebSocket | null>(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<WebSocket | null>(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`);
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;
};
websocket.value.onmessage = (event) => {
const data = JSON.parse(event.data);
// 显示通知,并在点击时通过 eventBus 触发全局弹窗事件
showNotification(data);
const data = JSON.parse(event.data); // 解析收到的数据
handlePopupNotification(data); // 根据模式处理弹窗通知
};
websocket.value.onclose = handleClose;
websocket.value.onerror = handleError;
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) => {
// 根据弹窗模式处理通知
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: `
<div style="max-height: 200px; overflow-y: auto;">
<p><strong></strong>${data.id || '未知'}</p>
<p><strong></strong>${data.camera_id || '未知'}</p>
<p><strong></strong>${data.camera.name || '未知'}</p>
<p><strong></strong>${data.camera?.name|| '未知'}</p>
<p><strong></strong>${algorithmMap.value.get(data.types) || '未知'}</p>
<p><strong></strong>${formattedTime || '未知'}</p>
</div>
`,
dangerouslyUseHTMLString: true,
duration: 5000,
customClass: 'custom-notification',
onClick: () => {
// 触发全局事件总线的 showDialog 事件
eventBus.emit('showDialog', data);
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 => ({