|
|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
- <div v-drag-window class="content">
|
|
|
+ <div v-drag-window class="content infoModal-content">
|
|
|
<div class="content-title">
|
|
|
<div class="drag-title">
|
|
|
<div class="content-title-left">
|
|
|
@@ -30,12 +30,16 @@
|
|
|
</div>
|
|
|
<div class="content-dock-info">
|
|
|
<div class="content-dock-info-cell">
|
|
|
- <div class="content-dock-info-cell-style">
|
|
|
- {{ getTextByDockModeCode(deviceInfo.dock.basic_osd?.mode_code) }}
|
|
|
+ <div class="content-dock-info-cell-style"
|
|
|
+ :style="deviceInfo.dock && deviceInfo.dock.basic_osd?.mode_code !== EDockModeCode.Disconnected ? 'color:#00EE8B' : 'color:red'">
|
|
|
+ {{ getTextByDockModeCode(deviceInfo.dock ? deviceInfo.dock.basic_osd?.mode_code
|
|
|
+ : EDockModeCode.Disconnected) }}
|
|
|
</div>
|
|
|
<div class="content-dock-info-cell-status">
|
|
|
- <div v-if="deviceInfo.device">
|
|
|
- 获取机场状态
|
|
|
+ <div v-if="hangarLogInfo">
|
|
|
+ <span class="word-loop">
|
|
|
+ {{ hangarLogInfo }}
|
|
|
+ </span>
|
|
|
</div>
|
|
|
<div v-else>
|
|
|
N/A
|
|
|
@@ -123,12 +127,15 @@
|
|
|
</div>
|
|
|
<div class="content-aircraft-head-right">
|
|
|
<div class="content-aircraft-head-right-top">
|
|
|
- <div class="content-aircraft-head-right-top-style">
|
|
|
- 舱内关闭
|
|
|
+ <div class="content-aircraft-head-right-top-style"
|
|
|
+ :style="deviceInfo.device && deviceInfo.device.mode_code !== EModeCode.Disconnected ? 'color:#00EE8B' : 'color:red'">
|
|
|
+ {{ getTextByModeCode(deviceInfo.device ? deviceInfo.device.mode_code : EModeCode.Disconnected) }}
|
|
|
</div>
|
|
|
<div class="content-aircraft-head-right-top-status">
|
|
|
- <div v-if="deviceInfo.device">
|
|
|
- {{ getTextByModeCode(deviceInfo.device.mode_code) }}
|
|
|
+ <div v-if="aircraftLogInfo">
|
|
|
+ <span class="word-loop">
|
|
|
+ {{ aircraftLogInfo }}
|
|
|
+ </span>
|
|
|
</div>
|
|
|
<div v-else>
|
|
|
N/A
|
|
|
@@ -136,19 +143,26 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="content-aircraft-head-right-bottom">
|
|
|
- <div class="content-aircraft-head-right-bottom-button">
|
|
|
- 开启直播
|
|
|
+ <div class="content-aircraft-head-right-bottom-button"
|
|
|
+ @click="state.deviceLiveVisible = !state.deviceLiveVisible">
|
|
|
+ <span class="openLiveButton" v-if="!state.deviceLiveVisible">
|
|
|
+ 开启直播
|
|
|
+ </span>
|
|
|
+ <span class="openLiveButton" v-else>
|
|
|
+ 关闭直播
|
|
|
+ </span>
|
|
|
</div>
|
|
|
<div class="content-aircraft-head-right-bottom-icon">
|
|
|
<a-tooltip title="操作">
|
|
|
- <img :src="aircraftSelectedSrc" @click="setDockControlPanelVisible(false)"
|
|
|
- v-if="dockControlPanelVisible">
|
|
|
- <img :src="aircraftSrc" @click="setDockControlPanelVisible(true)" v-else>
|
|
|
+ <!-- <img :src="aircraftSelectedSrc" @click="state.droneControlPanelVisible = false"
|
|
|
+ v-if="state.droneControlPanelVisible">
|
|
|
+ <img :src="aircraftSrc" @click="state.droneControlPanelVisible = true" v-else> -->
|
|
|
+ <img style="cursor: not-allowed;" :src="aircraftSrc">
|
|
|
</a-tooltip>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="content-aircraft-head-right-select">
|
|
|
- <div v-if="state.deviceLiveStatus">
|
|
|
+ <div v-if="state.deviceLiveVisible">
|
|
|
<a-select style="width: 125px;margin-right: 5px;" placeholder="摄像头" v-model:value="state.cameraValue">
|
|
|
<a-select-option v-for="item in state.cameraList" :key="item.value" :value="item.value"
|
|
|
@click="onCameraSelect(item)">
|
|
|
@@ -161,17 +175,21 @@
|
|
|
{{ item.label }}
|
|
|
</a-select-option>
|
|
|
</a-select>
|
|
|
- <a-button style="margin-right: 5px;" :icon="h(PlaySquareOutlined)" @click="onStart" />
|
|
|
- <a-button :icon="h(PoweroffOutlined)" @click="onStop" />
|
|
|
+ <a-tooltip title="播放">
|
|
|
+ <a-button style="margin-right: 5px;" :icon="h(PlaySquareOutlined)" @click="onStart" />
|
|
|
+ </a-tooltip>
|
|
|
+ <a-tooltip title="停止">
|
|
|
+ <a-button :icon="h(PoweroffOutlined)" @click="onStop" />
|
|
|
+ </a-tooltip>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="battery-slide">
|
|
|
<div style="background: #535759;" class="width-100"></div>
|
|
|
- <div class="capacity-percent" :style="{ width: deviceInfo.device?.battery.capacity_percent + '%' }"></div>
|
|
|
+ <div class="capacity-percent" :style="{ width: capacity + '%' }"></div>
|
|
|
</div>
|
|
|
- <LivePlayer :text="state.playerText" :url="state.playerUrl" v-if="state.deviceLiveStatus" />
|
|
|
+ <LivePlayer :text="state.playerText" :url="state.playerUrl" v-if="state.deviceLiveVisible" />
|
|
|
<div class="content-aircraft-info">
|
|
|
<a-row style="margin-bottom: 5px;">
|
|
|
<a-col span="6">
|
|
|
@@ -302,10 +320,11 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 机场控制面板 -->
|
|
|
- <DockControlPanel v-if="dockControlPanelVisible" :sn="osdInfo.gateway_sn" :deviceInfo="deviceInfo"
|
|
|
- @close-control-panel="onCloseControlPanel" />
|
|
|
+ <DockControlPanel :sn="osdInfo.gateway_sn" :deviceInfo="deviceInfo" @close-control-panel="onCloseControlPanel"
|
|
|
+ v-if="dockControlPanelVisible" />
|
|
|
<!-- 飞行指令 -->
|
|
|
- <!-- <DroneControlPanel :sn="osdInfo.gateway_sn" :deviceInfo="deviceInfo" :payloads="osdInfo.payloads" /> -->
|
|
|
+ <DroneControlPanel :sn="osdInfo.gateway_sn" :deviceInfo="deviceInfo" :payloads="osdInfo.payloads"
|
|
|
+ v-if="state.droneControlPanelVisible" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -348,7 +367,9 @@ import { getLiveCapacity, startLivestream, stopLivestream } from '/@/api/manage'
|
|
|
import DockControlPanel from '../../g-map/DockControlPanel.vue'
|
|
|
import DroneControlPanel from '../../g-map/DroneControlPanel.vue'
|
|
|
import { useDockControl } from '../../g-map/use-dock-control';
|
|
|
+import { useMyStore } from '/@/store';
|
|
|
import { getTextByModeCode, getTextByDockModeCode } from '/@/utils/index'
|
|
|
+import { EModeCode, EDockModeCode } from '/@/types/device';
|
|
|
|
|
|
interface Props {
|
|
|
osdInfo: any
|
|
|
@@ -359,8 +380,34 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
|
|
|
});
|
|
|
|
|
|
+const store = useMyStore()
|
|
|
+
|
|
|
// 机场控制面板
|
|
|
-const { dockControlPanelVisible, setDockControlPanelVisible, onCloseControlPanel } = useDockControl()
|
|
|
+const { dockControlPanelVisible, setDockControlPanelVisible, onCloseControlPanel } = useDockControl();
|
|
|
+
|
|
|
+const hmsInfo = computed(() => store.state.hmsInfo);
|
|
|
+
|
|
|
+// 飞行器告警信息
|
|
|
+const aircraftLogInfo = computed(() => {
|
|
|
+ const hmsList = hmsInfo.value[props.osdInfo.sn] || [];
|
|
|
+ const info = hmsList[0];
|
|
|
+ if (info) {
|
|
|
+ return info.message_zh;
|
|
|
+ } else {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+// 机库告警信息
|
|
|
+const hangarLogInfo = computed(() => {
|
|
|
+ const hmsList = hmsInfo.value[props.osdInfo.gateway_sn] || [];
|
|
|
+ const info = hmsList[0];
|
|
|
+ if (info) {
|
|
|
+ return info.message_zh;
|
|
|
+ } else {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+})
|
|
|
|
|
|
// 遥控器信号
|
|
|
const controllerSignal = computed(() => {
|
|
|
@@ -387,7 +434,7 @@ const RTK = computed(() => {
|
|
|
if (info) {
|
|
|
return info.position_state.rtk_number;
|
|
|
} else {
|
|
|
- return '';
|
|
|
+ return 0;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -419,7 +466,7 @@ const windSpeed = computed(() => {
|
|
|
return (info.wind_speed / 10).toFixed(2) + ' m/s';
|
|
|
}
|
|
|
} else {
|
|
|
- return '';
|
|
|
+ return '--';
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -432,7 +479,7 @@ const ASL = computed(() => {
|
|
|
return info.height.toFixed(2) + ' m';
|
|
|
}
|
|
|
} else {
|
|
|
- return '';
|
|
|
+ return '--';
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -445,7 +492,7 @@ const AGL = computed(() => {
|
|
|
return info.elevation.toFixed(2) + ' m';
|
|
|
}
|
|
|
} else {
|
|
|
- return '';
|
|
|
+ return '--';
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -458,7 +505,7 @@ const HS = computed(() => {
|
|
|
return info.horizontal_speed.toFixed(2) + ' m/s';
|
|
|
}
|
|
|
} else {
|
|
|
- return '';
|
|
|
+ return '--';
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -471,7 +518,7 @@ const homeDistance = computed(() => {
|
|
|
return info.home_distance.toFixed(2) + ' m';
|
|
|
}
|
|
|
} else {
|
|
|
- return '';
|
|
|
+ return '--';
|
|
|
}
|
|
|
});
|
|
|
|
|
|
@@ -505,7 +552,8 @@ const clarityList: SelectOption[] = [
|
|
|
]
|
|
|
|
|
|
interface State {
|
|
|
- deviceLiveStatus: boolean,
|
|
|
+ deviceLiveVisible: boolean,
|
|
|
+ droneControlPanelVisible: boolean,
|
|
|
cameraList: SelectOption[],
|
|
|
cameraValue?: string,
|
|
|
videoList: SelectOption[],
|
|
|
@@ -517,7 +565,8 @@ interface State {
|
|
|
}
|
|
|
|
|
|
const state: State = reactive({
|
|
|
- deviceLiveStatus: false,// 设备直播状态
|
|
|
+ deviceLiveVisible: false,
|
|
|
+ droneControlPanelVisible: false,
|
|
|
cameraList: [],
|
|
|
cameraValue: undefined,
|
|
|
videoList: [],
|
|
|
@@ -529,27 +578,27 @@ const state: State = reactive({
|
|
|
})
|
|
|
|
|
|
const fetchLiveCapacity = async () => {
|
|
|
- // try {
|
|
|
- // const res = await getLiveCapacity({});
|
|
|
- // if (res.code === 0) {
|
|
|
- // const deviceInfo = res.data.filter((item: any) => item.sn === props.osdInfo.sn)[0];
|
|
|
- // const cameras_list = deviceInfo.cameras_list || [];
|
|
|
- // const cameraList = cameras_list.map((item: any) => {
|
|
|
- // return {
|
|
|
- // label: item.name,
|
|
|
- // value: item.index,
|
|
|
- // more: item.videos_list
|
|
|
- // }
|
|
|
- // })
|
|
|
- // state.cameraList = cameraList;
|
|
|
- // }
|
|
|
- // } catch (e: any) {
|
|
|
- // console.error(e);
|
|
|
- // }
|
|
|
+ try {
|
|
|
+ const res = await getLiveCapacity({});
|
|
|
+ if (res.code === 0) {
|
|
|
+ const deviceInfo = res.data.filter((item: any) => item.sn === props.osdInfo.sn)[0];
|
|
|
+ const cameras_list = deviceInfo.cameras_list || [];
|
|
|
+ const cameraList = cameras_list.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.index,
|
|
|
+ more: item.videos_list
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.cameraList = cameraList;
|
|
|
+ }
|
|
|
+ } catch (e: any) {
|
|
|
+ console.error(e);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
onMounted(async () => {
|
|
|
- // await fetchLiveCapacity()
|
|
|
+ await fetchLiveCapacity()
|
|
|
})
|
|
|
|
|
|
const onCameraSelect = (record: SelectOption) => {
|
|
|
@@ -696,6 +745,9 @@ const onStop = async () => {
|
|
|
&-style {
|
|
|
width: 100px;
|
|
|
border-right: 1px solid #535759;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
margin-right: 5px;
|
|
|
|
|
|
img {
|
|
|
@@ -719,6 +771,7 @@ const onStop = async () => {
|
|
|
flex: 1;
|
|
|
padding-left: 5px;
|
|
|
background: #4a4d4e;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
|
|
|
&-button {
|
|
|
@@ -727,7 +780,7 @@ const onStop = async () => {
|
|
|
padding: 2px 4px;
|
|
|
border: 1.5px solid #535759;
|
|
|
border-radius: 2px;
|
|
|
- cursor: pointer;
|
|
|
+ cursor: not-allowed;
|
|
|
margin-right: 5px;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
@@ -777,12 +830,14 @@ const onStop = async () => {
|
|
|
text-align: center;
|
|
|
white-space: nowrap;
|
|
|
overflow: hidden;
|
|
|
+ margin-bottom: 5px
|
|
|
}
|
|
|
}
|
|
|
|
|
|
&-right {
|
|
|
flex: 1;
|
|
|
padding: 5px;
|
|
|
+ overflow: hidden;
|
|
|
|
|
|
&-top {
|
|
|
margin: 10px 0;
|
|
|
@@ -791,8 +846,10 @@ const onStop = async () => {
|
|
|
|
|
|
&-style {
|
|
|
width: 100px;
|
|
|
- color: #2a994b;
|
|
|
border-right: 1px solid #535759;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
margin-right: 5px;
|
|
|
}
|
|
|
|
|
|
@@ -800,10 +857,12 @@ const onStop = async () => {
|
|
|
flex: 1;
|
|
|
padding-left: 5px;
|
|
|
background: #4a4d4e;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
&-bottom {
|
|
|
+ margin: 10px 0;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
@@ -891,4 +950,74 @@ const onStop = async () => {
|
|
|
border-radius: 2px;
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
+
|
|
|
+.word-loop {
|
|
|
+ white-space: nowrap;
|
|
|
+ display: inline-block;
|
|
|
+ animation: 10s loop linear infinite normal;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes loop {
|
|
|
+ 0% {
|
|
|
+ transform: translateX(20px);
|
|
|
+ -webkit-transform: translateX(20px);
|
|
|
+ }
|
|
|
+
|
|
|
+ 100% {
|
|
|
+ transform: translateX(-100%);
|
|
|
+ -webkit-transform: translateX(-100%);
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.infoModal-content {
|
|
|
+
|
|
|
+ // 修改按钮样式
|
|
|
+ .ant-btn {
|
|
|
+ color: #FFFFFF;
|
|
|
+ background: transparent;
|
|
|
+ border: 1px solid #535759;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #fff;
|
|
|
+ background-color: transparent;
|
|
|
+ border-color: #535759;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:focus {
|
|
|
+ color: #fff;
|
|
|
+ background-color: transparent;
|
|
|
+ border-color: #535759;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .ant-select-selector {
|
|
|
+ color: #FFFFFF;
|
|
|
+ background: transparent !important;
|
|
|
+ border: 1px solid #535759 !important;
|
|
|
+ box-shadow: none !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ant-select-arrow {
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ant-select-dropdown {
|
|
|
+ background-color: transparent;
|
|
|
+
|
|
|
+ .ant-select-item {
|
|
|
+ background-color: #000000 !important;
|
|
|
+ color: #fff;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #4a4a4a !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .ant-select-item-option-selected {
|
|
|
+ background-color: #3a3a3a;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|