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