forked from drone/command-center-dashboard

罗广辉
2025-04-16 88a0986cdcb84b16ed63a88f8dbefb9aa44e7365
feat: 当前任务详情,相机模式,拍照录像,ui调整
6 files modified
2 files added
507 ■■■■ changed files
src/api/payload.js 46 ●●●●● patch | view | raw | blame | history
src/assets/images/taskManagement/taskIntermediateContent/droneImg.png patch | view | raw | blame | history
src/hooks/controlDrone/useManualControl.js 51 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel/BaseControl.vue 1 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel/ControlPanel.vue 230 ●●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/CurrentTaskDetails.vue 30 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/TaskDetailsLeft.vue 129 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/TaskDetailsRight.vue 20 ●●●● patch | view | raw | blame | history
src/api/payload.js
New file
@@ -0,0 +1,46 @@
import request from '@/axios'
import { ElMessage } from 'element-plus'
const API_PREFIX = '/drone-device-core/control/api/v1'
// 获取负载控制权
export async function postPayloadAuth(sn, body) {
    return await request.post(`${API_PREFIX}/devices/${sn}/authority/payload`, body)
}
export const PayloadCommandsEnum = {
  CameraModeSwitch: 'camera_mode_switch',
  CameraPhotoTake: 'camera_photo_take',
  CameraRecordingStart: 'camera_recording_start',
  CameraScreenDrag: 'camera_screen_drag',
  CameraRecordingStop: 'camera_recording_stop',
  CameraFocalLengthSet: 'camera_focal_length_set',
  GimbalReset: 'gimbal_reset',
  CameraAim: 'camera_aim',
};
// 发送负载名称
export async function postPayloadCommands(sn, body, config = {}) {
    return await request.post(`${API_PREFIX}/devices/${sn}/payload/commands`, body, config)
}
// 拍照和录像
export async function callPhotoAndVideoCmd(sn, type) {
  return await request({
    url:`/droneAirport/liveStreamApi/${sn}/payload/photoAndVideoCmd/${type}`,
    method:'get',
  })
}
// 切换直播镜头
export const switchLivestream = (data) => {
  const url = `${API_PREFIX}/live/streams/switch`;
  return request({
    url,
    method: 'post',
    data,
  });
};
src/assets/images/taskManagement/taskIntermediateContent/droneImg.png
src/hooks/controlDrone/useManualControl.js
@@ -1,19 +1,38 @@
import { DRC_METHOD } from '@/const/drc.js'
import { useMqtt } from '@/hooks/controlDrone/useMqtt'
import { ElMessage } from 'element-plus'
import { postPayloadCommands } from '@/api/payload'
let myInterval
export const KeyCode = {
    KEY_W: 'KeyW',
    KEY_A: 'KeyA',
    KEY_S: 'KeyS',
    KEY_D: 'KeyD',
    KEY_Q: 'KeyQ',
    KEY_E: 'KeyE',
    ARROW_UP: 'ArrowUp',
    ARROW_DOWN: 'ArrowDown',
}
export const KeyCode =  {
        KEY_W: 'KeyW',
        KEY_A: 'KeyA',
        KEY_S: 'KeyS',
        KEY_D: 'KeyD',
        KEY_Q: 'KeyQ',
        KEY_E: 'KeyE',
        KEY_J: 'KeyJ',
        KEY_K: 'KeyK',
        KEY_L: 'KeyL',
        KEY_X: 'KeyX',
        KEY_Z: 'KeyZ',
        KEY_C: 'KeyC',
        KEY_I: 'KeyI',
        KEY_O: 'KeyO',
        ARROW_UP: 'ArrowUp',
        ARROW_DOWN: 'ArrowDown',
        ARROW_LEFT: 'ArrowLeft',
        ARROW_RIGHT: 'ArrowRight',
        NUMPAD_SUBTRACT: 'NumpadSubtract',
        NUMPAD_ADD: 'NumpadAdd',
        // 提升速度
        KEY_EQUAL: 'Equal',
        KEY_MINUS: 'Minus',
        // 录音
        KEY_N: 'KeyN',
        KEY_M: 'KeyM',
    }
export function useManualControl(mqttState,deviceTopicInfo, isCurrentFlightController) {
    const activeCodeKey = ref(null)
@@ -104,11 +123,23 @@
                handlePublish({ h: -HEIGHT })
                activeCodeKey.value = keyCode
                break
            default:
                break
        }
    }
    const handlePayloadTurn = (params) => {
        handleClearInterval()
        if (!this.myInterval) {
            postPayloadCommands(this.sn, params)
        }
        this.myInterval = setInterval(() => {
            postPayloadCommands(this.sn, params)
        }, 500)
    }
    function handleClearInterval() {
        clearInterval(myInterval)
        myInterval = undefined
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel/BaseControl.vue
@@ -50,7 +50,6 @@
}
function manualControl() {
    isAutoControl.value = false
    EventBus.emit('controlPanel-control')
}
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;
                }
            }
        }
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -18,8 +18,10 @@
            <TaskDetailsRight v-if="isAutoControl" />
            <template v-else>
                <TaskDetailsHead />
                <TaskDetailsLeft />
            </template>
            <TaskDetailsLeft />
            <!--    控制面板,里面有方法需要立即执行,不可用v-if        -->
            <ControlPanel v-show="!isAutoControl" />
        </div>
