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

---
 src/page/login/index.vue                                                         |    2 
 src/views/Home/HomeRight/EventOverview.vue                                       |  695 ++++++++++++------------
 src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue                  |  268 ++++++---
 src/views/TaskManage/SearchBox.vue                                               |   17 
 src/const/drc.js                                                                 |    3 
 src/api/payload.js                                                               |   12 
 src/components/CurrentTaskDetails/TaskDetailsLeft.vue                            |    9 
 src/styles/element-ui.scss                                                       |  136 ++++
 src/assets/images/home/useEventOperate/point.png                                 |    0 
 src/components/CurrentTaskDetails/CurrentTaskDetails.vue                         |   55 +
 src/assets/images/home/useEventOperate/point-active.png                          |    0 
 src/components/CurrentTaskDetails/RealTimeMap.vue                                |   45 
 src/hooks/controlDrone/useManualControl.js                                       |    9 
 src/views/Home/HomeLeft/OverviewNext.vue                                         |    5 
 src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue                  |  117 +++
 src/hooks/controlDrone/useMqtt.js                                                |    1 
 src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue    |   59 +
 src/views/TaskManage/TaskIntermediateContent/TaskIntermediateContent.vue         |   29 
 src/views/TaskManage/components/TaskAlgorithmBusiness.vue                        |    4 
 src/components/CurrentTaskDetails/TaskDetailsHead.vue                            |  176 +++++-
 src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue |    6 
 21 files changed, 1,085 insertions(+), 563 deletions(-)

diff --git a/src/api/payload.js b/src/api/payload.js
index aa4796a..8bc5a14 100644
--- a/src/api/payload.js
+++ b/src/api/payload.js
@@ -44,7 +44,7 @@
 // 拍照和录像
 export async function callPhotoAndVideoCmd(sn, type) {
   return await request({
-    url:`/drone-device-core/droneAirport/liveStreamApi/${sn}/payload/photoAndVideoCmd/${type}`,
+    url:`${API_PREFIX}/devices/${sn}/payload/photoAndVideoCmd/${type}`,
     method:'get',
   })
 }
@@ -132,4 +132,14 @@
 };
 
 
+// 无人机开启ai
+export const getLiveAiLinkApi = (data) => {
+  return request({
+    url:`/drone-device-core/manage/api/v1/live/streams/start/ai`,
+    method: 'post',
+    data,
+  });
+};
+
+
 
diff --git a/src/assets/images/home/useEventOperate/point-active.png b/src/assets/images/home/useEventOperate/point-active.png
index 3f5c556..c5869c7 100644
--- a/src/assets/images/home/useEventOperate/point-active.png
+++ b/src/assets/images/home/useEventOperate/point-active.png
Binary files differ
diff --git a/src/assets/images/home/useEventOperate/point.png b/src/assets/images/home/useEventOperate/point.png
index b574793..9caf3bd 100644
--- a/src/assets/images/home/useEventOperate/point.png
+++ b/src/assets/images/home/useEventOperate/point.png
Binary files differ
diff --git a/src/components/CurrentTaskDetails/ControlComPass/ControlComPass.vue b/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
similarity index 97%
rename from src/components/CurrentTaskDetails/ControlComPass/ControlComPass.vue
rename to src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
index 8ec1d8b..5685ca1 100644
--- a/src/components/CurrentTaskDetails/ControlComPass/ControlComPass.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
@@ -3,7 +3,7 @@
     <div class="left-img" :data-text="`${attitude_pitch}°`">
       <div class="scaleImg">
         <p class="scale" :style="{ top: 45 + ScaleTop + 'px' }"></p>
-        <img src="../../../assets/images/rightmapidentification.png" />
+        <img src="../../../../assets/images/rightmapidentification.png" />
       </div>
     </div>
     <div class="instrument-center">
@@ -14,13 +14,13 @@
         </div>
       </div>
       <div class="center-show">
-        <img src="../../../assets/images/mapidentification.png" />
+        <img src="../../../../assets/images/mapidentification.png" />
       </div>
       <div class="rotat-btn"></div>
     </div>
     <div class="right-img" :data-text="`${height}m`">
       <div class="ident-arrow">
-        <img src="../../../assets/images/leftmapidentification.png" />
+        <img src="../../../../assets/images/leftmapidentification.png" />
         <div class="arrow-box" :style="{ bottom: realHeight }">
           <div class="arrow"></div>
         </div>
diff --git a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
index 546ab80..901d30d 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
@@ -126,7 +126,7 @@
 	</div>
 </template>
 <script setup>
-import ControlComPass from '../ControlComPass/ControlComPass.vue'
+import ControlComPass from '@/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue'
 import { KeyCode, useManualControl } from '@/hooks/controlDrone/useManualControl'
 import { droneController, exitController, postDrc, returnHome, returnHomeCancel } from '@/api/drc'
 import { ElMessage } from 'element-plus'
@@ -144,12 +144,13 @@
 	RefreshLeft,
 	RefreshRight,
 } from '@element-plus/icons-vue'
-
+import _ from 'lodash'
 import BaseControl from '@/components/CurrentTaskDetails/ControlPanel/BaseControl.vue'
 import EventBus from '@/event-bus'
 import { getPayloadControlApi, ptzControlApi } from '@/api/payload'
 
 const deviceOsdInfo = inject('deviceOsdInfo')
+const host = computed(() => deviceOsdInfo?.value?.data?.host || {})
 const taskDetails = inject('taskDetails')
 const dockSn = inject('dockSn')
 const droneSn = inject('droneSn')
@@ -183,18 +184,106 @@
 	{ name: '左', key: KeyCode.ARROW_LEFT, operate: 'left', style: { left: '-70%' } },
 ]
 
-const list4 = [
-	[
-		{ name: '焦距倍数', value: '0' },
-		{ name: '俯仰角度', value: '0.0°' },
-		{ name: '横向角度', value: '0.0°' },
-	],
-	[
-		{ name: '储存', value: '64.5G' },
-		{ name: '方向', value: '正北' },
-		{ name: '方向', value: '正北' },
-	],
-]
+const list4 = computed(() => {
+	const { longitude, latitude, height, payloads } = host?.value || {}
+	const { gimbal_pitch } = payloads?.[0] || {} //俯仰角度
+	return [
+		[
+			{ name: '焦距倍数', value: '0' },
+			{ name: '俯仰角度', value: pitchAngle.value.angle },
+			{ name: '横向角度', value: yawAngle.value.angle },
+		],
+		[
+			{ name: '储存', value: '64.5G' },
+			{ name: '方向', value: pitchAngle.value.direction },
+			{ name: '方向', value: yawAngle.value.direction },
+		],
+	]
+})
+const pitchAngle = computed(() => {
+	const { longitude, latitude, height, payloads } = host?.value || {}
+	const gimbal_pitch = payloads?.[0]?.gimbal_pitch || 0
+	let direction = ''
+	if (gimbal_pitch > -2 && gimbal_pitch < 2) {
+		direction = '正前'
+	} else if (gimbal_pitch >= 2 && gimbal_pitch < 90) {
+		direction = '斜上'
+	} else if (gimbal_pitch === 90) {
+		direction = '正上'
+	} else if (gimbal_pitch <= -2 && gimbal_pitch > -90) {
+		direction = '斜下'
+	} else if (gimbal_pitch === -90 || gimbal_pitch < -90) {
+		direction = '正下'
+	}
+	return {
+		angle: _.round(gimbal_pitch || 0, 1) + '°',
+		direction,
+	}
+})
+
+const yawAngle = computed(() => {
+	let { longitude, latitude, height, payloads, attitude_head } = host?.value || {}
+	const gimbal_pitch = payloads?.[0]?.gimbal_pitch || 0
+	const gimbal_yaw = payloads?.[0]?.gimbal_yaw || 0
+	attitude_head = attitude_head || 0
+	let yaw = ''
+	if (gimbal_yaw > 180) {
+		yaw = gimbal_yaw
+	} else {
+		yaw = gimbal_yaw - attitude_head
+	}
+	let result = 0
+	if (yaw < 0) {
+		result = yaw + 360
+	}
+	if (yaw > 0) {
+		result = yaw
+	}
+	if ((yaw > -2 && yaw < 2) || parseInt(attitude_head) === parseInt(gimbal_yaw)) {
+		result = attitude_head < 0 ? 180 + (180 + attitude_head) : attitude_head
+	}
+	let direction = ''
+	const roundResult = Math.round(result)
+	if (roundResult === 0) {
+		direction = '正北'
+	} else if (roundResult > 0 && roundResult < 45) {
+		direction = '北偏东'
+	} else if (roundResult === 45) {
+		direction = '东北'
+	} else if (roundResult > 45 && roundResult < 90) {
+		direction = '北偏东'
+	} else if (roundResult === 90) {
+		direction = '正东'
+	} else if (roundResult > 90 && roundResult < 135) {
+		direction = '东偏南'
+	} else if (roundResult === 135) {
+		direction = '东南'
+	} else if (roundResult > 135 && roundResult < 180) {
+		direction = '南偏东'
+	} else if (roundResult === 180) {
+		direction = '正南'
+	} else if (roundResult > 180 && roundResult < 225) {
+		direction = '南偏西'
+	} else if (roundResult === 225) {
+		direction = '西南'
+	} else if (roundResult > 225 && roundResult < 270) {
+		direction = '西偏南'
+	} else if (roundResult === 270) {
+		direction = '正西'
+	} else if (roundResult > 270 && roundResult < 315) {
+		direction = '西偏北'
+	} else if (roundResult === 315) {
+		direction = '西北'
+	} else if (roundResult > 315 && roundResult < 360) {
+		direction = '北偏西'
+	} else if (roundResult === 360) {
+		direction = '正北'
+	}
+	return {
+		angle: _.round(result, 1) + '°',
+		direction,
+	}
+})
 
 const deviceTopicInfo = ref({
 	pubTopic: '',
diff --git a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
index 1d8f12c..d259b64 100644
--- a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
+++ b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -47,21 +47,29 @@
 import { ElMessage } from 'element-plus'
 import EventBus from '@/event-bus'
 import { updateDroneQualityApi } from '@/api/drc'
+import { getLiveAiLinkApi } from '@/api/payload'
+import { CURRENT_CONFIG } from '@/utils/http/config'
 
 const isAutoControl = ref(true)
 const lineQuality = ref(1) //1流畅,2标清
 provide('isAutoControl', isAutoControl)
 provide('lineQuality', lineQuality)
 
+const taskDetailsViewer = ref(null)
+provide('taskDetailsViewer', taskDetailsViewer)
+
 let taskDetails = ref({})
-const deviceOsdInfo = ref({})
 provide('taskDetails', taskDetails)
+const deviceOsdInfo = ref({})
 provide('deviceOsdInfo', deviceOsdInfo)
 
 const dockSn = computed(() => taskDetails?.value?.device_sns?.[0])
 const droneSn = computed(() => deviceOsdInfo?.value?.data?.sn)
 provide('dockSn', dockSn)
 provide('droneSn', droneSn)
+
+const isAiLive = ref(false)
+provide('isAiLive', isAiLive)
 
 const isShow = defineModel('show')
 const props = defineProps(['id'])
@@ -70,19 +78,27 @@
 const isMaxMap = ref(false)
 let droneWebSocket //WS实例
 
-// 机巢直播
+const video_id = ref('')
+provide('video_id', video_id)
+
+// 获取机巢直播
 const getDeviceLiveUrl = async () => {
 	const res = await liveStart(dockSn.value, 2)
 	currentLiveUrl.value = res.data.data.rtcs_url
 }
 
-const video_id = ref('')
+const getAiLiveUrl = ()=>{
+	const res = getLiveAiLinkApi({ original_stream_url: `${CURRENT_CONFIG.rtmpURL}${video_id.value}`, video_id:video_id.value })
+	currentLiveUrl.value = res.data.data.rtcs_url
+	isAiLive.value = true
+}
 
 // 获取无人机直播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
+	isAiLive.value = false
 }
 
 // 无人机直播画质切换
@@ -113,14 +129,41 @@
 	})
 }
 
