From 980017c9508f8b8449e773d8913b3b407f0a3416 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Fri, 18 Apr 2025 08:44:13 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/drone/command-center-dashboard

---
 src/utils/stateToImageMap/event.js                              |   23 
 src/hooks/components/useMapHandlerClick.js                      |   89 ++
 src/hooks/components/EventPopUpBox.vue                          |   16 
 src/api/drc.js                                                  |    9 
 src/views/SignMachineNest/MachineRight/MachineMonitor.vue       |  135 ++--
 src/api/payload.js                                              |   11 
 src/views/SignMachineNest/SignMachineNest.vue                   |    1 
 src/components/CurrentTaskDetails/TaskDetailsLeft.vue           |   21 
 src/hooks/useMapAggregation/useMapAggregation.js                |  139 +----
 src/views/Home/SearchBox.vue                                    |  442 ++++++++--------
 src/components/CurrentTaskDetails/CurrentTaskDetails.vue        |   21 
 src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue |  404 +++++++-------
 src/hooks/useSingleDroneMap/useSingleDroneMap.js                |  135 ----
 src/hooks/controlDrone/useManualControl.js                      |  130 +++-
 src/mqtt/index.js                                               |    2 
 src/utils/stateToImageMap/drone.js                              |   32 +
 src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue |    1 
 src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue  |    1 
 src/components/CurrentTaskDetails/TaskDetailsRight.vue          |    4 
 19 files changed, 838 insertions(+), 778 deletions(-)

diff --git a/src/api/drc.js b/src/api/drc.js
index 674f8c7..9706b3f 100644
--- a/src/api/drc.js
+++ b/src/api/drc.js
@@ -30,6 +30,15 @@
   })
 }
 
+// 无人控制
+export async function updateDroneQualityApi (data) {
+  return request({
+    url: '/drone-device-core/manage/api/v1/live/streams/update',
+    method: 'post',
+    data,
+  })
+}
+
 // 无人机退出控制
 export async function exitController(data) {
   return request({
diff --git a/src/api/payload.js b/src/api/payload.js
index 61e91ea..77b9be3 100644
--- a/src/api/payload.js
+++ b/src/api/payload.js
@@ -53,12 +53,21 @@
 // 相机参数调整
 export async function cameraParamsChangeApi(data) {
   return await request({
-    url:`/drone-device-core/payload-control/payload/zoom/level`,
+    url:`${API_PREFIX}/devices/payload-control/payload/zoom/level`,
     method:'post',
     data
   })
 }
 
+// 云台重置
+export async function ptzResetModeApi(params) {
+  return await request({
+    url:`${API_PREFIX}/devices/payload-control/payload/reset`,
+    method:'get',
+    params
+  })
+}
+
 
 
 // 切换直播镜头
diff --git a/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue b/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue
index fd914f6..b682f14 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue
@@ -55,6 +55,7 @@
 }
 
 function turnBack() {
+	isAutoControl.value = true
 	EventBus.emit('controlPanel-returnOrCancelReturn')
 }
 </script>
diff --git a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
index d78a55a..546ab80 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
@@ -88,6 +88,7 @@
 						:style="item.style"
 						class="ptzControlItem"
 						@mousedown="onMouseDown(item.key)"
+						@mouseup="onMouseUp"
 					></div>
 
 					<div
diff --git a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
index 8d51880..c93ba94 100644
--- a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
+++ b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -18,8 +18,8 @@
 			<TaskDetailsRight v-if="isAutoControl" />
 			<template v-else>
 				<TaskDetailsHead />
+				<TaskDetailsLeft />
 			</template>
-			<TaskDetailsLeft />
 
 			<!--	控制面板,里面有方法需要立即执行,不可用v-if		-->
 			<ControlPanel v-show="!isAutoControl" />
@@ -45,7 +45,7 @@
 import amplifyImg from '@/assets/images/taskManagement/taskIntermediateContent/amplifyImg.png'
 import { ElMessage } from 'element-plus'
 import EventBus from '@/event-bus'
-
+import { updateDroneQualityApi } from '@/api/drc'
 
 const isAutoControl = ref(true)
 const lineQuality = ref(1) //1流畅,2标清
@@ -67,7 +67,7 @@
 const currentLiveUrl = ref('')
 const isTakeOff = ref(false)
 const isMaxMap = ref(false)
-let droneWebSocket  //WS实例
+let droneWebSocket //WS实例
 
 // 机巢直播
 const getDeviceLiveUrl = async () => {
@@ -75,10 +75,19 @@
 	currentLiveUrl.value = res.data.data.rtcs_url
 }
 
-// 无人机直播画质切换
-const changeLineQuality = async () => {
+const video_id = ref('')
+
+// 获取无人机直播url
+async function getDroneLiveUrl() {
 	const res = await liveStart(droneSn.value, lineQuality.value)
 	currentLiveUrl.value = res.data.data.rtcs_url
+	video_id.value = res.data.data.video_id
+}
+
+// 无人机直播画质切换
+const changeLineQuality = async () => {
+	const res = await updateDroneQualityApi({ video_id: video_id.value, video_quality: lineQuality.value })
+	ElMessage.success('切换画质成功')
 }
 
 // 设置当前直播地址
@@ -89,7 +98,7 @@
 	// 如果还是之前的状态,不切换
 	if (isTakeOff.value === currentIsTakeOff) return
 	isTakeOff.value = currentIsTakeOff
-	isTakeOff.value ? await changeLineQuality() : await getDeviceLiveUrl()
+	isTakeOff.value ? await getDroneLiveUrl() : await getDeviceLiveUrl()
 }
 
 // 获取任务详情获取航线文件
diff --git a/src/components/CurrentTaskDetails/TaskDetailsLeft.vue b/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
index 812bd86..861e33f 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
@@ -11,8 +11,8 @@
 			{{ item.name }}相机
 		</div>
 		<div class="multiCol">
-			<div @click="faceToCenter">云台回中</div>
-			<div @click="faceToDown">云台朝下</div>
+			<div @click="ptzResetMode(0)">云台回中</div>
+			<div @click="ptzResetMode(1)">云台朝下</div>
 		</div>
 		<el-select class="qualityChange" v-model="lineQuality" @change="qualityChange">
 			<el-option v-for="item in qualityList" :key="item.id" :label="item.name" :value="item.id" />
@@ -30,8 +30,9 @@
 			<el-slider
 				v-model="cameraParams.zoom_factor"
 				vertical
-				:max="cameraParams.camera_type === 'ir' ? 20 : 50"
-				@input="sliderChange"
+				:min="cameraParams.camera_type === 'ir' ? 2 : 0"
+				:max="cameraParams.camera_type === 'ir' ? 200 : 200"
+				@change="sliderChange"
 			/>
 		</div>
 	</div>
@@ -39,7 +40,7 @@
 
 <script setup>
 import EventBus from '@/event-bus'
-import { callPhotoAndVideoCmd, cameraParamsChangeApi } from '@/api/payload'
+import { callPhotoAndVideoCmd, cameraParamsChangeApi, ptzResetModeApi } from '@/api/payload'
 import { ElMessage } from 'element-plus'
 import { throttle } from 'lodash'
 
@@ -65,9 +66,9 @@
 	{ name: '超清', id: 4 },
 ]
 
-function faceToCenter() {}
-
-function faceToDown() {}
+function ptzResetMode(resetMode) {
+	ptzResetModeApi({ sn: dockSn.value, resetMode })
+}
 
 // 倍率调整
 function sliderChange(val) {
@@ -82,9 +83,11 @@
 
 // 修改相机参数
 function cameraParamsChange() {
+	const { camera_type, zoom_factor} = cameraParams.value
 	cameraParamsChangeApi({
 		sn: dockSn.value,
 		...cameraParams.value,
+		zoom_factor: camera_type === 'wide' ? undefined : zoom_factor,
 	})
 }
 
@@ -97,7 +100,7 @@
 		cameraParams.value.zoom_factor = 5
 	}
 	if (row.key === 'ir') {
-		cameraParams.value.zoom_factor = 0
+		cameraParams.value.zoom_factor = 2
 	}
 	cameraParamsChange()
 }
diff --git a/src/components/CurrentTaskDetails/TaskDetailsRight.vue b/src/components/CurrentTaskDetails/TaskDetailsRight.vue
index 32105be..61b2189 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsRight.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsRight.vue
@@ -54,6 +54,10 @@
 	gap: 25px 0;
 	align-items: center;
 
+	.manualControl{
+		background: transparent !important;
+	}
+
 	.titleImg {
 		width: 224px;
 		height: 131px;
diff --git a/src/hooks/components/EventPopUpBox.vue b/src/hooks/components/EventPopUpBox.vue
index 5a50e29..ddee5be 100644
--- a/src/hooks/components/EventPopUpBox.vue
+++ b/src/hooks/components/EventPopUpBox.vue
@@ -31,7 +31,7 @@
 	</div>
 </template>
 <script setup>
-import { ElImage } from 'element-plus'
+import { ElImage, ElIcon } from 'element-plus'
 
 // src="@/assets/images/home/useEventOperate/eventErr.png"
 import { Close } from '@element-plus/icons-vue'
@@ -54,10 +54,20 @@
 	loading.value = true
 	const res = await getEventDetails({ id: props.data.eventId })
 	info.value = res.data.data
-
-	info.value.url = import.meta.env.VITE_APP_AIRLINE_URL + info.value.url
+	info.value.url = disposeUrl(info.value)
 	loading.value = false
 })
