From 46cdda27d21f30b4e87018e76e438d11c75c7108 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Fri, 08 Aug 2025 15:38:03 +0800
Subject: [PATCH] feat: 下载逻辑

---
 src/page/index/index.vue                         |    1 
 src/page/index/useDownloadWs.js                  |   48 ++++++++
 src/views/device/addDevice.vue                   |    2 
 .env.jiangwu                                     |    4 
 .env.test                                        |    2 
 src/views/device/airport.vue                     |    8 
 src/utils/websocket/config.js                    |   11 +
 .env.development                                 |    8 
 /dev/null                                        |   19 ---
 src/views/dataCenter/components/searchData.vue   |   80 ++++++++++++-
 src/store/modules/common.js                      |    7 +
 .env.localhost                                   |    2 
 src/utils/util.js                                |   14 ++
 src/views/device/components/DockControlPanel.vue |   18 +-
 src/views/dataCenter/dataCenter.vue              |   15 +-
 .env.production                                  |    2 
 src/api/dataCenter/dataCenter.js                 |   17 ++
 src/utils/websocket/index.js                     |   76 ++++++++++++
 src/App.vue                                      |    3 
 src/utils/websocket/connect-websocket.js         |   16 ++
 20 files changed, 294 insertions(+), 59 deletions(-)

diff --git a/.env.development b/.env.development
index 1fbe070..e35d854 100644
--- a/.env.development
+++ b/.env.development
@@ -4,10 +4,10 @@
  # @LastEditors  : yuan
  # @LastEditTime : 2025-07-29 16:15:31
  # @FilePath     : \.env.development
- # @Description  : 
- # Copyright 2025 OBKoro1, All Rights Reserved. 
+ # @Description  :
+ # Copyright 2025 OBKoro1, All Rights Reserved.
  # 2025-07-29 15:59:42
-### 
+###
 NODE_ENV = 'development'
 
 #开发环境配置
@@ -30,7 +30,7 @@
 VITE_APP_AREA_NAME = https://wrj.shuixiongit.com
 
 # ws地址
-VITE_APP_WS_API_URL = wss://wrj.shuixiongit.com
+VITE_APP_WS_API_URL = wss://wrj.shuixiongit.com/drone-wss/api/v1/ws
 
 # 航线文件地址
 VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/minio/cloud-bucket
diff --git a/.env.jiangwu b/.env.jiangwu
index 72f4bc3..83fb5e5 100644
--- a/.env.jiangwu
+++ b/.env.jiangwu
@@ -22,7 +22,7 @@
 VITE_APP_DASHBOARD_URL = 'http://192.168.253.121:8080/command-center-dashboard/'
 
 # ws地址
-VITE_APP_WS_API_URL = ws://192.168.253.121:8080
+VITE_APP_WS_API_URL = ws://192.168.253.121:8080/drone-wss/api/v1/ws
 
 # 航线文件地址
 VITE_APP_AIRLINE_URL = http://192.168.253.121:9000/cloud-bucket
@@ -45,4 +45,4 @@
 VITE_APP_DEVICE_IP = '139.196.74.78:1883'
 
 VITE_APP_TDT_TOKEN = e110584a27d506da2740edca951683f4
-VITE_APP_CESIUM_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYTZlNGNlYS01NTU1LTQ1MGEtYmNlZS0yNTE2NDk5YWM2MjEiLCJpZCI6MTc5Njk2LCJpYXQiOjE3MDA1NDcwMjV9.qcl4AH2731cfFd0-I1ZLUINPXqvglLkDFD-UGR2zU5M
\ No newline at end of file
+VITE_APP_CESIUM_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYTZlNGNlYS01NTU1LTQ1MGEtYmNlZS0yNTE2NDk5YWM2MjEiLCJpZCI6MTc5Njk2LCJpYXQiOjE3MDA1NDcwMjV9.qcl4AH2731cfFd0-I1ZLUINPXqvglLkDFD-UGR2zU5M
diff --git a/.env.localhost b/.env.localhost
index e49eac7..258a5ec 100644
--- a/.env.localhost
+++ b/.env.localhost
@@ -20,7 +20,7 @@
 VITE_APP_AREA_NAME = http://192.168.1.227:80
 
 # ws地址
