飞行作业页面部分内容对接

main
刘妍 3 months ago
parent a219da084e
commit 6147718a3c

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -145,3 +145,8 @@ export const withInstall = <T extends CustomComponent>(component: T, alias?: str
};
return component as WithInstall<T>;
};
// 时间戳转时间
export const timestampToFormattedDate = (timestamp) => {
const date = new Date(timestamp);
return `${date.getFullYear()}-${('0' + (date.getMonth() + 1)).slice(-2)}-${('0' + date.getDate()).slice(-2)} ${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}:${('0' + date.getSeconds()).slice(-2)}`;
};

@ -48,13 +48,19 @@ const createConnection = () => {
const connectUrl = `${protocol}://${host}:${port}${endpoint}`;
client = mqtt.connect(connectUrl, options);
if (client.on) {
// client.on('reconnect', handleOnReConnect);
return client;
// client.on('reconnect', handleOnReConnect);
}
} catch (error) {
console.log('mqtt.connect error', error);
}
};
const getClient = () => {
if (!client || !client.connected) {
createConnection();
}
return client;
};
// 断开连接
const destroyConnection = () => {
if (client.connected) {
@ -83,4 +89,5 @@ export {
// 连接
createConnection,
destroyConnection,
getClient,
};

@ -3,9 +3,9 @@
<div style="width: 100%; height: calc(100vh - 80px)">
<Map></Map>
</div>
<SelectComponent />
<AirportInformation @changeLive="changeAirportLive" />
<UAVInformation />
<SelectComponent @selectChange="changeSelect" />
<AirportInformation @changeLive="changeAirportLive" :airportAllVal="airportAllVal" />
<UAVInformation :uavAllVal="uavAllVal" />
<div class="AirportLive" v-if="airportLiveVisible">
<AirportLive />
</div>
@ -32,45 +32,51 @@
Map,
} from './index';
import { useMessage } from '@/hooks/web/useMessage';
import { createConnection } from '@/utils/mqtt';
import { getClient, createConnection } from '@/utils/mqtt';
import { buildGUID } from '@/utils/uuid';
const { createMessage } = useMessage();
const airportAllVal = ref();
const uavAllVal = ref();
onMounted(() => {
createConnection().on('connect', (res) => {
console.log('连接成功', res);
// createMessage.success('');
});
createConnection();
});
const changeSelectValue = ref();
const airportLiveVisible = ref(false);
const livePreviewVisible = ref(true);
const changeAirportLive = () => {
airportLiveVisible.value = !airportLiveVisible.value;
const requestData = {
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=
},
};
console.log(requestData);
const publish = {
topic: 'thing/product/8UUXN5400A079H/services',
qos: 0,
payload: JSON.stringify(requestData),
};
const { topic, qos, payload } = publish;
createConnection().publish(topic, payload, { qos }, (error, res) => {
};
const changeSelect = (value: any) => {
console.log(value);
changeSelectValue.value = value;
const topic = 'thing/product/8UUXN5400A079H/osd';
// const topic = 'thing/product/8UUXN5400A079H/requests';
// const topic = 'thing/product/8UUXN5400A079H/events';
getClient().subscribe(topic, { qos: 0 }, (error, res) => {
if (error) {
console.log('Publish error', error);
createConnection();
return;
}
console.log('Publish success', res);
//
const timer = window.setInterval(() => {
if (getClient() != null) {
// Received
getClient().on('message', (topic, message, packet) => {
const rs = JSON.parse(message);
console.log(rs);
if (!rs.data.wind_speed) {
} else {
//
airportAllVal.value = rs;
}
//
// uavAllVal.value =
});
} else {
console.log('开启定时器接收数据2');
}
}, 5000);
});
};
</script>

@ -1,48 +1,63 @@
<template>
<div class="airport-information">
<div class="title">机场信息<span>设备空闲中</span></div>
<div class="airport-information" v-if="airportVal">
<div class="title"
>机场信息<span>
<template v-if="airportVal.mode_code == 0"></template>
<template v-else-if="airportVal.mode_code == 1">飞行作业中</template>
<template v-else-if="airportVal.mode_code == 2">作业后状态恢复</template>
<template v-else-if="airportVal.mode_code == 3">自定义飞行区更新中</template>
<template v-else-if="airportVal.mode_code == 4">地形障碍物更新中</template>
<template v-else-if="airportVal.mode_code == 5">任务空闲</template>
<template v-else-if="airportVal.mode_code == 255">飞行器异常</template>
<template v-else-if="airportVal.mode_code == 256">未知状态</template>
</span></div
>
<div class="content">
<div class="content-title">
2025-06-27 00:00:00
<span>机场摄像头未开</span>
{{ time }}
<!-- 获取不到摄像头的内容 -->
<!-- <span>机场摄像头未开</span> -->
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
<img src="@/assets/images/flightoperation/wind_speed.png" alt="" />
{{ airportVal.wind_speed }}m/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/environment_temperature.png" alt="" />
{{ airportVal.environment_temperature }}
</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/temperature.png" alt="" />
{{ airportVal.temperature }}
</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/rainfall.png" alt="" />
<template v-if="airportVal.rainfall == 0"></template>
<template v-else-if="airportVal.rainfall == 1">小雨</template>
<template v-else-if="airportVal.rainfall == 2">中雨</template>
<template v-else-if="airportVal.rainfall == 3">大雨</template>
</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/rate.png" alt="" />
{{ airportVal.network_state.rate }}KB/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/drone_in_dock.png" alt="" />
{{ airportVal.drone_in_dock == 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/voltage.png" alt="" />
{{ airportVal.drone_charge_state.capacity_percent }} %
</div>
</div>
<div class="content-button">
@ -55,23 +70,42 @@
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
import { CopyOutlined } from '@ant-design/icons-vue';
import { createConnection } from '@/utils/mqtt';
import { onMounted, ref, watch } from 'vue';
import { getClient, createConnection } from '@/utils/mqtt';
import { timestampToFormattedDate } from '@/utils/index';
const emits = defineEmits(['changeLive']);
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,
},
});
const time = ref(timestampToFormattedDate(new Date().getTime()));
watch(
() => props.airportAllVal,
(val) => {
console.log(val);
airportVal.value = val.data;
time.value = timestampToFormattedDate(val.timestamp);
},
);
const airportLive = () => {
emits('changeLive');
};
onMounted(() => {
createConnection().subscribe('thing/product/8UUXN5400A079H/osd', (error, res) => {
if (error) {
console.log('Subscribe to topics error', error);
return;
}
console.log('Subscribe to topics res', res);
});
});
onMounted(() => {});
</script>
<style lang="less" scoped>
.airport-information {
@ -113,6 +147,9 @@
padding: 10px 0;
.item-div {
width: 49%;
img {
width: 20px;
}
}
}
.content-button {

@ -1,154 +0,0 @@
<template>
<div class="live-preview">
<div class="preview-title">
<div class="title-select">
<div class="title-select-item">
<span>相机:</span>
<a-select
ref="select"
v-model:value="selectVal.camera"
style="width: 80px"
:options="optionsArr.cameraOptions"
/>
</div>
<div class="title-select-item">
<span>分辨率:</span>
<a-select
ref="select"
v-model:value="selectVal.resolution"
style="width: 80px"
:options="optionsArr.resolutionOptions"
/>
</div>
</div>
<div class="title-icon">
<RedoOutlined />
<a-divider type="vertical" style="border-color: #4e5778" />
<ExpandOutlined />
<a-divider type="vertical" style="border-color: #4e5778" />
<PoweroffOutlined />
</div>
</div>
<div class="live-type">广角</div>
</div>
</template>
<script setup lang="ts">
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
import { reactive } from 'vue';
import { useMessage } from '@/hooks/web/useMessage';
import { createConnection } from '@/utils/mqtt';
const { createMessage } = useMessage();
createConnection()
.on('connect', (res) => {
console.log('连接成功', res);
createMessage.success('链接成功');
})
.on('message', (topic, message) => {
console.log(topic, JSON.parse(message));
//
})
.on('reconnect', (topic, message) => {
createMessage.warning('重连');
})
.on('error', () => {
console.log('77877');
//
client.reconnect();
});
const selectVal = reactive({
camera: null,
resolution: null,
});
const optionsArr = reactive({
cameraOptions: [
{
label: '项目1',
value: 1,
},
],
resolutionOptions: [],
});
</script>
<style lang="less" scoped>
.live-preview {
width: 400px;
height: 248px;
padding: 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;
opacity: 0.9;
backdrop-filter: blur(3px);
color: #fff;
margin-top: 10px;
.preview-title {
display: flex;
align-items: center;
justify-content: space-between;
.title-select {
font-size: 12px;
display: flex;
align-items: center;
.title-select-item {
border: 1px solid #3a57e8;
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: 2px;
padding-left: 4px;
height: 38px;
border-radius: 4px;
display: flex;
align-items: center;
cursor: pointer;
font-size: 12px;
::v-deep .ant-select-selector {
background: none;
border: none;
color: #f4ba19;
font-size: 12px;
padding: 0 0 0 2px;
.ant-select-selection-placeholder {
color: #fff;
}
}
::v-deep .ant-select-selection-item {
padding: 0;
}
::v-deep .ant-select-arrow {
color: #fff;
}
&:last-child {
margin-left: 4px;
}
}
}
.title-icon {
padding: 4px 6px;
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: 2px;
border: 1px solid #3a57e8;
}
}
.live-type {
width: 40px;
height: 40px;
background: #0a99eb;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
left: 0;
top: 100px;
}
}
</style>

@ -46,8 +46,8 @@
<script setup lang="ts">
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
import { reactive, onMounted, ref } from 'vue';
import { createConnection } from '@/utils/mqtt';
import { buildGUID } from '@/utils/uuid';
import { getClient, createConnection } from '@/utils/mqtt';
const srcUrl = ref('rtmp://221.2.83.254:1935/live/2');
const selectVal = reactive({
@ -90,6 +90,44 @@
});
const resolutionChange = (val: any) => {
console.log(val);
const requestData = {
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: val, // 0=1=2=3=4=
},
};
console.log(requestData);
const publish = {
topic: 'thing/product/8UUXN5400A079H/services',
qos: 0,
payload: JSON.stringify(requestData),
};
const { topic, qos, payload } = publish;
getClient().publish(topic, payload, { qos }, (error, res) => {
if (error) {
console.log('Publish error', error);
}
console.log('Publish success', res);
//
const timer = window.setInterval(() => {
if (getClient() != null) {
// Received
getClient().on('message', (topic, message, packet) => {
const rs = JSON.parse(message);
console.log(rs);
});
} else {
console.log('开启定时器接收数据2');
}
}, 5000);
});
};
const cameraChange = (val: any) => {
console.log(val);
@ -109,7 +147,7 @@
payload: JSON.stringify(requestData),
};
const { topic, qos, payload } = publish;
createConnection().publish(topic, payload, { qos }, (error, res) => {
getClient().publish(topic, payload, { qos }, (error, res) => {
if (error) {
console.log('Publish error', error);
}
@ -169,7 +207,9 @@
console.log(player);
data.playedTime = player.currentTime();
};
onMounted(() => {});
onMounted(() => {
resolutionChange(1);
});
</script>
<style lang="less" scoped>
.live-preview {

@ -8,6 +8,7 @@
style="width: 120px"
:options="optionsArr.projectOptions"
placeholder="项目选择"
@change="handleChange"
/>
</div>
<div class="select-item">
@ -18,6 +19,7 @@
style="width: 120px"
:options="optionsArr.equipmentOptions"
placeholder="设备选择"
@change="handleChange"
/>
</div>
<div class="select-item">
@ -28,6 +30,7 @@
style="width: 120px"
:options="optionsArr.airportOptions"
placeholder="机场选择"
@change="handleChange"
/>
</div>
</div>
@ -36,6 +39,7 @@
import { reactive, ref } from 'vue';
import { CopyOutlined, DownOutlined } from '@ant-design/icons-vue';
const emits = defineEmits(['selectChange']);
const selectVal = reactive({
project: null,
equipment: null,
@ -48,9 +52,23 @@
value: 1,
},
],
equipmentOptions: [],
airportOptions: [],
equipmentOptions: [
{
label: '无人机',
value: '1581F8HGX254V00A0BUY',
},
],
airportOptions: [
{
label: '机场',
value: '8UUXN5400A079H',
},
],
});
const handleChange = () => {
console.log(selectVal);
emits('selectChange', selectVal);
};
</script>
<style lang="less" scoped>
.flightoperation-top {

@ -95,10 +95,13 @@
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import { CopyOutlined, EditOutlined } from '@ant-design/icons-vue';
import { reactive, onMounted } from 'vue';
import { createConnection } from '@/utils/mqtt';
import { timestampToFormattedDate } from '@/utils/index';
const props = defineProps({
uavAllVal: Object,
});
const data = reactive({
navigationLight: '关闭',
altitude: '70m',
@ -106,20 +109,19 @@
limitedRange: '500m',
obstacleAvoidance: '500m',
});
onMounted(() => {
createConnection().subscribe('thing/product/8UUXN5400A079H/osd', (error, res) => {
if (error) {
console.log('Subscribe to topics error', error);
return;
}
console.log('Subscribe to topics res', res);
});
});
const time = ref(timestampToFormattedDate(new Date().getTime()));
watch(
() => props.uavAllVal,
(val) => {
console.log(val);
time.value = timestampToFormattedDate(val.timestamp);
},
);
</script>
<style lang="less" scoped>
.airport-information {
position: absolute;
top: 350px;
top: 360px;
left: 0;
z-index: 999;
width: 260px;

Loading…
Cancel
Save