+
+const disposeUrl = ({ url, media_type }) => {
+	if (media_type == 'PHOTO_TYPE') {
+		const parts = url.split('.')
+		parts[parts.length - 2] += '_small' // 在最后一个点前插入 _small
+
+		return import.meta.env.VITE_APP_AIRLINE_URL + parts.join('.')
+	}
+
+	return import.meta.env.VITE_APP_AIRLINE_URL + url
+}
 </script>
 
 <style scoped lang="scss">
diff --git a/src/hooks/components/useMapHandlerClick.js b/src/hooks/components/useMapHandlerClick.js
index a4854ce..82d59c5 100644
--- a/src/hooks/components/useMapHandlerClick.js
+++ b/src/hooks/components/useMapHandlerClick.js
@@ -2,33 +2,72 @@
  * @Author: shuishen 1109946754@qq.com
  * @Date: 2025-04-15 22:41:40
  * @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2025-04-16 19:02:39
+ * @LastEditTime: 2025-04-17 19:43:36
  * @FilePath: \command-center-dashboard\src\hooks\components\useMapHandlerClick.js
  * @Description: 
  * 
  * Copyright (c) 2025 by shuishen, All Rights Reserved. 
  */
 import * as Cesium from 'cesium'
+import { render } from 'vue'
+import { useStore } from 'vuex'
+
+import DevicePopUpBox from '@/hooks/components/DevicePopUpBox.vue'
 import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue'
 
 /**
  * 
  * @param {Object} options - 配置选项
  */
