From 7319ec49da9f1490ad35f47e0da62546d1cc7ff4 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Tue, 27 Jan 2026 18:05:34 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue                 |    2 
 uniapps/work-wx/src/pages/equipmentManagement/index.vue                                              |    6 
 applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue             |    2 
 applications/task-work-order/src/views/orderView/organizational/zoningManagement/FormDiaLog.vue      |  316 +++++++++
 uniapps/work-wx/src/subPackages/flightApplication/index.vue                                          |    2 
 applications/drone-command/src/views/permissionManage/permissionRole/index.vue                       |    4 
 applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue           |  337 ++++++++++
 applications/drone-command/src/utils/cesium/DrawPolygon.js                                           |   24 
 applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue                             |   13 
 applications/drone-command/src/components/map-container/device-map-container.vue                     |  343 +++++++--
 applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue |    2 
 applications/drone-command/src/views/permissionManage/permissionDept/FormDiaLog.vue                  |   31 
 applications/task-work-order/src/styles/common/cockpit.scss                                          |   24 
 uniapps/work-wx/src/subPackages/deviceRegistration/details.vue                                       |   54 
 applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue        |   58 -
 applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue                        |   35 
 applications/task-work-order/src/views/orderView/flyingHand/FlyingHandDialog.vue                     |   36 
 applications/task-work-order/src/views/orderView/organizational/agenciesManagement/FormDiaLog.vue    |   98 ++
 applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue         |   30 
 applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue                  |    2 
 applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue             |    4 
 uniapps/work-wx/src/subPackages/deviceRegistration/add.vue                                           |    1 
 uniapps/work-wx/src/subPackages/flightApplication/add.vue                                            |   13 
 uniapps/work-wx/src/subPackages/flightApplication/details.vue                                        |   52 
 applications/drone-command/src/views/dataCockpit/index.vue                                           |  113 +++
 uniapps/work-wx/src/pages/legalPolicy/index.vue                                                      |    7 
 applications/task-work-order/src/views/orderView/organizational/zoningManagement/zoningApi.js        |   66 ++
 applications/drone-command/src/views/dataCockpit/components/RealWarning.vue                          |  130 ---
 applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue                          |   57 +
 applications/drone-command/src/views/areaManage/partition/index.vue                                  |    9 
 uniapps/work-app/src/subPackages/workDetail/index.vue                                                |    8 
 31 files changed, 1,414 insertions(+), 465 deletions(-)

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 49bd52b..f7fb7e9 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
@@ -39,7 +39,7 @@
 			@close="closePopup" />
 
 		<DronePopup :visible="popupVisible && isDronePopup" :position="popupPosition" :drone="selectedDevice"
-			:favorite="Boolean(selectedDevice?.isFavorite)" @close="closePopup" @toggle-favorite="toggleDroneFavorite"
+			:favorite="Boolean(selectedDevice?.isFavorite)" @close="closePopup" @toggle-favorite="handleDroneFavorite"
 			@signal="handleDroneSignal" @counter="handleDroneCounter" />
 	</div>
 </template>
@@ -78,6 +78,10 @@
 		type: Array,
 		default: () => [],
 	},
+	alarmDrones: {
+		type: Array,
+		default: () => [],
+	},
 	leftCollapsed: {
 		type: Boolean,
 		default: false,
@@ -91,7 +95,7 @@
 		default: true,
 	},
 })
-const emit = defineEmits(['droneSignal', 'droneCounter'])
+const emit = defineEmits(['droneSignal', 'droneCounter', 'droneFavorite'])
 
 const DEFAULT_ZONE_PAGE_SIZE = 999
 
@@ -115,6 +119,14 @@
 let droneTrackTickHandler = null
 let droneTrackStartTime = null
 let droneTrackRuntime = []
+let favoritePulseRafId = null
+let favoritePulseStartAt = 0
+let favoritePulseElapsed = 0
+const favoritePulseEntities = []
+const pulseBaseColor = Cesium.Color.fromCssColorString('#FF3B30')
+const PULSE_MIN_RADIUS_M = 60
+const PULSE_MAX_RADIUS_M = 180
+const PULSE_DURATION_S = 1.6
 const detailVisible = ref(true)
 const clusterVisible = ref(false)
 const countyCenterMap = new Map()
@@ -168,6 +180,57 @@
  */
 
 const adminBoundaryVisible = ref(treeCheckedKeys.value.includes('admin'))
+
+const isFavorited = item => {
+	const value = item?.favorited ?? item?.isFavorite
+	return value === 1 || value === '1' || value === true
+}
+
+let pulseCanvas = null
+const getPulseCanvas = () => {
+	if (pulseCanvas) return pulseCanvas
+	const size = 256
+	const canvas = document.createElement('canvas')
+	canvas.width = size
+	canvas.height = size
+	const ctx = canvas.getContext('2d')
+	const center = size / 2
+	const radius = center - 2
+	const gradient = ctx.createRadialGradient(center, center, radius * 0.1, center, center, radius)
+	gradient.addColorStop(0, 'rgba(255,59,48,0.55)')
+	gradient.addColorStop(0.35, 'rgba(255,59,48,0.35)')
+	gradient.addColorStop(0.7, 'rgba(255,59,48,0.15)')
+	gradient.addColorStop(1, 'rgba(255,59,48,0)')
+	ctx.fillStyle = gradient
+	ctx.beginPath()
+	ctx.arc(center, center, radius, 0, Math.PI * 2)
+	ctx.fill()
+	pulseCanvas = canvas
+	return canvas
+}
+
+const createFavoritePulseEntity = (billboard) => {
+	if (!viewer || !billboard) return
+	const material = new Cesium.ImageMaterialProperty({
+		image: getPulseCanvas(),
+		transparent: true,
+	})
+	const pulse = {
+		material,
+		offset: Math.random() * PULSE_DURATION_S,
+		entity: null,
+	}
+	pulse.entity = viewer.entities.add({
+		position: new Cesium.CallbackProperty(() => billboard.position, false),
+		ellipse: {
+			semiMajorAxis: new Cesium.CallbackProperty(() => getPulseRadius(pulse), false),
+			semiMinorAxis: new Cesium.CallbackProperty(() => getPulseRadius(pulse), false),
+			material,
+			heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+		},
+	})
+	favoritePulseEntities.push(pulse)
+}
 
 const getDevicePosition = item => {
 	const longitudeRaw = item.longitude ?? item.lng ?? item.lon
@@ -307,6 +370,12 @@
 	}
 }
 
+const getPulseRadius = pulse => {
+	const phase = ((favoritePulseElapsed + pulse.offset) % PULSE_DURATION_S) / PULSE_DURATION_S
+	const wave = phase < 0.5 ? phase * 2 : (1 - phase) * 2
+	return PULSE_MIN_RADIUS_M + (PULSE_MAX_RADIUS_M - PULSE_MIN_RADIUS_M) * wave
+}
+
 const setDetailVisibility = visible => {
 	detailVisible.value = visible
 	if (defenseZonePrimitive) defenseZonePrimitive.show = visible
@@ -341,6 +410,11 @@
 const setDroneVisibility = visible => {
 	if (droneTrackBillboardCollection) droneTrackBillboardCollection.show = visible
 	if (droneTrackPolylineCollection) droneTrackPolylineCollection.show = visible
+	if (favoritePulseEntities.length) {
+		favoritePulseEntities.forEach(pulse => {
+			if (pulse?.entity) pulse.entity.show = visible
+		})
+	}
 	if (!visible && selectedTargetType.value === 'drone') {
 		closePopup()
 	}
@@ -363,50 +437,93 @@
 	})
 }
 
