From 89380e6260a75d1d3b94de687ebcc2f50d50659d Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Tue, 03 Feb 2026 15:44:33 +0800
Subject: [PATCH] feat:环境变量配置调整

---
 applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue |  140 ++++++++++++++++++++++++++++++++--------------
 1 files changed, 97 insertions(+), 43 deletions(-)

diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 472eddb..342b43c 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -160,7 +160,8 @@
 					</el-form-item>
 					<el-form-item label="关联派出所" prop="policeStationId">
 						<el-select class="command-select" popper-class="command-select-popper"
-							v-model="formData.policeStationId" placeholder="请选择" clearable>
+							v-model="formData.policeStationId" placeholder="请选择" clearable filterable remote
+							:remote-method="handlePoliceStationSearch" :loading="policeStationLoading">
 							<el-option v-for="item in policeStationOptions" :key="item.id" :label="item.stationName"
 								:value="item.id" />
 						</el-select>
@@ -252,13 +253,14 @@
 } from '@/utils/cesium/deviceRange'
 import * as Cesium from 'cesium'
 import { AREA_TYPE_STYLE_MAP, BUFFER_LEVEL_STYLES, DEFAULT_AREA_STYLE } from '@ztzf/constants'
-import { fwPoliceStationQueryByPolygonsApi } from '@/views/areaManage/precinctInfo/precinctInfoApi'
+import { fwPoliceStationListApi } from '@/views/areaManage/precinctInfo/precinctInfoApi'
 import { fwDeviceListByPolygonsApi } from '@/views/basicManage/deviceStock/fwDevice'
 import polygonIcon from '@/assets/images/areaMap/polygon.png'
 import rectIcon from '@/assets/images/areaMap/rect.png'
 import ellipseIcon from '@/assets/images/areaMap/ellipse.png'
 import bufferIcon from '@/assets/images/areaMap/buffer.png'
 import trashIcon from '@/assets/images/areaMap/trash.png'
+import equipmentIcon from '@/assets/images/dataCockpit/map/equipment.png'
 
 const initForm = () => ({
 	areaName: '', // 区域名称
@@ -285,6 +287,10 @@
 const searchName = ref('')
 const selectedDeviceRows = ref([])
 const policeStationOptions = ref([]) // 关联派出所
+const policeStationAllOptions = ref([])
+const policeStationLoading = ref(false)
+const policeStationSearchTimer = ref(null)
+const policeStationSearchKeyword = ref('')
 const deviceOptions = ref([]) // 关联设备
 const dictObj = inject('dictObj')
 const mapRef = ref(null)
@@ -309,6 +315,7 @@
 let viewEntity
 let shapeDisplaySource
 const deviceRangePrimitiveMap = new Map()
+const deviceIconEntityMap = new Map()
 const activeToolMode = ref('')
 const suppressDeviceFly = ref(false)
 const isDialogInitializing = ref(false)
@@ -316,8 +323,6 @@
 let deviceRangeRenderToken = 0
 let deviceListTimer = null
 let deviceListRequestToken = 0
-let policeStationListTimer = null
-let policeStationRequestToken = 0
 
 const rules = {
 	areaName: fieldRules(true, 50),
@@ -424,9 +429,9 @@
 				clearTimeout(deviceListTimer)
 				deviceListTimer = null
 			}
-			if (policeStationListTimer) {
-				clearTimeout(policeStationListTimer)
-				policeStationListTimer = null
+			if (policeStationSearchTimer.value) {
+				clearTimeout(policeStationSearchTimer.value)
+				policeStationSearchTimer.value = null
 			}
 			viewEntity && viewer?.entities?.remove(viewEntity)
 			viewEntity = null
@@ -434,6 +439,7 @@
 			hideTypePanel()
 			clearShapeDisplay()
 			clearDeviceRangePrimitives()
+			clearDeviceIconEntities()
 		}
 	}
 )
@@ -448,7 +454,6 @@
 	() => {
 		if (isDialogInitializing.value) return
 		queueDeviceListRefresh()
-		queuePoliceStationRefresh()
 	},
 	{ deep: true }
 )
@@ -502,18 +507,23 @@
 	deviceRangePrimitiveMap.clear()
 }
 
+function clearDeviceIconEntities () {
+	if (!viewer || !deviceIconEntityMap.size) return
+	for (const entity of deviceIconEntityMap.values()) {
+		viewer.entities.remove(entity)
+	}
+	deviceIconEntityMap.clear()
+}
+
 function clearDeviceListState () {
 	deviceOptions.value = []
 	selectedDeviceRows.value = []
 	formData.value.deviceIds = ''
+	clearDeviceRangePrimitives()
+	clearDeviceIconEntities()
 	if (deviceTableRef.value) {
 		deviceTableRef.value.clearSelection()
 	}
-}
-
-function clearPoliceStationState () {
-	policeStationOptions.value = []
-	formData.value.policeStationId = ''
 }
 
 function formatWktNumber (value) {
@@ -602,8 +612,10 @@
 async function renderDeviceRangeSingle (device) {
 	if (!viewer) return
 	clearDeviceRangePrimitives()
+	clearDeviceIconEntities()
 	const position = getDeviceLngLat(device)
 	if (!position) return
+	addDeviceIconEntity(device, position)
 	const rangeMeters = normalizeDeviceRange(device.effectiveRangeKm)
 	const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters)
 	if (!primitive) return
@@ -623,6 +635,12 @@
 			deviceRangePrimitiveMap.delete(id)
 		}
 	}