-export function useMapHandlerClick (viewer, options = {
-  type: 'single-drone-event',
-  customDom: EventPopUpBox
-}) {
-  const { type } = options
+export function useMapHandlerClick (options = {}) {
+  const {
+    popupType = 'event-popup',
+    eventType = 'single-drone-event',
+    styleTransform = 'translate(-50%,-110%)',
+    getViewer
+  } = options
 
-  const currentClickEntity = ref(null)
+  const store = useStore()
+
+  const popupData = {
+    'event-popup': EventPopUpBox,
+    'device-popup': DevicePopUpBox
+  }
+
+  const MapPopUpBox = popupData[popupType]
+
+  let viewer = null
   let handler = null
+  let currentClickEntity = null
 
   // 查找特定类型的实体
   const findEntityByType = (entities, type) => {
-    return entities.find(entity =>
-      entity?.properties?.customData?._value?.data?.type === type
-    )
+    let types = []
+
+    Array.isArray(type) ? types = type : types = [type]
+
+    return types.reduce((pre, curType) => {
+      let entity = entities.find(entity => entity?.properties?.customData?._value?.data?.type === curType)
+
+      return entity ? (pre.push({
+        type: curType,
+        entity
+      }), pre) : pre
+    }, [])
+  }
+
+  const publicEvent = (entity) => {
+    viewer.scene.postRender.addEventListener(labelBoxRender)
+  }
+
+  const typeEvent = {
+    'deviceAggregation': publicEvent,
+    'single-drone-event': publicEvent,
+    'event': publicEvent,
+    'device': (entity) => {
+      const device = entity.properties.customData._value.data
+      store.commit('setSingleUavHome', device)
+    }
   }
 
   // 左键单机事件
@@ -36,17 +75,21 @@
     let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id)
     if (!clickedEntities.length) return
 
-    currentClickEntity.value = findEntityByType(clickedEntities, type)
+    let curClick = findEntityByType(clickedEntities, eventType)
 
     removeLabel()
 
-    if (currentClickEntity.value) {
-      viewer?.scene.postRender.addEventListener(labelBoxRender)
+    if (curClick.length > 0 && typeEvent[curClick[0].type]) {
+      currentClickEntity = curClick[0].entity
+
+      typeEvent[curClick[0].type](currentClickEntity)
     }
   }
 
   // 事件初始化
   const handlerInit = () => {
+    !viewer && (viewer = getViewer())
+
     if (handler) return
 
     handler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
@@ -62,7 +105,7 @@
 
   // 获取弹框box
   const getLabelDom = data => {
-    const vNode = h(customDom, { data, removeLabel })
+    const vNode = h(MapPopUpBox, { data, removeLabel })
     const tooltipContainer = document.createElement('div')
     tooltipContainer.id = 'mapPopUpBox'
     tooltipContainer.style.position = 'absolute'
@@ -75,12 +118,12 @@
 
   // 弹框位置刷新
   const labelBoxRender = () => {
-    if (!currentEntity) return
+    if (!currentClickEntity) return
     let dom = document.querySelector('#mapPopUpBox')
     if (!dom) {
-      dom = getLabelDom(currentEntity.properties.customData._value.data)
+      dom = getLabelDom(currentClickEntity.properties.customData._value.data)
     }
-    const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentEntity?.position?._value)
+    const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentClickEntity?.position?._value)
     if (screenPosition) {
       dom.style.left = `${screenPosition.x}px`
       dom.style.top = `${screenPosition.y}px`
@@ -101,15 +144,19 @@
     removeDom()
   }
 
-  // 自动清理
-  onUnmounted(() => {
+  const removeAll = () => {
     removeHandler()
     removeLabel()
+  }
+
+  // 自动清理
+  onUnmounted(() => {
+    removeAll()
   })
 
   return {
-    currentClickEntity,
     handlerInit,
-    removeHandler
+    removeAll,
+    removeLabel
   }
 }
\ No newline at end of file
diff --git a/src/hooks/controlDrone/useManualControl.js b/src/hooks/controlDrone/useManualControl.js
index 4dc12ff..4ccce9f 100644
--- a/src/hooks/controlDrone/useManualControl.js
+++ b/src/hooks/controlDrone/useManualControl.js
@@ -36,11 +36,18 @@
 	}
 
 export function useManualControl(mqttState,deviceTopicInfo, isCurrentFlightController,paramsRef) {
-	const activeCodeKey = ref(null)
+	let activeCodeKey = null
 	let genPortOne = true //是一代机场
 	const mqttHooks = useMqtt(mqttState,deviceTopicInfo)
 	let seq = 0
-	let throttledPtz = null
+	const keysPressed = [
+		{key: 'KeyQ', value: false},
+		{key: 'KeyW', value: false},
+		{key: 'KeyE', value: false},
+		{key: 'KeyA', value: false},
+		{key: 'KeyS', value: false},
+		{key: 'KeyD', value: false},
+	]
 
 	function handlePublish(params) {
 		const body = {
@@ -51,7 +58,7 @@
 		myInterval = setInterval(() => {
 			body.data.seq = seq++
 			seq++
-			window.console.log('keyCode>>>>', activeCodeKey.value, body)
+			window.console.log('keyCode>>>>', activeCodeKey, body)
 			mqttHooks?.publishMqtt(deviceTopicInfo.pubTopic, body, { qos: 0 })
 		}, 50)
 	}
@@ -71,84 +78,137 @@
 		const HEIGHT = genPortOne ? 5 : 500; //  check
 		const W_SPEED = genPortOne ? 20 : 500 // 机头角速度
 
+
+		let arrList = []
+		if (genPortOne) {
+			arrList = [
+				{ Key: 'KeyQ', category: 'w', value: -W_SPEED },{ Key: 'KeyW',category: 'x', value: SPEED },
+				{ Key: 'KeyE', category: 'w', value: W_SPEED},{ Key: 'KeyA', category: 'y', value: -SPEED},
+				{ Key: 'KeyS', category: 'x', value: -SPEED},{ Key: 'KeyD', category: 'y', value: SPEED}
+			]
+		} else {
+			arrList = [
+				{ Key: 'KeyQ', category: 'yaw', value: 1024-W_SPEED },{ Key: 'KeyW',category: 'pitch', value: 1024+SPEED },
+				{ Key: 'KeyE', category: 'yaw', value: 1024+W_SPEED},{ Key: 'KeyA', category: 'roll', value: 1024-SPEED},
+				{ Key: 'KeyS', category: 'pitch', value: 1024-SPEED},{ Key: 'KeyD', category: 'roll', value: 1024+SPEED}
+			]
+		}
+		let resultObj = []
+		let resultArr = []
+		// 遍历被选中得数组
+		if (keyCode === 'assemblyKeys') {
+			keysPressed.map(key => {
+				if (key.value) {
+					let result = arrList.filter(item =>item.Key===key.key)
+					resultObj.push(result[0])
+				}
+			})
+			// 相同属性值进行计算
+			resultArr = resultObj.reduce((acc, item) => {
+				// 如果累加器中已经有这个 category,则累加 value
+				if (acc[item.category]) {
+					// acc[item.category] += item.value;
+					acc[item.category] = genPortOne ? 0 : 1024;
+				} else {
+					// 否则,初始化这个 category 的 value
+					acc[item.category] = item.value;
+				}
+				return acc;
+			}, {});
+		}
+
 		seq = 0
 		switch (keyCode) {
+			case 'assemblyKeys': // 针对Q W E A S D 组合键
+				if (activeCodeKey === keyCode) return
+				handlePublish(resultArr)
+				activeCodeKey = keyCode
+				break
 			case 'KeyQ':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objQ = { yaw: 1024-W_SPEED }
 				if (genPortOne) {objQ = {w: -W_SPEED}}
 				handlePublish(objQ)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			case 'KeyW':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objW = { pitch: 1024+SPEED }
 				if (genPortOne) {objW = {x: SPEED}}
 				handlePublish(objW)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			case 'KeyE':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objE = { yaw: 1024+W_SPEED }
 				if (genPortOne) {objE = {w: W_SPEED}}
 				handlePublish(objE)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			case 'KeyA':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objA = { roll: 1024-SPEED }
 				if (genPortOne) {objA = {y: -SPEED}}
 				handlePublish(objA)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			case 'KeyS':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objS = { pitch: 1024-SPEED }
 				if (genPortOne) {objS = {x: -SPEED}}
 				handlePublish(objS)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			case 'KeyD':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objD = { roll: 1024+SPEED }
 				if (genPortOne) {objD = {y: SPEED}}
 				handlePublish(objD)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			case 'KeyZ':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objZ = { throttle: 1024-HEIGHT }
 				if (genPortOne) {objZ = {h: -HEIGHT}}
 				handlePublish(objZ)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			// case 'ArrowDown':
 			case 'KeyC':
-				if (activeCodeKey.value === keyCode) return
+				if (activeCodeKey === keyCode) return
 				let objC = { throttle: 1024+HEIGHT }
 				if (genPortOne) {objC = {h: HEIGHT}}
 				handlePublish(objC)
-				activeCodeKey.value = keyCode
+				activeCodeKey = keyCode
 				break
 			case 'ArrowUp':
-				ptzThrottle[0]()
+				if (activeCodeKey === keyCode) return
+				clearInterval(myInterval)
+				myInterval = setInterval(()=>ptzControl('up'), 200)
+				activeCodeKey = keyCode
 				break
 			case 'ArrowDown':
-				ptzThrottle[1]()
+				if (activeCodeKey === keyCode) return
+				clearInterval(myInterval)
+				myInterval = setInterval(()=>ptzControl('down'), 200)
+				activeCodeKey = keyCode
 				break
 			case 'ArrowLeft':
-				ptzThrottle[2]()
+				if (activeCodeKey === keyCode) return
+				clearInterval(myInterval)
+				myInterval = setInterval(()=>ptzControl('left'), 200)
+				activeCodeKey = keyCode
 				break
 			case 'ArrowRight':
-				ptzThrottle[3]()
+				if (activeCodeKey === keyCode) return
+				clearInterval(myInterval)
+				myInterval = setInterval(()=>ptzControl('right'), 200)
+				activeCodeKey = keyCode
 				break
 			default:
 				break
 		}
 	}
-
-	// 云台控制节流list
-	const ptzThrottle = ['up','down','left','right'].map(key => throttle(()=>ptzControl(key), 500))
 
 	// 云台上下左右
 	function ptzControl(key) {
@@ -175,7 +235,8 @@
 	}
 
 	function resetControlState() {
-		activeCodeKey.value = null
+		keysPressed.map(item => item.value = false)
+		activeCodeKey = null
 		seq = 0
 		handleClearInterval()
 	}
@@ -185,7 +246,16 @@
 	}
 
 	function onKeydown(e) {
-		handleKeyup(e.code)
+		e.preventDefault()
+		keysPressed.forEach(item => {
+			if(e.code === item.key) item.value = true
+		})
+		let result = keysPressed.filter(item=>item.value===true)
+		if (result && result.length >= 2) {
+			handleKeyup('assemblyKeys')
+		} else {
+			handleKeyup(e.code)
+		}
 	}
 
 	function startKeyboardManualControl() {
@@ -211,6 +281,10 @@
 		{ immediate: true }
 	)
 
+	onBeforeUnmount(()=>{
+		mqttHooks?.d
+	})
+
 	onUnmounted(() => {
 		closeKeyboardManualControl()
 	})
diff --git a/src/hooks/useMapAggregation/useMapAggregation.js b/src/hooks/useMapAggregation/useMapAggregation.js
index 5557967..d46d74a 100644
--- a/src/hooks/useMapAggregation/useMapAggregation.js
+++ b/src/hooks/useMapAggregation/useMapAggregation.js
@@ -3,30 +3,19 @@
 import eventAggregationImg from '@/assets/images/home/useUavHome/eventAggregationImg.png'
 import uavImg from '@/assets/images/home/useUavHome/uavImg.png'
 
-// 事件图标
-import eventSingle from '@/assets/images/home/useEventOperate/eventSingle.png'
+import { getEventImage } from '@/utils/stateToImageMap/event'
+import { getDroneStatusImage } from '@/utils/stateToImageMap/drone'
 
-import eventPending from '@/assets/images/home/useEventOperate/eventPending.png' // 待处理 0
-import eventWaitAudit from '@/assets/images/home/useEventOperate/eventWaitAudit.png' // 待审核 2
-import eventProcessing from '@/assets/images/home/useEventOperate/eventProcessing.png' // 处理中 3
-import eventCompleted from '@/assets/images/home/useEventOperate/eventCompleted.png' // 已完成 4
-import eventClosed from '@/assets/images/home/useEventOperate/eventClosed.png' // 已完结 5
-
-import DevicePopUpBox from '@/hooks/components/DevicePopUpBox.vue'
-import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue'
-
-
-// 机巢图标
-import endingImg from '@/assets/images/aiNowFly/ending.png'
-import endingHighImg from '@/assets/images/aiNowFly/ending-high.png'
-
-import { render } from 'vue'
 import { useStore } from 'vuex'
 import { getCenterPoint } from '@/utils/cesium/mapUtil'
 import cesiumOperation from '@/utils/cesium-tsa'
 import { getDeviceRegion, getDeviceRegionCount, getEventDetails, getMapEvents } from '@/api/home/aggregation'
 import { PolyGradientMaterial } from '@/utils/cesium/Material'
 import { start } from 'nprogress'
+
+// hook
+import { useMapHandlerClick } from '@/hooks/components/useMapHandlerClick'
+
 /**
  * 机巢聚合功能
  */
@@ -51,8 +40,21 @@
   const { flyTo } = cesiumOperation()
 
   const mergeImg = type === 'device' ? aggregationImg : eventAggregationImg
-  const MapPopUpBox = type === 'device' ? DevicePopUpBox : EventPopUpBox
   const styleTransform = type === 'device' ? 'translateY(-50%)' : 'translate(-50%,-110%)'
+  const eventType = type === 'device' ? ['deviceAggregation', 'device'] : 'event'
+
+  const {
+    handlerInit: mapHandlerInit,
+    removeAll: removeMapHandlerAll,
+    removeLabel: removeMapLabel
+  } = useMapHandlerClick({
+    popupType: `${type}-popup`,
+    eventType: eventType,
+    styleTransform,
+    getViewer () {
+      return viewer
+    }
+  })
 
   let scalingJudgment = [
     { name: '县', splashedList: [], gJson: null, show: false, outline: {}, value: [0, 48651], height: 31753 },
@@ -69,8 +71,6 @@
   ]
   let viewer = null
   let active = null
-  let handler = null
-  let currentEntity = null
 
   const store = useStore()
   const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode)
@@ -104,7 +104,7 @@
         if (active === item.name) return
         active = item.name
         removeEntities()
-        removeLabel()
+        removeMapLabel()
         renderOutline(item)
         if (!item.gJson && !item.splashedList?.length) return
         item.gJson ? aggregation(item) : splashed(item)
@@ -288,7 +288,7 @@
 
       needFly = true
       if (!viewer) return
-      handlerInit()
+      mapHandlerInit()
 
       viewer.scene.postRender.removeEventListener(determineScaling)
 
@@ -302,15 +302,7 @@
   //散点机巢
   function splashed (row) {
     row.splashedList.forEach((item, index) => {
-      const eventImage = {
-        0: eventPending,
-        2: eventWaitAudit,
-        3: eventProcessing,
-        4: eventCompleted,
-        5: eventClosed
-      }
-
-      const image = type === 'device' ? (item.status === "OFFLINE" ? endingHighImg : endingImg) : eventImage[item.status] || eventSingle
+      const image = type === 'device' ? getDroneStatusImage(item.status) : getEventImage(item.status)
 
       viewer.entities.add({
         id: `aggregation-splashed-${index}`,
@@ -470,33 +462,6 @@
     })
   }
 
-  // 获取弹框box
-  const getLabelDom = data => {
-    const vNode = h(MapPopUpBox, { data, removeLabel })
-    const tooltipContainer = document.createElement('div')
-    tooltipContainer.id = 'mapPopUpBox'
-    tooltipContainer.style.position = 'absolute'
-    tooltipContainer.style.transform = styleTransform
-    tooltipContainer.style.pointerEvents = 'none'
-    document.querySelector('.page-index').append(tooltipContainer)
-    render(vNode, tooltipContainer)
-    return tooltipContainer
-  }
-
-  // 弹框位置刷新
-  const labelBoxRender = () => {
-    if (!currentEntity) return
-    let dom = document.querySelector('#mapPopUpBox')
-    if (!dom) {
-      dom = getLabelDom(currentEntity.properties.customData._value.data)
-    }
-    const screenPosition = viewer.scene.cartesianToCanvasCoordinates(currentEntity?.position?._value)
-    if (screenPosition) {
-      dom.style.left = `${screenPosition.x}px`
-      dom.style.top = `${screenPosition.y}px`
-      dom.style.display = 'block'
-    }
-  }
 
   /**
    * 根据条件获取项
@@ -506,41 +471,6 @@
    */
   const findTypeItem = (arr, condition) => {
     return arr.find(item => condition(item))
-  }
-
-  // 左键单机事件
-  const singleMachineEvent = async click => {
-    let clickTargets = viewer.scene.drillPick(click.position).map(item => item.id)
-    if (!clickTargets.length) return
-
-    let deviceAggregationFind = findTypeItem(
-      clickTargets,
-      item => item?.properties?.customData?._value?.data?.type === 'deviceAggregation'
-    )
-    let deviceFind = findTypeItem(clickTargets, item => item?.properties?.customData?._value?.data?.type === 'device')
-    // "event"
-    let eventFind = findTypeItem(clickTargets, item => item?.properties?.customData?._value?.data?.type === 'event')
-    // let eventFind = findTypeItem(clickTargets, (item) => item?.properties?.customData?._value?.data?.type === 'eventAggregation')
-    currentEntity = deviceAggregationFind || deviceFind || eventFind
-
-    if (!currentEntity) return
-    if (!currentEntity?.position?._value) return
-    // 一定要移除
-    removeLabel()
-    if (deviceAggregationFind || eventFind) {
-      viewer.scene.postRender.addEventListener(labelBoxRender)
-    }
-    if (deviceFind) {
-      const device = deviceFind.properties.customData._value.data
-      store.commit('setSingleUavHome', device)
-    }
-  }
-
-  const removeDom = () => {
-    const dom = document.querySelector('#mapPopUpBox')
-    if (dom && dom.parentNode) {
-      dom.parentNode.removeChild(dom)
-    }
   }
 
   // 移除 点 和 gjson 实体
@@ -556,11 +486,7 @@
       item.includes('aggregation-') && viewer.entities.removeById(item)
     })
   }