-const buildSimulatedTrackPoints = () => {
-	return [
-		{
-			longitude: 114.963191,
-			latitude: 27.136716,
-			height: 120
-		},
-		{
-			longitude: 114.957308,
-			latitude: 27.138452,
-			height: 120
-		},
-		{
-			longitude: 114.952,
-			latitude: 27.136317,
-			height: 120
-		},
-		{
-			longitude: 114.949293,
-			latitude: 27.133864,
-			height: 120
-		},
-		{
-			longitude: 114.944666,
-			latitude: 27.130526,
-			height: 120
-		},
-		{
-			longitude: 114.945909,
-			latitude: 27.127845,
-			height: 120
-		},
-		{
-			longitude: 114.962974,
-			latitude: 27.136242,
-			height: 120
-		},
+const buildSimulatedTrackPoints = center => {
+	const basePoints = [
+		[
+			{
+				longitude: 114.963191,
+				latitude: 27.136716,
+				height: 120
+			},
+			{
+				longitude: 114.957308,
+				latitude: 27.138452,
+				height: 120
+			},
+			{
+				longitude: 114.952,
+				latitude: 27.136317,
+				height: 120
+			},
+			{
+				longitude: 114.949293,
+				latitude: 27.133864,
+				height: 120
+			},
+			{
+				longitude: 114.944666,
+				latitude: 27.130526,
+				height: 120
+			},
+			{
+				longitude: 114.945909,
+				latitude: 27.127845,
+				height: 120
+			},
+			{
+				longitude: 114.962974,
+				latitude: 27.136242,
+				height: 120
+			},
+		],
+
+		[
+			{
+				longitude: 114.931063,
+				latitude: 27.095052,
+				height: 120
+			},
+			{
+				longitude: 114.928653,
+				latitude: 27.096307,
+				height: 120
+			},
+			{
+				longitude: 114.925958,
+				latitude: 27.096963,
+				height: 120
+			},
+			{
+				longitude: 114.925836, 
+				latitude: 27.096102,
+				height: 120
+			},
+			{
+				longitude: 114.928384, 
+				latitude: 27.095866,
+				height: 120
+			},
+			{
+				longitude: 114.929874, 
+				latitude: 27.096095,
+				height: 120
+			},
+			{
+				longitude: 114.931048, 
+				latitude: 27.097666,
+				height: 120
+			},
+		]
 	]
+
+	return basePoints[center.trackIndex]
 }
 
 
 const clearDroneTrackEntities = () => {
 	if (!viewer) return
 	stopDroneTrackAnimation()
+	stopFavoritePulseAnimation()
 	if (droneTrackBillboardCollection) {
 		if (!droneTrackBillboardCollection.isDestroyed?.()) {
 			removeCockpitPrimitive(droneTrackBillboardCollection)
@@ -420,6 +537,12 @@
 		droneTrackPolylineCollection = null
 	}
 	droneTrackRuntime = []
+	if (favoritePulseEntities.length) {
+		favoritePulseEntities.forEach(pulse => {
+			if (pulse?.entity) viewer?.entities?.remove(pulse.entity)
+		})
+		favoritePulseEntities.length = 0
+	}
 	dronePickMap.clear()
 	if (selectedTargetType.value === 'drone') {
 		closePopup()
@@ -486,72 +609,95 @@
 	droneTrackTickHandler = null
 }
 
-const renderSimulatedDroneTrack = () => {
+const startFavoritePulseAnimation = () => {
+	if (!viewer || favoritePulseRafId) return
+	favoritePulseStartAt = performance.now()
+	const tick = now => {
+		if (!viewer || viewer.isDestroyed?.() || !favoritePulseEntities.length) {
+			favoritePulseRafId = null
+			return
+		}
+		favoritePulseElapsed = (now - favoritePulseStartAt) / 1000
+		viewer.scene.requestRender()
+		favoritePulseRafId = requestAnimationFrame(tick)
+	}
+	favoritePulseRafId = requestAnimationFrame(tick)
+}
+
+const stopFavoritePulseAnimation = () => {
+	if (favoritePulseRafId) {
+		cancelAnimationFrame(favoritePulseRafId)
+		favoritePulseRafId = null
+	}
+}
+
+const renderSimulatedDroneTrack = (list) => {
 	if (!viewer) return
 	clearDroneTrackEntities()
+	if (!list?.length) return
 	ensureDroneTrackCollections()
 	droneTrackBillboardCollection.show = detailVisible.value
 	droneTrackPolylineCollection.show = detailVisible.value
 	droneTrackRuntime = []
-	const baseCenters = [['默认区域', { longitude: 114.958541, latitude: 27.121917 }]]
 	const segmentDuration = 6
 	const baseTrackColor = Cesium.Color.fromCssColorString('red')
-	baseCenters.forEach(([centerName, center], trackIndex) => {
-		const points = buildSimulatedTrackPoints(center)
-		if (points.length < 2) return
-		const positions = points.map(point =>
-			Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, point.height)
-		)
-		let trackMaterial = createDroneTrackMaterial({
-			color: baseTrackColor,
-			speed: 4.5,
-			headWidth: 0.2,
-			glowPower: 1.8,
-			backgroundAlpha: 0.34,
-		})
-		if (!trackMaterial) {
-			trackMaterial = Cesium.Material.fromType('Color', { color: baseTrackColor })
-		}
-		droneTrackPolylineCollection.add({
-			positions,
-			width: 3,
-			material: trackMaterial,
-		})
-		const droneId = `drone-track-${trackIndex}`
-		const billboard = droneTrackBillboardCollection.add({
-			position: positions[positions.length - 1],
-			image: droneIcon,
-			width: 36,
-			height: 36,
-			verticalOrigin: Cesium.VerticalOrigin.CENTER,
-			disableDepthTestDistance: Number.POSITIVE_INFINITY,
-		})
-		billboard.id = droneId
-		const speedMs = Math.round(Cesium.Cartesian3.distance(positions[0], positions[1]) / segmentDuration)
+		; (list || []).forEach((item, trackIndex) => {
+			const position = getDevicePosition(item)
+			if (!position) return
+			const points = buildSimulatedTrackPoints({ ...position, height: item.flightHeightM, trackIndex })
+			if (points.length < 2) return
+			const positions = points.map(point =>
+				Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, point.height)
+			)
+			let trackMaterial = createDroneTrackMaterial({
+				color: baseTrackColor,
+				speed: 4.5,
+				headWidth: 0.2,
+				glowPower: 1.8,
+				backgroundAlpha: 0.34,
+			})
+			if (!trackMaterial) {
+				trackMaterial = Cesium.Material.fromType('Color', { color: baseTrackColor })
+			}
+			droneTrackPolylineCollection.add({
+				positions,
+				width: 3,
+				material: trackMaterial,
+			})
+			const droneId = `drone-alarm-${item?.alarmRecordId ?? item?.id ?? trackIndex}`
+			const billboard = droneTrackBillboardCollection.add({
+				position: positions[positions.length - 1],
+				image: droneIcon,
+				width: 36,
+				height: 36,
+				verticalOrigin: Cesium.VerticalOrigin.CENTER,
+				disableDepthTestDistance: Number.POSITIVE_INFINITY,
+			})
+			billboard.id = droneId
+			const speedMs = Math.round(Cesium.Cartesian3.distance(positions[0], positions[1]) / segmentDuration)
 		dronePickMap.set(droneId, {
 			data: {
-				droneName: `无人机-${trackIndex + 1}`,
-				droneSerialNo: `UAV-${trackIndex + 1}`,
-				flightHeightM: points[0].height,
-				flightSpeedMs: speedMs,
-				longitude: points[0].longitude,
-				latitude: points[0].latitude,
-				flightStatus: 1,
-				deviceName: centerName,
-				dataSource: centerName,
-				counterDeviceName: centerName,
+				...item,
+				flightHeightM: item.flightHeightM ?? points[0].height,
+				flightSpeedMs: item.flightSpeedMs ?? speedMs,
+				longitude: item.longitude ?? points[0].longitude,
+				latitude: item.latitude ?? points[0].latitude,
 			},
 			billboard,
 		})
-		droneTrackRuntime.push({
-			positions,
-			billboard,
-			segmentDuration,
-			duration: (points.length - 1) * segmentDuration,
+		if (isFavorited(item)) {
+			createFavoritePulseEntity(billboard)
+		}
+			droneTrackRuntime.push({
+				positions,
+				billboard,
+				segmentDuration,
+				duration: (points.length - 1) * segmentDuration,
+			})
 		})
-	})
 	viewer.clock.multiplier = 1
 	startDroneTrackAnimation()
+	startFavoritePulseAnimation()
 	reorderCockpitPrimitives()
 }
 
@@ -860,9 +1006,9 @@
 const popupPosition = ref({ x: 0, y: 0 })
 const popupVisible = computed(() => Boolean(selectedDevice.value))
 const isDronePopup = computed(() => selectedTargetType.value === 'drone')
-const toggleDroneFavorite = () => {
+const handleDroneFavorite = () => {
 	if (!selectedDevice.value) return
-	selectedDevice.value.isFavorite = !selectedDevice.value.isFavorite
+	emit('droneFavorite', selectedDevice.value)
 }
 const handleDroneSignal = () => emit('droneSignal', selectedDevice.value)
 const handleDroneCounter = () => emit('droneCounter', selectedDevice.value)
@@ -911,6 +1057,19 @@
 	() => props.onlineDevices,
 	devices => {
 		renderDeviceEntities(devices || [])
+	},
+	{ deep: true }
+)
+
+watch(
+	() => props.alarmDrones,
+	list => {
+		renderSimulatedDroneTrack(list || [])
+		if (selectedTargetType.value === 'drone' && selectedDevice.value) {
+			const selectedId = selectedDevice.value.alarmRecordId ?? selectedDevice.value.id
+			const match = (list || []).find(item => (item?.alarmRecordId ?? item?.id) === selectedId)
+			if (match) selectedDevice.value = { ...selectedDevice.value, ...match }
+		}
 	},
 	{ deep: true }
 )
@@ -970,7 +1129,7 @@
 	loadPartitions()
 	loadAggregation()
 	loadCommandPosts()
-	renderSimulatedDroneTrack()
+	renderSimulatedDroneTrack(props.alarmDrones)
 	initDeviceClickHandler()
 }
 
diff --git a/applications/drone-command/src/utils/cesium/DrawPolygon.js b/applications/drone-command/src/utils/cesium/DrawPolygon.js
index b7bc2c0..6bea7f4 100644
--- a/applications/drone-command/src/utils/cesium/DrawPolygon.js
+++ b/applications/drone-command/src/utils/cesium/DrawPolygon.js
@@ -715,7 +715,8 @@
 		this.initHandler(viewer)
 		this.isPureSpotPreview = isPurePreview
 		this.startDrawing()
-		let newPosition = positions.map(item => {
+		const normalizedPositions = this.normalizePolygonPositions(positions)
+		let newPosition = normalizedPositions.map(item => {
 			return Cesium.Cartesian3.fromDegrees(Number(item.lng), Number(item.lat), Number(item?.height || 0))
 		})
 		// 预览航线的时候调用
@@ -728,17 +729,14 @@
 		})
 
 		// 视角飞入区域
-		const newBox = boxTransformScale(
-			positions.map(item => [item.lng, item.lat]),
-			5
-		)
+		const newBox = boxTransformScale(normalizedPositions.map(item => [item.lng, item.lat]), 5)
 		viewer.camera.flyTo({
 			destination: Cesium.Rectangle.fromDegrees(...newBox),
 			offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90), 0),
 			duration: 0.5,
 		})
 
-		let pointList = await getPointPositionsHeight(positions, viewer)
+		let pointList = await getPointPositionsHeight(normalizedPositions, viewer)
 		flyVisual({ positionsData: pointList.map(item => [item.lng, item.lat, item.ASL]), viewer })
 
 		this.drawingMode = false
@@ -748,6 +746,20 @@
 		this.rebuildMidPoints()
 	}
 
+	// 规范化多边形点位:如果首尾重复,去掉末尾闭合点
+	normalizePolygonPositions(positions) {
+		if (!Array.isArray(positions) || positions.length < 2) return positions || []
+		const first = positions[0]
+		const last = positions[positions.length - 1]
+		const sameLng = Number(first?.lng) === Number(last?.lng)
+		const sameLat = Number(first?.lat) === Number(last?.lat)
+		const sameHeight = Number(first?.height || 0) === Number(last?.height || 0)
+		if (sameLng && sameLat && sameHeight) {
+			return positions.slice(0, -1)
+		}
+		return positions
+	}
+
 	// 初始化事件处理器
 	initHandler(viewer) {
 		this.viewer = viewer
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 0b2786e..8d4a069 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -42,7 +42,9 @@
 						</el-col>
 						<el-col :span="24">
 							<div class="label">触发条件</div>
-							<div class="val">{{ formData.triggerCondition }}</div>
+							<div class="val">
+								{{ getDictLabel(formData.triggerCondition, dictObj.triggeringCondition) }}
+							</div>
 						</el-col>
 						<el-col :span="24">
 							<div class="label">响应机制</div>
@@ -102,8 +104,11 @@
 							maxlength="200" placeholder="请输入" clearable />
 					</el-form-item>
 					<el-form-item label="触发条件" prop="triggerCondition">
-						<el-input class="command-input" v-model="formData.triggerCondition"
-							maxlength="200" placeholder="请输入" clearable />
+						<el-select class="command-select" popper-class="command-select-popper"
+							v-model="formData.triggerCondition" placeholder="请选择" clearable>
+							<el-option v-for="item in dictObj.triggeringCondition" :key="item.dictKey"
+								:label="item.dictValue" :value="item.dictKey" />
+						</el-select>
 					</el-form-item>
 					<el-form-item label="管控级别" prop="controlLevel">
 						<el-select class="command-select" popper-class="command-select-popper"
@@ -410,7 +415,7 @@
 // 获取设备列表
 async function getDeviceList () {
 	if (deviceOptions.value.length) return
-	const res = await fwDeviceListApi({ isAreaSelect: 1, areaId: formData.value.id })
+	const res = await fwDeviceListApi({ isAreaSelect: 1, areaId: formData.value.id, isTrack: 1 })
 	deviceOptions.value = res?.data?.data ?? []
 	if (dialogMode.value === 'view') {
 		deviceOptions.value = deviceOptions.value.filter(item => formData.value.deviceIds.includes(item.id))
diff --git a/applications/drone-command/src/views/areaManage/partition/index.vue b/applications/drone-command/src/views/areaManage/partition/index.vue
index c066bba..bd3f8ae 100644
--- a/applications/drone-command/src/views/areaManage/partition/index.vue
+++ b/applications/drone-command/src/views/areaManage/partition/index.vue
@@ -42,7 +42,11 @@
 							{{ getDictLabel(row.areaType, dictObj.areaType) }}
 						</template>
 					</el-table-column>
-					<el-table-column prop="triggerCondition" show-overflow-tooltip width="130" label="触发条件" />
+					<el-table-column prop="triggerCondition" show-overflow-tooltip width="130" label="触发条件">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.triggerCondition, dictObj.triggeringCondition) }}
+						</template>
+					</el-table-column>
 					<el-table-column prop="responseMechanism" show-overflow-tooltip width="130" label="响应机制" />
 					<el-table-column prop="controlLevel" show-overflow-tooltip width="120" label="管控级别">
 						<template v-slot="{ row }">
@@ -168,13 +172,14 @@
 const dictObj = ref({
 	areaType: [], //区域类型
 	controlLevel: [], //管控级别
+	triggeringCondition: [], //触发条件
 	deviceType: [],
 })
 provide('dictObj', dictObj)
 
 // 获取字典
 function getDictList() {
-	getDictionaryByCode('areaType,controlLevel,deviceType').then(res => {
+	getDictionaryByCode('areaType,controlLevel,deviceType,triggeringCondition').then(res => {
 		dictObj.value = res.data.data
 	})
 }
diff --git a/applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue b/applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue
index b570b0f..2e63d4d 100644
--- a/applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue
+++ b/applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue
@@ -62,15 +62,20 @@
 						<el-table-column prop="charger" label="负责人" />
 						<el-table-column prop="contactPhone" label="联系电话" />
 						<el-table-column prop="outTarget" label="出库去向" />
-						<el-table-column prop="outTime" label="出库时间" />
+
+						<el-table-column prop="outTime" show-overflow-tooltip label="出库时间">
+							<template v-slot="{ row }">
+								{{ dayjs(row.outTime).format('YYYY-MM-DD') }}
+							</template>
+						</el-table-column>
 						<el-table-column prop="purpose" label="用途" />
 					</el-table>
 				</div>
 
 				<div class="command-table-pagination">
-					<el-pagination popper-class="command-select-popper"
-						v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
-						layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+					<el-pagination popper-class="command-select-popper" v-model:current-page="searchParams.current"
+						v-model:page-size="searchParams.size" layout="total, prev, pager, next, sizes" :total="total"
+						@change="getList" />
 				</div>
 			</div>
 		</div>
@@ -79,8 +84,8 @@
 			<el-row>
 				<el-col :span="12">
 					<el-form-item label="设备名称" prop="deviceName">
-						<el-input class="command-input" v-model="formData.deviceName" maxlength="50"
-							placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.deviceName" maxlength="50" placeholder="请输入"
+							clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
@@ -94,8 +99,8 @@
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="设备编码" prop="deviceSn">
-						<el-input class="command-input" v-model="formData.deviceSn" maxlength="50"
-							placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.deviceSn" maxlength="50" placeholder="请输入"
+							clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
@@ -109,40 +114,39 @@
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="型号" prop="deviceModel">
-						<el-input class="command-input" v-model="formData.deviceModel" maxlength="50"
-							placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.deviceModel" maxlength="50" placeholder="请输入"
+							clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="规格" prop="deviceSpecification">
-						<el-input class="command-input" v-model="formData.deviceSpecification"
-							maxlength="50" placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.deviceSpecification" maxlength="50"
+							placeholder="请输入" clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="生产厂商" prop="manufacturer">
-						<el-input class="command-input" v-model="formData.manufacturer" maxlength="50"
-							placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.manufacturer" maxlength="50" placeholder="请输入"
+							clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="来源" prop="source">
-						<el-input class="command-input" v-model="formData.source" maxlength="50"
-							placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.source" maxlength="50" placeholder="请输入"
+							clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="用途" prop="purpose">
-						<el-input class="command-input" v-model="formData.purpose" maxlength="50"
-							placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.purpose" maxlength="50" placeholder="请输入"
+							clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="所属部门" prop="belongDept">
-						<el-tree-select class="command-select"
-							popper-class="command-tree-select-popper" v-model="formData.belongDept"
-							node-key="id" :data="deptTree" :props="treeProps" check-strictly @change="belongDeptChange"
-							clearable />
+						<el-tree-select class="command-select" popper-class="command-tree-select-popper"
+							v-model="formData.belongDept" node-key="id" :data="deptTree" :props="treeProps"
+							check-strictly @change="belongDeptChange" clearable />
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
@@ -155,14 +159,15 @@
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="联系电话" prop="contactPhone">
-						<el-input class="command-input" v-model="formData.contactPhone" maxlength="50"
-							placeholder="请输入" clearable />
+						<el-input class="command-input" v-model="formData.contactPhone" maxlength="50" placeholder="请输入"
+							clearable />
 					</el-form-item>
 				</el-col>
 			</el-row>
 		</el-form>
 		<template #footer>
-			<el-button v-if="dialogMode != 'view'" color="#2B2B4C" @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
+			<el-button v-if="dialogMode != 'view'" color="#2B2B4C" @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消'
+				}}</el-button>
 			<el-button color="#284FE3" v-if="!dialogReadonly" type="primary" :loading="submitting"
 				:disabled="submitting" @click="handleSubmit">
 				保存
@@ -172,6 +177,8 @@
 </template>
 
 <script setup>
+import dayjs from 'dayjs'
+
 import { computed, ref } from 'vue'
 import { ElMessage } from 'element-plus'
 import { fwDeviceDetailApi, fwDeviceSubmitApi } from '@/views/basicManage/deviceStock/fwDevice'
diff --git a/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue b/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
index 65c2764..a524faa 100644
--- a/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
+++ b/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
@@ -12,7 +12,16 @@
 			</div>
 
 			<div class="content">
-				<component :is="currentComponent" />
+				<RealWarning
+					v-if="activeIdModel === 1"
+					:data="realWarningData"
+					:loading="realWarningLoading"
+					@signal="emit('real-warning-signal', $event)"
+					@counter="emit('real-warning-counter', $event)"
+					@favorite="emit('real-warning-favorite', $event)"
+				/>
+				<EquipmentWarning v-else-if="activeIdModel === 2" />
+				<HistoryWarning v-else />
 			</div>
 		</div>
 
@@ -24,11 +33,11 @@
 
 <script setup>
 import TitleTemplate from './templateComponents/TitleTemplate.vue'
-import RealWarning from './RealWarning.vue'
 import EquipmentWarning from './EquipmentWarning.vue'
 import HistoryWarning from './HistoryWarning.vue'
 import { alarmStatisticsApi } from '@/api/dataCockpit'
-import { onMounted } from 'vue'
+import { computed, onMounted, ref } from 'vue'
+import RealWarning from './RealWarning.vue'
 
 const props = defineProps({
 	activeId: {
@@ -38,10 +47,24 @@
 	collapsed: {
 		type: Boolean,
 		default: false
+	},
+	realWarningData: {
+		type: Array,
+		default: () => []
+	},
+	realWarningLoading: {
+		type: Boolean,
+		default: false
 	}
 })
 
-const emit = defineEmits(['update:activeId', 'update:collapsed'])
+const emit = defineEmits([
+	'update:activeId',
+	'update:collapsed',
+	'real-warning-signal',
+	'real-warning-counter',
+	'real-warning-favorite'
+])
 
 const activeIdModel = computed({
 	get: () => props.activeId,
@@ -73,10 +96,6 @@
 		component: HistoryWarning
 	}
 ])
-
-const currentComponent = computed(() => {
-	return categoryList.value.find(i => i.id === activeIdModel.value)?.component
-})
 
 const toggleCollapse = () => {
 	collapsedModel.value = !collapsedModel.value
diff --git a/applications/drone-command/src/views/dataCockpit/components/RealWarning.vue b/applications/drone-command/src/views/dataCockpit/components/RealWarning.vue
index 132e7a2..09d99e6 100644
--- a/applications/drone-command/src/views/dataCockpit/components/RealWarning.vue
+++ b/applications/drone-command/src/views/dataCockpit/components/RealWarning.vue
@@ -2,137 +2,39 @@
  * @Author       : yuan
  * @Date         : 2026-01-08 09:29:07
  * @LastEditors  : yuan
- * @LastEditTime : 2026-01-26 09:59:52
+ * @LastEditTime : 2026-01-27 14:49:56
  * @FilePath     : \applications\drone-command\src\views\dataCockpit\components\RealWarning.vue
  * @Description  : 
  * Copyright 2026 OBKoro1, All Rights Reserved. 
  * 2026-01-08 09:29:07
 -->
 <template>
-	<div
-		class="real-warning"
-		v-loading="loading"
-		element-loading-background="rgba(5, 5, 15, 0.6)"
-		element-loading-text="加载中..."
-	>
+	<div class="real-warning" v-loading="props.loading" element-loading-background="rgba(5, 5, 15, 0.6)"
+		element-loading-text="加载中...">
 		<div class="list-content">
-			<EmptyState v-if="!realWarningData.length" />
-			<RealTemplate
-				v-else
-				v-for="(item, ind) in realWarningData"
-				:key="ind"
-				:data="item"
-				@signal="() => handleAction('signal', item)"
-				@counter="() => handleAction('counter', item)"
-				@favorite="() => handleFavorite(item)"
-			/>
+			<EmptyState v-if="!props.data.length && !props.loading" />
+			<RealTemplate v-else v-for="(item, ind) in props.data" :key="ind" :data="item"
+				@signal="emit('signal', item)" @counter="emit('counter', item)" @favorite="emit('favorite', item)" />
 		</div>
 	</div>
 </template>
 
 <script setup>
 import RealTemplate from './templateComponents/RealTemplate.vue'
-import {
-	alarmLogApi,
-	alarmFavoriteRemoveApi,
-	alarmFavoriteSaveApi,
-	interferenceAndExpulsionApi
-} from '@/api/dataCockpit'
-import { onMounted, ref } from 'vue'
 import EmptyState from './EmptyState.vue'
-import { ElMessage } from 'element-plus'
 
-const realWarningData = ref([])
-const loading = ref(true)
-const minLoadingMs = 400
-
-const actionTextMap = {
-	signal: '信号干扰',
-	counter: '诱导驱离'
-}
-
-
-const getAlarmRecordId = (item) => item?.alarmRecordId ?? item?.id
-const getFavoriteId = (item) =>
-	item?.favoriteId ??
-	item?.alarmFavoriteId ??
-	item?.fwAlarmFavoriteId ??
-	item?.favoriteRecordId ??
-	getAlarmRecordId(item)
-
-const isFavorited = (item) => {
-	const value = item?.favorited ?? item?.isFavorite
-	return value === 1 || value === '1' || value === true
-}
-
-const buildPayload = (type, item) => ({
-	counterWay: type === 'signal' ? 1 : type === 'counter' ? 2 : '',
-	alarmRecordId: getAlarmRecordId(item)
+const props = defineProps({
+	data: {
+		type: Array,
+		default: () => []
+	},
+	loading: {
+		type: Boolean,
+		default: false
+	}
 })
 
-const handleAction = async (type, item) => {
-	const actionText = actionTextMap[type] || '操作'
-	try {
-		const res = await interferenceAndExpulsionApi(buildPayload(type, item))
-		if (res?.data?.success) {
-			ElMessage({ type: 'success', message: actionText + '成功' })
-			await fetchRealWarning()
-		} else {
-			ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' })
-		}
-	} catch (error) {
-		ElMessage({ type: 'error', message: actionText + '失败' })
-	}
-}
-
-const handleFavorite = async (item) => {
-	const alarmRecordId = getAlarmRecordId(item)
-	if (!alarmRecordId) {
-		ElMessage({ type: 'warning', message: '缺少告警记录ID' })
-		return
-	}
-	const isFavorite = isFavorited(item)
-	const actionText = isFavorite ? '取消关注' : '关注'
-	try {
-		const res = isFavorite
-			? await alarmFavoriteRemoveApi(getFavoriteId(item))
-			: await alarmFavoriteSaveApi({ alarmRecordId })
-		if (res?.data?.success) {
-			ElMessage({ type: 'success', message: actionText + '成功' })
-			await fetchRealWarning()
-		} else {
-			ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' })
-		}
-	} catch (error) {
-		ElMessage({ type: 'error', message: actionText + '失败' })
-	}
-}
-
-const fetchRealWarning = async () => {
-	const startAt = Date.now()
-	loading.value = true
-	try {
-		const params = { current: 1, size: 20, alarmType: '1' }
-		const res = await alarmLogApi(params)
-		const records = res?.data?.data?.records ?? []
-		realWarningData.value = records.map((record) => ({
-			...record,
-			isFavorite:
-				record?.isFavorite ??
-				(record?.favorited === 1 || record?.favorited === '1')
-		}))
-	} finally {
-		const elapsed = Date.now() - startAt
-		if (elapsed < minLoadingMs) {
-			await new Promise((resolve) => setTimeout(resolve, minLoadingMs - elapsed))
-		}
-		loading.value = false
-	}
-}
-
-onMounted(() => {
-	fetchRealWarning()
-})
+const emit = defineEmits(['signal', 'counter', 'favorite'])
 </script>
 
 <style lang="scss" scoped>
diff --git a/applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue b/applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue
index 7b09cfb..27afb8a 100644
--- a/applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue
+++ b/applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue
@@ -48,7 +48,7 @@
 			<div class="row">
 				<div class="col">
 					<span class="label">有效范围</span>
-					{{ data.range }}
+					{{ Number(data.range).toFixed(0) }}m
 				</div>
 				<div class="col">
 					<span class="label">设备型号</span>
diff --git a/applications/drone-command/src/views/dataCockpit/index.vue b/applications/drone-command/src/views/dataCockpit/index.vue
index 7f44448..aafe0df 100644
--- a/applications/drone-command/src/views/dataCockpit/index.vue
+++ b/applications/drone-command/src/views/dataCockpit/index.vue
@@ -12,10 +12,23 @@
   <div class="page-container">
     <DeviceMapContainer
       :online-devices="onlineDevices"
+      :alarm-drones="realWarningData"
       :left-collapsed="leftCollapsed"
       container-id="data-cockpit-map"
+      @drone-signal="handleAlarmAction('signal', $event)"
+      @drone-counter="handleAlarmAction('counter', $event)"
+      @drone-favorite="handleAlarmFavorite"
     />  
-    <LeftContainer class="left-container" v-model:activeId="leftActiveId" v-model:collapsed="leftCollapsed" />  
+    <LeftContainer
+      class="left-container"
+      v-model:activeId="leftActiveId"
+      v-model:collapsed="leftCollapsed"
+      :real-warning-data="realWarningData"
+      :real-warning-loading="realWarningLoading"
+      @real-warning-signal="handleAlarmAction('signal', $event)"
+      @real-warning-counter="handleAlarmAction('counter', $event)"
+      @real-warning-favorite="handleAlarmFavorite"
+    />  
     <RightContainer class="right-container" v-model:collapsed="rightCollapsed" v-model:onlineDevices="onlineDevices" />  
     <CenterContainer @select-warning="onSelectWarning" @select-equipment="onSelectEquipment" />  
     <LegendBar class="legend-container" />
@@ -28,12 +41,23 @@
   import RightContainer from './components/RightContainer.vue';
   import CenterContainer from './components/CenterContainer.vue';
   import LegendBar from './components/LegendBar.vue';
+  import {
+    alarmLogApi,
+    alarmFavoriteRemoveApi,
+    alarmFavoriteSaveApi,
+    interferenceAndExpulsionApi
+  } from '@/api/dataCockpit';
+  import { ElMessage } from 'element-plus';
+  import { onMounted, ref } from 'vue';
 
   const leftActiveId = ref(1);
   const leftCollapsed = ref(false);
 
   const rightCollapsed = ref(false);
   const onlineDevices = ref([]);
+  const realWarningData = ref([]);
+  const realWarningLoading = ref(true);
+  const minLoadingMs = 400;
 
   const onSelectWarning = (type) => {
     leftActiveId.value = type;
@@ -43,6 +67,93 @@
   const onSelectEquipment = () => {
     rightCollapsed.value = false;
   };
+
+  const actionTextMap = {
+    signal: '信号干扰',
+    counter: '诱导驱离'
+  };
+
+  const getAlarmRecordId = (item) => item?.alarmRecordId ?? item?.id;
+  const getFavoriteId = (item) =>
+    item?.favoriteId ??
+    item?.alarmFavoriteId ??
+    item?.fwAlarmFavoriteId ??
+    item?.favoriteRecordId ??
+    getAlarmRecordId(item);
+
+  const isFavorited = (item) => {
+    const value = item?.favorited ?? item?.isFavorite;
+    return value === 1 || value === '1' || value === true;
+  };
+
+  const buildPayload = (type, item) => ({
+    counterWay: type === 'signal' ? 1 : type === 'counter' ? 2 : '',
+    alarmRecordId: getAlarmRecordId(item)
+  });
+
+  const handleAlarmAction = async (type, item) => {
+    const actionText = actionTextMap[type] || '操作';
+    try {
+      const res = await interferenceAndExpulsionApi(buildPayload(type, item));
+      if (res?.data?.success) {
+        ElMessage({ type: 'success', message: actionText + '成功' });
+        await fetchRealWarning();
+      } else {
+        ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' });
+      }
+    } catch (error) {
+      ElMessage({ type: 'error', message: actionText + '失败' });
+    }
+  };
+
+  const handleAlarmFavorite = async (item) => {
+    const alarmRecordId = getAlarmRecordId(item);
+    if (!alarmRecordId) {
+      ElMessage({ type: 'warning', message: '缺少告警记录ID' });
+      return;
+    }
+    const favorite = isFavorited(item);
+    const actionText = favorite ? '取消关注' : '关注';
+    try {
+      const res = favorite
+        ? await alarmFavoriteRemoveApi(getFavoriteId(item))
+        : await alarmFavoriteSaveApi({ alarmRecordId });
+      if (res?.data?.success) {
+        ElMessage({ type: 'success', message: actionText + '成功' });
+        await fetchRealWarning();
+      } else {
+        ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' });
+      }
+    } catch (error) {
+      ElMessage({ type: 'error', message: actionText + '失败' });
+    }
+  };
+
+  const fetchRealWarning = async () => {
+    const startAt = Date.now();
+    realWarningLoading.value = true;
+    try {
+      const params = { current: 1, size: 20, alarmType: '1' };
+      const res = await alarmLogApi(params);
+      const records = res?.data?.data?.records ?? [];
+      realWarningData.value = records.map((record) => ({
+        ...record,
+        isFavorite:
+          record?.isFavorite ??
+          (record?.favorited === 1 || record?.favorited === '1')
+      }));
+    } finally {
+      const elapsed = Date.now() - startAt;
+      if (elapsed < minLoadingMs) {
+        await new Promise((resolve) => setTimeout(resolve, minLoadingMs - elapsed));
+      }
+      realWarningLoading.value = false;
+    }
+  };
+
+  onMounted(() => {
+    fetchRealWarning();
+  });
 </script>
 
 <style scoped lang="scss">
diff --git a/applications/drone-command/src/views/permissionManage/permissionDept/FormDiaLog.vue b/applications/drone-command/src/views/permissionManage/permissionDept/FormDiaLog.vue
index 95955ad..37310d6 100644
--- a/applications/drone-command/src/views/permissionManage/permissionDept/FormDiaLog.vue
+++ b/applications/drone-command/src/views/permissionManage/permissionDept/FormDiaLog.vue
@@ -71,14 +71,14 @@
 				<el-col :span="12">
 					<el-form-item label="部门类型" prop="deptCategory">
 						<el-select class="command-select" popper-class="command-select-popper" v-model="formData.deptCategory" placeholder="请选择" clearable>
-							<el-option v-for="item in dictObj.org_category" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
+							<el-option v-for="item in dictObj.org_category" :key="item.dictKey" :label="item.dictValue" :value="Number(item.dictKey)" />
 						</el-select>
 					</el-form-item>
 				</el-col>
 				<el-col :span="12">
 					<el-form-item label="部门性质" prop="deptNature">
 						<el-select class="command-select" popper-class="command-select-popper" v-model="formData.deptNature" placeholder="请选择" clearable>
-							<el-option v-for="item in dictObj.org_nature" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
+							<el-option v-for="item in dictObj.org_nature" :key="item.dictKey" :label="item.dictValue" :value="Number(item.dictKey)" />
 						</el-select>
 					</el-form-item>
 				</el-col>
@@ -137,9 +137,9 @@
 	fullName: '',
 	parentId: '',
 	parentName: '',
-	deptCategory: '',
-	deptNature: '',
-	areaCode: '',
+	deptCategory: null,
+	deptNature: null,
+	areaCode: [],
 	areaName: '',
 	deploymentMode: 0,
 	sort: 0,
@@ -154,7 +154,7 @@
 const areaProps = {
 	label: 'title',
 	value: 'value',
-	emitPath: false,
+	emitPath: true,
 	checkStrictly: true,
 	lazy: true,
 	lazyLoad(node, resolve) {
@@ -230,19 +230,26 @@
 }
 
 function getFullAreaCode(areaCode) {
-	if (!areaCode) return ''
+	if (!areaCode) return []
+	if (Array.isArray(areaCode)) return areaCode
 	const code = areaCode.toString()
-	if (code.includes(',')) return code
+	if (code.includes(',')) return code.split(',')
 	if (code.endsWith('0000000000')) {
-		return code
+		return [code]
 	} else if (code.endsWith('00000000') && !code.endsWith('0000000000')) {
 		const provinceCode = code.substring(0, 2) + '0000000000'
-		return `${provinceCode},${code}`
+		return [provinceCode, code]
 	} else {
 		const provinceCode = code.substring(0, 2) + '0000000000'
 		const cityCode = code.substring(0, 4) + '00000000'
-		return `${provinceCode},${cityCode},${code}`
+		return [provinceCode, cityCode, code]
 	}
+}
+
+function normalizeNumber(value) {
+	if (value === '' || value === null || value === undefined) return null
+	const num = Number(value)
+	return Number.isNaN(num) ? null : num
 }
 
 function handleCancel() {
@@ -283,6 +290,8 @@
 	const data = res?.data?.data ?? {}
 	formData.value = {
 		...data,
+		deptCategory: normalizeNumber(data.deptCategory),
+		deptNature: normalizeNumber(data.deptNature),
 		areaCode: getFullAreaCode(data.areaCode),
 	}
 }
diff --git a/applications/drone-command/src/views/permissionManage/permissionRole/index.vue b/applications/drone-command/src/views/permissionManage/permissionRole/index.vue
index 726ec3c..421ff3d 100644
--- a/applications/drone-command/src/views/permissionManage/permissionRole/index.vue
+++ b/applications/drone-command/src/views/permissionManage/permissionRole/index.vue
@@ -36,7 +36,7 @@
 				color="#1A2652"
 				type="primary"
 				:disabled="selectedIds.length !== 1"
-				v-if="userInfo.role_name?.includes('admin')"
+				v-if="permission.permissionRole_set"
 				@click="handleRole"
 			>
 				权限设置
@@ -113,7 +113,7 @@
 const dialogRef = ref(null)
 const roleDialogRef = ref(null)
 const store = useStore()
-const userInfo = computed(() => store.getters.userInfo || {})
+const permission = computed(() => store.getters.permission || {})
 const route = useRoute()
 
 async function loadList() {
diff --git a/applications/task-work-order/src/styles/common/cockpit.scss b/applications/task-work-order/src/styles/common/cockpit.scss
index e84887a..3c10b27 100644
--- a/applications/task-work-order/src/styles/common/cockpit.scss
+++ b/applications/task-work-order/src/styles/common/cockpit.scss
@@ -475,6 +475,7 @@
     .detail-container {
       display: flex;
       justify-content: space-between;
+      height: 680px;
 
       .detail-left {
         margin-right: 20px;
@@ -484,16 +485,21 @@
       }
 
       .detail-right {
-        &>div {
-          .detail-title {
-            margin: 10px 0;
-          }
+        width: 920px;
+        flex: 1;
+        overflow: auto;
+        display: flex;
+        flex-direction: column;
 
-          &:first-child {
-            .detail-title {
-              margin-top: 0;
-            }
-          }
+        .view-container {
+          display: flex;
+          flex-direction: column;
+        }
+
+        .gd-cesium {
+          width: 100%;
+          min-height: 380px;
+          flex: 1;
         }
       }
     }
diff --git a/applications/task-work-order/src/views/orderView/flyingHand/FlyingHandDialog.vue b/applications/task-work-order/src/views/orderView/flyingHand/FlyingHandDialog.vue
index 4566740..d0cc686 100644
--- a/applications/task-work-order/src/views/orderView/flyingHand/FlyingHandDialog.vue
+++ b/applications/task-work-order/src/views/orderView/flyingHand/FlyingHandDialog.vue
@@ -199,7 +199,8 @@
 })
 
 const formRef = ref(null)
-const formData = reactive({
+
+const initForm = () => ({
 	flyerName: '',
 	flyerId: '',
 	flyerPhone: '',
@@ -208,7 +209,22 @@
 	technicalStrength: '',
 	skilledUavType: '',
 	certification: [], // 证书
+	regionCode: '', // 区域编码
 })
+
+const formData = ref(initForm()) // 表单数据
+
+
+// const rules = {
+// 	flyerId: fieldRules(true),
+// 	flyerPhone: fieldRules(true, 50),
+// 	flightHours: fieldRules(true, 50),
+// 	technicalSkills: fieldRules(true, 50),
+// 	skilledTaskType: fieldRules(true),
+// 	projectExperience: fieldRules(true),
+// 	technicalStrength: fieldRules(true),
+// 	skilledUavType: fieldRules(true, 50),
+// }
 
 const rules = {
 	flyerId: [
@@ -243,10 +259,11 @@
 watch(
 	() => props.flyingHandData,
 	(newData) => {
+		formData.value = initForm()
 		if (newData) {
-			Object.assign(formData, newData)
-			formData.flightHours = Number(newData.flightHours)
-		}
+			Object.assign(formData.value, newData)
+			formData.value.flightHours = Number(newData.flightHours)
+		} 
 	},
 	{ deep: true, immediate: true }
 )
@@ -260,8 +277,9 @@
 // 处理选择飞手姓名
 function handleChange(val) {
 	const result = flyingHandList.value.find(item => item.id === val) || []
-	formData.flyerName = result.name
-	formData.certification = formData.certification.concat(result.licenseFrontFileUrl || [], result.licenseBackFileUrl || [])
+	formData.value.flyerName = result.name
+	formData.value.regionCode = result.regionCode
+	formData.value.certification = formData.value.certification.concat(result.licenseFrontFileUrl || [], result.licenseBackFileUrl || [])
 }
 
 
@@ -270,7 +288,7 @@
 function resetForm() {
 	formRef.value?.resetFields()
 	// 重置为默认值
-	Object.assign(formData, {
+	Object.assign(formData.value, {
 		flyerName: '',
 		flyerPhone: '',
 		flightHours: 0,
@@ -290,10 +308,10 @@
 
 	try {
 		if (props.dialogType === 'add') {
-			await submitFlyingHand(formData)
+			await submitFlyingHand(formData.value)
 			ElMessage.success('添加成功')
 		} else if (props.dialogType === 'edit') {
-			await submitFlyingHand(formData)
+			await submitFlyingHand(formData.value)
 			ElMessage.success('编辑成功')
 		}
 		emit('confirm')
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue b/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue
index 36caab1..5625a83 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue
@@ -45,7 +45,7 @@
 				<el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
 					<el-table-column label="序号" width="70" align="center">
 						<template #default="{ $index }">
-							{{ formatNumber((searchParams.current - 1) * searchParams.size + $index + 1) }}
+							{{ $index + 1 }}
 						</template>
 					</el-table-column>
 					<el-table-column prop="caseName" show-overflow-tooltip label="案例名称" />
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue b/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue
index 54902ce..1970f55 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue
@@ -45,7 +45,7 @@
 				<el-table class="gd-table" :data="list">
 					<el-table-column label="序号" width="70">
 						<template v-slot="{ $index }">
-							{{ String($index + 1).padStart(2, '0') }}
+							{{ $index + 1 }}
 						</template>
 					</el-table-column>
 					<el-table-column prop="title" show-overflow-tooltip label="标题" />
@@ -63,7 +63,7 @@
 					<el-table-column prop="otherObjectionDetail" show-overflow-tooltip label="其他异议详情" />
 					<el-table-column prop="submitter" show-overflow-tooltip label="问题提交人" />
 					<el-table-column prop="submitterContact" show-overflow-tooltip width="120" label="提交人联系方式" />
-					<el-table-column prop="submitUnitName" show-overflow-tooltip label="提交单位" />
+					<el-table-column prop="createDeptName" show-overflow-tooltip label="提交单位" />
 					<el-table-column prop="handleUnit" show-overflow-tooltip label="处理单位" />
 					<el-table-column prop="objectionDesc" show-overflow-tooltip label="异议描述" />
 					<el-table-column prop="objectionBasis" show-overflow-tooltip label="异议依据" />
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
index 2ab783b..ecf226c 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
@@ -39,7 +39,7 @@
 				<el-table class="gd-table" :data="list">
 					<el-table-column label="序号" width="80">
 						<template v-slot="{ $index }">
-							{{ ((searchParams.current - 1) * searchParams.size + $index + 1).toString().padStart(2, '0') }}
+							{{ $index + 1 }}
 						</template>
 					</el-table-column>
 					<el-table-column prop="title" show-overflow-tooltip label="标题" />
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
index 3a4fcf5..0a5b011 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
@@ -44,7 +44,7 @@
 				<el-table class="gd-table" :data="list">
 					<el-table-column label="序号" width="70" align="center">
 						<template #default="scope">
-							{{ ((searchParams.current - 1) * searchParams.size + scope.$index + 1).toString().padStart(2, '0') }}
+							{{ scope.$index + 1 }}
 						</template>
 					</el-table-column>
 					<el-table-column prop="demandName" show-overflow-tooltip label="需求名称" />
diff --git a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
index ccbe7a3..89a3c4e 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
@@ -5,11 +5,10 @@
 		:title="titleEnum[dialogMode]"
 		@closed="visible = false"
 		destroy-on-close
-		width="auto"
 		:close-on-click-modal="false"
 	>
-		<div class="content" style="display: flex">
-			<div class="processBox" v-if="dialogMode !== 'add' && processList.length">
+		<div class="detail-container" style="display: flex">
+			<div class="detail-left" v-if="dialogMode !== 'add' && processList.length">
 				<el-timeline class="gd-timeline">
 					<el-timeline-item
 						v-for="(activity, index) in processList"
@@ -27,9 +26,10 @@
 					</el-timeline-item>
 				</el-timeline>
 			</div>
-			<div class="leftBox">
+
+			<div class="detail-right">
 				<!-- 查看模式 -->
-				<div class="detail-container" v-if="dialogReadonly">
+				<div class="view-container" v-if="dialogReadonly">
 					<div class="detail-title">工单详情</div>
 					<el-row class="detail-row-view">
 						<el-col :span="12">
@@ -507,52 +507,4 @@
 </script>
 
 <style lang="scss" scoped>
-.content {
-	display: flex;
-	gap: 0 20px;
-	height: 680px;
-
-	.leftBox {
-		width: 920px;
-		flex: 1;
-		overflow: auto;
-		display: flex;
-		flex-direction: column;
-		.gd-cesium {
-			width: 100%;
-			min-height: 380px;
-			flex: 1;
-		}
-	}
-	.processBox {
-		width: 312px;
-		padding: 24px 0;
-		border: 1px solid #e4e4e4;
-		overflow: auto;
-
-		.item-content {
-			position: relative;
-			.flowName {
-				width: 80px;
-				position: absolute;
-				left: -120px;
-				top: 0px;
-			}
-		}
-	}
-	.imgBox {
-		display: flex;
-		flex-wrap: wrap;
-		gap: 10px;
-		> div {
-			width: calc((100% - 40px) / 5); /* 5列布局,减去4个10px间隙 */
-			height: 110px;
-			flex-shrink: 0;
-		}
-		.el-image {
-			width: 100%;
-			height: 100%;
-		}
-	}
-}
 </style>
diff --git a/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/FormDiaLog.vue
index 205905a..44f488c 100644
--- a/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/FormDiaLog.vue
@@ -48,6 +48,7 @@
               popper-class="gd-tree-select-popper"
               v-model="formData.areaCode"
               node-key="id"
+              :default-expanded-keys="expandedKeys"
               :props="{
                 value: 'id',
                 label: 'name',
@@ -136,6 +137,8 @@
 const submitting = ref(false) // 提交中
 const dialogReadonly = computed(() => dialogMode.value === 'view')
 const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
+const expandedKeys = ref([]) // 树形选择器展开的节点
+const regionNodeCache = ref(new Map()) // 缓存区域节点及其父节点关系
 
 const rules = {
   deptName: fieldRules(true),
@@ -173,6 +176,62 @@
     data.areaCode = String(data.areaCode)
   }
   formData.value = data
+  
+  // 如果是编辑模式,获取区域节点的路径以展开树形选择器
+  if (dialogMode.value === 'edit' && data.areaCode) {
+    await loadRegionPath(data.areaCode)
+  }
+}
+
+// 加载区域节点路径
+async function loadRegionPath(areaCode) {
+  try {
+    const path = []
+    const queue = [{ code: '360800000000', currentPath: ['360800000000'] }]
+    let found = false
+    
+    // 广度优先搜索,逐层加载节点直到找到目标节点
+    while (queue.length > 0 && !found) {
+      const { code, currentPath } = queue.shift()
+      
+      // 获取当前节点的子节点
+      const res = await regionLazyTreeApi({ parentCode: code })
+      const nodes = res?.data?.data || []
+      
+      for (const node of nodes) {
+        const nodeId = node.id || node.value
+        
+        // 缓存节点及其父节点关系
+        regionNodeCache.value.set(nodeId, {
+          id: nodeId,
+          name: node.name || node.title || node.label,
+          parentId: code,
+          hasChildren: node.hasChildren || false
+        })
+        
+        // 检查是否找到目标节点
+        if (nodeId === areaCode) {
+          path.push(...currentPath, nodeId)
+          found = true
+          break
+        }
+        
+        // 如果有子节点,加入队列继续搜索
+        if (node.hasChildren) {
+          queue.push({
+            code: nodeId,
+            currentPath: [...currentPath, nodeId]
+          })
+        }
+      }
+    }
+    
+    if (path.length > 0) {
+      expandedKeys.value = path
+    }
+  } catch (error) {
+    console.error('加载区域路径失败:', error)
+  }
 }
 
 // 打开弹框
@@ -186,14 +245,25 @@
 // 懒加载获取区域节点数据
 async function loadRegionNode(node, resolve) {
   try {
-    const parentCode = node.data?.id  || '360800000000'
-    const res = await regionLazyTreeApi({ parentCode })
+    // 初始化加载时传递 code 参数,加载子节点时传递 parentCode 参数
+    const params = node.data?.id ? { parentCode: node.data.id } : { code: '360800000000' }
+    const parentCode = node.data?.id || '360800000000'
+    const res = await regionLazyTreeApi(params)
     const nodes = res?.data?.data || []
     
     // 处理返回的节点数据
     const processedNodes = nodes.map(item => {
+      const nodeId = item.id || item.value
+      // 缓存节点及其父节点关系
+      regionNodeCache.value.set(nodeId, {
+        id: nodeId,
+        name: item.name || item.title || item.label,
+        parentId: parentCode,
+        hasChildren: item.hasChildren || false
+      })
+      
       return {
-        id: item.id || item.value,
+        id: nodeId,
         name: item.name || item.title || item.label,
         hasChildren: item.hasChildren || false
       }
@@ -205,30 +275,10 @@
     resolve([])
   }
 }
-// 获取初始区域数据(根节点)
-async function getRegionList() {
-  try {
-    // 懒加载模式下,只需要初始化根节点
-    const res = await regionLazyTreeApi({ parentCode: '360800000000' })
-    const nodes = res?.data?.data || []
-    
-    // 处理根节点数据
-    regionOptions.value = nodes.map(item => {
-      return {
-        id: item.id || item.value,
-        name: item.name || item.title || item.label,
-        hasChildren: item.hasChildren || false
-      }
-    })
-  } catch (error) {
-    console.error('获取区域数据失败:', error)
-    ElMessage.error('获取区域数据失败')
-  }
-}
+
 defineExpose({ open })
 
 onMounted(() => {
-  getRegionList()
 })
 </script>
 
diff --git a/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue b/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue
index 457e203..fc7452c 100644
--- a/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue
+++ b/applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue
@@ -56,7 +56,7 @@
         <el-table class="gd-table" :data="list">
           <el-table-column label="序号" width="80">
             <template v-slot="{ $index }">
-              {{ ((searchParams.current - 1) * searchParams.size + $index + 1).toString().padStart(2, '0') }}
+              {{ $index + 1 }}
             </template>
           </el-table-column>
           <el-table-column prop="deptCode" show-overflow-tooltip label="机构编码" />
@@ -68,7 +68,7 @@
              {{ getDictLabel(row.status, dictObj.institutionStatus) }}
             </template>
           </el-table-column>
-          <el-table-column label="操作" class-name="operation-btns" width="310">
+          <el-table-column label="操作" class-name="operation-btns" width="400">
             <template v-slot="{ row }">
               <el-link type="primary" @click="openForm('view', row)">查看</el-link>
               <el-link type="primary"  @click="openForm('edit', row)">编辑</el-link>
@@ -197,8 +197,9 @@
 async function loadRegionNode(node, resolve) {
 
   try {
-    const parentCode = node.data?.id || '360800000000'
-    const res = await regionLazyTreeApi({ parentCode })
+    // 初始化加载时传递 code 参数,加载子节点时传递 parentCode 参数
+    const params = node.data?.id ? { parentCode: node.data.id } : { code: '360800000000' }
+    const res = await regionLazyTreeApi(params)
     const nodes = res?.data?.data || []
     
     // 处理返回的节点数据
@@ -217,25 +218,7 @@
   }
 }
 
-// 获取初始区域数据(根节点)
-async function getRegionList() {
-  try {
-    // 懒加载模式下,只需要初始化根节点
-    const res = await regionLazyTreeApi({ parentCode: '360800000000' })
-    const nodes = res?.data?.data || []
-    
-    // 处理根节点数据
-    regionOptions.value = nodes.map(item => {
-      return {
-        id: item.id || item.value,
-        name: item.name || item.title || item.label,
-        hasChildren: item.hasChildren || false
-      }
-    })
-  } catch (error) {
-    console.error('获取区域数据失败:', error)
-  }
-}
+
 
 // 获取列表
 async function getList() {
@@ -384,7 +367,6 @@
 
 onMounted(() => {
   getDictList()
-  getRegionList()
   getList()
 })
 </script>
diff --git a/applications/task-work-order/src/views/orderView/organizational/zoningManagement/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/organizational/zoningManagement/FormDiaLog.vue
new file mode 100644
index 0000000..5a8c4fc
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/organizational/zoningManagement/FormDiaLog.vue
@@ -0,0 +1,316 @@
+<template>
+  <el-dialog
+    class="gd-dialog"
+    v-model="visible"
+    :title="titleEnum[dialogMode]"
+    @closed="visible = false"
+    destroy-on-close
+    :close-on-click-modal="false"
+  >
+    <el-row class="detail-row-view" v-if="dialogReadonly">
+      <el-col :span="12">
+        <div class="label">区划代码</div>
+        <div class="val">{{ formData.code }}</div>
+      </el-col>
+      <el-col :span="12">
+        <div class="label">区划名称</div>
+        <div class="val">{{ formData.name }}</div>
+      </el-col>
+      <el-col :span="12">
+        <div class="label">上级区划</div>
+        <div class="val">{{ formData.parentName }}</div>
+      </el-col>
+      <el-col :span="12">
+        <div class="label">区划级别</div>
+        <div class="val"> {{ getDictLabel(formData.regionLevel, dictObj.divisionLevel) }}</div>
+      </el-col>
+      <el-col :span="12">
+        <div class="label">区划排序</div>
+        <div class="val">{{ formData.sort }}</div>
+      </el-col>
+      <el-col :span="12">
+        <div class="label">区划状态</div>
+        <div class="val"> {{ getDictLabel(formData.status, dictObj.zoningStatus) }}</div>
+      </el-col>
+    </el-row>
+
+    <el-form
+      class="gd-dialog-form"
+      v-else
+      ref="formRef"
+      :model="formData"
+      :rules="rules"
+      :disabled="dialogReadonly"
+      label-width="140px"
+    >
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="区划代码" prop="code">
+            <el-input class="gd-input" v-model="formData.code" placeholder="请输入" clearable />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="区划名称" prop="name">
+            <el-input class="gd-input" v-model="formData.name" placeholder="请输入" clearable />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="上级区划" prop="parentCode">
+            <el-tree-select
+              class="gd-select"
+              popper-class="gd-tree-select-popper"
+              v-model="formData.parentCode"
+              node-key="id"
+              :default-expanded-keys="expandedKeys"
+              :props="{
+                value: 'id',
+                label: 'name',
+                children: 'children'
+              }"
+              placeholder="请选择"
+              clearable
+              filterable
+              :check-strictly="true"
+              lazy
+              :load="loadRegionNode"
+              :render-after-expand="false"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="区划级别" prop="regionLevel">
+            <el-select
+              class="gd-select"
+              popper-class="gd-select-popper"
+              v-model="formData.regionLevel"
+              placeholder="请选择"
+              clearable
+            >
+              <el-option v-for="item in dictObj.divisionLevel" :key="item.dictKey"
+								:label="item.dictValue"
+								:value="item.dictKey" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="区划排序" prop="sort">
+            <el-input class="gd-input" v-model="formData.sort" placeholder="请输入" clearable />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="区划状态" prop="status">
+            <el-select
+              class="gd-select"
+              popper-class="gd-select-popper"
+              v-model="formData.status"
+              placeholder="请选择"
+              clearable
+            >
+              <el-option v-for="item in dictObj.zoningStatus" :key="item.dictKey"
+								:label="item.dictValue"
+								:value="item.dictKey" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer v-if="!dialogReadonly">
+      <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
+      <el-button
+        class="save-btn"
+        color="#4C34FF"
+        :loading="submitting"
+        :disabled="submitting"
+        @click="handleSubmit"
+      >
+        保存
+      </el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { getDictLabel } from '@ztzf/utils'
+import { computed, ref, inject, nextTick } from 'vue'
+import { ElMessage } from 'element-plus'
+import { fieldRules } from '@ztzf/utils'
+import {
+  zoningSubmitApi,
+  zoningDetailApi,
+  regionLazyTreeApi
+} from './zoningApi'
+
+// 初始化表单数据
+const initForm = () => ({
+  code: '',
+  name: '',
+  parentCode: '',
+  regionLevel: '',
+  sort: '',
+  status: '',
+  id: null,
+  parentName: ''
+})
+
+const dictObj = inject('dictObj')
+const regionOptions = inject('regionOptions')
+
+const emit = defineEmits(['success'])
+const formRef = ref(null) // 表单实例
+const formData = ref(initForm()) // 表单数据
+const visible = defineModel() // 弹框显隐
+const dialogMode = ref('add') // 弹框模式
+const submitting = ref(false) // 提交中
+const dialogReadonly = computed(() => dialogMode.value === 'view')
+const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
+const expandedKeys = ref([]) // 树形选择器展开的节点
+const regionNodeCache = ref(new Map()) // 缓存区域节点及其父节点关系
+
+const rules = {
+  code: fieldRules(true),
+  name: fieldRules(true),
+  parentCode: fieldRules(true),
+  regionLevel: fieldRules(true),
+  sort: fieldRules(true),
+  status: fieldRules(true),
+}
+
+// 提交新增/编辑
+async function handleSubmit() {
+  const isValid = await formRef.value?.validate().catch(() => false)
+  if (!isValid) return
+  submitting.value = true
+  try {
+    await zoningSubmitApi(formData.value)
+    ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
+    visible.value = false
+    emit('success')
+  } finally {
+    submitting.value = false
+  }
+}
+
+// 加载详情
+async function loadDetail() {
+  if (!formData.value.id) return
+  const res = await zoningDetailApi({ id: formData.value.id })
+  const data = res?.data?.data ?? {}
+  // 将 status 和 regionLevel 转换为字符串类型,与字典中的 dictKey 类型保持一致
+  if (data.status !== undefined) {
+    data.status = String(data.status)
+  }
+  if (data.regionLevel !== undefined) {
+    data.regionLevel = String(data.regionLevel)
+  }
+  // 将 parentCode 转换为字符串类型,与 regionOptions 中的 value 类型保持一致
+  if (data.parentCode !== undefined) {
+    data.parentCode = String(data.parentCode)
+  }
+  formData.value = data
+  
+  // 如果是编辑模式,获取区域节点的路径以展开树形选择器
+  if (dialogMode.value === 'edit' && data.parentCode) {
+    await loadRegionPath(data.parentCode)
+  }
+}
+
+// 加载区域节点路径
+async function loadRegionPath(parentCode) {
+  try {
+    const path = []
+    const queue = [{ code: '360800000000', currentPath: ['360800000000'] }]
+    let found = false
+    
+    // 广度优先搜索,逐层加载节点直到找到目标节点
+    while (queue.length > 0 && !found) {
+      const { code, currentPath } = queue.shift()
+      
+      // 获取当前节点的子节点
+      const res = await regionLazyTreeApi({ parentCode: code })
+      const nodes = res?.data?.data || []
+      
+      for (const node of nodes) {
+        const nodeId = node.id || node.value
+        
+        // 缓存节点及其父节点关系
+        regionNodeCache.value.set(nodeId, {
+          id: nodeId,
+          name: node.name || node.title || node.label,
+          parentId: code,
+          hasChildren: node.hasChildren || false
+        })
+        
+        // 检查是否找到目标节点
+        if (nodeId === parentCode) {
+          path.push(...currentPath, nodeId)
+          found = true
+          break
+        }
+        
+        // 如果有子节点,加入队列继续搜索
+        if (node.hasChildren) {
+          queue.push({
+            code: nodeId,
+            currentPath: [...currentPath, nodeId]
+          })
+        }
+      }
+    }
+    
+    if (path.length > 0) {
+      expandedKeys.value = path
+    }
+  } catch (error) {
+    console.error('加载区域路径失败:', error)
+  }
+}
+
+// 打开弹框
+async function open({ mode = 'add', row } = {}) {
+  dialogMode.value = mode
+  formData.value = dialogMode.value === 'add' ? initForm() : row
+  if (dialogMode.value !== 'add') {
+    await loadDetail()
+  }
+}
+// 懒加载获取区域节点数据
+async function loadRegionNode(node, resolve) {
+  try {
+    // 初始化加载时传递 code 参数,加载子节点时传递 parentCode 参数
+    const params = node.data?.id ? { parentCode: node.data.id } : { code: '360800000000' }
+    const parentCode = node.data?.id || '360800000000'
+    const res = await regionLazyTreeApi(params)
+    const nodes = res?.data?.data || []
+    
+    // 处理返回的节点数据
+    const processedNodes = nodes.map(item => {
+      const nodeId = item.id || item.value
+      // 缓存节点及其父节点关系
+      regionNodeCache.value.set(nodeId, {
+        id: nodeId,
+        name: item.name || item.title || item.label,
+        parentId: parentCode,
+        hasChildren: item.hasChildren || false
+      })
+      
+      return {
+        id: nodeId,
+        name: item.name || item.title || item.label,
+        hasChildren: item.hasChildren || false
+      }
+    })
+    
+    resolve(processedNodes)
+  } catch (error) {
+    console.error('获取区域数据失败:', error)
+    resolve([])
+  }
+}
+defineExpose({ open })
+
+onMounted(() => {
+})
+</script>
+
+<style scoped lang="scss">
+</style>
\ No newline at end of file
diff --git a/applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue b/applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue
index 3459668..5c87710 100644
--- a/applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue
+++ b/applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue
@@ -1,19 +1,336 @@
 <template>
- <div>
-    区划管理
- </div>
+  <basic-container>
+    <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
+      <el-form-item label="上级区划名称" prop="parentName">
+        <el-input
+          class="gd-input gray"
+          v-model="searchParams.parentName"
+          placeholder="请输入"
+          clearable
+          @clear="handleSearch"
+        />
+      </el-form-item>
+
+      <el-form-item label="区划名称" prop="districtName">
+        <el-input
+          class="gd-input gray"
+          v-model="searchParams.districtName"
+          placeholder="请输入"
+          clearable
+          @clear="handleSearch"
+        />
+      </el-form-item>
+
+      <el-form-item label="区划代码" prop="cityCode">
+        <el-input
+          class="gd-input gray"
+          v-model="searchParams.cityCode"
+          placeholder="请输入"
+          clearable
+          @clear="handleSearch"
+        />
+      </el-form-item>
+
+      <el-form-item class="gd-search-actions">
+        <el-button :icon="RefreshRight" @click="resetForm"></el-button>
+        <el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+      </el-form-item>
+    </el-form>
+
+    <div class="gd-table-toolbar">
+      <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增区划</el-button>
+      <el-button :icon="Upload" @click="handleImport">导入区划</el-button>
+      <el-button :icon="Download" @click="handleExport">导出区划</el-button>
+    </div>
+
+    <div class="gd-table-container" v-loading="loading">
+      <div class="gd-table-content gd-table-content-bg">
+        <el-table class="gd-table" :data="list">
+          <el-table-column label="序号" width="80">
+            <template v-slot="{ $index }">
+               {{ $index + 1 }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="code" show-overflow-tooltip label="区划代码" />
+          <el-table-column prop="name" show-overflow-tooltip label="区划名称" />
+          <el-table-column prop="parentName" show-overflow-tooltip label="上级区划名称" />
+          <el-table-column prop="regionLevel" show-overflow-tooltip label="区划级别">
+            <template v-slot="{ row }">
+              {{ getDictLabel(row.regionLevel, dictObj.divisionLevel) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="sort" show-overflow-tooltip label="排序" />
+          <el-table-column prop="status" show-overflow-tooltip label="区划状态">
+            <template v-slot="{ row }">
+              {{ getDictLabel(row.status, dictObj.zoningStatus) }}
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" class-name="operation-btns" width="400">
+            <template v-slot="{ row }">
+              <el-link type="primary" @click="openForm('view', row)">查看</el-link>
+              <el-link type="primary"  @click="openForm('edit', row)">编辑</el-link>
+              <el-link type="primary" @click="handleDelete(row)">删除</el-link>
+              <el-link type="primary" @click="toggleStatus(row)">{{row.status === 1 ? '禁用' : '启用'}}</el-link>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <div class="gd-pagination-parent">
+        <el-pagination
+          popper-class="gd-select-popper"
+          v-model:current-page="searchParams.current"
+          v-model:page-size="searchParams.size"
+          layout="total, prev, pager, next, sizes"
+          :total="total"
+          @change="getList"
+        />
+      </div>
+    </div>
+
+    <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" />
+
+    <!-- 导入区划弹框 -->
+    <el-dialog
+      class="gd-dialog"
+      append-to-body
+      v-model="isShowImportView"
+      title="导入区划"
+      :width="pxToRem(600)"
+      :close-on-click-modal="false"
+      :destroy-on-close="true"
+      @close="handleImportClose"
+    >
+      <el-form class="gd-dialog-form" ref="importFormRef" :model="importParams" :rules="importRules" label-width="140px">
+        <el-form-item label="上传文件" prop="file">
+          {{ importFileName }}
+          <el-upload class="avatar-uploader" action="" :show-file-list="false" :before-upload="onImportFileBefore">
+            <el-button size="small" type="primary">点击上传</el-button>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button color="#F2F3F5" @click="isShowImportView = false">取消</el-button>
+        <el-button
+          class=""
+          color="#4C34FF"
+          :loading="importSubmitting"
+          :disabled="importSubmitting"
+          @click="submitImport(importFormRef)"
+        >
+          导入
+        </el-button>
+      </template>
+    </el-dialog>
+  </basic-container>
 </template>
 
-<script setup >
-/**
- * @description index
- * @date 2026-01-26 (周一) 10:50:43
- */
-defineOptions({
- name: 'index'
+<script setup>
+import { Search, RefreshRight, Plus, Upload, Download } from '@element-plus/icons-vue'
+import { onMounted, ref, provide, nextTick } from 'vue'
+import { ElMessage, ElMessageBox, ElUpload } from 'element-plus'
+import FormDiaLog from './FormDiaLog.vue'
+import {
+  zoningPageApi,
+  zoningRemoveApi,
+  zoningImportApi,
+  zoningExportApi,
+  regionLazyTreeApi,
+  zoningSubmitApi
+} from './zoningApi'
+import { getDictionaryByCode } from '@/api/system/dictbiz'
+import { getDictLabel } from '@ztzf/utils'
+import { pxToRem } from '@/utils/rem'
+// 初始化查询参数
+const initSearchParams = () => ({
+  parentName: '', // 上级区划名称
+  districtName: '', // 区划名称
+  cityCode: '', // 区划代码
+  current: 1, // 当前页
+  size: 10, // 每页大小
+})
+const searchParams = ref(initSearchParams()) // 查询参数
+const total = ref(0) // 总条数
+const loading = ref(true) // 列表加载中
+const list = ref([]) // 列表数据
+const queryParamsRef = ref(null) // 查询表单实例
+const dialogRef = ref(null) // 弹框实例
+const dialogVisible = ref(false)
+const regionOptions = ref([]) // 区域选项
+const dictObj = ref({}) // 字典对象
+
+// 导入区划相关
+const isShowImportView = ref(false)
+const importFileName = ref('')
+const importParams = ref({
+  isCovered: '0',
+  file: '',
+})
+const importFormRef = ref()
+const importSubmitting = ref(false)
+const importRules = ref({
+  file: [{ required: true, message: '请上传文件', trigger: ['change'] }],
 })
 
+provide('regionOptions', regionOptions)
+provide('dictObj', dictObj)
 
+// 获取字典列表
+function getDictList() {
+	return getDictionaryByCode('zoningStatus,divisionLevel').then(res => {
+		dictObj.value = res.data.data
+	})
+}
+
+// 获取列表
+async function getList() {
+  loading.value = true
+  try {
+    const res = await zoningPageApi(searchParams.value)
+    list.value = res?.data?.data?.records ?? []
+    total.value = res?.data?.data?.total ?? 0
+  } finally {
+    loading.value = false
+  }
+}
+
+// 查询
+function handleSearch() {
+  searchParams.value.current = 1
+  getList()
+}
+
+// 重置查询
+function resetForm() {
+  queryParamsRef.value?.resetFields()
+  searchParams.value.current = 1
+  getList()
+}
+
+// 新增/编辑/查看 弹框
+function openForm(mode, row) {
+  dialogVisible.value = true
+  nextTick(() => {
+    dialogRef.value?.open({ mode, row })
+  })
+}
+
+// 删除
+async function handleDelete(row) {
+  await ElMessageBox.confirm('确认删除该条记录吗?', '提示', {
+    type: 'warning',
+    customClass: 'gd-confirm-custom',
+    confirmButtonClass: 'gd-confirm-button',
+    cancelButtonClass: 'gd-confirm-cancel-button',
+  })
+  await zoningRemoveApi({ id: row.id })
+  ElMessage.success('删除成功')
+  getList()
+}
+
+// 切换区划状态
+async function toggleStatus(row) {
+  // 计算目标状态:当前为1则切换为0,当前为0则切换为1
+  const targetStatus = row.status === 1 ? 0 : 1
+  const actionText = targetStatus === 0 ? '禁用' : '启用'
+  
+  await ElMessageBox.confirm(`确认${actionText}该区划吗?`, '提示', {
+    type: 'warning',
+    customClass: 'gd-confirm-custom',
+    confirmButtonClass: 'gd-confirm-button',
+    cancelButtonClass: 'gd-confirm-cancel-button',
+  })
+  
+  try {
+    await zoningSubmitApi({ ...row, status: targetStatus })
+    ElMessage.success(`${actionText}成功`)
+    getList()
+  } catch (error) {
+    ElMessage.error(`${actionText}失败`)
+  }
+}
+
+// 导入区划
+function handleImport() {
+  isShowImportView.value = true
+}
+
+// 导入区划弹框关闭
+function handleImportClose() {
+  importFileName.value = ''
+  importParams.value = {
+    isCovered: '0',
+    file: '',
+  }
+}
+
+// 上传文件前处理
+function onImportFileBefore(file) {
+  // 检查文件类型
+  const allowedTypes = ['.xlsx', '.xls']
+  const fileExtension = file.name.substring(file.name.lastIndexOf('.')).toLowerCase()
+  if (!allowedTypes.includes(fileExtension)) {
+    ElMessage.error('请上传Excel文件(.xlsx 或 .xls)')
+    return false
+  }
+  let data = new FormData()
+  data.append('file', file)
+
+  zoningImportApi(data, { isCovered: importParams.value.isCovered }).then(res => {
+    if (res.data.code === 200) {
+      ElMessage.success('导入成功')
+      // 保存文件名
+      importFileName.value = file.name
+      importParams.value.file = file
+      isShowImportView.value = false
+      getList()
+    } else {
+      ElMessage.error(res.msg || '导入失败')
+    }
+  })
+
+  return false // 阻止组件的默认上传行为
+}
+
+// 提交导入
+async function submitImport(formValidate) {
+  if (!formValidate) return
+  await formValidate.validate(async (valid, fields) => {
+    if (valid) {
+      importSubmitting.value = true
+      try {
+        if (!importParams.value.file) {
+          ElMessage.error('请先上传文件')
+          return
+        }
+        // 触发上传操作
+        await onImportFileBefore(importParams.value.file)
+      } finally {
+        importSubmitting.value = false
+      }
+    }
+  })
+}
+
+// 导出区划
+function handleExport() {
+  zoningExportApi(searchParams.value).then(res => {
+    const blob = new Blob([res.data])
+    const url = URL.createObjectURL(blob)
+    const a = document.createElement('a')
+    a.href = url
+    a.download = `区划列表${new Date().getTime()}.xlsx`
+    document.body.appendChild(a)
+    a.click()
+    document.body.removeChild(a)
+    URL.revokeObjectURL(url)
+  })
+}
+
+onMounted(() => {
+  getDictList()
+  getList()
+})
 </script>
 
 <style scoped lang="scss">
diff --git a/applications/task-work-order/src/views/orderView/organizational/zoningManagement/zoningApi.js b/applications/task-work-order/src/views/orderView/organizational/zoningManagement/zoningApi.js
new file mode 100644
index 0000000..ff818d5
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/organizational/zoningManagement/zoningApi.js
@@ -0,0 +1,66 @@
+import request from '@/axios'
+
+// 列表
+export const zoningPageApi = params => {
+  return request({
+    url: `/blade-system/region/page`,
+    method: 'get',
+    params: { ...params },
+  })
+}
+
+// 新增或编辑
+export const zoningSubmitApi = data => {
+  return request({
+    url: `/blade-system/region/submit`,
+    method: 'post',
+    data,
+  })
+}
+
+// 删除
+export const zoningRemoveApi = params => {
+  return request({
+    url: `/blade-system/region/remove`,
+    method: 'post',
+    params,
+  })
+}
+
+// 详情
+export const zoningDetailApi = params => {
+  return request({
+    url: `/blade-system/region/detail`,
+    method: 'get',
+    params,
+  })
+}
+
+// 导入区划
+export const zoningImportApi = (data,params) => {
+  return request({
+    url: `/blade-system/region/import-region`,
+    method: 'post',
+    data,
+    params
+  })
+}
+
+// 导出区划
+export const zoningExportApi = params => {
+  return request({
+    url: `/blade-system/region/export-region`,
+    method: 'get',
+    params,
+    responseType: 'blob',
+  })
+}
+
+// 懒加载列表
+export const regionLazyTreeApi = params => {
+  return request({
+    url: `/blade-system/region/lazy-tree`,
+    method: 'get',
+    params,
+  })
+}
\ No newline at end of file
diff --git a/uniapps/work-app/src/subPackages/workDetail/index.vue b/uniapps/work-app/src/subPackages/workDetail/index.vue
index d46e87d..c951f8f 100644
--- a/uniapps/work-app/src/subPackages/workDetail/index.vue
+++ b/uniapps/work-app/src/subPackages/workDetail/index.vue
@@ -158,7 +158,11 @@
     uni.showToast({
       title: '退回成功',
       icon: 'success',
+      duration: 1500
     })
+    setTimeout(() => {
+      uni.navigateBack()
+    }, 1500)
   })
 
 }
@@ -169,7 +173,11 @@
     uni.showToast({
       title: '确认成功',
       icon: 'success',
+      duration: 1500
     })
+    setTimeout(() => {
+      uni.navigateBack()
+    }, 1500)
   })
 }
 // 分享模态框状态
diff --git a/uniapps/work-wx/src/pages/equipmentManagement/index.vue b/uniapps/work-wx/src/pages/equipmentManagement/index.vue
index 7bb6e62..4c0b578 100644
--- a/uniapps/work-wx/src/pages/equipmentManagement/index.vue
+++ b/uniapps/work-wx/src/pages/equipmentManagement/index.vue
@@ -132,7 +132,7 @@
   }
   .card {
     display: flex;
-    padding: 44rpx;
+    padding: 40rpx 0;
     border-bottom: 1px solid #EBEEF3;
     .left {
       width: 70px;
@@ -157,6 +157,10 @@
         color: #86909C;
         margin-bottom: 14rpx;
       }
+      // 最后一个txt 不添加margin-bottom
+      .txt:last-child {
+        margin-bottom: 0;
+      }
     }
   }
   // 第一个card 不添加下边框
diff --git a/uniapps/work-wx/src/pages/legalPolicy/index.vue b/uniapps/work-wx/src/pages/legalPolicy/index.vue
index cd77c46..304a745 100644
--- a/uniapps/work-wx/src/pages/legalPolicy/index.vue
+++ b/uniapps/work-wx/src/pages/legalPolicy/index.vue
@@ -1,7 +1,7 @@
 <template>
   <view class="legalPolicy">
     <!-- <u-navbar title="法律政策" @rightClick="rightClick" :autoBack="true"></u-navbar> -->
-    <u-search :bgColor="'white'" v-model="noticeTitle" :show-action="true" actionText="搜索" :animation="true" @custom="handleSearch"></u-search>
+    <u-search :bgColor="'white'" v-model="formParams.noticeTitle" :show-action="true" actionText="搜索" :animation="true" @custom="handleSearch"></u-search>
     <view class="tabs-container">
       <u-tabs :list="tabs" lineColor="#265CFD" @click="tabClick"></u-tabs>
     </view>
@@ -27,8 +27,6 @@
   import docSvg from '@/static/images/doc.png'
 import { ref, onMounted } from 'vue'
 
-const noticeTitle = ref('')
-
 const tabs = ref([
   {
     name: '法律法规',
@@ -42,7 +40,7 @@
   current: 1,
   size: 10,
   noticeType: 2,
-  noticeTitle: noticeTitle.value,
+  noticeTitle: '',
   isAsc: true
 })
 
@@ -62,7 +60,6 @@
 const handleSearch = () => {
   // 搜索时重置为第一页
   formParams.value.current = 1
-  formParams.value.noticeTitle = formParams.value.noticeTitle.trim()
   getSysNoticeList()
 }
 // 触底加载
diff --git a/uniapps/work-wx/src/subPackages/deviceRegistration/add.vue b/uniapps/work-wx/src/subPackages/deviceRegistration/add.vue
index 5bf7f64..8bcdb3c 100644
--- a/uniapps/work-wx/src/subPackages/deviceRegistration/add.vue
+++ b/uniapps/work-wx/src/subPackages/deviceRegistration/add.vue
@@ -649,6 +649,7 @@
 
     :deep(.u-button--primary) {
         background-color: #265CFD;
+        border-color: #265CFD;
     }
 
     :deep(.u-form) {
diff --git a/uniapps/work-wx/src/subPackages/deviceRegistration/details.vue b/uniapps/work-wx/src/subPackages/deviceRegistration/details.vue
index c1f61a7..e10db1d 100644
--- a/uniapps/work-wx/src/subPackages/deviceRegistration/details.vue
+++ b/uniapps/work-wx/src/subPackages/deviceRegistration/details.vue
@@ -9,7 +9,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.name" border="none"></u-input>
+            <u-input v-model="formParams.name" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="SN(出厂序列号)"
@@ -18,7 +18,7 @@
                 :borderBottom="true"
                 ref="item2"
         >
-            <u-input v-model="formParams.sn" border="none"></u-input>
+            <u-input v-model="formParams.sn" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="飞行器厂商"
@@ -28,9 +28,8 @@
                 ref="item2"
         >
             <u-input
-                v-model="formParams.manufacturer"
-                disabled
-                disabledColor="#ffffff"
+                v-model="formParams.manufacturerText"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -41,7 +40,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.model" border="none"></u-input>
+            <u-input v-model="formParams.model" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="是否改装"
@@ -52,8 +51,7 @@
         >
             <u-input
                 v-model="formParams.isModified"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -66,8 +64,7 @@
         >
             <u-input
                 v-model="formParams.type"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -79,7 +76,8 @@
                 ref="item1"
         >
             <u-input
-                    v-model="formParams.holder"
+                    v-model="formParams.holder" 
+                    readonly
                     border="none"
             ></u-input>
         </u-form-item>
@@ -90,7 +88,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.purchaseDate" border="none" placeholder="请选择日期" suffixIcon="calendar"></u-input>
+            <u-input v-model="formParams.purchaseDate" readonly border="none" placeholder="请选择日期" suffixIcon="calendar"></u-input>
         </u-form-item>
         <u-form-item
                 label="有无保险"
@@ -101,8 +99,7 @@
         >
             <u-input
                 v-model="formParams.hasInsurance"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -115,8 +112,7 @@
         >
             <u-input
                 v-model="formParams.region"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -128,7 +124,8 @@
                 ref="item1"
         >
             <u-input
-                    v-model="formParams.caacRegistrationCode"
+                    v-model="formParams.caacRegistrationCode" 
+                    readonly
                     border="none"
             ></u-input>
         </u-form-item>
@@ -140,7 +137,8 @@
                 ref="item1"
         >
             <u-input
-                    v-model="formParams.deviceImage"
+                    v-model="formParams.deviceImage" 
+                    readonly
                     border="none"
             ></u-input>
         </u-form-item>
@@ -152,7 +150,8 @@
                 ref="item1"
         >
             <u-input
-                    v-model="formParams.remarks"
+                    v-model="formParams.remarks" 
+                    readonly
                     border="none"
             ></u-input>
         </u-form-item>
@@ -314,11 +313,13 @@
         current: 1,
         size: 1000,
     }).then(res => {
-        manufacturerList.value = res.data.data.records.map(item => ({
-            ...item,
-            label: item.unitName,
-            value: item.id,
-        }))
+        // manufacturerList.value = res.data.data.records.map(item => ({
+        //     ...item,
+        //     label: item.unitName,
+        //     value: item.id,
+        // }))
+        console.log(formParams.value.manufacturer, res.data.data.records.find(item => item.id === formParams.value.manufacturer))
+        formParams.value.manufacturerText = res.data.data.records.find(item => item.id === formParams.value.manufacturer)?.unitName || ''
     })
 }
 onLoad((options) => {
@@ -326,16 +327,17 @@
         formParams.value = res.data.data
         formParams.value.isModified = res.data.data.isModified ? '是' : '否'
         formParams.value.hasInsurance = res.data.data.hasInsurance === '1' ? '有' : '无'
-        formParams.value.manufacturer = manufacturerList.value.find(item => item.value === res.data.data.manufacturer)?.label || ''
+        // formParams.value.manufacturer = manufacturerList.value.find(item => item.value === res.data.data.manufacturer)?.label || ''
         formParams.value.type = typeList.value.find(item => item.value === res.data.data.type)?.label || ''
         formParams.value.region = res.data.data.region
+        getManufacturerInfoApi()
     })
     
     
 })
 onMounted(async () => {
+    // getManufacturerInfoApi()
     getProTypeApi()
-    getManufacturerInfoApi()
     // 动态导入xzqhData,确保在使用前已初始化
     const { xzqhData } = await import('@/static/xzqh/index')
     areaData.value = xzqhData
diff --git a/uniapps/work-wx/src/subPackages/flightApplication/add.vue b/uniapps/work-wx/src/subPackages/flightApplication/add.vue
index 080da5c..d660720 100644
--- a/uniapps/work-wx/src/subPackages/flightApplication/add.vue
+++ b/uniapps/work-wx/src/subPackages/flightApplication/add.vue
@@ -329,20 +329,22 @@
         @confirm="onPickerPlanType"
         @cancel="isShowPlanType = false"
     />
-    <up-datetime-picker
+    <u-datetime-picker
             :show="isShowStartTime"
             v-model="startTime"
             mode="datetime"
+            :min-date="minDate"
             @confirm="onConfirmStartTime"
              @cancel="isShowStartTime = false"
-        ></up-datetime-picker>
-        <up-datetime-picker
+        ></u-datetime-picker>
+        <u-datetime-picker
             :show="isShowEndTime"
             v-model="endTime"
             mode="datetime"
+            :min-date="minDate"
             @confirm="onConfirmEndTime"
             @cancel="isShowEndTime = false"
-        ></up-datetime-picker>
+        ></u-datetime-picker>
     <!-- <u-calendar :show="isShowTimeRange" mode="date" @confirm="onConfirmTimeRange" @close="isShowTimeRange = false" :close-on-click-overlay="true"></u-calendar> -->
     <!-- <u-calendar :show="isShowTimeRange" mode="range" @confirm="onConfirmTimeRange" @close="isShowTimeRange = false" :close-on-click-overlay="true" :allow-same-day="true" :show-time="true" time-format="HH:mm:ss"></u-calendar> -->
     <!-- 飞行器 -->
@@ -541,6 +543,7 @@
 const isShowStartTime = ref(false)
 // 是否显示结束时间选择器
 const isShowEndTime = ref(false)
+const minDate = ref(Date.now()); // 设置最小日期为当前时间戳
 const startTime = ref(Date.now()); // 设置默认值为当前时间戳
 const endTime = ref(Date.now()); // 设置默认值为当前时间戳
 
@@ -714,6 +717,8 @@
         duration: 2000
       })
     }
+  }).finally(() => {
+    isSubmitDisabled.value = false
   })
 }
 onMounted(() => {
diff --git a/uniapps/work-wx/src/subPackages/flightApplication/details.vue b/uniapps/work-wx/src/subPackages/flightApplication/details.vue
index 6d8e44e..2369026 100644
--- a/uniapps/work-wx/src/subPackages/flightApplication/details.vue
+++ b/uniapps/work-wx/src/subPackages/flightApplication/details.vue
@@ -10,7 +10,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.flightPlanName" border="none"></u-input>
+            <u-input v-model="formParams.flightPlanName" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="任务类型"
@@ -21,8 +21,7 @@
         >
             <u-input
                 v-model="formParams.flightTaskType"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -35,8 +34,7 @@
         >
             <u-input
                 v-model="formParams.flightRule"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -49,8 +47,7 @@
         >
             <u-input
                 v-model="formParams.flightMode"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -61,7 +58,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.flightStartTime" border="none" suffixIcon="calendar"></u-input>
+            <u-input v-model="formParams.flightStartTime" border="none" readonly suffixIcon="calendar"></u-input>
         </u-form-item>
          <u-form-item
                 label="飞行活动结束日期"
@@ -70,7 +67,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.flightEndTime" border="none" suffixIcon="calendar"></u-input>
+            <u-input v-model="formParams.flightEndTime" readonly border="none" suffixIcon="calendar"></u-input>
         </u-form-item>
 
         <u-form-item
@@ -82,8 +79,7 @@
         >
             <u-input
                 v-model="formParams.planType"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -94,7 +90,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.contactPerson" border="none"></u-input>
+            <u-input v-model="formParams.contactPerson" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="联系电话"
@@ -103,7 +99,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.contactPhone" border="none"></u-input>
+            <u-input v-model="formParams.contactPhone" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="承办人"
@@ -112,7 +108,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.undertaker" border="none"></u-input>
+            <u-input v-model="formParams.undertaker" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="承办人联系电话"
@@ -121,7 +117,7 @@
                 :borderBottom="true"
                 ref="item1"
         >
-            <u-input v-model="formParams.undertakerPhone" border="none"></u-input>
+            <u-input v-model="formParams.undertakerPhone" readonly border="none"></u-input>
         </u-form-item>
         <u-form-item
                 label="临时空域批件"
@@ -140,7 +136,8 @@
                 ref="item1"
         >
             <u-input
-                    v-model="formParams.weatherCondition"
+                    v-model="formParams.weatherCondition" 
+                    readonly
                     border="none"
             ></u-input>
         </u-form-item>
@@ -154,8 +151,7 @@
         >
             <u-input
                 v-model="formParams.aircraftId"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -168,8 +164,7 @@
         >
             <u-input
                 v-model="formParams.pilotId"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -183,8 +178,7 @@
         >
             <u-input
                 v-model="formParams.airspaceId"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -197,8 +191,7 @@
         >
             <u-input
                 v-model="formParams.routeId"
-                disabled
-                disabledColor="#ffffff"
+                readonly
                 border="none"
             ></u-input>
         </u-form-item>
@@ -317,16 +310,19 @@
      flightPlanDetailsApi(options.id).then(res => {
         // return
         const result = res.data.data
+        console.log(result, '7777')
         formParams.value = result
-        formParams.value.routeId = result.routeInfo.name
-        formParams.value.airspaceId = result.airspaceInfo.taskName || '无'
-        formParams.value.aircraftId = result.airspaceInfo.aircraftInfoList.map(item => item.name).join(',') || '无'
-        formParams.value.pilotId = result.operatorInfoList.map(item => item.name).join(',') || '无'
         // 字典
         formParams.value.flightRule = actionsFlightRule.value.find(item => item.dictValue === result.flightRule)?.dictLabel || '无'
         formParams.value.flightMode = actionsFlightMode.value.find(item => item.dictValue === result.flightMode)?.dictLabel || '无'
         formParams.value.planType = actionsPlanType.value.find(item => item.dictValue === result.planType)?.dictLabel || '无'
         formParams.value.flightTaskType = actionsFlightTaskType.value.find(item => item.dictValue === result.flightTaskType)?.dictLabel || '无'
+        // 数据
+        formParams.value.routeId = result?.routeInfo?.name || '无'
+        formParams.value.airspaceId = result?.airspaceInfo?.taskName || '无'
+        formParams.value.aircraftId = result?.airspaceInfo?.aircraftInfoList?.map(item => item.name).join(',') || '无'
+        formParams.value.pilotId = result?.operatorInfoList?.map(item => item.name).join(',') || '无'
+        
     })
 })
 onMounted(() => {
diff --git a/uniapps/work-wx/src/subPackages/flightApplication/index.vue b/uniapps/work-wx/src/subPackages/flightApplication/index.vue
index 5c9f930..f060e70 100644
--- a/uniapps/work-wx/src/subPackages/flightApplication/index.vue
+++ b/uniapps/work-wx/src/subPackages/flightApplication/index.vue
@@ -187,7 +187,7 @@
                 flex: 1;
                 max-width: 350rpx;
                 height: 166rpx;
-                background: rgba(251,253,255,0.57);
+                background: rgba(251,253,255,0.8);
                 box-shadow: inset 0px 0px 7px 0px rgba(64,156,230,0.14), 0px 1px 3px 0px rgba(35,49,96,0.11);
                 border-radius: 8px 8px 8px 8px;
                 border: 1px solid #fff;

--
Gitblit v1.9.3