+	for (const [id, entity] of deviceIconEntityMap.entries()) {
+		if (!nextIds.has(id)) {
+			viewer.entities.remove(entity)
+			deviceIconEntityMap.delete(id)
+		}
+	}
 	const pendingRows = selectedRows.filter(row => {
 		const id = String(row?.id)
 		return id && !deviceRangePrimitiveMap.has(id)
@@ -631,14 +649,17 @@
 	const primitives = await Promise.all(
 		pendingRows.map(async row => {
 			const position = getDeviceLngLat(row)
-			if (!position) return { row, primitive: null }
+			if (!position) return { row, primitive: null, position: null }
 			const rangeMeters = normalizeDeviceRange(row.effectiveRangeKm)
 			const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters)
-			return { row, primitive }
+			return { row, primitive, position }
 		})
 	)
 	if (renderToken !== deviceRangeRenderToken) return
-	primitives.forEach(({ row, primitive }) => {
+	primitives.forEach(({ row, primitive, position }) => {
+		if (position) {
+			addDeviceIconEntity(row, position)
+		}
 		if (!primitive) return
 		const id = String(row?.id)
 		if (!nextIds.has(id)) return
@@ -668,6 +689,23 @@
 function clearShapeDisplay () {
 	if (!shapeDisplaySource) return
 	shapeDisplaySource.entities.removeAll()
+}
+
+function addDeviceIconEntity (device, position) {
+	if (!viewer || !position) return
+	const id = String(device?.id ?? '')
+	if (!id || deviceIconEntityMap.has(id)) return
+	const entity = viewer.entities.add({
+		position: Cesium.Cartesian3.fromDegrees(position.lng, position.lat, position.height || 0),
+		billboard: {
+			image: equipmentIcon,
+			width: 28,
+			height: 38,
+			verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+			heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+		},
+	})
+	deviceIconEntityMap.set(id, entity)
 }
 
 function normalizeShapePoint (point) {
@@ -1203,36 +1241,45 @@
 }
 
 // 获取派出所列表
-function queuePoliceStationRefresh () {
+async function getPoliceStationList (keyword = '') {
 	if (!visible.value) return
-	if (policeStationListTimer) {
-		clearTimeout(policeStationListTimer)
+	policeStationLoading.value = true
+	try {
+		const res = await fwPoliceStationListApi({
+			stationName: keyword || undefined,
+		})
+		const list = res?.data?.data ?? []
+		policeStationOptions.value = list
+		if (!keyword) {
+			policeStationAllOptions.value = list
+		}
+		await nextTick()
+		if (!keyword) {
+			const matched = policeStationOptions.value.find(
+				item => String(item.id) === String(formData.value.policeStationId)
+			)
+			if (!matched) {
+				formData.value.policeStationId = ''
+			}
+		}
+	} finally {
+		policeStationLoading.value = false
 	}
-	policeStationListTimer = setTimeout(() => {
-		policeStationListTimer = null
-		void getPoliceStationListByPolygons()
-	}, 200)
 }
 
-async function getPoliceStationListByPolygons () {
-	if (!visible.value) return
-	const polygons = resolveShapePolygonsWkt()
-	if (!polygons.length) {
-		clearPoliceStationState()
+function handlePoliceStationSearch (query) {
+	policeStationSearchKeyword.value = (query || '').trim()
+	if (!policeStationSearchKeyword.value) {
+		policeStationOptions.value = [...policeStationAllOptions.value]
 		return
 	}
-	policeStationRequestToken += 1
-	const requestToken = policeStationRequestToken
-	const res = await fwPoliceStationQueryByPolygonsApi({ polygons })
-	if (requestToken !== policeStationRequestToken) return
-	policeStationOptions.value = res?.data?.data ?? []
-	await nextTick()
-	const matched = policeStationOptions.value.find(
-		item => String(item.id) === String(formData.value.policeStationId)
-	)
-	if (!matched) {
-		formData.value.policeStationId = ''
+	if (policeStationSearchTimer.value) {
+		clearTimeout(policeStationSearchTimer.value)
 	}
+	policeStationSearchTimer.value = setTimeout(() => {
+		policeStationSearchTimer.value = null
+		void getPoliceStationList(policeStationSearchKeyword.value)
+	}, 300)
 }
 
 // 获取设备列表
@@ -1337,6 +1384,12 @@
 	selectedDeviceRows.value = []
 	deviceOptions.value = []
 	policeStationOptions.value = []
+	policeStationAllOptions.value = []
+	policeStationSearchKeyword.value = ''
+	if (policeStationSearchTimer.value) {
+		clearTimeout(policeStationSearchTimer.value)
+		policeStationSearchTimer.value = null
+	}
 	shapeList.value = []
 	activeShapeId.value = null
 	activeAreaType.value = ''
@@ -1345,6 +1398,7 @@
 	initMap()
 	clearShapeDisplay()
 	clearDeviceRangePrimitives()
+	clearDeviceIconEntities()
 	viewEntity && viewer?.entities?.remove(viewEntity)
 	viewEntity = null
 	clearActiveTool()
@@ -1386,7 +1440,7 @@
 	}
 	isDialogInitializing.value = false
 	queueDeviceListRefresh()
-	queuePoliceStationRefresh()
+	void getPoliceStationList()
 }
 
 onBeforeUnmount(() => {
@@ -1394,9 +1448,9 @@
 		clearTimeout(deviceListTimer)
 		deviceListTimer = null
 	}
-	if (policeStationListTimer) {
-		clearTimeout(policeStationListTimer)
-		policeStationListTimer = null
+	if (policeStationSearchTimer.value) {
+		clearTimeout(policeStationSearchTimer.value)
+		policeStationSearchTimer.value = null
 	}
 	hideTypePanel()
 })

--
Gitblit v1.9.3