-  // 移除弹框标签
-  const removeLabel = () => {
-    viewer?.scene.postRender.removeEventListener(labelBoxRender)
-    removeDom()
-  }
+
 
   // 移除所有监听事件,变量置空
   const removeAll = () => {
@@ -571,14 +497,12 @@
   const clearMapEntity = () => {
     if (!viewer) return
     removeEntities()
-    removeLabel()
+    removeMapHandlerAll()
+
     // viewer.camera.moveEnd.removeEventListener(determineScaling);
     viewer.scene.postRender.removeEventListener(determineScaling)
-    handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
-    handler?.destroy()
+
     active = null
-    handler = null
-    currentEntity = null
   }
 
   const init = () => {
@@ -588,14 +512,7 @@
       viewer.scene.postRender.addEventListener(determineScaling)
     })
 
-    handlerInit()
-  }
-
-  const handlerInit = () => {
-    if (handler) return
-
-    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
-    handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK)
+    mapHandlerInit()
   }
 
   onBeforeUnmount(() => { })
diff --git a/src/hooks/useSingleDroneMap/useSingleDroneMap.js b/src/hooks/useSingleDroneMap/useSingleDroneMap.js
index ff7f0c3..b8b7aa7 100644
--- a/src/hooks/useSingleDroneMap/useSingleDroneMap.js
+++ b/src/hooks/useSingleDroneMap/useSingleDroneMap.js
@@ -2,25 +2,18 @@
  * @Author: shuishen 1109946754@qq.com
  * @Date: 2025-04-15 22:41:40
  * @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2025-04-17 15:05:32
+ * @LastEditTime: 2025-04-17 20:24:19
  * @FilePath: \command-center-dashboard\src\hooks\useSingleDroneMap\useSingleDroneMap.js
  * @Description: 
  * 
  * Copyright (c) 2025 by shuishen, All Rights Reserved. 
  */
 import * as Cesium from 'cesium'
-import { render } from 'vue'
-import endingImg from '@/assets/images/aiNowFly/ending.png'
-import endingHighImg from '@/assets/images/aiNowFly/ending-high.png'
-import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue'
 
-import eventSingle from '@/assets/images/home/useEventOperate/eventSingle.png'
+import { getEventImage } from '@/utils/stateToImageMap/event'
+import { getDroneFlagImage } from '@/utils/stateToImageMap/drone'
 
-import eventPending from '@/assets/images/home/useEventOperate/eventPending.png' // 待处理 0
-import eventWaitAudit from '@/assets/images/home/useEventOperate/eventWaitAudit.png' // 待审核 2
-import eventProcessing from '@/assets/images/home/useEventOperate/eventProcessing.png' // 处理中 3
-import eventCompleted from '@/assets/images/home/useEventOperate/eventCompleted.png' // 已完成 4
-import eventClosed from '@/assets/images/home/useEventOperate/eventClosed.png' // 已完结 5
+import { useMapHandlerClick } from '@/hooks/components/useMapHandlerClick'
 
 /**
  * 
@@ -31,20 +24,18 @@
   eventApi: null,
   eventApiParams: {}
 }) {
-  const styleTransform = 'translate(-50%,-110%)'
-
   const { eventPositions, eventApi, eventApiParams } = options
-  const eventImage = {
-    0: eventPending,
-    2: eventWaitAudit,
-    3: eventProcessing,
-    4: eventCompleted,
-    5: eventClosed
-  }
 
   let viewer = null
-  let handler = null
-  let currentEntity = null
+
+  const {
+    handlerInit: mapHandlerInit,
+    removeAll: removeMapHandlerAll
+  } = useMapHandlerClick({
+    getViewer () {
+      return viewer
+    }
+  })
 
   // 初始化机场位置
   const initDroneEntity = (dronePosition) => {
@@ -52,7 +43,7 @@
 
     if (!lng || !lat) return
 
-    const markerImg = status ? endingHighImg : endingImg
+    const markerImg = getDroneFlagImage(status)
     const position = Cesium.Cartesian3.fromDegrees(+lng, +lat, 0)
 
     const droneEntity = viewer?.entities.add({
@@ -93,7 +84,7 @@
     eventData.length && eventData.forEach((item, index) => {
       const { longitude, latitude, status, id } = item
 
-      const curImg = eventImage[status] || eventSingle
+      const curImg = getEventImage(status)
 
       const position = Cesium.Cartesian3.fromDegrees(+longitude, +latitude, 0)
 
@@ -109,7 +100,7 @@
           customData: {
             data: {
               ...item,
-              eventId: item.id,
+              eventId: id,
               type: 'single-drone-event'
             }
           }
@@ -155,104 +146,20 @@
     })
   }
 
-  // 查找特定类型的实体
-  const findEntityByType = (entities, type) => {
-    return entities.find(entity =>
-      entity?.properties?.customData?._value?.data?.type === type
-    )
-  }
-
-  // 左键单机事件
-  const singleMachineEvent = async click => {
-    currentEntity = null
-
-    let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id)
-
-    if (!clickedEntities?.length) return
-
-    currentEntity = findEntityByType(clickedEntities, 'single-drone-event')
-
-    removeLabel()
-
-    if (currentEntity) {
-      viewer?.scene.postRender.addEventListener(labelBoxRender)
-    }
-  }
-
-  // 事件初始化
-  const handlerInit = () => {
-    if (handler) return
-
-    handler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
-    handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK)
-  }
-
-  // 事件移除
-  const removeHandler = () => {
-    handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
-    handler?.destroy()
-    handler = null
-  }
-
-  // 获取弹框box
-  const getLabelDom = data => {
-    const vNode = h(EventPopUpBox, { data, removeLabel })
-    const tooltipContainer = document.createElement('div')
-    tooltipContainer.id = 'mapPopUpBox'
-    tooltipContainer.style.position = 'absolute'
-    tooltipContainer.style.transform = styleTransform
-    tooltipContainer.style.pointerEvents = 'none'
-    document.querySelector('.page-index').append(tooltipContainer)
-    render(vNode, tooltipContainer)
-    return tooltipContainer
-  }
-
-  // 弹框位置刷新
-  const labelBoxRender = () => {
-    if (!currentEntity) return
-    let dom = document.querySelector('#mapPopUpBox')
-
-    if (!dom) {
-      dom = getLabelDom(currentEntity.properties.customData._value.data)
-    }
-    const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentEntity?.position?._value)
-    if (screenPosition) {
-      dom.style.left = `${screenPosition.x}px`
-      dom.style.top = `${screenPosition.y}px`
-      dom.style.display = 'block'
-    }
-  }
-
-  const removeDom = () => {
-    const dom = document.querySelector('#mapPopUpBox')
-    if (dom && dom.parentNode) {
-      dom.parentNode.removeChild(dom)
-    }
-  }
-
-  // 移除弹框标签
-  const removeLabel = () => {
-    viewer?.scene.postRender.removeEventListener(labelBoxRender)
-    removeDom()
-  }
-
-
   const init = () => {
     viewer = window.$viewer
 
-    handlerInit()
+    mapHandlerInit()
   }
 
   const removeAll = () => {
     removeLayer()
-    removeHandler()
-    removeLabel()
+    removeMapHandlerAll()
   }
 
-  onMounted(() => {
-    nextTick(() => {
-      init()
-    })
+  onMounted(async () => {
+    await nextTick()
+    init()
   })
 
   // 自动清理
diff --git a/src/mqtt/index.js b/src/mqtt/index.js
index 896d2a5..8b53f7b 100644
--- a/src/mqtt/index.js
+++ b/src/mqtt/index.js
@@ -65,7 +65,7 @@
 
 	// 关闭 mqtt 客户端
 	destroyed = () => {
-		window.console.log('mqtt destroyed')
+		window.console.log('mqtt 销毁')
 		this._client?.end()
 	}
 
diff --git a/src/utils/stateToImageMap/drone.js b/src/utils/stateToImageMap/drone.js
new file mode 100644
index 0000000..192e78b
--- /dev/null
+++ b/src/utils/stateToImageMap/drone.js
@@ -0,0 +1,32 @@
+/*
+ * @Author: shuishen 1109946754@qq.com
+ * @Date: 2025-04-17 20:17:12
+ * @LastEditors: shuishen 1109946754@qq.com
+ * @LastEditTime: 2025-04-17 20:28:08
+ * @FilePath: \command-center-dashboard\src\utils\stateToImageMap\drone.js
+ * @Description: 
+ * 
+ * Copyright (c) 2025 by shuishen, All Rights Reserved. 
+ */
+import endingImg from '@/assets/images/aiNowFly/ending.png'
+import endingHighImg from '@/assets/images/aiNowFly/ending-high.png'
+
+const droneImage = {
+  'OFFLINE': endingImg,
+  'WORKING': endingHighImg,
+  'LEISURE': endingHighImg
+}
+
+/**
+ * 根据机巢状态获取图片
+ * @param {string} status 状态
+ * @returns 
+ */
+export const getDroneStatusImage = (status) => droneImage[status] || endingHighImg
+
+/**
+ * 根据机巢状态获取图片
+ * @param {boolean} isOnline 状态
+ * @returns 
+ */
+export const getDroneFlagImage = (isOnline) => isOnline ? endingHighImg : endingImg
\ No newline at end of file
diff --git a/src/utils/stateToImageMap/event.js b/src/utils/stateToImageMap/event.js
new file mode 100644
index 0000000..fe6ca7e
--- /dev/null
+++ b/src/utils/stateToImageMap/event.js
@@ -0,0 +1,23 @@
+import eventSingle from '@/assets/images/home/useEventOperate/eventSingle.png'
+
+import eventPending from '@/assets/images/home/useEventOperate/eventPending.png' // 待处理 0
+import eventWaitAudit from '@/assets/images/home/useEventOperate/eventWaitAudit.png' // 待审核 2
+import eventProcessing from '@/assets/images/home/useEventOperate/eventProcessing.png' // 处理中 3
+import eventCompleted from '@/assets/images/home/useEventOperate/eventCompleted.png' // 已完成 4
+import eventClosed from '@/assets/images/home/useEventOperate/eventClosed.png' // 已完结 5
+
+
+const eventImage = {
+  0: eventPending,
+  2: eventWaitAudit,
+  3: eventProcessing,
+  4: eventCompleted,
+  5: eventClosed
+}
+
+/**
+ * 根据事件状态获取图片资源
+ * @param {*} status 状态
+ * @returns 
+ */
+export const getEventImage = (status) => eventImage[status] || eventSingle
\ No newline at end of file
diff --git a/src/views/Home/SearchBox.vue b/src/views/Home/SearchBox.vue
index 46d23e7..fb3b28c 100644
--- a/src/views/Home/SearchBox.vue
+++ b/src/views/Home/SearchBox.vue
@@ -1,277 +1,281 @@
 <template>
