forked from drone/command-center-dashboard

罗广辉
2025-04-16 88a0986cdcb84b16ed63a88f8dbefb9aa44e7365
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel/ControlPanel.vue
@@ -34,7 +34,7 @@
         </div>
         <div class="speed">
            <el-icon class="btnIcon">
            <el-icon class="btnIcon" @click="speed = speed + 1">
               <Plus />
            </el-icon>
            <div>
@@ -42,7 +42,7 @@
               <br />
               m/s
            </div>
            <el-icon class="btnIcon">
            <el-icon class="btnIcon" @click="speed = speed - 1">
               <Minus />
            </el-icon>
         </div>
@@ -81,26 +81,34 @@
            <br />
            制
         </div>
         <div class="ptzControlBtn b-r">
            <div v-for="(item, index) in list5" :style="item.style" class="ptzControlItem"></div>
         <div class="ptzControlBtnBox">
            <div class="ptzControlBtn b-r">
               <div v-for="(item, index) in list5" :style="item.style" class="ptzControlItem"></div>
            <div
               class="ptzControlItemIcon"
               v-for="(item, index) in list5"
               :style="{ transform: `rotate(${index * 90}deg)` }"
            >
               <el-icon>
                  <CaretRight />
               </el-icon>
            </div>
            <div class="circles1 b-r">
               <div class="circles2 b-r">
                  <div class="circles3 b-r">
                     <div class="circles4 b-r"></div>
               <div
                  class="ptzControlItemIcon"
                  v-for="(item, index) in list5"
                  :style="{ transform: `rotate(${index * 90}deg)` }"
               >
                  <el-icon>
                     <CaretRight />
                  </el-icon>
               </div>
               <div class="circles1 b-r">
                  <div class="circles2 b-r">
                     <div class="circles3 b-r">
                        <div class="circles4 b-r"></div>
                     </div>
                  </div>
               </div>
            </div>
            <div class="videoBox" v-if="valueTime !== '00:00:00'">
               <div class="videoName">录像</div>
               <div class="videoPoint"></div>
               <div class="videoTime">{{ valueTime }}</div>
            </div>
         </div>
         <div class="divider"></div>
         <div v-for="arr in list4" class="info">
            <div v-for="item in arr" class="infoItem">
