直播接口对接,飞行作业剩余页面内容布局

main
刘妍 3 months ago
parent 17960dfa5b
commit 3d13fe720f

@ -1,10 +1,11 @@
import { defHttp } from '@/utils/http/axios';
import { StartLiveParams ,SetCameraVideoParams} from './model/index';
import { StartLiveParams, SetCameraVideoParams, ExchangeCameraParams } from './model/index';
enum Api {
StartLive = '/api/AirportMaintenance/StartLive',
EndLive = '/api/AirportMaintenance/EndLive',
SetCameraVideo = '/api/AirportMaintenance/SetCameraVideo',
ExchangeCamera = '/api/AirportMaintenance/ExchangeCamera',
}
export const startLive = (params: StartLiveParams) =>
@ -23,3 +24,9 @@ export const setCameraVideo = (params: SetCameraVideoParams) =>
url: Api.SetCameraVideo,
params,
});
export const exchangeCamera = (params: ExchangeCameraParams) =>
defHttp.post({
url: Api.ExchangeCamera,
params,
});

@ -14,3 +14,9 @@ export interface SetCameraVideoParams {
videoId?: string;
videoQuality?: number;
}
export interface ExchangeCameraParams {
videoId?: string;
position?: number;
camera?: string;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,52 @@
// 定义一个自定义指令,用来实现拖拽的逻辑
export const vDrag = {
// 在元素被插入到 DOM 前调用
beforeMount(el) {
// 定义一些变量,用来存储拖拽的状态
let isDown = false; // 是否按下鼠标
let offsetX = 0; // 鼠标相对于元素的水平偏移量
let offsetY = 0; // 鼠标相对于元素的垂直偏移量
// 定义一个函数,用来处理鼠标按下的事件
function handleMouseDown(e) {
// 设置按下的标志为 true
isDown = true;
// 计算鼠标相对于元素的偏移量
offsetX = e.clientX - el.offsetLeft;
offsetY = e.clientY - el.offsetTop;
}
// 定义一个函数,用来处理鼠标移动的事件
function handleMouseMove(e) {
// 如果按下的标志为 true才执行拖拽的逻辑
if (isDown) {
// 计算元素的新位置
let left = e.clientX - offsetX;
let top = e.clientY - offsetY;
// 设置元素的样式,使其移动到新位置
el.style.left = left + 'px';
el.style.top = top + 'px';
}
}
// 定义一个函数,用来处理鼠标松开的事件
function handleMouseUp() {
// 设置按下的标志为 false
isDown = false;
}
// 给元素添加鼠标按下的事件监听器
el.addEventListener('mousedown', handleMouseDown);
// 给 document 添加鼠标移动的事件监听器,这样可以使元素跟随鼠标移动,即使鼠标移出了元素的范围
document.addEventListener('mousemove', handleMouseMove);
// 给 document 添加鼠标松开的事件监听器,这样可以使元素停止移动,即使鼠标松开在元素外面
document.addEventListener('mouseup', handleMouseUp);
},
// 在绑定元素的父组件卸载后调用
// unmounted(el) {
// // 移除之前添加的事件监听器,避免内存泄漏
// el.removeEventListener('mousedown', handleMouseDown);
// document.removeEventListener('mousemove', handleMouseMove);
// document.removeEventListener('mouseup', handleMouseUp);
// },
};

@ -3,4 +3,7 @@ export { default as AirportInformation } from './src/AirportInformation.vue';
export { default as UAVInformation } from './src/UAVInformation.vue';
export { default as AirportLive } from './src/AirportLive.vue';
export { default as LivePreview } from './src/LivePreview.vue';
export { default as RemoteDebugging } from './src/RemoteDebugging.vue';
export { default as LoadControl } from './src/LoadControl.vue';
export { default as FlightControl } from './src/FlightControl.vue';
export { default as Map } from '../workplan/components/map.vue';

@ -1,24 +1,42 @@
<template>
<div>
<div style="width: 100%; height: calc(100vh - 80px)">
<Map></Map>
<div style="width: 100%; height: 100vh">
<Map :airRoute="airRoute"></Map>
</div>
<SelectComponent @selectChange="changeSelect" />
<AirportInformation @changeLive="changeAirportLive" :airportAllVal="airportAllVal" />
<UAVInformation :uavAllVal="uavAllVal" />
<div class="AirportLive" v-if="airportLiveVisible">
<AirportInformation
@changeLive="changeAirportLive"
@changeRemote="changeRemote"
:airportAllVal="airportAllVal"
/>
<UAVInformation
:uavAllVal="uavAllVal"
@changeLoadControl="changeLoadControl"
@changeFlightControl="changeFlightControl"
/>
<!-- 远程调试 -->
<div v-if="remoteVisible">
<RemoteDebugging @changeRemote="changeRemote" />
</div>
<!-- 负载控制 -->
<div v-if="loadControlVisible">
<LoadControl @changeLoadControl="changeLoadControl" />
</div>
<!-- 飞行控制 -->
<div v-if="flightControlVisible">
<FlightControl @changeFlightControl="changeFlightControl" />
</div>
<div class="AirportLive" v-if="airportLiveVisible" v-drag>
<AirportLive />
</div>
<div
class="LivePreview"
v-if="livePreviewVisible"
:style="{ bottom: airportLiveVisible ? '300px' : '20px' }"
v-drag
>
<LivePreview />
</div>
<!-- <div class="flightoperation-container">
</div> -->
</div>
</template>
<script setup lang="ts">
@ -30,23 +48,51 @@
AirportLive,
LivePreview,
Map,
RemoteDebugging,
LoadControl,
FlightControl,
} from './index';
import { useMessage } from '@/hooks/web/useMessage';
import { getClient, createConnection } from '@/utils/mqtt';
import { buildGUID } from '@/utils/uuid';
import { vDrag } from '@/utils/drag';
const { createMessage } = useMessage();
const airportAllVal = ref();
const uavAllVal = ref();
const airRoute = ref({
airLineType: null,
airType: null,
airModel: null,
name: null,
});
onMounted(() => {
createConnection();
});
const changeSelectValue = ref();
const airportLiveVisible = ref(false);
//
const airportLiveVisible = ref(true);
//
const livePreviewVisible = ref(true);
//
const remoteVisible = ref(false);
//
const loadControlVisible = ref(false);
//
const flightControlVisible = ref(false);
const changeAirportLive = () => {
airportLiveVisible.value = !airportLiveVisible.value;
};
const changeRemote = () => {
remoteVisible.value = !remoteVisible.value;
};
const changeLoadControl = () => {
loadControlVisible.value = !loadControlVisible.value;
};
const changeFlightControl = () => {
flightControlVisible.value = !flightControlVisible.value;
};
const changeSelect = (value: any) => {
console.log(value);
changeSelectValue.value = value;

@ -61,10 +61,12 @@
</div>
</div>
<div class="content-button">
<a-button type="primary" style="background: #3a57e8" @click="airportLive"
<a-button type="primary" style="background: #3a57e8" @click="emits('changeLive')"
>机场直播</a-button
>
<a-button type="primary" style="background: #0a99eb">远程调试</a-button>
<a-button type="primary" style="background: #0a99eb" @click="emits('changeRemote')"
>远程调试</a-button
>
</div>
</div>
</div>
@ -74,7 +76,7 @@
import { getClient, createConnection } from '@/utils/mqtt';
import { timestampToFormattedDate } from '@/utils/index';
const emits = defineEmits(['changeLive']);
const emits = defineEmits(['changeLive', 'changeRemote']);
const props = defineProps({
airportAllVal: Object,
});
@ -102,9 +104,6 @@
time.value = timestampToFormattedDate(val.timestamp);
},
);
const airportLive = () => {
emits('changeLive');
};
onMounted(() => {});
</script>
<style lang="less" scoped>
@ -120,7 +119,6 @@
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
opacity: 0.9;
backdrop-filter: blur(3px);
color: #fff;
.title {
@ -128,7 +126,6 @@
padding: 10px 0;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-bottom: 1px solid #4e5778;
opacity: 0.5;
span {
color: #f2762d;
}

@ -26,7 +26,6 @@
<script setup lang="ts">
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
import { onMounted, onBeforeUnmount } from 'vue';
// import 'videojs-contrib-hls';
import { startLive, endLive } from '@/api/workmanagement/airportMaintenance';
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css'; //
@ -59,6 +58,7 @@
videoId: '8UUXN5400A079H/165-0-7/normal-0',
}).then((res) => {
console.log(res);
player.dispose();
});
};
onMounted(() => {
@ -80,7 +80,6 @@
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
opacity: 0.9;
backdrop-filter: blur(3px);
color: #fff;
margin-top: 10px;

@ -0,0 +1,164 @@
<template>
<div class="flight-control" v-if="airportVal" v-drag>
<div class="title">
<div> 飞行控制<i>暂无 </i> </div>
<div @click="emits('changeFlightControl')">
<CloseOutlined />
</div>
</div>
<div class="content">
<div class="content-button">
<a-button>抢夺负载控制</a-button>
<a-button>进入指令飞行</a-button>
<a-button>退出指令飞行</a-button>
<a-button>一键起飞</a-button>
<a-button>飞向目标点</a-button>
<a-button>一键返航</a-button>
</div>
<div class="content-info">
<div class="info-item">
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
<div class="info-item-top"></div>
<div class="info-item-right"></div>
<div class="info-item-bottom"></div>
<div class="info-item-left"></div>
</div>
<div class="info-item">
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
<div class="info-item-top"></div>
<div class="info-item-right"></div>
<div class="info-item-bottom"></div>
<div class="info-item-left"></div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { getClient, createConnection } from '@/utils/mqtt';
import { CloseOutlined } from '@ant-design/icons-vue';
import { vDrag } from '@/utils/drag';
const emits = defineEmits(['changeFlightControl']);
const props = defineProps({
airportAllVal: Object,
});
console.log(props);
const airportVal: any = ref({
mode_code: 0,
wind_speed: 0,
environment_temperature: 0,
temperature: 0,
rainfall: 0,
network_state: {
rate: 0,
},
drone_in_dock: 0,
drone_charge_state: {
capacity_percent: 0,
},
});
watch(
() => props.airportAllVal,
(val) => {
console.log(val);
airportVal.value = val.data;
},
);
onMounted(() => {});
</script>
<style lang="less" scoped>
.flight-control {
position: absolute;
bottom: 100px;
left: 700px;
width: 360px;
height: 350px;
padding: 10px 20px;
margin: 10px 0 0 10px;
background: #0d0e15;
box-shadow:
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
backdrop-filter: blur(3px);
color: #fff;
.title {
width: 100%;
padding: 10px 0;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-bottom: 1px solid #4e5778;
display: flex;
align-items: center;
justify-content: space-between;
i {
color: #f2762d;
font-style: normal;
}
div {
color: #fff;
cursor: pointer;
}
}
.content-item {
display: flex;
align-items: center;
border-bottom: 1px solid #4e5778;
padding: 10px 0;
}
.content-button {
margin-top: 10px;
button {
background: none;
margin: 10px 0 0 10px;
color: #fff;
}
}
.content-info {
display: flex;
align-items: center;
justify-content: space-between;
.info-item {
position: relative;
width: 48%;
margin: 40px 0 20px 20px;
img {
width: 100px;
}
.info-item-top {
width: 40px;
height: 40px;
position: absolute;
top: 0px;
left: 30px;
cursor: pointer;
}
.info-item-right {
width: 40px;
height: 40px;
position: absolute;
top: 30px;
right: 40px;
cursor: pointer;
}
.info-item-bottom {
width: 40px;
height: 40px;
position: absolute;
bottom: 0px;
left: 30px;
cursor: pointer;
}
.info-item-left {
width: 40px;
height: 40px;
position: absolute;
top: 30px;
left: 0px;
cursor: pointer;
}
}
}
}
</style>

@ -33,7 +33,7 @@
<div class="live-type">广角</div>
<div class="player">
<video
id="player-container-id"
id="player-container-id-live"
width="414"
height="270"
preload="auto"
@ -49,7 +49,12 @@
import { reactive, onMounted, ref } from 'vue';
import { buildGUID } from '@/utils/uuid';
import { getClient, createConnection } from '@/utils/mqtt';
import { startLive, endLive, setCameraVideo } from '@/api/workmanagement/airportMaintenance';
import {
startLive,
endLive,
setCameraVideo,
exchangeCamera,
} from '@/api/workmanagement/airportMaintenance';
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css'; //
@ -62,11 +67,11 @@
cameraOptions: [
{
label: '相机',
value: 1,
value: 0,
},
{
label: '直播',
value: 2,
value: 1,
},
],
resolutionOptions: [
@ -92,6 +97,19 @@
},
],
});
const startLiveFun = () => {
const querys = {
urlType: 1, // 0 = RTMP 1GB28181 3WebRTC 4
url: 'rtmp://221.2.83.254:1935/live/3',
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
quality: 1, // 0=1=2=3=4=
};
startLive(querys).then((res) => {
console.log(res);
playVideo();
});
};
const resolutionChange = (val: any) => {
const querys = {
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
@ -105,20 +123,14 @@
const cameraChange = (val: any) => {
console.log(val);
const requestData = {
bid: buildGUID(),
data: {
camera_position: 0,
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
},
method: 'live_camera_change',
tid: buildGUID(),
timestamp: 1654070968655,
};
const publish = {
topic: 'thing/product/8UUXN5400A079H/services',
qos: 0,
payload: JSON.stringify(requestData),
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
position: val, // 0=1=2=3=4=
camera: '99-0-0',
};
exchangeCamera(requestData).then((res) => {
console.log(res);
playVideo();
});
};
const data = reactive({
playedTime: 0,
@ -126,7 +138,7 @@
maxTime: 0,
});
const playVideo = () => {
player = TCPlayer('player-container-id', {
player = TCPlayer('player-container-id-live', {
width: 380,
height: 180,
sources: [
@ -139,13 +151,14 @@
};
const closeLive = () => {
endLive({
videoId: '8UUXN5400A079H/165-0-7/normal-0',
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
}).then((res) => {
console.log(res);
});
};
onMounted(() => {
resolutionChange(1);
startLiveFun();
// resolutionChange(1);
});
</script>
<style lang="less" scoped>
@ -158,7 +171,6 @@
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
opacity: 0.9;
backdrop-filter: blur(3px);
color: #fff;
margin-top: 10px;

@ -0,0 +1,169 @@
<template>
<div class="remote-debugging" v-if="airportVal" v-drag>
<div class="title">
<span> 负载控制 </span>
<div @click="emits('changeLoadControl')">
<CloseOutlined />
</div>
</div>
<div class="content">
<div class="content-item">
<span>负载控制</span>
<a-button>抢夺负载控制</a-button>
</div>
<div class="content-item">
<span>切换相机模式</span>
<a-button>抢夺负载控制</a-button>
</div>
<div class="content-item">
<span>拍照</span>
<a-button>单拍</a-button>
</div>
<div class="direction-controller">
<img src="@/assets/images/flightoperation/direction_controller.png" alt="" />
<div class="direction-controller-top"></div>
<div class="direction-controller-right"></div>
<div class="direction-controller-bottom"></div>
<div class="direction-controller-left"></div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { getClient, createConnection } from '@/utils/mqtt';
import { CloseOutlined } from '@ant-design/icons-vue';
import { vDrag } from '@/utils/drag';
const emits = defineEmits(['changeLoadControl']);
const props = defineProps({
airportAllVal: Object,
});
console.log(props);
const checked = ref(false);
const airportVal: any = ref({
mode_code: 0,
wind_speed: 0,
environment_temperature: 0,
temperature: 0,
rainfall: 0,
network_state: {
rate: 0,
},
drone_in_dock: 0,
drone_charge_state: {
capacity_percent: 0,
},
});
watch(
() => props.airportAllVal,
(val) => {
console.log(val);
airportVal.value = val.data;
},
);
onMounted(() => {});
</script>
<style lang="less" scoped>
.remote-debugging {
position: absolute;
bottom: 100px;
left: 300px;
width: 360px;
height: 420px;
padding: 10px 20px;
margin: 10px 0 0 10px;
background: #0d0e15;
box-shadow:
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
backdrop-filter: blur(3px);
color: #fff;
.title {
width: 100%;
padding: 10px 0;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-bottom: 1px solid #4e5778;
display: flex;
align-items: center;
justify-content: space-between;
div {
cursor: pointer;
}
}
.content-title {
font-size: 14px;
padding: 10px 0;
span {
font-size: 12px;
}
}
.content-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
span {
display: block;
width: 50%;
text-align: right;
}
button {
text-align: center;
background: none;
font-size: 12px;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-radius: 2px;
border: 1px solid #3b4154;
color: #fff;
}
}
.content-button {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.direction-controller {
position: relative;
img {
margin-left: 60px;
width: 200px;
}
.direction-controller-top {
width: 50px;
height: 50px;
position: absolute;
top: 20px;
left: 130px;
cursor: pointer;
}
.direction-controller-right {
width: 50px;
height: 50px;
position: absolute;
top: 70px;
right: 80px;
cursor: pointer;
}
.direction-controller-bottom {
width: 50px;
height: 50px;
position: absolute;
bottom: 20px;
right: 130px;
cursor: pointer;
}
.direction-controller-left {
width: 50px;
height: 50px;
position: absolute;
top: 80px;
left: 80px;
cursor: pointer;
}
}
}
</style>

@ -0,0 +1,232 @@
<template>
<div class="remote-debugging" v-if="airportVal" v-drag>
<div class="title">
<span>
远程调试
<a-switch v-model:checked="checked" />
</span>
<div @click="emits('changeRemote')">
<CloseOutlined />
</div>
</div>
<div class="content">
<div class="content-item">
<div class="item-div">
<img src="@/assets/images/flightoperation/cover.png" alt="" />
<div class="item-text">
<span>关闭</span>
<i>舱盖</i>
</div>
<a-button>开启</a-button>
</div>
<div class="item-div">
<img src="@/assets/images/flightoperation/push_od.png" alt="" />
<div class="item-text">
<span>关闭</span>
<i>推杆</i>
</div>
<a-button>开启</a-button>
</div>
</div>
<div class="content-item">
<div class="item-div">
<img src="@/assets/images/flightoperation/voltage.png" alt="" />
<div class="item-text">
<span>空闲中</span>
<i>机场系统</i>
</div>
<a-button>重启</a-button>
</div>
<div class="item-div">
<img src="@/assets/images/flightoperation/4g.png" alt="" />
<div class="item-text">
<span>关闭</span>
<i>增强图传</i>
</div>
<a-button>开启</a-button>
</div>
</div>
<div class="content-item">
<div class="item-div">
<img src="@/assets/images/flightoperation/shut_down.png" alt="" />
<div class="item-text">
<span>关机</span>
<i>飞行器电源</i>
</div>
<a-button>开机</a-button>
</div>
<div class="item-div">
<img src="@/assets/images/flightoperation/charging.png" alt="" />
<div class="item-text">
<span>空闲</span>
<i>飞行器充电</i>
</div>
<a-button>开启</a-button>
</div>
</div>
<div class="content-item">
<div class="item-div">
<img src="@/assets/images/flightoperation/conditioner.png" alt="" />
<div class="item-text">
<span>空闲中</span>
<i>空调模式</i>
</div>
<a-button>切换</a-button>
</div>
<div class="item-div">
<img src="@/assets/images/flightoperation/storage.png" alt="" />
<div class="item-text">
<span>空闲中</span>
<i>机场存储</i>
</div>
<a-button>格式化</a-button>
</div>
</div>
<div class="content-item">
<div class="item-div">
<img src="@/assets/images/flightoperation/alarm.png" alt="" />
<div class="item-text">
<span>关闭</span>
<i>声光报警</i>
</div>
<a-button>开启</a-button>
</div>
<div class="item-div">
<img src="@/assets/images/flightoperation/battery.png" alt="" />
<div class="item-text">
<span>待命模式</span>
<i>电池模式</i>
</div>
<a-button>计划</a-button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { getClient, createConnection } from '@/utils/mqtt';
import { CloseOutlined } from '@ant-design/icons-vue';
import { vDrag } from '@/utils/drag';
const emits = defineEmits(['changeRemote']);
const props = defineProps({
airportAllVal: Object,
});
console.log(props);
const checked = ref(false);
const airportVal: any = ref({
mode_code: 0,
wind_speed: 0,
environment_temperature: 0,
temperature: 0,
rainfall: 0,
network_state: {
rate: 0,
},
drone_in_dock: 0,
drone_charge_state: {
capacity_percent: 0,
},
});
watch(
() => props.airportAllVal,
(val) => {
console.log(val);
airportVal.value = val.data;
},
);
onMounted(() => {});
</script>
<style lang="less" scoped>
.remote-debugging {
position: absolute;
top: 100px;
left: 300px;
width: 360px;
padding: 10px 20px;
margin: 10px 0 0 10px;
background: #0d0e15;
box-shadow:
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
backdrop-filter: blur(3px);
color: #fff;
.title {
width: 100%;
padding: 10px 0;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-bottom: 1px solid #4e5778;
display: flex;
align-items: center;
justify-content: space-between;
div {
cursor: pointer;
}
}
.content-title {
font-size: 14px;
padding: 10px 0;
span {
font-size: 12px;
}
}
.content-item {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #4e5778;
padding: 10px 0;
.item-div {
width: 48%;
display: flex;
align-items: center;
justify-content: space-around;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-radius: 2px;
border: 1px solid #3b4154;
img {
width: 20px;
}
.item-text {
width: 60px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
span {
font-size: 12px;
width: 60px;
padding: 4px 0;
}
i {
width: 60px;
padding: 4px 0;
font-size: 10px;
display: block;
border-top: 1px solid #4e5778;
font-style: normal;
}
}
button {
text-align: center;
background: none;
height: 20px;
padding: 0 4px;
font-size: 12px;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-radius: 2px;
border: 1px solid #3b4154;
color: #fff;
}
}
}
.content-button {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
</style>

@ -1,7 +1,7 @@
<template>
<div class="flightoperation-top">
<div class="select-item">
<CopyOutlined style="color: #fff; font-size: 20px; margin-left: 10px" />
<img src="@/assets/images/flightoperation/project.png" alt="" />
<a-select
ref="select"
v-model:value="selectVal.project"
@ -12,7 +12,7 @@
/>
</div>
<div class="select-item">
<CopyOutlined style="color: #fff; font-size: 20px; margin-left: 10px" />
<img src="@/assets/images/flightoperation/equipment.png" alt="" />
<a-select
ref="select"
v-model:value="selectVal.equipment"
@ -23,7 +23,7 @@
/>
</div>
<div class="select-item">
<CopyOutlined style="color: #fff; font-size: 20px; margin-left: 10px" />
<img src="@/assets/images/flightoperation/airport.png" alt="" />
<a-select
ref="select"
v-model:value="selectVal.airport"
@ -37,7 +37,6 @@
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { CopyOutlined, DownOutlined } from '@ant-design/icons-vue';
const emits = defineEmits(['selectChange']);
const selectVal = reactive({
@ -98,6 +97,10 @@
::v-deep .ant-select-arrow {
color: #fff;
}
img {
width: 20px;
margin-left: 10px;
}
}
.select-item:nth-child(2) {
background: #08b1ba;

@ -8,46 +8,46 @@
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
<img src="@/assets/images/flightoperation/project.png" alt="" />
1
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
<img src="@/assets/images/flightoperation/arrow.png" alt="" />
0%
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
<img src="@/assets/images/flightoperation/rtk.png" alt="" />
0
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
<img src="@/assets/images/flightoperation/electricity.png" alt="" />
89%(空闲中)
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
<img src="@/assets/images/flightoperation/agl.png" alt="" />
0M
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
<img src="@/assets/images/flightoperation/agl.png" alt="" />
0M
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
<img src="@/assets/images/flightoperation/hs.png" alt="" />
0m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
<img src="@/assets/images/flightoperation/h.png" alt="" />
0M
</div>
</div>
<div class="content-edit">
@ -85,11 +85,17 @@
</div>
</div>
<div class="content-button">
<a-button type="primary" style="background: #3a57e8">飞行控制</a-button>
<a-button type="primary" style="background: #0a99eb">负载控制</a-button>
<a-button type="primary" style="background: #3a57e8" @click="emits('changeFlightControl')"
>飞行控制</a-button
>
<a-button type="primary" style="background: #0a99eb" @click="emits('changeLoadControl')"
>负载控制</a-button
>
</div>
<div class="content-button">
<a-button type="primary" style="background: #3a57e8; width: 100%">负载直播</a-button>
<a-button type="primary" style="background: #3a57e8; width: 100%" @click="loadLiveStreaming"
>负载直播</a-button
>
</div>
</div>
</div>
@ -98,7 +104,53 @@
import { reactive, ref, watch } from 'vue';
import { CopyOutlined, EditOutlined } from '@ant-design/icons-vue';
import { timestampToFormattedDate } from '@/utils/index';
import { getClient, createConnection } from '@/utils/mqtt';
import { buildGUID } from '@/utils/uuid';
//
const loadLiveStreaming = () => {
const querys = {
bid: buildGUID,
method: 'live_start_push',
tid: buildGUID,
timestamp: new Date().getTime(),
data: {
url_type: 1, // 0 = RTMP 1GB28181 3WebRTC 4
url: 'rtmp://221.2.83.254:1935/live/2',
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
video_id: '8UUXN5400A079H/165-0-7/normal-0',
video_quality: 1, // 0=1=2=3=4=
},
};
getClient().publish(
'thing/product/8UUXN5400A079H/services',
JSON.stringify(querys),
{ qos: 0 },
(err) => {
if (err) {
console.error('Publish error:', err);
}
},
);
getClient().subscribe('thing/product/8UUXN5400A079H/services_reply', { qos: 0 }, (err, res) => {
console.log('订阅成功', res);
//
const timer = window.setInterval(() => {
const topic = 'thing/product/8UUXN5400A079H/services_reply';
if (getClient() != null) {
// Received
getClient().on('message', (topic, message, packet) => {
const rs = JSON.parse(message);
console.log(rs);
});
} else {
console.log('开启定时器接收数据2');
}
}, 5000);
});
};
const emits = defineEmits(['changeLoadControl', 'changeFlightControl']);
const props = defineProps({
uavAllVal: Object,
});
@ -132,7 +184,6 @@
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
opacity: 0.9;
backdrop-filter: blur(3px);
color: #fff;
.title {
@ -140,7 +191,6 @@
padding: 10px 0;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-bottom: 1px solid #4e5778;
opacity: 0.5;
span {
color: #3a57e8;
}
@ -159,6 +209,9 @@
padding: 10px 0;
.item-div {
width: 49%;
img {
width: 20px;
}
}
}
.content-button {

Loading…
Cancel
Save