-  <div class="searchBox" ref="searchBoxRef">
-    <div class="searchInput">
-      <el-select v-model="optionsValue" @change="optionChange" placeholder="请选择查询">
-        <el-option
-          v-for="item in options"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value"
-        />
-      </el-select>
+	<div class="searchBox" ref="searchBoxRef">
+		<div class="searchInput">
+			<el-select v-model="optionsValue" @change="optionChange" placeholder="请选择查询">
+				<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+			</el-select>
 
-      <el-input v-model="searchKey"  @focus="handleFocus" placeholder="请输入搜索关键字"></el-input>
-    </div>
-    <div class="searchBtn" @click="searchClick"></div>
-    <div class="region">
-      <el-tree-select
-        v-model="treeValue"
-        check-strictly
-        lazy
-        :load="load"
-        :props="props"
-        style="width: 240px"
-        @node-click="handleNodeClick"
-      />
-    </div>
-  </div>
-  <div class="select-down-list" ref="selectDownRef" v-show="isSelectDown">
-    <div class="item" v-for="item in downList" @click="selectedValue(item)">{{ item.nickname || item.name }}</div>
-  </div>
+			<el-input
+				v-model="searchKey"
+				@input="handlerInput"
+				@focus="handleFocus"
+				placeholder="请输入搜索关键字"
+			></el-input>
+		</div>
+		<div class="searchBtn" @click="searchClick"></div>
+		<div class="region">
+			<el-tree-select
+				v-model="treeValue"
+				check-strictly
+				lazy
+				:load="load"
+				:props="props"
+				style="width: 240px"
+				@node-click="handleNodeClick"
+			/>
+		</div>
+	</div>
+	<div class="select-down-list" ref="selectDownRef" v-show="isSelectDown">
+		<div class="item" v-for="item in downList" @click="selectedValue(item)">{{ item.nickname || item.name }}</div>
+	</div>
 </template>
 <script setup>
-import { getRegion } from '@/api/home';
-import { searchByKeyword, selectDeviceList } from '@/api/home/common';
-import { useStore } from 'vuex';
+import _ from 'lodash'
+import { getRegion } from '@/api/home'
+import { searchByKeyword, selectDeviceList } from '@/api/home/common'
+import { useStore } from 'vuex'
 import cesiumOperation from '@/utils/cesium-tsa'
 
 const { flyTo } = cesiumOperation()
 
-const store = useStore();
-const searchKey = ref('');
-const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode);
-const selectedAreaCode = computed(() => store.state.user.selectedAreaCode);
-const areaValue = ref('江西省');
-const treeValue = ref(userAreaCode.value);
-let first = true;
-const searchBoxRef = ref(null);
-const selectDownRef = ref(null);
+const store = useStore()
+const searchKey = ref('')
+const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode)
+const selectedAreaCode = computed(() => store.state.user.selectedAreaCode)
+const areaValue = ref('江西省')
+const treeValue = ref(userAreaCode.value)
+let first = true
+const searchBoxRef = ref(null)
+const selectDownRef = ref(null)
 
 function handleNodeClick(data) {
-  areaValue.value = data.name;
-  store.commit('setSelectedAreaCode', data.code);
+	areaValue.value = data.name
+	store.commit('setSelectedAreaCode', data.code)
 }
 
 const props = {
-  label: 'name',
-  value: 'code',
-  children: 'children',
-};
+	label: 'name',
+	value: 'code',
+	children: 'children',
+}
 const load = async (node, resolve) => {
-  if (first) {
-    first = false;
-    const res = await getRegion(userAreaCode.value);
-    const { provinceCode, provinceName } = res?.data?.data?.[0] || {};
-    resolve([{ code: provinceCode, name: provinceName }]);
-    return;
-  }
-  const code = node?.data?.code || userAreaCode.value;
-  if ((node?.data?.regionLevel || 0) > 2) return resolve([]);
-  getRegion(code).then(res => {
-    resolve(res?.data?.data || []);
-  });
-};
+	if (first) {
+		first = false
+		const res = await getRegion(userAreaCode.value)
+		const { provinceCode, provinceName } = res?.data?.data?.[0] || {}
+		resolve([{ code: provinceCode, name: provinceName }])
+		return
+	}
+	const code = node?.data?.code || userAreaCode.value
+	if ((node?.data?.regionLevel || 0) > 2) return resolve([])
+	getRegion(code).then(res => {
+		resolve(res?.data?.data || [])
+	})
+}
 
-const optionsValue = ref('1');
+const optionsValue = ref('1')
 const options = [
-  {
-    value: '1',
-    label: '机巢',
-  },
-  {
-    value: '2',
-    label: '地址',
-  },
-];
+	{
+		value: '1',
+		label: '机巢',
+	},
+	{
+		value: '2',
+		label: '地址',
+	},
+]
 
-const isSelectDown = ref(false);
-// 下拉数据列表
-const machineNestList = ref([]);
+const isSelectDown = ref(false)
+
 // 地址搜索结果
