From 521bcd986338f91ef38f7a7b56f4253ce8723afb Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Fri, 30 Jan 2026 13:50:19 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/jagzwxm/ja_web

---
 applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/FormDiaLog.vue |  130 ++++++++-
 /dev/null                                                                                     |   46 ---
 applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue     |   90 ++++++
 applications/drone-command/src/views/areaManage/sceneConfig/index.vue                         |    6 
 applications/drone-command/src/views/areaManage/sceneManage/FormDiaLog.vue                    |  349 +++++++++++++-------------
 applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue      |    2 
 applications/drone-command/src/views/areaManage/sceneManage/sceneManageApi.js                 |   38 ++
 applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/FormDiaLog.vue |    1 
 applications/drone-command/src/views/areaManage/sceneConfig/FormDiaLog.vue                    |    6 
 applications/drone-command/src/views/areaManage/sceneManage/index.vue                         |   67 +---
 10 files changed, 430 insertions(+), 305 deletions(-)

diff --git a/applications/drone-command/src/views/areaManage/sceneConfig/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/sceneConfig/FormDiaLog.vue
index 63d49aa..43d3a82 100644
--- a/applications/drone-command/src/views/areaManage/sceneConfig/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/sceneConfig/FormDiaLog.vue
@@ -23,7 +23,7 @@
 					<div class="detail-title">场景详情</div>
 					<el-row>
 						<el-col :span="24">
-							<div class="label">场景名称</div>
+							<div class="label">场景配置名称</div>
 							<div class="val">{{ formData.sceneName }}</div>
 						</el-col>
 						<el-col :span="24">
@@ -60,7 +60,7 @@
 					:disabled="readonly"
 					label-width="96px"
 				>
-					<el-form-item label="场景名称" prop="sceneName">
+					<el-form-item label="场景配置名称" prop="sceneName">
 						<el-input
 							class="command-input"
 							v-model="formData.sceneName"
