Compare commits

...

5 Commits

Author SHA1 Message Date
徐景良 5b79174956 长光卫星地图,航线管理迁移,样式修改 2025-07-10 09:19:27 +08:00
徐景良 fdb579d42b Merge branch 'main' of http://123.132.248.154:10000/gitY/DiKongGanZhiPingTai 2025-07-10 08:56:16 +08:00
徐景良 ccf04514c7 merge 2025-07-10 08:55:10 +08:00
徐景良 d5a233b1b9 merge 2025-07-09 17:12:03 +08:00
徐景良 0ab7e0941d merge 2025-07-01 14:17:05 +08:00
8 changed files with 1109 additions and 852 deletions

View File

@ -0,0 +1,201 @@
<template>
<div>
<div style="width:100%;height: calc( 100vh - 80px);" >
<Map :workPlanFormShow="workPlanFormShow" :airRoute="airRoute" @exitDraw="exitDraw" @flyToThere="flyToThere" :wayline="wayline" :waylineInfo="waylineInfo"></Map>
</div>
<!-- 航线库 -->
<div v-if="ariLineShow" style="width:566px;position:absolute;top:30px;left:30px;z-index:1;height: calc( 100vh - 164px);overflow-y:hidden;">
<airLineList :title="'航线管理'" @checkAriLine="checkAriLine" @previewAirLine="previewAirLine" @createAirLine="handlerCreateAirLine"></airLineList>
</div>
<!-- 新建航线 -->
<div v-if="createAirLineShow" style="width:566px;background:#0d0e15c1 ;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1;height: calc( 100vh - 164px);overflow-y:hidden;">
<createAirLine @createAirLine="handlerCreateAirRoute" @cancle="cancleCreateAirLine"></createAirLine>
</div>
</div>
</template>
<script lang="ts" setup>
import {ref,watch} from 'vue';
import airLineList from '../workplan/components/airLineList.vue';
import createAirLine from '../workplan/components/createAirLine.vue'
import Map from '../workplan/components/map.vue'
import AirPolygon from './components/airPolygon.vue';
import {getAirLine} from '@/api/sys/workplan';
import JSZip from 'jszip';
import axios from 'axios';
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
const airRoute = ref({})
const flyToTherePosition = ref({
lng:null,
lat:null,
alt:null,
})
const flyToThere = (e)=>{
console.log(e);
}
const planListShow = ref(true);
const workPlanFormShow = ref(false);
const ariLineShow = ref(true);
const aircraftShow = ref(false);
const createAirLineShow = ref(false);
const selectAriLine = ()=> {
ariLineShow.value = true;
aircraftShow.value = false;
}
const selectAircraft = ()=>{
aircraftShow.value = true;
ariLineShow.value = false;
}
const cancleCraete = ()=>{
workPlanFormShow.value = false;
ariLineShow.value = false;
aircraftShow.value = false;
planListShow.value = true;
}
const checkedAriLine = ref({});
const checkAriLine = (item)=>{
if(item){
ariLineShow.value = false;
checkedAriLine.value = item;
}
}
const checkedDronePort = ref({});
const checkDronePort = (item)=>{
if(item){
aircraftShow.value = false;
checkedDronePort.value = item;
}
}
const formData = ref(null);
const toCreateWorkPlan = (data)=> {
formData.value = data;
planListShow.value = false;
workPlanFormShow.value = true;
}
// 线
const handlerCreateAirLine = ()=>{
createAirLineShow.value = true;
}
const cancleCreateAirLine = ()=>{
createAirLineShow.value = false;
}
const handlerCreateAirRoute = (info)=>{
console.log("info",info);
workPlanFormShow.value = false;
ariLineShow.value = false;
aircraftShow.value = false;
planListShow.value = false;
createAirLineShow.value = false;
airRoute.value = info
}
const successCreatePlan = ()=>{
workPlanFormShow.value = false;
ariLineShow.value = false;
aircraftShow.value = false;
planListShow.value = true;
}
// 线退
const exitDraw = ()=>{
planListShow.value = false;
workPlanFormShow.value = true;
ariLineShow.value = true;
}
// 线
const wayline = ref({});
const waylineInfo = ref(null)
const previewAirLine =async (line,type) => {
let info =await getAirLine({airLineId:type.value?.id});
if(info){
wayline.value = line;
waylineInfo.value = info;
}
}
// 线
const planDetail =async (item) => {
formData.value = item;
console.log("formData",formData.value?.airLineId);
let info =await getAirLine({airLineId : formData.value?.airLineId});
if(info){
// wayline.value = line;
waylineInfo.value = info;
wayline.value = await airLineDetail(info);
}
workPlanFormShow.value = true;
}
// wpml
const currentPreviewWayLine = ref(null);
const airLineDetail =async (item) => {
currentPreviewWayLine.value = item;
try{
let response = await axios.get(item.wpml,{responseType: 'arraybuffer'});
// kmz
let xmlStr =await extractKmz(response.data);
let xmlData = xmlStr.replace(/wpml:/g,"");
const parser = new XMLParser();
const jsonObj = parser.parse(xmlData);
return jsonObj.kml.Document;
}catch(e){
console.error(e);
}
}
// 线
const extractKmz = async (kmzBlob)=>{
const zip = new JSZip();
const contents = await zip.loadAsync(kmzBlob);
// .wmpl
for (const [filename, file] of Object.entries(contents.files)) {
if (filename.toLowerCase().endsWith('.wpml')) {
return await file.async('text');
}
}
throw new Error('KMZ文件中未找到WMPL文件');
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<div class="container">
<div class="title">
<LeftOutlined @click="checkAriLine(null)" /> &nbsp; 选择航线
<LeftOutlined @click="checkAriLine(null)" v-show="props.title=='线'" /> &nbsp; {{props.title}}
</div>
<div class="filter-container">
@ -77,48 +77,48 @@
<PlusOutlined @click="createAirLine" />
</div>
</div>
<div class="ari-line" v-for="(item,index) in ariLineList" :key="index"
>
<div class="title">
<div style="flex:1;">
{{item.airLineName}}
<div class="slide-container">
<div class="ari-line" v-for="(item,index) in ariLineList" :key="index" >
<div class="title">
<div style="flex:1;">
{{item.airLineName}}
</div>
<div style="">
<!-- <EditOutlined @click="editLine" /> -->
&nbsp;
<a-dropdown>
<MoreOutlined />
<template #overlay>
<a-menu>
<a-menu-item @click="checkAriLine(item)" >
<a href="javascript:;">选择</a>
</a-menu-item>
<a-menu-item @click="airLineDetail(item)" >
<a href="javascript:;">预览</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;">编辑</a>
</a-menu-item>
<a-menu-item @click="deletePlan(item.id)">
<a href="javascript:;">删除</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</div>
<div style="">
<!-- <EditOutlined @click="editLine" /> -->
&nbsp;
<a-dropdown>
<MoreOutlined />
<template #overlay>
<a-menu>
<a-menu-item @click="checkAriLine(item)" >
<a href="javascript:;">选择</a>
</a-menu-item>
<a-menu-item @click="airLineDetail(item)" >
<a href="javascript:;">预览</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;">编辑</a>
</a-menu-item>
<a-menu-item @click="deletePlan(item.id)">
<a href="javascript:;">删除</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<div class="type" >
<img src="/public/iocn/uav.png" alt="">
{{item.uavId}}Matrice 4TD
</div>
</div>
<div class="type" >
<img src="/public/iocn/uav.png" alt="">
{{item.uavId}}
</div>
<div class="time">
<div>
更新时间{{item.createTime}}
<div class="time">
<div>
更新时间{{item.createTime}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@ -184,12 +184,14 @@
</template>
<script lang="ts" setup>
import { ExclamationCircleOutlined,PlusOutlined,FileAddOutlined,LeftOutlined,ImportOutlined,MoreOutlined,EditOutlined,InboxOutlined } from '@ant-design/icons-vue';
import {ref,defineEmits,createVNode} from 'vue'
import {ref,defineEmits,defineProps,createVNode} from 'vue'
import { getAirLineList,uploadXmlFile,deleteAirLine,addAirLine} from '@/api/sys/workplan';
import { Modal, message } from 'ant-design-vue';
const emit = defineEmits(["checkAriLine","createAirLine","previewAirLine"])
const props = defineProps(["title"])
import {templateTypeOptions} from '../waylineConfig/index';
import JSZip from 'jszip';
@ -292,7 +294,7 @@
const parser = new XMLParser();
const jsonObj = parser.parse(xmlData);
emit("previewAirLine",jsonObj.kml.Document,currentPreviewWayLine)
}catch(e){
console.error(e);
}
@ -396,6 +398,10 @@
.container{
width:100%;
height:100%;
background: #0D0E15;
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15), 0px 10px 30px 1px rgba(0,0,6,0.15), inset 0px 0px 20px 8px rgba(58,87,232,0.73);
border-radius: 6px;
opacity: 0.8;
}
.title{
padding:15px;
@ -429,7 +435,6 @@
}
.routers-container{
display:flex;
gap:10px;
font-size:14px;
border-top:1px solid rgba(204, 204, 204, 0.219) ;
height: 100%;
@ -438,38 +443,77 @@
.file-container{
width:220px;
border-right: 1px solid rgba(204, 204, 204, 0.227) ;
padding:15px
padding:0px;
display:flex;
flex-direction: column;
gap:20px;
}
.file-container .tip{
display: flex;
color:#fff;
padding:8px 0px;
padding:15px 10px;
background: linear-gradient( 270deg, rgba(89,98,128,0) 0%, #2D3349 100%);
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15);
position:relative;
}
.file-container .tip::before{
content:"";
height: 0px;
width:0px;
border-top:6px solid #2C45B8;
border-left:6px solid #2C45B8;
border-right: 6px solid rgba(0,0,0,0);
border-bottom: 6px solid rgba(0,0,0,0);
position:absolute;
top:0px;
left:0px;
}
.file-container .tip .info{
flex:1;
}
.routers-list{
flex:1;
padding:15px;
}
.routers-list .tip{
display: flex;
color:#fff;
padding:8px 0px;
padding:15px 10px;
background: linear-gradient( 270deg, rgba(89,98,128,0) 0%, #2D3349 100%);
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15);
position:relative;
}
.routers-list .tip .info{
flex:1;
}
.routers-list .tip::before{
content:"";
height: 0px;
width:0px;
border-top:6px solid #2C45B8;
border-left:6px solid #2C45B8;
border-right: 6px solid rgba(0,0,0,0);
border-bottom: 6px solid rgba(0,0,0,0);
position:absolute;
top:0px;
left:0px;
}
.routers-list .slide-container{
padding:20px;
}
.ari-line{
background:#3F4150;
color:#fff;
padding:5px 10px;
margin-bottom:10px;
position:relative;
font-size: 13px;
border-radius: 3px;
background: linear-gradient( 132deg, #323D62 0%, #525F83 100%);
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15);
border-radius: 10px;
}
.ari-line::before{

View File

@ -71,7 +71,6 @@
<a-slider v-model:value="props.currentAirPoint.cameraHorizontalAngle" :min="-180" :max="180" :step="0.01" />
</div>
</div>
<div class="config-item">
<div class="item-title">
<div class="label">
@ -80,7 +79,6 @@
<div class="">
{{ props.currentAirPoint.cameraVerticalAngle }} °
</div>
</div>
<div class="item-content">
<a-slider v-model:value="props.currentAirPoint.cameraVerticalAngle" :min="-180" :max="180" :step="0.01" />

View File

@ -2,9 +2,11 @@
<div class="container">
<div class="title">
<div style="flex:1;">
<LeftOutlined @click="checkAriLine(null);"/> &nbsp; 新建航线
创建新航线
</div>
<div>
<LeftOutlined @click="checkAriLine(null);"/> &nbsp;
</div>
</div>
<div class="item-label">航线类型</div>
@ -200,14 +202,26 @@
color:#fff;
}
.title{
padding:15px;
padding:15px 0px;
color:#fff;
font-size:14px;
display:flex;
}
.item-label{
padding:10px 0px;
color:#999;
padding:15px 0px;
color:#fff;
position:relative;
}
.item-label::before{
content:"";
height:14px;
width:3px;
position:absolute;
top:15px;
left:-8px;
background: linear-gradient( 180deg, #234AFF 0%, #4981FF 100%);
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15);
border-radius: 2px;
}
.draw-type{
display:grid;

View File

@ -354,6 +354,10 @@ const resetForm = () => {
.container{
width:100%;
height:100%;
background: #0D0E15;
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15), 0px 10px 30px 1px rgba(0,0,6,0.15), inset 0px 0px 20px 8px rgba(58,87,232,0.73);
border-radius: 6px;
opacity: 0.8;
padding:10px 20px;
}
.title{
@ -388,14 +392,15 @@ const resetForm = () => {
width:100%;
display: flex;
color:#fff;
border:1px solid rgba(204, 204, 204, 0.787);
border:1px solid #3B4154;
padding:0px;
border-radius: 15px;
}
.select-item .item-name{
flex:1;
border-right:1px solid rgba(204, 204, 204, 0.787);
border-right:1px solid #3B4154;
padding:4px;
}
.select-item .item-operate{
@ -410,13 +415,16 @@ const resetForm = () => {
display: flex;
overflow: hidden;
border:0.5px solid #3B4154 ;
background:#050608;
font-size:13px;
border-radius: 15px;
}
.radio-box .radio-item{
flex:1;
color:#8A92A6 ;
text-align: center;
background:#222738 ;
padding:5px;
cursor:pointer;
@ -428,6 +436,7 @@ const resetForm = () => {
text-align: center;
background:#3A57E8 ;
padding:5px;
border-radius: 15px;
cursor:pointer;
}
@ -444,6 +453,7 @@ const resetForm = () => {
padding:3px;
text-align: center;
cursor:pointer;
border-radius: 15px;
}
::v-deep .ant-form-item-label > label{
@ -539,4 +549,8 @@ const resetForm = () => {
::v-deep .ant-input::placeholder{
color:rgba(255, 255, 255, 0.533)!important;
}
::v-deep .ant-btn{
border-radius: 15px!important;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
<div style="flex:1;">
工作计划
</div>
<div>
<div class="create-button">
<PlusOutlined @click="createWorkPlan(null)" />
</div>
</div>
@ -12,7 +12,7 @@
<div>
<a-select
ref="select"
style="width: 140px"
style="width: 100px"
placeholder="计划状态"
>
<a-select-option value="jack">全部</a-select-option>
@ -60,11 +60,8 @@
</a-dropdown>
</div>
</div>
<div class="type" >
{{item.description}}
</div>
<div class="time">更新时间{{item.createTime}}</div>
<div class="username"><UserOutlined />&nbsp;{{item.createId}}</div>
<div class="time">更新时间{{item.createTime}}</div>
</div>
</div>
</div>
@ -217,13 +214,23 @@
.container{
width:100%;
height:100%;
background: #0D0E15;
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15), 0px 10px 30px 1px rgba(0,0,6,0.15), inset 0px 0px 20px 8px rgba(58,87,232,0.73);
border-radius: 6px;
opacity: 0.8;
padding:0px 10px;
}
.title{
padding:30px 15px;
color:#fff;
color:#ffffff;
font-size:16px;
display:flex;
}
.create-button{
border:1px solid #fff;
padding:4px 6px;
font-size:12px;
}
.filter-container{
padding:0px 15px;
display:flex;
@ -285,13 +292,15 @@
flex:1;
}
.ari-line{
background:#3F4150;
color:#fff;
padding:5px 10px;
margin-bottom:10px;
position:relative;
font-size: 13px;
border-radius: 3px;
background: linear-gradient( 315deg, #515F84 0%, #313C62 100%);
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15);
border-radius: 10px;
}
.ari-line .title{
@ -316,8 +325,8 @@
}
.ari-line .state-no{
border:1px solid rgb(246, 18, 18);
color:rgb(246, 18, 18);;
border:1px solid #F6B50A;
color:#F6B50A;
font-size:12px;
height:24px;
line-height:20px;
@ -343,8 +352,8 @@
}
.ari-line .username{
margin-top:10px;
color:#ccc;
margin:12px 0px;
}
.pagenation{
@ -354,8 +363,10 @@
::v-deep .ant-select-selector{
border:none!important;
color:#fff!important;
background:#3F4150!important ;
background: linear-gradient( 101deg, #3F4B71 0%, #1F2840 100%)!important ;
border-radius: 3px!important;
border-top-left-radius: 15px!important;
border-bottom-left-radius: 15px!important;
}
@ -426,13 +437,19 @@
}
::v-deep .ant-input{
background:#3c3c3c!important ;
background: #364167!important ;
border:none!important;
border-top-left-radius: 3px !important;
border-bottom-left-radius: 3px !important;
border-top-right-radius: 0px !important;
border-bottom-right-radius: 0px !important;
color:#fff!important;
}
::v-deep .ant-input-search-button{
border-top-right-radius: 15px!important;
border-bottom-right-radius: 15px!important;
}
::v-deep .ant-input::placeholder{
color:rgba(255, 255, 255, 0.533)!important;
}

View File

@ -5,18 +5,18 @@
</div>
<!-- 工作计划列表 -->
<div v-show="planListShow" style="width:360px;background:#0d0e15c1 ;position:absolute;top:0px;left:0px;z-index:1;height: calc( 100vh - 104px);overflow-y:hidden;">
<div v-show="planListShow" style="width:360px;position:absolute;top:20px;left:20px;z-index:1;height: calc( 100vh - 144px);overflow-y:hidden;">
<planList :planListShow="planListShow" @planDetail="planDetail" @createWorkPlan="toCreateWorkPlan" ></planList>
</div>
<!-- 创建计划弹窗 -->
<div v-if="workPlanFormShow" style="width:380px;background:#0d0e15ce ;position:absolute;top:30px;left:30px;z-index:1;height: calc( 100vh - 164px);overflow-y:hidden;">
<div v-if="workPlanFormShow" style="width:380px;position:absolute;top:30px;left:30px;z-index:1;height: calc( 100vh - 164px);overflow-y:hidden;">
<createWorkPlan :formData="formData" @successCreatePlan="successCreatePlan" @cancleCraete="cancleCraete" @selectAircraft="selectAircraft" @selectAriLine="selectAriLine" :checkedAriLine="checkedAriLine" :checkedDronePort="checkedDronePort"></createWorkPlan>
</div>
<!-- 航线库 -->
<div v-if="ariLineShow" style="width:566px;background:#0d0e15c1 ;position:absolute;top:30px;left:440px;z-index:1;height: calc( 100vh - 164px);overflow-y:hidden;">
<airLineList @checkAriLine="checkAriLine" @previewAirLine="previewAirLine" @createAirLine="handlerCreateAirLine"></airLineList>
<div v-if="ariLineShow" style="width:566px;position:absolute;top:30px;left:440px;z-index:1;height: calc( 100vh - 164px);overflow-y:hidden;">
<airLineList :title="'选择航线'" @checkAriLine="checkAriLine" @previewAirLine="previewAirLine" @createAirLine="handlerCreateAirLine"></airLineList>
</div>
<!-- 飞行器 -->