-const downList = ref([]);
-const position = ref({});
+const downList = ref([])
+const position = ref({})
 
 // 获取机巢搜索结果
 const getDeviceList = async () => {
-  const res = await selectDeviceList({nickname: searchKey.value});
-  if (res.data.code !== 0) return;
-  machineNestList.value = res?.data?.data || [];
-  downList.value = res?.data?.data || [];
-};
+	const res = await selectDeviceList({ nickname: searchKey.value })
+	if (res.data.code !== 0) return
+	downList.value = res?.data?.data || []
+}
 // 获取地址搜索结果
 const getAddressList = async () => {
-  const res = await searchByKeyword(encodeURIComponent(`${areaValue.value}+${searchKey.value}`));
-  if (res.data.code !== 0) return;
-  downList.value = res?.data?.data.tips || [];
-  if (downList.value.length > 0) {
-    isSelectDown.value = true;
-  }
-};
+	const res = await searchByKeyword(encodeURIComponent(`${areaValue.value}+${searchKey.value}`))
+	if (res.data.code !== 0) return
+	downList.value = res?.data?.data.tips || []
+	if (downList.value.length > 0) {
+		isSelectDown.value = true
+	}
+}
 // 搜索结果
 const searchClick = () => {
 	const longitude = Number(position.value.longitude)
 	const latitude = Number(position.value.latitude)
 	flyTo({ longitude, latitude }, 1, 1000)
-};
+}
 
 // 地址和机巢的切换
 const optionChange = () => {
-  searchKey.value = '';
-  downList.value = [];
-};
+	searchKey.value = ''
+	downList.value = []
+
+	inputSelect()
+}
+
+// input对应下拉数据初始化
+const inputSelect = () => {
+	if (optionsValue.value === '2') {
+		getAddressList()
+	} else {
+		getDeviceList()
+	}
+}
+
+inputSelect()
+
+// 输入框input事件
+const handlerInput = _.debounce(inputSelect, 1000)
+
 // 输入框获取焦点
 const handleFocus = () => {
-  if (optionsValue.value === '1') {
-    isSelectDown.value = true;
-    downList.value = machineNestList.value;
-  }
-};
+	isSelectDown.value = true
+}
 // 机巢下拉获取值
 const selectedValue = item => {
-  searchKey.value = item.nickname || item.name;
-  if (optionsValue.value === '1') {
-    position.value = item;
-  } else {
-    position.value = { longitude: item.location.split(',')[0], latitude: item.location.split(',')[1] };
-  }
-  
-  isSelectDown.value = false;
-};
+	searchKey.value = item.nickname || item.name
+	if (optionsValue.value === '1') {
+		position.value = item
+	} else {
+		position.value = { longitude: item.location.split(',')[0], latitude: item.location.split(',')[1] }
+	}
 
-// 监听搜索关键字变化
-watch(searchKey, async (newVal) => {
-  if (optionsValue.value === '2') {
-    await getAddressList();
-  } else {
-    await getDeviceList();
-  }
-}, { immediate: false });
+	isSelectDown.value = false
+}
 
 onMounted(() => {
-  document.addEventListener('click', handleClickOutside);
-});
+	document.addEventListener('click', handleClickOutside)
+})
 
 onUnmounted(() => {
-  document.removeEventListener('click', handleClickOutside);
-});
+	document.removeEventListener('click', handleClickOutside)
+})
 
