From ee6c54cf8cf65ecbc28c800d345c85c0bd865373 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Thu, 26 Feb 2026 14:16:54 +0800
Subject: [PATCH] feat: 工单机巢只能在覆盖范围内绘制

---
 applications/drone-command/src/views/areaManage/defenseZone/FormDiaLog.vue              |    4 ++--
 applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue           |    4 ++--
 applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue |    8 +++++---
 packages/utils/map/DrawPolygon.js                                                       |   38 +++++++++++++++++++++++++++++++++++++-
 4 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/applications/drone-command/src/views/areaManage/defenseZone/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/defenseZone/FormDiaLog.vue
index 9e5bc91..58551ba 100644
--- a/applications/drone-command/src/views/areaManage/defenseZone/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/defenseZone/FormDiaLog.vue
@@ -251,7 +251,7 @@
 
 // 新增模式绘制
 function addPolygon () {
-	drawPolygonExample = new DrawPolygon(viewer)
+	drawPolygonExample = new DrawPolygon()
 	drawPolygonExample.initHandler(viewer)
 	drawPolygonExample.subscribe('getPolygonPositions', drawFinished)
 }
@@ -261,7 +261,7 @@
 	if (!formData.value?.geom) return
 	pointList = geomAnalysis(formData.value.geom)
 	drawPolygonExample?.destroy()
-	drawPolygonExample = new DrawPolygon(viewer)
+	drawPolygonExample = new DrawPolygon()
 	let noClosedList = _.cloneDeep(pointList)
 	noClosedList.pop()
 	drawPolygonExample.initPolygon(
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue
index 92a98c9..d90bd8f 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue
@@ -352,7 +352,7 @@
 
 // 新增模式绘制
 function addPolygon () {
-	drawPolygonExample = new DrawPolygon(viewer)
+	drawPolygonExample = new DrawPolygon()
 	drawPolygonExample.initHandler(viewer)
 	drawPolygonExample.subscribe('getPolygonPositions', drawFinished)
 }
@@ -362,7 +362,7 @@
 	if (!formData.value?.geom) return
 	pointList = geomAnalysis(formData.value.geom)
 	drawPolygonExample?.destroy()
-	drawPolygonExample = new DrawPolygon(viewer)
+	drawPolygonExample = new DrawPolygon()
 	let pointList1 = _.cloneDeep(pointList)
 	pointList1.pop()
 	drawPolygonExample.initPolygon(
diff --git a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
index b74affd..b5c8899 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
@@ -317,6 +317,7 @@
 const suddenlyEdit = ref(false)
 const processList = ref([])
 let viewPlane
+let allDeviceList = []
 const hasPatrolTaskList = computed(() => ['30', '40', '50', '60'].includes(String(formData.value.workOrderStatus)))
 
 const gdStatusObj = {
@@ -472,7 +473,7 @@
 
 // 新增模式绘制
 function addPolygon() {
-	drawPolygonExample = new DrawPolygon(viewer)
+	drawPolygonExample = new DrawPolygon({ deviceList: allDeviceList })
 	drawPolygonExample.initHandler(viewer)
 	drawPolygonExample.subscribe('getPolygonPositions', drawFinished)
 }
@@ -494,7 +495,7 @@
 	if (!formData.value?.geom) return
 	pointList.value = geomAnalysis(formData.value.geom)
 	drawPolygonExample?.destroy()
-	drawPolygonExample = new DrawPolygon(viewer)
+	drawPolygonExample = new DrawPolygon({ deviceList: allDeviceList })
 	let noClosedList = _.cloneDeep(pointList.value)
 	noClosedList.pop()
 	drawPolygonExample.initPolygon(
@@ -627,7 +628,8 @@
 	initMap()
 	const allDeviceRes = await gdManageDeviceListApi()
 	formData.value = dialogMode.value === 'add' ? initForm() : row
-	renderingAllDevice(allDeviceRes?.data?.data || [])
+	allDeviceList = allDeviceRes?.data?.data || []
+	renderingAllDevice(allDeviceList)
 	if (dialogMode.value === 'add') {
 		addPolygon()
 	} else {
diff --git a/packages/utils/map/DrawPolygon.js b/packages/utils/map/DrawPolygon.js
index a3f6afb..2bdeeff 100644
--- a/packages/utils/map/DrawPolygon.js
+++ b/packages/utils/map/DrawPolygon.js
@@ -14,7 +14,10 @@
  *  - 外部订阅/通知机制
  */
 export class DrawPolygon {
-	constructor() {
+	constructor(options = {}) {
+		// 设备覆盖范围列表(经纬度 + 5000m半径)
+		this.deviceList = options.deviceList || []
+		this.coverageRadius = 5000
 		// 图斑预览模式标记
 		this.isPureSpotPreview = false
 		// 是否删除测区
@@ -398,6 +401,19 @@
 	handleLeftUp() {
 		if (!(this.editingMode && this.curPolygon?.positions && this.draggedEntity)) return
 
+		// 检查松手位置是否在设备覆盖范围内
+		if (this.isDragging && !this.isWithinDeviceCoverage(this.curPolygon.positions[this.draggedEntity?.customData.ind])) {
+			ElMessage.warning('该位置不在设备覆盖范围内,请在设备5公里范围内绘制')
+			// 回弹到拖拽前的位置
+			this.draggedEntity.position = this.currentDragPointPosition
+			this.curPolygon.positions[this.draggedEntity?.customData.ind] = this.currentDragPointPosition
+			this.isDragging = false
+			this.draggedEntity = null
+			this.enableMapControl()
+			this.rebuildMidPoints()
+			return
+		}
+
 		if (this.currentDragPointIsValid && this.isDragging) {
 			// 更新点位置
 			this.draggedEntity.position = this.currentDragPointPosition
@@ -514,6 +530,12 @@
 		// 添加新的点
 		const cartesian = this.viewer.scene.pickPosition(click.position)
 		if (!cartesian) return
+
+		// 检查点击位置是否在设备覆盖范围内
+		if (!this.isWithinDeviceCoverage(cartesian)) {
+			ElMessage.warning('该位置不在设备覆盖范围内,请在设备5公里范围内绘制')
+			return
+		}
 
 		let arr = [...this.curPolygon.positions]
 		arr.pop()
@@ -726,6 +748,20 @@
 
 		return intersections.features.length === 0
 	}
+
+	// 检查位置是否在任意设备的覆盖范围内(5km)
+	isWithinDeviceCoverage(cartesian) {
+		if (!this.deviceList || this.deviceList.length === 0) return true
+		const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
+		const clickPoint = turf.point([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)])
+		return this.deviceList
+			.filter(item => item.latitude)
+			.some(item => {
+				const rangePoint = turf.point([item.longitude, item.latitude])
+				const distance = turf.distance(rangePoint, clickPoint, { units: 'kilometers' })
+				return distance <= 5
+			})
+	}
 	// 初始化已有多边形
 	async initPolygon(viewer, positions, isPurePreview = false) {
 		this.initHandler(viewer)

--
Gitblit v1.9.3