From 60688aad04e620db0d234a56874158e76b0bc6c8 Mon Sep 17 00:00:00 2001 From: JINGYJ <1458671527@qq.com> Date: Thu, 17 Apr 2025 18:00:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=81=94=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/websocketStore.ts | 44 +++++++++++++++++++++++ src/views/dashboard/AppearanceMonitor.vue | 41 ++++++++++++++------- src/views/dashboard/DataOverview.vue | 23 ++++++++++++ src/views/dashboard/DeviceStatus.vue | 23 +++++++++++- src/views/dashboard/PoleMonitor.vue | 19 ++++++++-- 5 files changed, 135 insertions(+), 15 deletions(-) create mode 100644 src/stores/websocketStore.ts diff --git a/src/stores/websocketStore.ts b/src/stores/websocketStore.ts new file mode 100644 index 0000000..4164f06 --- /dev/null +++ b/src/stores/websocketStore.ts @@ -0,0 +1,44 @@ +// stores/websocketStore.ts +import { defineStore } from 'pinia'; +import { ref } from 'vue'; + +export const useWebSocketStore = defineStore('websocket', () => { + const messages = ref([]); + const showModal = ref(false); + const currentMessage = ref(''); + let socket: WebSocket | null = null; + + const connect = () => { + try { + socket = new WebSocket('ws://192.168.10.14:8000/ws/logs/'); + + socket.addEventListener('open', () => { + console.log('WebSocket 连接已打开'); + }); + + socket.addEventListener('message', (event) => { + messages.value.push(JSON.parse(event.data)); + currentMessage.value = event.data; + showModal.value = true; + }); + + socket.addEventListener('close', () => { + console.log('WebSocket 连接已关闭,尝试重连...'); + // setTimeout(connect, 5000); + }); + + socket.addEventListener('error', (error) => { + console.error('WebSocket 连接出错:', error); + socket?.close(); + // setTimeout(connect, 5000); + }); + } catch (err) { + console.error('创建 WebSocket 实例时出错:', err); + // setTimeout(connect, 5000); + } + }; + + connect(); + + return { messages, showModal, currentMessage }; +}); \ No newline at end of file diff --git a/src/views/dashboard/AppearanceMonitor.vue b/src/views/dashboard/AppearanceMonitor.vue index fa0ed9a..76d098b 100644 --- a/src/views/dashboard/AppearanceMonitor.vue +++ b/src/views/dashboard/AppearanceMonitor.vue @@ -102,6 +102,8 @@ import { isSuccessApi } from "@/utils/forApi"; import PointModal from './components/PointModal.vue' import AlarmModal from './components/AlarmModal.vue' import DeleteModal from './components/DeleteModal.vue' +import { useWebSocketStore } from '@/stores/websocketStore'; +import { onBeforeRouteLeave } from 'vue-router'; import "swiper/css"; import 'swiper/scss'; @@ -113,6 +115,25 @@ const swiperRef = ref(null); const isPointOpen = ref(false); //点云弹窗 const isAlarmOpen = ref(false); //详情弹窗 const isDeleteOpen = ref(false); //删除弹窗 +const websocketStore = useWebSocketStore(); +// 监听 messages 的变化 +watch(() => websocketStore.messages, (newMessages: string[], oldMessages: string[]) => { + // console.log('新消息数组:', newMessages[newMessages?.length - 1].content); + // console.log('旧消息数组:', oldMessages); + // if (newMessages?.length > oldMessages?.length) { + // // 说明有新消息到来 + // const newMessage = newMessages[newMessages?.length - 1]; + // // console.log('接收到新的 WebSocket 消息:', newMessage); + + // // 这里可以添加更多的处理逻辑,例如弹出提示框等 + // } + if(newMessages?.length > 0 && !isAlarmOpen.value) { + console.log(newMessages[newMessages?.length - 1],'newMessages[newMessages?.length - 1]'); + currentRow.value = newMessages[newMessages?.length - 1]; + currFileList.value = newMessages[newMessages?.length - 1]?.images; + isAlarmOpen.value = true; + } +}, { deep: true, immediate: true }); const columns = [ { label: "站点", @@ -289,18 +310,7 @@ const getFileList = async () => { const res = await getAppearanceMonitorDetailApi({ id: currentRow.value?.id, current: 1, pageSize: 1000 }) console.log(res.data, 'getDetailList_data') if (isSuccessApi(res)) { - // currFileList.value = res.data.data; - currFileList.value = [ - { - image_url: 'https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg' - },{ - image_url: 'https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg' - },{ - image_url: 'https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg' - },{ - image_url: 'https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg' - } - ] + currFileList.value = res.data.data; currFile.value = res.data.data[0]; activeIndex.value = 0; } @@ -357,6 +367,7 @@ const handleQuery = () => { // 重置方法 const handleReset = () => { searchForm.train_number = ''; + searchForm.station = ''; searchForm.train_carriage_number = ''; searchForm.fault_type = ''; getList() @@ -383,6 +394,12 @@ const handleRowClick = (row, event, rowIndex) => { getFileList() }; +onBeforeRouteLeave(() => { + isAlarmOpen.value = false; + currentRow.value = {}; + currFileList.value = []; +}); + onMounted(() => { getList(); }); diff --git a/src/views/dashboard/DataOverview.vue b/src/views/dashboard/DataOverview.vue index 46c7117..3956b43 100644 --- a/src/views/dashboard/DataOverview.vue +++ b/src/views/dashboard/DataOverview.vue @@ -154,6 +154,7 @@ + @@ -166,6 +167,9 @@ import PieChartSmall from "./components/PieChartSmall.vue"; import DeviceStatus from "./components/DeviceStatus.vue"; import { getDataOverviewApi, getDeviceInfowApi, getRecordFaultApi, getRealTimeApi } from '@/api/dashboard'; import { isSuccessApi } from "@/utils/forApi"; +import AlarmModal from './components/AlarmModal.vue' +import { useWebSocketStore } from '@/stores/websocketStore'; +import { onBeforeRouteLeave } from 'vue-router'; defineOptions({ name: "DataOverviewWrap" @@ -197,6 +201,20 @@ const carFaultTotal = ref([]); const poleFaultTotal = ref([]); const imageFault = ref([]); const activeBtn = ref("month"); +const isAlarmOpen = ref(false); //详情弹窗 +const currentRow = ref>({}); // 当前选中行 +const currFileList = ref[]>([]); // 详情的文件列表 + +const websocketStore = useWebSocketStore(); +// 监听 messages 的变化 +watch(() => websocketStore.messages, (newMessages: string[], oldMessages: string[]) => { + if(newMessages?.length > 0 && !isAlarmOpen.value) { + currentRow.value = newMessages[newMessages?.length - 1]; + currFileList.value = newMessages[newMessages?.length - 1]?.images; + isAlarmOpen.value = true; + } +}, { deep: true, immediate: true }); + const getList = async (dateType: string = "month") => { activeBtn.value = dateType const res = await getDataOverviewApi({ dateType }) @@ -272,6 +290,11 @@ const getRealTime = async () => { console.error('获取设备信息出错:', error); } } +onBeforeRouteLeave(() => { + isAlarmOpen.value = false; + currentRow.value = {}; + currFileList.value = []; +}); onMounted(() => { getList() getDeviceInfo() diff --git a/src/views/dashboard/DeviceStatus.vue b/src/views/dashboard/DeviceStatus.vue index b22c8b3..4450b69 100644 --- a/src/views/dashboard/DeviceStatus.vue +++ b/src/views/dashboard/DeviceStatus.vue @@ -46,6 +46,7 @@ + @@ -61,6 +62,9 @@ import outLineIcon from '@/assets/common/outline_icon.png'; import errorIcon from '@/assets/common/error_icon.png'; import { getDeviceStatusApi } from '@/api/dashboard'; import { isSuccessApi } from "@/utils/forApi"; +import AlarmModal from './components/AlarmModal.vue' +import { useWebSocketStore } from '@/stores/websocketStore'; +import { onBeforeRouteLeave } from 'vue-router'; defineOptions({ name: "DeviceStatusIndex" @@ -104,6 +108,19 @@ const isRealOpen = ref(false); // 实时视频弹窗 const isHistoryOpen = ref(false); // 历史视频弹窗 const historyVideos = ref[]>([]); //历史视频数据 const historyModalRef = ref(null); +const isAlarmOpen = ref(false); //详情弹窗 +const currentDetailRow = ref>({}); // 当前选中行 +const currFileList = ref[]>([]); // 详情的文件列表 + +const websocketStore = useWebSocketStore(); +// 监听 messages 的变化 +watch(() => websocketStore.messages, (newMessages: string[], oldMessages: string[]) => { + if(newMessages?.length > 0 && !isAlarmOpen.value) { + currentDetailRow.value = newMessages[newMessages?.length - 1]; + currFileList.value = newMessages[newMessages?.length - 1]?.images; + isAlarmOpen.value = true; + } +}, { deep: true, immediate: true }); const columns = [ { @@ -238,7 +255,11 @@ function openHistory(row) { currentRow.value = row; fetchHistoryList(); } - +onBeforeRouteLeave(() => { + isAlarmOpen.value = false; + currentDetailRow.value = {}; + currFileList.value = []; +}); onMounted(() => { getList(); }); diff --git a/src/views/dashboard/PoleMonitor.vue b/src/views/dashboard/PoleMonitor.vue index 129d5cb..dc813b8 100644 --- a/src/views/dashboard/PoleMonitor.vue +++ b/src/views/dashboard/PoleMonitor.vue @@ -95,6 +95,7 @@