@@ -165,7 +165,7 @@
 import { AREA_TYPE_STYLE_MAP, BUFFER_LEVEL_STYLES, DEFAULT_AREA_STYLE } from '@ztzf/constants'
 
 const initForm = () => ({
-	sceneName: '', // 场景名称
+	sceneName: '', // 场景配置名称
 	sceneType: '', // 场景类型
 	deviceMode: '', // 设备模式
 	areaDivideIds: '', // 关联区域ID
diff --git a/applications/drone-command/src/views/areaManage/sceneConfig/index.vue b/applications/drone-command/src/views/areaManage/sceneConfig/index.vue
index 1d744f4..75de78d 100644
--- a/applications/drone-command/src/views/areaManage/sceneConfig/index.vue
+++ b/applications/drone-command/src/views/areaManage/sceneConfig/index.vue
@@ -1,7 +1,7 @@
 <template>
 	<basic-container>
 		<el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
-			<el-form-item label="场景名称" prop="sceneName">
+			<el-form-item label="场景配置名称" prop="sceneName">
 				<el-input
 					class="command-input"
 					v-model="searchParams.sceneName"
@@ -46,7 +46,7 @@
 					<el-table-column type="selection" width="46" />
 					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
 
-					<el-table-column prop="sceneName" show-overflow-tooltip label="场景名称" />
+					<el-table-column prop="sceneName" show-overflow-tooltip label="场景配置名称" />
 					<el-table-column prop="sceneType" show-overflow-tooltip label="场景类型">
 						<template v-slot="{ row }">
 							{{ getDictLabel(row.sceneType, dictObj.CommandSceneType) }}
@@ -93,7 +93,7 @@
 import { useRoute } from 'vue-router'
 
 const initSearchParams = () => ({
-	sceneName: '', // 场景名称
+	sceneName: '', // 场景配置名称
 	sceneType: '', // 场景类型
 	current: 1, // 当前页
 	size: 10, // 每页大小
diff --git a/applications/drone-command/src/views/areaManage/sceneManage/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/sceneManage/FormDiaLog.vue
index 0b15bc6..eba09ef 100644
--- a/applications/drone-command/src/views/areaManage/sceneManage/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/sceneManage/FormDiaLog.vue
@@ -20,35 +20,33 @@
 				</div>
 
 				<div class="content" v-if="readonly">
-					<div class="detail-title">场景详情</div>
+					<div class="detail-title">场景管理详情</div>
 					<el-row>
 						<el-col :span="24">
 							<div class="label">场景名称</div>
 							<div class="val">{{ formData.sceneName }}</div>
 						</el-col>
 						<el-col :span="24">
-							<div class="label">场景类型</div>
-							<div class="val">{{ getDictLabel(formData.sceneType, dictObj.CommandSceneType) }}</div>
+							<div class="label">负责人</div>
+							<div class="val">{{ formData.defenseLeader }}</div>
 						</el-col>
 						<el-col :span="24">
-							<div class="label">设备模式</div>
-							<div class="val">{{ getDictLabel(formData.deviceMode, dictObj.deviceMode) }}</div>
+							<div class="label">负责人电话</div>
+							<div class="val">{{ formData.leaderPhone }}</div>
+						</el-col>
+						<el-col :span="24">
+							<div class="label">有效时间</div>
+							<div class="val">{{ formatEffectiveDate(formData) }}</div>
+						</el-col>
+						<el-col :span="24">
+							<div class="label">指挥点位置</div>
+							<div class="val">{{ formatLocation(formData) }}</div>
+						</el-col>
+						<el-col :span="24">
+							<div class="label">关联场景配置</div>
+							<div class="val">{{ getSceneConfigName(formData.defenseSceneId) }}</div>
 						</el-col>
 					</el-row>
-
-					<div class="detail-title">关联区域</div>
-					<div class="command-table-container">
-						<div class="command-table-content">
-							<el-table class="command-table" ref="areaTableRef" :data="areaList" row-key="id">
-								<el-table-column prop="areaName" label="区域名称" />
-								<el-table-column prop="areaType" label="区域类型">
-									<template v-slot="{ row }">
-										{{ getDictLabel(row.areaType, dictObj.areaType) }}
-									</template>
-								</el-table-column>
-							</el-table>
-						</div>
-					</div>
 				</div>
 
 				<el-form
@@ -58,7 +56,7 @@
 					:model="formData"
 					:rules="rules"
 					:disabled="readonly"
-					label-width="96px"
+					label-width="110px"
 				>
 					<el-form-item label="场景名称" prop="sceneName">
 						<el-input
@@ -69,66 +67,52 @@
 							clearable
 						/>
 					</el-form-item>
-					<el-form-item label="场景类型" prop="sceneType">
+					<el-form-item label="关联场景配置" prop="defenseSceneId">
 						<el-select
 							class="command-select"
 							popper-class="command-select-popper"
-							v-model="formData.sceneType"
+							v-model="formData.defenseSceneId"
 							placeholder="请选择"
 							clearable
 						>
-							<el-option
-								v-for="item in dictObj.CommandSceneType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
+							<el-option v-for="item in sceneConfigList" :key="item.id" :label="item.sceneName" :value="item.id" />
 						</el-select>
 					</el-form-item>
-					<el-form-item label="设备模式" prop="deviceMode">
-						<el-select
-							class="command-select"
-							popper-class="command-select-popper"
-							v-model="formData.deviceMode"
-							placeholder="请选择"
+					<el-form-item label="负责人" prop="defenseLeader">
+						<el-input
+							class="command-input"
+							v-model="formData.defenseLeader"
+							maxlength="50"
+							placeholder="请输入"
 							clearable
-						>
-							<el-option
-								v-for="item in dictObj.deviceMode"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
+						/>
 					</el-form-item>
-
-					<div class="search-table-container">
-						<div class="search-box">
-							<div class="label">关联区域</div>
-
-							<el-input class="command-input" v-model="searchName" placeholder="请输入" clearable></el-input>
-						</div>
-
-						<el-form-item prop="areaDivideIds" label-width="0">
-							<el-table
-								class="command-table"
-								ref="areaTableRef"
-								:data="areaList.filter(item => item.areaName.includes(searchName))"
-								row-key="id"
-								@selection-change="handleAreaSelectionChange"
-							>
-								<el-table-column type="selection" width="55" :reserve-selection="true" />
-								<el-table-column prop="areaName" show-overflow-tooltip label="区域名称" />
-								<el-table-column prop="areaType" show-overflow-tooltip label="区域类型">
-									<template v-slot="{ row }">
-										{{ getDictLabel(row.areaType, dictObj.areaType) }}
-									</template>
-								</el-table-column>
-							</el-table>
-						</el-form-item>
-					</div>
+					<el-form-item label="负责人电话" prop="leaderPhone">
+						<el-input
+							class="command-input"
+							v-model="formData.leaderPhone"
+							maxlength="50"
+							placeholder="请输入"
+							clearable
+						/>
+					</el-form-item>
+					<el-form-item label="有效时间范围" prop="effectiveDateStart">
+						<el-date-picker
+							class="command-date-picker"
+							popper-class="command-date-picker-popper"
+							v-model="effectiveDateRange"
+							type="datetimerange"
+							range-separator="至"
+							start-placeholder="开始时间"
+							end-placeholder="结束时间"
+							value-format="YYYY-MM-DD HH:mm:ss"
+							clearable
+						/>
+					</el-form-item>
+					<el-form-item label="指挥点位置" prop="longitude">
+						<div class="val">{{ formatLocation(formData) }}</div>
+					</el-form-item>
 				</el-form>
-
 				<div class="footer">
 					<el-button v-if="dialogMode != 'view'" color="#2B2B4C" @click="handleCancel">
 						{{ readonly ? '关闭' : '取消' }}
@@ -152,24 +136,27 @@
 <script setup>
 import { Close } from '@element-plus/icons-vue'
 
-import { computed, inject, nextTick, onMounted, ref, watch } from 'vue'
+import { computed, nextTick, onMounted, ref, watch } from 'vue'
 import { ElMessage } from 'element-plus'
-import { fwDefenseSceneDetailApi, fwDefenseSceneSubmitApi } from './sceneConfigApi'
-import { fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils'
+import { fwDefenseSceneManageDetailApi, fwDefenseSceneManageSubmitApi } from './sceneManageApi'
+import { fwDefenseSceneListApi } from '../sceneConfig/sceneConfigApi'
+import { fieldRules } from '@ztzf/utils'
 import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
 import * as Cesium from 'cesium'
-import { fwAreaDivideDetailApi, fwAreaDivideListApi } from '../partition/partitionApi'
-import { DrawPolygon } from '@/utils/cesium/DrawPolygon'
 import commandPost from '@/assets/images/dataCockpit/legend/command-post.png'
 import { saveOperationLog } from '@ztzf/apis'
 import { useRoute } from 'vue-router'
 
+// 初始化表单数据
 const initForm = () => ({
 	sceneName: '', // 场景名称
-	sceneType: '', // 场景类型
-	deviceMode: '', // 设备模式
-	areaDivideIds: '', // 关联区域ID
-	areaCount: 0, // 区域数量
+	defenseLeader: '', // 防控负责人
+	leaderPhone: '', // 防控负责人电话
+	effectiveDateStart: '', // 有效时间-开始
+	effectiveDateEnd: '', // 有效时间-结束
+	longitude: null, // 指挥点经度
+	latitude: null, // 指挥点纬度
+	defenseSceneId: '', // 关联场景配置ID
 })
 
 const emit = defineEmits(['success'])
@@ -180,22 +167,22 @@
 const submitting = ref(false) // 提交中
 const readonly = computed(() => dialogMode.value === 'view')
 const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
-const areaTableRef = ref(null)
-const searchName = ref('')
-const areaList = ref([]) // 关联区域列表
-const selectedAreaRows = ref([]) //选中列表
-const dictObj = inject('dictObj')
+const effectiveDateRange = ref([]) // 有效时间范围
+const sceneConfigList = ref([]) // 场景配置列表
 const mapRef = ref(null)
 const route = useRoute()
 let viewer
 let redPointEntity
 let leftClickBound = false
 
+// 表单验证规则
 const rules = {
 	sceneName: fieldRules(true, 50),
-	sceneType: fieldRules(true),
-	deviceMode: fieldRules(true),
-	areaDivideIds: fieldRules(false),
+	defenseLeader: fieldRules(true, 50),
+	leaderPhone: fieldRules(true, 50),
+	effectiveDateStart: fieldRules(true),
+	longitude: fieldRules(true),
+	defenseSceneId: fieldRules(true),
 }
 
 // 关闭弹框
@@ -209,13 +196,10 @@
 	if (!isValid) return
 	submitting.value = true
 	try {
-		const ids = selectedAreaRows.value.map(item => item.id)
-		formData.value.areaDivideIds = ids.join(',')
-		formData.value.areaCount = ids.length
-		await fwDefenseSceneSubmitApi(formData.value)
+		await fwDefenseSceneManageSubmitApi(formData.value)
 		saveOperationLog({
 			requestUri: route.path,
-			title: `${route.name || '场景配置管理'}-${dialogMode.value === 'add' ? '新增' : '编辑'}`,
+			title: `${route.name || '场景管理'}-${dialogMode.value === 'add' ? '新增' : '编辑'}`,
 			type: 1,
 		})
 		ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
@@ -226,128 +210,135 @@
 	}
 }
 
+// 监听有效时间范围变化,同步到表单数据
+watch(
+	() => effectiveDateRange.value,
+	() => {
+		formData.value.effectiveDateStart = effectiveDateRange.value?.[0] || ''
+		formData.value.effectiveDateEnd = effectiveDateRange.value?.[1] || ''
+	}
+)
+
 // 加载详情
 async function loadDetail() {
 	if (!formData.value.id) return
-	const res = await fwDefenseSceneDetailApi({ id: formData.value.id })
+	const res = await fwDefenseSceneManageDetailApi({ id: formData.value.id })
 	formData.value = res?.data?.data ?? initForm()
+	// 同步有效时间范围
+	effectiveDateRange.value = [formData.value.effectiveDateStart, formData.value.effectiveDateEnd].filter(Boolean)
 }
 
-// 获取区域列表
-async function getAreaList() {
-	if (areaList.value.length) return
-	const res = await fwAreaDivideListApi({ filterSelected: 1, sceneId: formData.value.id })
-	areaList.value = res?.data?.data ?? []
+// 获取场景配置列表
+async function getSceneConfigList() {
+	if (sceneConfigList.value.length) return
+	const res = await fwDefenseSceneListApi({unbound: 1})
+	sceneConfigList.value = res?.data?.data ?? []
 }
 
-// 关联区域变更
-async function handleAreaSelectionChange(rows) {
-	const selectedRows = await ensureAreaGeom(rows)
-	selectedAreaRows.value = selectedRows
-	const ids = selectedRows.map(item => item.id)
-	formData.value.areaDivideIds = ids.join(',')
-	formData.value.areaCount = ids.length
+// 获取场景配置名称
+function getSceneConfigName(id) {
+	if (!id) return ''
+	const item = sceneConfigList.value.find(item => item.id === id)
+	return item?.sceneName || id
 }
 
-// 渲染面
-function renderingSurface() {
-	if (!geometricSource) {
-		initMap()
-	}
-	if (!geometricSource) return
-	geometricSource && geometricSource.entities.removeAll()
-	selectedAreaRows.value.forEach(item => {
-		if (item.geom) {
-			const pointList = geomAnalysis(item.geom)
-			const result = pointList.map(item => [item.longitude, item.latitude]).flat()
-			geometricSource.entities?.add({
-				customType: 'control_group',
-				position: Cesium.Cartesian3.fromDegrees(result[0], result[1]),
-				polyline: {
-					positions: Cesium.Cartesian3.fromDegreesArray(result),
-					clampToGround: true,
-					width: 3,
-					material: Cesium.Color.RED,
-				},
-			})
-		}
-	})
+// 格式化指挥点位置
+function formatLocation(row) {
+	if (row?.longitude == null || row?.latitude == null) return ''
+	return `${_.round(row.longitude, 6)}, ${_.round(row.latitude, 6)}`
 }
 
-watch(() => selectedAreaRows.value, renderingSurface)
-
-async function ensureAreaGeom(rows) {
-	const missingRows = rows.filter(row => row?.id && !row.geom)
-	if (!missingRows.length) return rows
-	const detailList = await Promise.all(
-		missingRows.map(row =>
-			fwAreaDivideDetailApi({ id: row.id })
-				.then(res => res?.data?.data)
-				.catch(() => null)
-		)
-	)
-	const detailMap = new Map(detailList.filter(Boolean).map(item => [String(item.id), item]))
-	if (!detailMap.size) return rows
-	areaList.value = areaList.value.map(item => {
-		const detail = detailMap.get(String(item.id))
-		return detail ? { ...item, ...detail } : item
-	})
-	return rows.map(item => {
-		const detail = detailMap.get(String(item.id))
-		return detail ? { ...item, ...detail } : item
-	})
+// 格式化有效时间
+function formatEffectiveDate(row) {
+	if (!row?.effectiveDateStart && !row?.effectiveDateEnd) return ''
+	return `${row.effectiveDateStart || '-'} ~ ${row.effectiveDateEnd || '-'}`
 }
 
-// 同步关联区域
-function syncAreaSelection() {
-	if (!areaTableRef.value) return
-	areaTableRef.value.clearSelection()
-	const rows = []
-	const areaDivideIds = formData.value.areaDivideIds
-	const arr = Array.isArray(areaDivideIds)
-		? areaDivideIds.map(item => String(item))
-		: String(areaDivideIds || '')
-				.split(',')
-				.filter(Boolean)
-	areaList.value.forEach(row => {
-		if (arr.includes(String(row.id))) {
-			areaTableRef.value.toggleRowSelection(row, true)
-			rows.push(row)
-		}
-	})
-	selectedAreaRows.value = rows
-	if (!rows.length) return
-	formData.value.areaCount = rows.length
-}
-
-let geometricSource
 // 初始化地图实例
 function initMap() {
 	if (viewer) return
 	const map = mapRef.value?.getMap()
 	if (!map?.viewer) return
 	viewer = map.viewer
-	if (!geometricSource) {
-		geometricSource = new Cesium.CustomDataSource('geometricSource')
-		viewer.dataSources.add(geometricSource)
+	if (!readonly.value && !leftClickBound) {
+		map.publicCesium?.addLeftClickEvent?.(null, LeftClickEvent)
+		leftClickBound = true
+	}
+}
+
+// 地图左键点击事件
+function LeftClickEvent(click) {
+	const pos = click.position
+	// 优先使用 pickPosition 获取贴地坐标(包含地形高度)
+	let cartesian3 = viewer.scene.pickPosition(pos)
+	// 如果 pickPosition 失败,回退到 pickEllipsoid
+	if (!cartesian3 || !Cesium.defined(cartesian3)) {
+		cartesian3 = viewer.camera.pickEllipsoid(pos, viewer.scene.globe.ellipsoid)
+	}
+	if (!cartesian3) return
+	const carto = Cesium.Cartographic.fromCartesian(cartesian3)
+	const longitude = Cesium.Math.toDegrees(carto.longitude)
+	const latitude = Cesium.Math.toDegrees(carto.latitude)
+	formData.value.longitude = _.round(longitude, 6)
+	formData.value.latitude = _.round(latitude, 6)
+	setMapPoint(formData.value.longitude, formData.value.latitude)
+}
+
+// 设置地图点位
+function setMapPoint(longitude, latitude) {
+	if (!viewer || longitude == null || latitude == null) return
+	if (!redPointEntity) {
+		redPointEntity = viewer.entities.add({
+			position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
+			billboard: {
+				image: commandPost,
+				width: 40,
+				height: 56,
+				verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			},
+			label: {
+				text: `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`,
+				font: '14px',
+				fillColor: Cesium.Color.WHITE,
+				backgroundColor: Cesium.Color.BLACK.withAlpha(0.6),
+				backgroundPadding: new Cesium.Cartesian2(5, 5),
+				showBackground: true,
+				style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+				horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+				verticalOrigin: Cesium.VerticalOrigin.CENTER,
+				outlineWidth: 1,
+				outlineColor: Cesium.Color.WHITE,
+				pixelOffset: new Cesium.Cartesian2(0, -72),
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			},
+		})
+	} else {
+		redPointEntity.position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
+		redPointEntity.label.text = `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`
 	}
 }
 
 // 打开弹框
 async function open({ mode, row } = {}) {
 	dialogMode.value = mode || 'add'
-	formData.value = dialogMode.value === 'add' ? initForm() : row
-	selectedAreaRows.value = []
+	formData.value = dialogMode.value === 'add' ? initForm() : { ...row }
+	effectiveDateRange.value = []
 	redPointEntity = null
 	await nextTick()
 	initMap()
-	await getAreaList()
+	await getSceneConfigList()
 	if (dialogMode.value !== 'add') {
 		await loadDetail()
 	}
 	await nextTick()
-	syncAreaSelection()
+	setMapPoint(formData.value.longitude, formData.value.latitude)
 }
+
+onMounted(() => {
+	getSceneConfigList()
+})
+
 defineExpose({
 	open,
 })
diff --git a/applications/drone-command/src/views/areaManage/sceneManage/index.vue b/applications/drone-command/src/views/areaManage/sceneManage/index.vue
index 1d744f4..503d3d7 100644
--- a/applications/drone-command/src/views/areaManage/sceneManage/index.vue
+++ b/applications/drone-command/src/views/areaManage/sceneManage/index.vue
@@ -11,24 +11,6 @@
 				/>
 			</el-form-item>
 
-			<el-form-item label="场景类型" prop="sceneType">
-				<el-select
-					class="command-select"
-					popper-class="command-select-popper"
-					v-model="searchParams.sceneType"
-					placeholder="请选择"
-					clearable
-					@change="handleSearch"
-				>
-					<el-option
-						v-for="item in dictObj.CommandSceneType"
-						:key="item.dictKey"
-						:label="item.dictValue"
-						:value="item.dictKey"
-					/>
-				</el-select>
-			</el-form-item>
-
 			<el-form-item class="history-search-actions">
 				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
 				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
@@ -47,14 +29,19 @@
 					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
 
 					<el-table-column prop="sceneName" show-overflow-tooltip label="场景名称" />
-					<el-table-column prop="sceneType" show-overflow-tooltip label="场景类型">
+					<el-table-column show-overflow-tooltip label="指挥点经度纬度">
 						<template v-slot="{ row }">
-							{{ getDictLabel(row.sceneType, dictObj.CommandSceneType) }}
+							{{ formatLocation(row) }}
 						</template>
 					</el-table-column>
-					<el-table-column prop="areaCount" show-overflow-tooltip label="区域数量" />
-					<el-table-column prop="counterDeviceCount" show-overflow-tooltip label="反制设备数量" />
-					<el-table-column prop="detectDeviceCount" show-overflow-tooltip label="探测设备数量" />
+					<el-table-column prop="defenseLeader" show-overflow-tooltip label="防控负责人" />
+					<el-table-column prop="leaderPhone" show-overflow-tooltip label="防控负责人电话" />
+					<el-table-column show-overflow-tooltip label="有效时间">
+						<template v-slot="{ row }">
+							{{ formatEffectiveDate(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="defenseSceneId" show-overflow-tooltip label="关联场景配置ID" />
 					<el-table-column label="操作" class-name="operation-btns">
 						<template v-slot="{ row }">
 							<el-link @click="openForm('view', row)">查看</el-link>
@@ -83,18 +70,16 @@
 
 <script setup>
 import { Search, RefreshRight, Plus, Delete } from '@element-plus/icons-vue'
-import { nextTick, onMounted, provide, ref } from 'vue'
+import { nextTick, onMounted, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { fwDefenseScenePageApi, fwDefenseSceneRemoveApi } from './sceneConfigApi'
+import { fwDefenseSceneManagePageApi, fwDefenseSceneManageRemoveApi } from './sceneManageApi'
 import FormDiaLog from './FormDiaLog.vue'
-import { getDictionaryByCode } from '@/api/system/dictbiz'
-import { getDictLabel } from '@ztzf/utils'
 import { saveOperationLog } from '@ztzf/apis'
 import { useRoute } from 'vue-router'
 
+// 初始化查询参数
 const initSearchParams = () => ({
 	sceneName: '', // 场景名称
-	sceneType: '', // 场景类型
 	current: 1, // 当前页
 	size: 10, // 每页大小
 })
@@ -109,11 +94,11 @@
 const dialogVisible = ref(false)
 const route = useRoute()
 
-// 获取列表
+// 获取列表数据
 async function getList() {
 	loading.value = true
 	try {
-		const res = await fwDefenseScenePageApi(searchParams.value)
+		const res = await fwDefenseSceneManagePageApi(searchParams.value)
 		list.value = res?.data?.data?.records ?? []
 		total.value = res?.data?.data?.total ?? 0
 	} finally {
@@ -144,10 +129,10 @@
 		cancelButtonClass: 'command-message-box-cancel',
 	})
 	const ids = row ? row.id : selectedIds.value.join(',')
-	await fwDefenseSceneRemoveApi({ ids })
+	await fwDefenseSceneManageRemoveApi({ ids })
 	saveOperationLog({
 		requestUri: route.path,
-		title: `${route.name || '场景配置管理'}-删除`,
+		title: `${route.name || '场景管理'}-删除`,
 		type: 1,
 	})
 	ElMessage.success('删除成功')
@@ -160,23 +145,16 @@
 	selectedIds.value = rows.map(item => item.id)
 }
 
+// 格式化指挥点位置
 function formatLocation(row) {
 	if (row?.longitude == null || row?.latitude == null) return ''
 	return `${_.round(row.longitude, 6)}, ${_.round(row.latitude, 6)}`
 }
 
-const dictObj = ref({
-	sceneType: [], // 场景类型
-	deviceMode: [], // 设备模式
-	areaType: [], // 区域类型
-})
-provide('dictObj', dictObj)
-
-// 获取字典
-function getDictList() {
-	getDictionaryByCode('CommandSceneType,deviceMode,areaType').then(res => {
-		dictObj.value = res.data.data
-	})
+// 格式化有效时间
+function formatEffectiveDate(row) {
+	if (!row?.effectiveDateStart && !row?.effectiveDateEnd) return ''
+	return `${row.effectiveDateStart || '-'} ~ ${row.effectiveDateEnd || '-'}`
 }
 
 // 新增/编辑/查看 弹框
@@ -189,7 +167,6 @@
 
 onMounted(() => {
 	getList()
-	getDictList()
 })
 </script>
 <style scoped lang="scss"></style>
diff --git a/applications/drone-command/src/views/areaManage/sceneManage/sceneConfigApi.js b/applications/drone-command/src/views/areaManage/sceneManage/sceneConfigApi.js
deleted file mode 100644
index fbd0373..0000000
--- a/applications/drone-command/src/views/areaManage/sceneManage/sceneConfigApi.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import request from '@/axios'
-
-// 查page
-export const fwDefenseScenePageApi = params => {
-	return request({
-		url: `/drone-fw/area/fwDefenseScene/page`,
-		method: 'get',
-		params: { descs: 'update_time', ...params },
-	})
-}
-
-// 查list
-export const fwDefenseSceneListApi = params => {
-	return request({
-		url: `/drone-fw/area/fwDefenseScene/list`,
-		method: 'get',
-		params,
-	})
-}
-
-// 增加或更新
-export const fwDefenseSceneSubmitApi = data => {
-	return request({
-		url: `/drone-fw/area/fwDefenseScene/submit`,
-		method: 'post',
-		data,
-	})
-}
-
-//删除
-export const fwDefenseSceneRemoveApi = params => {
-	return request({
-		url: `/drone-fw/area/fwDefenseScene/remove`,
-		method: 'post',
-		params,
-	})
-}
-
-//详情
-export const fwDefenseSceneDetailApi = params => {
-	return request({
-		url: `/drone-fw/area/fwDefenseScene/detail`,
-		method: 'get',
-		params,
-	})
-}
diff --git a/applications/drone-command/src/views/areaManage/sceneManage/sceneManageApi.js b/applications/drone-command/src/views/areaManage/sceneManage/sceneManageApi.js
new file mode 100644
index 0000000..77464c3
--- /dev/null
+++ b/applications/drone-command/src/views/areaManage/sceneManage/sceneManageApi.js
@@ -0,0 +1,38 @@
+import request from '@/axios'
+
+// 分页查询场景管理列表
+export const fwDefenseSceneManagePageApi = params => {
+	return request({
+		url: `/drone-fw/area/fwDefenseSceneManage/page`,
+		method: 'get',
+		params: { descs: 'update_time', ...params },
+	})
+}
+
+// 获取场景管理详情
+export const fwDefenseSceneManageDetailApi = params => {
+	return request({
+		url: `/drone-fw/area/fwDefenseSceneManage/detail`,
+		method: 'get',
+		params,
+	})
+}
+
+// 新增或修改场景管理
+export const fwDefenseSceneManageSubmitApi = data => {
+	return request({
+		url: `/drone-fw/area/fwDefenseSceneManage/submit`,
+		method: 'post',
+		data,
+	})
+}
+
+// 删除场景管理
+export const fwDefenseSceneManageRemoveApi = params => {
+	return request({
+		url: `/drone-fw/area/fwDefenseSceneManage/remove`,
+		method: 'post',
+		params,
+	})
+}
+
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/FormDiaLog.vue
index d236c6a..33d2751 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/FormDiaLog.vue
@@ -6,6 +6,7 @@
 		@closed="visible = false"
 		destroy-on-close
 		:close-on-click-modal="false"
+		width="800px"
 	>
 		<div class="detail-container" v-if="dialogReadonly">
 			<el-row class="detail-row-view">
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/FormDiaLog.vue
index e2220ad..d68afc9 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/FormDiaLog.vue
@@ -218,6 +218,42 @@
 <!--				<el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">关闭</el-button>-->
 			</template>
 		</template>
+
+		<!-- 申请弹框 -->
+		<el-dialog
+			class="gd-dialog"
+			v-model="showApplyDialog"
+			title="申请"
+			@closed="handleApplyDialogClosed"
+			width="500px"
+			destroy-on-close
+			:close-on-click-modal="false"
+		>
+			<el-form class="gd-dialog-form" ref="applyFormRef" :model="applyFormData" :rules="applyRules">
+				<el-row>
+					<el-col :span="24">
+						<el-form-item label="申请对象部门" prop="applyTargetDeptId">
+							<el-tree-select
+								class="gd-select"
+								popper-class="gd-tree-select-popper"
+								v-model="applyFormData.applyTargetDeptId"
+								node-key="id"
+								:data="deptTree"
+								:props="treeProps"
+								check-strictly
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<el-button color="#F2F3F5" @click="showApplyDialog = false">取消</el-button>
+				<el-button class="" color="#4C34FF" :loading="applying" :disabled="applying" @click="handleApplySubmit">
+					确认
+				</el-button>
+			</template>
+		</el-dialog>
 	</el-dialog>
 </template>
 
@@ -283,6 +319,14 @@
 const attachmentDetailsList = ref([])
 const uploading = ref(false) // 文件上传中状态
 
+// 申请弹框相关
+const showApplyDialog = ref(false)
+const applyFormRef = ref(null)
+const applying = ref(false)
+const applyFormData = ref({
+	applyTargetDeptId: ''
+})
+
 // 表单校验规则
 const rules = {
 	title: fieldRules(true),
@@ -300,6 +344,11 @@
 const feedbackRules = {
 	otherObjectionDetail: fieldRules(true),
 	reviewOpinion: fieldRules(true),
+}
+
+// 申请弹框校验规则
+const applyRules = {
+	applyTargetDeptId: fieldRules(true),
 }
 
 // 自定义上传请求
@@ -323,9 +372,6 @@
 }
 
 // 文件移除
-// const handleFileRemove = (file, fileListVal) => {
-// uploadedFiles.value = fileListVal
-// }
 const handleFileRemove = (file, fileListVal) => {
   // 从展示列表中移除
   fileList.value = fileListVal
@@ -409,13 +455,6 @@
 			}),
       objectionStatus: objectionStatus
     }
-    
-    // 如果是编辑且没有修改附件,可以保留原有附件ID
-    if (dialogMode.value === 'edit' && formData.value.attachIds) {
-      // 这里可以根据业务需求决定是否保留原附件ID
-      // 如果接口支持更新时重新上传附件ID列表,可以这样做
-    }
-    
     await gdDataObjectionSubmitApi(submitData)
     ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
     visible.value = false
@@ -430,9 +469,66 @@
 	await submitForm('0')
 }
 
-// 申请提交
+// 申请弹框关闭处理
+function handleApplyDialogClosed() {
+	applyFormData.value.applyTargetDeptId = ''
+}
+
+// 申请
 async function handleApply() {
-	await submitForm('1')
+     formData.value.attachId = uploadedFiles.value.length > 0 ? uploadedFiles.value.length : ''
+	 // 先验证主表单
+	 const mainFormValid = await formRef.value?.validate().catch(() => false)
+	 if (!mainFormValid) return
+
+	 showApplyDialog.value = true
+}
+
+// 申请提交
+async function handleApplySubmit() {
+	const isValid = await applyFormRef.value?.validate().catch(() => false)
+	if (!isValid) return
+	applying.value = true
+	try {
+		// 构建申请数据
+		const applyData = {
+			...formData.value,
+			objectionStatus: '1',
+			applyTargetDeptId: applyFormData.value.applyTargetDeptId
+		}
+		
+		// 构建符合接口要求的提交数据
+		const submitData = {
+			// 编辑模式下传递id
+			...(applyData.id && { id: applyData.id }),
+			title: applyData.title,
+			objectionType: applyData.objectionType,
+			submitter: applyData.submitter,
+			submitterContact: applyData.submitterContact,
+			catalogResourceName: applyData.catalogResourceName,
+			objectionDesc: applyData.objectionDesc,
+			objectionBasis: applyData.objectionBasis,
+			areaCode: applyData.areaCode || '',
+			handleUnit: applyData.handleUnit || '',
+			// 构建附件列表 - 使用当前已上传的文件(包括回显的)
+			...(uploadedFiles.value.length > 0 && {
+				attachmentList: uploadedFiles.value.map(file => ({
+					attachId: file.attachId,
+					attachName: file.originalName,
+				})),
+			}),
+			objectionStatus: applyData.objectionStatus,
+			applyTargetDeptId: applyData.applyTargetDeptId
+		}
+		
+		await gdDataObjectionSubmitApi(submitData)
+		ElMessage.success('申请成功')
+		showApplyDialog.value = false
+		visible.value = false
+		emit('success')
+	} finally {
+		applying.value = false
+	}
 }
 
 // 处理异议反馈提交
@@ -510,8 +606,6 @@
     ElMessage.warning('没有可下载的附件')
     return
   }
-
-
   // 顺序下载每个附件
   for (let i = 0; i < attachmentDetailsList.value.length; i++) {
     const attach = attachmentDetailsList.value[i]
@@ -522,10 +616,6 @@
     }
 
     try {
-      // 显示当前下载的文件信息
-      const currentFileName = attach.originalName || attach.name || `附件_${i + 1}`
-   
-      
       const response = await fetch(attach.link)
       const blob = await response.blob()
       const url = window.URL.createObjectURL(blob)
@@ -569,8 +659,6 @@
   }
   
 }
-
-
 // 打开弹框
 async function open({ mode = 'add', row } = {}) {
   dialogMode.value = mode
@@ -581,6 +669,8 @@
   formData.value = dialogMode.value === 'add' ? initForm() : row
   // 重置反馈表单数据
   feedbackFormData.value = initFeedbackForm()
+  // 重置申请弹框数据
+  applyFormData.value.applyTargetDeptId = ''
   
   if (dialogMode.value !== 'add') {
     // 如果是编辑,设置ID并加载详情
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 fc0cc14..10a457d 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
@@ -59,7 +59,7 @@
 							{{ getDictLabel(row.objectionStatus, dictObj.objectionStatus) }}
 						</template>
 					</el-table-column>
-					<el-table-column prop="catalogResourceName" width="130" show-overflow-tooltip  label="目录/申请资源名称" />
+					<el-table-column prop="catalogResourceName" width="140" show-overflow-tooltip  label="目录/申请资源名称" />
 					<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="提交人联系方式" />
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue
index d6ae8f9..9935c07 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue
@@ -8,7 +8,7 @@
 		:close-on-click-modal="false"
 	>
 		<div class="detail-container" v-if="dialogReadonly">
-			<el-row class="detail-row-view">
+			<el-row class="detail-row-view supplyAddLabel">
 				<el-col :span="12">
 					<div class="label">需求名称</div>
 					<div class="val">{{ formData.demandName }}</div>
@@ -194,9 +194,45 @@
 			>
 				保存
 			</el-button>
-			<el-button color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button>
+			<el-button color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply" >申请</el-button>
 
 		</template>
+
+		<!-- 申请弹框 -->
+		<el-dialog
+			class="gd-dialog"
+			v-model="showApplyDialog"
+			title="申请"
+			@closed="handleApplyDialogClosed"
+			width="500px"
+			destroy-on-close
+			:close-on-click-modal="false"
+		>
+			<el-form class="gd-dialog-form" ref="applyFormRef" :model="applyFormData" :rules="applyRules">
+				<el-row>
+					<el-col :span="24">
+						<el-form-item label="申请对象部门" prop="applyTargetDeptId">
+							<el-tree-select
+								class="gd-select"
+								popper-class="gd-tree-select-popper"
+								v-model="applyFormData.applyTargetDeptId"
+								node-key="id"
+								:data="deptTree"
+								:props="treeProps"
+								check-strictly
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<el-button color="#F2F3F5" @click="showApplyDialog = false">取消</el-button>
+				<el-button class="" color="#4C34FF" :loading="applying" :disabled="applying" @click="handleApplySubmit">
+					确认
+				</el-button>
+			</template>
+		</el-dialog>
 	</el-dialog>
 </template>
 
@@ -240,6 +276,14 @@
 const dialogReadonly = computed(() => dialogMode.value === 'view')
 const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
 
+// 申请弹框相关
+const showApplyDialog = ref(false)
+const applyFormRef = ref(null)
+const applying = ref(false)
+const applyFormData = ref({
+	applyTargetDeptId: ''
+})
+
 const rules = {
 	demandName: fieldRules(true),
 	demandType: fieldRules(true),
@@ -253,6 +297,11 @@
 	responsibleDeptId: fieldRules(true),
 	dataSource: fieldRules(true),
 	demandInfo: fieldRules(true),
+}
+
+// 申请弹框校验规则
+const applyRules = {
+	applyTargetDeptId: fieldRules(true),
 }
 // 根据部门ID获取部门名称
 function getDeptNameById(deptId, deptList) {
@@ -295,19 +344,37 @@
 	}
 }
 
-// 申请提交
+// 申请弹框关闭处理
+function handleApplyDialogClosed() {
+	applyFormData.value.applyTargetDeptId = ''
+}
+// 申请
 async function handleApply() {
-	const isValid = await formRef.value?.validate().catch(() => false)
+	 // 先验证主表单
+	 const mainFormValid = await formRef.value?.validate().catch(() => false)
+	 if (!mainFormValid) return
+
+	 showApplyDialog.value = true
+ }
+// 申请提交
+async function handleApplySubmit() {
+	const isValid = await applyFormRef.value?.validate().catch(() => false)
 	if (!isValid) return
-	submitting.value = true
+	applying.value = true
 	try {
-		formData.value.demandStatus = '1'
-		await gdSupplyDemandSubmitApi(formData.value)
+		// 构建申请数据
+		const applyData = {
+			...formData.value,
+			demandStatus: '1',
+			applyTargetDeptId: applyFormData.value.applyTargetDeptId
+		}
+		await gdSupplyDemandSubmitApi(applyData)
 		ElMessage.success('申请成功')
+		showApplyDialog.value = false
 		visible.value = false
 		emit('success')
 	} finally {
-		submitting.value = false
+		applying.value = false
 	}
 }
 
@@ -334,3 +401,10 @@
 
 defineExpose({ open })
 </script>
+<style scoped lang="scss">
+.supplyAddLabel {
+	.label {
+		width: 120px !important;
+	}
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3