From 9abd80906217e2206a6db109dddebe7634e11aff Mon Sep 17 00:00:00 2001 From: betaqi <3188864257@qq.com> Date: Thu, 22 May 2025 18:11:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=9F=E8=83=BD=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 + .env.local | 1 + .env.prod | 1 + global.types/components.d.ts | 3 +- package.json | 4 +- src/api/module/firmware/index.ts | 11 +- src/api/module/transfer/index.ts | 1 + src/composables/useZMQJsonWorker.ts | 16 +- src/stores/transferData.ts | 62 +++- src/utils/zmq.ts | 4 +- src/utils/zmqJsonWorker.ts | 14 +- src/views/firmwareUpload/index.vue | 40 +-- .../stationData/components/PointGroupTree.vue | 138 ++++++++ .../stationData/components/deviceDrawer.vue | 169 ++++++---- .../stationData/components/newDataChart.vue | 19 +- ...siteTransferDlg.vue => offTransferDlg.vue} | 35 +- .../stationData/components/transferMask.vue | 39 +++ src/views/stationData/index.vue | 179 ++-------- src/views/stationData/transferData.vue | 309 +++++++++++------- src/views/stationData/type.ts | 8 +- vite.config.ts | 4 +- 21 files changed, 637 insertions(+), 422 deletions(-) create mode 100644 .env.local create mode 100644 .env.prod create mode 100644 src/views/stationData/components/PointGroupTree.vue rename src/views/stationData/components/{siteTransferDlg.vue => offTransferDlg.vue} (66%) create mode 100644 src/views/stationData/components/transferMask.vue diff --git a/.env b/.env index 90e4a25..5dc33d1 100644 --- a/.env +++ b/.env @@ -1 +1,3 @@ VITE_BASE_API = '/remoteServer' +VITE_SHOW_ONLINE_DEVICE = true +VITE_APP_ENV = local diff --git a/.env.local b/.env.local new file mode 100644 index 0000000..e890e1e --- /dev/null +++ b/.env.local @@ -0,0 +1 @@ +VITE_APP_ENV = local diff --git a/.env.prod b/.env.prod new file mode 100644 index 0000000..2ca27fa --- /dev/null +++ b/.env.prod @@ -0,0 +1 @@ +VITE_APP_ENV = prod diff --git a/global.types/components.d.ts b/global.types/components.d.ts index 0ad67ec..b6c94ef 100644 --- a/global.types/components.d.ts +++ b/global.types/components.d.ts @@ -16,13 +16,13 @@ declare module 'vue' { EdfsWrap: typeof import('./../src/components/Edfs-wrap.vue')['default'] ElAside: typeof import('element-plus/es')['ElAside'] ElButton: typeof import('element-plus/es')['ElButton'] - ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] ElContainer: typeof import('element-plus/es')['ElContainer'] ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDialog: typeof import('element-plus/es')['ElDialog'] + ElDivider: typeof import('element-plus/es')['ElDivider'] ElDrawer: typeof import('element-plus/es')['ElDrawer'] ElHeader: typeof import('element-plus/es')['ElHeader'] ElInput: typeof import('element-plus/es')['ElInput'] @@ -34,6 +34,7 @@ declare module 'vue' { ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] ElTag: typeof import('element-plus/es')['ElTag'] ElTooltip: typeof import('element-plus/es')['ElTooltip'] + ElTree: typeof import('element-plus/es')['ElTree'] ElUpload: typeof import('element-plus/es')['ElUpload'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] diff --git a/package.json b/package.json index d5b7342..dd35ccc 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "build": "run-p type-check \"build-only {@}\" --", "preview": "vite preview", "build-only": "vite build", + "build:local": "vite build --mode local", + "build:prod": "vite build --mode prod", "type-check": "vue-tsc --build" }, "dependencies": { @@ -48,4 +50,4 @@ "vite-plugin-vue-devtools": "^7.7.2", "vue-tsc": "^2.2.2" } -} +} \ No newline at end of file diff --git a/src/api/module/firmware/index.ts b/src/api/module/firmware/index.ts index d4df2d6..4dba6ba 100644 --- a/src/api/module/firmware/index.ts +++ b/src/api/module/firmware/index.ts @@ -3,19 +3,20 @@ import { globalServer } from '../index' -export const uploadFirmwareFile = (params: File, abort: AbortController) => +export const uploadFirmwareFile = (params: FormData, abort: AbortController) => globalServer({ url: 'api/upload', method: 'POST', data: params, signal: abort.signal, - headers: { - 'Content-Type': 'multipart/form-data', - }, + headers: { 'Content-Type': 'multipart/form-data' }, + timeout: 0, }) -export const getFirmwarePath = () => globalServer({ +export const getFirmwarePath = () => globalServer<{ + path: string +}>({ url: 'api/package-path', method: 'GET', }) \ No newline at end of file diff --git a/src/api/module/transfer/index.ts b/src/api/module/transfer/index.ts index 3230eb6..03fad17 100644 --- a/src/api/module/transfer/index.ts +++ b/src/api/module/transfer/index.ts @@ -6,6 +6,7 @@ interface IGetDeviceDataParams { limit?: number offset?: number host?: string + name: string } diff --git a/src/composables/useZMQJsonWorker.ts b/src/composables/useZMQJsonWorker.ts index 776dc12..1f8da66 100644 --- a/src/composables/useZMQJsonWorker.ts +++ b/src/composables/useZMQJsonWorker.ts @@ -2,7 +2,7 @@ import { WorkerCMD, ZmqCMD, } from '@/utils/zmq' import type { ManualAction, PublishMsg, PubMsgData, SubMsgData, TimeoutMsg, ZmqMessage } from '@/utils/zmq' import webWorker from '@/utils/zmqJsonWorker?worker' -const defaultHost = import.meta.env.PROD ? window.location.hostname : '192.168.1.115' +const defaultHost = import.meta.env.PROD ? window.location.hostname : '192.168.1.199' class ZMQJsonWorker { private static instance: ZMQJsonWorker | null = null; // ➤ 单例实例 @@ -11,6 +11,7 @@ class ZMQJsonWorker { private pubTimeoutHandlers: Map void> = new Map(); private host: string; private statusCallback: ((status: string) => void) | null = null; + private isAlwaysListenMsgMap: Map> = new Map(); private constructor(host: string = defaultHost) { this.host = host; @@ -51,7 +52,7 @@ class ZMQJsonWorker { this.worker.postMessage({ cmd: WorkerCMD.UNSUBSCRIBE, topic }); } - publish(topic: string, msg: PublishMsg, isTimeout: boolean = false, handler?: (msg: TimeoutMsg) => void) { + publish(topic: string, msg: PublishMsg, isTimeout: boolean = false, handler?: (msg: TimeoutMsg) => void, isAlwaysListen: boolean = false) { if (isTimeout) { const timeoutId = msg.id if (typeof handler !== 'function') { @@ -60,7 +61,10 @@ class ZMQJsonWorker { } this.pubTimeoutHandlers.set(timeoutId, handler) } - this.worker.postMessage({ cmd: WorkerCMD.PUBLISH, topic, msg: JSON.stringify(msg), isTimeout }); + if (isAlwaysListen) { + this.isAlwaysListenMsgMap.set(`${msg.id}`, msg) + } + this.worker.postMessage({ cmd: WorkerCMD.PUBLISH, topic, msg: JSON.stringify(msg), isTimeout, isAlwaysListen }); } setStatusCallback(callback: (status: string) => void) { @@ -117,8 +121,10 @@ class ZMQJsonWorker { this.handleSubscribeMessage(`${topic}-${json.id}`, json); // 删除发布消息的回调 if (Object.keys(json).includes('result') && json.result !== 'progress') { - this.GC_pubReleaseSub(`${topic}-${json.id}`) - this.GC_pubReleaseTimeout(`${json.id}`) + if (!this.isAlwaysListenMsgMap.has(`${json.id}`)) { + this.GC_pubReleaseSub(`${topic}-${json.id}`) + this.GC_pubReleaseTimeout(`${json.id}`) + } } } diff --git a/src/stores/transferData.ts b/src/stores/transferData.ts index f474d71..70e755f 100644 --- a/src/stores/transferData.ts +++ b/src/stores/transferData.ts @@ -35,22 +35,27 @@ export const useTransferDataStore = defineStore('transfer', () => { function getSubDevicesCb(msg: SubMsgData) { const { feedback } = msg const sn = feedback[1] - const device: IOnlineDevice = { - clientIp: feedback[0], - sn: sn, - stationName: feedback[2], - footprint: feedback[3] ?? '--', - lastUpdated: Date.now(), - status: '在线', // 初始状态为在线 - isChecked: false, - } + const hasDevice = devicesMap.get(sn) + if (hasDevice) { + hasDevice.lastUpdated = Date.now() + hasDevice.status = '在线' + } else { + const device: IOnlineDevice = { + clientIp: feedback[0], + sn: sn, + stationName: feedback[2], + footprint: feedback[3] ?? '--', + lastUpdated: Date.now(), + status: '在线', // 初始状态为在线 + isChecked: false, + } + devicesMap.set(sn, device) + } - devicesMap.set(sn, device) isConnected.value = devicesMap.size > 0 } - const onlineCount = computed(() => { return Array.from(devicesMap.values()).filter(item => item.status === '在线') .length @@ -61,9 +66,6 @@ export const useTransferDataStore = defineStore('transfer', () => { .length }) - - - onMounted(() => { worker.subscribe(getDeviceTopic, getSubDevicesCb) checkDeviceStatus() @@ -84,14 +86,30 @@ export const useTransferDataStore = defineStore('transfer', () => { const device = devicesMap.get(sn) if (device) { device.upFirmware = 'updating' - const step = feedback[0] + const step = feedback[1] + const progress = feedback[2] || undefined + const errMsg = feedback[3] || undefined + if (step < (device.upFirmwareStatus?.step ?? -100)) return + device.upFirmwareStatus = { + step, + progress: progress === -1 ? 100 : progress, + errMsg, + } + } + } + + function upFirmwareStatusReject(sn: string, feedback: any[]) { + const device = devicesMap.get(sn) + if (device) { + device.upFirmware = 'rejected' + const step = feedback[1] const progress = feedback[2] || undefined const errMsg = feedback[3] || undefined if (step < (device.upFirmwareStatus?.step ?? -100)) return device.upFirmwareStatus = { step, - progress, - errMsg + progress: progress === -1 ? 100 : progress, + errMsg, } } } @@ -127,6 +145,14 @@ export const useTransferDataStore = defineStore('transfer', () => { } } + function upFirmwareTimeout(sn: string) { + const device = devicesMap.get(sn) + if (device) { + device.upFirmware = 'timeout' + device.upFirmwareStatus = undefined + } + } + return { isConnected, @@ -141,5 +167,7 @@ export const useTransferDataStore = defineStore('transfer', () => { upFirmwareReset, upFirmwareStatus, upFirmwareSucceed, + upFirmwareStatusReject, + upFirmwareTimeout } }) diff --git a/src/utils/zmq.ts b/src/utils/zmq.ts index 1867a72..8de081a 100644 --- a/src/utils/zmq.ts +++ b/src/utils/zmq.ts @@ -69,11 +69,11 @@ export interface SubMsgData { */ export function getPubTopic(type: TopicType, module: string,) { - return `web/${type}/${module}` + return `web/${type}/${module}/` } export function getSubTopic(server: string, type: TopicType, module: string,) { - return `${server}/${type}/${module}` + return `${server}/${type}/${module}/` } // 获取随机id diff --git a/src/utils/zmqJsonWorker.ts b/src/utils/zmqJsonWorker.ts index c6c0e9a..d57e3a0 100644 --- a/src/utils/zmqJsonWorker.ts +++ b/src/utils/zmqJsonWorker.ts @@ -5,7 +5,7 @@ import { WorkerCMD, ZmqCMD, type PublishMsg, type PubMsgData, } from './zmq' const HEARTBEAT_TOPIC = 'HEARTBEAT' const HEARTBEAT_INTERVAL = 3000 const STATUS_CHECK_INTERVAL = 1000 -let messageTimeout = 10000 +let messageTimeout = 5000 let heartClient: ZmqClient | null, subClient: ZmqClient | null, pubClient: ZmqClient | null let subHost = '', pubHost = '' @@ -78,8 +78,10 @@ function handleZmqMessage(topic: Uint8Array, msg: Uint8Array) { msg: jsonMessage }) const parsedMessage = JSON.parse(jsonMessage) as PubMsgData - if (parsedMessage.id && traceMessages.has(parsedMessage.id)) { - if (parsedMessage.result === 'progress') { + // traceMessages.get(parsedMessage.id) + const curTraceMessages = traceMessages.get(parsedMessage.id) + if (parsedMessage.id && !!curTraceMessages) { + if (curTraceMessages.isAlwaysListen || parsedMessage.result === 'progress') { // 重置消息超时时间 const val = traceMessages.get(parsedMessage.id) if (val) { @@ -106,7 +108,6 @@ function connect(host: string) { heartClient = new ZmqClient('sub') heartClient.zmqSub(subHost, updateHeartbeat) heartClient.subscribe(HEARTBEAT_TOPIC) - monitorConnection() pubHost = `ws://${host}:15556` @@ -131,7 +132,7 @@ function connect(host: string) { const traceMessages = new Map() self.onmessage = function (event) { - const { cmd, topic, msg, isTimeout = false } = event.data + const { cmd, topic, msg, isTimeout = false, isAlwaysListen } = event.data switch (cmd) { case WorkerCMD.START: @@ -152,7 +153,8 @@ self.onmessage = function (event) { const parseMsg = JSON.parse(msg) as PublishMsg traceMessages.set(parseMsg.id, { timestamp: Date.now(), - topic: topic + topic: topic, + isAlwaysListen, }) } pubClient?.publishStr(topic, msg) diff --git a/src/views/firmwareUpload/index.vue b/src/views/firmwareUpload/index.vue index ad07d80..a9c84d2 100644 --- a/src/views/firmwareUpload/index.vue +++ b/src/views/firmwareUpload/index.vue @@ -1,19 +1,9 @@