-const handleClickOutside = (event) => {
-  if (!searchBoxRef.value?.contains(event.target) && !selectDownRef.value?.contains(event.target)) {
-    isSelectDown.value = false;
-  }
-};
+const handleClickOutside = event => {
+	if (!searchBoxRef.value?.contains(event.target) && !selectDownRef.value?.contains(event.target)) {
+		isSelectDown.value = false
+	}
+}
 </script>
 <style scoped lang="scss">
 .select-down-list {
-  position: absolute;
-  top: 188px;
-  left: 44%;
-  transform: translateX(-40%);
-  width: 220px;
-  height: 256px;
-  overflow-y: auto;
-  background: linear-gradient( 180deg, #0D3556 0%, #012350 100%);
-  border-radius: 0px 0px 8px 8px;
-  border: 1px solid;
-  border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1;
-  opacity: 0.8;
-  &::-webkit-scrollbar {
-    width: 0;
-    display: none;
-  }
-  -ms-overflow-style: none;  /* IE and Edge */
-  scrollbar-width: none;  /* Firefox */
-  .item {
-    color: #FFFFFF;
-    height: 32px;
-    line-height: 32px;
-    text-align: center;
-    cursor: pointer;
-    &:hover {
-      background: linear-gradient( 90deg, rgba(0,122,255,0) 0%, rgba(0,98,204,0.6) 50%, rgba(0,73,153,0) 100%);
-      border: 1px solid;
-      border-image: linear-gradient(90deg, rgba(0, 199, 190, 0), rgba(48, 176, 199, 1), rgba(0, 199, 190, 0)) 1 1;
-    }
-  }
+	position: absolute;
+	top: 188px;
+	left: 44%;
+	transform: translateX(-40%);
+	width: 220px;
+	height: 256px;
+	overflow-y: auto;
+	background: linear-gradient(180deg, #0d3556 0%, #012350 100%);
+	border-radius: 0px 0px 8px 8px;
+	border: 1px solid;
+	border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1;
+	opacity: 0.8;
+	&::-webkit-scrollbar {
+		width: 0;
+		display: none;
+	}
+	-ms-overflow-style: none; /* IE and Edge */
+	scrollbar-width: none; /* Firefox */
+	.item {
+		color: #ffffff;
+		height: 32px;
+		line-height: 32px;
+		text-align: center;
+		cursor: pointer;
+		&:hover {
+			background: linear-gradient(90deg, rgba(0, 122, 255, 0) 0%, rgba(0, 98, 204, 0.6) 50%, rgba(0, 73, 153, 0) 100%);
+			border: 1px solid;
+			border-image: linear-gradient(90deg, rgba(0, 199, 190, 0), rgba(48, 176, 199, 1), rgba(0, 199, 190, 0)) 1 1;
+		}
+	}
 }
 .searchBox {
-  width: 420px;
-  height: 43px;
-  position: absolute;
-  top: 145px;
-  left: 50%;
-  transform: translateX(-50%);
-  display: flex;
+	width: 420px;
+	height: 43px;
+	position: absolute;
+	top: 145px;
+	left: 50%;
+	transform: translateX(-50%);
+	display: flex;
 
-  .el-select {
-    width: 130px;
-    height: 100%;
+	.el-select {
+		width: 130px;
+		height: 100%;
 
-    :deep() {
-      .el-select__wrapper {
-        background: transparent;
-        border: none;
-        box-shadow: none;
-        height: 100%;
-        padding-left: 20px;
-      }
+		:deep() {
+			.el-select__wrapper {
+				background: transparent;
+				border: none;
+				box-shadow: none;
+				height: 100%;
+				padding-left: 20px;
+			}
 
-      .el-select__selected-item {
-        font-family: Source Han Sans CN, Source Han Sans CN, serif;
-        font-weight: 400;
-        font-size: 14px;
-        color: #ffffff;
-        line-height: 18px;
-      }
-    }
-  }
+			.el-select__selected-item {
+				font-family: Source Han Sans CN, Source Han Sans CN, serif;
+				font-weight: 400;
+				font-size: 14px;
+				color: #ffffff;
+				line-height: 18px;
+			}
+		}
+	}
 
-  .searchInput {
-    width: 243px;
-    height: 100%;
-    background: url('@/assets/images/home/searchBox/searchBg1.png') no-repeat center / 100% 100%;
-    display: flex;
+	.searchInput {
+		width: 243px;
+		height: 100%;
+		background: url('@/assets/images/home/searchBox/searchBg1.png') no-repeat center / 100% 100%;
+		display: flex;
 
-    .el-input {
-      height: 100%;
+		.el-input {
+			height: 100%;
 
-      :deep() {
-        .el-input__wrapper {
-          background: transparent;
-          border: none;
-          box-shadow: none;
-          height: 100%;
-        }
+			:deep() {
+				.el-input__wrapper {
+					background: transparent;
+					border: none;
+					box-shadow: none;
+					height: 100%;
+				}
 
-        .el-input__inner {
-          font-family: Source Han Sans CN, Source Han Sans CN, serif;
-          font-weight: 400;
-          font-size: 14px;
-          color: #ffffff;
-          line-height: 18px;
-        }
-      }
-    }
-  }
+				.el-input__inner {
+					font-family: Source Han Sans CN, Source Han Sans CN, serif;
+					font-weight: 400;
+					font-size: 14px;
+					color: #ffffff;
+					line-height: 18px;
+				}
+			}
+		}
+	}
 
-  .searchBtn {
-    width: 67px;
-    height: 100%;
-    background: url('@/assets/images/home/searchBox/searchBg2.png') no-repeat center / 100% 100%;
-    cursor: pointer;
-  }
+	.searchBtn {
+		width: 67px;
+		height: 100%;
+		background: url('@/assets/images/home/searchBox/searchBg2.png') no-repeat center / 100% 100%;
+		cursor: pointer;
+	}
 
-  .region {
-    width: 0;
-    flex-grow: 1;
-    background: url('@/assets/images/home/searchBox/searchBg3.png') no-repeat center / 100% 100%;
+	.region {
+		width: 0;
+		flex-grow: 1;
+		background: url('@/assets/images/home/searchBox/searchBg3.png') no-repeat center / 100% 100%;
 
-    :deep() {
-      .el-select__wrapper {
-        width: 100px;
-        padding-left: 20px;
-      }
-    }
-  }
+		:deep() {
+			.el-select__wrapper {
+				width: 100px;
+				padding-left: 20px;
+			}
+		}
+	}
 }
 </style>
diff --git a/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue b/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue
index 98c6ac5..2c24401 100644
--- a/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue
+++ b/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue
@@ -1,228 +1,230 @@
 <!-- 任务事件概况 -->
 <template>
-    <common-title title="任务事件概况" :style="{ marginLeft: pxToRem(14) }"></common-title>
-    <div class="inspection-rask-details">
-        <CommonDateTime :style="{ top: pxToRem(14),marginLeft: pxToRem(10) }" v-model="newTime" @change="getData"></CommonDateTime>
-        <div class="chart-container" ref="chartRef"></div>
-        <div class="pie-container" ref="pieRef"></div>
-    </div>
+	<common-title title="任务事件概况" :style="{ marginLeft: pxToRem(14) }"></common-title>
+	<div class="inspection-rask-details">
+		<CommonDateTime
+			:style="{ top: pxToRem(14), marginLeft: pxToRem(10) }"
+			v-model="newTime"
+			@change="getData"
+		></CommonDateTime>
+		<div class="chart-container" ref="chartRef"></div>
+		<div class="pie-container" ref="pieRef"></div>
+	</div>
 </template>
 
 <script setup>
-import * as echarts from 'echarts';
-import dayjs from 'dayjs';
-import { pxToRem } from '@/utils/rem';
-import CommonTitle from '@/components/CommonTitle.vue';
-import CommonDateTime from '@/components/CommonDateTime.vue';
+import * as echarts from 'echarts'
+import dayjs from 'dayjs'
+import { pxToRem } from '@/utils/rem'
+import CommonTitle from '@/components/CommonTitle.vue'
+import CommonDateTime from '@/components/CommonDateTime.vue'
 import { jobNumBar, eventNumPie } from '@/api/home'
 import useEchartsResize from '@/hooks/useEchartsResize'
+import { useStore } from 'vuex'
 
+const store = useStore()
+// 单个机巢信息
+const singleUavHome = computed(() => store.state.home.singleUavHome)
 // 日期
-const currenDate = dayjs().format('YYYY-MM-DD');
-const newTime = ref([currenDate, currenDate]);
+const currenDate = dayjs().format('YYYY-MM-DD')
+const newTime = ref([currenDate, currenDate])
 // 统计图
-const chartRef = ref(null);
+const chartRef = ref(null)
 let { chart } = useEchartsResize(chartRef)
-const pieRef = ref(null);
+const pieRef = ref(null)
 let { chart: pieChart } = useEchartsResize(pieRef)
 
-
 const option = {
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
-        }
-    },
-    grid: {
-        top: '15%',
-        left: '3%',
-        right: '4%',
-        bottom: '3%',
-        containLabel: true
-    },
-    legend: {
-        data: ['任务', '事件'],
-        textStyle: {
-            color: '#fff'
-        }
-    },
-    xAxis: {
-        type: 'category',
-        // data: ['1月', '2月', '3月', '4月', '5月', '6月'],
-        axisLine: {
-            lineStyle: {
-                color: '#fff'
-            }
-        },
-        axisLabel: {
-            color: '#fff'
-        }
-    },
-    yAxis: {
-        type: 'value',
-        axisLine: {
-            lineStyle: {
-                color: '#fff'
-            }
-        },
-        splitLine: {
-            lineStyle: {
-                color: 'rgba(255, 255, 255, 0.1)'
-            }
-        },
-        axisLabel: {
-            color: '#fff'
-        }
-    },
-    series: [
-        {
-            name: '任务',
-            type: 'bar',
-            barWidth: '20%',
-            // data: [10, 15, 20, 25, 30, 35],
-            itemStyle: {
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                    { offset: 0, color: '#1EE7E7' },
-                    { offset: 1, color: 'rgba(30, 231, 231, 0.1)' }
-                ])
-            }
-        },
-        {
-            name: '事件',
-            type: 'bar',
-            barWidth: '20%',
-            // data: [15, 20, 25, 30, 35, 40],
-            itemStyle: {
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                    { offset: 0, color: '#0070FF' },
-                    { offset: 1, color: 'rgba(0, 112, 255, 0.1)' }
-                ])
-            }
-        }
-    ]
-};
+	tooltip: {
+		trigger: 'axis',
+		axisPointer: {
+			type: 'shadow',
+		},
+	},
+	grid: {
+		top: '15%',
+		left: '3%',
+		right: '4%',
+		bottom: '3%',
+		containLabel: true,
+	},
+	legend: {
+		data: ['任务', '事件'],
+		textStyle: {
+			color: '#fff',
+		},
+	},
+	xAxis: {
+		type: 'category',
+		// data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+		axisLine: {
+			lineStyle: {
+				color: '#fff',
+			},
+		},
+		axisLabel: {
+			color: '#fff',
+		},
+	},
+	yAxis: {
+		type: 'value',
+		axisLine: {
+			lineStyle: {
+				color: '#fff',
+			},
+		},
+		splitLine: {
+			lineStyle: {
+				color: 'rgba(255, 255, 255, 0.1)',
+			},
+		},
+		axisLabel: {
+			color: '#fff',
+		},
+	},
+	series: [
+		{
+			name: '任务',
+			type: 'bar',
+			barWidth: '20%',
+			// data: [10, 15, 20, 25, 30, 35],
+			itemStyle: {
+				color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+					{ offset: 0, color: '#1EE7E7' },
+					{ offset: 1, color: 'rgba(30, 231, 231, 0.1)' },
+				]),
+			},
+		},
+		{
+			name: '事件',
+			type: 'bar',
+			barWidth: '20%',
+			// data: [15, 20, 25, 30, 35, 40],
+			itemStyle: {
+				color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+					{ offset: 0, color: '#0070FF' },
+					{ offset: 1, color: 'rgba(0, 112, 255, 0.1)' },
+				]),
+			},
+		},
+	],
+}
 
 // chart.setOption(option);
 
 const pieOption = {
-    tooltip: {
-        trigger: 'item',
-        formatter: '{b}: {c} ({d}%)'
-    },
-    legend: {
-        orient: 'vertical',
-        right: '5%',
-        top: 'middle',
-        textStyle: {
-            color: '#fff',
-            fontSize: 12
-        },
-        itemWidth: 10,
-        itemHeight: 10,
-        itemGap: 10,
-        formatter: function(name) {
-            let data = pieOption.series[0].data;
-            let total = 0;
-            let tarValue = 0;
-            for (let i = 0; i < data.length; i++) {
-                total += data[i].value;
-                if (data[i].name === name) {
-                    tarValue = data[i].value;
-                }
-            }
-            let percentage = ((tarValue / total) * 100).toFixed(1);
-            return `${name} ${percentage}%`;
-        }
-    },
-    series: [
-        {
-            name: '任务状态',
-            type: 'pie',
-            radius: ['10%', '90%'],
-            center: ['35%', '50%'],  // 将图表向左偏移
-            roseType: 'radius',
-            itemStyle: {
-                borderRadius: 4
-            },
-            label: {
-                show: true,
-                position: 'inside',
-                formatter: '{c}%',
-                fontSize: 12,
-                color: '#fff'
-            },
-            data: [
-                { value: 0, name: '待审核', itemStyle: { color: '#1860EC' } },
-                { value: 0, name: '待处理', itemStyle: { color: '#47D107' } },
-                { value: 0, name: '已完成', itemStyle: { color: '#F29509' } },
-                // { value: 0, name: '待分拨', itemStyle: { color: '#E9C81A' } },
-                { value: 0, name: '处理中', itemStyle: { color: '#0FC1E8' } },
-                { value: 0, name: '已完结', itemStyle: { color: '#FE577F' } }
-            ]
-        }
-    ]
-};
+	tooltip: {
+		trigger: 'item',
+		formatter: '{b}: {c} ({d}%)',
+	},
+	legend: {
+		orient: 'vertical',
+		right: '5%',
+		top: 'middle',
+		textStyle: {
+			color: '#fff',
+			fontSize: 12,
+		},
+		itemWidth: 10,
+		itemHeight: 10,
+		itemGap: 10,
+		formatter: function (name) {
+			let data = pieOption.series[0].data
+			let total = 0
+			let tarValue = 0
+			for (let i = 0; i < data.length; i++) {
+				total += data[i].value
+				if (data[i].name === name) {
+					tarValue = data[i].value
+				}
+			}
+			let percentage = ((tarValue / total) * 100).toFixed(1)
+			return `${name} ${percentage}%`
+		},
+	},
+	series: [
+		{
+			name: '任务状态',
+			type: 'pie',
+			radius: ['10%', '90%'],
+			center: ['35%', '50%'], // 将图表向左偏移
+			roseType: 'radius',
+			itemStyle: {
+				borderRadius: 4,
+			},
+			label: {
+				show: true,
+				position: 'inside',
+				formatter: '{c}%',
+				fontSize: 12,
+				color: '#fff',
+			},
+			data: [
+				{ value: 0, name: '待审核', itemStyle: { color: '#1860EC' } },
+				{ value: 0, name: '待处理', itemStyle: { color: '#47D107' } },
+				{ value: 0, name: '已完成', itemStyle: { color: '#F29509' } },
+				// { value: 0, name: '待分拨', itemStyle: { color: '#E9C81A' } },
+				{ value: 0, name: '处理中', itemStyle: { color: '#0FC1E8' } },
+				{ value: 0, name: '已完结', itemStyle: { color: '#FE577F' } },
+			],
+		},
+	],
+}
 
 // TODAY,CURRENT_WEEK,CURRENT_MONTH,CURRENT_YEAR
