From 8210c143e8550aa5711d29fc3cb71f44106000c1 Mon Sep 17 00:00:00 2001 From: betaqi <3188864257@qq.com> Date: Thu, 9 Oct 2025 16:35:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9C=A8=E7=BA=BF=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E7=AB=99=E7=82=B9=E5=8C=BA=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- global.types/components.d.ts | 2 + src/stores/transferData.ts | 109 +++++++++++++--- src/views/stationData/index.vue | 151 ++++++++++++----------- src/views/stationData/transfer/index.vue | 2 +- 4 files changed, 171 insertions(+), 93 deletions(-) diff --git a/global.types/components.d.ts b/global.types/components.d.ts index d5f9cbf..70d83f7 100644 --- a/global.types/components.d.ts +++ b/global.types/components.d.ts @@ -34,6 +34,8 @@ declare module 'vue' { ElOption: typeof import('element-plus/es')['ElOption'] ElPagination: typeof import('element-plus/es')['ElPagination'] ElProgress: typeof import('element-plus/es')['ElProgress'] + ElRadio: typeof import('element-plus/es')['ElRadio'] + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElRow: typeof import('element-plus/es')['ElRow'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElSelect: typeof import('element-plus/es')['ElSelect'] diff --git a/src/stores/transferData.ts b/src/stores/transferData.ts index ca8a84f..a77eadf 100644 --- a/src/stores/transferData.ts +++ b/src/stores/transferData.ts @@ -1,10 +1,16 @@ -import { ref, computed } from 'vue' +import { ref, computed, reactive } from 'vue' import { defineStore } from 'pinia' import type { IOnlineDevice, IUpFirmwareStatus } from '@/views/stationData/type' import ZMQWorker from '@/composables/useZMQJsonWorker' import { getSubTopic, type SubMsgData } from '@/utils/zmq' import { getDeviceTopic } from '@/views/stationData/utils' -import dayjs from "dayjs"; + +export interface SiteInfo { + id: string + onlineCount: number + offlineCount: number + devices: Map +} export const useTransferDataStore = defineStore('transfer', () => { const subDevices = getSubTopic('client', 'status', 'transfer') @@ -13,20 +19,52 @@ export const useTransferDataStore = defineStore('transfer', () => { const connectSite = ref(null) - async function initConnectSite() { - if (connectSite.value) return - connectSite.value = { - title: '未命名站点', - edit: true, - editTitle: '未命名站点', - } - } + const checkDeviceStatusInterval = ref() + + const siteMap = reactive(new Map()) const devicesMap = reactive(new Map()) - const checkDeviceStatusInterval = ref() - function checkDeviceStatus() { - checkDeviceStatusInterval.value = setInterval(checkDeviceStatusFn, 100); + // =========== mock ================= + // let i = 0 + // + // function mockSubDeviceMsg() { + // // 随机生成 SN + // const sn = `SN-${Math.floor(Math.random() * 1000)}` + // // const siteId = `${i % 2 === 0 ? 'site1' : 'site2'}` + // const siteId = `siteId-${Math.floor(Math.random() * 1000)}` + // const clientIp = `192.168.0.${Math.floor(Math.random() * 255)}` + // const version = `v${(Math.random() * 2 + 1).toFixed(2)}` + // const footprint = (Math.random() * 50000).toFixed(2) // KB + // + // // const sn = 123 + // // const siteId = 123123 + // // const clientIp = `192.168.0.${Math.floor(Math.random() * 255)}` + // // const version = `v${(Math.random() * 2 + 1).toFixed(2)}` + // // const footprint = (Math.random() * 50000).toFixed(2) // KB + // + // const msg: any = { + // feedback: [clientIp, sn, siteId, version, footprint], + // } + // + // getSubDevicesCb(msg) + // } + // + // + // let a = setInterval(() => { + // i++ + // mockSubDeviceMsg() + // }, 1000) + + // setTimeout(() => { + // clearInterval(a) + // }, 8000) + + // =========== mock end ================= + + function startCheckStatus() { + clearInterval(checkDeviceStatusInterval.value) + checkDeviceStatusInterval.value = setInterval(checkDeviceStatusFn, 1000); } const checkDeviceStatusFn = () => { @@ -37,6 +75,7 @@ export const useTransferDataStore = defineStore('transfer', () => { device.status = '离线'; } }); + reassignDevicesToSites() } function formatSizeFromKB(num: number): string { @@ -77,8 +116,34 @@ export const useTransferDataStore = defineStore('transfer', () => { } devicesMap.set(sn, device) } + } + + function reassignDevicesToSites() { + devicesMap.forEach((device) => { + const siteId = device.site_id + if (!siteId) return + + // 若该站点还未创建,则初始化 + if (!siteMap.has(siteId)) { + siteMap.set(siteId, { + id: siteId, + onlineCount: 0, + offlineCount: 0, + devices: reactive(new Map()), + }) + } + + // 获取站点信息并更新 + const siteInfo = siteMap.get(siteId)! + siteInfo.devices.set(device.sn, device) + }) - isConnected.value = devicesMap.size > 0 + // 更新site 在线数量和离线数量 + siteMap.forEach((siteInfo) => { + const devices = Array.from(siteInfo.devices.values()) + siteInfo.onlineCount = devices.filter(item => item.status === '在线').length + siteInfo.offlineCount = devices.filter(item => item.status === '离线').length + }) } const onlineCount = computed(() => { @@ -93,8 +158,8 @@ export const useTransferDataStore = defineStore('transfer', () => { onMounted(() => { worker.subscribe(getDeviceTopic, getSubDevicesCb) - checkDeviceStatus() - document.addEventListener('visibilitychange', checkDeviceStatusFn) + startCheckStatus() + document.addEventListener('visibilitychange', handleVisibilityChange) }) const route = useRoute() @@ -102,11 +167,18 @@ export const useTransferDataStore = defineStore('transfer', () => { watch(() => route.path, (val) => { if (!['/station/data-transfer', '/station'].includes(val)) { clearInterval(checkDeviceStatusInterval.value) - document.removeEventListener('visibilitychange', checkDeviceStatusFn) + document.removeEventListener('visibilitychange', handleVisibilityChange) worker.unsubscribe(subDevices) } }) + function handleVisibilityChange() { + if (document.hidden) { + clearInterval(checkDeviceStatusInterval.value) + } else { + startCheckStatus() + } + } function upFirmwareStatus(sn: string, feedback: any[]) { const device = devicesMap.get(sn) @@ -181,14 +253,13 @@ export const useTransferDataStore = defineStore('transfer', () => { return { + siteMap, isConnected, devicesMap, connectSite, checkDeviceStatusInterval, onlineCount, offlineCount, - checkDeviceStatus, - initConnectSite, upFirmwarePending, upFirmwareReset, upFirmwareStatus, diff --git a/src/views/stationData/index.vue b/src/views/stationData/index.vue index ba355c6..ea71de4 100644 --- a/src/views/stationData/index.vue +++ b/src/views/stationData/index.vue @@ -1,97 +1,108 @@ diff --git a/src/views/stationData/transfer/index.vue b/src/views/stationData/transfer/index.vue index b95b994..f095c7b 100644 --- a/src/views/stationData/transfer/index.vue +++ b/src/views/stationData/transfer/index.vue @@ -181,7 +181,7 @@ const transferStatus = ref< const devices = computed(() => { return isonLineTransfer.value - ? Array.from(devicesMap.value.values()) + ? Array.from(devicesMap.value.values()).filter(r => r.site_id === siteInfo.value.id) : offLineDeviceList.value }) as Ref