@@ -135,6 +143,7 @@
import controlCenterImg from '@/assets/images/taskManagement/taskIntermediateContent/controlCenter.png'
import BaseControl from '@/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel/BaseControl.vue'
import EventBus from '@/event-bus'
import dayjs from 'dayjs'
const deviceOsdInfo = inject('deviceOsdInfo')
const taskDetails = inject('taskDetails')
@@ -176,6 +185,9 @@
let mqttState = null
const client_id = ref('')
const valueTime = ref('00:00:00')
let timer = null
let totalSeconds = 0
const deviceTopicInfo = ref({
   sn: deviceOsdInfo.value?.data?.sn,
@@ -183,25 +195,38 @@
   subTopic: '',
})
const flightController = ref(false)
console.log('控制面板')
// 控制对象
let manualControl = {}
const sn = computed(() => deviceOsdInfo?.value?.data?.sn)
const isAutoControl = inject('isAutoControl')
const getStyle = item => {
   return {
      ...item.style,
const timeStart = () => {
   stop() // 避免重复启动
   timer = setInterval(() => {
      totalSeconds++
      const hours = String(Math.floor(totalSeconds / 3600)).padStart(2, '0')
      const minutes = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0')
      const secs = String(totalSeconds % 60).padStart(2, '0')
      valueTime.value = `${hours}:${minutes}:${secs}`
   }, 1000)
}
const timeStop = () => {
   if (timer) {
      clearInterval(timer)
      timer = null
      totalSeconds = 0
      valueTime.value = '00:00:00'
   }
}
// 控制对象
let manualControl = {}
const sn = computed(() => deviceOsdInfo?.value?.data?.sn)
// 按下操作
function onMouseDown(type) {
   manualControl?.handleKeyup(type, { sn: sn.value, speed: speed.value })
}
// 弹起操作
function onMouseUp() {
   console.log('弹起')
   manualControl?.resetControlState()
}
@@ -231,6 +256,7 @@
         deviceTopicInfo.value.pubTopic = data.pub[0]
      }
      ElMessage.success('控制成功')
      isAutoControl.value = false
   })
}
@@ -268,6 +294,15 @@
   }
}
// 返航或取消返航
const returnOrCancelReturn = () => {
   if (deviceOsdInfo.value?.data?.host?.mode_code === 9) {
      cancelBackDock()
   } else {
      onBackDock()
   }
}
watch(
   () => workspace_id.value,
   async () => {
@@ -279,25 +314,22 @@
   }
)
// 返航或取消返航
const returnOrCancelReturn = () => {
   if (deviceOsdInfo.value?.data?.host?.mode_code === 9) {
      cancelBackDock()
   } else {
      onBackDock()
   }
}
onMounted(async () => {
   EventBus.on('controlPanel-control', control)
   EventBus.on('controlPanel-cancelControl', cancelControl)
   EventBus.on('controlPanel-returnOrCancelReturn', returnOrCancelReturn)
   EventBus.on('controlPanel-onMouseDown', onMouseDown)
   EventBus.on('controlPanel-timeStart', timeStart)
   EventBus.on('controlPanel-timeStop', timeStop)
})
onBeforeUnmount(() => {
   EventBus.off('controlPanel-control', control)
   EventBus.off('controlPanel-cancelControl', cancelControl)
   EventBus.off('controlPanel-returnOrCancelReturn', returnOrCancelReturn)
   EventBus.off('controlPanel-onMouseDown', onMouseDown)
   EventBus.off('controlPanel-timeStart', timeStart)
   EventBus.off('controlPanel-timeStop', timeStop)
   destroyConnect()
})
</script>
@@ -399,61 +431,95 @@
      align-items: center;
      justify-content: space-evenly;
      .ptzControlBtn {
         position: relative;
         overflow: hidden;
         width: 154px;
         height: 154px;
         background: linear-gradient(180deg, #818181 0%, #222222 100%);
         box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
      .ptzControlBtnBox {
         display: flex;
         flex-direction: column;
         align-items: center;
         .ptzControlItemIcon {
            pointer-events: none;
            width: 75px;
            display: flex;
            justify-content: right;
            font-size: 18px;
            position: absolute;
         }
         .ptzControlBtn {
            position: relative;
            overflow: hidden;
            width: 154px;
            height: 154px;
            background: linear-gradient(180deg, #818181 0%, #222222 100%);
            box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
         .ptzControlItem {
            position: absolute;
            width: 100%;
            height: 100%;
            transform: rotate(45deg);
            .ptzControlItemIcon {
               pointer-events: none;
               width: 75px;
               display: flex;
               justify-content: right;
               font-size: 18px;
               position: absolute;
            }
            &:hover {
               cursor: pointer;
               box-shadow: 0 0 20px 5px rgba(0, 0, 0, 0.3);
            .ptzControlItem {
               position: absolute;
               width: 100%;
               height: 100%;
               transform: rotate(45deg);
               &:hover {
                  cursor: pointer;
                  box-shadow: 0 0 20px 5px rgba(0, 0, 0, 0.3);
               }
            }
            .circles1 {
               width: 130px;
               height: 130px;
               background: linear-gradient(360deg, #282828 23%, #3a3a3a 70%, #3c3a3a 95%);
               box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
               .circles2 {
                  width: 79px;
                  height: 79px;
                  background: linear-gradient(180deg, #484848 0%, #3f3f3f 100%);
                  box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25), inset -1px -2px 4px 0px rgba(255, 255, 255, 0.25);
                  border: 1px solid rgba(0, 0, 0, 0.2);
                  .circles3 {
                     width: 42px;
                     height: 42px;
                     background: rgba(0, 0, 0, 0.31);
                     z-index: 1;
                     .circles4 {
                        width: 23px;
                        height: 23px;
                        background: #ffffff;
                        box-shadow: 2px 4px 6px 0px rgba(35, 37, 39, 0.26);
                     }
                  }
               }
            }
         }
         .circles1 {
            width: 130px;
            height: 130px;
            background: linear-gradient(360deg, #282828 23%, #3a3a3a 70%, #3c3a3a 95%);
            box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
         .videoBox {
            display: flex;
            align-items: center;
            font-family: Segoe UI, Segoe UI;
            margin-top: 5px;
            .circles2 {
               width: 79px;
               height: 79px;
               background: linear-gradient(180deg, #484848 0%, #3f3f3f 100%);
               box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25), inset -1px -2px 4px 0px rgba(255, 255, 255, 0.25);
               border: 1px solid rgba(0, 0, 0, 0.2);
            .videoName {
               font-weight: 400;
               font-size: 12px;
               color: rgba(210, 232, 250, 0.57);
            }
               .circles3 {
                  width: 42px;
                  height: 42px;
                  background: rgba(0, 0, 0, 0.31);
                  z-index: 1;
            .videoPoint {
               width: 3px;
               height: 3px;
               background: #12ff7f;
               border-radius: 50%;
               margin: 0 5px;
            }
                  .circles4 {
                     width: 23px;
                     height: 23px;
                     background: #ffffff;
                     box-shadow: 2px 4px 6px 0px rgba(35, 37, 39, 0.26);
                  }
               }
            .videoTime {
               font-weight: 400;
               font-size: 16px;
               color: #ffffff;
               line-height: 15px;
            }
         }
      }