From a2bb326dfbc6024916d360b89d021243f8502e33 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Fri, 12 Sep 2025 14:51:46 +0800
Subject: [PATCH] feat:空域录入相关调整

---
 src/views/airspace/components/AirspaceMap.vue |  176 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 158 insertions(+), 18 deletions(-)

diff --git a/src/views/airspace/components/AirspaceMap.vue b/src/views/airspace/components/AirspaceMap.vue
index cd2d1aa..89707c6 100644
--- a/src/views/airspace/components/AirspaceMap.vue
+++ b/src/views/airspace/components/AirspaceMap.vue
@@ -5,16 +5,35 @@
 			<div class="form-container">
 				<avue-form ref="formEle" :option="option" v-model="form"></avue-form>
 			</div>
+
 			<div class="map-container">
+				<div class="tool-tip warning" v-show="isShowWaringTip">
+					<span class="icon">
+						<el-icon>
+							<WarningFilled />
+						</el-icon>
+					</span>
+					<span>空域不支持交叉面,无法生成空域</span>
+				</div>
 				<div id="AirspaceMap" class="ztzf-cesium"></div>
+			</div>
+
+			<div class="btn-container">
+				<el-button icon="el-icon-check" type="primary" @click="handleSubmit">确定</el-button>
+				<el-button icon="el-icon-close" @click="dialogShow = false">取消</el-button>
 			</div>
 		</div>
 	</el-dialog>
 </template>
 
 <script setup>
+import _, { cloneDeep, throttle } from 'lodash'
+
 import * as Cesium from 'cesium'
+import * as turf from '@turf/turf'
+import { DrawPolygon } from '@/utils/drawPolygon/drawPolygon'
 import { PublicCesium } from '@/utils/cesium/publicCesium'
+import { ElMessageBox, ElMessage } from 'element-plus'
 
 const props = defineProps({
 	title: {
@@ -23,6 +42,8 @@
 	},
 })
 
+const emit = defineEmits(['submitClick'])
+
 const dialogShow = defineModel('show')
 
 const formEle = ref(null)
@@ -30,10 +51,11 @@
 const option = ref({
 	submitBtn: false,
 	emptyBtn: false,
+	menuBtn: false,
 	column: [
 		{
 			label: '名称',
-			prop: 'input',
+			prop: 'name',
 			type: 'input',
 			rules: [
 				{
@@ -46,7 +68,7 @@
 
 		{
 			label: '高度',
-			prop: 'input',
+			prop: 'height',
 			type: 'input',
 			rules: [
 				{
@@ -59,18 +81,13 @@
 
 		{
 			label: '类型',
-			prop: 'select',
+			prop: 'type',
 			type: 'select',
-			dicData: [
-				{
-					label: '字典1',
-					value: 0,
-				},
-				{
-					label: '字典2',
-					value: 1,
-				},
-			],
+			dicUrl: `/blade-system/dict/dictionary?code=flow`,
+			props: {
+				label: 'dictValue',
+				value: 'dictKey',
+			},
 			rules: [
 				{
 					required: true,
@@ -97,21 +114,26 @@
 		},
 
 		{
-			label: '备注',
-			prop: 'input',
+			label: '管控原因',
+			prop: 'remark',
 			type: 'textarea',
 			span: 24,
 			rows: 1,
 			minRows: 1,
 			maxRows: 1,
-			placeholder: '请输入备注',
+			placeholder: '请输入管控原因',
 		},
 	],
 })
 
+let drawPolygonExample = null
 let publicCesiumInstance = null
 let viewer = null
 // 地图
+const isShowWaringTip = ref(false)
+
+const curDrawPolygonData = ref([])
+
 const initMap = () => {
 	if (!document.getElementById('AirspaceMap')) {
 		return
@@ -121,37 +143,155 @@
 		flatMode: false,
 		terrain: true,
 		layerMode: 4,
-		contour: false,
+		contour: true,
+		flyToContour: true,
 	})
 	viewer = publicCesiumInstance.getViewer()
+	drawPolygonExample = new DrawPolygon()
+	drawPolygonExample.initHandler(viewer)
+
+	drawPolygonExample?.subscribe('getShowWaringTip', data => {
+		isShowWaringTip.value = 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) // 纬度
+
+			return {
+				lng: _.round(lng, 6),
+				lat: _.round(lat, 6),
+			}
+		})
+	})
 }
 
 watch(dialogShow, async (show) => {
 	if (show) {
 		await nextTick()
+		cesiumContextMenu()
 		initMap()
 	}
 })
 
+const handleSubmit = () => {
+	if (ElMessage.value) {
+		ElMessage.warning('空域不支持交叉,请重新绘制或调整')
+		return
+	}
+
+	if (curDrawPolygonData.value.length === 0) {
+		ElMessage.warning('请绘制空域区域')
+		return
+	}
+
+	if (formEle.value) {
+		formEle.value.validate((valid, done, msg) => {
+			if (valid) {
+				let disposePolygon = curDrawPolygonData.value.map(i => [i.lng, i.lat])
+
+				let polygon = turf.polygon([
+					[
+						...disposePolygon,
+						disposePolygon[0]
+					]
+				])
+
+				let area = turf.area(polygon)
+
+				emit('submitClick')
+				done()
+			} else {
+				return false
+			}
+		})
+	}
+}
+
 const handleClose = () => {
+	isShowWaringTip.value = false
+	curDrawPolygonData.value = []
+	cesiumContextMenu(false)
+	drawPolygonExample?.destroy()
 	publicCesiumInstance?.viewerDestroy()
 	publicCesiumInstance = null
 	viewer = null
+	drawPolygonExample = null
 	form.value = {}
 	formEle.value.resetForm()
 	dialogShow.value = false
+}
+
+// 阻止右键默认行为
+const preventDefault = event => {
+	event.preventDefault()
+	return
+}
+
+const cesiumContextMenu = (isAdd = true) => {
+	let cesium = document.getElementById('AirspaceMap')
+	if (!cesium) return
+	if (isAdd) {
+		cesium.addEventListener('contextmenu', preventDefault)
+	} else {
+		cesium.removeEventListener('contextmenu', preventDefault)
+	}
 }
 </script>
 
 <style scoped lang="scss">
 .custom-container {
 	.map-container {
-		height: 440px;
+		height: 620px;
 
 		#AirspaceMap {
+			position: relative;
 			width: 100%;
 			height: 100%;
+			overflow: hidden;
 		}
 	}
+
+	.btn-container {
+		margin-top: 16px;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+}
+
+.tool-tip {
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	position: absolute;
+	width: 800px;
+	height: 64px;
+	font-family: Source Han Sans CN, Source Han Sans CN;
+	font-size: 18px;
+	color: #ffffff;
+
+	background: rgba(11, 31, 58, 0.7);
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+	z-index: 9;
+}
+
+.warning {
+	top: 234px;
+	left: 50%;
+	transform: translateX(-50%);
+	color: #fff;
+	background: rgba(140, 0, 0, 0.4);
+
+	.icon {
+		display: flex;
+		align-items: center;
+		color: #ff1f1f;
+	}
 }
 </style>

--
Gitblit v1.9.3