From 678f5050633c1bc53ba92bdb7aa8b85d055b443f Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Fri, 18 Apr 2025 19:54:47 +0800
Subject: [PATCH] feat: 指南针60%

---
 src/hooks/controlDrone/useManualControl.js                                       |    4 
 src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue                  |   14 
 src/components/CurrentTaskDetails/TaskDetailsHead.vue                            |   11 
 src/components/CurrentTaskDetails/TaskDetailsRight.vue                           |   33 ++-
 src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue |  571 ++++++++++++++++++---------------------------------
 src/components/CurrentTaskDetails/CurrentTaskDetails.vue                         |   12 
 6 files changed, 255 insertions(+), 390 deletions(-)

diff --git a/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue b/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
index 5685ca1..60530dc 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/ControlComPass/ControlComPass.vue
@@ -1,392 +1,229 @@
 <template>
-  <div class="instrument-content">
-    <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" />
-      </div>
-    </div>
-    <div class="instrument-center">
-      <div class="compass-box" :data-text="`${prevRotate?.toFixed(2)}°`">
-        <div v-for="(item, index) in str" :key="index" class="scale"
-          :style="{ '--rotate': 30 * index - prevRotate + 'deg' }">
-          <span class="text">{{ item }}</span>
-        </div>
-      </div>
-      <div class="center-show">
-        <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" />
-        <div class="arrow-box" :style="{ bottom: realHeight }">
-          <div class="arrow"></div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-<script>
-import _ from 'lodash';
-export default {
-  data () {
-    return {
-      str: ['W', 30, 33, 'N', 3, 6, 'E', 12, 15, 'S', 21, 24],
-      // 俯仰角度数
-      attitude_pitch: 0,
-      // 真空高度
-      height: 0,
-      // 旋转方向角度
-      prevRotate: 0,
-      dockHeight: 0,
-    }
-  },
-  watch: {
-    roamPoint: {
-      handler (val) {
-        // this.prevRotate = val.arrowHeading
-        // this.attitude_pitch = val.roll
-        // this.height = _.round(val.altitude,1)
-      },
-    },
-  },
-  computed: {
-    // roamPoint: vuexStateSimplify('pointsWayLine', 'roamPoint'),
-    ScaleTop () {
-      return (-this.attitude_pitch * 30) / 90
-    },
-    realHeight () {
-			return 0
-      // 无人机高度
-      const maxHeight = 240
-      // 真空高度
-      const vacuumHeight = 120
-      // 机场高度
-      const dockHeightConfig = {
-        'e3dea0f5-37f2-4d79-ae58-490af3228069': 14.7,
-        '4a574db8-4ad3-48f7-9f16-3edbcd8056e1': 54,
-        // 'f47ac10b-58cc-4372-a567-0e02b2c3d479': 81,
-      }
-      const workspaceId =
-        this.$store.state.drone.selectedWorkSpaceId ||
-        window.localStorage.getItem('bs_workspace_id')
-      const dockHeight = dockHeightConfig?.[workspaceId] || 1
+	<div class="instrument-content">
+		<div class="left-img">
+			<div class="valueBox">{{props?.pitchAngle || 0}}°</div>
+			<img src="@/assets/images/rightmapidentification.png" alt="" />
+			<div class="triangle" :style="pitchAngleStyle"></div>
+			<div class="nameBox" >俯仰角度</div>
+		</div>
 
-      let proportion = 0
-      // 处于真空高度和最大高度之间
-      if (this.height < maxHeight && this.height >= vacuumHeight) {
-        const height = this.height - vacuumHeight
-        const proport = height / maxHeight
-        proportion = Math.round(proport * 50 + 50)
-      }
-      // 小于等于真空高度计算
-      if (this.height < vacuumHeight && this.height >= dockHeight) {
-        const height = this.height - dockHeight
-        const copyVacuumHeight = vacuumHeight - dockHeight
-        const proport = height / copyVacuumHeight
-        proportion = Math.round(proport * 25 + 25)
-      }
-      // 小于机场高度计算
-      if (this.height < dockHeight && this.height >= 0) {
-        const proport = this.height / dockHeight
-        proportion = Math.round(proport * 25)
-      }
-      // 大于最大高度计算
-      if (this.height >= maxHeight) {
-        proportion = 95
-      }
-      return proportion + '%'
-      // const proportion = Math.ceil((this.height / maxHeight) * 100) || 50;
-    },
-  },
-  methods: {
-    getAngle (currentLngLat, targetLngLat) {
-      const { longitude: lng_a, latitude: lat_a } = currentLngLat
-      const { longitude: lng_b, latitude: lat_b } = targetLngLat
-      var a = ((90 - lat_b) * Math.PI) / 180
-      var b = ((90 - lat_a) * Math.PI) / 180
-      var AOC_BOC = ((lng_b - lng_a) * Math.PI) / 180
-      var cosc =
-        Math.cos(a) * Math.cos(b) +
-        Math.sin(a) * Math.sin(b) * Math.cos(AOC_BOC)
-      var sinc = Math.sqrt(1 - cosc * cosc)
-      var sinA = (Math.sin(a) * Math.sin(AOC_BOC)) / sinc
-      var A = (Math.asin(sinA) * 180) / Math.PI
-      var res = 0
-      if (lng_b > lng_a && lat_b > lat_a) res = A
-      else if (lng_b > lng_a && lat_b < lat_a) res = 180 - A
-      else if (lng_b < lng_a && lat_b < lat_a) res = 180 - A
-      else if (lng_b < lng_a && lat_b > lat_a) res = 360 + A
-      else if (lng_b > lng_a && lat_b == lat_a) res = 90
-      else if (lng_b < lng_a && lat_b == lat_a) res = 270
-      else if (lng_b == lng_a && lat_b > lat_a) res = 0
-      else if (lng_b == lng_a && lat_b < lat_a) res = 180
-      return res
-    },
-  },
-}
+		<div class="instrument-center">
+			<div class="compass-box" >
+				<div
+					v-for="(item, index) in str"
+					:key="index"
+					class="scale"
+					:style="{ '--rotate': 30 * index - prevRotate + 'deg' }"
+				>
+					<span class="text">{{ item }}</span>
+				</div>
+			</div>
+			<div class="center-show">
+				<img src="@/assets/images/mapidentification.png" alt="" />
+			</div>
+		</div>
+
+		<div class="right-img">
+			<div class="valueBox">{{props.trueAltitude}}m</div>
+			<img src="@/assets/images/leftmapidentification.png" alt="" />
+			<div class="rightTriangle" :style="trueAltitudeStyle"></div>
+			<div class="nameBox">真空高度</div>
+		</div>
+	</div>
+</template>
+
+<script setup>
+const str = ['W', 30, 33, 'N', 3, 6, 'E', 12, 15, 'S', 21, 24]
+const attitude_pitch = 0 // 俯仰角度数
+const height = 0 // 真空高度
+const prevRotate = 0
+const dockHeight = 0
+
+const props = defineProps(['pitchAngle','trueAltitude'])
+const pitchAngleStyle = computed(() => {
+	const pitchAngle = props?.pitchAngle || 0;
+	// 将 [-90, 90] 映射到 [0%, 100%]
+	const percentage = ((pitchAngle + 90) / 180 * 100).toFixed(2);
+	return {
+		bottom: `${percentage}%`
+	};
+})
+
+const trueAltitudeStyle = computed(() => {
+	const trueAltitude = props?.trueAltitude || 0;
+	// 将 [-240,240] 映射到 [0%, 100%]
+	const percentage = ((trueAltitude + 240) / 480 * 100).toFixed(2);
+	return {
+		bottom: `${percentage}%`
+	};
+})
+
+
 </script>
