2025-11-14 17:50:10 +08:00

565 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
航线规划-航线列表
crate by churl
2023-3-6
-->
<template>
<div class="el-container flexD dark">
<div class="el-header">
<div style="display: flex;align-items: center;">
<!-- <el-popconfirm title="返回后内容不会保存;确定返回吗?" @confirm="toList()">
<template #reference>
<el-icon size="24px" class="addBtn">
<ArrowLeftBold />
</el-icon>
</template>
</el-popconfirm> -->
<h2 class="title" style="display: inline-block;margin-left: 8px;">创建空域</h2>
</div>
</div>
<div class="el-main">
<el-form :model="form" :rules="rules" ref="formRef" label-position="top">
<el-form-item label="空域名称" prop="name">
<el-input v-model.trim="form.name" placeholder="请输入空域名称(建议:分局名称+时间+编号)"></el-input>
</el-form-item>
<el-form-item label="所属战区" prop="militaryAreaName">
<el-select v-model="form.militaryAreaName" placeholder="请选择所属战区" style="width: 100%;">
<el-option v-for="item in slectmilitaryAreaList" :key="item.value" :label="item.name"
:value="item.value">{{ item.name }}</el-option>
</el-select>
</el-form-item>
<el-form-item label="空域性制" prop="airspaceProp">
<el-select v-model="form.airspaceProp" placeholder="请选择空域性制" style="width: 100%;">
<el-option v-for="item in slectAirspacePropList" :key="item.value" :label="item.name"
:value="item.value">{{ item.name }}</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="飞行规则" prop="flightRule">
<el-select v-model="form.flightRule" placeholder="请选择飞行规则" style="width: 100%;">
<el-option v-for="item in slectFlightRuleList" :key="item.value" :label="item.name"
:value="item.value">{{ item.name }}</el-option>
</el-select>
</el-form-item> -->
<!--
<div class="marginBottom18">
<div class="labelBtnDom">
<span class="label">申请空域起点设置 (AGL)</span>
<el-button v-if="mapWork.qfdPosition.value?.lng" size="small" type="danger"
@click="mapWork.deleteQFD">删除起点</el-button>
<el-button v-else size="small" type="success"
@click="() => { pointList_show_handel(false), mapWork.setQFD() }">设置起点</el-button>
</div>
<div class="lnglataltDom" v-if="mapWork.qfdPosition.value?.lng">
<div style="margin-bottom: 8px;">
<CLngLat :lngValue="mapWork.qfdPosition.value.lng"
:latValue="mapWork.qfdPosition.value.lat"
:rules="[{ required: true, message: '请输入经度和纬度', trigger: 'change' }]"
@change="setPosition" />
</div>
</div>
</div>
<div class="marginBottom18" v-if="form.airspaceType==2">
<div class="labelBtnDom">
<span class="label">边界点</span>
<div v-if="mapWork.qfdPosition.value">
<el-button size="small" v-if="pointList_show" type="info"
@click="pointList_show_handel(false)">关闭</el-button>
<el-button size="small" v-else type="warning"
@click="pointList_show_handel(true)">设置</el-button>
</div>
<div v-else>请先设置申请空域起点</div>
</div>
</div> -->
<div>
<el-form-item label="空域类型" prop="airspaceType">
<el-select v-model="form.airspaceType" placeholder="请选择空域类型" style="width: 40%;" >
<el-option v-for="item in slectAirspaceTypeList" :key="item.value" :label="item.name"
:value="item.value">{{ item.name }}</el-option>
</el-select>
<div style="margin-left: 10px;"></div>
<el-tooltip
class="box-item"
effect="dark"
content="圆"
placement="top-start"
>
<el-button class="vertical-button" v-if="form.airspaceType==1" type="primary" @click="mapWork.drawEllipse(false)">
绘制空域
<svg-icon icon-class="circle"/>
</el-button>
</el-tooltip>
<el-tooltip
class="box-item"
effect="dark"
content="多边形"
placement="top-start"
>
<el-button class="vertical-button" v-if="form.airspaceType==2" type="primary" @click="mapWork.drawPolygon(false)">
绘制空域
<svg-icon icon-class="polygon"/>
</el-button>
</el-tooltip>
<el-button type="primary" v-if="form.airspaceType==1 || form.airspaceType==2 " @click="clear">清除空域</el-button>
<!-- <el-tooltip
class="box-item"
effect="dark"
content="取消绘制"
placement="top-start"
>
<el-button class="vertical-button" type="primary" @click="mapWork.endDraw()">
<el-icon>
<Close />
</el-icon>
</el-button>
</el-tooltip> -->
</el-form-item>
</div>
<!-- <el-form-item label="半径长度" prop="radLength" v-if="form.airspaceType==1">
<el-input v-model.trim="form.radLength" placeholder="请输入半径长度 单位(米)" maxlength="15"></el-input>
</el-form-item> -->
<!-- <el-form-item label="最小高度" prop="hightMin">
<el-input v-model.trim="form.hightMin" maxlength="15"></el-input>
</el-form-item> -->
<el-form-item label="最大高度" prop="hightMax">
<el-input v-model.trim="form.hightMax" maxlength="15"></el-input>
</el-form-item>
<el-form-item label="开始时间" prop="planBeg">
<el-date-picker
v-model="form.planBeg"
type="datetime"
placeholder="选择日期时间"
value-format="YYYY-MM-DD hh:mm:ss"
>
</el-date-picker>
<!-- <el-input v-model.trim="form.hightMin" maxlength="15"></el-input> -->
<!-- <el-date-picker v-model="form.planBeg" value-format="YYYY-MM-DD HH:mm:SS" type="date" style="width: 100%" size="default"
@change="getLineList" /> -->
</el-form-item>
<el-form-item label="截止时间" prop="planEnd">
<!-- <el-input v-model.trim="form.hightMin" maxlength="15"></el-input> -->
<el-date-picker v-model="form.planEnd" type="datetime"
placeholder="选择日期时间"
value-format="YYYY-MM-DD hh:mm:ss"
/>
</el-form-item>
</el-form>
</div>
<div class="el-footer">
<!-- <el-popconfirm title="提交后会覆盖之前内容;确定提交吗?" @confirm=" editForm()" v-if="props.hxid">
<template #reference>
<div>
<el-tooltip :content="form.isOriginal === 0 ? '该副本不支持修改后保存' : ''" placement="top">
<el-button :type="form.isOriginal === 0 ? 'info' : 'primary'" :disabled="form.isOriginal === 0">
提交
</el-button>
</el-tooltip>
</div>
</template>
</el-popconfirm> -->
<el-button type="primary" @click="submitForms">返回</el-button>
<el-button type="primary" v-if="props.hxid" @click="editForm">提交</el-button>
<el-button type="primary" v-else @click="submitForm">提交</el-button>
</div>
</div>
<!-- 途径点列表 -->
<!-- <pointList ref="pointListRef" :storageTypeList="storageTypeList" :storageType="form.storageType" v-if="pointList_show"
@close="pointList_show_handel" /> -->
</template>
<script setup>
import "./ele.dark.style.css";
import "@/assets/styles/c_style.scss"
// import * as mapWork from "../map.js";
import { ref, reactive, onMounted, getCurrentInstance, computed } from 'vue';
import { addAirLine_c, eidtAirLine_c, getLineListDetial_c,getPlottingByUuid } from "../api";
// import pointList from "./pointList.vue";
const { proxy } = getCurrentInstance();
const props = defineProps(["id", 'hxid'])
const emit = defineEmits(["setShowType"])
//表单数据
const formRef = ref(null)
const form = reactive({
// airlineName: '',
airlineType: 0,
waypointCount: '',
length: '',
expectedTime: '',
flyToWaylineMode: 'safely',
alt: 0,
heightType: 'relativeToStartPoint',
// height: 0,
// speed: 1,
waypointHeadingMode: 'followWayline',
gimbalPitchMode: 'manual',
waypointTurnMode: 'coordinateTurn',
executionType: 'goHome',
uavType: '',
uavPTZ: '',
storageType: ['wide', 'zoom', 'ir'],
hightMax: '',
hightMin: '',
lat: '',
lng: '',
militaryAreaName: '',
militaryAreaId: null,
name: '',
flightRule: '',
airspaceType: '',
airspaceProp: '',
radLength: '',
startTime: null,
endTime: null,
planBeg: null,
planEnd: null,
uuid: null
})
//
// 表单校验
const rules = reactive({
name: [{ required: true, message: '请输入名称' },],
militaryAreaName: [{ required: true, message: '请选择所属战区' },],
airspaceType: [{ required: true, message: '请选择空域类型' },],
airspaceProp: [{ required: true, message: '请选择空域性质' },],
flightRule: [{ required: true, message: '请选择飞行规则' },],
})
//表单提交方法
const submitForm = () => {
formRef.value.validate(async (valid) => {
if (valid) {
form.itemId = props.id
// form.uuid =mapWork.kyuuid
// console.log("form.uuID",form.uuid)
addAirLine_c(form).then((res) => {
if (res.code === 200) {
// proxy.$message.success("添加成功");
toList()
} else {
// proxy.$message.error(res.message);
}
});
} else {
return false;
}
});
}
const submitForms = () => {
toList()
}
// 修改保存
const editForm = () => {
formRef.value.validate(async (valid) => {
if (valid) {
if (form.isOriginal == 0) {
return proxy.$message.error("该副本不支持修改后保存");
}
// form.uuid =mapWork.kyuuid
// console.log("form.uuID",form.uuid)
eidtAirLine_c(form).then((res) => {
if (res.code === 200) {
// proxy.$message.success("修改成功");
toList()
} else {
// proxy.$message.error(res.message);
}
});
} else {
return false;
}
});
}
// 设置位置
const setPosition = (val) => {
if (val.lng && val.lat) {
mapWork.setQFDposition(val)
}
if (typeof val === 'number') {
mapWork.setQFDposition({ alt: val })
}
}
// 设置公共高度
const changeHeight = (val) => {
form.height = val
// form.ellipsoidHeight = val.egmAlt
mapWork.commonData.height = val
}
const clear = () => {
mapWork.resethangxian()
console.log("清除地图")
}
// 返回列表
const toList = () => {
// mapWork.resethangxian()
console.log("重置地图")
emit('setShowType', 'routeList', props.id)
}
// 无人机下拉列表
const slectUavTypeList = [{ name: 'M30 系列', value: '67' }, { name: 'Mavic 3 行业系列', value: '77' }]
const slectmilitaryAreaList = [{ name: '东部战区', value: '1' }, { name: '南部战区', value: '2' }, { name: '西部战区', value: '3' }, { name: '北部战区', value: '4' }, { name: '中部战区', value: '5' }]
const slectAirspaceTypeList = [{ name: '圆形空域', value: '1' }, { name: '多边形空域', value: '2' }]
const slectFlightRuleList = [{ name: 'VFR', value: '1' }, { name: 'IFR', value: '2' }]
const slectAirspacePropList = [{ name: '固定空域', value: '1' }, { name: '临时空域', value: '2' }]
// const getSelectUavTypeList = (val) => {
// getSelectUavTypeList_c().then((res) => {
// slectUavTypeList.value = res.data
// });
// }
// 云台列表
const payloadTypeList = computed(() => {
let arr = []
if (form.uavType == '77') {
arr = [{ name: 'Mavic 3E 相机', value: '66' }, { name: 'Mavic 3T 相机', value: '67' }]
} else if (form.uavType == '67') {
arr = [{ name: 'M30 相机', value: '52' }, { name: 'M30T 相机', value: '53' }]
} else {
arr = [{ name: '请选择无人机后选择云台', value: '' }]
}
return arr
})
// 存储类型
const storageTypeList = computed(() => {
let arr = []
const arrMap = [
[() => form.uavType == '77' && form.payloadType == '66', () => arr = []],
[() => form.uavType == '77' && form.payloadType == '67', () => arr = []],
[() => form.uavType == '67' && form.payloadType == '52', () => arr = [{ value: 'wide', name: '广角照片(W)', jc: 'W' }, { value: 'zoom', name: '变焦照片(Z)', jc: 'Z' },]],
[() => form.uavType == '67' && form.payloadType == '53', () => arr = [{ value: 'wide', name: '广角照片(W)', jc: 'W' }, { value: 'zoom', name: '变焦照片(Z)', jc: 'Z' }, { value: 'ir', name: '红外照片(IR)', jc: 'IR' },]],
]
const target = arrMap.find((m) => m[0]())
if (target) {
target[1]()
}
return arr
})
watch(() => payloadTypeList.value, (val) => {
//form.payloadType = ''
}, { deep: true })
watch(() => storageTypeList.value, (val) => {
if (val && val.length) {
form.storageType = val.map(obj => obj.value)
} else {
form.storageType = []
}
}, { deep: true })
const pointList_show = ref(false)
const pointList_show_handel = (val) => {
console.log("这个val的值为",val)
pointList_show.value = val
if (!val) {
mapWork?.pointEndDraw()
}
}
// 获取详情
const getDetial = (id) => {
// mapWork.loadingDomShow(true)
// console.log("这个是地图",mapWork)
getLineListDetial_c(id).then((res) => {
if (res.code === 200) {
Object.assign(form, res.data)
console.log("返回的经纬度",res.data.lat)
console.log("返回的UUID",res.data.uuid)
getPlotting(res.data.uuid)
} else {
proxy.$message.error(res.message);
}
});
// mapWork.loadingDomShow(false)
}
const getPlotting = (id) => {
getPlottingByUuid(id).then((res) => {
if (res.code == 200) {
mapWork.groupLayerTreeArr.value = []
mapWork.graphicLayer;
console.log("mapWork.graphicLayer:",mapWork.graphicLayer)
mapWork.graphicLayer.getGraphicById(id)
console.log("mapWork.graphicLayer根据id获取:",mapWork.graphicLayer.getGraphicById(id))
console.log("返回的数据:",res.data)
let dirList = res.data;
let plot = [];
dirList.forEach((item, index) => {
plot = plot.concat(item.plottings)
// item.plottings.forEach((m,n) =>{
// plot.push(m)
// })
// if(item.init === 1 && item.source === 2){
// item.name = 'DroneFly共享目录'
// item.plottings.forEach((plot,inde) =>{
// plot.isShare = true
// })
// }
// if(item.init === 1 && item.source === 1){
// item.name = '默认目录'
// }
mapWork.groupLayerTreeArr.value
.push({
id: item.id,
name: item.name,
type: item.type,
appId: item.appId,
orgId: item.orgId,
// parentId: item.parentId,
// folderId: item.parentId,
// lockStatus: item.lockStatus,
// shareStatus: item.shareStatus,
showStatusWeb: item.showStatusWeb,
// source: item.source,
// init: item.init,
// couldDel: item.couldDel,
plottingStatus:item.plottingStatus,
children: item.plottings,
});
});
// mapWork.groupLayerTreeArr.value
// .push({
// id: res.data.id,
// name: res.data.name,
// type: res.data.type,
// appId: res.data.appId,
// orgId: res.data.orgId,
// // parentId: item.parentId,
// // folderId: item.parentId,
// // lockStatus: item.lockStatus,
// // shareStatus: item.shareStatus,
// showStatusWeb: res.data.showStatusWeb,
// // source: item.source,
// // init: item.init,
// // couldDel: item.couldDel,
// plottingStatus:item.plottingStatus,
// children: item.plottings,
// });
mapWork.geoJsonLayerList(res.data);
// handleLocal(res.data)
// 在数据加载完毕后,使用 nextTick 确保 el-tree 渲染完毕再设置选中
// nextTick(() => {
// setTreeNodeSelected({ id: 9 });
// });
} else {
proxy.$message.error(res.msg);
}
});
}
// 关闭途径点标绘
const closedTJD = () => {
if (proxy.$refs['pointListRef']) {
console.log("🚀 ~ file: routeAdd.vue:377 ~ closedTJD ~ proxy.$refs['pointListRef']:", proxy.$refs['pointListRef'])
}
}
onMounted(() => {
if (props.hxid) {
getDetial(props.hxid)
}
})
</script>
<style lang="scss" scoped>
.el-container {
position: absolute;
left: 0;
top: 0;
right: auto;
bottom: 70px;
z-index: 1001;
width: 420px;
height: auto;
background: rgba(29, 37, 50, 0.85);
.el-header,
.el-footer {
background: transparent;
}
.title {
font-size: 16px;
font-weight: bold;
color: white;
}
.addBtn {
cursor: pointer;
&:hover {
opacity: 0.8;
}
}
.editBtn {
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
cursor: pointer;
background: #414243;
&:hover {
opacity: 0.8;
}
}
}
.displayFlex {
border-bottom: 1px solid #414243;
.contentDom {
padding: 15px 0;
}
&:last-child {
border-bottom: none;
.contentDom {
padding-bottom: 0;
}
}
&:first-child {
.contentDom {
padding-top: 0;
}
}
li {
line-height: 22px;
}
}
</style>