From b0daa0c145ff5455de8aacf5a892e84b6d88b462 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Sat, 07 Feb 2026 16:49:24 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/utils/cesium/shapeTools/draw/DrawPolygonTool.js | 11 +++--
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue | 67 +++++++++++++++++----------------
AGENTS.md | 13 ++++++
applications/drone-command/src/components/map-container/device-map-container.vue | 7 ++-
applications/drone-command/src/components/map-container/components/DronePopup.vue | 3 -
5 files changed, 60 insertions(+), 41 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index fb53b8d..c422872 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -36,3 +36,16 @@
## 环境与配置
- Node.js >= 20,pnpm >= 9。
- 优先使用根目录工作区脚本,除非必要不要在子目录直接运行脚本。
+
+# AI Rules / AI行为规范
+
+- 对低风险修改,AI可自主执行,无需批准。
+ AI may proceed autonomously for low-risk changes.
+- 仅当修改可能影响架构、核心模块、公共接口、数据结构或安全性时,才需要请求批准。
+ Ask for approval only for high-impact changes.
+- 若问题不影响系统正确性,应自行做出合理决策,而不是提问。
+ DO NOT ask questions that do not affect correctness.
+- 优先最小化修改范围。
+ Prefer minimal changes.
+- 未被明确要求时,禁止大规模重构。
+ Avoid large refactors unless requested.
diff --git a/applications/drone-command/src/components/map-container/components/DronePopup.vue b/applications/drone-command/src/components/map-container/components/DronePopup.vue
index 759e748..316f279 100644
--- a/applications/drone-command/src/components/map-container/components/DronePopup.vue
+++ b/applications/drone-command/src/components/map-container/components/DronePopup.vue
@@ -127,8 +127,7 @@
const num = Number(value)
if (!Number.isFinite(num)) return '-'
const absVal = Math.abs(num).toFixed(6)
- const dir = type === 'lng' ? (num >= 0 ? 'E' : 'W') : num >= 0 ? 'N' : 'S'
- return `${absVal} ${dir}`
+ return `${absVal}`
}
const height = computed(() => formatNumber(props.drone?.flightHeightM, 'm', 0))
diff --git a/applications/drone-command/src/components/map-container/device-map-container.vue b/applications/drone-command/src/components/map-container/device-map-container.vue
index 0e37663..6f48e5a 100644
--- a/applications/drone-command/src/components/map-container/device-map-container.vue
+++ b/applications/drone-command/src/components/map-container/device-map-container.vue
@@ -77,6 +77,7 @@
const DETAIL_HEIGHT = 10000
const POLYGON_HEIGHT_M = 0.2
const DRONE_TRACK_DURATION_S = 30 * 60
+const FIXED_DRONE_TRACK_IDS = ['6000000000602', '6000000000601']
const props = defineProps({
allDevices: {
@@ -718,7 +719,9 @@
droneTrackPolylineCollection.show = detailVisible.value
droneTrackRuntime = []
const baseTrackColor = Cesium.Color.fromCssColorString('red')
- ; (list || []).forEach((item, trackIndex) => {
+ ; (FIXED_DRONE_TRACK_IDS || []).forEach((trackId, trackIndex) => {
+ const item = (list || []).find(entry => String(entry?.id) === String(trackId))
+ if (!item) return
const position = getDevicePosition(item)
if (!position) return
const points = buildSimulatedTrackPoints({ ...position, height: item.flightHeightM, trackIndex })
@@ -742,7 +745,7 @@
width: 3,
material: trackMaterial,
})
- const droneId = `drone-alarm-${item?.alarmRecordId ?? item?.id ?? trackIndex}`
+ const droneId = `drone-alarm-${trackId}`
const startTime = viewer.clock.startTime
const stopTime = viewer.clock.stopTime
const positionProperty = new Cesium.SampledPositionProperty()
diff --git a/applications/drone-command/src/utils/cesium/shapeTools/draw/DrawPolygonTool.js b/applications/drone-command/src/utils/cesium/shapeTools/draw/DrawPolygonTool.js
index 7df67da..207ad4e 100644
--- a/applications/drone-command/src/utils/cesium/shapeTools/draw/DrawPolygonTool.js
+++ b/applications/drone-command/src/utils/cesium/shapeTools/draw/DrawPolygonTool.js
@@ -91,6 +91,9 @@
}
start() {
+ if (!this.tooltip) {
+ this.tooltip = new MapTooltip(this.viewer)
+ }
this.dataSource = new Cesium.CustomDataSource('draw-polygon')
this.viewer.dataSources.add(this.dataSource)
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
@@ -139,10 +142,10 @@
if (!this.isDrawing) return
const tipText = this.getTipText()
if (!this.tooltip?.isVisible) {
- this.tooltip.show(tipText, movement.endPosition)
+ this.tooltip?.show(tipText, movement.endPosition)
} else {
- this.tooltip.show(tipText)
- this.tooltip.move(movement.endPosition)
+ this.tooltip?.show(tipText)
+ this.tooltip?.move(movement.endPosition)
}
if (this.positions.length === 0) return
const position = this.getPositionFromScreen(movement.endPosition)
@@ -283,7 +286,7 @@
this.floatPosition = null
this.isIntersecting = false
this.notify('getPolygonPositions', this.positions)
- this.tooltip.hide()
+ this.tooltip?.hide()
this.clearPreviewEntities()
}
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 0d7cb25..de30c67 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -97,7 +97,7 @@
<div class="detail-title">绘制区域列表</div>
<div class="command-table-container">
<div class="command-table-content">
- <el-table class="command-table" :data="shapeList" row-key="id">
+ <el-table class="command-table" :data="shapeList" row-key="id" height="240">
<el-table-column prop="areaType" label="区域类型">
<template v-slot="{ row }">
{{ resolveShapeAreaTypeLabel(row) }}
@@ -116,7 +116,7 @@
<div class="command-table-container">
<div class="command-table-content">
<el-table class="command-table" ref="deviceTableRef" :data="deviceOptions" row-key="id"
- @row-click="handleDeviceRowClick">
+ @row-click="handleDeviceRowClick" height="240">
<el-table-column prop="deviceName" label="设备名称" />
<el-table-column prop="deviceType" label="类型">
<template v-slot="{ row }">
@@ -169,7 +169,7 @@
<div class="shape-table-container">
<div class="shape-table-title">绘制区域列表</div>
- <el-table class="command-table" :data="shapeList" row-key="id" height="auto">
+ <el-table class="command-table" :data="shapeList" row-key="id" height="240">
<el-table-column prop="areaType" label="区域类型">
<template v-slot="{ row }">
{{ resolveShapeAreaTypeLabel(row) }}
@@ -201,7 +201,7 @@
<el-form-item prop="deviceIds" label-width="0">
<el-table class="command-table" ref="deviceTableRef"
:data="deviceOptions.filter(item => item.deviceName.includes(searchName))" row-key="id"
- @selection-change="handleDeviceSelectionChange" @row-click="handleDeviceRowClick">
+ @selection-change="handleDeviceSelectionChange" @row-click="handleDeviceRowClick" height="240">
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column prop="deviceName" label="设备名称" />
<el-table-column prop="deviceType" label="类型">
@@ -323,6 +323,7 @@
let deviceRangeRenderToken = 0
let deviceListTimer = null
let deviceListRequestToken = 0
+let deviceMapRequestToken = 0
const rules = {
areaName: fieldRules(true, 50),
@@ -519,8 +520,6 @@
deviceOptions.value = []
selectedDeviceRows.value = []
formData.value.deviceIds = ''
- clearDeviceRangePrimitives()
- clearDeviceIconEntities()
if (deviceTableRef.value) {
deviceTableRef.value.clearSelection()
}
@@ -661,20 +660,6 @@
if (wkt) polygons.push(wkt)
})
return polygons
-}
-
-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
- deviceRangePrimitiveMap.set(String(device?.id ?? Date.now()), primitive)
- viewer.scene.primitives.add(primitive)
}
async function renderDeviceRanges (rows) {
@@ -1384,9 +1369,29 @@
suppressDeviceFly.value = true
syncDeviceSelection()
suppressDeviceFly.value = prevSuppressDeviceFly
- if (!readonly.value) {
- renderDeviceRanges(selectedDeviceRows.value)
+ if (readonly.value) {
+ await renderDeviceRanges(deviceOptions.value)
}
+}
+
+// 设备上图(新增/编辑用)
+async function getDeviceListForMapDisplay () {
+ if (!visible.value || !viewer) return
+ deviceMapRequestToken += 1
+ const requestToken = deviceMapRequestToken
+ const res = await fwDeviceListByPolygonsApi({
+ areaId: dialogMode.value === 'add' ? '' : formData.value.id,
+ isAreaSelect: 1,
+ isTrack: 1,
+ })
+ if (requestToken !== deviceMapRequestToken) return
+ const list = res?.data?.data ?? []
+ if (!list.length) {
+ clearDeviceRangePrimitives()
+ clearDeviceIconEntities()
+ return
+ }
+ await renderDeviceRanges(list)
}
// 关联设备变更
@@ -1394,7 +1399,6 @@
selectedDeviceRows.value = rows
const ids = rows.map(item => item.id)
formData.value.deviceIds = ids.join(',')
- renderDeviceRanges(rows)
if (suppressDeviceFly.value) {
lastSelectedDeviceIds = [...ids]
return
@@ -1409,12 +1413,13 @@
function handleDeviceRowClick (row) {
if (readonly.value) {
- renderDeviceRangeSingle(row)
void flyToDevice(row)
return
}
- renderDeviceRanges(selectedDeviceRows.value)
- void flyToDevice(row)
+ const isSelected = selectedDeviceRows.value.some(item => String(item?.id) === String(row?.id))
+ if (isSelected) {
+ void flyToDevice(row)
+ }
}
// 同步选择状态
@@ -1429,10 +1434,6 @@
})
selectedDeviceRows.value = rows
formData.value.deviceIds = rows.map(item => item.id).join(',')
- if (readonly.value) {
- renderDeviceRanges(selectedDeviceRows.value)
- return
- }
if (!deviceTableRef.value) return
deviceTableRef.value.clearSelection()
rows.forEach(row => {
@@ -1499,11 +1500,11 @@
lastSelectedDeviceIds = selectedDeviceRows.value.map(row => row.id)
await nextTick()
suppressDeviceFly.value = false
- if (!readonly.value) {
- renderDeviceRanges(selectedDeviceRows.value)
- }
isDialogInitializing.value = false
queueDeviceListRefresh()
+ if (dialogMode.value === 'add' || dialogMode.value === 'edit') {
+ void getDeviceListForMapDisplay()
+ }
void getPoliceStationList()
}
--
Gitblit v1.9.3