+
 <style lang="scss" scoped>
 .instrument-content {
-  height: 100%;
-  width: 100%;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  position: relative;
-  transform: translateY(20px);
+	height: 100%;
+	width: 100%;
+	display: flex;
+	gap: 0 30px;
+	justify-content: center;
+	align-items: center;
+	position: relative;
 
-  .left-img,
-  .right-img {
-    position: relative;
-    height: 100%;
-    display: flex;
-    align-items: center;
-    width: 40px;
+	.left-img,
+	.right-img {
+		position: relative;
+		width: 9px;
+		height: 127px;
 
-    img {
-      height: 100px;
-    }
-  }
+		img {
+			width: 100%;
+			height: 100%;
+		}
 
-  .left-img {
-    .text {
-      position: absolute;
-      left: 0px;
-      top: 50px;
-      width: 60px;
-      text-align: center;
-    }
+		.triangle {
+			width: 0px;
+			height: 0px;
+			margin: auto;
+			border: 6px solid transparent;
+			border-left-color: #0fff7b;
+			position: absolute;
+			left: -10px;
 
-    .scaleImg {
-      position: relative;
-      width: 100%;
-      height: 100px;
+			transform: translateY(50%);
+		}
 
-      img {
-        margin-left: 25px;
-      }
+		.rightTriangle {
+			width: 0px;
+			height: 0px;
+			margin: auto;
+			border: 6px solid transparent;
+			border-left-color: #0fff7b;
+			position: absolute;
+			right: -10px;
+			transform: translateY(50%) rotate(180deg);
+		}
 
-      .scale {
-        width: 10px;
-        height: 10px;
-        background-color: #1fa3f6;
-        position: absolute;
-        margin-left: 10px;
+		.valueBox {
+			position: absolute;
+			top: -20px;
+			left: 50%;
+			transform: translateX(-50%);
+		}
 
-        &::before {
-          content: '';
-          position: absolute;
-          width: 0;
-          height: 0;
-          top: 0px;
-          left: 10px;
-          border-top: solid 5px transparent;
-          border-left: solid 5px #1fa3f6;
-          border-bottom: solid 5px transparent;
-        }
-      }
-    }
+		.nameBox {
+			position: absolute;
+			bottom: -20px;
+			left: 50%;
+			width: auto;
+			transform: translateX(-50%);
+			font-family: Segoe UI, Segoe UI;
+			font-weight: 400;
+			font-size: 12px;
+			white-space: nowrap;
+			color: #ffffff;
+		}
+	}
 
-    &::before {
-      content: attr(data-text);
-      position: absolute;
-      right: 0px;
-      top: 50px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
+	.instrument-center {
+		position: relative;
 
-    &::after {
-      content: '俯仰角度';
-      position: absolute;
-      right: 0px;
-      text-align: right;
-      bottom: 30px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
-  }
+		.compass-box {
+			width: 180px;
+			height: 180px;
+			border-radius: 50%;
+			position: relative;
+			border: 30px solid rgba($color: #323931, $alpha: 0.5);
+			box-shadow: 0 2px 12px 0 #158aff;
+			user-select: none;
+			transform: none !important;
 
-  .right-img {
-    &::before {
-      content: attr(data-text);
-      position: absolute;
-      left: 0px;
-      top: 50px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
+			.scale {
+				width: 135%;
+				position: absolute;
+				top: 50%;
+				left: 50%;
+				font-weight: bold;
+				color: #c1c3c4;
+				text-align: left;
+				transform: translate(-50%, -50%) rotate(var(--rotate));
 
-    &::after {
-      content: '真空高度';
-      position: absolute;
-      left: 0px;
-      bottom: 30px;
-      font-size: 14px;
-      font-weight: bolder;
-      font-family: none;
-    }
+				&:nth-child(3n - 2) {
+					color: #fff;
+					font-weight: bolder;
+					font-size: 20px;
+				}
+			}
 
-    .ident-arrow {
-      position: relative;
+			.scale {
+				.text {
+					display: inline-block;
+					// rotate: -90deg;
+					transform: rotate(-90deg);
+					-ms-transform: rotate(-90deg);
+					-moz-transform: rotate(-90deg);
+					-webkit-transform: rotate(-90deg);
+					-o-transform: rotate(-90deg);
+				}
+			}
+		}
 
-      .arrow-box {
-        position: absolute;
-        bottom: 0;
-        left: 20px;
+		.rotat-btn {
+			width: 16px;
+			height: 16px;
+			background-color: rgba($color: #1fa3f6, $alpha: 1);
+			position: absolute;
+			top: 10px;
+			left: 50%;
+			transform: translateX(-50%);
 
-        .arrow {
-          position: relative;
-          width: 10px;
-          height: 10px;
-          background-color: #1fa3f6;
+			&::before {
+				content: '';
+				display: block;
+				width: 0;
+				height: 0;
+				border-left: 8px solid transparent;
+				border-right: 8px solid transparent;
+				border-bottom: 8px solid #1fa3f6;
+				position: absolute;
+				bottom: 100%;
+			}
+		}
 
-          &::before {
-            content: '';
-            position: absolute;
-            left: -9px;
-            top: 0;
+		.center-show {
+			width: 30px;
+			height: 40px;
+			position: absolute;
+			left: 50%;
+			top: 50%;
+			transform: translate(-50%, -50%);
 
-            border: 5px solid transparent {
-              right: solid 5px #1fa3f6;
-            }
-          }
-        }
-      }
-    }
-  }
+			img {
+				width: 100%;
+				height: 100%;
+				transform: rotate(var(--rotate));
+				transition: all 0.5s linear;
+			}
+		}
 
-  .instrument-center {
-    position: relative;
+		&::after {
+			content: '';
+			position: absolute;
+			width: 40px;
+			top: 50%;
+			left: 0;
+			z-index: 99;
+		}
 
-    .compass-box {
-      width: 180px;
-      height: 180px;
-      border-radius: 50%;
-      position: relative;
-      border: 30px solid rgba($color: #323931, $alpha: 0.5);
-      box-shadow: 0 2px 12px 0 #158aff;
-      user-select: none;
-      transform: none !important;
-
-      .scale {
-        width: 135%;
-        position: absolute;
-        top: 50%;
-        left: 50%;
-        font-weight: bold;
-        color: #c1c3c4;
-        text-align: left;
-        transform: translate(-50%, -50%) rotate(var(--rotate));
-
-        &:nth-child(3n - 2) {
-          color: #fff;
-          font-weight: bolder;
-          font-size: 20px;
-        }
-      }
-
-      .scale {
-        .text {
-          display: inline-block;
-          // rotate: -90deg;
-          transform: rotate(-90deg);
-          -ms-transform: rotate(-90deg);
-          -moz-transform: rotate(-90deg);
-          -webkit-transform: rotate(-90deg);
-          -o-transform: rotate(-90deg);
-        }
-      }
-
-      &::before {
-        content: '';
-        position: absolute;
-        top: -45px;
-        left: 50%;
-        transform: translateX(-50%);
-        width: 7px;
-        height: 15px;
-        background: #00ee8b;
-        margin: 0 auto;
-        box-shadow: 0 0 4px rgba(0, 0, 0, 0.5), -1px -1px 0 rgba(0, 0, 0, 0.5),
-          1px -1px 0 rgba(0, 0, 0, 0.5), -1px 1px 0 rgba(0, 0, 0, 0.5),
-          1px 1px 0 rgba(0, 0, 0, 0.5);
-      }
-
-      &::after {
-        content: attr(data-text);
-        position: absolute;
-        top: -60px;
-        font-size: 16px;
-        line-height: 16px;
-        font-weight: 600;
-        color: #00ee8b;
-        left: 50%;
-        transform: translateX(-50%);
-      }
-    }
-
-    .rotat-btn {
-      width: 16px;
-      height: 16px;
-      background-color: rgba($color: #1fa3f6, $alpha: 1);
-      position: absolute;
-      top: 10px;
-      left: 50%;
-      transform: translateX(-50%);
-
-      &::before {
-        content: '';
-        display: block;
-        width: 0;
-        height: 0;
-        border-left: 8px solid transparent;
-        border-right: 8px solid transparent;
-        border-bottom: 8px solid #1fa3f6;
-        position: absolute;
-        bottom: 100%;
-      }
-    }
-
-    .center-show {
-      width: 30px;
-      height: 40px;
-      position: absolute;
-      left: 50%;
-      top: 50%;
-      transform: translate(-50%, -50%);
-
-      img {
-        width: 100%;
-        height: 100%;
-        transform: rotate(var(--rotate));
-        transition: all 0.5s linear;
-      }
-    }
-
-    &::after {
-      content: '';
-      position: absolute;
-      width: 40px;
-      top: 50%;
-      left: 0;
-      z-index: 99;
-    }
-
-    &::before {
-      content: '';
-      position: absolute;
-      width: 40px;
-      top: 50%;
-      right: 0;
-      z-index: 99;
-    }
-  }
+		&::before {
+			content: '';
+			position: absolute;
+			width: 40px;
+			top: 50%;
+			right: 0;
+			z-index: 99;
+		}
+	}
 }
 </style>
diff --git a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
index 901d30d..f56ff8c 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
@@ -68,7 +68,7 @@
 		</div>
 		<!--     指南针-->
 		<div class="compass">
-			<ControlComPass />
+			<ControlComPass :pitchAngle="pitchAngle.angle" :trueAltitude="trueAltitude" />
 		</div>
 
 		<div class="ptzControlBox">
@@ -119,7 +119,7 @@
 			<div v-for="arr in list4" class="info">
 				<div v-for="item in arr" class="infoItem">
 					<div class="infoName">{{ item.name }}</div>
-					<div class="infoValue">{{ item.value }}</div>
+					<div class="infoValue">{{ item.value + (item.unit || '') }}</div>
 				</div>
 			</div>
 		</div>
@@ -154,6 +154,8 @@
 const taskDetails = inject('taskDetails')
 const dockSn = inject('dockSn')
 const droneSn = inject('droneSn')
+
+const trueAltitude = inject('trueAltitude')
 
 const store = useStore()
 let mqttState = null
@@ -190,8 +192,8 @@
 	return [
 		[
 			{ name: '焦距倍数', value: '0' },
-			{ name: '俯仰角度', value: pitchAngle.value.angle },
-			{ name: '横向角度', value: yawAngle.value.angle },
+			{ name: '俯仰角度', value: pitchAngle.value.angle,unit:'°' },
+			{ name: '横向角度', value: yawAngle.value.angle,unit:'°' },
 		],
 		[
 			{ name: '储存', value: '64.5G' },
@@ -201,7 +203,7 @@
 	]
 })
 const pitchAngle = computed(() => {
-	const { longitude, latitude, height, payloads } = host?.value || {}
+	const { payloads } = host?.value || {}
 	const gimbal_pitch = payloads?.[0]?.gimbal_pitch || 0
 	let direction = ''
 	if (gimbal_pitch > -2 && gimbal_pitch < 2) {
@@ -216,7 +218,7 @@
 		direction = '正下'
 	}
 	return {
-		angle: _.round(gimbal_pitch || 0, 1) + '°',
+		angle: _.round(gimbal_pitch || 0, 1),
 		direction,
 	}
 })
diff --git a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
index cc4fe6f..3034518 100644
--- a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
+++ b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -22,6 +22,7 @@
 			</template>
 
 			<!--	控制面板,里面有方法需要立即执行,不可用v-if		-->
+<!--			<ControlPanel />-->
 			<ControlPanel v-show="!isAutoControl" />
 			<img alt="" :src="amplifyImg" class="amplify" @click="isMaxMap = !isMaxMap" />
 		</div>
@@ -67,6 +68,9 @@
 provide('dockSn', dockSn)
 provide('droneSn', droneSn)
 
+const trueAltitude = ref('')
+provide('trueAltitude', trueAltitude)
+
 const isAiLive = ref(false)
 provide('isAiLive', isAiLive)
 
@@ -86,9 +90,13 @@
 	currentLiveUrl.value = res.data.data.rtcs_url
 }
 
-const getAiLiveUrl = ()=>{
-	const res = getLiveAiLinkApi({ original_stream_url: `${CURRENT_CONFIG.rtmpURL}${video_id.value}`, video_id:video_id.value })
+const getAiLiveUrl = async ()=>{
+	const res =await getLiveAiLinkApi({
+		original_stream_url: `${CURRENT_CONFIG.rtmpURL}${video_id.value.replace(/\//g, '-')}`,
+		video_id:video_id.value
+	})
 	currentLiveUrl.value = res.data.data.rtcs_url
+	ElMessage.success('开启成功')
 	isAiLive.value = true
 }
 
diff --git a/src/components/CurrentTaskDetails/TaskDetailsHead.vue b/src/components/CurrentTaskDetails/TaskDetailsHead.vue
index 19f7ca0..d417c4b 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsHead.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsHead.vue
@@ -1,6 +1,6 @@
 <template>
 	<div class="detailsHead">
-		<div class="droneName" :title="taskDetails.name">{{ taskDetails.name }}</div>
+		<div class="droneName" :title="taskDetails.device_names">{{ taskDetails.device_names }}</div>
 		<div class="infoListBox">
 			<div v-for="item in infoList">
 				<div class="infoValue" :title="item.value">{{ item.value }}{{ item.unit }}</div>
@@ -61,7 +61,7 @@
 	}
 }
 
-function refreshLive(){
+function refreshLive() {
 	EventBus.emit('CurrentTaskDetails-getDroneLiveUrl')
 }
 
@@ -72,6 +72,9 @@
 	})
 }
 
+const trueAltitude = inject('trueAltitude')
+
+// 获取真实高度
 function getRealTimeReallyHigh() {
 	if (!taskDetailsViewer?.value) return
 	const device_osd_host = wsInfo?.value?.device_osd?.data?.host || {}
@@ -79,7 +82,8 @@
 	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)
+		infoList.value[0].value = last ? _.round(height - res?.height, 1) : infoList.value[0].value
+		trueAltitude.value = infoList.value[0].value
 	})
 }
 