-VITE_APP_WS_API_URL = wss://192.168.1.227:80
+VITE_APP_WS_API_URL = wss://192.168.1.227:80/drone-wss/api/v1/ws
 
 # 航线文件地址
 VITE_APP_AIRLINE_URL = http://192.168.1.227:80/minio/cloud-bucket
diff --git a/.env.production b/.env.production
index 0ff225a..97e2aff 100644
--- a/.env.production
+++ b/.env.production
@@ -22,7 +22,7 @@
 VITE_APP_DASHBOARD_URL = 'https://aisky.org.cn/command-center-dashboard/'
 
 # ws地址
-VITE_APP_WS_API_URL = wss://aisky.org.cn
+VITE_APP_WS_API_URL = wss://aisky.org.cn/drone-wss/api/v1/ws
 
 # 航线文件地址
 VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket
diff --git a/.env.test b/.env.test
index 06a3d3c..6e5f172 100644
--- a/.env.test
+++ b/.env.test
@@ -20,7 +20,7 @@
 VITE_APP_AREA_NAME = https://wrj.shuixiongit.com
 
 # ws地址
-VITE_APP_WS_API_URL = wss://wrj.shuixiongit.com
+VITE_APP_WS_API_URL = wss://wrj.shuixiongit.com/drone-wss/api/v1/ws
 
 # 航线文件地址
 VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/minio/cloud-bucket
diff --git a/src/App.vue b/src/App.vue
index 24cea39..066092b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -2,7 +2,10 @@
   <router-view />
 </template>
 
+
 <script setup>
+import { useDownloadWs } from '@/page/index/useDownloadWs';
+useDownloadWs()
 </script>
 
 <style>
diff --git a/src/api/dataCenter/dataCenter.js b/src/api/dataCenter/dataCenter.js
index 2c0a1a4..996ac7f 100644
--- a/src/api/dataCenter/dataCenter.js
+++ b/src/api/dataCenter/dataCenter.js
@@ -35,6 +35,23 @@
 		data
 	})
 }
