From ea6e49ccb4d3bdb510ccf87844490823a96ebf08 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Fri, 12 Sep 2025 20:11:51 +0800
Subject: [PATCH] feat:空域录入完善,增删改查

---
 src/views/airspace/components/AirspaceMap.vue |  145 ++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 126 insertions(+), 19 deletions(-)

diff --git a/src/views/airspace/components/AirspaceMap.vue b/src/views/airspace/components/AirspaceMap.vue
index 89707c6..828c467 100644
--- a/src/views/airspace/components/AirspaceMap.vue
+++ b/src/views/airspace/components/AirspaceMap.vue
@@ -6,7 +6,8 @@
 				<avue-form ref="formEle" :option="option" v-model="form"></avue-form>
 			</div>
 
-			<div class="map-container">
+			<div class="map-container" v-loading="mapLoading" element-loading-text="地形初始化中,请稍后..."
+				element-loading-background="rgba(0, 0, 0, 0.7)">
 				<div class="tool-tip warning" v-show="isShowWaringTip">
 					<span class="icon">
 						<el-icon>
@@ -31,15 +32,33 @@
 
 import * as Cesium from 'cesium'
 import * as turf from '@turf/turf'
+
+import { getPointPositionsHeight } from '@/utils/cesium/mapUtil'
 import { DrawPolygon } from '@/utils/drawPolygon/drawPolygon'
 import { PublicCesium } from '@/utils/cesium/publicCesium'
 import { ElMessageBox, ElMessage } from 'element-plus'
+
+import {
+	airspaceEnteringAdd,
+	airspaceEnteringUpdate
+} from '@/api/airspace/airspace'
+
 
 const props = defineProps({
 	title: {
 		type: String,
 		default: '新增空域',
 	},
+
+	type: {
+		type: String,
+		default: 'add',
+	},
+
+	curEditRow: {
+		type: Object,
+		default: () => { },
+	}
 })
 
 const emit = defineEmits(['submitClick'])
@@ -47,7 +66,9 @@
 const dialogShow = defineModel('show')
 
 const formEle = ref(null)
