交互式开关和响应式弹窗总线数据监听和传递
This commit is contained in:
parent
6c39f1aa5f
commit
a8266b78eb
|
@ -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 => ({
|
||||
|
|
Loading…
Reference in New Issue