feat: 当前任务详情,相机模式,拍照录像,ui调整
6 files modified
2 files added
| New file |
| | |
| | | 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, |
| | | }); |
| | | }; |
| | | |
| | | |
| | | |
| | |
| | | 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) |
| | |
| | | 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 |
| | |
| | | } |
| | | |
| | | function manualControl() { |
| | | isAutoControl.value = false |
| | | EventBus.emit('controlPanel-control') |
| | | } |
| | | |
| | |
| | | </div> |
| | | |
| | | <div class="speed"> |
| | | <el-icon class="btnIcon"> |
| | | <el-icon class="btnIcon" @click="speed = speed + 1"> |
| | | <Plus /> |
| | | </el-icon> |
| | | <div> |
| | |
| | | <br /> |
| | | m/s |
| | | </div> |
| | | <el-icon class="btnIcon"> |
| | | <el-icon class="btnIcon" @click="speed = speed - 1"> |
| | | <Minus /> |
| | | </el-icon> |
| | | </div> |
| | |
| | | <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"> |
| | |
| | | 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') |
| | |
| | | |
| | | 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, |
| | |
| | | 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() |
| | | } |
| | | |
| | |
| | | deviceTopicInfo.value.pubTopic = data.pub[0] |
| | | } |
| | | ElMessage.success('控制成功') |
| | | isAutoControl.value = false |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | // 返航或取消返航 |
| | | const returnOrCancelReturn = () => { |
| | | if (deviceOsdInfo.value?.data?.host?.mode_code === 9) { |
| | | cancelBackDock() |
| | | } else { |
| | | onBackDock() |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => workspace_id.value, |
| | | async () => { |
| | |
| | | } |
| | | ) |
| | | |
| | | // 返航或取消返航 |
| | | 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> |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | |
| | | <TaskDetailsRight v-if="isAutoControl" /> |
| | | <template v-else> |
| | | <TaskDetailsHead /> |
| | | <TaskDetailsLeft /> |
| | | </template> |
| | | <TaskDetailsLeft /> |
| | | |
| | | |
| | | <!-- 控制面板,里面有方法需要立即执行,不可用v-if --> |
| | | <ControlPanel v-show="!isAutoControl" /> |
| | | </div> |
| | |
| | | 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({ |
| | |
| | | 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 |
| | | } |
| | |
| | | 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) |
| | | } |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | // websocket 的消息 |
| | | const messageHandler = result => { |
| | | let payload = JSON.parse(result) // 为了兼容聊天消息 |
| | | switch (payload.biz_code) { |
| | |
| | | |
| | | onMounted(() => { |
| | | getTaskDetails() |
| | | EventBus.on('CurrentTaskDetails-timeStop', changeLineQuality) |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | EventBus.off('CurrentTaskDetails-timeStop', changeLineQuality) |
| | | removeEvent() |
| | | }) |
| | | </script> |
| | |
| | | <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> |
| | |
| | | </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 { |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | |
| | | <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"> |
| | |
| | | </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') |
| | |
| | | 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 { |
| | |
| | | .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; |
| | | } |
| | | } |
| | | } |