From 75cdd3cdcec1fc22bddebd6352e5e87e0a8d5d33 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Fri, 18 Apr 2025 10:57:41 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 src/assets/images/home/useUavHome/eventAggregationImg1.png                    |    0 
 src/layout/Header.vue                                                         |    8 
 src/page/login/index.vue                                                      |    4 
 src/utils/stateToImageMap/event.js                                            |   23 
 src/hooks/components/useMapHandlerClick.js                                    |   89 ++
 src/hooks/components/EventPopUpBox.vue                                        |   16 
 src/views/SignMachineNest/MachineRight/MachineMonitor.vue                     |  135 ++--
 src/styles/login.scss                                                         |   19 
 .env.test                                                                     |    3 
 src/views/SignMachineNest/SignMachineNest.vue                                 |    1 
 src/hooks/useMapAggregation/useMapAggregation.js                              |  139 +----
 src/views/Home/AINowFly.vue                                                   |    2 
 src/views/Home/SearchBox.vue                                                  |  442 ++++++++--------
 src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue               |  404 +++++++-------
 src/hooks/useSingleDroneMap/useSingleDroneMap.js                              |  135 ----
 .env.development                                                              |    2 
 src/assets/images/home/useUavHome/eventAggregationImg.png                     |    0 
 src/utils/stateToImageMap/drone.js                                            |   32 +
 .env.production                                                               |    2 
 src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue |   46 +
 20 files changed, 750 insertions(+), 752 deletions(-)

diff --git a/.env.development b/.env.development
index 4792921..c1b7c39 100644
--- a/.env.development
+++ b/.env.development
@@ -12,4 +12,4 @@
 VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/minio/cloud-bucket
 
 #系统运维
-VITE_APP_ADMIN_URL = 'https://wrj.shuixiongit.com/manage'
\ No newline at end of file
+VITE_APP_ADMIN_URL = 'https://wrj.shuixiongit.com/manage'
diff --git a/.env.production b/.env.production
index d4914e6..4e96c25 100644
--- a/.env.production
+++ b/.env.production
@@ -6,4 +6,4 @@
 # ws地址
 VITE_APP_WS_API_URL = wss://wrj.shuixiongit.com/drone-wss/api/v1/ws
 # 管理后台地址
-VITE_APP_ADMIN_URL = ' https://aisky.org.cn/manage'
+VITE_APP_ADMIN_URL = 'https://aisky.org.cn/manage'
diff --git a/.env.test b/.env.test
index 3ed2c36..1518c99 100644
--- a/.env.test
+++ b/.env.test
@@ -5,3 +5,6 @@
 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
+
+#系统运维
+VITE_APP_ADMIN_URL = 'https://wrj.shuixiongit.com/manage'
diff --git a/src/assets/images/home/useUavHome/eventAggregationImg.png b/src/assets/images/home/useUavHome/eventAggregationImg.png
index da95764..da133c4 100644
--- a/src/assets/images/home/useUavHome/eventAggregationImg.png
+++ b/src/assets/images/home/useUavHome/eventAggregationImg.png
Binary files differ
diff --git a/src/assets/images/home/useUavHome/eventAggregationImg1.png b/src/assets/images/home/useUavHome/eventAggregationImg1.png
new file mode 100644
index 0000000..da95764
--- /dev/null
+++ b/src/assets/images/home/useUavHome/eventAggregationImg1.png
Binary files differ
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/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/layout/Header.vue b/src/layout/Header.vue
index 3e67c19..8bdf2ca 100644
--- a/src/layout/Header.vue
+++ b/src/layout/Header.vue
@@ -128,14 +128,16 @@
     font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
     font-weight: 400;
     font-size: 45px;
-    color: #ffffff;
     line-height: 53px;
     letter-spacing: 11px;
-    text-shadow: 0px 4px 1px rgba(19, 80, 143, 0.66), 0px 0px 18px rgba(130, 165, 255, 0.4),
-      inset 0px 0px 2px rgba(255, 255, 255, 0.8);
+    text-shadow: 0px 4px 1px rgba(19,80,143,0.66), 0px 0px 18px rgba(130,165,255,0.4), inset 0px 0px 2px rgba(255,255,255,0.8);
     text-align: center;
     font-style: normal;
     text-transform: none;