-const getData = (value,date_enum) => {
-    const params = {
-        device_sn: '',
-        date_enum,
-        // start_date: newTime.value[0],
-        // end_date: newTime.value[1]
-    };
-    // 获取柱状图
-    jobNumBar(params).then(res => {
-        if (res.data.code !== 0) return;
-        option.xAxis.data = res.data?.data.map(item => item.name);
-        option.series[0].data = res.data?.data.map(item => item.data[0].value);
-        option.series[1].data = res.data?.data.map(item => item.data[1].value);
-        chart.value.setOption(option);
-    })
-    // 获取饼状图
-    eventNumPie(params).then(res => {
-        if (res.data.code!== 0) return;
-        // 更新饼图数据
-        const updatedPieData = pieOption.series[0].data.map(item => {
-            const matchedData = res.data?.data.find(dataItem => dataItem.name === item.name);
-            return {
-                ...item,
-                value: matchedData ? matchedData.value : item.value
-            };
-        });
-        pieOption.series[0].data = updatedPieData;
-        pieChart.value.setOption(pieOption);
-    })
-};
+const getData = (value, date_enum) => {
+	const params = {
+		device_sn: singleUavHome.value.device_sn,
+		date_enum,
+		// start_date: newTime.value[0],
+		// end_date: newTime.value[1]
+	}
+	// 获取柱状图
+	jobNumBar(params).then(res => {
+		if (res.data.code !== 0) return
+		option.xAxis.data = res.data?.data.map(item => item.name)
+		option.series[0].data = res.data?.data.map(item => item.data[0].value)
+		option.series[1].data = res.data?.data.map(item => item.data[1].value)
+		chart.value.setOption(option)
+	})
+	// 获取饼状图
+	eventNumPie(params).then(res => {
+		if (res.data.code !== 0) return
+		// 更新饼图数据
+		const updatedPieData = pieOption.series[0].data.map(item => {
+			const matchedData = res.data?.data.find(dataItem => dataItem.name === item.name)
+			return {
+				...item,
+				value: matchedData ? matchedData.value : item.value,
+			}
+		})
+		pieOption.series[0].data = updatedPieData
+		pieChart.value.setOption(pieOption)
+	})
+}
 onMounted(() => {
-    getData(newTime.value, 'TODAY');
-});
+	getData(newTime.value, 'TODAY')
+})
 </script>
 
 <style lang="scss" scoped>
 .inspection-rask-details {
-    margin-left: 29px;
-    // padding: 16px 16px;
-    width: 390px;
-    height: 526px;
-    background: linear-gradient(
-        270deg,
-        rgba(31, 62, 122, 0) 0%,
-        rgba(31, 62, 122, 0.35) 21%,
-        #1f3e7a 100%
-    );
-    border-radius: 0px 0px 0px 0px;
-    opacity: 0.85;
-    .chart-container {
-        width: 100%;
-        height: 220px;
-        margin-top: 20px;
-    }
-    .pie-container {
-        width: 100%;
-        height: 212px;
-        margin-top: 10px;
-    }
+	margin-left: 29px;
+	// padding: 16px 16px;
+	width: 390px;
+	height: 526px;
+	background: linear-gradient(270deg, rgba(31, 62, 122, 0) 0%, rgba(31, 62, 122, 0.35) 21%, #1f3e7a 100%);
+	border-radius: 0px 0px 0px 0px;
+	opacity: 0.85;
+	.chart-container {
+		width: 100%;
+		height: 220px;
+		margin-top: 20px;
+	}
+	.pie-container {
+		width: 100%;
+		height: 212px;
+		margin-top: 10px;
+	}
 }
 </style>
diff --git a/src/views/SignMachineNest/MachineRight/MachineMonitor.vue b/src/views/SignMachineNest/MachineRight/MachineMonitor.vue
index a0b30b8..ef582ce 100644
--- a/src/views/SignMachineNest/MachineRight/MachineMonitor.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineMonitor.vue
@@ -1,81 +1,90 @@
+<!--
+ * @Author: shuishen 1109946754@qq.com
+ * @Date: 2025-04-15 17:19:35
+ * @LastEditors: shuishen 1109946754@qq.com
+ * @LastEditTime: 2025-04-17 21:16:50
+ * @FilePath: \command-center-dashboard\src\views\SignMachineNest\MachineRight\MachineMonitor.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2025 by shuishen, All Rights Reserved. 
+-->
 <!-- 机巢监控 -->
 <template>
-  <CommonTitle title="直播监控" />
-  <div :style="{ marginLeft: pxToRem(14) }">
-    <div class="machine-monitor">
-      <LiveVideo :videoUrl="airPortUrl" />
-    </div>
-  </div>
+	<CommonTitle title="直播监控" />
+	<div :style="{ marginLeft: pxToRem(14) }">
+		<div class="machine-monitor">
+			<LiveVideo :videoUrl="airPortUrl" />
+		</div>
+	</div>
 </template>
 
 <script setup>
-import CommonTitle from '@/components/CommonTitle.vue';
-import LiveVideo from '@/components/LiveVideo.vue';
-import { liveStart } from '@/api/home/machineNest';
+import CommonTitle from '@/components/CommonTitle.vue'
+import LiveVideo from '@/components/LiveVideo.vue'
+import { liveStart } from '@/api/home/machineNest'
 // import { CURRENT_CONFIG as config } from '@/utils/http/config'
-import { useStore } from 'vuex';
+import { useStore } from 'vuex'
 
-
-const store = useStore();
+const store = useStore()
 // 单个机巢信息
-const singleUavHome = computed(() => store.state.home.singleUavHome);
+const singleUavHome = computed(() => store.state.home.singleUavHome)
 // 直播地址
-let airPortUrl = ref('');
+let airPortUrl = ref('')
 // 获取直播地址
-const getVideoUrl = (sn,quality) => {
-  liveStart(sn, quality).then(res => {
-    if (res.data.code !== 0) return;
-    airPortUrl.value = res.data.data.rtcs_url;
-  });
-};
-let isCurrentSn = ref(false);
-let CurrentSn = ref('');
+const getVideoUrl = (sn, quality) => {
+	liveStart(sn, quality).then(res => {
+		if (res.data.code !== 0) return
+		airPortUrl.value = res.data.data.rtcs_url
+	})
+}
+let isCurrentSn = ref(false)
+let CurrentSn = ref('')
 // 监听ws消息
 watch(
-  () => store.state.home.deviceState.deviceInfo,
-  (newValue) => {
-    CurrentSn.value = Object.keys(newValue)[0];
-    const currentDevice = newValue[CurrentSn.value];
-    if (currentDevice && currentDevice?.mode_code > 0) {
-      isCurrentSn.value = true;
-    } else if (currentDevice && currentDevice?.mode_code === 14) {
-      isCurrentSn.value = false;
-    } else {
-      isCurrentSn.value = false;
-    }
-  },
-  {
-    immediate: true,
-    deep: true,
-  }
-);
+	() => store.state.home.deviceState.deviceInfo,
+	newValue => {
+		CurrentSn.value = Object.keys(newValue)[0]
+		const currentDevice = newValue[CurrentSn.value]
+		if (currentDevice && currentDevice?.mode_code > 0) {
+			isCurrentSn.value = true
+		} else if (currentDevice && currentDevice?.mode_code === 14) {
+			isCurrentSn.value = false
+		} else {
+			isCurrentSn.value = false
+		}
+	},
+	{
+		immediate: true,
+		deep: true,
+	}
+)
 // 监听 isCurrentSn
-watch(isCurrentSn, (newVal) => {
-  if (newVal) {
-    getVideoUrl(CurrentSn.value, 2);
-  } else {
-    getVideoUrl(singleUavHome.value.device_sn,1);
-  }
-}, { immediate: true,deep: true });
+watch(
+	isCurrentSn,
+	newVal => {
+		if (newVal) {
+			getVideoUrl(CurrentSn.value, 2)
+		} else {
+			getVideoUrl(singleUavHome.value.device_sn, 1)
+		}
+	},
+	{ immediate: true, deep: true }
+)
+
 onMounted(() => {
-  getVideoUrl(singleUavHome.value.device_sn,1);
-});
+	// getVideoUrl(singleUavHome.value.device_sn,1);
+})
 </script>
 
 <style lang="scss" scoped>
-  .machine-monitor {
-    width: 390px;
-    height: 228px;
-    background: linear-gradient(
-      270deg,
-      #1f3e7a 0%,
-      rgba(31, 62, 122, 0.35) 79%,
-      rgba(31, 62, 122, 0) 100%
-    );
-    opacity: 0.85;
-    margin: 2px 0 13 0;
-    display: flex;
-    justify-content: space-between;
-    padding: 12px 10px 0;
- }
+.machine-monitor {
+	width: 390px;
+	height: 228px;
+	background: linear-gradient(270deg, #1f3e7a 0%, rgba(31, 62, 122, 0.35) 79%, rgba(31, 62, 122, 0) 100%);
+	opacity: 0.85;
+	margin: 2px 0 13 0;
+	display: flex;
+	justify-content: space-between;
+	padding: 12px 10px 0;
+}
 </style>
diff --git a/src/views/SignMachineNest/SignMachineNest.vue b/src/views/SignMachineNest/SignMachineNest.vue
index 2c73acd..33c48e8 100644
--- a/src/views/SignMachineNest/SignMachineNest.vue
+++ b/src/views/SignMachineNest/SignMachineNest.vue
@@ -19,7 +19,6 @@
 let connectWs = ref(null)
 // 单个机巢信息
 const singleUavHome = computed(() => store.state.home.singleUavHome)
-const selectedAreaCode = computed(() => store.state.user.selectedAreaCode)
 
 let osdVisible = ref({})
 

--
Gitblit v1.9.3