+const dockOsdInfo = ref({})
+provide('dockOsdInfo', dockOsdInfo)
+
+const wsInfo = ref({})
+provide('wsInfo', wsInfo)
 // websocket 的消息回调
 const messageHandler = result => {
 	let payload = JSON.parse(result)
+	wsInfo.value[payload.biz_code] = payload
 	switch (payload.biz_code) {
+		// 无人机
 		case EBizCode.DeviceOsd: {
 			deviceOsdInfo.value = payload
 			setCurrentLiveUrl()
-			console.log(deviceOsdInfo.value, 'device_osd信息')
+			console.log(payload, 'DeviceOsd--信息')
+			break
+		}
+		// 遥控器
+		case EBizCode.GatewayOsd: {
+			console.log(payload, 'GatewayOsd--信息')
+			break
+		}
+		// 机巢
+		case EBizCode.DockOsd: {
+			console.log(payload, 'DockOsd--信息')
+			break
+		}
+		// PsdkWidgetValues
+		case EBizCode.PsdkWidgetValues: {
+			console.log(payload, 'PsdkWidgetValues--信息')
+			break
+		}
+		// VideoSurveillance
+		case EBizCode.VideoSurveillance: {
+			console.log(payload, 'VideoSurveillance--信息')
 			break
 		}
 		default:
@@ -140,6 +183,8 @@
 onMounted(() => {
 	getTaskDetails()
 	EventBus.on('CurrentTaskDetails-timeStop', changeLineQuality)
+	EventBus.on('CurrentTaskDetails-getAiLiveUrl', getAiLiveUrl)
+	EventBus.on('CurrentTaskDetails-getDroneLiveUrl', getDroneLiveUrl)
 })
 
 onBeforeUnmount(() => {
@@ -147,6 +192,8 @@
 	deviceOsdInfo.value = {}
 	droneWebSocket = null
 	EventBus.off('CurrentTaskDetails-timeStop', changeLineQuality)
+	EventBus.off('CurrentTaskDetails-getAiLiveUrl', getAiLiveUrl)
+	EventBus.off('CurrentTaskDetails-getDroneLiveUrl', getDroneLiveUrl)
 })
 </script>
 
diff --git a/src/components/CurrentTaskDetails/RealTimeMap.vue b/src/components/CurrentTaskDetails/RealTimeMap.vue
index 4a63684..c5c01bc 100644
--- a/src/components/CurrentTaskDetails/RealTimeMap.vue
+++ b/src/components/CurrentTaskDetails/RealTimeMap.vue
@@ -26,12 +26,14 @@
 	tilingScheme: new AmapMercatorTilingScheme(),
 	credit: 'amap_SL',
 })