-const form = ref({})
+const form = ref({
+	height: 120,
+})
 const option = ref({
 	submitBtn: false,
 	emptyBtn: false,
@@ -70,23 +91,38 @@
 			label: '高度',
 			prop: 'height',
 			type: 'input',
+			value: 120,
+			min: 5,
+			max: 500,
+			type: 'number',
+			change ({ column, value }) {
+				drawPolygonExample?.setPolygonHeight?.(value)
+			},
 			rules: [
 				{
 					required: true,
 					message: '请输入高度',
 					trigger: 'blur'
+				},
+				{
+					pattern: /^(?:[5-9]|[1-9]\d|[1-4]\d{2}|500)$/, // 5-500
+					message: '高度需在5-500之间',
+					trigger: ['blur', 'change']
 				}
 			]
 		},
 
 		{
 			label: '类型',
-			prop: 'type',
+			prop: 'flight_type',
 			type: 'select',
-			dicUrl: `/blade-system/dict/dictionary?code=flow`,
+			dicUrl: `/drone-device-core/airspace/page?current=1&size=10000&typeName=`,
 			props: {
-				label: 'dictValue',
-				value: 'dictKey',
+				label: 'type_name',
+				value: 'id',
+			},
+			dicFormatter (res) {
+				return res.data.records
 			},
 			rules: [
 				{
@@ -98,7 +134,7 @@
 		},
 		{
 			label: '管控时段',
-			prop: 'daterange',
+			prop: 'time_period',
 			type: 'daterange',
 			format: 'YYYY-MM-DD',
 			valueFormat: 'YYYY-MM-DD',
@@ -130,11 +166,13 @@
 let publicCesiumInstance = null
 let viewer = null
 // 地图
+const mapLoading = ref(true)
+
 const isShowWaringTip = ref(false)
 
 const curDrawPolygonData = ref([])
 
-const initMap = () => {
+const initMap = async () => {
 	if (!document.getElementById('AirspaceMap')) {
 		return
 	}
@@ -145,24 +183,36 @@
 		layerMode: 4,
 		contour: true,
 		flyToContour: true,
+		terrainInit () {
+			setTimeout(async () => {
+				initDrawPolygon()
+				mapLoading.value = false
+			}, 1500)
+		}
 	})
+
 	viewer = publicCesiumInstance.getViewer()
+
 	drawPolygonExample = new DrawPolygon()
+
 	drawPolygonExample.initHandler(viewer)
 
-	drawPolygonExample?.subscribe('getShowWaringTip', data => {
+	drawPolygonExample.subscribe('getShowWaringTip', data => {
 		isShowWaringTip.value = data
 	})
 
-	drawPolygonExample?.subscribe('getPolygonPositions', data => {
+	drawPolygonExample.subscribe('getPolygonPositions', data => {
 		curDrawPolygonData.value = data.map(item => {
 			let cartographic = Cesium.Cartographic.fromCartesian(item)
+
 			let lng = Cesium.Math.toDegrees(cartographic.longitude) // 经度
 			let lat = Cesium.Math.toDegrees(cartographic.latitude) // 纬度
+			let height = cartographic.height
 
 			return {
 				lng: _.round(lng, 6),
 				lat: _.round(lat, 6),
+				height
 			}
 		})
 	})
@@ -170,11 +220,32 @@
 
 watch(dialogShow, async (show) => {
 	if (show) {
+		if (props.type === 'edit') {
+			form.value = { ...props.curEditRow }
+		}
+
+		initDrawPolygon()
+
+		if (viewer) return
+
 		await nextTick()
 		cesiumContextMenu()
 		initMap()
 	}
 })
+
+const initDrawPolygon = async () => {
+	if (props.type === 'edit' && drawPolygonExample) {
+		drawPolygonExample?.setPolygonHeight?.(props.curEditRow.height)
+
+		let polygon = JSON.parse(props.curEditRow.flight_range)
+
+		if (polygon.length > 0) {
+			const aslData = await getPointPositionsHeight(polygon, viewer)
+			drawPolygonExample?.initPolygon(viewer, aslData.map(item => ({ ...item, height: item.ASL })))
+		}
+	}
+}
 
 const handleSubmit = () => {
 	if (ElMessage.value) {
@@ -201,8 +272,38 @@
 
 				let area = turf.area(polygon)
 
-				emit('submitClick')
-				done()
+				if (props.type === 'edit') {
+					airspaceEnteringUpdate({
+						id: props.curEditRow.id,
+						name: form.value.name,
+						flight_range: JSON.stringify(curDrawPolygonData.value),
+						height: form.value.height,
+						time_period: form.value.time_period.join('~'),
+						flight_type: form.value.flight_type,
+						remark: form.value.remark,
+						area: area
+					}).then(res => {
+						ElMessage.success('更新成功')
+						dialogShow.value = false
+						emit('submitClick')
+						done()
+					})
+				} else {
+					airspaceEnteringAdd({
+						name: form.value.name,
+						flight_range: JSON.stringify(curDrawPolygonData.value),
+						height: form.value.height,
+						time_period: form.value.time_period.join('~'),
+						flight_type: form.value.flight_type,
+						remark: form.value.remark,
+						area: area
+					}).then(res => {
+						ElMessage.success('新增成功')
+						dialogShow.value = false
+						emit('submitClick')
+						done()
+					})
+				}
 			} else {
 				return false
 			}
@@ -211,15 +312,12 @@
 }
 
 const handleClose = () => {
+	drawPolygonExample?.delPolygon()
 	isShowWaringTip.value = false
 	curDrawPolygonData.value = []
-	cesiumContextMenu(false)
-	drawPolygonExample?.destroy()
-	publicCesiumInstance?.viewerDestroy()
-	publicCesiumInstance = null
-	viewer = null
-	drawPolygonExample = null
-	form.value = {}
+	form.value = {
+		height: 120
+	}
 	formEle.value.resetForm()
 	dialogShow.value = false
 }
@@ -239,6 +337,15 @@
 		cesium.removeEventListener('contextmenu', preventDefault)
 	}
 }
+
+onBeforeUnmount(() => {
+	drawPolygonExample?.destroy()
+	drawPolygonExample = null
+	cesiumContextMenu(false)
+	publicCesiumInstance?.viewerDestroy()
+	publicCesiumInstance = null
+	viewer = null
+})
 </script>
 
 <style scoped lang="scss">

--
Gitblit v1.9.3