飞行作业

main
刘妍 3 months ago
parent b113366dbe
commit 3d470eac91

@ -0,0 +1,5 @@
export { default as SelectComponent } from './src/SelectComponent.vue';
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';

@ -1,5 +1,81 @@
<template>
<div>飞行作业</div>
<div class="flightoperation-container">
<SelectComponent />
<AirportInformation @changeLive="changeAirportLive" />
<UAVInformation />
<div class="AirportLive" v-if="airportLiveVisible">
<AirportLive />
</div>
<div
class="LivePreview"
v-if="livePreviewVisible"
:style="{ bottom: airportLiveVisible ? '300px' : '10px' }"
>
<LivePreview />
</div>
</div>
</template>
<script setup lang="ts"></script>
<style lang="less" scoped></style>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import {
SelectComponent,
AirportInformation,
UAVInformation,
AirportLive,
LivePreview,
} from './index';
const airportLiveVisible = ref(false);
const livePreviewVisible = ref(true);
const changeAirportLive = () => {
airportLiveVisible.value = !airportLiveVisible.value;
};
</script>
<style lang="less" scoped>
.flightoperation-top {
display: flex;
}
.select-item {
width: 160px;
height: 38px;
margin-left: 10px;
background: #3a57e8;
border-radius: 4px;
display: flex;
align-items: center;
cursor: pointer;
::v-deep .ant-select-selector {
background: #3a57e8;
border: none;
color: #fff;
.ant-select-selection-placeholder {
color: #fff;
}
}
::v-deep .ant-select-arrow {
color: #fff;
}
}
.select-item:nth-child(2) {
background: #08b1ba;
::v-deep .ant-select-selector {
background: #08b1ba;
}
}
.select-item:nth-child(3) {
background: #1aa053;
::v-deep .ant-select-selector {
background: #1aa053;
}
}
.AirportLive {
position: absolute;
right: 10px;
bottom: 10px;
}
.LivePreview {
position: absolute;
right: 10px;
bottom: 10px;
}
</style>

@ -0,0 +1,111 @@
<template>
<div class="airport-information">
<div class="title">机场信息<span>设备空闲中</span></div>
<div class="content">
<div class="content-title">
2025-06-27 00:00:00
<span>机场摄像头未开</span>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
</div>
<div class="content-button">
<a-button type="primary" style="background: #3a57e8" @click="airportLive"
>机场直播</a-button
>
<a-button type="primary" style="background: #0a99eb">远程调试</a-button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { CopyOutlined } from '@ant-design/icons-vue';
const emits = defineEmits(['changeLive']);
const airportLive = () => {
emits('changeLive');
};
</script>
<style lang="less" scoped>
.airport-information {
width: 260px;
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;
opacity: 0.9;
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;
opacity: 0.5;
span {
color: #f2762d;
}
}
.content-title {
font-size: 14px;
padding: 10px 0;
span {
font-size: 12px;
}
}
.content-item {
display: flex;
align-items: center;
border-bottom: 1px solid #4e5778;
padding: 10px 0;
.item-div {
width: 49%;
}
}
.content-button {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
</style>

@ -0,0 +1,57 @@
<template>
<div class="airport-live">
<div class="airport-title">
<div class="title">机场直播</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>
</template>
<script setup lang="ts">
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
</script>
<style lang="less" scoped>
.airport-live {
width: 400px;
height: 248px;
padding: 10px 20px;
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;
.airport-title {
display: flex;
align-items: center;
justify-content: space-between;
.title {
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: 4px 6px;
font-size: 12px;
}
.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;
}
}
}
</style>

@ -0,0 +1,134 @@
<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';
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>