-let viewer = null
+
+const taskDetailsViewer = inject('taskDetailsViewer')
+
 const taskDetails = inject('taskDetails')
 const deviceOsdInfo = inject('deviceOsdInfo')
 
 const initMap = () => {
-	viewer = new Viewer('currentTaskMap', {
+	taskDetailsViewer.value = new Viewer('currentTaskMap', {
 		terrain: Terrain.fromWorldTerrain(),
 		infoBox: false, // 禁用沙箱,解决控制台报错
 		animation: false, // 左下角的动画仪表盘
@@ -45,17 +47,17 @@
 		baseLayer: false,
 		fullscreenButton: false,
 	})
-	const gdLayer = viewer.imageryLayers.addImageryProvider(imageryProvider_ammapSL)
+	const gdLayer = taskDetailsViewer?.value.imageryLayers.addImageryProvider(imageryProvider_ammapSL)
 	const options = {
 		bInvertColor: true,
 		bFilterColor: true,
 		filterColor: '#4e70a6',
 	}
 	// 添加蓝色滤镜
-	addBlueFilter(options, viewer, gdLayer)
-	viewer.scene.morphTo2D(0)
+	addBlueFilter(options, taskDetailsViewer?.value, gdLayer)
+	taskDetailsViewer?.value.scene.morphTo2D(0)
 	//设置默认点
-	viewer.camera.setView({
+	taskDetailsViewer?.value.camera.setView({
 		destination: Cartesian3.fromDegrees(115.763819, 28.787374, 5000),
 	})
 }
@@ -66,7 +68,7 @@
 		return Cartesian3.fromDegrees(Number(lon), Number(lat))
 	})
 	// 起点
-	viewer.entities.add({
+	taskDetailsViewer?.value.entities.add({
 		position: positions[0],
 		billboard: {
 			image: new Cesium.ConstantProperty(rwqfdImg),
@@ -75,7 +77,7 @@
 		},
 	})
 	// 终点
-	viewer.entities.add({
+	taskDetailsViewer?.value.entities.add({
 		position: positions[positions.length - 1],
 		billboard: {
 			image: new Cesium.ConstantProperty(endPointImg),
@@ -85,7 +87,7 @@
 		},
 	})
 	// 路径线
-	viewer.entities.add({
+	taskDetailsViewer?.value.entities.add({
 		polyline: {
 			width: 4,
 			positions: positions,
@@ -108,29 +110,28 @@
 	const waylinesXMLObj = removeTextKey(waylinesXMLJSON.Folder)
 	if (!waylinesXMLObj.Placemark.length) return
 	const allPoint = waylinesXMLObj.Placemark.map(item => item.Point.coordinates.split(','))
-	flyVisual(allPoint, viewer)
+	flyVisual(allPoint, taskDetailsViewer?.value)
 	drawWayline(waylinesXMLObj)
 }
 
 const removeMap = () => {
-	viewer.entities.removeAll()
-	viewer.destroy()
+	taskDetailsViewer?.value.entities.removeAll()
+	taskDetailsViewer?.value.destroy()
 }
-
 let viewInfoFrustum
 // 设置视椎
 const setCreateFrustum = () => {
-	const deviceInfo = deviceOsdInfo.value?.data?.host
-	if (!deviceInfo) return
+	const host = deviceOsdInfo.value?.data?.host
+	if (!host) return
 	viewInfoFrustum?.clear()
-	if ([14, 0].includes(deviceInfo.mode_code)) return
-	const attitude_head = 180 + deviceInfo.attitude_head
-	const gimbal_pitch = 90 - Number(deviceInfo?.payloads[0]?.gimbal_pitch) || 0
-	viewInfoFrustum = new CreateFrustum(viewer, {
+	if ([14, 0].includes(host.mode_code)) return
+	const attitude_head = 180 + host.attitude_head
+	const gimbal_pitch = 90 - Number(host?.payloads[0]?.gimbal_pitch) || 0
+	viewInfoFrustum = new CreateFrustum(taskDetailsViewer?.value, {
 		position: {
-			longitude: deviceInfo.longitude,
-			latitude: deviceInfo.latitude,
-			altitude: deviceInfo.height,
+			longitude: host.longitude,
+			latitude: host.latitude,
+			altitude: host.height,
 		},
 		width: 30,
 		height: 30,
diff --git a/src/components/CurrentTaskDetails/TaskDetailsHead.vue b/src/components/CurrentTaskDetails/TaskDetailsHead.vue
index 91ed227..19f7ca0 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsHead.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsHead.vue
@@ -1,17 +1,19 @@
 <template>
 	<div class="detailsHead">
-		<div class="droneName">小蓝工业园</div>
+		<div class="droneName" :title="taskDetails.name">{{ taskDetails.name }}</div>
 		<div class="infoListBox">
 			<div v-for="item in infoList">
-				<div class="infoValue">{{ item.value }}</div>
+				<div class="infoValue" :title="item.value">{{ item.value }}{{ item.unit }}</div>
 				<div class="infoTitle">{{ item.title }}</div>
 			</div>
 		</div>
 		<div class="controlBtn">
-			<el-icon class="refresh"><Refresh /></el-icon>
+			<el-icon class="refresh" @click="refreshLive">
+				<Refresh />
+			</el-icon>
 			<div class="switchBtn" @click="switchBtn">
-				<div :class="{ open: open }">NO</div>
-				<div :class="{ open: !open }">OFF</div>
+				<div :class="{ open: !isAiLive }">OFF</div>
+				<div :class="{ open: isAiLive }">ON</div>
 			</div>
 		</div>
 	</div>
@@ -19,26 +21,117 @@
 
 <script setup>
 import { Refresh } from '@element-plus/icons-vue'
+import { getFlightStatistics } from '@/api/home/machineNest'
+import _, { throttle } from 'lodash'
+import { getLnglatAltitude, getLnglatDist } from '@/utils/cesium/mapUtil'
+import { fourGQuality, SDRQuality } from '@/const/drc'
+import { ElMessage } from 'element-plus'
+import EventBus from '@/event-bus'
 
-const open = ref(true)
+const taskDetailsViewer = inject('taskDetailsViewer')
+const wsInfo = inject('wsInfo')
+const dockSn = inject('dockSn')
+const taskDetails = inject('taskDetails')
+const isAiLive = inject('isAiLive')
+const singleTotal = ref({})
+
+// 不要随意更换顺序,有联动
+const infoList = ref([
+	{ index: 0, title: '实时真高', value: 0, unit: 'M' },
+	{ index: 1, title: '绝对高度', value: 0, unit: 'M' },
+	{ index: 2, title: '水平速度', value: 0, unit: 'M/s' },
+	{ index: 3, title: '垂直速度', value: 0, unit: 'M/s' },
+	{ index: 4, title: '经度', value: 0, unit: '°' },
+	{ index: 5, title: '纬度', value: 0, unit: '°' },
+	{ index: 6, title: '风速', value: 0, unit: 'M/s' },
+	{ index: 7, title: '4G信号', value: 0, unit: '' },
+	{ index: 8, title: 'SDR信号', value: 0, unit: '' },
+	{ index: 9, title: 'GPS搜星数', value: 0, unit: '' },
+	{ index: 10, title: 'RTK搜星数', value: 0, unit: '' },
+	{ index: 11, title: '距离机场', value: 0, unit: 'M' },
+	{ index: 12, title: '飞行时长', value: 0, unit: '小时' },
+	{ index: 13, title: '电池电量', value: 0, unit: '%' },
+])
+
 const switchBtn = () => {
-	open.value = !open.value
+	if (isAiLive.value) {
+		EventBus.emit('CurrentTaskDetails-getDroneLiveUrl')
+	} else {
+		EventBus.emit('CurrentTaskDetails-getAiLiveUrl')
+	}
 }
-const infoList = [
-	{ title: '实时真高', value: '0' },
-	{ title: '绝对高度', value: '0' },
-	{ title: '水平速度', value: '0' },
-	{ title: '垂直速度', value: '0' },
-	{ title: '经度', value: '0' },
-	{ title: '纬度', value: '0' },
-	{ title: '4G信号', value: '0' },
-	{ title: 'SDR信号', value: '0' },
-	{ title: 'GPS搜星数', value: '0' },
-	{ title: 'RTK搜星数', value: '0' },
-	{ title: '距离机场', value: '0' },
-	{ title: '飞行时长', value: '0' },
-	{ title: '电池电量', value: '0' },
-]
+
+function refreshLive(){
+	EventBus.emit('CurrentTaskDetails-getDroneLiveUrl')
+}
+
+function getFlightStatisticsFun() {
+	if (!dockSn.value) return
+	getFlightStatistics(dockSn.value).then(res => {
+		singleTotal.value = res.data.data
+	})
+}
+
+function getRealTimeReallyHigh() {
+	if (!taskDetailsViewer?.value) return
+	const device_osd_host = wsInfo?.value?.device_osd?.data?.host || {}
+	const { latitude, longitude, height } = device_osd_host
+	if (!latitude) return
+	getLnglatAltitude(longitude, latitude, taskDetailsViewer.value).then(res => {
+		const last = height - res?.height
+		infoList.value[0].value = last ? infoList.value[0].value : _.round(height - res?.height, 1)
+	})
+}
+
+function getHeadInfo() {
+	const device_osd_host = wsInfo?.value?.device_osd?.data?.host || {}
+	const dock_osd_host = wsInfo?.value?.dock_osd?.data?.host || {}
+	const { longitude, latitude, height, horizontal_speed, vertical_speed, wind_speed, battery } = device_osd_host
+	const { longitude: dockLon, latitude: dockLat, wireless_link } = dock_osd_host
+
+	let dist = infoList.value[11].value
+	if (longitude && latitude && dockLon && dockLat) {
+		dist = _.round(getLnglatDist(longitude, latitude, dockLon, dockLat), 0)
+	}
+
+	const newGPSNum = dock_osd_host?.position_state?.gps_number
+	const newRTKNum = dock_osd_host?.position_state?.rtk_number
+	const newFourG = wireless_link?.['4g_quality']
+	const newSdr = wireless_link?.['sdr_quality']
+
+	infoList.value[1].value = _.round(height || 0, 1)
+	infoList.value[2].value = _.round(horizontal_speed || 0, 0)
+	infoList.value[3].value = _.round(vertical_speed || 0, 0)
+	infoList.value[4].value = _.round(longitude || 0, 2)
+	infoList.value[5].value = _.round(latitude || 0, 2)
+	infoList.value[6].value = _.round(wind_speed || 0, 0)
+	if (newFourG !== undefined) infoList.value[7].value = fourGQuality[newFourG]
+	if (newSdr !== undefined) infoList.value[8].value = SDRQuality[newSdr]
+	if (newGPSNum !== undefined) infoList.value[9].value = newGPSNum
+	if (newRTKNum !== undefined) infoList.value[10].value = newRTKNum
+	infoList.value[11].value = dist
+	infoList.value[12].value = _.round(singleTotal.value?.hour_count || 0, 1)
+	infoList.value[13].value = battery?.capacity_percent || 0
+	getRealTimeReallyHigh()
+}
+
+const getHeadInfoThrottle = throttle(getHeadInfo, 1000, { leading: true, trailing: true })
+
+watch(
+	wsInfo,
+	() => {
+		getHeadInfoThrottle()
+	},
+	{ immediate: true, deep: true }
+)
+
+watch(
+	dockSn,
+	() => {
+		getFlightStatisticsFun()
+	},
+	{ immediate: true }
+)
 </script>
 
 <style scoped lang="scss">
@@ -48,7 +141,7 @@
 	z-index: 5;
 	width: 100%;
 	height: 68px;
-	background: rgb(0,0,0,.4); /* 半透明背景 */
+	background: rgb(0, 0, 0, 0.4); /* 半透明背景 */
 	backdrop-filter: blur(5px);
 	padding: 0 31px;
 	display: flex;
@@ -67,6 +160,10 @@
 		color: #ededed;
 		text-align: center;
 		line-height: 42px;
+		white-space: nowrap;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		padding: 0 10px;
 	}
 
 	.infoListBox {
@@ -74,21 +171,30 @@
 		flex: 1;
 		display: flex;
 		align-items: center;
-		justify-content: space-around;
+		justify-content: space-evenly;
 		font-family: Segoe UI, Segoe UI;
 		font-weight: 400;
+		margin-left: 15px;
 
-		.infoValue {
-			font-size: 20px;
-			color: #ffffff;
-			line-height: 15px;
-			margin-bottom: 10px;
-		}
+		> div {
+			width: 90px;
 
-		.infoTitle {
-			font-size: 12px;
-			color: #d2e8fa;
-			line-height: 15px;
+			.infoValue {
+				white-space: nowrap;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				font-size: 20px;
+				color: #ffffff;
+				line-height: 18px;
+				margin-bottom: 10px;
+
+			}
+
+			.infoTitle {
+				font-size: 12px;
+				color: #d2e8fa;
+				line-height: 15px;
+			}
 		}
 	}
 
@@ -98,7 +204,7 @@
 		align-items: center;
 		justify-content: space-between;
 
-		.refresh{
+		.refresh {
 			color: white;
 			font-size: 30px;
 			cursor: pointer;
diff --git a/src/components/CurrentTaskDetails/TaskDetailsLeft.vue b/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
index 1f80069..0e39eca 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
@@ -143,7 +143,7 @@
 
 // 修改相机参数
 function cameraParamsChange() {
-	const { camera_type, zoom_factor} = cameraParams.value
+	const { camera_type, zoom_factor } = cameraParams.value
 	cameraParamsChangeApi({
 		sn: dockSn.value,
 		...cameraParams.value,
@@ -176,7 +176,7 @@
 	const msg = isRecording.value ? '停止录像' : '开始录像'
 	const emitType = isRecording.value ? 'controlPanel-timeStop' : 'controlPanel-timeStart'
 
-	callPhotoAndVideoCmd(droneSn.value, type).then(res => {
+	callPhotoAndVideoCmd(dockSn.value, type).then(res => {
 		ElMessage.success(msg)
 		EventBus.emit(emitType)
 		isRecording.value = !isRecording.value
@@ -185,8 +185,11 @@
 
 // 拍照
 function takePictures() {
+	if (isRecording.value) {
+		return ElMessage.warning('请先结束录像')
+	}
 	// photo拍照,video_start开始录像,video_stop结束录像
-	callPhotoAndVideoCmd(droneSn.value, 'photo').then(res => {
+	callPhotoAndVideoCmd(dockSn.value, 'photo').then(res => {
 		ElMessage.success('拍照成功')
 	})
 }
diff --git a/src/const/drc.js b/src/const/drc.js
index 1c601b5..c4a4ad1 100644
--- a/src/const/drc.js
+++ b/src/const/drc.js
@@ -7,3 +7,6 @@
 	HSI_INFO_PUSH: 'hsi_info_push', // 避障信息上报
 	DELAY_TIME_INFO_PUSH: 'delay_info_push', // 图传链路延时信息上报
 }
+
+export const fourGQuality = { 0: '无信号', 1: '差', 2: '较差', 3: '一般', 4: '较好', 5: '好' }
+export const SDRQuality = { 0: '无信号', 1: '差', 2: '较差', 3: '一般', 4: '较好', 5: '好' }
diff --git a/src/hooks/controlDrone/useManualControl.js b/src/hooks/controlDrone/useManualControl.js
index 4ccce9f..c21c5c6 100644
--- a/src/hooks/controlDrone/useManualControl.js
+++ b/src/hooks/controlDrone/useManualControl.js
@@ -38,7 +38,7 @@
 export function useManualControl(mqttState,deviceTopicInfo, isCurrentFlightController,paramsRef) {
 	let activeCodeKey = null
 	let genPortOne = true //是一代机场
-	const mqttHooks = useMqtt(mqttState,deviceTopicInfo)
+	let mqttHooks = useMqtt(mqttState,deviceTopicInfo)
 	let seq = 0
 	const keysPressed = [
 		{key: 'KeyQ', value: false},
@@ -281,11 +281,10 @@
 		{ immediate: true }
 	)
 
-	onBeforeUnmount(()=>{
-		mqttHooks?.d
-	})
-
 	onUnmounted(() => {
+		deviceTopicInfo.subTopic = ''
+		deviceTopicInfo.pubTopic = ''
+		mqttHooks = null
 		closeKeyboardManualControl()
 	})
 
diff --git a/src/hooks/controlDrone/useMqtt.js b/src/hooks/controlDrone/useMqtt.js
index caaff48..8ac4679 100644
--- a/src/hooks/controlDrone/useMqtt.js
+++ b/src/hooks/controlDrone/useMqtt.js
@@ -67,6 +67,7 @@
       // 2.发心跳
       publishDrcPing(deviceTopicInfo.sn)
     } else {
+      console.log('清除pingInterval')
       clearInterval(state.heartState.get(deviceTopicInfo.sn)?.pingInterval)
       state.heartState.delete(deviceTopicInfo.sn)
       heartBeatSeq.value = 0
diff --git a/src/page/login/index.vue b/src/page/login/index.vue
index 426e960..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>
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index 878186d..5668e7c 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -236,9 +236,68 @@
   .el-range-separator {
     color: #ffffff;
   }
+ 
+  
 }
+ // 日期下拉框
+.custom-date-picker {
+	background: #012350 !important;
+	border: 1px solid !important;
+	border-radius: 0px 0px 8px 8px;
+	border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
+	/* 修改箭头样式 */
+	.el-popper__arrow {
+		&::before {
+			background: #0d3556 !important;
+			border: 1px solid #0d3556 !important;
+			box-sizing: border-box;
+		}
+	}
+	/* 修改头部背景色 */
+	.custom-date-picker .el-picker-panel__header {
+		background: linear-gradient(180deg, rgba(13, 53, 86, 0.85) 0%, rgba(1, 35, 80, 0.85) 100%) !important;
+		color: #fff !important;
+	}
+	.el-date-table {
+		th {
+			color: #fff !important; /* 星期标题颜色 */
+		}
+	}
+	/* 修改日期单元格悬停/选中状态 */
+	.custom-date-picker .el-date-table td:hover,
+	.custom-date-picker .el-date-table td.current:not(.disabled) {
+		background: rgba(60, 121, 202) !important;
+		color: white !important;
+	}
+	// 头部按钮
+	.el-date-table td.start-date span,
+	.el-date-table td.start-date span,
+	.el-date-table td.end-date span {
+		background-color: #012350 !important;
+	}
 
+	.el-date-table td.in-range div,
+	.el-date-table td.in-range div:hover,
+	.el-date-table.is-week-mode .el-date-table__row.current div,
+	.el-date-table.is-week-mode .el-date-table__row:hover div {
+		background-color: rgba(60, 121, 202) !important;
+	}
+  .el-picker-panel__icon-btn {
+    color: #fff !important;
+    
+    &:hover {
+      color: var(--el-color-primary) !important;
+    }
+    
+    .el-icon {
+      &::before {
+        color: inherit !important;
+      }
+    }
+  }
+}
 //下拉
+// :teleported="false"
 .ztzf-select {
   .el-select__wrapper {
     background: #012A50;
@@ -254,6 +313,83 @@
       color: #ffffff;
     }
   }
+
+
+  // 下拉框
+  .el-select-dropdown__empty {
+    background: #012A50;
+    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;
+  }
+  .el-select-dropdown__list {
+    padding: 0 !important;
+  }
+  .el-select-dropdown {
+    overflow-x: hidden !important;
+  
+    .el-select-dropdown__wrap {
+      overflow-x: hidden !important;
+      margin-right: 0 !important;
+    }
+  }
+  .el-select-dropdown__wrap {
+    overflow-x: hidden !important;
+    margin-right: 0 !important;
+  }
+  /* 箭头样式 */
+  .el-popper__arrow::before {
+    background: #0d3556 !important;
+    border: 1px solid #0d3556 !important;
+  }
+  .el-select {
+    --el-select-border-color-hover: rgb(0, 162, 255) !important;
+    /* // 修改下拉框hover的默认样式 */
+  }
+  
+  .el-input {
+    --el-border-color: rgb(0, 162, 255);
+    /* // 修改下拉框的边框 */
+  }
+  
+  .el-select .el-input__wrapper {
+    background-color: #012350 !important;
+    /* // 外层下拉框背景 */
+  }
+  
+  .el-input__wrapper {
+    --el-input-text-color: #012350 !important; /* // 修改外层下拉框的颜色 */
+  }
+  
+  .el-select__popper.el-popper {
+    border: rgba(0, 27, 63) !important;
+    /* // 修改内部下拉框的边框颜色 */
+  }
+  
+  .el-select-dropdown__wrap {
+    background: linear-gradient(180deg, rgba(13, 53, 86, 0.85) 0%, rgba(1, 35, 80, 0.85) 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;
+    /* // 下拉框背景色 */
+  }
+  
+  .el-select-dropdown__item {
+    background: rgba(0, 27, 63) !important; /* // 下拉框选项的颜色 */
+  }
+  
+  .el-select-dropdown__item {
+    color: white;
+  }
+  
+  .el-select-dropdown__item.hover {
+    background-color: rgba(0, 120, 233, 0.63) !important;
+    color: white;
+  }
+  .el-select-dropdown__item.selected {
+    color: #8ac3fd !important;
+    font-weight: 700;
+  }
 }
 
 .ztzf-input{
diff --git a/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue b/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue
index 9d4161f..502ccc2 100644
--- a/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue
+++ b/src/views/Home/EventOverviewDetail/EventOverviewDetailRight.vue
@@ -1,9 +1,15 @@
 <template>
 	<div class="event-overviewdetail-right" :class="{ isMore }">
-		<CommonTitle title="事件概况" :style="{width: isMore?pxToRem(820):pxToRem(404)}" />
+		<CommonTitle title="事件概况" :style="{ width: isMore ? pxToRem(820) : pxToRem(404) }" />
 
 		<div class="content">
-			<img class="leftArrow" :class="isMore?'rightArrow':''" :src="isMore ? rightArrowImg : leftArrowImg" @click="leftArrowFun" alt="" />
+			<img
+				class="leftArrow"
+				:class="isMore ? 'rightArrow' : ''"
+				:src="isMore ? rightArrowImg : leftArrowImg"
+				@click="leftArrowFun"
+				alt=""
+			/>
 
 			<el-date-picker
 				class="ztzf-date-picker"
@@ -50,7 +56,7 @@
 					<img class="statusItemImg" :src="item.img" alt="" />
 					<div class="statusItemInfo">
 						<div class="statusItemName">{{ item.name }}</div>
-						<div class="statusItemNum" :style="{ color:item.color }">{{ item.num || 0 }}</div>
+						<div class="statusItemNum" :style="{ color: item.color }">{{ item.num || 0 }}</div>
 					</div>
 				</div>
 			</div>
@@ -66,12 +72,7 @@
 
 			<div class="eventList">
 				<div class="eventListItem" v-for="item in list">
-					<img
-						class="eventListItemImg"
-						:src="getSmallImg(item.photo_url)"
-						alt=""
-						@click="getFindImgHistory(item)"
-					/>
+					<img class="eventListItemImg" :src="getSmallImg(item.photo_url)" alt="" @click="getFindImgHistory(item)" />
 					<div class="eventListItemPosition" :title="item.address" @click="positioning(item)">
 						<img :src="positioningImg" alt="" title="点击定位" />
 						<!-- <div class="address">{{ item.address }}</div> -->
@@ -96,23 +97,32 @@
 			</div>
 		</div>
 	</div>
-	<div class="image-list" v-if="isShowBigImg" :style="{ right: isMore?pxToRem(840):pxToRem(460) }">
+	<div class="image-list" v-if="isShowBigImg" :style="{ right: isMore ? pxToRem(838) : pxToRem(460) }">
 		<div class="title">
-			<img @click="isShowBigImg=false" src="@/assets/images/home/useEventOperate/close.png" alt="">
+			<img @click="isShowBigImg = false" src="@/assets/images/home/useEventOperate/close.png" alt="" />
 		</div>
 		<div class="content">
-			<img :src="clickImgSrc" alt="">
+			<img :src="clickImgSrc" alt="" />
 		</div>
 		<div class="card">
-			<div v-for="(item,index) in imageList">
-				<div class="time-top" :class="index===selectedImgIndex?'active':''" @click="clickWeekTime(item,index)">{{ item.create_time_str }}</div>
-				<div class="time-point">
-					<img v-if="index===selectedImgIndex" src="@/assets/images/home/useEventOperate/point-active.png" alt="">
-					<img v-else src="@/assets/images/home/useEventOperate/point.png" alt="">
+			<div class="card-content">
+				<div v-for="(item, index) in imageList">
+					<div class="time-top" :class="index === selectedImgIndex ? 'active' : ''" @click="clickWeekTime(item, index)">
+						{{ item.create_time_str }}
+					</div>
+					<div class="time-point">
+						<img
+							class="active"
+							v-if="index === selectedImgIndex"
+							src="@/assets/images/home/useEventOperate/point-active.png"
+							alt=""
+						/>
+						<img v-else src="@/assets/images/home/useEventOperate/point.png" alt="" />
+					</div>
+					<div class="time-bottom">{{ item.create_time }}</div>
 				</div>
-				<div class="time-bottom">{{ item.create_time }}</div>
+				<div class="time-line"></div>
 			</div>
-			<div class="time-line"></div>
 		</div>
 	</div>
 </template>
@@ -159,7 +169,7 @@
 	size: 8,
 })
 
-const getSmallImg = (url) => {
+const getSmallImg = url => {
 	return url ? url.substring(0, url.lastIndexOf('.')) + '_small' + url.substring(url.lastIndexOf('.')) : ''
 }
 
@@ -195,16 +205,16 @@
 	})
 }
 const { flyTo } = cesiumOperation()
-const longitudeOffset = ref(0);
+const longitudeOffset = ref(0)
 const positioning = row => {
 	const longitude = Number(row.longitude)
 	const latitude = Number(row.latitude)
-	flyTo({ longitude: longitude, latitude:latitude + 0.0002 }, 1, 1000);
+	flyTo({ longitude: longitude, latitude: latitude + 0.0008 }, 1, 1000)
 }
 
 // 事件状态+数量
 const statusList = ref([
-	{ name: '全部状态', img: status0Img, id: undefined,few: true, color: '#FFD509' },
+	{ name: '全部状态', img: status0Img, id: undefined, few: true, color: '#FFD509' },
 	{ name: '待审核', img: status1Img, id: 2, color: '#8CFEA7' },
 	{ name: '待处理', img: status2Img, id: 0, few: true, color: '#FF7411' },
 	{ name: '处理中', img: status3Img, id: 3, few: true, color: '#FFC398' },
@@ -241,7 +251,7 @@
 	params.value.start_date = start_date
 	params.value.end_date = end_date
 	// 提交数据,更新聚合
-	store.commit('setEventTimeRang', timeArr.value);
+	store.commit('setEventTimeRang', timeArr.value)
 	// 重置
 	getEventStatusNumFun()
 	getEventList()
@@ -263,49 +273,53 @@
 	}
 	getEventPage(params.value, pageParams).then(res => {
 		const resData = res.data.data
-		list.value = (resData?.records || [])
+		list.value = resData?.records || []
 		total.value = resData.total
 	})
 }
 const isShowBigImg = ref(false)
-const imageList = ref([]);
-const clickImgSrc = ref('');
-const selectedImgIndex = ref(0);
+const imageList = ref([])
+const clickImgSrc = ref('')
+const selectedImgIndex = ref(0)
 // 点击图片放大 显示详细信息
-const getFindImgHistory = (item) => {
+const getFindImgHistory = item => {
 	// 下半部分隐藏 右侧隐藏
 	isShowBigImg.value = true
 	store.commit('setHideBottomIcon', false)
-	findImgHistory(item.id).then((res) => {
+	findImgHistory(item.id).then(res => {
 		if (res.data.code !== 0) return
 		imageList.value = res.data.data
-		clickImgSrc.value = res.data.data[0]?.url;
+		clickImgSrc.value = res.data.data[0]?.url
 	})
-	positioning(item);
+	positioning(item)
 }
 // 点击周期
-const clickWeekTime = (item,index) => {
+const clickWeekTime = (item, index) => {
 	clickImgSrc.value = item.url
 	selectedImgIndex.value = index
 }
 
 const getDateRange = unit => {
-  if (unit === 'today') {
-    return [dayjs().format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')];
-  }
-  return [dayjs().startOf(unit).format('YYYY-MM-DD HH:mm:ss'), dayjs().endOf(unit).format('YYYY-MM-DD HH:mm:ss')];
-};
+	if (unit === 'today') {
+		return [dayjs().format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')]
+	}
+	return [dayjs().startOf(unit).format('YYYY-MM-DD HH:mm:ss'), dayjs().endOf(unit).format('YYYY-MM-DD HH:mm:ss')]
+}
 
 // 监听事件时间范围变化
-watch(() => store.state.home.eventTimeType, (newVal) => {
-	timeArr.value = getDateRange(newVal);
-	const [start_date, end_date] = getDateRange(newVal);
-	params.value.start_date = start_date
-	params.value.end_date = end_date
-	getEventStatusNumFun()
-	getEventList()
-	getList()
-}, { immediate: false,deep: true })
+watch(
+	() => store.state.home.eventTimeType,
+	newVal => {
+		timeArr.value = getDateRange(newVal)
+		const [start_date, end_date] = getDateRange(newVal)
+		params.value.start_date = start_date
+		params.value.end_date = end_date
+		getEventStatusNumFun()
+		getEventList()
+		getList()
+	},
+	{ immediate: false, deep: true }
+)
 
 onMounted(() => {
 	getDeviceList()
@@ -340,11 +354,7 @@
 	.content {
 		width: 390px;
 		height: 877px;
-		background: linear-gradient(
-    270deg,
-    rgba(31, 62, 122, 0) 0%,
-    rgba(31, 62, 122, 0.35) 21%,
-    #1f3e7a 100%);
+		background: linear-gradient(270deg, rgba(31, 62, 122, 0) 0%, rgba(31, 62, 122, 0.35) 21%, #1f3e7a 100%);
 		display: flex;
 		justify-content: space-between;
 		align-content: start;
@@ -384,7 +394,14 @@
 				// margin-right: 4px;
 
 				&.active {
-					background: linear-gradient( 180deg, rgba(19,80,141,0) 0%, rgba(22,56,91,0.48) 48%, #053462 98%, #259DFF 98%, #259DFF 98%);
+					background: linear-gradient(
+						180deg,
+						rgba(19, 80, 141, 0) 0%,
+						rgba(22, 56, 91, 0.48) 48%,
+						#053462 98%,
+						#259dff 98%,
+						#259dff 98%
+					);
 				}
 
 				.statusItemImg {
@@ -531,30 +548,46 @@
 	display: flex;
 	justify-content: center;
 }
+
 .image-list {
-	border: 1px solid red;
 	position: absolute;
-	z-index: 1;
+	top: 148px;
+
 	right: 460px;
-	top: 122px;
-	width: 540px;
-	height: 420px;
-	background: #0F1929;
-	// box-shadow: inset 0px -50px 50px 0px rgba(27,148,255,0.13);
-	// border-radius: 0px 0px 0px 0px;
-	border: 2px solid;
-	border-image: linear-gradient(180deg, rgba(81, 168, 255, 0), rgba(48, 111, 202, 1), rgba(255, 255, 255, 1), rgba(27, 148, 255, 1)) 2 2;
+
+	width: 632px;
+	height: 476px;
+	border: solid;
+	background: #0f1929;
+	z-index: 1;
+
+	border: solid 2px transparent;
+	border-radius: 20px;
+	background-image: linear-gradient(#fff, #fff), linear-gradient(180deg, rgba(81, 168, 255, 1), rgba(189, 228, 255, 1));
+	background-origin: border-box;
+	background-clip: content-box, border-box;
+
+	overflow: hidden;
 	.title {
+		display: flex;
+		align-items: center;
+		justify-content: center;
 		position: absolute;
 		text-align: right;
-		right: 12px;
-		// top: 12px;
+		top: 0;
+		right: 0;
+		width: 45px;
+		height: 44px;
+		background: rgba(0, 0, 0, 0.5);
+		border-radius: 0px 20px 0px 8px;
+
 		img {
-			width: 10px;
-			height: 10px;
+			width: 10.55px;
+			height: 10.55px;
 			cursor: pointer;
 		}
 	}
+
 	.content {
 		img {
 			width: 100%;
@@ -562,43 +595,80 @@
 			border-radius: 10px 10px 10px 10px;
 		}
 	}
+
 	.card {
-		background: linear-gradient( 180deg, rgba(13,30,70,0.72) 0%, #142E6B 100%);
-		padding: 0px 10px 0px 10px;
-		color: #BECBEA;
-		display: flex;
-		justify-content: space-between;
 		position: absolute;
 		bottom: 0px;
 		width: 100%;
-		.time-top {
-			width: 50px;
-			height: 30px;
-			line-height: 30px;
-			text-align: center;
-			color: #ffffff;
-			background: linear-gradient( 180deg, rgba(13,30,70,0.72) 0%, #142E6B 100%);
-			border: 1px solid #0054D3;
-			cursor: pointer;
-		}
-		.active {
-			background: linear-gradient( 180deg, rgba(13,48,131,0.72) 0%, #023DC8 100%);
-			border: 1px solid;
-			border-image: linear-gradient(180deg, rgba(0, 84, 211, 1), rgba(146, 186, 245, 1)) 1 1;
-		}
-		.time-point {
-			text-align: center;
-			img {
-				width: 8px;
-				height: 12px;
-			}
-		}
-		.time-line {
+		height: 67px;
+		background: rgba(0, 0, 0, 0.42);
+		border-radius: 0px 0px 20px 20px;
+		padding: 0px 6px 0px 29px;
+
+		color: #d5d5d5;
+		font-size: 14px;
+
+		.card-content {
+			display: flex;
+			justify-content: space-between;
+
 			position: absolute;
-			background: linear-gradient( 82deg, rgba(23,40,79,0) 0%, #576D9F 17%, #576D9F 86%, rgba(23,40,79,0) 100%);
-			height: 2px;
-			top: 38px;
-			width: 100%;
+			left: 29px;
+			width: calc(100% - 29px - 6px);
+			height: 100%;
+
+			& > div {
+				position: relative;
+			}
+
+			.time-top {
+				margin-top: 10px;
+				line-height: 1;
+				text-align: center;
+				cursor: pointer;
+			}
+
+			.active {
+				font-weight: 400;
+				color: #ffffff;
+			}
+
+			.time-point {
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				position: absolute;
+				top: 28px;
+				left: 50%;
+				width: 18px;
+				height: 18px;
+				z-index: 1;
+				transform: translate(-50%, 0);
+
+				img {
+					width: 11.2px;
+					height: 11.2px;
+				}
+
+				img.active {
+					width: 16.89px;
+					height: 16.89px;
+				}
+			}
+
+			.time-bottom {
+				margin-top: 20px;
+			}
+
+			.time-line {
+				position: absolute;
+				top: 35px;
+				width: 100%;
+				width: 595px;
+				border-radius: 0px 0px 0px 0px;
+				border: 1px solid rgba(237, 237, 237, 0.6);
+				z-index: 0;
+			}
 		}
 	}
 }
diff --git a/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue b/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue
index c74eacf..67c4236 100644
--- a/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue
+++ b/src/views/Home/HomeLeft/InspectionRaskDetails/InspectionRaskDetailsDialog.vue
@@ -20,19 +20,19 @@
 					<el-input class="ztzf-input" v-model="searchForm.key_word" placeholder="请输入任务/机巢名称" clearable />
 				</el-form-item>
 				<el-form-item label="关联算法">
-					<el-select class="ztzf-select" v-model="searchForm.ai_types" placeholder="请选择">
+					<el-select :teleported="false" class="ztzf-select" v-model="searchForm.ai_types" placeholder="请选择">
 						<el-option v-for="item in taskAlgorithm" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
 					</el-select>
 				</el-form-item>
 				<el-form-item label="任务状态">
-					<el-select class="ztzf-select" v-model="searchForm.status" placeholder="请选择" clearable>
+					<el-select :teleported="false" class="ztzf-select" v-model="searchForm.status" placeholder="请选择" clearable>
 						<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
 					</el-select>
 				</el-form-item>
 			</div>
 			<div class="search-row">
 				<el-form-item label="选择机巢">
-					<el-select class="ztzf-select" v-model="searchForm.device_sn" placeholder="请选择">
+					<el-select :teleported="false" class="ztzf-select" v-model="searchForm.device_sn" placeholder="请选择">
 						<el-option
 							v-for="item in deviceList"
 							:label="item.nickname"
@@ -43,6 +43,7 @@
 				</el-form-item>
 				<el-form-item>
 					<el-date-picker
+						popper-class="custom-date-picker"
 						class="ztzf-date-picker"
 						v-model="dateRange"
 						type="daterange"
@@ -88,7 +89,9 @@
 									? 'finish '
 									: scope.row.status === 5
 									? 'fail '
-									: ' '">
+									: ' '
+							"
+						>
 							{{
 								scope.row.status === 1
 									? '待执行'
@@ -110,7 +113,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 +135,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 +154,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 +169,7 @@
 const statusOptions = [
 	{ label: '待执行', value: 1 },
 	{ label: '执行中', value: 2 },
-	{ label: '已完成', value: 3 },
+	{ label: '已执行', value: 3 },
 
 	{ label: '执行失败', value: 5 },
 ]
@@ -215,7 +236,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
@@ -251,12 +271,35 @@
 		return 'success-row'
 	}
 }
+// 查看
+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(() => {
 	requestDictionary()
 	getJobList()
 	getDeviceList()
 })
 </script>
+<style lang="scss">
+/* 修改日期单元格背景色 */
+.custom-date-picker .el-picker-panel__body {
+	background: #012350 !important;
+	color: #fff !important;
+}
+
+</style>
 <style scoped lang="scss">
 .search-row {
 	display: flex;
@@ -331,7 +374,7 @@
 }
 // 执行中
 .distributed {
-	color: #FFA768;
+	color: #ffa768;
 }
 // 已执行
 .finish {
diff --git a/src/views/Home/HomeLeft/OverviewNext.vue b/src/views/Home/HomeLeft/OverviewNext.vue
index a1e4e07..5b090e7 100644
--- a/src/views/Home/HomeLeft/OverviewNext.vue
+++ b/src/views/Home/HomeLeft/OverviewNext.vue
@@ -155,11 +155,11 @@
 			margin-bottom: 13px;
 			.name {
 				margin-left: 46px;
+			
 			}
 		}
 		.table-body {
 			height: 190px;
-
 			overflow: auto;
 			&::-webkit-scrollbar {
 				width: 0;
@@ -211,8 +211,7 @@
 			}
 			.active {
 				color: #ffa768;
-				background: linear-gradient(90deg, rgba(12, 45, 92, 1) 0%, #154671 50%, rgba(12, 45, 92, 1) 100%),
-					linear-gradient(90deg, rgba(12, 45, 92, 1) 0%, rgba(12, 45, 92, 1) 50%, rgba(12, 45, 92, 1) 100%);
+				
 			}
 			.idle-active {
 				color: #8effac;
diff --git a/src/views/Home/HomeRight/EventOverview.vue b/src/views/Home/HomeRight/EventOverview.vue
index 5ddff84..d608a20 100644
--- a/src/views/Home/HomeRight/EventOverview.vue
+++ b/src/views/Home/HomeRight/EventOverview.vue
@@ -1,420 +1,415 @@
 <template>
-  <CommonTitle title="事件概况" @Details="details"/>
-  <div :style="{ marginLeft: pxToRem(14) }">
-    <div class="eventOverview">
-      <div class="overviewData">
-        <div class="totalBox">
-          <div class="totalNumber">{{ eventTotal }}</div>
-          <div class="totalLabel">总事件数</div>
-        </div>
-        <div class="contentBox">
-          <div class="overviewItem" v-for="item in eventTypeList" :key="item.name">
-            <div class="itemName"><img :src="item.img" alt="" />{{ item.name }}</div>
-            <div class="itemValue" :style="{ color: item.color }">{{ item.value }}</div>
-          </div>
-        </div>
-      </div>
-      <CommonDateTime class="dateTime" v-model="timeArr" @change="timeChange" />
+	<CommonTitle title="事件概况" @Details="details" />
+	<div :style="{ marginLeft: pxToRem(14) }">
+		<div class="eventOverview">
+			<div class="overviewData">
+				<div class="totalBox">
+					<div class="totalNumber">{{ eventTotal }}</div>
+					<div class="totalLabel">总事件数</div>
+				</div>
+				<div class="contentBox">
+					<div class="overviewItem" v-for="item in eventTypeList" :key="item.name">
+						<div class="itemName">
+							<img :src="item.img" alt="" />
+							{{ item.name }}
+						</div>
+						<div class="itemValue" :style="{ color: item.color }">{{ item.value }}</div>
+					</div>
+				</div>
+			</div>
+			<CommonDateTime class="dateTime" v-model="timeArr" @change="timeChange" />
 
-      <el-select
-        class="homeRightSelect"
-        v-model="params.device_sn"
-        placeholder="请选择"
-        size="large"
-        filterable
-        :remote-method="remoteMethod"
-        remote-show-suffix
-        remote
-        clearable
-        popper-class="uavHomePopper"
-        v-select-load:uavHomePopper="scrollEvent"
-        @change="selectChange"
-      >
-        <el-option
-          v-for="item in deviceList"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value"
-        />
-      </el-select>
-      <div class="completion">
-        <img class="completion-left-img" :src="completionLeft" alt="" />
-        <div class="completion-text">事件类型完成率情况</div>
-        <div class="completion-separator"></div>
-        <img class="completion-left-img" :src="completionLeft" alt="" />
-      </div>
+			<el-select
+				:teleported="false"
+				class="homeRightSelect ztzf-select"
+				v-model="params.device_sn"
+				placeholder="请选择机巢"
+				size="large"
+				filterable
+				:remote-method="remoteMethod"
+				remote-show-suffix
+				remote
+				clearable
+				popper-class="uavHomePopper"
+				v-select-load:uavHomePopper="scrollEvent"
+				@change="selectChange"
+			>
+				<el-option v-for="item in deviceList" :key="item.value" :label="item.label" :value="item.value" />
+			</el-select>
+			<div class="completion">
+				<img class="completion-left-img" :src="completionLeft" alt="" />
+				<div class="completion-text">事件类型完成率情况</div>
+				<div class="completion-separator"></div>
+				<img class="completion-left-img" :src="completionLeft" alt="" />
+			</div>
 
-      <div class="chart" ref="echartsRef"></div>
-    </div>
-  </div>
+			<div class="chart" ref="echartsRef"></div>
+		</div>
+	</div>
 </template>
 <script setup>
-import CommonTitle from '@/components/CommonTitle.vue';
-import overviewImg1 from '@/assets/images/home/homeRight/overview1.png';
-import overviewImg2 from '@/assets/images/home/homeRight/overview2.png';
-import overviewImg3 from '@/assets/images/home/homeRight/overview3.png';
-import overviewImg4 from '@/assets/images/home/homeRight/overview4.png';
-import overviewImg5 from '@/assets/images/home/homeRight/overview5.png';
-import overviewImg6 from '@/assets/images/home/homeRight/overview6.png';
-import completionLeft from '@/assets/images/home/homeRight/completionLeft.png';
-import * as echarts from 'echarts';
-import CommonDateTime from '@/components/CommonDateTime.vue';
-import VSelectLoad from '@/directive/selectLoad';
-import { getJobEventBrokerLine, getJobEventByStatus, getJobEventTotal } from '@/api/home';
-import dayjs from 'dayjs';
-import { selectDevicePage } from '@/api/home/machineNest';
+import CommonTitle from '@/components/CommonTitle.vue'
+import overviewImg1 from '@/assets/images/home/homeRight/overview1.png'
+import overviewImg2 from '@/assets/images/home/homeRight/overview2.png'
+import overviewImg3 from '@/assets/images/home/homeRight/overview3.png'
+import overviewImg4 from '@/assets/images/home/homeRight/overview4.png'
+import overviewImg5 from '@/assets/images/home/homeRight/overview5.png'
+import overviewImg6 from '@/assets/images/home/homeRight/overview6.png'
+import completionLeft from '@/assets/images/home/homeRight/completionLeft.png'
+import * as echarts from 'echarts'
+import CommonDateTime from '@/components/CommonDateTime.vue'
+import VSelectLoad from '@/directive/selectLoad'
+import { getJobEventBrokerLine, getJobEventByStatus, getJobEventTotal } from '@/api/home'
+import dayjs from 'dayjs'
+import { selectDevicePage } from '@/api/home/machineNest'
 import { useStore } from 'vuex'
 import useEchartsResize from '@/hooks/useEchartsResize'
 
 const echartsOption = {
-  tooltip: {
-    trigger: 'axis',
-    axisPointer: {
-      type: 'shadow',
-    },
-  },
-  grid: {
-    top: '5%',
-    left: 0,
-    right: 0,
-    bottom: 0,
-    containLabel: true,
-  },
-  xAxis: {
-    type: 'category',
-    axisLabel: {
-      rotate: -45, // 旋转角度
-      interval: 0, // 显示所有标签
-      color: '#FFFFFF',
-      fontFamily: 'Source Han Sans CN, Source Han Sans CN',
-      fontWeight: 400,
-      fontSize: 10,
-    },
-    data: [],
-  },
-  yAxis: [
-    {
-      type: 'value',
-      axisLabel: {
-        interval: 0, // 显示所有标签
-        color: '#FFFFFF',
-        fontFamily: 'Source Han Sans CN, Source Han Sans CN',
-        fontWeight: 400,
-        fontSize: 10,
-      },
-      axisLine: {
-        lineStyle: {
-          color: '#ffffff',
-        },
-      },
-      splitLine: {
-        lineStyle: {
-          color: 'rgba(255, 255, 255, 0.1)',
-          type: 'dashed', // 设置为虚线
-        },
-      },
-    },
-  ],
-  series: [],
-};
+	tooltip: {
+		trigger: 'axis',
+		axisPointer: {
+			type: 'shadow',
+		},
+	},
+	grid: {
+		top: '5%',
+		left: 0,
+		right: 0,
+		bottom: 0,
+		containLabel: true,
+	},
+	xAxis: {
+		type: 'category',
+		axisLabel: {
+			rotate: -45, // 旋转角度
+			interval: 0, // 显示所有标签
+			color: '#FFFFFF',
+			fontFamily: 'Source Han Sans CN, Source Han Sans CN',
+			fontWeight: 400,
+			fontSize: 10,
+		},
+		data: [],
+	},
+	yAxis: [
+		{
+			type: 'value',
+			axisLabel: {
+				interval: 0, // 显示所有标签
+				color: '#FFFFFF',
+				fontFamily: 'Source Han Sans CN, Source Han Sans CN',
+				fontWeight: 400,
+				fontSize: 10,
+			},
+			axisLine: {
+				lineStyle: {
+					color: '#ffffff',
+				},
+			},
+			splitLine: {
+				lineStyle: {
+					color: 'rgba(255, 255, 255, 0.1)',
+					type: 'dashed', // 设置为虚线
+				},
+			},
+		},
+	],
+	series: [],
+}
 
 const eventTypeList = ref([
-  { name: '待审核', value: 0, img: overviewImg1, color: '#8CFEA7', status: '2' },
-  // { name: '待分拨', value: 0, img: overviewImg2, color: '#6FCAFF', status: '1' },
-  { name: '待处理', value: 0, img: overviewImg3, color: '#E36913', status: '0' },
-  { name: '处理中', value: 0, img: overviewImg4, color: '#FFC398', status: '3' },
-  { name: '已完成', value: 0, img: overviewImg5, color: '#AFD9FB', status: '4' },
-  { name: '已完结', value: 0, img: overviewImg6, color: '#11C4FF', status: '5' },
-]);
-const seriesObj = {};
+	{ name: '待审核', value: 0, img: overviewImg1, color: '#8CFEA7', status: '2' },
+	// { name: '待分拨', value: 0, img: overviewImg2, color: '#6FCAFF', status: '1' },
+	{ name: '待处理', value: 0, img: overviewImg3, color: '#E36913', status: '0' },
+	{ name: '处理中', value: 0, img: overviewImg4, color: '#FFC398', status: '3' },
+	{ name: '已完成', value: 0, img: overviewImg5, color: '#AFD9FB', status: '4' },
+	{ name: '已完结', value: 0, img: overviewImg6, color: '#11C4FF', status: '5' },
+])
+const seriesObj = {}
 eventTypeList.value.forEach(item => {
-  seriesObj[item.status] = {
-    type: 'bar',
-    stack: 'Ad',
-    emphasis: {
-      focus: 'series',
-    },
-    name: item.name,
-    itemStyle: { color: item.color },
-    data: [],
-  };
-});
-const echartsRef = ref(null);
+	seriesObj[item.status] = {
+		type: 'bar',
+		stack: 'Ad',
+		emphasis: {
+			focus: 'series',
+		},
+		name: item.name,
+		itemStyle: { color: item.color },
+		data: [],
+	}
+})
+const echartsRef = ref(null)
 let { chart } = useEchartsResize(echartsRef)
-const deviceList = ref([]);
-const today = dayjs().format('YYYY-MM-DD');
-const timeArr = ref([today, today]);
+const deviceList = ref([])
+const today = dayjs().format('YYYY-MM-DD')
+const timeArr = ref([today, today])
 const completionRateSeries = {
-  name: '完成率',
-  type: 'line',
-  itemStyle: {
-    color: '#0CEBF7', // 设置颜色
-  },
-  lineStyle: {
-    width: 2, // 线条宽度
-    type: 'solid', // 线条类型
-  },
-  symbol: 'circle', // 数据点符号
-  symbolSize: 6, // 数据点符号大小
-  emphasis: {
-    focus: 'series',
-  },
-  data: [], // 示例数据,根据实际完成率计算
-};
+	name: '完成率',
+	type: 'line',
+	itemStyle: {
+		color: '#0CEBF7', // 设置颜色
+	},
+	lineStyle: {
+		width: 2, // 线条宽度
+		type: 'solid', // 线条类型
+	},
+	symbol: 'circle', // 数据点符号
+	symbolSize: 6, // 数据点符号大小
+	emphasis: {
+		focus: 'series',
+	},
+	data: [], // 示例数据,根据实际完成率计算
+}
 
-const eventTotal = ref(0);
-let deviceTotal = 0;
+const eventTotal = ref(0)
+let deviceTotal = 0
 const devicePageParams = ref({
-  current: 1,
-  size: 10,
-  total: 0,
-  nickname: '',
-});
+	current: 1,
+	size: 10,
+	total: 0,
+	nickname: '',
+})
 const params = ref({
-  date_enum: 'TODAY',
-  device_sn: '',
-  end_date: undefined,
-  start_date: undefined,
-});
+	date_enum: 'TODAY',
+	device_sn: '',
+	end_date: undefined,
+	start_date: undefined,
+})
 
 const store = useStore()
-const details = () =>{
-	store.commit('setFootActiveIndex',1)
-	store.commit('setIsEventOverviewDetail',true)
+const details = () => {
+	store.commit('setFootActiveIndex', 1)
+	store.commit('setIsEventOverviewDetail', true)
 }
 
 // 远程查询
 const remoteMethod = nickname => {
-  devicePageParams.value.nickname = nickname;
-  devicePageParams.value.current = 1;
-  devicePageParams.value.size = 10;
-  deviceList.value = [];
-  getTableList();
-};
+	devicePageParams.value.nickname = nickname
+	devicePageParams.value.current = 1
+	devicePageParams.value.size = 10
+	deviceList.value = []
+	getTableList()
+}
 // 滚动查询
 const scrollEvent = () => {
-  const { current, size } = devicePageParams.value;
-  if (current * size < deviceTotal) {
-    devicePageParams.value.current = current + 1;
-    getTableList();
-  }
-};
+	const { current, size } = devicePageParams.value
+	if (current * size < deviceTotal) {
+		devicePageParams.value.current = current + 1
+		getTableList()
+	}
+}
 // 机巢列表数据
 const getTableList = async () => {
-  const res = await selectDevicePage({ ...devicePageParams.value, type: 1 });
-  const arr = res?.data?.data?.records || [];
-  deviceList.value = deviceList.value.concat(
-    arr.map(item => ({
-      value: item.device_sn,
-      label: item.nickname,
-    }))
-  );
-  deviceTotal = res?.data?.data?.total || 0;
-};
+	const res = await selectDevicePage({ ...devicePageParams.value, type: 1 })
+	const arr = res?.data?.data?.records || []
+	deviceList.value = deviceList.value.concat(
+		arr.map(item => ({
+			value: item.device_sn,
+			label: item.nickname,
+		}))
+	)
+	deviceTotal = res?.data?.data?.total || 0
+}
 // 下拉变化
 const selectChange = val => {
-  getData();
-};
+	getData()
+}
 
 // 时间变化
 const timeChange = (value, date_enum) => {
-  params.value = {
-    ...params.value,
-    date_enum,
-  };
-  getData();
-};
+	params.value = {
+		...params.value,
+		date_enum,
+	}
+	getData()
+}
 
 // 获取柱状图数据
 const getBarChartData = () => {
-  getJobEventBrokerLine(params.value).then(res => {
-    const list = res?.data?.data || [];
-    echartsOption.xAxis.data = list.map(item => item.name);
+	getJobEventBrokerLine(params.value).then(res => {
+		const list = res?.data?.data || []
+		echartsOption.xAxis.data = list.map(item => item.name)
 		// 赋值前清空数据
-		Object.keys(seriesObj).forEach(key => {seriesObj[key].data = []})
-    list.forEach(item => {
-      item.data.forEach((item1, index) => {
+		Object.keys(seriesObj).forEach(key => {
+			seriesObj[key].data = []
+		})
+		list.forEach(item => {
+			item.data.forEach((item1, index) => {
 				if (!seriesObj?.[item1.status]) return
-        seriesObj[item1.status].data.push(item1.value);
-      });
-    });
-    completionRateSeries.data = list.map(item => item.rate);
-    echartsOption.series = Object.values(seriesObj);
-    echartsOption.series.push(completionRateSeries);
-    chart.value.setOption(echartsOption);
-  });
-};
+				seriesObj[item1.status].data.push(item1.value)
+			})
+		})
+		completionRateSeries.data = list.map(item => item.rate)
+		echartsOption.series = Object.values(seriesObj)
+		echartsOption.series.push(completionRateSeries)
+		chart.value.setOption(echartsOption)
+	})
+}
 
 //  事件类型数据
 const getTypeData = () => {
-  getJobEventByStatus(params.value).then(res => {
-    const resList = res?.data?.data || [];
-    resList.forEach(item => {
-      eventTypeList.value.forEach(item1 => {
-        if (item1.name === item.name) {
-          item1.value = item.num;
-        }
-      });
-    });
-  });
-};
+	getJobEventByStatus(params.value).then(res => {
+		const resList = res?.data?.data || []
+		resList.forEach(item => {
+			eventTypeList.value.forEach(item1 => {
+				if (item1.name === item.name) {
+					item1.value = item.num
+				}
+			})
+		})
+	})
+}
 
 // 获取事件概括数据
 const getData = () => {
-  getTypeData();
-  getBarChartData();
-};
+	getTypeData()
+	getBarChartData()
+}
 
 onMounted(() => {
-  getJobEventTotal().then(res => {
-    eventTotal.value = res?.data?.data || 0;
-  });
-  getData();
-  getTableList();
-});
+	getJobEventTotal().then(res => {
+		eventTotal.value = res?.data?.data || 0
+	})
+	getData()
+	getTableList()
+})
 </script>
-
 <style scoped lang="scss">
 .homeRightSelect {
-  width: 356px;
+	width: 356px;
 
-  :deep() {
-    .el-select__wrapper {
-      background: linear-gradient(90deg, #195bad 0%, rgba(25, 91, 173, 0) 100%);
-      min-height: 28px;
-      height: 28px;
-      box-shadow: none;
-      border: 1px solid #306fca;
-    }
+	:deep() {
+		.el-select__wrapper {
+			background: linear-gradient(90deg, #195bad 0%, rgba(25, 91, 173, 0) 100%);
+			min-height: 28px;
+			height: 28px;
+			box-shadow: none;
+			border: 1px solid #306fca;
+		}
 
-    .el-select__placeholder {
-      font-family: Microsoft YaHei, Microsoft YaHei, serif;
-      color: #ffffff;
-      font-size: 14px;
-    }
-  }
+		.el-select__placeholder {
+			font-family: Microsoft YaHei, Microsoft YaHei, serif;
+			color: #ffffff;
+			font-size: 14px;
+		}
+	}
 }
 
 .eventOverview {
-  width: 390px;
-  height: 445px;
-  background: linear-gradient(
-    270deg,
-    #1f3e7a 0%,
-    rgba(31, 62, 122, 0.35) 79%,
-    rgba(31, 62, 122, 0) 100%
-  );
-  border-radius: 0px 0px 0px 0px;
-  opacity: 0.85;
-  margin: 3px 0 0 0;
-  padding-top: 15px;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
+	width: 390px;
+	height: 445px;
+	background: linear-gradient(270deg, #1f3e7a 0%, rgba(31, 62, 122, 0.35) 79%, rgba(31, 62, 122, 0) 100%);
+	border-radius: 0px 0px 0px 0px;
+	opacity: 0.85;
+	margin: 3px 0 0 0;
+	padding-top: 15px;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
 
-  .dateTime {
-    width: 356px;
-    margin: 15px 0 8px 0;
-  }
+	.dateTime {
+		width: 356px;
+		margin: 15px 0 8px 0;
+	}
 
-  .overviewData {
-    width: 360px;
-    height: 122px;
-    background: url('@/assets/images/home/homeRight/overviewBg.png') no-repeat center / 100% 100%;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    padding-left: 11px;
+	.overviewData {
+		width: 360px;
+		height: 122px;
+		background: url('@/assets/images/home/homeRight/overviewBg.png') no-repeat center / 100% 100%;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		padding-left: 11px;
 
-    .totalBox {
-      width: 77px;
+		.totalBox {
+			width: 77px;
 
-      .totalNumber {
-        font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
-        font-weight: 400;
-        font-size: 26px;
-        color: #ffffff;
-        line-height: 30px;
-        text-align: center;
-      }
+			.totalNumber {
+				font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
+				font-weight: 400;
+				font-size: 26px;
+				color: #ffffff;
+				line-height: 30px;
+				text-align: center;
+			}
 
-      .totalLabel {
-        font-family: Source Han Sans CN, Source Han Sans CN;
-        font-weight: 400;
-        font-size: 14px;
-        color: #ffffff;
-        line-height: 20px;
-        text-align: center;
-      }
-    }
+			.totalLabel {
+				font-family: Source Han Sans CN, Source Han Sans CN;
+				font-weight: 400;
+				font-size: 14px;
+				color: #ffffff;
+				line-height: 20px;
+				text-align: center;
+			}
+		}
 
-    .contentBox {
-      width: 246px;
-      display: flex;
-      flex-wrap: wrap;
-      gap: 13px 0;
-      font-family: Source Han Sans CN, Source Han Sans CN, serif;
-      font-weight: 400;
-      font-size: 14px;
-      color: #ffffff;
-      line-height: 14px;
+		.contentBox {
+			width: 246px;
+			display: flex;
+			flex-wrap: wrap;
+			gap: 13px 0;
+			font-family: Source Han Sans CN, Source Han Sans CN, serif;
+			font-weight: 400;
+			font-size: 14px;
+			color: #ffffff;
+			line-height: 14px;
 
-      .overviewItem {
-        width: calc(100% / 3);
+			.overviewItem {
+				width: calc(100% / 3);
 
-        .itemName {
-          display: flex;
-          align-items: center;
-          margin-bottom: 6px;
+				.itemName {
+					display: flex;
+					align-items: center;
+					margin-bottom: 6px;
 
-          img {
-            width: 16px;
-            height: 16px;
-          }
-        }
+					img {
+						width: 16px;
+						height: 16px;
+					}
+				}
 
-        .itemValue {
-          font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif;
-          font-weight: 400;
-          font-size: 24px;
-          line-height: 18px;
-        }
-      }
-    }
-  }
+				.itemValue {
+					font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif;
+					font-weight: 400;
+					font-size: 24px;
+					line-height: 18px;
+				}
+			}
+		}
+	}
 
-  .completion {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    width: 356px;
-    height: 23px;
-    margin-top: 16px;
+	.completion {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		width: 356px;
+		height: 23px;
+		margin-top: 16px;
 
-    &--left-img {
-      width: 16px;
-      height: 16px;
-    }
+		&--left-img {
+			width: 16px;
+			height: 16px;
+		}
 
-    &-text {
-      font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif;
-      font-weight: 400;
-      font-size: 18px;
-      color: #ffffff;
-      line-height: 21px;
-    }
+		&-text {
+			font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif;
+			font-weight: 400;
+			font-size: 18px;
+			color: #ffffff;
+			line-height: 21px;
+		}
 
-    &-separator {
-      width: 149px;
-      height: 0px;
-      border: 1px solid #4ca6ff;
-      opacity: 0.2;
-    }
-  }
+		&-separator {
+			width: 149px;
+			height: 0px;
+			border: 1px solid #4ca6ff;
+			opacity: 0.2;
+		}
+	}
 
-  .chart {
-    width: 356px;
-    height: 190px;
-  }
+	.chart {
+		width: 356px;
+		height: 190px;
+	}
 }
 </style>
diff --git a/src/views/TaskManage/SearchBox.vue b/src/views/TaskManage/SearchBox.vue
index ceef403..6205201 100644
--- a/src/views/TaskManage/SearchBox.vue
+++ b/src/views/TaskManage/SearchBox.vue
@@ -6,17 +6,18 @@
           <el-input class="ztzf-input" v-model="searchForm.key_word" placeholder="请输入任务/机巢名称" clearable />
         </el-form-item>
         <el-form-item label="行政区划:">
-          <el-select class="ztzf-select" v-model="searchForm.area_code" @change="deptChange" placeholder="请选择部门" clearable>
+          <el-select :teleported="false" class="ztzf-select" v-model="searchForm.area_code" @change="deptChange" placeholder="请选择部门" clearable>
             <el-option v-for="item in deptTreeData" :key="item.area_code" :label="item.area_name" :value="item.area_code" />
           </el-select>
         </el-form-item>
         <el-form-item label="所属机巢:">
-          <el-select class="ztzf-select" v-model="searchForm.device_sn" placeholder="请选择机巢" clearable>
+          <el-select :teleported="false" class="ztzf-select" v-model="searchForm.device_sn" placeholder="请选择机巢" clearable>
             <el-option v-for="item in machineData" :key="item.device_sn" :label="item.nickname" :value="item.device_sn" />
           </el-select>
         </el-form-item>
         <el-form-item>
           <el-date-picker
+          popper-class="custom-date-picker"
 						class="ztzf-date-picker"
 						v-model="dateRange"
 						type="daterange"
@@ -43,12 +44,12 @@
           <TaskAlgorithmBusiness :setWidth="186" :showAlgorithm="true" @algorithmChange="algorithmChange"/>
         </el-form-item>
         <el-form-item label="所属部门:" v-if="isExpand">
-          <el-select class="ztzf-select" v-model="searchForm.create_dept" placeholder="请选择部门" clearable>
+          <el-select :teleported="false" class="ztzf-select" v-model="searchForm.create_dept" placeholder="请选择部门" clearable>
             <el-option v-for="item in deptData" :key="item.id" :label="item.deptName" :value="item.id" />
           </el-select>
         </el-form-item>
         <el-form-item label="任务状态:" v-if="isExpand">
-          <el-select class="ztzf-select" v-model="searchForm.status" placeholder="请选择状态" clearable>
+          <el-select :teleported="false" class="ztzf-select" v-model="searchForm.status" placeholder="请选择状态" clearable>
             <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
@@ -208,7 +209,13 @@
   handleSearch();
 });
 </script>
-
+<style lang="scss">
+/* 修改日期单元格背景色 */
+.custom-date-picker .el-picker-panel__body {
+	background: #012350 !important;
+	color: #fff !important;
+}
+</style>
 <style lang="scss" scoped>
 .search-box-test {
   transition: all 0.3s;
diff --git a/src/views/TaskManage/TaskIntermediateContent/TaskIntermediateContent.vue b/src/views/TaskManage/TaskIntermediateContent/TaskIntermediateContent.vue
index a4aa8c4..8ed3524 100644
--- a/src/views/TaskManage/TaskIntermediateContent/TaskIntermediateContent.vue
+++ b/src/views/TaskManage/TaskIntermediateContent/TaskIntermediateContent.vue
@@ -20,10 +20,10 @@
         <el-table-column label="任务状态" >
           <template #default="scope">
             <span :style="{
-              color: scope.row.status === 1 ? '#e36913' :
-                     scope.row.status === 2 ? '#ffc398' :
-                     scope.row.status === 3 ? '#afd9fb' :
-                     scope.row.status === 4 ? '#11c4ff' : '8cfea7'
+              color: scope.row.status === 1 ? '#ffe17e' :
+                     scope.row.status === 2 ? '#ffa768' :
+                     scope.row.status === 3 ? '#8effac' :
+                     scope.row.status === 5 ? '#ff8e8e':''
             }">
               {{ scope.row.status ? getStatusText(scope.row.status) : '' }}
             </span>
@@ -59,7 +59,15 @@
   <!-- 添加任务 -->
   <AddTask v-model:show="isShowAddTask" @refresh="searchClick"/>
   <!-- 当前任务详情 -->
-  <CurrentTaskDetails v-if="isShowCurrentTaskDetails"  v-model:show="isShowCurrentTaskDetails" :id="rowData.id"/>
+  <CurrentTaskDetails
+		v-if="isShowCurrentTaskDetails"
+		v-model:show="isShowCurrentTaskDetails"
+		:id="rowData.id"/>
+	<!-- 历史人物详情 -->
+  <DeviceJobDetails
+		v-if="isShowDeviceJobDetails"
+		v-model:show="isShowDeviceJobDetails"
+		:wayLineJodInfoId="wayLineJodInfoId"/>
 </template>
 
 <script setup>
@@ -68,6 +76,7 @@
 import CurrentTaskDetails from '@/components/CurrentTaskDetails/CurrentTaskDetails.vue';
 import { jobList } from '@/api/home/task';
 import { ElMessage } from 'element-plus'
+import DeviceJobDetails from '@/components/DeviceJobDetails/DeviceJobDetails.vue'
 
 const jobListParams = reactive({
   current: 1,
@@ -76,6 +85,9 @@
 });
 const jobListData = ref([]);
 const total = ref(0);
+let wayLineJodInfoId = ref('')
+let isShowDeviceJobDetails = ref(false);
+let isShowCurrentTaskDetails = ref(false);
 
 // 获取任务列表
 const getJobList = () => {
@@ -90,7 +102,7 @@
   const statusMap = {
     1: '待执行',
     2: '执行中',
-    3: '已完成',
+    3: '已执行',
     4: '已取消',
     5: '执行失败'
   };
@@ -98,15 +110,16 @@
 };
 
 // 查看当前任务详情 如果是一台机则显示详情 如果是多台机则进入集群调度(暂未开发)
-let isShowCurrentTaskDetails = ref(true);
 let rowData = ref({});
 const handleDetail = (row) => {
 	if (row.device_sns.length === 1){
+		console.log(row)
 		if (row.status === 2 || row.status === 1){
 			rowData.value = row? row : {};
 			isShowCurrentTaskDetails.value = true;
 		} else{
-			ElMessage.warning('todo 跳历史任务详情')
+			wayLineJodInfoId.value = row.id
+			isShowDeviceJobDetails.value = true
 		}
 	}else{
 		ElMessage.warning('即将跳转到集群调度');
diff --git a/src/views/TaskManage/components/TaskAlgorithmBusiness.vue b/src/views/TaskManage/components/TaskAlgorithmBusiness.vue
index d508c4b..01f1524 100644
--- a/src/views/TaskManage/components/TaskAlgorithmBusiness.vue
+++ b/src/views/TaskManage/components/TaskAlgorithmBusiness.vue
@@ -1,12 +1,12 @@
 <!-- 关联算法和综合业务 -->
 <template>
   <div class="task-algorithm" v-if="showAlgorithm">
-    <el-select class="ztzf-select" :style="{ width: pxToRem(setWidth) }" v-model="ai_types" multiple collapse-tags collapse-tags-tooltip placeholder="请选择算法" clearable @change="handleAlgorithmChange">
+    <el-select :teleported="false" class="ztzf-select" :style="{ width: pxToRem(setWidth) }" v-model="ai_types" multiple collapse-tags collapse-tags-tooltip placeholder="请选择算法" clearable @change="handleAlgorithmChange">
       <el-option v-for="item in taskAlgorithm" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
     </el-select>
   </div>
   <div class="task-business" v-if="showBusiness">
-    <el-select class="ztzf-select" :style="{ width: pxToRem(setWidth) }" v-model="industry_type" placeholder="请选择类型" clearable @change="handleBusinessChange">
+    <el-select :teleported="false" class="ztzf-select" :style="{ width: pxToRem(setWidth) }" v-model="industry_type" placeholder="请选择类型" clearable @change="handleBusinessChange">
       <el-option v-for="item in taskBusiness" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
     </el-select>
   </div>

--
Gitblit v1.9.3