+    background: linear-gradient(180deg, #FFFFFF 23%, #E9F8FF 46%, #77BAFF 76%);
+    -webkit-background-clip: text;
+    color: transparent;
+    background-clip: text;
   }
 
   .h-right {
diff --git a/src/page/login/index.vue b/src/page/login/index.vue
index 7e0f0a8..1049488 100644
--- a/src/page/login/index.vue
+++ b/src/page/login/index.vue
@@ -3,7 +3,7 @@
     <div class="login-header">
       <div class="title">中图智飞低空智能感知网平台</div>
     </div>
-    <div class="login-left-title">中国图强 智领飞跃</div>
+    <!-- <div class="login-left-title">中国图强 智领飞跃</div> -->
     <div class="login-left"></div>
     <userLogin v-if="activeName === 'user'"></userLogin>
   </div>
@@ -31,7 +31,7 @@
   data() {
     return {
       login:{
-        info: '中图智绘低空无人机监测网平台'
+        info: '中图智飞低空智能感知网平台'
       },
       website: website,
       time: '',
diff --git a/src/styles/login.scss b/src/styles/login.scss
index f46ceeb..07131c3 100644
--- a/src/styles/login.scss
+++ b/src/styles/login.scss
@@ -23,15 +23,17 @@
     text-align: center;
     font-style: normal;
     text-transform: none;
-    color: #fff;
-    // background: linear-gradient(90deg, #FFFFFF 0%, #B2D5FF 100%);
+    background: linear-gradient(180deg, #FFFFFF 0%, #B2D5FF 100%);
+    -webkit-background-clip: text;
+    color: transparent;
+    background-clip: text;
   }
 }
-.login-left-title-new {
+.login-left-title {
   position: absolute;
-  border: 1px solid greenyellow;
-  left: 147px;
-  top: 263px;
+  // border: 1px solid greenyellow;
+  left: 160px;
+  top: 240px;
   width: 926px;
   height: 42px;
   font-family: Source Han Sans CN, Source Han Sans CN;
@@ -44,7 +46,10 @@
   text-align: center;
   font-style: normal;
   text-transform: none;
-  // background: linear-gradient(90.00000000000004deg, #FFFFFF 0%, #E3FEFF 63%, #88BAFF 100%);
+  background: linear-gradient(90.00000000000004deg, #FFFFFF 0%, #E3FEFF 63%, #88BAFF 100%);
+  -webkit-background-clip: text;
+  color: transparent;
+  background-clip: text;
 }
 .login-left-new {
   position: absolute;
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/AINowFly.vue b/src/views/Home/AINowFly.vue
index 05a4f78..dbad17b 100644
--- a/src/views/Home/AINowFly.vue
+++ b/src/views/Home/AINowFly.vue
@@ -122,6 +122,8 @@
 	await ruleFormRef.value.validate()
 	if (!params.value.dock_sns.length) return ElMessage.warning('请选择将要飞行的机巢')
 	if (!params.value.longitude) return ElMessage.warning('请选择飞行的点')
+	// 先清除,再push
+	params.value.action_modes = [{action_actuator_func:'startRecord'}]
 	if (isPhoto.value) {
 		params.value.action_modes.push({action_actuator_func:'takePhoto'})
 	}
diff --git a/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue b/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue
index c74eacf..62c42e2 100644
--- a/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue
+++ b/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue
@@ -88,7 +88,9 @@
 									? 'finish '
 									: scope.row.status === 5
 									? 'fail '
-									: ' '">
+									: ' '
+							"
+						>
 							{{
 								scope.row.status === 1
 									? '待执行'
@@ -110,7 +112,11 @@
 						<span>{{ scope.row.event_number ? scope.row.event_number : '/' }}</span>
 					</template>
 				</el-table-column>
-				<el-table-column label="操作" width="80"><div class="ztzf-view">查看</div></el-table-column>
+				<el-table-column label="操作" width="80">
+					<template #default="scope">
+						<div class="ztzf-view" @click="viewDetail(scope.row)">查看</div>
+					</template>
+				</el-table-column>
 			</el-table>
 		</div>
 		<!-- 分页 -->
@@ -128,6 +134,18 @@
 			/>
 		</div>
 	</el-dialog>
+	<!-- 当前任务详情 -->
+	<CurrentTaskDetails
+		v-if="isShowCurrentTaskDetails"
+		v-model:show="isShowCurrentTaskDetails"
+		:id="currentTaskDetailsId"
+	/>
+	<!-- 历史任务详情 -->
+	<DeviceJobDetails
+		v-if="deviceJobDetailsShow"
+		v-model:show="deviceJobDetailsShow"
+		:wayLineJodInfoId="wayLineJodInfoId"
+	/>
 </template>
 <script setup>
 import { pxToRem } from '@/utils/rem'
@@ -135,6 +153,8 @@
 import { getDictionary } from '@/api/system/dict'
 import { selectDevicePage } from '@/api/home/machineNest'
 import { getMultipleDictionary } from '@/api/system/dictbiz'
+import CurrentTaskDetails from '@/components/CurrentTaskDetails/CurrentTaskDetails.vue'
+import DeviceJobDetails from '@/components/DeviceJobDetails/DeviceJobDetails.vue'
 const isShowDetailsDialog = defineModel('show')
 const dateRange = ref('')
 const searchForm = reactive({
@@ -148,7 +168,7 @@
 const statusOptions = [
 	{ label: '待执行', value: 1 },
 	{ label: '执行中', value: 2 },
-	{ label: '已完成', value: 3 },
+	{ label: '已执行', value: 3 },
 
 	{ label: '执行失败', value: 5 },
 ]
@@ -215,7 +235,6 @@
 }
 // 获取任务列表
 const getJobList = () => {
-	// 事件状态:0 =待处理,1=待分拨,2=待处理,3=处理中,4=已完成 5=已完结
 	jobList(taskDetailParams).then(res => {
 		if (res.data.code !== 0) return
 		taskDetailData.value = res.data.data.records
@@ -249,6 +268,23 @@
 		return 'warning-row'
 	} else {
 		return 'success-row'
+	}
+}
+// 查看
+	// 当前任务详情 1:待执行  2:执行中
+	// 历史任务详情 3:已执行  5:执行失败
+const isShowCurrentTaskDetails = ref(false)
+const currentTaskDetailsId = ref(null)
+const deviceJobDetailsShow = ref(false)
+const wayLineJodInfoId = ref(null)
+const viewDetail = row => {
+	if (row.status === 1 || row.status === 2) {
+		currentTaskDetailsId.value = row.id
+		isShowCurrentTaskDetails.value = true
+	}
+	if (row.status === 3 || row.status === 5) {
+		wayLineJodInfoId.value = row.id
+		deviceJobDetailsShow.value = true
 	}
 }
 onMounted(() => {
@@ -331,7 +367,7 @@
 }
 // 执行中
 .distributed {
-	color: #FFA768;
+	color: #ffa768;
 }
 // 已执行
 .finish {
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..8f44c2f 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: 10px 10px;
+}
 </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