@ -0,0 +1,93 @@
<template>
<div class="flightoperation-top">
<div class="select-item">
<CopyOutlined style="color: #fff; font-size: 20px; margin-left: 10px" />
<a-select
ref="select"
v-model:value="selectVal.project"
style="width: 120px"
:options="optionsArr.projectOptions"
placeholder="项目选择"
/>
</div>
<div class="select-item">
<CopyOutlined style="color: #fff; font-size: 20px; margin-left: 10px" />
<a-select
ref="select"
v-model:value="selectVal.equipment"
style="width: 120px"
:options="optionsArr.equipmentOptions"
placeholder="设备选择"
/>
</div>
<div class="select-item">
<CopyOutlined style="color: #fff; font-size: 20px; margin-left: 10px" />
<a-select
ref="select"
v-model:value="selectVal.airport"
style="width: 120px"
:options="optionsArr.airportOptions"
placeholder="机场选择"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { CopyOutlined, DownOutlined } from '@ant-design/icons-vue';
const selectVal = reactive({
project: null,
equipment: null,
airport: null,
});
const optionsArr = reactive({
projectOptions: [
{
label: '项目1',
value: 1,
},
],
equipmentOptions: [],
airportOptions: [],
});
</script>
<style lang="less" scoped>
.flightoperation-top {
display: flex;
margin-top: 10px;
}
.select-item {
width: 160px;
height: 38px;
margin-left: 10px;
background: #3a57e8;
border-radius: 4px;
display: flex;
align-items: center;
cursor: pointer;
::v-deep .ant-select-selector {
background: #3a57e8;
border: none;
color: #fff;
.ant-select-selection-placeholder {
color: #fff;
}
}
::v-deep .ant-select-arrow {
color: #fff;
}
}
.select-item:nth-child(2) {
background: #08b1ba;
::v-deep .ant-select-selector {
background: #08b1ba;
}
}
.select-item:nth-child(3) {
background: #1aa053;
::v-deep .ant-select-selector {
background: #1aa053;
}
}
</style>

@ -0,0 +1,173 @@
<template>
<div class="airport-information">
<div class="title">无人机信息<span>未连接</span></div>
<div class="content">
<div class="content-title">
2025-06-27 00:00:00
<span>临近或已接近夜晚</span>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
</div>
</div>
<div class="content-item">
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
2.6m/s
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div">
<CopyOutlined style="color: #fff; font-size: 14px" />
35.3
</div>
</div>
<div class="content-edit">
飞行器夜航灯
<div>
<a-input v-model:value="data.navigationLight" />
<EditOutlined style="color: #0a99eb; cursor: pointer" />
</div>
</div>
<div class="content-edit">
备降转移高度
<div>
<a-input v-model:value="data.altitude" readonly />
</div>
</div>
<div class="content-edit">
限高
<div>
<a-input v-model:value="data.heightPermitted" />
<EditOutlined style="color: #0a99eb; cursor: pointer" />
</div>
</div>
<div class="content-edit">
限远
<div>
<a-input v-model:value="data.limitedRange" />
<EditOutlined style="color: #0a99eb; cursor: pointer" />
</div>
</div>
<div class="content-edit">
避障
<div>
<a-input v-model:value="data.obstacleAvoidance" />
<EditOutlined style="color: #0a99eb; cursor: pointer" />
</div>
</div>
<div class="content-button">
<a-button type="primary" style="background: #3a57e8">飞行控制</a-button>
<a-button type="primary" style="background: #0a99eb">负载控制</a-button>
</div>
<div class="content-button">
<a-button type="primary" style="background: #3a57e8; width: 100%">负载直播</a-button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { CopyOutlined, EditOutlined } from '@ant-design/icons-vue';
import { reactive } from 'vue';
const data = reactive({
navigationLight: '关闭',
altitude: '70m',
heightPermitted: '100m',
limitedRange: '500m',
obstacleAvoidance: '500m',
});
</script>
<style lang="less" scoped>
.airport-information {
width: 260px;
padding: 10px;
background: #0d0e15;
margin: 10px 0 0 10px;
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;
.title {
width: 100%;
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;
}
}
.content-title {
font-size: 14px;
padding: 10px 0;
span {
font-size: 12px;
}
}
.content-item {
display: flex;
align-items: center;
border-bottom: 1px solid #4e5778;
padding: 10px 0;
.item-div {
width: 49%;
}
}
.content-button {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.content-edit {
display: flex;
align-items: center;
justify-content: space-between;
border: 1px solid #4e5778;
margin-top: 10px;
padding: 2px 10px;
border-radius: 4px;
font-size: 12px;
input {
background: none;
border: none;
width: 100px;
text-align: right;
color: #fff;
font-size: 12px;
}
}
}
</style>
Loading…
Cancel
Save