+
+// 查询下载状态
+export const getDownloadStatusApi = (data) => {
+	return request({
+		url: `/blade-resource/attach/getDownloadStatus`,
+		method: 'post',
+		data
+	})
+}
+// 取消下载
+export const cancelDownloadApi = (data) => {
+	return request({
+		url: `/blade-resource/attach/cancelDownload`,
+		method: 'post',
+		data
+	})
+}
 // 地图
 export const getMapInfoAPI = (jobId) => {
     return request({
diff --git a/src/event-bus/index.js b/src/event-bus/index.js
deleted file mode 100644
index 3b59d14..0000000
--- a/src/event-bus/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * @Author: shuishen 1109946754@qq.com
- * @Date: 2024-09-10 11:43:39
- * @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2024-09-10 11:44:09
- * @FilePath: \drone-web-manage\src\event-bus\index.js
- * @Description:
- *
- * Copyright (c) 2024 by shuishen, All Rights Reserved.
- */
-import mitt from 'mitt';
-
-const emitter = mitt();
-export default emitter;
diff --git a/src/hooks/use-connect-websocket.js b/src/hooks/use-connect-websocket.js
deleted file mode 100644
index 0c92ea3..0000000
--- a/src/hooks/use-connect-websocket.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import { onMounted, onUnmounted } from "vue"
-import ConnectWebSocket from "@/websocket"
-import { getWebsocketUrl } from "@/websocket/util/config"
-
-/**
- * 接收一个message函数
- * @param messageHandler
- */
-export function useConnectWebSocket(messageHandler, url) {
-  const webSocket = new ConnectWebSocket(url || getWebsocketUrl())
-
-  onMounted(() => {
-    webSocket?.registerMessageHandler(messageHandler)
-    webSocket?.initSocket()
-  })
-
-  onUnmounted(() => {
-    webSocket?.close()
-  })
-}
diff --git a/src/page/index/index.vue b/src/page/index/index.vue
index c0b819c..c761232 100644
--- a/src/page/index/index.vue
+++ b/src/page/index/index.vue
@@ -27,7 +27,6 @@
     <!-- <wechat></wechat> -->
   </div>
 </template>
-
 <script>
 import index from '@/mixins/index'
 import wechat from './wechat.vue'
diff --git a/src/page/index/useDownloadWs.js b/src/page/index/useDownloadWs.js
new file mode 100644
index 0000000..d39324d
--- /dev/null
+++ b/src/page/index/useDownloadWs.js
@@ -0,0 +1,48 @@
+import { getWebsocketUrl } from '@/utils/websocket/config'
+import { useConnectWebSocket } from '@/utils/websocket/connect-websocket'
+import { useStore } from 'vuex'
+import dayjs from 'dayjs'
+import { aLinkDownloadUtil } from '@/utils/util'
+import EventBus from '@/utils/eventBus'
+import { computed, onBeforeUnmount, onMounted } from 'vue';
+import { setStore,getStore } from '@/utils/store';
+import { getDownloadStatusApi } from '@/api/dataCenter/dataCenter';
+
+export const useDownloadWs = () => {
+	const store = useStore()
+	const loginUserInfo = computed(() => store.state.user.userInfo)
+	const downloadProgress = computed(() => store.state.common.downloadProgress)
+	let currentWebSocket = null
+	function messageHandler(payload) {
+		const {type,status,progress,download_url} = payload
+		const setProgress = status === 'CANCELLED'
+			? 100
+			: (status !== 'COMPLETED' && progress === 100) ? 99 : progress
+		store.commit('setDownloadProgress', {
+			...downloadProgress.value,
+			[type]: setProgress,
+		})
+		if (status === 'COMPLETED' && ['htsjzx','htlsrwxq'].includes(type)) {
+			const name = `数据中心-${dayjs().format('YYYYMMDDHHmmss')}.zip`
+			const currentUrl = getStore({name: 'downloadUrl'})
+			if (currentUrl === download_url && download_url!== undefined) return
+			aLinkDownloadUtil(download_url, name)
+			setStore({ name: 'downloadUrl', content: download_url })
+		}
+	}
+
+	onMounted(() => {
+		let webSocketUrl = getWebsocketUrl() + `&model_type=3&workspace-id=${loginUserInfo.value.user_id}`
+		currentWebSocket = useConnectWebSocket((result)=>{
+			const payload = JSON.parse(result)
+			messageHandler(payload.data)
+		}, webSocketUrl)
+		EventBus.on('useDownloadWs-messageHandler',messageHandler)
+	})
+
+	onBeforeUnmount(() => {
+		currentWebSocket?.close()
+		EventBus.off('useDownloadWs-messageHandler',messageHandler)
+	})
+	return {}
+}
diff --git a/src/store/modules/common.js b/src/store/modules/common.js
index 146f8cf..46f4fb2 100644
--- a/src/store/modules/common.js
+++ b/src/store/modules/common.js
@@ -15,8 +15,15 @@
     lockPasswd: getStore({ name: 'lockPasswd' }) || '',
     website: website,
     setting: website.setting,
+    downloadProgress:{
+      htsjzx: 100, //数据中心
+      htlsrwxq: 100, //历史任务详情
+    }
   },
   mutations: {
+    setDownloadProgress(state, data) {
+      state.downloadProgress = data
+    },
     SET_LANGUAGE: (state, language) => {
       state.language = language;
       setStore({
diff --git a/src/utils/util.js b/src/utils/util.js
index f2b2e09..325dcc5 100644
--- a/src/utils/util.js
+++ b/src/utils/util.js
@@ -477,4 +477,16 @@
     }
   }
   return newObj
-}
\ No newline at end of file
+}
+
+// a链接直接下载
+export const aLinkDownloadUtil = (url, name) => {
+  let a = document.createElement('a')
+  a.style.display = 'none'
+  a.href = url
+  a.download = name
+  document.body.appendChild(a)
+  a.click()
+  document.body.removeChild(a)
+  a = null
+}
diff --git a/src/utils/websocket/config.js b/src/utils/websocket/config.js
new file mode 100644
index 0000000..9eca663
--- /dev/null
+++ b/src/utils/websocket/config.js
@@ -0,0 +1,11 @@
+import { getToken } from '@/utils/auth';
+
+export function getWebsocketUrl() {
+  const token = getToken() || '';
+  return import.meta.env.VITE_APP_WS_API_URL + '?x-auth-token=' + encodeURI(token);
+}
+// AI 指令飞行
+export function getAIWebsocketUrl() {
+	const token = getToken() || ''
+	return `${import.meta.env.VITE_APP_WS_API_URL}?x-auth-token=${encodeURI(token)}`;
+}
diff --git a/src/utils/websocket/connect-websocket.js b/src/utils/websocket/connect-websocket.js
new file mode 100644
index 0000000..5b36316
--- /dev/null
+++ b/src/utils/websocket/connect-websocket.js
@@ -0,0 +1,16 @@
+import ConnectWebSocket from '@/utils/websocket/index'
+import { getWebsocketUrl } from '@/utils/websocket/config'
+
+/**
+ * 接收一个message函数
+ * @param messageHandler
+ * @param url
+ */
+export function useConnectWebSocket(messageHandler, url) {
+	const webSocket = new ConnectWebSocket(url || getWebsocketUrl())
+
+	webSocket?.registerMessageHandler(messageHandler)
+	webSocket?.initSocket()
+
+	return webSocket
+}
diff --git a/src/utils/websocket/index.js b/src/utils/websocket/index.js
new file mode 100644
index 0000000..48e79d6
--- /dev/null
+++ b/src/utils/websocket/index.js
@@ -0,0 +1,76 @@
+import ReconnectingWebSocket from 'reconnecting-websocket'
+
+/**
+ * ConnectWebSocket 类
+ * TODO: 优化messageHandler: EventEmitter。暂时传入回调函数
+ */
+
+class ConnectWebSocket {
+	_url
+	_socket
+	_hasInit
+	_messageHandler
+
+	constructor(url) {
+		this._url = url
+		this._socket = null
+		this._hasInit = false
+		this._messageHandler = null
+	}
+
+	initSocket() {
+		if (this._hasInit) {
+			return
+		}
+		if (!this._url) {
+			return
+		}
+		// 会自动重连,无需处理重连逻辑
+		this._socket = new ReconnectingWebSocket(this._url, [], {
+			maxReconnectionDelay: 20000, // 断开后最大的重连时间: 20s,每多一次重连,会增加 1.3 倍,5 * 1.3 * 1.3 * 1.3...
+			minReconnectionDelay: 5000, // 断开后最短的重连时间: 5s
+			maxRetries: 5,
+		})
+		this._hasInit = true
+
+		this._socket.addEventListener('open', this._onOpen.bind(this))
+		this._socket.addEventListener('close', this._onClose.bind(this))
+		this._socket.addEventListener('error', this._onError.bind(this))
+		this._socket.addEventListener('message', this._onMessage.bind(this))
+	}
+
+	_onOpen() {
+		console.log('ws连接成功')
+	}
+
+	_onClose() {
+		console.log('ws连接已断开')
+	}
+
+	_onError() {
+		console.log('ws连接 error')
+	}
+
+	registerMessageHandler(messageHandler) {
+		this._messageHandler = messageHandler
+	}
+
+	_onMessage(msg) {
+		// const data = JSON.parse(msg.data);
+		this._messageHandler && this._messageHandler(msg.data)
+	}
+
+	sendMessage = message => {
+		// 目前只供AI聊天使用
+		this._socket?.send(message)
+		// this._socket?.send(JSON.stringify(message.data));
+	}
+
+	close() {
+		this._socket?.close()
+		this._messageHandler = null
+		this._socket = null
+	}
+}
+
+export default ConnectWebSocket
diff --git a/src/views/dataCenter/components/searchData.vue b/src/views/dataCenter/components/searchData.vue
index 2c4d8c2..eba767a 100644
--- a/src/views/dataCenter/components/searchData.vue
+++ b/src/views/dataCenter/components/searchData.vue
@@ -101,12 +101,18 @@
       </div>
       <div class="search-first">
         <div class="search-btn">
-          <el-button type="primary" icon="el-icon-download" @click="allDownloadFun"
-            >全部下载</el-button
-          >
-          <el-button type="success" plain icon="el-icon-download" @click="downloadFun"
-            >下载</el-button
-          >
+<!--          <el-button type="primary" icon="el-icon-download" @click="allDownloadFun"-->
+<!--            >全部下载</el-button-->
+<!--          >-->
+          <div class="downloadBtn" @click="htsjzx === 100 && downloadFun()">
+            <el-progress v-if="htsjzx !== 100" :percentage="htsjzx" :show-text="false" striped striped-flow :duration="1" />
+            <div class="downloadBtnText">
+              <span v-if="htsjzx === 100">下载</span>
+              <template v-else>
+                处理中<el-icon @click="cancelDownload"><CircleClose /></el-icon>
+              </template>
+            </div>
+          </div>
         </div>
       </div>
     </el-form>
@@ -120,9 +126,13 @@
 import { useStore } from 'vuex';
 import { getRegionTreeAll, getDeviceRegion, deptsByAreaCode } from '@/api/job/task';
 import { watch } from 'vue';
+import { cancelDownloadApi, getDownloadStatusApi } from '@/api/dataCenter/dataCenter';
+import EventBus from '@/utils/eventBus';
 const store = useStore();
 const userAreaCode = computed(() => store.getters.userInfo.detail.areaCode);
 const selectedAreaCode = computed(() => store.state.user.selectedAreaCode);
+const htsjzx = computed(() => store.state.common.downloadProgress?.htsjzx || 100)
+
 const emit = defineEmits(['search', 'downFun', 'allDownFun']);
 const startTime = dayjs().subtract(6, 'day').startOf('day');
 const endTime = dayjs().endOf('day');
@@ -165,7 +175,7 @@
   {
     value: '5',
     label: '全景',
-    
+
   },
   {
     value: '4',
@@ -301,8 +311,20 @@
 const allDownloadFun = () => {
   emit('allDownFun');
 };
+
+function cancelDownload() {
+  cancelDownloadApi({ type:'htsjzx' }).then(res =>{
+    ElMessage.success('取消成功')
+  })
+}
+
 onMounted(() => {
   requestDockInfo();
+  getDownloadStatusApi({type: 'htsjzx'}).then(res =>{
+    if (!['CANCELLED','COMPLETED'].includes(res.data.data?.status || 'COMPLETED')){
+      EventBus.emit('useDownloadWs-messageHandler',res.data.data)
+    }
+  })
 });
 </script>
 
@@ -320,6 +342,50 @@
 
     .search-btn {
       margin-right: 32px;
+
+      .downloadBtn{
+        position: relative;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 28px;
+        padding: 0 15px;
+        background: rgb(239.8,248.9,235.3);
+        border-radius: 4px 4px 4px 4px;
+        border: 1px solid rgb(179,224.5,156.5);
+        cursor: pointer;
+        color: #67c23a;
+        font-size: 14px;
+
+        .downloadBtnText{
+          display: flex;
+          align-items: center;
+          gap: 5px;
+          z-index: 5;
+        }
+        .el-progress{
+          height: 100%;
+          position: absolute;
+          left: 0;
+          top: 0;
+          width: 100%;
+
+          :deep(){
+            .el-progress-bar__outer{
+              height: 26px !important;
+              border-radius: 0 !important;
+              background: transparent !important;
+
+              .el-progress-bar__inner{
+                border-radius: 0 !important;
+                background-color: #e5ffd9;
+              }
+            }
+          }
+        }
+
+      }
+
     }
     .time-card {
       text-align: center;
diff --git a/src/views/dataCenter/dataCenter.vue b/src/views/dataCenter/dataCenter.vue
index 7acdbd8..6fa651d 100644
--- a/src/views/dataCenter/dataCenter.vue
+++ b/src/views/dataCenter/dataCenter.vue
@@ -306,7 +306,7 @@
   deleteFileMultipleApi,
   downloadApi,
   updataTitleApi,
-  getOrthoimageInfo,
+  getOrthoimageInfo, getDownloadStatusApi
 } from '@/api/dataCenter/dataCenter';
 import { getShowImg, getSmallImg, getzsSmallImg } from '@/utils/util';
 import { onMounted, watch } from 'vue';
@@ -482,7 +482,7 @@
   a.click();
   document.body.removeChild(a);
 }
-const fileDownload = () => {
+const fileDownload = async () => {
   const list = selectedRows.value.filter(i => i.checked);
   if (!list?.length) return ElMessage.warning('请选择文件');
   if (list.length === 1) {
@@ -503,11 +503,14 @@
       jobName: '',
       resultType: '',
       startTime: '',
-      wayLineJobIds: [],
+      type:'htsjzx'
     };
-
-    downloadApi(aaa).then(res => {
-      aLinkDownload(res.data.data, `sjzx-file-pack-${dayjs().format('YYYYMMDDHHmmss')}.zip`);
+    const res = await getDownloadStatusApi({type: 'htsjzx'})
+    if (!['CANCELLED','COMPLETED'].includes(res.data.data?.status || 'COMPLETED')){
+      loading.close()
+      return ElMessage.warning('还有正在处理的')
+    }
+    downloadApi(aaa).finally(res => {
       loading.close();
     });
   }
diff --git a/src/views/device/addDevice.vue b/src/views/device/addDevice.vue
index b4d7684..f55d3af 100644
--- a/src/views/device/addDevice.vue
+++ b/src/views/device/addDevice.vue
@@ -27,8 +27,6 @@
 import { getLazyTree } from '@/api/base/region'
 
 import { mapGetters } from 'vuex'
-import { getWebsocketUrl } from '@/websocket/util/config'
-import ConnectWebSocket from '@/websocket'
 import { $Clipboard } from "@smallwei/avue"
 
 
diff --git a/src/views/device/airport.vue b/src/views/device/airport.vue
index eb61ea9..ac96407 100644
--- a/src/views/device/airport.vue
+++ b/src/views/device/airport.vue
@@ -154,8 +154,8 @@
 import FirmwareManage from './components/firmwareManage.vue'
 import DevicePerShare from './components/devicePerShare.vue'
 import DockControlPanel from './components/DockControlPanel.vue'
-import { getWebsocketUrl } from '@/websocket/util/config'
-import ConnectWebSocket from '@/websocket'
+import { getWebsocketUrl } from '@/utils/websocket/config';
+import ConnectWebSocket from '@/utils/websocket';
 export default {
   components: {
     FirmwareManage,
@@ -584,10 +584,10 @@
         this.webSocketIdSet.add(webSocketId)
         const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + data.workspace_id
         // 监听ws 消息
-        this.useConnectWebSocket(webSocketId, webSorketUrl)
+        this.useConnectWebSocket1(webSocketId, webSorketUrl)
       }
     },
-    useConnectWebSocket (webSocketId, url) {
+    useConnectWebSocket1 (webSocketId, url) {
       const websocket = new ConnectWebSocket(url)
       // 加入 webscoket map
       this.websocketMap.set(webSocketId, websocket)
diff --git a/src/views/device/components/DockControlPanel.vue b/src/views/device/components/DockControlPanel.vue
index 6a8d389..af1a16e 100644
--- a/src/views/device/components/DockControlPanel.vue
+++ b/src/views/device/components/DockControlPanel.vue
@@ -77,10 +77,7 @@
 
 <script setup>
 import { ElMessage } from 'element-plus';
-import EventBus from '@/event-bus'
 import { EBizCode, ELocalStorageKey, ERouterName } from '@/types'
-import { useConnectWebSocket } from '@/hooks/use-connect-websocket'
-import { getWebsocketUrl } from '@/websocket/util/config'
 import { defineProps, ref, watch, reactive } from 'vue'
 import { cmdList as baseCmdList } from '@/types/device-cmd'
 import { useDockControl } from './use-dock-control'
@@ -89,6 +86,9 @@
 import { setThermalCurrentPaletteStyle, setPhotoStorageSet, setVideoStorageSet, getLiveStatus, setStreamsSwitch, photoAndVideoCmd } from '@/api/device-setting'
 
 import Store from '@/store'
+import { useConnectWebSocket } from '@/utils/websocket/connect-websocket';
+import { getWebsocketUrl } from '@/utils/websocket/config';
+import EventBus from '@/utils/eventBus';
 
 const valueStyle = ref(0)
 const cameraModeValue = ref(0)
@@ -248,6 +248,9 @@
   }
 )
 onMounted(() => {
+  const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + props.deviceInfo.workspace_id
+  // 监听ws 消息
+  useConnectWebSocket(messageHandler, webSorketUrl)
   getLiveStatuss()
 });
 
@@ -292,13 +295,11 @@
     action: cmdItem.action,
   }
   const success = await sendDockControlCmd(params, true)
-  if (success) {
-    updateDeviceSingleCmdInfo(cmdList.value[index])
-  }
 }
 
 // webSocket 监听
 const messageHandler = async payload => {
+  payload = JSON.parse(payload)
   if (!payload) {
     return
   }
@@ -384,9 +385,6 @@
   }
 }
 
-const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + props.deviceInfo.workspace_id
-// 监听ws 消息
-useConnectWebSocket(messageHandler, webSorketUrl)
 
 // 添加 changs 方法
 async function changs(value, item) {
@@ -532,4 +530,4 @@
     }
   }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/websocket/index.js b/src/websocket/index.js
deleted file mode 100644
index 6f4bfe8..0000000
--- a/src/websocket/index.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * @Author: shuishen 1109946754@qq.com
- * @Date: 2024-09-09 19:13:20
- * @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2024-09-09 19:14:05
- * @FilePath: \drone-web-manage\src\websocket\index.js
- * @Description: 
- * 
- * Copyright (c) 2024 by shuishen, All Rights Reserved. 
- */
-import ReconnectingWebSocket from "reconnecting-websocket"
-
-/**
- * ConnectWebSocket 类
- * TODO: 优化messageHandler: EventEmitter。暂时传入回调函数
- */
-class ConnectWebSocket {
-  constructor(url) {
-    this._url = url
-    this._socket = null
-    this._hasInit = false
-    this._messageHandler = null
-  }
-
-  initSocket() {
-    if (this._hasInit) {
-      return
-    }
-    if (!this._url) {
-      return
-    }
-    // 会自动重连,无需处理重连逻辑
-    this._socket = new ReconnectingWebSocket(this._url, [], {
-      maxReconnectionDelay: 20000, // 断开后最大的重连时间: 20s,每多一次重连,会增加 1.3 倍,5 * 1.3 * 1.3 * 1.3...
-      minReconnectionDelay: 5000, // 断开后最短的重连时间: 5s
-      maxRetries: 5
-    })
-    this._hasInit = true
-
-    this._socket.addEventListener("open", this._onOpen.bind(this))
-    this._socket.addEventListener("close", this._onClose.bind(this))
-    this._socket.addEventListener("error", this._onError.bind(this))
-    this._socket.addEventListener("message", this._onMessage.bind(this))
-  }
-
-  _onOpen() {
-    console.log("连接成功")
-  }
-
-  _onClose() {
-    console.log("连接已断开")
-  }
-
-  _onError() {
-    console.log("连接 error")
-  }
-
-  registerMessageHandler(messageHandler) {
-    this._messageHandler = messageHandler
-  }
-
-  _onMessage(msg) {
-    const data = JSON.parse(msg.data)
-    this._messageHandler && this._messageHandler(data)
-    // console.log('接受消息', msg)
-  }
-
-  sendMessage = message => {
-    this._socket?.send(JSON.stringify(message.data))
-  }
-
-  close() {
-    this._socket?.close()
-  }
-}
-
-export default ConnectWebSocket
diff --git a/src/websocket/util/config.js b/src/websocket/util/config.js
deleted file mode 100644
index f4a70a9..0000000
--- a/src/websocket/util/config.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * @Author: shuishen 1109946754@qq.com
- * @Date: 2024-09-09 19:13:20
- * @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2024-09-09 19:14:36
- * @FilePath: \drone-web-manage\src\websocket\util\config.ts
- * @Description:
- *
- * Copyright (c) 2024 by shuishen, All Rights Reserved.
- */
-
-import { getToken } from '@/utils/auth';
-
-export function getWebsocketUrl() {
-  const token = getToken();
-  // const url = CURRENT_CONFIG.websocketURL
-  const url = `${import.meta.env.VITE_APP_WS_API_URL}/drone-wss/api/v1/ws?x-auth-token=${encodeURI(token)}`;
-  return url;
-}

--
Gitblit v1.9.3