@@ -41,9 +43,12 @@
import TaskDetailsLeft from '@/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/TaskDetailsLeft.vue'
import TaskDetailsRight from '@/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/TaskDetailsRight.vue'
import { ElMessage } from 'element-plus'
import EventBus from '@/event-bus'
const isAutoControl = ref(true)
const lineQuality = ref(1) //1流畅,2标清
provide('isAutoControl', isAutoControl)
provide('lineQuality', lineQuality)
const isShow = defineModel('show')
const props = defineProps({
@@ -60,19 +65,29 @@
const deviceOsdInfo = ref({})
provide('taskDetails', taskDetails)
provide('deviceOsdInfo', deviceOsdInfo)
provide('dockSn', taskDetails?.value?.device_sns?.[0])
provide('droneSn', deviceOsdInfo?.value?.data?.sn)
// 机巢直播
const getDeviceLiveUrl = async () => {
    if (machineNestUrl.value) return machineNestUrl.value
    const res = await liveStart(taskDetails.value.device_sns[0], '')
    const res = await liveStart(taskDetails.value.device_sns[0], 2)
    machineNestUrl.value = res.data.data.rtcs_url
    return machineNestUrl.value
}
// 无人机直播
const getDockLiveUrl = async dockSn => {
const getDroneLiveUrl = async droneSn => {
    if (droneLiveUrl.value) return droneLiveUrl.value
    const res = await liveStart(dockSn, '')
    const res = await liveStart(droneSn, lineQuality.value)
    droneLiveUrl.value = res.data.data.rtcs_url
    return droneLiveUrl.value
}
// 无人机直播画质切换
const changeLineQuality = async () => {
    const res = await liveStart(droneSn, lineQuality.value)
    droneLiveUrl.value = res.data.data.rtcs_url
    return droneLiveUrl.value
}
@@ -81,11 +96,11 @@
const setCurrentLiveUrl = async () => {
    const data = deviceOsdInfo.value?.data
    const deviceInfo = data?.host
    const dockSn = data?.sn
    const drone = data?.sn
    if ([14, 0].includes(deviceInfo.mode_code)) {
        currentLiveUrl.value = await getDeviceLiveUrl()
    } else {
        currentLiveUrl.value = await getDockLiveUrl(dockSn)
        currentLiveUrl.value = await getDroneLiveUrl(drone)
    }
}
@@ -99,6 +114,7 @@
    })
}
// websocket 的消息
const messageHandler = result => {
    let payload = JSON.parse(result) // 为了兼容聊天消息
    switch (payload.biz_code) {
@@ -137,9 +153,11 @@
onMounted(() => {
    getTaskDetails()
    EventBus.on('CurrentTaskDetails-timeStop', changeLineQuality)
})
onBeforeUnmount(() => {
    EventBus.off('CurrentTaskDetails-timeStop', changeLineQuality)
    removeEvent()
})
</script>
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/TaskDetailsLeft.vue
@@ -1,17 +1,19 @@
<template>
    <div class="taskDetailsLeft">
        <div class="title">负载控制</div>
        <div class="singleCol">广角相机</div>
        <div class="singleCol">变焦相机</div>
        <div class="singleCol">红外相机</div>
        <div class="singleCol" @click="cameraType('wide', '广角')">广角相机</div>
        <div class="singleCol" @click="cameraType('zoom', '变焦')">变焦相机</div>
        <div class="singleCol" @click="cameraType('ir', '红外')">红外相机</div>
        <div class="multiCol">
            <div>云台回中</div>
            <div>云台朝下</div>
        </div>
        <div class="singleCol">画质</div>
        <el-select class="qualityChange" v-model="lineQuality" @change="qualityChange">
            <el-option v-for="item in qualityList" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
        <div class="multiCol">
            <div>拍照</div>
            <div>录像</div>
            <div @click="takePictures">拍照</div>
            <div @click="recordFun">{{ isRecording ? '录像中...' : '录像' }}</div>
        </div>
        <div class="multiCol">
            <div>喊话</div>
@@ -20,7 +22,58 @@
    </div>
</template>
<script setup></script>
<script setup>
import EventBus from '@/event-bus'
import { callPhotoAndVideoCmd, switchLivestream } from '@/api/payload'
import { ElMessage } from 'element-plus'
const isRecording = ref(false)
const droneSn = inject('droneSn')
const lineQuality = inject('lineQuality')
const qualityList = [
    { name: '自适应', id: 0 },
    { name: '流畅', id: 1 },
    { name: '标清', id: 2 },
    { name: '高清', id: 3 },
    { name: '超清', id: 4 },
]
// todo
function cameraType(video_type, name) {
    switchLivestream({
        // video_id: this.videoId,
        video_type,
    }).then(res => {
        ElMessage.success(`切换为${name}相机成功`)
    })
}
// 画质切换
function qualityChange() {
    EventBus.emit('CurrentTaskDetails-timeStop')
}
// 录像
function recordFun() {
    const type = isRecording.value ? 'video_stop' : 'video_start'
    const msg = isRecording.value ? '停止录像' : '开始录像'
    const emitType = isRecording.value ? 'controlPanel-timeStop' : 'controlPanel-timeStart'
    callPhotoAndVideoCmd(droneSn.value, type).then(res => {
        ElMessage.success(msg)
        EventBus.emit(emitType)
        isRecording.value = !isRecording.value
    })
}
// 拍照
function takePictures() {
    // photo拍照,video_start开始录像,video_stop结束录像
    callPhotoAndVideoCmd(droneSn.value, 'photo').then(res => {
        ElMessage.success('拍照成功')
    })
}
</script>
<style scoped lang="scss">
.taskDetailsLeft {
@@ -40,45 +93,73 @@
    font-family: Segoe UI, Segoe UI;
    font-weight: 400;
    font-size: 14px;
    color: #FFFFFF;
    color: #ffffff;
    line-height: 18px;
    text-align: center;
    align-items: center;
    gap: 12px;
    .singleCol{
    .qualityChange{
        width: 146px;
        height: 40px;
        box-shadow: 0px 4px 72px 0px rgba(0,0,0,0.25);
        background: rgba(74, 72, 72, 0.67);
        border:none!important;
        display:flex;
        justify-content:center;
        box-shadow: 0 0.4rem 7.2rem 0 rgba(0, 0, 0, 0.25);
        border-radius: 0.8rem 0.8rem 0.8rem 0.8rem;
        :deep(){
            .el-select__wrapper{
                width: 100px;
                height: 100%;
                background: transparent;
                color: #3d3b3b;
                border: none;
                box-shadow: none;
            }
            .el-select__selected-item{
                font-family: Segoe UI, Segoe UI;
                color: #ffffff;
                font-size: 14px;
            }
        }
    }
    .singleCol {
        width: 146px;
        height: 40px;
        box-shadow: 0px 4px 72px 0px rgba(0, 0, 0, 0.25);
        border-radius: 8px 8px 8px 8px;
        line-height: 40px;
        cursor: pointer;
        background: rgba(74,72,72,0.67);
        background: rgba(74, 72, 72, 0.67);
        &:hover{
            background: rgba(255,255,255,0.78);
            color: #3D3B3B;
            border: 1px solid rgba(255,255,255,0.99);
        &:hover {
            background: rgba(255, 255, 255, 0.78);
            color: #3d3b3b;
            border: 1px solid rgba(255, 255, 255, 0.99);
        }
    }
    .multiCol{
    .multiCol {
        display: flex;
        gap: 12px;
        >div{
        > div {
            cursor: pointer;
            width: 67px;
            height: 40px;
            background: rgba(74,72,72,0.67);
            box-shadow: 0px 4px 72px 0px rgba(0,0,0,0.25);
            background: rgba(74, 72, 72, 0.67);
            box-shadow: 0px 4px 72px 0px rgba(0, 0, 0, 0.25);
            border-radius: 8px 8px 8px 8px;
            line-height: 40px;
            &:hover{
                background: rgba(255,255,255,0.78);
                color: #3D3B3B;
                border: 1px solid rgba(255,255,255,0.99);
            &:hover {
                background: rgba(255, 255, 255, 0.78);
                color: #3d3b3b;
                border: 1px solid rgba(255, 255, 255, 0.99);
            }
        }
    }
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/TaskDetailsRight.vue
@@ -1,6 +1,8 @@
<template>
    <div class="task-details-right-container">
        <img :src="kz1Img" alt="" class="titleImg" />
        <div  class="titleImg">
            <img :src="droneImg" alt="" />
        </div>
        <div class="taskInfo">
            <div v-for="item in list" class="itemBox">
@@ -13,7 +15,7 @@
    </div>
</template>
<script setup>
import kz1Img from '@/assets/images/taskManagement/taskIntermediateContent/controlCenter.png'
import droneImg from '@/assets/images/taskManagement/taskIntermediateContent/droneImg.png'
import BaseControl from '@/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel/BaseControl.vue'
const taskDetails = inject('taskDetails')
@@ -59,6 +61,13 @@
        box-shadow: 0px 4px 72px 0px rgba(0, 0, 0, 0.25);
        border-radius: 12px 12px 12px 12px;
        border: 1px solid rgba(255, 255, 255, 0.99);
        display: flex;
        align-items: center;
        justify-content: center;
        img{
            width: 100px;
            height: 68px;
        }
    }
    .taskInfo {
@@ -72,16 +81,17 @@
        .itemBox {
            display: flex;
            font-family: Segoe UI, Segoe UI;
            font-size: 14px;
            .itemName {
                flex-shrink: 0;
                font-weight: 400;
                color: #D3D3D3;
            }
            .itemValue {
                font-weight: bold;
                font-size: 14px;
                color: #ffffff;
                line-height: 18px;
            }
        }
    }