@@ -187,7 +191,6 @@
 				color: #ffffff;
 				line-height: 18px;
 				margin-bottom: 10px;
-
 			}
 
 			.infoTitle {
diff --git a/src/components/CurrentTaskDetails/TaskDetailsRight.vue b/src/components/CurrentTaskDetails/TaskDetailsRight.vue
index 61b2189..1e7776f 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsRight.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsRight.vue
@@ -1,6 +1,6 @@
 <template>
 	<div class="task-details-right-container">
-		<div  class="titleImg">
+		<div class="titleImg">
 			<img :src="droneImg" alt="" />
 		</div>
 
@@ -11,7 +11,7 @@
 			</div>
 		</div>
 
-		<BaseControl v-if="taskDetails.workspace_id"/>
+		<BaseControl v-if="taskDetails.workspace_id" />
 	</div>
 </template>
 <script setup>
@@ -19,12 +19,6 @@
 import BaseControl from '@/components/CurrentTaskDetails/ControlPanel/BaseControl.vue'
 
 const taskDetails = inject('taskDetails')
-
-watch(taskDetails, () => {
-	list.value.forEach(item => {
-		item.value = taskDetails?.value?.[item.field] || ''
-	})
-})
 
 const list = ref([
 	{ name: '任务编号', value: '', field: 'job_info_num' },
@@ -37,6 +31,21 @@
 	{ name: '关联算法', value: '', field: 'ai_type_str' },
 	{ name: '任务描述', value: '', field: 'remark' },
 ])
+
+watch(
+	taskDetails,
+	() => {
+		list.value.forEach(item => {
+			item.value = taskDetails?.value?.[item.field] || ''
+		})
+	},
+	{
+		immediate: true,
+		deep: true,
+	}
+)
+
+
 </script>
 
 <style scoped lang="scss">
@@ -54,7 +63,7 @@
 	gap: 25px 0;
 	align-items: center;
 
-	.manualControl{
+	.manualControl {
 		background: transparent !important;
 	}
 
@@ -68,7 +77,8 @@
 		display: flex;
 		align-items: center;
 		justify-content: center;
-		img{
+
+		img {
 			width: 100px;
 			height: 68px;
 		}
@@ -86,11 +96,12 @@
 			display: flex;
 			font-family: Segoe UI, Segoe UI;
 			font-size: 14px;
+
 			.itemName {
 				flex-shrink: 0;
 				font-weight: 400;
 
-				color: #D3D3D3;
+				color: #d3d3d3;
 			}
 
 			.itemValue {
diff --git a/src/hooks/controlDrone/useManualControl.js b/src/hooks/controlDrone/useManualControl.js
index c21c5c6..62085ce 100644
--- a/src/hooks/controlDrone/useManualControl.js
+++ b/src/hooks/controlDrone/useManualControl.js
@@ -184,24 +184,28 @@
 			case 'ArrowUp':
 				if (activeCodeKey === keyCode) return
 				clearInterval(myInterval)
+				ptzControl('up')
 				myInterval = setInterval(()=>ptzControl('up'), 200)
 				activeCodeKey = keyCode
 				break
 			case 'ArrowDown':
 				if (activeCodeKey === keyCode) return
 				clearInterval(myInterval)
+				ptzControl('down')
 				myInterval = setInterval(()=>ptzControl('down'), 200)
 				activeCodeKey = keyCode
 				break
 			case 'ArrowLeft':
 				if (activeCodeKey === keyCode) return
 				clearInterval(myInterval)
+				ptzControl('left')
 				myInterval = setInterval(()=>ptzControl('left'), 200)
 				activeCodeKey = keyCode
 				break
 			case 'ArrowRight':
 				if (activeCodeKey === keyCode) return
 				clearInterval(myInterval)
+				ptzControl('right')
 				myInterval = setInterval(()=>ptzControl('right'), 200)
 				activeCodeKey = keyCode
 				break

--
Gitblit v1.9.3