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 | 236 ++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 155 insertions(+), 81 deletions(-)
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 9083c47..342b43c 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -23,22 +23,26 @@
</div>
<div class="map-toolbar">
<el-tooltip content="多边形" placement="left">
- <button class="tool-btn" type="button" @click="handleDraw('polygon')">
+ <button class="tool-btn" :class="{ active: currentShapeType === 'polygon' }" type="button"
+ @click="handleDraw('polygon')">
<img class="tool-icon-image" :src="polygonIcon" alt="多边形" />
</button>
</el-tooltip>
<el-tooltip content="矩形" placement="left">
- <button class="tool-btn" type="button" @click="handleDraw('rectangle')">
+ <button class="tool-btn" :class="{ active: currentShapeType === 'rectangle' }" type="button"
+ @click="handleDraw('rectangle')">
<img class="tool-icon-image" :src="rectIcon" alt="矩形" />
</button>
</el-tooltip>
<el-tooltip content="椭圆" placement="left">
- <button class="tool-btn" type="button" @click="handleDraw('ellipse')">
+ <button class="tool-btn" :class="{ active: currentShapeType === 'ellipse' }" type="button"
+ @click="handleDraw('ellipse')">
<img class="tool-icon-image" :src="ellipseIcon" alt="椭圆" />
</button>
</el-tooltip>
<el-tooltip content="缓冲圆" placement="left">
- <button class="tool-btn" type="button" @click="handleDraw('buffer')">
+ <button class="tool-btn" :class="{ active: currentShapeType === 'buffer' }" type="button"
+ @click="handleDraw('buffer')">
<img class="tool-icon-image" :src="bufferIcon" alt="缓冲圆" />
</button>
</el-tooltip>
@@ -156,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>
@@ -248,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: '', // 区域名称
@@ -281,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)
@@ -305,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)
@@ -312,8 +323,6 @@
let deviceRangeRenderToken = 0
let deviceListTimer = null
let deviceListRequestToken = 0
-let policeStationListTimer = null
-let policeStationRequestToken = 0
const rules = {
areaName: fieldRules(true, 50),
@@ -420,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
@@ -430,6 +439,7 @@
hideTypePanel()
clearShapeDisplay()
clearDeviceRangePrimitives()
+ clearDeviceIconEntities()
}
}
)
@@ -444,7 +454,6 @@
() => {
if (isDialogInitializing.value) return
queueDeviceListRefresh()
- queuePoliceStationRefresh()
},
{ deep: true }
)
@@ -498,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) {
@@ -598,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
@@ -619,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)
@@ -627,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
@@ -664,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) {
@@ -870,7 +912,8 @@
}
// 绘制完成回调
-const drawFinished = async data => {
+const drawFinished = async (data, options = {}) => {
+ const shouldContinueDraw = options?.continueDraw || activeToolMode.value === 'draw'
const positions = Array.isArray(data?.positions) ? data.positions : data
if (!Array.isArray(positions) || positions.length < 3) {
pointList = []
@@ -949,6 +992,12 @@
shapeList.value.splice(targetIndex, 1, shapePayload)
}
renderShapeList()
+ if (shouldContinueDraw && !readonly.value) {
+ activeShapeId.value = null
+ pointList = []
+ clearActiveTool()
+ startDraw(currentShapeType.value || 'polygon')
+ }
}
function getDetectAreaTypeKey () {
@@ -1049,11 +1098,13 @@
const positions = activeTool?.getPositions?.()
if (Array.isArray(positions) && positions.length >= 3) {
suppressTypePanelOnce.value = true
- drawFinished(positions)
+ drawFinished(positions, { continueDraw: true })
+ return
}
if (positions?.positions?.length >= 3) {
suppressTypePanelOnce.value = true
- drawFinished(positions)
+ drawFinished(positions, { continueDraw: true })
+ return
}
clearActiveTool()
}
@@ -1123,15 +1174,17 @@
function handleClearShape () {
if (readonly.value) return
- clearActiveTool()
viewEntity && viewer?.entities?.remove(viewEntity)
viewEntity = null
pointList = []
shapeList.value = []
activeShapeId.value = null
- activeAreaType.value = ''
hideTypePanel()
clearShapeDisplay()
+ clearActiveTool()
+ if (viewer && currentShapeType.value) {
+ startDraw(currentShapeType.value)
+ }
}
function handleShapeEdit (row) {
@@ -1188,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)
}
// 获取设备列表
@@ -1242,6 +1304,7 @@
deviceListRequestToken += 1
const requestToken = deviceListRequestToken
const res = await fwDeviceListByPolygonsApi({
+ areaId: dialogMode.value === 'add' ? '' : formData.value.id,
isAreaSelect: 1,
isTrack: 1,
polygons,
@@ -1321,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 = ''
@@ -1329,15 +1398,33 @@
initMap()
clearShapeDisplay()
clearDeviceRangePrimitives()
+ clearDeviceIconEntities()
viewEntity && viewer?.entities?.remove(viewEntity)
viewEntity = null
clearActiveTool()
if (dialogMode.value === 'add') {
mapRef.value?.zoomToAdminBoundary?.()
- // default no draw mode
+ handleDraw('polygon')
} else if (dialogMode.value === 'edit') {
await loadDetail()
viewPolygon()
+ activeShapeId.value = null
+ pointList = []
+ const firstShape = shapeList.value[0]
+ const initialType = firstShape?.drawType || 'polygon'
+ currentShapeType.value = initialType
+ if (initialType === 'buffer') {
+ activeAreaType.value = bufferAreaTypeValue.split(',')
+ } else if (firstShape?.areaType) {
+ activeAreaType.value = firstShape.areaType
+ } else {
+ const defaultAreaType = getDetectAreaTypeKey()
+ if (defaultAreaType) {
+ activeAreaType.value = defaultAreaType
+ }
+ }
+ clearActiveTool()
+ startDraw(initialType)
} else {
await loadDetail()
viewPolygon()
@@ -1353,7 +1440,7 @@
}
isDialogInitializing.value = false
queueDeviceListRefresh()
- queuePoliceStationRefresh()
+ void getPoliceStationList()
}
onBeforeUnmount(() => {
@@ -1361,9 +1448,9 @@
clearTimeout(deviceListTimer)
deviceListTimer = null
}
- if (policeStationListTimer) {
- clearTimeout(policeStationListTimer)
- policeStationListTimer = null
+ if (policeStationSearchTimer.value) {
+ clearTimeout(policeStationSearchTimer.value)
+ policeStationSearchTimer.value = null
}
hideTypePanel()
})
@@ -1426,44 +1513,31 @@
right: 16px;
display: flex;
flex-direction: column;
- gap: 10px;
- padding: 10px 8px;
- background: rgba(19, 28, 36, 0.75);
+ gap: 14px;
+ padding: 32px 14px;
+ background: rgba(26, 25, 25, 0.6);
+ border-radius: 8px 8px 8px 8px;
backdrop-filter: blur(4px);
- border-radius: 8px;
- box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
}
.tool-btn {
- padding: 0;
+ padding: 0 !important;
+ width: 46px;
+ height: 46px;
display: flex;
flex-direction: column;
align-items: center;
- gap: 6px;
- background: rgba(255, 255, 255, 0.08);
- border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: 8px;
- color: #ffffff;
- font-size: 12px;
- line-height: 1;
+ border: none !important;
+ box-shadow: none;
cursor: pointer;
- transition: all 0.2s ease;
overflow: hidden;
+ background: transparent !important;
+ box-sizing: border-box;
}
-.tool-btn:hover {
- background: rgba(255, 255, 255, 0.16);
- border-color: rgba(255, 255, 255, 0.35);
- transform: translateY(-1px);
-}
-
-.tool-btn:active {
- transform: translateY(0);
-}
-
-.tool-btn.danger {
- border-color: rgba(255, 112, 112, 0.6);
- color: #ffb3b3;
+.tool-btn.active {
+ border: 2px solid #FFFFFF !important;
}
.tool-icon {
@@ -1471,8 +1545,8 @@
}
.tool-icon-image {
- width: 36px;
- height: 36px;
+ width: 100%;
+ height: 100%;
}
.tool-icon.polygon {
--
Gitblit v1.9.3