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