吉安感知网项目-前端
chenyao
2026-01-19 4db717891564367505251cbf335859e67fffc72f
Merge remote-tracking branch 'origin/master'
67 files modified
7 files added
4 files deleted
4863 ■■■■ changed files
applications/drone-command/src/api/dataCockpit/index.js 8 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/assets/images/common/checkbox.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/left-btn.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/legend/command-post.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/legend/equipment.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/map/aggregation.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/map/command-post.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/map/equipment.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/map/popup-close.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/right-btn.png patch | view | raw | blame | history
applications/drone-command/src/components/map-container/common-cesium-map.vue 2 ●●● patch | view | raw | blame | history
applications/drone-command/src/components/map-container/device-map-container.vue 575 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/styles/common/cockpit.scss 127 ●●●● patch | view | raw | blame | history
applications/drone-command/src/styles/element-ui.scss 658 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/utils/cesium/publicCesium.js 35 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/api.txt 86 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/areaStatistics/index.vue 10 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/defenseZone/FormDiaLog.vue 8 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/defenseZone/index.vue 6 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue 22 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/index.vue 8 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/precinctInfo/FormDiaLog.vue 6 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/precinctInfo/index.vue 6 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/sceneConfig/FormDiaLog.vue 16 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/sceneConfig/index.vue 14 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/deviceScrap/index.vue 14 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/deviceStock/DeviceScrapDiaLog.vue 6 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/deviceStock/DeviceTrackDiaLog.vue 12 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue 28 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/deviceStock/index.vue 14 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/maintainRecord/FormDiaLog.vue 10 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/maintainRecord/MaintenanceDiaLog.vue 8 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/maintainRecord/index.vue 10 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue 18 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue 27 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue 10 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue 11 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/RealWarning.vue 36 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/RightContainer.vue 11 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue 32 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue 19 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/detectionCountermeasure/countermeasureEvaluation/index.vue 14 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/detectionCountermeasure/detectionRange/DetectionRangeDialog.vue 29 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/detectionCountermeasure/detectionRange/index.vue 10 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/detectionCountermeasure/deviceAppConfig/FormDiaLog.vue 24 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/detectionCountermeasure/deviceAppConfig/index.vue 14 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/detectionCountermeasure/taskSchedule/FormDiaLog.vue 26 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/detectionCountermeasure/taskSchedule/index.vue 14 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionDept/FormDiaLog.vue 20 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionDept/index.vue 8 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionRole/FormDiaLog.vue 8 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionRole/index.vue 8 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionUser/FormDiaLog.vue 42 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionUser/index.vue 12 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/recordManage/alarmRecords/index.vue 16 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue 2 ●●● patch | view | raw | blame | history
applications/drone-command/src/views/recordManage/historyTracks/index.vue 12 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/config/website.js 139 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/permission copy 2.js 71 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/permission copy.js 133 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/permission.js 3 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/router/page/index.js 133 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/router/views/index.js 18 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/store/modules/user.js 769 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/styles/common/cockpit.scss 63 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue 135 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/basicManage/maintainRecord/MaintenanceDiaLog.vue 177 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/basicManage/maintainRecord/fwDeviceMaintainRecord.js 19 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/basicManage/maintainRecord/index.vue 30 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/FormDiaLog.vue 220 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/evaluateApi.js 37 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue 178 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue 310 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue 218 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/supplyAddApi.js 55 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/wel/index.vue 4 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/subPackages/userDetail/infos/index.vue 37 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/api/dataCockpit/index.js
@@ -53,6 +53,14 @@
    })
}
// 数据驾驶舱地图聚合
export const cockpitAggregationApi = () => {
    return request({
        url: '/drone-fw/device/fwDevice/statisticalDeviceOut',
        method: 'get'
    })
}
// 区域列表
export const areaDivideListApi = (params) => {
    return request({
applications/drone-command/src/assets/images/common/checkbox.png
applications/drone-command/src/assets/images/dataCockpit/left-btn.png

applications/drone-command/src/assets/images/dataCockpit/legend/command-post.png

applications/drone-command/src/assets/images/dataCockpit/legend/equipment.png

applications/drone-command/src/assets/images/dataCockpit/map/aggregation.png
applications/drone-command/src/assets/images/dataCockpit/map/command-post.png

applications/drone-command/src/assets/images/dataCockpit/map/equipment.png

applications/drone-command/src/assets/images/dataCockpit/map/popup-close.png
applications/drone-command/src/assets/images/dataCockpit/right-btn.png

applications/drone-command/src/components/map-container/common-cesium-map.vue
@@ -42,7 +42,7 @@
    },
    zoomToBoundary: {
        type: Boolean,
        default: true,
        default: false,
    },
    enableStageEmit: {
        type: Boolean,
applications/drone-command/src/components/map-container/device-map-container.vue
@@ -1,35 +1,74 @@
<template>
    <CommonCesiumMap
        ref="mapRef"
        class="command-cesium map-container"
        :dom-id="props.containerId"
        :active="true"
        :flat-mode="false"
        :terrain="false"
        :layer-mode="4"
        :contour="false"
        :boundary="false"
        :show-admin-boundary="true"
        :zoom-to-boundary="true"
        @ready="handleMapReady"
    />
    <div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.leftCollapsed }">
        <div class="layer-control-wrap" ref="layerWrapRef">
            <div class="layer-control" @click="toggleLayerPanel">
                <img :src="layerControlIcon" alt="图层控制" />
            </div>
            <div v-if="showLayerPanel" class="layer-panel">
                <div class="panel-title">图层管理</div>
    <div class="map-shell">
        <CommonCesiumMap ref="mapRef" class="command-cesium map-container" :dom-id="props.containerId" :active="true"
            :flat-mode="false" :terrain="false" :layer-mode="4" :contour="false" :boundary="false"
            :show-admin-boundary="true" :zoom-to-boundary="true" :enable-stage-emit="true" :cluster-height="100000"
            @ready="handleMapReady" @stage-change="handleStageChange" />
        <div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.leftCollapsed }">
            <div class="layer-control-wrap" ref="layerWrapRef">
                <div class="layer-control" @click="toggleLayerPanel">
                    <img :src="layerControlIcon" alt="图层控制" />
                </div>
                <div v-if="showLayerPanel" class="layer-panel">
                    <div class="panel-title">图层管理</div>
                <div class="panel-content">
                    <el-tree
                        :data="layerTree"
                        show-checkbox
                        default-expand-all
                        node-key="key"
                        :props="layerTreeProps"
                        :default-checked-keys="defaultCheckedKeys"
                    />
                    <div class="panel-content">
                        <el-tree :data="layerTree" show-checkbox default-expand-all node-key="key"
                            :props="layerTreeProps" :default-checked-keys="defaultCheckedKeys" />
                    </div>
                </div>
            </div>
        </div>
        <div v-if="popupVisible" class="device-popup" :style="popupStyle" @click.stop>
            <div class="device-popup__header">
                <span class="device-popup__title">{{ popupTitle }}</span>
                <img class="device-popup__close" :src="popupClose" alt="" @click.stop="closePopup">
            </div>
            <div class="device-popup__type">
                <span class="value">{{ popupTypeText }}</span>
            </div>
            <div class="device-popup__subtitle">
                <span class="device-popup__dot" :class="popupActionClass"></span>
                <span class="device-popup__action">{{ popupActionText }}</span>
            </div>
            <div class="device-popup__rows">
                <div class="device-popup__row">
                    <div class="device-popup__col">
                        <span class="label">状态</span>
                        <span class="value" :class="popupStatusClass">{{ popupStatusText }}</span>
                    </div>
                    <span class="divider">|</span>
                    <div class="device-popup__col">
                        <span class="label">电量</span>
                        <span class="value">{{ popupBatteryText }}</span>
                    </div>
                </div>
                <div class="device-popup__row">
                    <div class="device-popup__col">
                        <span class="label">方位角</span>
                        <span class="value">{{ popupAzimuthText }}</span>
                    </div>
                    <span class="divider">|</span>
                    <div class="device-popup__col">
                        <span class="label">俯仰角</span>
                        <span class="value">{{ popupElevationText }}</span>
                    </div>
                </div>
                <div class="device-popup__row">
                    <span class="label">侦测目标</span>
                    <span class="value">{{ popupDetectCountText }}</span>
                </div>
                <div class="device-popup__row">
                    <span class="label">有效范围</span>
                    <span class="value">{{ popupRangeText }}</span>
                </div>
            </div>
        </div>
@@ -42,8 +81,14 @@
import { geomAnalysis } from '@ztzf/utils'
import { fwDefenseZonePageApi } from '@/views/areaManage/defenseZone/defenseZoneApi'
import { fwAreaDividePageApi } from '@/views/areaManage/partition/partitionApi'
import { fwDefenseSceneListApi } from '@/views/areaManage/sceneConfig/sceneConfigApi'
import { cockpitAggregationApi } from '@/api/dataCockpit'
import layerControlIcon from '@/assets/images/dataCockpit/layerControl.png'
import equipmentIcon from '@/assets/images/dataCockpit/map/equipment.png'
import aggregationIcon from '@/assets/images/dataCockpit/map/aggregation.png'
import commandPostIcon from '@/assets/images/dataCockpit/map/command-post.png'
import popupClose from '@/assets/images/dataCockpit/map/popup-close.png'
import jaGeojsonRaw from '@/assets/geojson/ja.geojson?raw'
const props = defineProps({
    onlineDevices: {
@@ -69,10 +114,20 @@
const mapRef = ref(null)
let viewer = null
const deviceEntityIds = new Set()
const deviceEntityMap = new Map()
let defenseZoneSource = null
let partitionSource = null
let aggregationSource = null
let commandPostSource = null
const detailVisible = ref(true)
const clusterVisible = ref(false)
const countyCenterMap = new Map()
const showLayerPanel = ref(false)
const layerWrapRef = ref(null)
const selectedDevice = ref(null)
let selectedDeviceEntity = null
let deviceClickHandler = null
let popupRenderHandler = null
const layerTreeProps = {
    label: 'label',
    children: 'children',
@@ -123,6 +178,7 @@
        viewer.entities.removeById(id)
    })
    deviceEntityIds.clear()
    deviceEntityMap.clear()
}
const clearDefenseZoneEntities = () => {
@@ -133,6 +189,44 @@
const clearPartitionEntities = () => {
    if (!partitionSource) return
    partitionSource.entities.removeAll()
}
const clearAggregationEntities = () => {
    if (!aggregationSource) return
    aggregationSource.entities.removeAll()
}
const clearCommandPostEntities = () => {
    if (!commandPostSource) return
    commandPostSource.entities.removeAll()
}
const setDetailVisibility = visible => {
    detailVisible.value = visible
    if (defenseZoneSource) defenseZoneSource.show = visible
    if (partitionSource) partitionSource.show = visible
    if (commandPostSource) commandPostSource.show = visible
    if (!visible) closePopup()
    deviceEntityIds.forEach(id => {
        const entity = viewer?.entities?.getById(id)
        if (entity) entity.show = visible
    })
}
const setClusterVisibility = visible => {
    clusterVisible.value = visible
    if (aggregationSource) aggregationSource.show = visible
}
const ensureCountyCenterMap = () => {
    if (countyCenterMap.size) return
    const geojson = JSON.parse(jaGeojsonRaw)
    geojson.features?.forEach(feature => {
        const name = feature?.properties?.name
        const center = feature?.properties?.centroid || feature?.properties?.center
        if (!name || !Array.isArray(center) || center.length < 2) return
        countyCenterMap.set(name, { longitude: center[0], latitude: center[1] })
    })
}
@@ -185,7 +279,7 @@
    return positions
}
const addDeviceRings = (center, baseId) => {
const addDeviceRings = (center, baseId, visible) => {
    RING_STYLES.forEach((ring, index) => {
        const outerPositions = buildCirclePositions(center, ring.outer)
        const holes = ring.inner
@@ -200,6 +294,7 @@
        const material = new RadialGradientMaterialProperty(color1, color2)
        viewer.entities.add({
            id: entityId,
            show: visible,
            polygon: {
                hierarchy: new Cesium.PolygonHierarchy(outerPositions, holes),
                material,
@@ -215,26 +310,26 @@
        this.color2 = color2
    }
    get isConstant() {
    get isConstant () {
        return true
    }
    get definitionChanged() {
    get definitionChanged () {
        return this._definitionChanged
    }
    getType() {
    getType () {
        return MATERIAL_TYPE
    }
    getValue(time, result) {
    getValue (time, result) {
        const target = result || {}
        target.color1 = this.color1
        target.color2 = this.color2
        return target
    }
    equals(other) {
    equals (other) {
        return (
            other instanceof RadialGradientMaterialProperty &&
            Cesium.Color.equals(this.color1, other.color1) &&
@@ -251,9 +346,10 @@
        if (!position) return
        const entityId = `online-device-${item.id ?? index}`
        deviceEntityIds.add(entityId)
        addDeviceRings(position, entityId)
        viewer.entities.add({
        addDeviceRings(position, entityId, detailVisible.value)
        const entity = viewer.entities.add({
            id: entityId,
            show: detailVisible.value,
            position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
            billboard: {
                image: equipmentIcon,
@@ -262,7 +358,11 @@
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
        })
        deviceEntityMap.set(entityId, { data: item, entity })
    })
    if (selectedDeviceEntity && !deviceEntityMap.has(selectedDeviceEntity.id)) {
        closePopup()
    }
}
const getDefenseZonePositions = geom => {
@@ -316,6 +416,7 @@
        viewer.dataSources.add(defenseZoneSource)
    }
    clearDefenseZoneEntities()
    defenseZoneSource.show = detailVisible.value
    renderZonePolygons({
        zones,
        source: defenseZoneSource,
@@ -332,6 +433,7 @@
        viewer.dataSources.add(partitionSource)
    }
    clearPartitionEntities()
    partitionSource.show = detailVisible.value
    renderZonePolygons({
        zones,
        source: partitionSource,
@@ -361,6 +463,225 @@
    }
}
const renderAggregation = list => {
    if (!viewer) return
    ensureCountyCenterMap()
    if (!aggregationSource) {
        aggregationSource = new Cesium.CustomDataSource('aggregationSource')
        viewer.dataSources.add(aggregationSource)
    }
    clearAggregationEntities()
    aggregationSource.show = clusterVisible.value
    const countMap = new Map()
        ; (list || []).forEach(item => {
            if (!item?.type) return
            countMap.set(item.type, Number(item.count ?? 0))
        })
    Array.from(countyCenterMap.entries()).forEach(([name, center], index) => {
        const position = Cesium.Cartesian3.fromDegrees(center.longitude, center.latitude, 0)
        const count = countMap.get(name) ?? 0
        aggregationSource.entities.add({
            id: `aggregation-${name}-${index}`,
            position,
            billboard: {
                image: aggregationIcon,
                width: 82.5,
                height: 59.25,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            },
            label: {
                text: `${count}`,
                fillColor: Cesium.Color.WHITE,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                verticalOrigin: Cesium.VerticalOrigin.CENTER,
                horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                font: '12pt Source Han Sans CN',
                eyeOffset: new Cesium.Cartesian3(0, 0, -20), // 让label "浮" 在广告牌前面
                pixelOffset: new Cesium.Cartesian2(2, -11),
                pixelOffset: new Cesium.Cartesian2(0, -48),
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            },
        })
    })
}
const getPickedDevice = picks => {
    for (const pick of picks) {
        const entityId = typeof pick?.id === 'string' ? pick.id : pick?.id?.id
        if (entityId && deviceEntityMap.has(entityId)) {
            return deviceEntityMap.get(entityId)
        }
    }
    return null
}
const updatePopupPosition = () => {
    if (!viewer || !selectedDeviceEntity) return
    const cartesian =
        selectedDeviceEntity.position?.getValue?.(Cesium.JulianDate.now()) ||
        selectedDeviceEntity.position?._value
    if (!cartesian) return
    const screenPosition = viewer.scene.cartesianToCanvasCoordinates(cartesian)
    if (!screenPosition) return
    popupPosition.value = { x: screenPosition.x, y: screenPosition.y }
}
const startPopupRender = () => {
    if (!viewer || popupRenderHandler) return
    popupRenderHandler = () => updatePopupPosition()
    viewer.scene.postRender.addEventListener(popupRenderHandler)
    updatePopupPosition()
}
const stopPopupRender = () => {
    if (!viewer || !popupRenderHandler) return
    viewer.scene.postRender.removeEventListener(popupRenderHandler)
    popupRenderHandler = null
}
const handleDeviceClick = movement => {
    if (!viewer) return
    const picks = viewer.scene.drillPick(movement.position) || []
    const pickedDevice = getPickedDevice(picks)
    if (!pickedDevice) {
        closePopup()
        return
    }
    selectedDevice.value = pickedDevice.data
    selectedDeviceEntity = pickedDevice.entity
    startPopupRender()
}
const initDeviceClickHandler = () => {
    if (deviceClickHandler || !viewer) return
    deviceClickHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    deviceClickHandler.setInputAction(handleDeviceClick, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}
const destroyDeviceClickHandler = () => {
    deviceClickHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    deviceClickHandler?.destroy()
    deviceClickHandler = null
}
function closePopup () {
    selectedDevice.value = null
    selectedDeviceEntity = null
    stopPopupRender()
}
const popupPosition = ref({ x: 0, y: 0 })
const popupVisible = computed(() => Boolean(selectedDevice.value))
const popupStyle = computed(() => ({
    left: `${popupPosition.value.x}px`,
    top: `${popupPosition.value.y}px`,
}))
const popupTitle = computed(() => selectedDevice.value?.deviceName || selectedDevice.value?.deviceModel || '-')
const popupStatusText = computed(() => {
    const status = selectedDevice.value?.status
    if (status === 0) return '在线'
    if (status === 1) return '离线'
    if (status === 2) return '故障'
    if (status === 3) return '报废'
    return '-'
})
const popupStatusClass = computed(() => (selectedDevice.value?.status === 0 ? 'online' : ''))
const popupActionText = computed(() => {
    const workMode = selectedDevice.value?.workMode
    if (workMode === 1 || workMode === '1') return '侦测中'
    if (workMode === 2 || workMode === '2') return '信号干扰中'
    if (workMode === 3 || workMode === '3') return '诱导驱离中'
    if (workMode === 4 || workMode === '4') return '待机'
    return workMode || '-'
})
const popupActionClass = computed(() => {
    const workMode = selectedDevice.value?.workMode
    if (workMode === 1 || workMode === '1') return 'is-detecting'
    if (workMode === 2 || workMode === '2') return 'is-jamming'
    if (workMode === 3 || workMode === '3') return 'is-driving'
    if (workMode === 4 || workMode === '4') return 'is-standby'
    return 'is-standby'
})
const popupTypeText = computed(() => {
    const type = selectedDevice.value?.deviceType
    if (type === 1 || type === '1') return '便捷侦测箱'
    if (type === 2 || type === '2') return '反制枪'
    if (type === 3 || type === '3') return '察打一体'
    return type || '-'
})
const popupBatteryText = computed(() => {
    const val = selectedDevice.value?.batteryPct
    if (val == null) return '-'
    return `${val}%`
})
const popupAzimuthText = computed(() => {
    const val = selectedDevice.value?.azimuth
    if (val == null) return '-'
    return `${val}°`
})
const popupElevationText = computed(() => {
    const val = selectedDevice.value?.elevation
    if (val == null) return '-'
    return `${val}°`
})
const popupDetectCountText = computed(() => {
    const val = selectedDevice.value?.detectTargetCnt
    if (val == null) return '-'
    return `${val}台`
})
const popupRangeText = computed(() => {
    const val = selectedDevice.value?.effectiveRangeKm
    if (val == null) return '-'
    return `${val}KM`
})
const renderCommandPosts = list => {
    if (!viewer) return
    if (!commandPostSource) {
        commandPostSource = new Cesium.CustomDataSource('commandPostSource')
        viewer.dataSources.add(commandPostSource)
    }
    clearCommandPostEntities()
    commandPostSource.show = detailVisible.value
        ; (list || []).forEach((item, index) => {
            const position = getDevicePosition(item)
            if (!position) return
            commandPostSource.entities.add({
                id: `command-post-${item.id ?? index}`,
                position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
                billboard: {
                    image: commandPostIcon,
                    width: 40,
                    height: 56,
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                },
            })
        })
}
const loadAggregation = async () => {
    try {
        const res = await cockpitAggregationApi()
        renderAggregation(res?.data?.data ?? [])
    } catch (error) {
        renderAggregation([])
    }
}
const loadCommandPosts = async () => {
    try {
        const res = await fwDefenseSceneListApi()
        renderCommandPosts(res?.data?.data ?? [])
    } catch (error) {
        renderCommandPosts([])
    }
}
watch(
    () => props.onlineDevices,
@@ -382,11 +703,27 @@
    showLayerPanel.value = !showLayerPanel.value
}
const updateStageDisplay = stage => {
    const showCluster = stage === 'cluster'
    setClusterVisibility(showCluster)
    setDetailVisibility(!showCluster)
}
const handleMapReady = ({ viewer: mapViewer }) => {
    viewer = mapViewer
    const height = viewer?.camera?.positionCartographic?.height
    const stage = height != null && height >= 100000 ? 'cluster' : 'detail'
    updateStageDisplay(stage)
    renderDeviceEntities(props.onlineDevices)
    loadDefenseZones()
    loadPartitions()
    loadAggregation()
    loadCommandPosts()
    initDeviceClickHandler()
}
const handleStageChange = stage => {
    updateStageDisplay(stage)
}
const handleClickOutside = event => {
@@ -407,11 +744,21 @@
    clearDeviceEntities()
    clearDefenseZoneEntities()
    clearPartitionEntities()
    clearAggregationEntities()
    clearCommandPostEntities()
    closePopup()
    destroyDeviceClickHandler()
    viewer = null
})
</script>
<style lang="scss" scoped>
.map-shell {
    position: relative;
    width: 100%;
    height: 100%;
}
.map-container {
    position: absolute;
    top: 0;
@@ -420,6 +767,158 @@
    height: 100%;
}
.device-popup {
    position: absolute;
    transform: translate(-50%, calc(-100% - 72px));
    width: 202px;
    padding: 0 16px 20px;
    border-radius: 16px;
    background: rgba(5, 5, 15, 0.7);
    backdrop-filter: blur(16px);
    color: #C3C3DD;
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-size: 12px;
    pointer-events: auto;
    z-index: 11;
    box-sizing: border-box;
    &::after {
        content: "";
        position: absolute;
        left: 50%;
        bottom: -8px;
        transform: translateX(-50%);
        width: 0;
        height: 0;
        border-left: 8px solid transparent;
        border-right: 8px solid transparent;
        border-top: 8px solid rgba(5, 5, 15, 0.7);
    }
    .device-popup__header {
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        position: relative;
        font-weight: bold;
        font-size: 14px;
        color: #FFFFFF;
        &::after {
            content: "";
            position: absolute;
            left: 0;
            bottom: 0;
            width: 50px;
            height: 2px;
            background: #284FE3;
            box-shadow: 0px 3px 2px 0px rgba(15, 89, 255, 0.1), 0px 7px 5px 0px rgba(15, 89, 255, 0.15), 0px 13px 10px 0px rgba(15, 89, 255, 0.18), 0px 22px 18px 0px rgba(15, 89, 255, 0.21), 0px 42px 33px 0px rgba(15, 89, 255, 0.26), 0px 100px 80px 0px rgba(15, 89, 255, 0.36);
            border-radius: 5px 5px 0px 0px;
        }
        &::before {
            content: "";
            position: absolute;
            left: 55px;
            right: 0;
            bottom: 0;
            height: 2px;
            background: #323245;
            border-radius: 0px 0px 5px 5px;
        }
        .device-popup__close {
            cursor: pointer;
        }
    }
    .device-popup__type {
        display: flex;
        align-items: center;
        gap: 6px;
        font-size: 12px;
        margin-top: 8px;
        margin-bottom: 10px;
        color: #d2d7df;
        .label {
            color: #9aa4b2;
        }
    }
    .device-popup__subtitle {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 2px 10px;
        border-radius: 999px;
        background: rgba(255, 255, 255, 0.06);
        font-size: 12px;
        margin-bottom: 10px;
        .device-popup__dot {
            width: 6px;
            height: 6px;
            border-radius: 50%;
            background: #6b7685;
            &.is-detecting {
                background: #35f08c;
                box-shadow: 0 0 6px rgba(53, 240, 140, 0.8);
            }
            &.is-jamming {
                background: #ff4444;
                box-shadow: 0 0 6px rgba(255, 68, 68, 0.7);
            }
            &.is-driving {
                background: #ffb020;
                box-shadow: 0 0 6px rgba(255, 176, 32, 0.7);
            }
            &.is-standby {
                background: #9aa4b2;
            }
        }
    }
    .device-popup__rows {
        display: flex;
        flex-direction: column;
        gap: 6px;
        font-size: 12px;
        color: #d2d7df;
        .device-popup__row {
            display: flex;
            align-items: center;
            margin-bottom: 10px;
            .device-popup__col {
                flex: 1;
                display: flex;
                align-items: center;
                &:last-child {
                    justify-content: flex-end;
                }
            }
        }
        .value {
            margin-left: 10px;
        }
        .value.online {
            color: #35f08c;
        }
    }
}
.layer-control-root {
    position: absolute;
    left: 337px;
applications/drone-command/src/styles/common/cockpit.scss
@@ -37,8 +37,47 @@
    }
}
.command-radio-group {
    .el-radio {
        .el-radio__input {
            width: 16px;
            height: 16px;
            border: none;
            .el-radio__inner {
                width: 16px;
                height: 16px;
                border: 2px solid #A1A3D4;
                border-radius: 50%;
                background: transparent !important;
                box-sizing: border-box;
            }
        }
        .el-radio__label {
            color: #FFFFFF;
        }
        &.is-checked {
            .el-radio__inner {
                background: #023AFF !important;
                border: none;
                &::after {
                    width: 8px;
                    height: 8px;
                }
            }
            .el-radio__label {
                color: #FFFFFF;
            }
        }
    }
}
// 数据驾驶舱专属
.command-data-cockpit-search-input {
.command-search-input {
    .el-input__wrapper {
        padding: 0 8px !important;
        background: #161B2C;
@@ -61,7 +100,7 @@
    }
}
.command-data-cockpit-date-picker {
.command-date-picker {
    box-shadow: none !important;
    background: #161B2C;
    border: none;
@@ -90,7 +129,7 @@
    }
}
.command-data-cockpit-date-picker-popper {
.command-date-picker-popper {
    background: #161B2C !important;
    border: none !important;
    border-radius: 0px 0px 8px 8px;
@@ -297,7 +336,7 @@
    }
}
.command-data-cockpit-select {
.command-select {
    .el-select__input {
        color: #ffffff !important;
    }
@@ -337,7 +376,7 @@
    }
}
.command-data-cockpit-select-popper.el-select__popper {
.command-select-popper.el-select__popper {
    border: none;
    background: #2E2E48 !important;
@@ -383,13 +422,13 @@
    }
}
.command-data-cockpit-cascader {
.command-cascader {
    .el-input__wrapper {
        --el-input-text-color: #161B2C !important;
    }
}
.command-data-cockpit-cascader-popper.el-cascader__dropdown {
.command-cascader-popper.el-cascader__dropdown {
    border: none;
    background: #2E2E48 !important;
@@ -417,7 +456,7 @@
}
// 树形选择
.command-data-cockpit-tree-select-popper {
.command-tree-select-popper {
    background: #2E2E48 !important;
    border: none !important;
@@ -495,7 +534,7 @@
    }
}
.command-data-cockpit-dialog {
.command-dialog {
    padding: 20px;
    display: flex;
    flex-direction: column;
@@ -550,7 +589,7 @@
        text-transform: none;
    }
    .command-data-cockpit-search-input {
    .command-search-input {
        .el-input__wrapper {
            background: #2E2E48;
        }
@@ -562,11 +601,11 @@
        }
    }
    .command-data-cockpit-date-picker {
    .command-date-picker {
        background: #2E2E48;
    }
    .command-data-cockpit-date-picker-popper {
    .command-date-picker-popper {
        background: #2E2E48 !important;
        .el-picker-panel {
@@ -639,13 +678,13 @@
        text-transform: none;
    }
    .command-data-cockpit-select {
    .command-select {
        .el-select__wrapper {
            background: #1C1C31;
        }
    }
    .command-data-cockpit-search-input {
    .command-search-input {
        .el-input__wrapper {
            background: #1C1C31;
        }
@@ -657,11 +696,11 @@
        }
    }
    .command-data-cockpit-date-picker {
    .command-date-picker {
        background: #1C1C31;
    }
    .command-data-cockpit-date-picker-popper {
    .command-date-picker-popper {
        background: #1C1C31 !important;
        .el-picker-panel {
@@ -799,6 +838,36 @@
        flex: 1;
        display: flex;
        flex-direction: column;
        .el-checkbox {
            width: 16px;
            height: 16px;
            .el-checkbox__input {
                width: 16px;
                height: 16px;
                .el-checkbox__inner {
                    width: 16px;
                    height: 16px;
                    background: transparent !important;
                    border-radius: 2px 2px 2px 2px;
                    border: 2px solid #A1A3D4;
                    box-shadow: none;
                    box-sizing: border-box;
                }
            }
            &.is-checked {
                .el-checkbox__input {
                    .el-checkbox__inner {
                        border: none;
                        background: url("@/assets/images/common/checkbox.png") no-repeat center / 100% 100% !important;
                    }
                }
            }
        }
    }
    .command-table-content-bg {
@@ -806,7 +875,7 @@
    }
}
.command-data-cockpit-table {
.command-table {
    height: 0;
    flex: 1;
    background: transparent !important;
@@ -1066,6 +1135,14 @@
                    .el-input-number {
                        width: 0;
                        flex: 1;
                        .el-input__inner {
                            text-align: left;
                            &::placeholder {
                                text-align: left;
                            }
                        }
                    }
                    .el-cascader {
@@ -1097,11 +1174,11 @@
                        box-shadow: none;
                    }
                    .command-data-cockpit-date-picker {
                    .command-date-picker {
                        background: #2E2E48;
                    }
                    .command-data-cockpit-date-picker-popper {
                    .command-date-picker-popper {
                        background: #2E2E48 !important;
                        .el-picker-panel {
@@ -1371,6 +1448,14 @@
                            .el-input-number {
                                width: 0;
                                flex: 1;
                                .el-input__inner {
                                    text-align: left;
                                    &::placeholder {
                                        text-align: left;
                                    }
                                }
                            }
                            .el-textarea {
@@ -1394,11 +1479,11 @@
                                color: #fff;
                            }
                            .command-data-cockpit-date-picker {
                            .command-date-picker {
                                background: #2E2E48;
                            }
                            .command-data-cockpit-date-picker-popper {
                            .command-date-picker-popper {
                                background: #2E2E48 !important;
                                .el-picker-panel {
applications/drone-command/src/styles/element-ui.scss
@@ -108,662 +108,4 @@
            }
        }
    }
}
.command-drawer-body-basic-container {
    .el-drawer__header {
        margin-bottom: 0;
    }
    .el-drawer__body {
        display: flex;
        flex-direction: column;
    }
}
.command-el-card__body {
    .el-card__body {
        .avue-form {
            padding: 0;
        }
    }
}
.command-public-general-avue-crud {
    .el-table {
        tr {
            min-height: 30px !important;
            line-height: 30px !important;
            box-sizing: border-box !important;
        }
        tr th,
        tr td {
            padding: 6px 0 !important;
            min-height: 30px !important;
            line-height: 30px !important;
            box-sizing: border-box !important;
            div.cell {
                min-height: 30px !important;
                line-height: 30px !important;
            }
        }
    }
}
.command-layer-input {
    .el-input__wrapper {
        padding: 0 8px !important;
        // background: #2D2D2D;
        background-color: transparent !important;
        box-shadow: none !important;
        border: 1px solid #fff;
        .el-input__inner {
            color: #ffffff;
            &::placeholder {
                color: rgba(255, 255, 255, 0.37);
            }
        }
    }
    &.is-disabled {
        .el-input__wrapper {
            background-color: #012a50;
        }
    }
}
.command-button {
    background-color: transparent !important;
    color: #fff !important;
}
.command-el-tree {
    background-color: transparent !important;
    --el-tree-node-hover-bg-color: transparent !important;
    color: #fff !important;
}
.command-layer-search {
    color: #fff !important;
    background-color: transparent !important;
    .el-select__wrapper {
        background-color: transparent !important;
    }
    .el-select__popper.el-popper {
        background-color: transparent !important;
    }
    .el-popper.is-light {
        background-color: transparent !important;
    }
    .el-select__placeholder {
        &.is-transparent {
            color: rgba(255, 255, 255, 0.37) !important;
        }
        &.is-disabled {
            color: rgba(255, 255, 255, 0.37) !important;
        }
    }
    .el-select__selected-item {
        color: #ffffff !important;
        &.is-disabled {
            color: rgba(255, 255, 255, 0.37) !important;
            z-index: 99;
        }
    }
}
.command-select-popper.el-select__popper {
    border: #2D2D2D !important;
    .el-select-dropdown {
        overflow-x: hidden !important;
        .el-scrollbar {
            .el-select-dropdown__wrap {
                background: linear-gradient(180deg, rgba(13, 53, 86, 0.85) 0%, rgba(1, 35, 80, 0.85) 100%);
                border-radius: 0px 0px 8px 8px;
                border: 1px solid;
                border-image: linear-gradient(180deg, #fff, #fff) 1 1;
                overflow-x: hidden !important;
                margin-right: 0 !important;
                .el-select-dropdown__list {
                    padding: 0 !important;
                    .el-select-dropdown__item {
                        background: #2D2D2D !important;
                        color: white;
                        &.hover {
                            background-color: #2D2D2D !important;
                            color: white;
                        }
                        &.selected {
                            color: #fff !important;
                            font-weight: 700;
                        }
                    }
                }
            }
        }
        .el-select-dropdown__empty {
            background: #2D2D2D;
            border-radius: 0px 0px 8px 8px;
            border: 1px solid;
            border-image: linear-gradient(180deg, #fff, #fff) 1 1;
        }
    }
    .el-popper__arrow::before {
        background: #2D2D2D !important;
        border: 1px solid #fff !important;
    }
}
//时间日期选择器
.command-layer-date-picker {
    box-shadow: none !important;
    background: transparent;
    border: 1px solid #fff;
    border-radius: 5px;
    .el-range-editor.is-disabled input {
        background-color: transparent !important;
    }
    .el-range-editor.is-disabled {
        background-color: transparent !important;
    }
    .el-input__wrapper {
        box-shadow: none !important;
        background-color: transparent !important;
        width: 300px;
        &.is-focus {
            box-shadow: none !important;
        }
    }
    .el-range-input {
        color: #fff;
        &::placeholder {
            color: rgba(255, 255, 255, 0.37);
        }
    }
    .el-range-separator {
        color: #ffffff;
    }
}
// 日期下拉框
.command-layer-date-picker-popper {
    background: #012350 !important;
    border: 1px solid !important;
    border-radius: 0px 0px 8px 8px;
    border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
    .el-picker-panel .el-time-panel {
        background: #012350 !important;
    }
    .el-time-spinner__item {
        color: #fff !important;
    }
    .el-time-spinner__item:hover:not(.is-disabled):not(.is-active) {
        background: transparent !important;
    }
    .el-picker-panel {
        .el-picker-panel__body-wrapper {
            .el-picker-panel__body {
                background: #012350 !important;
                color: #fff !important;
                .el-date-picker__time-header {
                    border: none;
                    .el-date-picker__editor-wrap {
                        .el-time-panel {
                            background: #012350 !important;
                            border-radius: 0px 0px 8px 8px;
                            border: 1px solid !important;
                            border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
                            // 将 time-picker-popper 的样式移到这里
                            .el-time-panel__header {
                                background: #012350 !important;
                                color: #ffffff !important;
                                border-bottom: 1px solid rgba(255, 255, 255, 0.37) !important;
                            }
                            .el-time-panel__content {
                                .el-time-spinner__item {
                                    color: #e6e6e6 !important;
                                    &:hover {
                                        background: #012350 !important;
                                    }
                                    &.active {
                                        color: #479dff !important;
                                        font-weight: bold;
                                    }
                                }
                            }
                            .el-time-panel__footer {
                                background: #012350 !important;
                                border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
                                .el-button {
                                    color: #fff !important;
                                    &:hover {
                                        color: #479dff !important;
                                    }
                                }
                                .el-time-panel__btn.cancel {
                                    color: #fff !important;
                                    &:hover {
                                        color: #fff !important;
                                    }
                                }
                            }
                        }
                    }
                }
                .el-picker-panel__content {
                    .el-date-range-picker__header {
                        .el-picker-panel__icon-btn {
                            color: #fff !important;
                            &:hover {
                                color: var(--el-color-primary) !important;
                            }
                            .el-icon {
                                &::before {
                                    color: inherit !important;
                                }
                            }
                        }
                        &>div {
                            span {
                                color: #fff !important;
                            }
                        }
                    }
                    .el-date-table {
                        th {
                            color: #fff !important;
                        }
                        td.disabled div {
                            background-color: #00193b !important;
                            color: #505050 !important;
                            cursor: not-allowed;
                        }
                        // td:hover,
                        // td.current:not(.disabled) {
                        //     background: rgba(60, 121, 202) !important;
                        //     color: white !important;
                        // }
                        td.start-date span,
                        td.start-date span,
                        td.end-date span {
                            background-color: #012350 !important;
                        }
                        td.in-range div,
                        td.in-range div:hover,
                        &.is-week-mode .el-date-table__row.current div,
                        &.is-week-mode .el-date-table__row:hover div {
                            background-color: rgba(60, 121, 202) !important;
                        }
                    }
                }
            }
        }
    }
    .el-popper__arrow {
        &::before {
            background: #0d3556 !important;
            border: 1px solid #0d3556 !important;
            box-sizing: border-box;
        }
    }
    .el-picker-panel__sidebar {
        background: #012350;
        color: #fff;
        .el-picker-panel__shortcut {
            color: #ffffff;
        }
    }
    .el-picker-panel__body {
        .el-input.is-disabled .el-input__wrapper {
            background: #012350;
            box-shadow: 0 0 0 0.1rem#409eff;
            color: #fff;
            .el-input__inner {
                color: #fff !important;
            }
        }
        .el-button.is-disabled,
        .el-button.is-disabled:hover {
            background: #012350;
        }
        .el-input__wrapper {
            background: #012350;
            box-shadow: 0 0 0 0.1rem#409eff;
            color: #fff;
            .el-input__inner {
                color: #fff !important;
            }
        }
    }
    .el-picker-panel__footer {
        background: #012350;
        color: #fff;
        border-top: none;
        .el-button--small {
            box-shadow: 0 0 0 0.1rem#409eff;
            background-color: #012350;
            color: #fff;
            border: none;
            &:hover {
                background-color: #012350;
                color: #fff;
                border-color: #409eff;
            }
        }
    }
}
.command-layer-time-picker-popper {
    background: rgba(0, 0, 0, 0.8) !important;
    border-radius: 0px 0px 8px 8px;
    border: 1px solid !important;
    border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
    .el-popper__arrow::before {
        background: rgba(0, 0, 0, 0.8) !important;
        border: 1px solid #479dff !important;
    }
    .el-time-panel__header {
        background: rgba(0, 0, 0, 0.8) !important;
        color: #ffffff !important;
        border-bottom: 1px solid rgba(71, 157, 255, 0.3) !important;
    }
    .el-time-panel__content {
        // background: #012350 !important;
        .el-time-spinner__item {
            color: #e6e6e6 !important;
            &:hover {
                background: rgba(71, 157, 255, 0.3) !important;
            }
            &.active {
                color: #479dff !important;
                font-weight: bold;
            }
        }
    }
    .el-time-panel__footer {
        background: rgba(0, 0, 0, 0.8) !important;
        border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
        .el-button {
            color: #fff !important;
            &:hover {
                color: #479dff !important;
            }
        }
        .el-time-panel__btn.cancel {
            color: #fff !important;
            &:hover {
                color: #fff !important;
            }
        }
    }
}
.command-custom-qrcode-popover {
    //background: url("@/assets/images/home/eventOverviewDetail/qrCodeBg.png") no-repeat center center !important;
    //background-size: cover !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 5px;
    min-width: 173px !important;
    height: 180px !important;
    /* 隐藏默认箭头 */
    .el-popper__arrow {
        display: none !important;
    }
    /* 调整二维码内容区域样式 */
    .qrcode-content {
        background: #fff;
        padding: 5px;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 146px;
        height: 130px;
        margin-top: 12px;
        .close-btn {
            position: absolute;
            top: 3px;
            right: 3px;
            width: 20px;
            height: 20px;
            color: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 100;
        }
    }
}
.command-dialog-video {
    background: #0f1929;
    box-shadow: inset 0px -50px 50px 0px rgba(27, 148, 255, 0.13);
    border-radius: 20px 0px 0px 0px;
    border: 2px solid;
    padding: 0 !important;
    border-image: linear-gradient(180deg,
            rgba(81, 168, 255, 0),
            rgba(48, 111, 202, 1),
            rgba(255, 255, 255, 1),
            rgba(27, 148, 255, 1)) 2 2;
    .el-dialog__header {
        width: 100%;
        height: 47px;
        //padding: 0;
        margin-bottom: 14px;
        //background: url("/src/assets/images/home/inspection-vector.png") no-repeat center;
        //background-size: 100% 100%;
        font-weight: bold;
        font-size: 16px;
        line-height: 47px;
    }
    .el-dialog__title {
        width: 112px;
        font-family: Segoe UI, Segoe UI;
        font-weight: bold;
        font-size: 16px;
        text-shadow: 0px 0px 5px rgba(154, 218, 255, 0.6);
        text-align: left;
        font-style: normal;
        text-transform: none;
        background: linear-gradient(90deg, #fbfdff 0%, #86d4ff 100%);
        margin-left: 16px;
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
    }
    .el-dialog .el-dialog__header {
        padding: 0px !important;
        padding-left: 0px !important;
    }
    .el-scrollbar__thumb {
        background: #13c6ff !important;
    }
}
//======以下针对表格功能 增删查改样式和弹窗=========
.command-dialog-mange {
    .el-dialog__body {
        padding: 2rem 2rem 4rem;
        flex: 1;
        overflow: scroll;
        border-top: 0.1rem solid #f0f0f0;
    }
    .el-dialog__footer {
        z-index: 2;
        display: block;
        padding: 1rem 1.6rem;
        box-sizing: border-box;
        border-top: 0.1rem solid #f0f0f0;
        width: 100%;
        position: absolute;
        left: 0;
        bottom: 0;
        background-color: #fff;
        text-align: right;
    }
}
.command-search-mange {
    height: 40px;
    .search-contain {
        display: flex;
        justify-content: space-between;
    }
}
.command-form-mange {
    .el-form-item {
        width: 300px;
        .el-form-item__content {
            width: 100%;
        }
        .el-form-item__label {
            width: 120px;
        }
    }
}
.command-form-search {
    .el-form-item {
        width: 100%;
        .el-form-item__label {
            width: 80px;
        }
        .el-form-item__content {
            display: flex;
            flex: 1;
        }
    }
}
.command-table-mange {
    th.el-table__cell {
        color: rgba(0, 0, 0, .85);
        background-color: #fafafa;
    }
}
.table-view-mange {
    width: 100%;
    border-top: 0.1rem solid #ebeef5;
    border-left: 0.1rem solid #ebeef5;
    margin-left: 0;
    margin-right: 0;
    .el-col {
        padding-left: 0;
        padding-right: 0;
        margin-bottom: 0;
        height: 32px;
        line-height: 32px;
        border-right: 0.1rem solid #ebeef5;
        text-align: center;
        align-items: center;
        .el-input__wrapper {
            box-shadow: none !important;
            border-bottom: 0.1rem solid #ebeef5;
        }
    }
    .label {
        color: #909399;
        box-sizing: border-box;
        background: #fafafa;
    }
}
applications/drone-command/src/utils/cesium/publicCesium.js
@@ -2,6 +2,7 @@
import * as Cesium from 'cesium'
import { Cartesian3, Terrain, Viewer } from 'cesium'
import store from '@/store/index'
import jaGeojsonRaw from '@/assets/geojson/ja.geojson?raw'
import getBaseConfig from '@/buildConfig/config'
@@ -32,6 +33,36 @@
/**
 * 公共的Cesium (蓝色,2d)
 */
const DEFAULT_VIEW_RECTANGLE = (() => {
    try {
        const geojson = JSON.parse(jaGeojsonRaw)
        let west = Infinity
        let east = -Infinity
        let south = Infinity
        let north = -Infinity
        const walk = coords => {
            if (!Array.isArray(coords)) return
            if (typeof coords[0] === 'number' && typeof coords[1] === 'number') {
                const lng = coords[0]
                const lat = coords[1]
                if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
                west = Math.min(west, lng)
                east = Math.max(east, lng)
                south = Math.min(south, lat)
                north = Math.max(north, lat)
                return
            }
            coords.forEach(walk)
        }
        geojson?.features?.forEach(feature => walk(feature?.geometry?.coordinates))
        if ([west, east, south, north].every(Number.isFinite)) {
            return Cesium.Rectangle.fromDegrees(west, south, east, north)
        }
    } catch (error) {}
    return Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
})()
// 封装的不用管
let cn = {
@@ -106,7 +137,7 @@
        } = options
        Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
        // 西南东北,默认显示中国
        Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
        Cesium.Camera.DEFAULT_VIEW_RECTANGLE = DEFAULT_VIEW_RECTANGLE
        const viewerOptions = {
            infoBox: false, // 禁用沙箱,解决控制台报错
            animation: false, // 左下角的动画仪表盘
@@ -881,4 +912,4 @@
            this.viewer?.imageryLayers.remove(imageryLayers)
        }
    }
}
}
applications/drone-command/src/views/api.txt
@@ -1,22 +1,33 @@
## 列表
## 信号干扰,诱导驱离
**接口地址**:`/drone-fw/area/fwAreaDivide/list`
**接口地址**:`/drone-fw/cockpit/dataCockpit/interferenceAndExpulsion`
**请求方式**:`GET`
**请求方式**:`POST`
**请求数据类型**:`application/x-www-form-urlencoded`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:<p>传入filterSelected或sceneId</p>
**接口描述**:<p>传入fwEffectEval</p>
**请求示例**:
```javascript
{
  "alarmRecordId": 0,
  "counterWay": ""
}
```
**请求参数**:
@@ -27,8 +38,9 @@
| 参数名称 | 参数说明 | 请求类型    | 是否必须 | 数据类型 | schema |
| -------- | -------- | ----- | -------- | -------- | ------ |
|filterSelected|是否过滤已被选择的数据(1过滤 0不过滤)|query|false|integer(int32)||
|sceneId|场景id|query|false|integer(int64)||
|fwEffectEvalParam|fwEffectEvalParam|body|true|FwEffectEvalParam|FwEffectEvalParam|
|&emsp;&emsp;alarmRecordId|告警记录ID(ja_fw_drone_alarm_record.id)||false|integer(int64)||
|&emsp;&emsp;counterWay|反制方式:1.信号干扰/2.诱导驱离/无||false|string||
**响应状态**:
@@ -36,7 +48,8 @@
| 状态码 | 说明 | schema |
| -------- | -------- | ----- | 
|200|OK|R«List«FwAreaDivide对象»»|
|200|OK|R|
|201|Created||
|401|Unauthorized||
|403|Forbidden||
|404|Not Found||
@@ -48,32 +61,7 @@
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | ----- |----- | 
|code|状态码|integer(int32)|integer(int32)|
|data|承载数据|array|FwAreaDivide对象|
|&emsp;&emsp;areaCode|区域编码|string||
|&emsp;&emsp;areaName|区域名称|string||
|&emsp;&emsp;areaSize|区域面积(km²)|number||
|&emsp;&emsp;areaType|区域类型:报警区/重点管制区|string||
|&emsp;&emsp;controlLevel|管控级别:日常/重点/严密|string||
|&emsp;&emsp;createDept|创建部门|integer(int64)||
|&emsp;&emsp;createTime|创建时间|string(date-time)||
|&emsp;&emsp;createUser|创建人|integer(int64)||
|&emsp;&emsp;deviceIds|关联设备ID,逗号分隔|string||
|&emsp;&emsp;flyDateEnd|可飞行日期时间-结束|string(date-time)||
|&emsp;&emsp;flyDateStart|可飞行日期时间-开始|string(date-time)||
|&emsp;&emsp;geom|经纬度面(存储地理面数据)|string||
|&emsp;&emsp;id|主键id|integer(int64)||
|&emsp;&emsp;isDeleted|是否已删除|integer(int32)||
|&emsp;&emsp;latitude|区域中心纬度|number(double)||
|&emsp;&emsp;longitude|区域中心经度|number(double)||
|&emsp;&emsp;policeStationContactPerson|派出所联系人|string||
|&emsp;&emsp;policeStationContactPhone|派出所联系电话|string||
|&emsp;&emsp;policeStationId|关联派出所id|integer(int64)||
|&emsp;&emsp;policeStationName|派出所名称|string||
|&emsp;&emsp;responseMechanism|响应机制内容|string||
|&emsp;&emsp;status|业务状态|integer(int32)||
|&emsp;&emsp;triggerCondition|触发条件|string||
|&emsp;&emsp;updateTime|更新时间|string(date-time)||
|&emsp;&emsp;updateUser|更新人|integer(int64)||
|data|承载数据|object||
|msg|返回消息|string||
|success|是否成功|boolean||
@@ -82,35 +70,7 @@
```javascript
{
    "code": 0,
    "data": [
        {
            "areaCode": "",
            "areaName": "",
            "areaSize": 0,
            "areaType": "",
            "controlLevel": "",
            "createDept": 0,
            "createTime": "",
            "createUser": 0,
            "deviceIds": "",
            "flyDateEnd": "",
            "flyDateStart": "",
            "geom": "",
            "id": 0,
            "isDeleted": 0,
            "latitude": 0,
            "longitude": 0,
            "policeStationContactPerson": "",
            "policeStationContactPhone": "",
            "policeStationId": 0,
            "policeStationName": "",
            "responseMechanism": "",
            "status": 0,
            "triggerCondition": "",
            "updateTime": "",
            "updateUser": 0
        }
    ],
    "data": {},
    "msg": "",
    "success": true
}
applications/drone-command/src/views/areaManage/areaStatistics/index.vue
@@ -2,12 +2,12 @@
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="区域名称" prop="areaName">
                <el-input class="command-data-cockpit-search-input" v-model="searchParams.areaName" placeholder="请输入"
                <el-input class="command-search-input" v-model="searchParams.areaName" placeholder="请输入"
                    clearable @clear="handleSearch" />
            </el-form-item>
            <el-form-item label="区域类型" prop="areaType">
                <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                <el-select class="command-select" popper-class="command-select-popper"
                    v-model="searchParams.areaType" placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.areaType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
@@ -15,7 +15,7 @@
            </el-form-item>
            <el-form-item label="场景类型" prop="sceneType">
                <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                <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.sceneType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
@@ -30,7 +30,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list">
                <el-table class="command-table" :data="list">
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="areaName" show-overflow-tooltip label="区域名称" />
                    <el-table-column prop="areaType" show-overflow-tooltip label="区域类型">
@@ -58,7 +58,7 @@
            </div>
            <div class="command-table-pagination">
                <el-pagination popper-class="command-data-cockpit-select-popper"
                <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>
applications/drone-command/src/views/areaManage/defenseZone/FormDiaLog.vue
@@ -34,7 +34,7 @@
                    <div class="detail-title">关联场景</div>
                    <div class="command-table-container">
                        <div class="command-table-content">
                            <el-table class="command-data-cockpit-table" :data="sceneList" row-key="id">
                            <el-table class="command-table" :data="sceneList" row-key="id">
                                <el-table-column prop="sceneName" label="场景名称" />
                                <el-table-column prop="sceneType" label="场景类型">
                                    <template v-slot="{ row }">
@@ -49,7 +49,7 @@
                <el-form class="dialog-form" v-else ref="formRef" :model="formData" :rules="rules" :disabled="readonly"
                    label-width="96px">
                    <el-form-item label="防区名称" prop="zoneName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.zoneName" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.zoneName" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                    <el-form-item label="防区面积" prop="zoneArea">
@@ -62,12 +62,12 @@
                                关联场景
                            </div>
                            <el-input class="command-data-cockpit-search-input" v-model="searchName" placeholder="请输入"
                            <el-input class="command-search-input" v-model="searchName" placeholder="请输入"
                                clearable></el-input>
                        </div>
                        <el-form-item prop="defenseSceneIds" label-width="0">
                            <el-table class="command-data-cockpit-table" ref="sceneTableRef"
                            <el-table class="command-table" ref="sceneTableRef"
                                :data="sceneList.filter(item => item.sceneName.includes(searchName))" row-key="id"
                                @selection-change="handleSceneSelectionChange">
                                <el-table-column type="selection" width="55" :reserve-selection="true" />
applications/drone-command/src/views/areaManage/defenseZone/index.vue
@@ -2,7 +2,7 @@
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="防区名称" prop="zoneName">
                <el-input class="command-data-cockpit-search-input" v-model="searchParams.zoneName" placeholder="请输入"
                <el-input class="command-search-input" v-model="searchParams.zoneName" placeholder="请输入"
                    clearable @clear="handleSearch" />
            </el-form-item>
@@ -19,7 +19,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="zoneName" show-overflow-tooltip label="防区名称" />
@@ -38,7 +38,7 @@
            </div>
            <div class="command-table-pagination">
                <el-pagination popper-class="command-data-cockpit-select-popper"
                <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>
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -63,7 +63,7 @@
                    <div class="detail-title">关联设备</div>
                    <div class="command-table-container">
                        <div class="command-table-content">
                            <el-table class="command-data-cockpit-table" ref="deviceTableRef" :data="deviceOptions"
                            <el-table class="command-table" ref="deviceTableRef" :data="deviceOptions"
                                row-key="id">
                                <el-table-column prop="deviceName" label="设备名称" />
                                <el-table-column prop="deviceType" label="类型">
@@ -79,7 +79,7 @@
                <el-form class="dialog-form" v-else ref="formRef" :model="formData" :rules="rules" :disabled="readonly"
                    label-width="96px">
                    <el-form-item label="区域名称" prop="areaName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.areaName" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.areaName" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                    <el-form-item label="区域位置" prop="longitude">
@@ -89,35 +89,35 @@
                        <div class="val">{{ formData.areaSize || '-' }}k㎡</div>
                    </el-form-item>
                    <el-form-item label="区域类型" prop="areaType">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.areaType" placeholder="请选择" clearable>
                            <el-option v-for="item in dictObj.areaType" :key="item.dictKey" :label="item.dictValue"
                                :value="item.dictKey" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="响应机制" prop="responseMechanism">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.responseMechanism"
                        <el-input class="command-search-input" v-model="formData.responseMechanism"
                            maxlength="200" placeholder="请输入" clearable />
                    </el-form-item>
                    <el-form-item label="触发条件" prop="triggerCondition">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.triggerCondition"
                        <el-input class="command-search-input" v-model="formData.triggerCondition"
                            maxlength="200" placeholder="请输入" clearable />
                    </el-form-item>
                    <el-form-item label="管控级别" prop="controlLevel">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.controlLevel" placeholder="请选择" clearable>
                            <el-option v-for="item in dictObj.controlLevel" :key="item.dictKey" :label="item.dictValue"
                                :value="item.dictKey" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="可飞行时段" prop="flyDateStart">
                        <el-date-picker class="command-data-cockpit-date-picker"
                            popper-class="command-data-cockpit-date-picker-popper" v-model="flyDateRange"
                        <el-date-picker class="command-date-picker"
                            popper-class="command-date-picker-popper" v-model="flyDateRange"
                            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="policeStationId">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.policeStationId" placeholder="请选择" clearable>
                            <el-option v-for="item in policeStationOptions" :key="item.id" :label="item.stationName"
                                :value="item.id" />
@@ -130,12 +130,12 @@
                                关联设备
                            </div>
                            <el-input class="command-data-cockpit-search-input" v-model="searchName" placeholder="请输入"
                            <el-input class="command-search-input" v-model="searchName" placeholder="请输入"
                                clearable></el-input>
                        </div>
                        <el-form-item prop="deviceIds" label-width="0">
                            <el-table class="command-data-cockpit-table" ref="deviceTableRef"
                            <el-table class="command-table" ref="deviceTableRef"
                                :data="deviceOptions.filter(item => item.deviceName.includes(searchName))" row-key="id"
                                @selection-change="handleDeviceSelectionChange">
                                <el-table-column type="selection" width="55" :reserve-selection="true" />
applications/drone-command/src/views/areaManage/partition/index.vue
@@ -2,12 +2,12 @@
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="区域名称" prop="areaName">
                <el-input class="command-data-cockpit-search-input" v-model="searchParams.areaName" placeholder="请输入"
                <el-input class="command-search-input" v-model="searchParams.areaName" placeholder="请输入"
                    clearable @clear="handleSearch" />
            </el-form-item>
            <el-form-item label="区域类型" prop="areaType">
                <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                <el-select class="command-select" popper-class="command-select-popper"
                    v-model="searchParams.areaType" placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.areaType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
@@ -27,7 +27,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="areaName" show-overflow-tooltip width="150" label="区域名称" />
@@ -66,7 +66,7 @@
            </div>
            <div class="command-table-pagination">
                <el-pagination popper-class="command-data-cockpit-select-popper"
                <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>
applications/drone-command/src/views/areaManage/precinctInfo/FormDiaLog.vue
@@ -26,19 +26,19 @@
            <el-row>
                <el-col :span="12">
                    <el-form-item label="派出所名称" prop="stationName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.stationName" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.stationName" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="联系人" prop="contactPerson">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.contactPerson" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.contactPerson" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="联系方式" prop="contactPhone">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.contactPhone" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.contactPhone" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
applications/drone-command/src/views/areaManage/precinctInfo/index.vue
@@ -2,7 +2,7 @@
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="派出所名称" prop="stationName">
                <el-input class="command-data-cockpit-search-input" v-model="searchParams.stationName" placeholder="请输入"
                <el-input class="command-search-input" v-model="searchParams.stationName" placeholder="请输入"
                    clearable @clear="handleSearch" />
            </el-form-item>
@@ -19,7 +19,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="stationName" show-overflow-tooltip label="派出所名称" />
@@ -38,7 +38,7 @@
            </div>
            <div class="command-table-pagination">
                <el-pagination popper-class="command-data-cockpit-select-popper"
                <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>
applications/drone-command/src/views/areaManage/sceneConfig/FormDiaLog.vue
@@ -53,7 +53,7 @@
                    <div class="detail-title">关联区域</div>
                    <div class="command-table-container">
                        <div class="command-table-content">
                            <el-table class="command-data-cockpit-table" ref="areaTableRef" :data="areaList" row-key="id">
                            <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 }">
@@ -68,29 +68,29 @@
                <el-form class="dialog-form" v-else ref="formRef" :model="formData" :rules="rules" :disabled="readonly"
                    label-width="96px">
                    <el-form-item label="场景名称" prop="sceneName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.sceneName" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.sceneName" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                    <el-form-item label="指挥点位置" prop="longitude">
                        <div class="val">{{ formatLocation(formData) }}</div>
                    </el-form-item>
                    <el-form-item label="场景类型" prop="sceneType">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.sceneType" placeholder="请选择" clearable>
                            <el-option v-for="item in dictObj.sceneType" :key="item.dictKey" :label="item.dictValue"
                                :value="item.dictKey" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="负责人" prop="defenseLeader">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.defenseLeader" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.defenseLeader" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                    <el-form-item label="负责人电话" prop="leaderPhone">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.leaderPhone" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.leaderPhone" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                    <el-form-item label="设备模式" prop="deviceMode">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.deviceMode" placeholder="请选择" clearable>
                            <el-option v-for="item in dictObj.deviceMode" :key="item.dictKey" :label="item.dictValue"
                                :value="item.dictKey" />
@@ -106,12 +106,12 @@
                                关联区域
                            </div>
                            <el-input class="command-data-cockpit-search-input" v-model="searchName" placeholder="请输入"
                            <el-input class="command-search-input" v-model="searchName" placeholder="请输入"
                                clearable></el-input>
                        </div>
                        <el-form-item prop="areaDivideIds" label-width="0">
                            <el-table class="command-data-cockpit-table" ref="areaTableRef"
                            <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" />
applications/drone-command/src/views/areaManage/sceneConfig/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="场景名称" prop="sceneName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.sceneName"
                    placeholder="请输入"
                    clearable
@@ -13,8 +13,8 @@
            <el-form-item label="场景类型" prop="sceneType">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.sceneType"
                    placeholder="请选择"
                    clearable
@@ -31,8 +31,8 @@
            <el-form-item label="场景状态" prop="status">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.status"
                    placeholder="请选择"
                    clearable
@@ -60,7 +60,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
@@ -92,7 +92,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/basicManage/deviceScrap/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="设备名称" prop="deviceName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.deviceName"
                    placeholder="请输入"
                    clearable
@@ -13,8 +13,8 @@
            <el-form-item label="设备类型" prop="deviceType">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.deviceType"
                    placeholder="请选择"
                    clearable
@@ -31,8 +31,8 @@
            <el-form-item label="所属部门" prop="belongDept">
                <el-tree-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-tree-select-popper"
                    class="command-select"
                    popper-class="command-tree-select-popper"
                    v-model="searchParams.belongDept"
                    :data="deptTree"
                    :props="treeProps"
@@ -51,7 +51,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list">
                <el-table class="command-table" :data="list">
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="deviceName" show-overflow-tooltip label="设备名称" />
                    <el-table-column prop="deviceType" show-overflow-tooltip label="设备类型">
@@ -82,7 +82,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/basicManage/deviceStock/DeviceScrapDiaLog.vue
@@ -4,17 +4,17 @@
            <el-row>
                <el-col :span="24">
                    <el-form-item label="报废原因" prop="scrapReason">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.scrapReason" maxlength="200" type="textarea" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.scrapReason" maxlength="200" type="textarea" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="处置方式" prop="disposeWay">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.disposeWay" maxlength="200" type="textarea" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.disposeWay" maxlength="200" type="textarea" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="报废时间" prop="scrapTime">
                        <el-date-picker class="command-data-cockpit-date-picker" popper-class="command-data-cockpit-date-picker-popper"
                        <el-date-picker class="command-date-picker" popper-class="command-date-picker-popper"
                            v-model="formData.scrapTime"
                            type="datetime"
                            placeholder="选择日期"
applications/drone-command/src/views/basicManage/deviceStock/DeviceTrackDiaLog.vue
@@ -4,21 +4,21 @@
            <el-row>
                <el-col :span="12">
                    <el-form-item label="负责人" prop="charger">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper" v-model="formData.charger" placeholder="请选择" clearable>
                        <el-select class="command-select" popper-class="command-select-popper" v-model="formData.charger" placeholder="请选择" clearable>
                            <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.name" />
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="联系电话" prop="contactPhone">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.contactPhone" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.contactPhone" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="出库去向" prop="outTarget">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.outTarget"
                            placeholder="请选择"
                            clearable
@@ -29,7 +29,7 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="出库时间" prop="outTime">
                        <el-date-picker class="command-data-cockpit-date-picker" popper-class="command-data-cockpit-date-picker-popper"
                        <el-date-picker class="command-date-picker" popper-class="command-date-picker-popper"
                            v-model="formData.outTime"
                            type="date"
                            placeholder="选择日期"
@@ -40,7 +40,7 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="用途" prop="purpose">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.purpose" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.purpose" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
            </el-row>
applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue
@@ -53,7 +53,7 @@
            <div class="detail-title">设备跟踪流转</div>
            <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
                <div class="command-table-content">
                    <el-table class="command-data-cockpit-table" :data="list">
                    <el-table class="command-table" :data="list">
                        <el-table-column type="index" width="60" label="序号" />
                        <el-table-column prop="charger" label="用户" />
                        <el-table-column prop="contactPhone" label="电话" />
@@ -64,7 +64,7 @@
                </div>
                <div class="command-table-pagination">
                    <el-pagination popper-class="command-data-cockpit-select-popper"
                    <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>
@@ -75,13 +75,13 @@
            <el-row>
                <el-col :span="12">
                    <el-form-item label="设备名称" prop="deviceName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.deviceName" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.deviceName" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="设备类型" prop="deviceType">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.deviceType" placeholder="请选择" clearable>
                            <el-option v-for="item in dictObj.deviceType" :key="item.dictKey" :label="item.dictValue"
                                :value="item.dictKey" />
@@ -90,7 +90,7 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="设备属性" prop="deviceAtt">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.deviceAtt" placeholder="请选择" clearable>
                            <el-option v-for="item in dictObj.deviceAtt" :key="item.dictKey" :label="item.dictValue"
                                :value="item.dictKey" />
@@ -99,45 +99,45 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="型号" prop="deviceModel">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.deviceModel" maxlength="50"
                        <el-input class="command-search-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-data-cockpit-search-input" v-model="formData.deviceSpecification"
                        <el-input class="command-search-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-data-cockpit-search-input" v-model="formData.manufacturer" maxlength="50"
                        <el-input class="command-search-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-data-cockpit-search-input" v-model="formData.source" maxlength="50"
                        <el-input class="command-search-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-data-cockpit-search-input" v-model="formData.purpose" maxlength="50"
                        <el-input class="command-search-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-data-cockpit-select"
                            popper-class="command-data-cockpit-tree-select-popper" v-model="formData.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-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="负责人" prop="charger">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.charger" placeholder="请选择" :disabled="!formData.belongDept" clearable>
                            <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.name" />
                        </el-select>
@@ -145,7 +145,7 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="联系电话" prop="contactPhone">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.contactPhone" maxlength="50"
                        <el-input class="command-search-input" v-model="formData.contactPhone" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
applications/drone-command/src/views/basicManage/deviceStock/index.vue
@@ -9,7 +9,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="设备名称" prop="deviceName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.deviceName"
                    placeholder="请输入"
                    clearable
@@ -19,8 +19,8 @@
            <el-form-item label="设备类型" prop="deviceType">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.deviceType"
                    placeholder="请选择"
                    clearable
@@ -37,8 +37,8 @@
            <el-form-item label="所属部门" prop="belongDept">
                <el-tree-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-tree-select-popper"
                    class="command-select"
                    popper-class="command-tree-select-popper"
                    v-model="searchParams.belongDept"
                    :data="deptTree"
                    :props="treeProps"
@@ -61,7 +61,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="deviceName" show-overflow-tooltip width="130" label="设备名称" />
@@ -101,7 +101,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/basicManage/maintainRecord/FormDiaLog.vue
@@ -49,7 +49,7 @@
            <div class="detail-title">维护详情</div>
            <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
                <div class="command-table-content">
                    <el-table class="command-data-cockpit-table" :data="list">
                    <el-table class="command-table" :data="list">
                        <el-table-column type="index" width="60" label="序号" />
                        <el-table-column prop="maintainTime" label="维护时间" />
                        <el-table-column prop="maintainContent" label="维护内容" />
@@ -58,7 +58,7 @@
                </div>
                <div class="command-table-pagination">
                    <el-pagination popper-class="command-data-cockpit-select-popper"
                    <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>
@@ -70,7 +70,7 @@
            <el-row>
                <el-col :span="12">
                    <el-form-item label="选择设备" prop="deviceId">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.deviceId" placeholder="请选择" filterable clearable>
                            <el-option v-for="item in deviceList" :key="item.id" :label="item.deviceName"
                                :value="item.id" />
@@ -79,7 +79,7 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="维护计划周期" prop="planCycleType">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.planCycleType" placeholder="请选择" clearable
                            @change="formData.planCycleValue = []">
                            <el-option v-for="item in planCycleOptions" :key="item.value" :label="item.label"
@@ -89,7 +89,7 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="维护计划时间" prop="planCycleValue">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                        <el-select class="command-select" popper-class="command-select-popper"
                            v-model="formData.planCycleValue" placeholder="请选择" clearable multiple
                            :disabled="!formData.planCycleType">
                            <el-option v-for="item in planCycleValueOptions" :key="item.value" :label="item.value"
applications/drone-command/src/views/basicManage/maintainRecord/MaintenanceDiaLog.vue
@@ -32,7 +32,7 @@
                <el-col :span="24">
                    <el-form-item label="维护内容" prop="maintainContent">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.maintainContent"
                            maxlength="200"
                            type="textarea"
@@ -44,7 +44,7 @@
                <el-col :span="24">
                    <el-form-item label="更换部件" prop="replacePart">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.replacePart"
                            maxlength="200"
                            type="textarea"
@@ -56,8 +56,8 @@
                <el-col :span="12">
                    <el-form-item label="实际维护时间" prop="maintainTime">
                        <el-date-picker
                            class="command-data-cockpit-date-picker"
                            popper-class="command-data-cockpit-date-picker-popper"
                            class="command-date-picker"
                            popper-class="command-date-picker-popper"
                            v-model="formData.maintainTime"
                            type="datetime"
                            placeholder="选择日期"
applications/drone-command/src/views/basicManage/maintainRecord/index.vue
@@ -2,12 +2,12 @@
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="设备名称" prop="deviceName">
                <el-input class="command-data-cockpit-search-input" v-model="searchParams.deviceName" placeholder="请输入"
                <el-input class="command-search-input" v-model="searchParams.deviceName" placeholder="请输入"
                    clearable @clear="handleSearch" />
            </el-form-item>
            <el-form-item label="设备类型" prop="deviceType">
                <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                <el-select class="command-select" popper-class="command-select-popper"
                    v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.deviceType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
@@ -15,7 +15,7 @@
            </el-form-item>
            <el-form-item label="所属部门" prop="belongDept">
                <el-tree-select class="command-data-cockpit-select" popper-class="command-data-cockpit-tree-select-popper"
                <el-tree-select class="command-select" popper-class="command-tree-select-popper"
                    v-model="searchParams.belongDept" :data="deptTree" :props="treeProps" node-key="id" check-strictly
                    clearable @change="handleSearch" />
            </el-form-item>
@@ -33,7 +33,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column prop="deviceName" show-overflow-tooltip label="设备名称" />
                    <el-table-column prop="deviceType" show-overflow-tooltip label="设备类型">
@@ -62,7 +62,7 @@
            </div>
            <div class="command-table-pagination">
                <el-pagination popper-class="command-data-cockpit-select-popper"
                <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>
applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue
@@ -1,26 +1,26 @@
<template>
    <el-dialog class="command-data-cockpit-dialog" append-to-body v-model="visibleModel" :title="dialogTitle"
    <el-dialog class="command-dialog" append-to-body v-model="visibleModel" :title="dialogTitle"
        :close-on-click-modal="false" :destroy-on-close="true">
        <el-form ref="queryParamsRef" :model="searchParams" class="command-dialog-history-search">
            <el-form-item label="关键字" prop="keyword">
                <el-input class="command-data-cockpit-search-input" v-model="searchParams.keyword" placeholder="名称/序列号"
                <el-input class="command-search-input" v-model="searchParams.keyword" placeholder="名称/序列号"
                    clearable @clear="handleSearch" />
            </el-form-item>
            <el-form-item prop="dateRange">
                <el-date-picker class="command-data-cockpit-date-picker"
                    popper-class="command-data-cockpit-tree-select-popper" v-model="searchParams.dateRange"
                <el-date-picker class="command-date-picker"
                    popper-class="command-date-picker-popper" v-model="searchParams.dateRange"
                    type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
                    value-format="YYYY/MM/DD" @change="handleSearch" />
            </el-form-item>
            <el-form-item label="区域" prop="area">
                <el-tree-select class="command-data-cockpit-select" popper-class="command-data-cockpit-tree-select-popper"
                <el-tree-select class="command-select" popper-class="command-tree-select-popper"
                    v-model="searchParams.area" :data="areaTree" :props="areaTreeProps" node-key="value" check-strictly filterable :filter-node-method="filterAreaNode" clearable placeholder="请选择" @change="handleSearch" />
            </el-form-item>
            <el-form-item label="无人机类型" prop="droneType">
                <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper"
                <el-select class="command-select" popper-class="command-select-popper"
                    v-model="searchParams.droneType" placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.droneType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
@@ -35,7 +35,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content">
                <el-table class="command-data-cockpit-table" :data="list">
                <el-table class="command-table" :data="list">
                    <el-table-column type="index" width="60" label="序号" />
                    <el-table-column prop="droneName" label="无人机名称" min-width="120" />
                    <el-table-column prop="droneSerialNo" label="无人机序列号" min-width="140" />
@@ -62,7 +62,7 @@
            </div>
            <div class="command-table-pagination">
                <el-pagination popper-class="command-data-cockpit-select-popper"
                <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>
@@ -96,7 +96,7 @@
})
const dialogTitle = computed(() => {
    return `反制设备名称 ${props.device?.name || ''}`.trim()
    return `${props.device?.name || ''}`.trim()
})
const initSearchParams = () => ({
applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue
@@ -15,14 +15,16 @@
        element-loading-background="rgba(5, 5, 15, 0.6)"
        element-loading-text="加载中..."
    >
        <EmptyState v-if="!equipmentWarningData.length" />
        <EquipmentTemplate
            v-else
            v-for="(item, ind) in equipmentWarningData"
            :key="ind"
            :data="item"
            @click="onCardClick"
        />
        <div class="list-content">
            <EmptyState v-if="!equipmentWarningData.length" />
            <EquipmentTemplate
                v-else
                v-for="(item, ind) in equipmentWarningData"
                :key="ind"
                :data="item"
                @click="onCardClick"
            />
        </div>
    </div>
</template>
@@ -94,8 +96,17 @@
<style lang="scss" scoped>
.equipment-warning {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.list-content {
    height: 0;
    flex: 1;
    overflow-y: auto;
}
</style>
applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue
@@ -8,14 +8,14 @@
        <!-- 搜索区(设计稿红框) -->
        <div class="search-box">
            <!-- 关键字 -->
            <el-input v-model="query.keyword" class="command-data-cockpit-search-input" placeholder="请输入数据名称" clearable
            <el-input v-model="query.keyword" class="command-search-input" placeholder="请输入数据名称" clearable
                @keyup.enter="onSearch">
            </el-input>
            <!-- 日期范围 -->
            <el-date-picker v-model="query.dateRange" 
                  class="command-data-cockpit-date-picker"
                 popper-class="command-data-cockpit-date-picker-popper"
                  class="command-date-picker"
                 popper-class="command-date-picker-popper"
                type="daterange" 
                range-separator="~"
                start-placeholder="创建开始日期" end-placeholder="结束日期" format="YYYY年MM月DD日" value-format="YYYY-MM-DD"
@@ -103,13 +103,14 @@
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
    .search-box {
        display: flex;
        flex-direction: column;
        gap: 10px;
        ::v-deep(.command-data-cockpit-date-picker) {
        ::v-deep(.command-date-picker) {
            width: 100% !important;
        }
    }
@@ -117,6 +118,7 @@
    .list-content {
        height: 0;
        flex: 1;
        overflow-y: auto;
    }
}
applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
@@ -113,7 +113,7 @@
.collapse-btn {
    position: absolute;
    top: 50%;
    bottom: 454px;
    left: 300px;
    cursor: pointer;
    display: flex;
@@ -121,11 +121,11 @@
    justify-content: center;
    color: #fff;
    z-index: 10;
    transform: translateY(-50%);
    transform: translateY(50%);
    .arrow {
        width: 32px;
        height: 32px;
        width: 36px;
        height: 36px;
        background: url('@/assets/images/dataCockpit/left-btn.png') center / 100% 100% no-repeat;
    }
@@ -213,7 +213,6 @@
    height: 0;
    flex: 1;
    margin-top: 20px;
    overflow-x: hidden;
    overflow-y: auto;
    overflow: hidden;
}
</style>
applications/drone-command/src/views/dataCockpit/components/RealWarning.vue
@@ -2,7 +2,7 @@
 * @Author       : yuan
 * @Date         : 2026-01-08 09:29:07
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-08 14:49:09
 * @LastEditTime : 2026-01-19 11:31:09
 * @FilePath     : \applications\drone-command\src\views\dataCockpit\components\RealWarning.vue
 * @Description  : 
 * Copyright 2026 OBKoro1, All Rights Reserved. 
@@ -15,16 +15,18 @@
        element-loading-background="rgba(5, 5, 15, 0.6)"
        element-loading-text="加载中..."
    >
        <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="() => console.log('收藏', item.id)"
        />
        <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="() => console.log('收藏', item.id)"
            />
        </div>
    </div>
</template>
@@ -46,8 +48,7 @@
const buildPayload = (type, item) => ({
    counterWay: type === 'signal' ? 1 : type === 'counter' ? 2 : '',
    deviceId: item.deviceId,
    droneDeviceCode: item.droneDeviceCode ?? item.droneSerialNo
    alarmRecordId: item?.alarmRecordId ?? item?.id
})
const handleAction = async (type, item) => {
@@ -56,6 +57,7 @@
        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}失败` })
        }
@@ -88,8 +90,16 @@
<style lang="scss" scoped>
.real-warning {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.list-content {
    height: 0;
    flex: 1;
    overflow-y: auto;
}
</style>
applications/drone-command/src/views/dataCockpit/components/RightContainer.vue
@@ -2,7 +2,7 @@
 * @Author       : yuan
 * @Date         : 2026-01-07 15:17:54
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-16 17:23:06
 * @LastEditTime : 2026-01-19 14:05:35
 * @FilePath     : \applications\drone-command\src\views\dataCockpit\components\RightContainer.vue
 * @Description  : 
 * Copyright 2026 OBKoro1, All Rights Reserved. 
@@ -134,6 +134,7 @@
        azimuth: item.azimuth ?? 0,
        elevation: item.elevation ?? 0,
        status: item.status ?? '-',
        workMode: item.workMode ?? '-',
        manufacturer: item.manufacturer || '-',
        detectTargetCnt: item.detectTargetCnt ?? 0,
        effectiveRangeKm: item.effectiveRangeKm ?? 0
@@ -265,7 +266,7 @@
.collapse-btn {
    position: absolute;
    top: 50%;
    bottom: 454px;
    right: 300px;
    cursor: pointer;
    display: flex;
@@ -273,11 +274,11 @@
    justify-content: center;
    color: #fff;
    z-index: 10;
    transform: translateY(-50%);
    transform: translateY(50%);
    .arrow {
        width: 32px;
        height: 32px;
        width: 36px;
        height: 36px;
        background: url('@/assets/images/dataCockpit/right-btn.png') center / 100% 100% no-repeat;
    }
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue
@@ -6,12 +6,12 @@
                <span class="name">{{ data.name }}</span>
                <span class="status">
                    <span :class="getStatusType(data.status)">
                    <span :class="getWorkModeType(data.workMode)">
                    </span>
                    <span>
                        {{ getStatusText(data.status) }}
                        {{ getWorkModeText(data.workMode) }}
                    </span>
                </span>
            </div>
@@ -90,9 +90,19 @@
    return value || '-'
}
const getStatusType = (value) => {
    if (value === 0 || value === '0') return 'detecting'
const getWorkModeText = (value) => {
    if (value === 1 || value === '1') return '侦测中'
    if (value === 2 || value === '2') return '信号干扰中'
    if (value === 3 || value === '3') return '诱导驱离中'
    if (value === 4 || value === '4') return '待机'
    return value || '-'
}
const getWorkModeType = (value) => {
    if (value === 1 || value === '1') return 'detecting'
    if (value === 2 || value === '2') return 'jamming'
    if (value === 3 || value === '3') return 'driving'
    if (value === 4 || value === '4') return 'standby'
    return ''
}
</script>
@@ -164,6 +174,20 @@
                    background: #FF4444;
                    border-radius: 50%;
                }
                span.driving {
                    width: 4px;
                    height: 4px;
                    background: #FFB020;
                    border-radius: 50%;
                }
                span.standby {
                    width: 4px;
                    height: 4px;
                    background: #9AA4B2;
                    border-radius: 50%;
                }
            }
        }
    }
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue
@@ -57,8 +57,8 @@
        </div>
        <div class="footer">
            <el-button class="general" color="#2B2B4C" @click="emit('signal')">信号干扰</el-button>
            <el-button color="#284FE3" type="primary" @click="emit('counter')">诱导驱离</el-button>
            <el-button v-if="showSignalBtn(data)" class="general" color="#2B2B4C" @click="emit('signal')">信号干扰</el-button>
            <el-button v-if="showCounterBtn(data)" color="#284FE3" type="primary" @click="emit('counter')">诱导驱离</el-button>
        </div>
    </div>
</template>
@@ -90,6 +90,21 @@
    return 'detecting'
}
const normalizeCounterWay = (value) => {
    if (value == null) return ''
    return String(value).trim()
}
const showSignalBtn = (item) => {
    const counterWay = normalizeCounterWay(item?.counterWay)
    return counterWay !== '1'
}
const showCounterBtn = (item) => {
    const counterWay = normalizeCounterWay(item?.counterWay)
    return counterWay !== '2'
}
const getDataSource = (item) => {
    return item?.deviceName || item?.areaName || '-'
}
applications/drone-command/src/views/detectionCountermeasure/countermeasureEvaluation/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="设备名称" prop="deviceName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.deviceName"
                    placeholder="请输入"
                    clearable
@@ -13,8 +13,8 @@
            <el-form-item label="设备类型" prop="deviceType">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.deviceType"
                    placeholder="请选择"
                    clearable
@@ -31,8 +31,8 @@
            <el-form-item label="反制效果" prop="counterEffect">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.counterEffect"
                    placeholder="请选择"
                    clearable
@@ -55,7 +55,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list">
                <el-table class="command-table" :data="list">
                    <el-table-column type="index" width="64" show-overflow-tooltip label="序号" />
                    <el-table-column prop="droneName" show-overflow-tooltip width="130" label="无人机名称" />
                    <el-table-column prop="droneType" show-overflow-tooltip width="130" label="无人机类型" />
@@ -101,7 +101,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/detectionCountermeasure/detectionRange/DetectionRangeDialog.vue
@@ -55,8 +55,8 @@
                <el-form v-else ref="formRef" class="dialog-form" :model="formData" :rules="rules" label-width="110px">
                    <el-form-item label="侦测设备" prop="deviceId">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.deviceId"
                            placeholder="请选择"
                            clearable
@@ -67,8 +67,8 @@
                    </el-form-item>
                    <el-form-item label="设备类型" prop="deviceType">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.deviceType"
                            placeholder="请选择"
                            clearable
@@ -83,7 +83,7 @@
                    </el-form-item>
                    <el-form-item label="设备位置" prop="deployLocation">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.deployLocation"
                            disabled
                            placeholder="请选择位置"
@@ -95,7 +95,7 @@
                    </el-form-item>
                    <el-form-item label="设备编号" prop="deviceSn">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.deviceSn"
                            placeholder="请输入"
                            clearable
@@ -103,7 +103,7 @@
                    </el-form-item>
                    <el-form-item label="设备型号" prop="deviceModel">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.deviceModel"
                            placeholder="请输入"
                            clearable
@@ -111,7 +111,7 @@
                    </el-form-item>
                    <el-form-item label="覆盖范围(m)" prop="effectiveRangeKm">
                        <el-input-number
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.effectiveRangeKm"
                            :min="0"
                            :precision="2"
@@ -148,7 +148,8 @@
} from '@/api/detectionCountermeasure/detectionRange'
import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
import * as Cesium from 'cesium'
import deviceZcImg from '@/assets/images/dataCockpit/device-zc.svg'
import commandPost from '@/assets/images/dataCockpit/legend/command-post.png'
const initForm = () => ({
    deviceId: '', // 侦测设备ID
@@ -276,9 +277,9 @@
        redPointEntity = viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
            billboard: {
                image: deviceZcImg, // 这里替换为你的图片路径或变量 deviceZcImg
                width: 30, // 可选:设置图片宽度
                height: 42, // 可选:设置图片高度
                image: commandPost, // 这里替换为你的图片路径或变量 deviceZcImg
                width: 40,
                height: 56,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 设置图片底部对齐坐标点
            },
            label: {
@@ -293,7 +294,7 @@
                verticalOrigin: Cesium.VerticalOrigin.CENTER,
                outlineWidth: 1,
                outlineColor: Cesium.Color.WHITE,
                pixelOffset: new Cesium.Cartesian2(0, -60),
                pixelOffset: new Cesium.Cartesian2(0, -72),
                eyeOffset: new Cesium.Cartesian3(0, 0, -20),
            },
        })
@@ -335,7 +336,7 @@
                material: Cesium.Color.fromCssColorString('#6b9ca8').withAlpha(0.6),
                outline: true,
                outlineColor: Cesium.Color.fromCssColorString('#6b9ca8').withAlpha(0.6),
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                heightReference: Cesium.HeightReference.NONE,
            },
        })
        return
applications/drone-command/src/views/detectionCountermeasure/detectionRange/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="设备名称" prop="deviceName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.deviceName"
                    placeholder="请输入"
                    clearable
@@ -13,8 +13,8 @@
            <el-form-item label="设备类型" prop="deviceType">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.deviceType"
                    placeholder="请选择"
                    clearable
@@ -41,7 +41,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list">
                <el-table class="command-table" :data="list">
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="deviceName" show-overflow-tooltip label="设备名称" />
                    <el-table-column prop="deviceType" show-overflow-tooltip label="设备类型">
@@ -77,7 +77,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/detectionCountermeasure/deviceAppConfig/FormDiaLog.vue
@@ -51,7 +51,7 @@
                <el-col :span="12">
                    <el-form-item label="起始扇区" prop="startSector">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.startSector"
                            maxlength="50"
                            placeholder="请输入"
@@ -62,7 +62,7 @@
                <el-col :span="12">
                    <el-form-item label="终止扇区" prop="endSector">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.endSector"
                            maxlength="50"
                            placeholder="请输入"
@@ -73,8 +73,8 @@
                <el-col :span="12">
                    <el-form-item label="搜索模式" prop="searchMode">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.searchMode"
                            placeholder="请选择"
                            clearable
@@ -86,7 +86,7 @@
                <el-col :span="12">
                    <el-form-item label="雷达频点" prop="radarFreq">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.radarFreq"
                            maxlength="50"
                            placeholder="请输入"
@@ -98,8 +98,8 @@
                <el-col :span="12">
                    <el-form-item label="伺服模式" prop="servoMode">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.servoMode"
                            placeholder="请选择"
                            clearable
@@ -111,8 +111,8 @@
                <el-col :span="12">
                    <el-form-item label="伺服数据模式" prop="servoDataMode">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.servoDataMode"
                            placeholder="请选择"
                            clearable
@@ -129,8 +129,8 @@
                <el-col :span="12">
                    <el-form-item label="轴选择" prop="axisSelect">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.axisSelect"
                            placeholder="请选择"
                            clearable
@@ -142,7 +142,7 @@
                <el-col :span="12">
                    <el-form-item label="伺服转速度" prop="servoTurnSpeed">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.servoTurnSpeed"
                            maxlength="50"
                            placeholder="请输入"
applications/drone-command/src/views/detectionCountermeasure/deviceAppConfig/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="设备名称" prop="deviceName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.deviceName"
                    placeholder="请输入"
                    clearable
@@ -13,8 +13,8 @@
            <el-form-item label="设备类型" prop="deviceType">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.deviceType"
                    placeholder="请选择"
                    clearable
@@ -31,8 +31,8 @@
            <el-form-item label="设备状态" prop="deviceStatus">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.deviceStatus"
                    placeholder="请选择"
                    clearable
@@ -55,7 +55,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list">
                <el-table class="command-table" :data="list">
                    <el-table-column type="index" width="64" show-overflow-tooltip label="序号" />
                    <el-table-column prop="deviceType" show-overflow-tooltip label="设备类型">
                        <template v-slot="{ row }">
@@ -94,7 +94,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/detectionCountermeasure/taskSchedule/FormDiaLog.vue
@@ -65,8 +65,8 @@
                <el-col :span="12">
                    <el-form-item label="设备" prop="deviceId">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.deviceId"
                            placeholder="请选择"
                            clearable
@@ -79,7 +79,7 @@
                <el-col :span="12">
                    <el-form-item label="设备编码" prop="deviceSn">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.deviceSn"
                            disabled
                            placeholder="选择设备后自动带出"
@@ -89,8 +89,8 @@
                <el-col :span="12">
                    <el-form-item label="场景" prop="defenseSceneId">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.defenseSceneId"
                            placeholder="请选择"
                            clearable
@@ -103,8 +103,8 @@
                <el-col :span="12">
                    <el-form-item label="区域" prop="areaDivideId">
                        <el-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-select-popper"
                            class="command-select"
                            popper-class="command-select-popper"
                            v-model="formData.areaDivideId"
                            placeholder="请先选择场景"
                            clearable
@@ -118,7 +118,7 @@
                <el-col :span="12">
                    <el-form-item label="调度人员" prop="dispatchUser">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.dispatchUser"
                            maxlength="50"
                            placeholder="请输入"
@@ -129,8 +129,8 @@
                <el-col :span="12">
                    <el-form-item label="调度日期" prop="dispatchDateRange">
                        <el-date-picker
                            class="command-data-cockpit-date-picker"
                            popper-class="command-data-cockpit-date-picker-popper"
                            class="command-date-picker"
                            popper-class="command-date-picker-popper"
                            v-model="formData.dispatchDateRange"
                            type="datetimerange"
                            range-separator="至"
@@ -153,7 +153,7 @@
                <el-col :span="24">
                    <el-form-item label="调度内容" prop="dispatchContent">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.dispatchContent"
                            type="textarea"
                            :rows="3"
@@ -166,7 +166,7 @@
                <el-col :span="24">
                    <el-form-item label="调度结果" prop="dispatchResult">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.dispatchResult"
                            type="textarea"
                            :rows="3"
@@ -179,7 +179,7 @@
                <el-col :span="24">
                    <el-form-item label="处理措施" prop="disposeMeasure">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.disposeMeasure"
                            type="textarea"
                            :rows="3"
applications/drone-command/src/views/detectionCountermeasure/taskSchedule/index.vue
@@ -3,8 +3,8 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="设备名称" prop="deviceId">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.deviceId"
                    placeholder="请选择"
                    clearable
@@ -17,8 +17,8 @@
            <el-form-item label="设备状态" prop="status">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.status"
                    placeholder="请选择"
                    clearable
@@ -36,7 +36,7 @@
            <el-form-item label="设备编码" prop="deviceSn">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.deviceSn"
                    placeholder="请输入"
                    clearable
@@ -57,7 +57,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="deviceName" show-overflow-tooltip width="140" label="设备名称" />
@@ -92,7 +92,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/permissionManage/permissionDept/FormDiaLog.vue
@@ -46,19 +46,19 @@
            <el-row>
                <el-col :span="12">
                    <el-form-item label="部门名称" prop="deptName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.deptName" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.deptName" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="部门全称" prop="fullName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.fullName" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.fullName" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="上级部门" prop="parentId">
                        <el-tree-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-tree-select-popper"
                            class="command-select"
                            popper-class="command-tree-select-popper"
                            v-model="formData.parentId"
                            :data="deptTree"
                            :props="treeProps"
@@ -70,14 +70,14 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="部门类型" prop="deptCategory">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper" v-model="formData.deptCategory" placeholder="请选择" clearable>
                        <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-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="部门性质" prop="deptNature">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper" v-model="formData.deptNature" placeholder="请选择" clearable>
                        <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-select>
                    </el-form-item>
@@ -90,8 +90,8 @@
                <el-col :span="12">
                    <el-form-item label="行政区划" prop="areaCode">
                        <el-cascader
                            class="command-data-cockpit-cascader"
                            popper-class="command-data-cockpit-cascader-popper"
                            class="command-cascader"
                            popper-class="command-cascader-popper"
                            v-model="formData.areaCode"
                            :props="areaProps"
                            clearable
@@ -100,7 +100,7 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="部署模式" prop="deploymentMode">
                        <el-radio-group v-model="formData.deploymentMode">
                        <el-radio-group v-model="formData.deploymentMode" class="command-radio-group">
                            <el-radio :label="0">统一部署</el-radio>
                            <el-radio :label="1">独立部署</el-radio>
                        </el-radio-group>
@@ -108,7 +108,7 @@
                </el-col>
                <el-col :span="24">
                    <el-form-item label="备注" prop="remark">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
            </el-row>
applications/drone-command/src/views/permissionManage/permissionDept/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="部门名称" prop="deptName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.deptName"
                    placeholder="请输入"
                    clearable
@@ -13,7 +13,7 @@
            <el-form-item label="部门全称" prop="fullName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.fullName"
                    placeholder="请输入"
                    clearable
@@ -37,7 +37,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table
                    class="command-data-cockpit-table"
                    class="command-table"
                    :data="list"
                    row-key="id"
                    lazy
@@ -80,7 +80,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/permissionManage/permissionRole/FormDiaLog.vue
@@ -26,19 +26,19 @@
            <el-row>
                <el-col :span="12">
                    <el-form-item label="角色名称" prop="roleName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.roleName" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.roleName" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="角色别名" prop="roleAlias">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.roleAlias" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.roleAlias" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="上级角色" prop="parentId">
                        <el-tree-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-tree-select-popper"
                            class="command-select"
                            popper-class="command-tree-select-popper"
                            v-model="formData.parentId"
                            :data="roleTree"
                            :props="treeProps"
applications/drone-command/src/views/permissionManage/permissionRole/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="角色名称" prop="roleName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.roleName"
                    placeholder="请输入"
                    clearable
@@ -13,7 +13,7 @@
            <el-form-item label="角色别名" prop="roleAlias">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.roleAlias"
                    placeholder="请输入"
                    clearable
@@ -46,7 +46,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table
                    class="command-data-cockpit-table"
                    class="command-table"
                    :data="list"
                    row-key="id"
                    :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
@@ -70,7 +70,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/permissionManage/permissionUser/FormDiaLog.vue
@@ -67,13 +67,13 @@
            <el-row :gutter="16">
                <el-col :span="12">
                    <el-form-item label="登录账号" prop="account">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.account" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.account" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12" v-if="dialogMode === 'add'">
                    <el-form-item label="密码" prop="password">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.password"
                            type="password"
                            maxlength="50"
@@ -86,7 +86,7 @@
                <el-col :span="12" v-if="dialogMode === 'add'">
                    <el-form-item label="确认密码" prop="password2">
                        <el-input
                            class="command-data-cockpit-search-input"
                            class="command-search-input"
                            v-model="formData.password2"
                            type="password"
                            maxlength="50"
@@ -102,22 +102,22 @@
            <el-row :gutter="16">
                <el-col :span="12">
                    <el-form-item label="用户姓名" prop="realName">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.realName" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.realName" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="手机号" prop="phone">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.phone" maxlength="20" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.phone" maxlength="20" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="电子邮箱" prop="email">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.email" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.email" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="用户性别" prop="sex">
                        <el-select class="command-data-cockpit-select" popper-class="command-data-cockpit-select-popper" v-model="formData.sex" placeholder="请选择" clearable>
                        <el-select class="command-select" popper-class="command-select-popper" v-model="formData.sex" placeholder="请选择" clearable>
                            <el-option label="男" :value="1" />
                            <el-option label="女" :value="2" />
                            <el-option label="未知" :value="3" />
@@ -127,8 +127,8 @@
                <el-col :span="12">
                    <el-form-item label="用户生日" prop="birthday">
                        <el-date-picker
                            class="command-data-cockpit-date-picker"
                            popper-class="command-data-cockpit-date-picker-popper"
                            class="command-date-picker"
                            popper-class="command-date-picker-popper"
                            v-model="formData.birthday"
                            type="datetime"
                            placeholder="请选择"
@@ -144,14 +144,14 @@
            <el-row :gutter="16">
                <el-col :span="12">
                    <el-form-item label="用户编号" prop="code">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.code" maxlength="50" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.code" maxlength="50" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="所属角色" prop="roleId">
                        <el-tree-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-tree-select-popper"
                            class="command-select"
                            popper-class="command-tree-select-popper"
                            v-model="formData.roleId"
                            :data="roleTree"
                            :props="treeProps"
@@ -165,8 +165,8 @@
                <el-col :span="12">
                    <el-form-item label="所属部门" prop="deptId">
                        <el-tree-select
                            class="command-data-cockpit-select"
                            popper-class="command-data-cockpit-tree-select-popper"
                            class="command-select"
                            popper-class="command-tree-select-popper"
                            v-model="formData.deptId"
                            :data="deptTree"
                            :props="deptTreeSelectProps"
@@ -184,8 +184,8 @@
                <el-col :span="12">
                    <el-form-item label="到期时间" prop="expireTime">
                        <el-date-picker
                            class="command-data-cockpit-date-picker"
                            popper-class="command-data-cockpit-date-picker-popper"
                            class="command-date-picker"
                            popper-class="command-date-picker-popper"
                            v-model="formData.expireTime"
                            type="datetime"
                            placeholder="请选择"
@@ -197,14 +197,14 @@
                </el-col>
                <el-col :span="12">
                    <el-form-item label="次数限制" prop="maxLoginNum">
                        <el-input class="command-data-cockpit-search-input" v-model="formData.maxLoginNum" placeholder="请输入" clearable />
                        <el-input class="command-search-input" v-model="formData.maxLoginNum" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="飞行开始时间" prop="flightStartTime">
                        <el-time-picker
                            class="command-data-cockpit-date-picker"
                            popper-class="command-data-cockpit-date-picker-popper"
                            class="command-date-picker"
                            popper-class="command-date-picker-popper"
                            v-model="formData.flightStartTime"
                            placeholder="请选择"
                            format="HH:mm"
@@ -216,8 +216,8 @@
                <el-col :span="12">
                    <el-form-item label="飞行结束时间" prop="flightEndTime">
                        <el-time-picker
                            class="command-data-cockpit-date-picker"
                            popper-class="command-data-cockpit-date-picker-popper"
                            class="command-date-picker"
                            popper-class="command-date-picker-popper"
                            v-model="formData.flightEndTime"
                            placeholder="请选择"
                            format="HH:mm"
applications/drone-command/src/views/permissionManage/permissionUser/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="登录账号" prop="account">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.account"
                    placeholder="请输入"
                    clearable
@@ -13,7 +13,7 @@
            <el-form-item label="用户姓名" prop="realName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.realName"
                    placeholder="请输入"
                    clearable
@@ -23,8 +23,8 @@
            <el-form-item label="所属部门" prop="deptId">
                <el-tree-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-tree-select-popper"
                    class="command-select"
                    popper-class="command-tree-select-popper"
                    v-model="searchParams.deptId"
                    :data="deptTree"
                    :props="treeProps"
@@ -59,7 +59,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="account" show-overflow-tooltip label="登录账号" />
@@ -79,7 +79,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/recordManage/alarmRecords/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="无人机名称" prop="droneName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.droneName"
                    placeholder="请输入"
                    clearable
@@ -12,7 +12,7 @@
            </el-form-item>
            <el-form-item label="区域" prop="areaName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.areaName"
                    placeholder="请输入"
                    clearable
@@ -21,8 +21,8 @@
            </el-form-item>
            <el-form-item label="设备类型" prop="droneType">
                <el-select
                    class="command-data-cockpit-select"
                    popper-class="command-data-cockpit-select-popper"
                    class="command-select"
                    popper-class="command-select-popper"
                    v-model="searchParams.droneType"
                    placeholder="请选择"
                    clearable
@@ -38,8 +38,8 @@
            </el-form-item>
            <el-form-item label="告警时间">
                <el-date-picker
                    popper-class="command-data-cockpit-date-picker-popper"
                    class="command-data-cockpit-date-picker"
                    popper-class="command-date-picker-popper"
                    class="command-date-picker"
                    v-model="dateRange"
                    type="daterange"
                    range-separator="至"
@@ -63,7 +63,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="command-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="droneName" show-overflow-tooltip width="140" label="无人机名称" />
@@ -88,7 +88,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue
@@ -40,7 +40,7 @@
                    <div class="detail-title">轨迹点</div>
                    <div class="command-table-container">
                        <div class="command-table-content">
                            <el-table class="command-data-cockpit-table" :data="list">
                            <el-table class="command-table" :data="list">
                                <el-table-column type="index" width="60" label="序号" />
                                <el-table-column label="经纬度">
                                    <template #default="{ row }">{{ row.longitude }},{{ row.latitude }}</template>
applications/drone-command/src/views/recordManage/historyTracks/index.vue
@@ -3,7 +3,7 @@
        <el-form ref="queryParamsRef" :model="searchParams" class="command-page-history-search">
            <el-form-item label="无人机名称" prop="droneName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.droneName"
                    placeholder="请输入"
                    clearable
@@ -12,7 +12,7 @@
            </el-form-item>
            <el-form-item label="区域" prop="areaName">
                <el-input
                    class="command-data-cockpit-search-input"
                    class="command-search-input"
                    v-model="searchParams.areaName"
                    placeholder="请输入"
                    clearable
@@ -21,8 +21,8 @@
            </el-form-item>
            <el-form-item label="告警时间">
                <el-date-picker
                    popper-class="command-data-cockpit-date-picker-popper"
                    class="command-data-cockpit-date-picker"
                    popper-class="command-date-picker-popper"
                    class="command-date-picker"
                    v-model="dateRange"
                    type="daterange"
                    range-separator="至"
@@ -44,7 +44,7 @@
        <div class="command-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="command-table-content command-table-content-bg">
                <el-table class="command-data-cockpit-table" :data="list">
                <el-table class="command-table" :data="list">
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="droneName" show-overflow-tooltip width="140" label="无人机名称" />
                    <el-table-column prop="serialNo" show-overflow-tooltip label="无人机序列号" />
@@ -66,7 +66,7 @@
            <div class="command-table-pagination">
                <el-pagination
                    popper-class="command-data-cockpit-select-popper"
                    popper-class="command-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
applications/task-work-order/src/config/website.js
@@ -4,81 +4,78 @@
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-16 11:12:30
 * @FilePath     : \applications\task-work-order\src\config\website.js
 * @Description  :
 * Copyright 2026 OBKoro1, All Rights Reserved.
 * @Description  :
 * Copyright 2026 OBKoro1, All Rights Reserved.
 * 2026-01-06 09:47:27
 */
/**
 * 全局配置文件
 */
export default {
  title: 'saber',
  logo: 'S',
  key: 'work', //配置主键,目前用于存储
  indexTitle: '',
  clientId: 'saber', // 客户端id
  clientSecret: 'saber_secret', // 客户端密钥
  tenantMode: true, // 是否开启租户模式
  tenantId: '000000', // 管理组租户编号
  captchaMode: true, // 是否开启验证码模式
  switchMode: false, // 是否开启部门切换模式
  lockPage: '/lock',
  tokenTime: 3000,
  tokenHeader: 'Blade-Auth',
  //http的status默认放行不才用统一处理的,
  statusWhiteList: [],
  //配置首页不可关闭
  setting: {
    sidebar: 'vertical',
    tag: true,
    debug: true,
    collapse: true,
    search: true,
    color: true,
    lock: true,
    screenshot: true,
    fullscreen: true,
    theme: true,
    menu: true,
  },
  fistPage: {
    name: '数据驾驶舱',
    path: '/dataCockpit/index',
    // path: '/tickets/ticket',
  },
  //配置菜单的属性
  menu: {
    iconDefault: 'icon-caidan',
    label: 'name',
    path: 'path',
    icon: 'source',
    children: 'children',
    query: 'query',
    href: 'path',
    meta: 'meta',
  },
  //oauth2配置
  oauth2: {
    // 是否开启注册功能
    registerMode: true,
    // 使用后端工程 @org.springblade.test.Sm2KeyGenerator 获取
    publicKey: '请配置国密sm2公钥',
    // 第三方系统授权地址
    authUrl: 'http://localhost/blade-auth/oauth/render',
    // 单点登录系统认证(cloud端口为8100,boot端口为80)
    ssoUrl:
      'http://localhost:8100/oauth/authorize?client_id=saber3&response_type=code&redirect_uri=',
    // 单点登录回调地址(Saber服务的登录界面地址)
    redirectUri: 'http://localhost:2888/login',
  },
  //设计器配置
  design: {
    // 流程设计器类型(true->nutflow,false->flowable)
    designMode: true,
    // 流程设计器地址(flowable模式)
    designUrl: 'http://localhost:9999',
    // 报表设计器地址(cloud端口为8108,boot端口为80)
    reportUrl: 'http://localhost:8108/ureport',
  },
    title: 'saber',
    logo: 'S',
    key: 'work', //配置主键,目前用于存储
    indexTitle: '',
    clientId: 'saber', // 客户端id
    clientSecret: 'saber_secret', // 客户端密钥
    tenantMode: true, // 是否开启租户模式
    tenantId: '000000', // 管理组租户编号
    captchaMode: true, // 是否开启验证码模式
    switchMode: false, // 是否开启部门切换模式
    lockPage: '/lock',
    tokenTime: 3000,
    tokenHeader: 'Blade-Auth',
    //http的status默认放行不才用统一处理的,
    statusWhiteList: [],
    //配置首页不可关闭
    setting: {
        sidebar: 'vertical',
        tag: true,
        debug: true,
        collapse: true,
        search: true,
        color: true,
        lock: true,
        screenshot: true,
        fullscreen: true,
        theme: true,
        menu: true,
    },
    fistPage: {
        name: '测试页',
        path: '/test',
    },
    //配置菜单的属性
    menu: {
        iconDefault: 'icon-caidan',
        label: 'name',
        path: 'path',
        icon: 'source',
        children: 'children',
        query: 'query',
        href: 'path',
        meta: 'meta',
    },
    //oauth2配置
    oauth2: {
        // 是否开启注册功能
        registerMode: true,
        // 使用后端工程 @org.springblade.test.Sm2KeyGenerator 获取
        publicKey: '请配置国密sm2公钥',
        // 第三方系统授权地址
        authUrl: 'http://localhost/blade-auth/oauth/render',
        // 单点登录系统认证(cloud端口为8100,boot端口为80)
        ssoUrl: 'http://localhost:8100/oauth/authorize?client_id=saber3&response_type=code&redirect_uri=',
        // 单点登录回调地址(Saber服务的登录界面地址)
        redirectUri: 'http://localhost:2888/login',
    },
    //设计器配置
    design: {
        // 流程设计器类型(true->nutflow,false->flowable)
        designMode: true,
        // 流程设计器地址(flowable模式)
        designUrl: 'http://localhost:9999',
        // 报表设计器地址(cloud端口为8108,boot端口为80)
        reportUrl: 'http://localhost:8108/ureport',
    },
}
applications/task-work-order/src/permission copy 2.js
File was deleted
applications/task-work-order/src/permission copy.js
File was deleted
applications/task-work-order/src/permission.js
@@ -67,7 +67,6 @@
            query: firstMenu.query || {},
            meta: firstMenu.meta || {},
          })
          store.commit('ADD_TAG', {
            name: toMenu.name,
            path: toMenu.path,
@@ -139,4 +138,4 @@
    const pageTitle = isLoginPage ? '中图智飞低空感知网平台' : '综合管理平台'
    document.title = pageTitle
    store.commit('SET_IS_SEARCH', false)
})
})
applications/task-work-order/src/router/page/index.js
@@ -1,77 +1,64 @@
import Store from '@/store/'
export default [
  {
    path: '/login',
    name: '登录页',
    component: () =>
      Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue'),
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/oauth/redirect/:source',
    name: '第三方登录',
    component: () =>
      Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue'),
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/lock',
    name: '锁屏页',
    component: () =>
      Store.getters.isMacOs ? import('@/mac/lock.vue') : import('@/page/lock/index.vue'),
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/404',
    component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/404.vue'),
    name: '404',
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/403',
    component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/403.vue'),
    name: '403',
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/500',
    component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/500.vue'),
    name: '500',
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/',
    name: '主页',
    redirect: '/wel',
  },
  // {
  //    path: '/',
  //    name: '主页',
  //    redirect: '/tickets/ticket',
  //    },
    {
        path: '/login',
        name: '登录页',
        component: () => (Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue')),
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/oauth/redirect/:source',
        name: '第三方登录',
        component: () => (Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue')),
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/lock',
        name: '锁屏页',
        component: () => (Store.getters.isMacOs ? import('@/mac/lock.vue') : import('@/page/lock/index.vue')),
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/404',
        component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/404.vue'),
        name: '404',
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/403',
        component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/403.vue'),
        name: '403',
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/500',
        component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/500.vue'),
        name: '500',
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
]
applications/task-work-order/src/router/views/index.js
@@ -18,24 +18,6 @@
      }
    ],
  },
  // 事件工单
  // {
  //    path: '/tickets',
  //   component: () =>
  //    Store.getters.isMacOs ? import('@/mac/index.vue') : import('@/page/index/index.vue'),
  //    redirect: '/tickets/ticket',
  //    children: [
  //    {
  //    path: 'ticket',
  //  name: '事件工单',
  //    meta: {
  //    i18n: 'dashboard',
  //   },
  //   component: () => import(/* webpackChunkName: "views" */ '@/views/tickets/ticket.vue'),
  //    },
  //   ],
  //    },
  {
    path: '/test',
    component: Layout,
applications/task-work-order/src/store/modules/user.js
@@ -1,396 +1,385 @@
import {
  setToken,
  setRefreshToken,
  removeToken,
  removeRefreshToken,
  getRefreshToken,
} from '@/utils/auth';
import { setStore, getStore } from '@/utils/store';
import { validatenull } from '@/utils/validate';
import { deepClone } from '@/utils/util';
import { setToken, setRefreshToken, removeToken, removeRefreshToken, getRefreshToken } from '@/utils/auth'
import { setStore, getStore } from '@/utils/store'
import { validatenull } from '@/utils/validate'
import { deepClone } from '@/utils/util'
import defaultAva from '@/assets/images/defaultava.png'
import {
  loginByUsername,
  loginBySocial,
  loginBySso,
  loginByPhone,
  getUserInfo,
  logout,
  refreshToken,
  getButtons,
  registerUser,
  getParentDeptInfo
} from '@/api/user';
import { getRoutes, getTopMenu } from '@/api/system/menu';
import { formatPath } from '@/router/avue-router';
import { ElMessage } from 'element-plus';
import { encrypt } from '@/utils/sm2';
import md5 from 'js-md5';
    loginByUsername,
    loginBySocial,
    loginBySso,
    loginByPhone,
    getUserInfo,
    logout,
    refreshToken,
    getButtons,
    registerUser,
    getParentDeptInfo,
} from '@/api/user'
import { getRoutes, getTopMenu } from '@/api/system/menu'
import { formatPath } from '@/router/avue-router'
import { ElMessage } from 'element-plus'
import { encrypt } from '@/utils/sm2'
import md5 from 'js-md5'
const user = {
  state: {
    tenantId: getStore({ name: 'tenantId' }) || '',
    userInfo: getStore({ name: 'userInfo' }) || [],
    permission: getStore({ name: 'permission' }) || {},
    roles: [],
    menuId: {},
    menu: getStore({ name: 'menu' }) || [],
    menuAll: getStore({ name: 'menuAll' }) || [],
    token: getStore({ name: 'token' }) || '',
    refreshToken: getStore({ name: 'refreshToken' }) || '',
    parentDeptInfo: getStore({ name: 'parentDeptInfo' }) || '',
    state: {
        tenantId: getStore({ name: 'tenantId' }) || '',
        userInfo: getStore({ name: 'userInfo' }) || [],
        permission: getStore({ name: 'permission' }) || {},
        roles: [],
        menuId: {},
        menu: getStore({ name: 'menu' }) || [],
        menuAll: getStore({ name: 'menuAll' }) || [],
        token: getStore({ name: 'token' }) || '',
        refreshToken: getStore({ name: 'refreshToken' }) || '',
        parentDeptInfo: getStore({ name: 'parentDeptInfo' }) || '',
    },
    actions: {
        //根据用户名登录
        LoginByUsername({ commit }, userInfo = {}) {
            return new Promise((resolve, reject) => {
                loginByUsername(
                    userInfo.tenantId,
                    userInfo.deptId,
                    userInfo.roleId,
                    userInfo.username,
                    md5(userInfo.password),
                    userInfo.type,
                    userInfo.key,
                    userInfo.code
                )
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('SET_USER_INFO', data)
                            commit('SET_PARENT_DEPT_INFO', data.dept_id)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //根据第三方信息登录
        LoginBySocial({ commit }, userInfo) {
            return new Promise((resolve, reject) => {
                loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state)
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_USER_INFO', data)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //根据单点信息登录
        LoginBySso({ commit }, userInfo) {
            return new Promise((resolve, reject) => {
                loginBySso(userInfo.state, userInfo.code)
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_USER_INFO', data)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //根据手机信息登录
        LoginByPhone({ commit }, userInfo) {
            return new Promise((resolve, reject) => {
                loginByPhone(userInfo.tenantId, encrypt(userInfo.phone), userInfo.codeId, userInfo.codeValue)
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_USER_INFO', data)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //用户注册
        RegisterUser({ commit }, userInfo = {}) {
            return new Promise((resolve, reject) => {
                registerUser(
                    userInfo.tenantId,
                    userInfo.name,
                    userInfo.account,
                    encrypt(userInfo.password),
                    userInfo.phone,
                    userInfo.email
                ).then(res => {
                    const data = res.data
                    if (data.error_description) {
                        ElMessage({
                            message: data.error_description,
                            type: 'error',
                        })
                        reject(data.error_description)
                    } else {
                        commit('SET_TOKEN', data.access_token)
                        commit('SET_REFRESH_TOKEN', data.refresh_token)
                        commit('SET_USER_INFO', data)
                        commit('SET_TENANT_ID', data.tenant_id)
                        commit('DEL_ALL_TAG')
                        commit('CLEAR_LOCK')
                    }
                    resolve()
                })
            })
        },
        GetUserInfo({ commit }) {
            return new Promise((resolve, reject) => {
                getUserInfo()
                    .then(res => {
                        const data = res.data.data
                        commit('SET_ROLES', data.roles)
                        resolve(data)
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //刷新token
        RefreshToken({ state, commit }, userInfo) {
            return new Promise((resolve, reject) => {
                refreshToken(
                    getRefreshToken(),
                    state.tenantId,
                    !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
                    !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
                )
                    .then(res => {
                        const data = res.data
                        commit('SET_TOKEN', data.access_token)
                        commit('SET_REFRESH_TOKEN', data.refresh_token)
                        commit('SET_USER_INFO', data)
                        resolve()
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        },
        // 登出
        LogOut({ commit }) {
            return new Promise((resolve, reject) => {
                logout()
                    .then(() => {
                        commit('SET_TOKEN', '')
                        commit('SET_MENU_ALL_NULL', [])
                        commit('SET_MENU', [])
                        commit('SET_ROLES', [])
                        commit('DEL_ALL_TAG', [])
                        commit('CLEAR_LOCK')
                        removeToken()
                        removeRefreshToken()
                        resolve()
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        },
        //注销session
        FedLogOut({ commit }) {
            return new Promise(resolve => {
                commit('SET_TOKEN', '')
                commit('SET_MENU_ALL_NULL', [])
                commit('SET_MENU', [])
                commit('SET_ROLES', [])
                commit('DEL_ALL_TAG', [])
                commit('CLEAR_LOCK')
                removeToken()
                removeRefreshToken()
                removeToken()
                resolve()
            })
        },
        GetTopMenu() {
            return new Promise(resolve => {
                getTopMenu().then(res => {
                    const data = res.data.data || []
                    resolve(data)
                })
            })
        },
        GetMenu({ commit, dispatch }, tenantId) {
            const errLogOut = () => {
                dispatch('LogOut').then(() => {
                    const env = import.meta.env.VITE_APP_ENV
                    const adminUrl = import.meta.env.VITE_APP_DASHBOARD_URL
                    env === 'development'
                        ? (window.location.href = '/task-work-order/login')
                        : window.location.replace(`${adminUrl}#/login`)
                })
            }
            return new Promise(resolve => {
                getRoutes({ tenantId, sysType: 6 })
                    .then(res => {
                        const data = res.data.data
                        let menu = deepClone(data)
                        if (!res.data?.data?.length) {
                            errLogOut()
                            return
                        }
                        menu.forEach(ele => formatPath(ele, true))
                        commit('SET_MENU', menu)
                        commit('SET_MENU_ALL', menu)
                        dispatch('GetButtons')
                        resolve(menu)
                    })
                    .catch(err => {
                        errLogOut()
                    })
            })
        },
        GetButtons({ commit }) {
            return new Promise(resolve => {
                getButtons({ sysType: 6 }).then(res => {
                    const data = res.data.data
                    commit('SET_PERMISSION', data)
                    resolve()
                })
            })
        },
    },
    mutations: {
        SET_PARENT_DEPT_INFO(state, deptId) {
            getParentDeptInfo({ deptId: deptId }).then(res => {
                const data = res.data.data
                state.parentDeptInfo = data
                setStore({ name: 'parentDeptInfo', content: data })
            })
        },
        SET_TOKEN: (state, token) => {
            setToken(token)
            state.token = token
            setStore({ name: 'token', content: state.token })
        },
        SET_REFRESH_TOKEN: (state, refreshToken) => {
            setRefreshToken(refreshToken)
            state.refreshToken = refreshToken
            setStore({ name: 'refreshToken', content: state.refreshToken })
        },
        SET_MENU_ID(state, menuId) {
            state.menuId = menuId
        },
        SET_TENANT_ID: (state, tenantId) => {
            state.tenantId = tenantId
            setStore({ name: 'tenantId', content: state.tenantId })
        },
        SET_USER_INFO: (state, userInfo) => {
            if (validatenull(userInfo.user_id) && validatenull(userInfo.account)) {
                state.userInfo = { user_name: 'unauth', role_name: 'unauth' }
            } else {
                if (validatenull(userInfo.avatar)) {
                    userInfo.avatar = defaultAva
                }
                state.userInfo = userInfo
            }
            setStore({ name: 'userInfo', content: state.userInfo })
        },
        SET_MENU_ALL: (state, menuAll) => {
            let menu = state.menuAll
            menuAll.forEach(ele => {
                let index = menu.findIndex(item => item.path === ele.path)
                if (index === -1) {
                    menu.push(ele)
                } else {
                    menu[index] = ele
                }
            })
            state.menuAll = menu
            setStore({ name: 'menuAll', content: state.menuAll })
        },
        SET_MENU_ALL_NULL: state => {
            state.menuAll = []
            setStore({ name: 'menuAll', content: state.menuAll })
        },
        SET_MENU: (state, menu) => {
            state.menu = menu
            setStore({ name: 'menu', content: state.menu })
        },
        SET_ROLES: (state, roles) => {
            state.roles = roles
        },
        SET_PERMISSION: (state, permission) => {
            let result = []
  },
  actions: {
    //根据用户名登录
    LoginByUsername({ commit }, userInfo = {}) {
      return new Promise((resolve, reject) => {
        loginByUsername(
          userInfo.tenantId,
          userInfo.deptId,
          userInfo.roleId,
          userInfo.username,
          md5(userInfo.password),
          userInfo.type,
          userInfo.key,
          userInfo.code
        )
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('SET_USER_INFO', data);
              commit('SET_PARENT_DEPT_INFO', data.dept_id);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //根据第三方信息登录
    LoginBySocial({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state)
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_USER_INFO', data);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //根据单点信息登录
    LoginBySso({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        loginBySso(userInfo.state, userInfo.code)
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_USER_INFO', data);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //根据手机信息登录
    LoginByPhone({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        loginByPhone(
          userInfo.tenantId,
          encrypt(userInfo.phone),
          userInfo.codeId,
          userInfo.codeValue
        )
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_USER_INFO', data);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //用户注册
    RegisterUser({ commit }, userInfo = {}) {
      return new Promise((resolve, reject) => {
        registerUser(
          userInfo.tenantId,
          userInfo.name,
          userInfo.account,
          encrypt(userInfo.password),
          userInfo.phone,
          userInfo.email
        ).then(res => {
          const data = res.data;
          if (data.error_description) {
            ElMessage({
              message: data.error_description,
              type: 'error',
            });
            reject(data.error_description);
          } else {
            commit('SET_TOKEN', data.access_token);
            commit('SET_REFRESH_TOKEN', data.refresh_token);
            commit('SET_USER_INFO', data);
            commit('SET_TENANT_ID', data.tenant_id);
            commit('DEL_ALL_TAG');
            commit('CLEAR_LOCK');
          }
          resolve();
        });
      });
    },
    GetUserInfo({ commit }) {
      return new Promise((resolve, reject) => {
        getUserInfo()
          .then(res => {
            const data = res.data.data;
            commit('SET_ROLES', data.roles);
            resolve(data);
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //刷新token
    RefreshToken({ state, commit }, userInfo) {
      return new Promise((resolve, reject) => {
        refreshToken(
          getRefreshToken(),
          state.tenantId,
          !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
          !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
        )
          .then(res => {
            const data = res.data;
            commit('SET_TOKEN', data.access_token);
            commit('SET_REFRESH_TOKEN', data.refresh_token);
            commit('SET_USER_INFO', data);
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    // 登出
    LogOut({ commit }) {
      return new Promise((resolve, reject) => {
        logout()
          .then(() => {
            commit('SET_TOKEN', '');
            commit('SET_MENU_ALL_NULL', []);
            commit('SET_MENU', []);
            commit('SET_ROLES', []);
            commit('DEL_ALL_TAG', []);
            commit('CLEAR_LOCK');
            removeToken();
            removeRefreshToken();
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    //注销session
    FedLogOut({ commit }) {
      return new Promise(resolve => {
        commit('SET_TOKEN', '');
        commit('SET_MENU_ALL_NULL', []);
        commit('SET_MENU', []);
        commit('SET_ROLES', []);
        commit('DEL_ALL_TAG', []);
        commit('CLEAR_LOCK');
        removeToken();
        removeRefreshToken();
        removeToken();
        resolve();
      });
    },
    GetTopMenu() {
      return new Promise(resolve => {
        getTopMenu().then(res => {
          const data = res.data.data || [];
          resolve(data);
        });
      });
    },
    GetMenu({ commit, dispatch }, tenantId) {
      const errLogOut = () => {
        dispatch('LogOut').then(()=>{
          const env = import.meta.env.VITE_APP_ENV
          const adminUrl = import.meta.env.VITE_APP_DASHBOARD_URL
          env === 'development'
            ? window.location.href = "/manage/login"
            : window.location.replace(`${adminUrl}#/login`)
        })
      }
      return new Promise(resolve => {
        getRoutes({tenantId,sysType: 6}).then(res => {
          const data = res.data.data;
          let menu = deepClone(data);
          if (!res.data?.data?.length){
            errLogOut()
            return
          }
          menu.forEach(ele => formatPath(ele, true));
          commit('SET_MENU', menu);
          commit('SET_MENU_ALL', menu);
          dispatch('GetButtons');
          resolve(menu);
        }).catch(err =>{
          errLogOut()
        })
      });
    },
    GetButtons({ commit }) {
      return new Promise(resolve => {
        getButtons({sysType: 6}).then(res => {
          const data = res.data.data;
          commit('SET_PERMISSION', data);
          resolve();
        });
      });
    },
  },
  mutations: {
    SET_PARENT_DEPT_INFO(state, deptId){
      getParentDeptInfo({deptId:deptId}).then(res=>{
        const data = res.data.data;
        state.parentDeptInfo = data;
        setStore({ name: 'parentDeptInfo', content: data });
      })
    },
    SET_TOKEN: (state, token) => {
      setToken(token);
      state.token = token;
      setStore({ name: 'token', content: state.token });
    },
    SET_REFRESH_TOKEN: (state, refreshToken) => {
      setRefreshToken(refreshToken);
      state.refreshToken = refreshToken;
      setStore({ name: 'refreshToken', content: state.refreshToken });
    },
    SET_MENU_ID(state, menuId) {
      state.menuId = menuId;
    },
    SET_TENANT_ID: (state, tenantId) => {
      state.tenantId = tenantId;
      setStore({ name: 'tenantId', content: state.tenantId });
    },
    SET_USER_INFO: (state, userInfo) => {
      if (validatenull(userInfo.user_id) && validatenull(userInfo.account)) {
        state.userInfo = { user_name: 'unauth', role_name: 'unauth' };
      } else {
        if (validatenull(userInfo.avatar)) {
          userInfo.avatar = defaultAva;
        }
        state.userInfo = userInfo;
      }
      setStore({ name: 'userInfo', content: state.userInfo });
    },
    SET_MENU_ALL: (state, menuAll) => {
      let menu = state.menuAll;
      menuAll.forEach(ele => {
        let index = menu.findIndex(item => item.path === ele.path);
        if (index === -1) {
          menu.push(ele);
        } else {
          menu[index] = ele;
        }
      });
      state.menuAll = menu;
      setStore({ name: 'menuAll', content: state.menuAll });
    },
    SET_MENU_ALL_NULL: state => {
      state.menuAll = [];
      setStore({ name: 'menuAll', content: state.menuAll });
    },
    SET_MENU: (state, menu) => {
      state.menu = menu;
      setStore({ name: 'menu', content: state.menu });
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles;
    },
    SET_PERMISSION: (state, permission) => {
      let result = [];
            function getCode(list) {
                list.forEach(ele => {
                    if (typeof ele === 'object') {
                        const children = ele.children
                        const code = ele.code
                        if (children) {
                            getCode(children)
                        } else {
                            result.push(code)
                        }
                    }
                })
            }
      function getCode(list) {
        list.forEach(ele => {
          if (typeof ele === 'object') {
            const children = ele.children;
            const code = ele.code;
            if (children) {
              getCode(children);
            } else {
              result.push(code);
            }
          }
        });
      }
      getCode(permission);
      state.permission = {};
      result.forEach(ele => {
        state.permission[ele] = true;
      });
      setStore({ name: 'permission', content: state.permission, type: 'session' });
    },
  },
};
export default user;
            getCode(permission)
            state.permission = {}
            result.forEach(ele => {
                state.permission[ele] = true
            })
            setStore({ name: 'permission', content: state.permission, type: 'session' })
        },
    },
}
export default user
applications/task-work-order/src/styles/common/cockpit.scss
@@ -1,3 +1,5 @@
//变量
$gd-placeholder: #86909C;
.gd-table {
  height: 0;
@@ -20,9 +22,7 @@
    border-bottom: 1px solid #DBDFF1 !important;
    .cell {
      padding: 0;
      padding-left: 16px;
      padding: 0 0 0 16px;
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
@@ -38,9 +38,7 @@
    height: 56px;
    .cell {
      padding: 0;
      padding-left: 16px;
      padding: 0 0 0 16px;
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
@@ -79,25 +77,25 @@
  }
}
.gd-input {
  .el-input__wrapper {
  .el-input__wrapper,.el-textarea__inner {
    padding: 0 8px !important;
    background: #DDE2ED;
    background: #F2F3F5;
    box-shadow: none !important;
    border: none;
  }
    .el-input__inner {
      color: #383874;
      &::placeholder {
        color: #A1A3D4;
      }
  .el-input__inner,.el-textarea__inner {
    &::placeholder {
      color: $gd-placeholder;
    }
  }
  &.is-disabled {
    .el-input__wrapper {
      background-color: #DDE2ED;
      background: #DDE2ED;
    }
  }
}
@@ -117,7 +115,7 @@
  .el-select__placeholder {
    &.is-transparent {
      color: #A1A3D4 !important;
      color: $gd-placeholder !important;
    }
    &.el-select__selected-item {
@@ -240,7 +238,7 @@
    color: #fff;
    &::placeholder {
      color: #A1A3D4;
      color: $gd-placeholder;
    }
  }
@@ -583,16 +581,6 @@
            }
          }
          .el-textarea {
            .el-textarea__inner {
              color: #fff;
              background: #DDE2ED !important;
              border: none;
              box-shadow: none;
            }
          }
          .el-button {
            color: #fff;
            background: #DDE2ED !important;
@@ -661,28 +649,7 @@
          }
        }
        .el-input {
          .el-input__wrapper {
            padding: 0 8px !important;
            background: #F2F3F5;
            box-shadow: none !important;
            border: none;
            .el-input__inner {
              color: #383874;
              &::placeholder {
                color: #86909C;
              }
            }
          }
          &.is-disabled {
            .el-input__wrapper {
              background-color: #F2F3F5;
            }
          }
        }
      }
    }
  }
applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue
@@ -1,7 +1,12 @@
<template>
    <el-dialog class="gd-dialog" v-model="visible" :title="titleEnum[dialogMode]" @closed="handleClosed" destroy-on-close>
    <el-dialog
        class="gd-dialog"
        v-model="visible"
        :title="titleEnum[dialogMode]"
        @closed="visible = false"
        destroy-on-close
    >
        <div class="detail-container" v-if="dialogReadonly">
            <div class="detail-title">设备详情</div>
            <el-row>
                <el-col :span="12">
                    <div class="label">设备名称</div>
@@ -44,29 +49,6 @@
                    <div class="val">{{ formData.manufacturer }}</div>
                </el-col>
            </el-row>
            <div class="detail-title">维护详情</div>
            <div class="gd-table-container" v-loading="loading">
                <div class="gd-table-content">
                    <el-table class="gd-table" :data="list">
                        <el-table-column type="index" width="60" label="序号" />
                        <el-table-column prop="maintainTime" label="维护时间" />
                        <el-table-column prop="maintainContent" label="维护内容" />
                        <el-table-column prop="replacePart" label="跟换部件" />
                    </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>
        </div>
        <el-form
@@ -107,30 +89,10 @@
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="维护计划时间" prop="planCycleValue">
                        <el-select
                            class="gd-select"
                            popper-class="gd-select-popper"
                            v-model="formData.planCycleValue"
                            placeholder="请选择"
                            clearable
                            multiple
                            :disabled="!formData.planCycleType"
                        >
                            <el-option
                                v-for="item in planCycleValueOptions"
                                :key="item.value"
                                :label="item.value"
                                :value="item.value"
                            />
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <el-button color="#F2F3F5" @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
            <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
            <el-button
                class="save-btn"
                color="#4C34FF"
@@ -149,11 +111,9 @@
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { fieldRules, getDictLabel } from '@ztzf/utils'
import { fwDeviceMaintainRecordPageApi } from '@/views/basicManage/maintainRecord/fwDeviceMaintainRecord'
import {
    fwDeviceMaintainPlanDetailApi,
    fwDeviceMaintainPlanSubmitApi,
    fwDevicePageApi,
} from '@/views/basicManage/maintainRecord/maintainRecordApi'
const initForm = () => ({
@@ -163,41 +123,23 @@
})
const planCycleOptions = inject('planCycleOptions')
const planCycleValueOptions = ref([])
const emit = defineEmits(['success'])
const formRef = ref(null) // 表单实例
const formData = ref(initForm()) // 表单数据
const visible = ref(false) // 弹框显隐
const visible = defineModel() // 弹框显隐
const dialogMode = ref('add') // 弹框模式
const submitting = ref(false) // 提交中
const deviceList = ref([]) // 设备列表
const getPlanCycleLabel = inject('getPlanCycleLabel')
const dictObj = inject('dictObj')
const dialogReadonly = computed(() => dialogMode.value === 'view')
const titleEnum = ref({ edit: '编辑', view: '查看', add: '维护计划' })
const planCycleLabel = computed(() => {
    const item = planCycleOptions.find(option => option.value === formData.value.planCycleType)
    return item?.label || formData.value.planCycleType || '-'
})
const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
const rules = {
    deviceId: fieldRules(true),
    planCycleType: fieldRules(true),
    planCycleValue: [{ required: true, message: '请选择', trigger: ['blur', 'change'] }],
}
// 获取设备列表
function getDeviceList() {
    return fwDevicePageApi({ current: 1, size: 999 }).then(res => {
        deviceList.value = res?.data?.data?.records ?? []
    })
}
// 关闭弹框
function handleCancel() {
    visible.value = false
}
// 提交新增/编辑
@@ -220,70 +162,21 @@
    if (!formData.value.id) return
    const res = await fwDeviceMaintainPlanDetailApi({ id: formData.value.id })
    formData.value = res?.data?.data ?? {}
    console.log(formData.value, 66)
}
// 关闭后重置
function handleClosed() {
    formData.value = initForm()
}
const initSearchParams = () => ({
    current: 1, // 当前页
    size: 10, // 每页大小
})
const searchParams = ref(initSearchParams())
const total = ref(0) // 总条数
const loading = ref(true) // 列表加载中
const list = ref([]) // 列表数据
async function getList() {
    loading.value = true
    try {
        const params = { ...searchParams.value, planId: formData.value.id }
        const res = await fwDeviceMaintainRecordPageApi(params)
        list.value = res?.data?.data?.records ?? []
        total.value = res?.data?.data?.total ?? 0
    } finally {
        loading.value = false
    }
}
// 打开弹框
async function open({ mode, row } = {}) {
    dialogMode.value = mode || 'add'
    visible.value = true
    await getDeviceList()
    if (dialogMode.value === 'add') {
        formData.value = initForm()
    } else {
        formData.value = row
async function open({ mode = 'add', row } = {}) {
    dialogMode.value = mode
    formData.value = dialogMode.value === 'add' ? initForm() : row
    if (dialogMode.value !== 'add') {
        await loadDetail()
        getList()
    }
}
defineExpose({ open })
watch(
    () => formData.value?.planCycleType,
    type => {
        planCycleValueOptions.value = []
        if (!type) return
        if (type === '1') {
            ;[...Array(12)].forEach((item, index) => {
                ;[...Array(31)].forEach((item1, index1) => {
                    planCycleValueOptions.value.push({ value: `${index + 1}月${index1 + 1}号` })
                })
            })
        } else if (type === '2') {
            ;[...Array(31)].forEach((item, index) => {
                planCycleValueOptions.value.push({ value: `${index + 1}号` })
            })
        } else if (type === '3') {
            ;[...Array(7)].forEach((item, index) => {
                planCycleValueOptions.value.push({ value: `星期${index + 1}` })
            })
        }
    }
)
</script>
applications/task-work-order/src/views/basicManage/maintainRecord/MaintenanceDiaLog.vue
File was deleted
applications/task-work-order/src/views/basicManage/maintainRecord/fwDeviceMaintainRecord.js
File was deleted
applications/task-work-order/src/views/basicManage/maintainRecord/index.vue
@@ -50,7 +50,7 @@
        </el-form>
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">维护计划</el-button>
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button>
            <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
        </div>
@@ -76,8 +76,8 @@
                    </el-table-column>
                    <el-table-column label="操作" class-name="operation-btns">
                        <template v-slot="{ row }">
                            <el-link @click="handleView(row)">查看</el-link>
                            <el-link @click="maintenance(row)">维护</el-link>
                            <el-link @click="openForm('view', row)">查看</el-link>
                            <el-link @click="openForm('edit', row)">编辑</el-link>
                            <el-link @click="handleDelete(row)">删除</el-link>
                        </template>
                    </el-table-column>
@@ -96,8 +96,7 @@
            </div>
        </div>
        <FormDiaLog ref="dialogRef" @success="getList" />
        <MaintenanceDiaLog ref="maintenanceDialogRef" @success="getList" />
        <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" />
    </basic-container>
</template>
<script setup>
@@ -108,7 +107,6 @@
import { getDeptTree } from '@/api/system/dept'
import { getDictLabel } from '@ztzf/utils'
import FormDiaLog from './FormDiaLog.vue'
import MaintenanceDiaLog from '@/views/basicManage/maintainRecord/MaintenanceDiaLog.vue'
import {
    fwDeviceMaintainPlanPageApi,
    fwDeviceMaintainPlanRemoveApi,
@@ -128,7 +126,7 @@
const selectedIds = ref([]) // 勾选的ID列表
const queryParamsRef = ref(null) // 查询表单实例
const dialogRef = ref(null) // 弹框实例
const maintenanceDialogRef = ref(null) // 弹框实例
const dialogVisible = ref(false)
const dictObj = ref({
    deviceType: [], // 设备类型
    deviceAtt: [], // 设备属性
@@ -171,14 +169,13 @@
    getList()
}
// 查看
function handleView(row) {
    dialogRef.value?.open({ mode: 'view', row: { ...row } })
}
// 维护
function maintenance(row) {
    maintenanceDialogRef.value?.open({ mode: 'edit', row: { ...row } })
// 新增/编辑/查看 弹框
function openForm(mode, row) {
    dialogVisible.value = true
    nextTick(() => {
        dialogRef.value?.open({ mode, row })
    })
}
// 删除
@@ -214,11 +211,6 @@
    getDeptTree().then(res => {
        deptTree.value = res.data.data
    })
}
// 新增
function handleAdd() {
    dialogRef.value?.open({ mode: 'add' })
}
function getPlanCycleLabel(row) {
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/FormDiaLog.vue
New file
@@ -0,0 +1,220 @@
<template>
    <el-dialog
        class="gd-dialog"
        v-model="visible"
        :title="titleEnum[dialogMode]"
        @closed="visible = false"
        destroy-on-close
    >
        <div class="detail-container" v-if="dialogReadonly">
            <el-row>
                <el-col :span="12">
                    <div class="label">标题</div>
                    <div class="val">{{ formData.title }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">数据名称</div>
                    <div class="val">{{ formData.dataName }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">提出部门</div>
                    <div class="val">{{ formData.proposeDeptName }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">数据提供部门</div>
                    <div class="val">{{ formData.dataProvideDeptName }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">评分</div>
                    <div class="val">{{ formData.score }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">是否解决</div>
                    <div class="val">{{ formData.isResolved === '1' ? '是' : '否' }}</div>
                </el-col>
                <el-col :span="24">
                    <div class="label">评价内容</div>
                    <div class="val">{{ formData.evaluationContent }}</div>
                </el-col>
            </el-row>
        </div>
        <el-form
            class="dialog-form"
            v-else
            ref="formRef"
            :model="formData"
            :rules="rules"
            :disabled="dialogReadonly"
            label-width="80px"
        >
            <el-row>
                <el-col :span="12">
                    <el-form-item label="标题" prop="title">
                        <el-input class="gd-input" v-model="formData.title" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="数据名称" prop="dataName">
                        <el-input class="gd-input" v-model="formData.dataName" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="提出部门" prop="proposeDeptId">
                        <el-tree-select
                            class="gd-select"
                            popper-class="gd-tree-select-popper"
                            v-model="formData.proposeDeptId"
                            node-key="id"
                            :data="deptTree"
                            :props="treeProps"
                            check-strictly
                            clearable
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="数据提供部门" prop="dataProvideDeptId">
                        <el-tree-select
                            class="gd-select"
                            popper-class="gd-tree-select-popper"
                            v-model="formData.dataProvideDeptId"
                            node-key="id"
                            :data="deptTree"
                            :props="treeProps"
                            check-strictly
                            clearable
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="评分" prop="score">
                        <el-input-number
                            class="gd-input"
                            v-model="formData.score"
                            :min="1"
                            :max="10"
                            placeholder="请输入"
                            controls-position="right"
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="是否解决" prop="isResolved">
                        <el-select
                            class="gd-select"
                            popper-class="gd-select-popper"
                            v-model="formData.isResolved"
                            placeholder="请选择"
                            clearable
                        >
                            <el-option v-for="item in isResolvedOptions" :key="item.value" :label="item.label" :value="item.value" />
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="评价内容" prop="evaluationContent">
                        <el-input
                            class="gd-input"
                            v-model="formData.evaluationContent"
                            type="textarea"
                            :rows="4"
                            placeholder="请输入"
                            clearable
                        />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
            <el-button
                class="save-btn"
                color="#4C34FF"
                v-if="!dialogReadonly"
                :loading="submitting"
                :disabled="submitting"
                @click="handleSubmit"
            >
                保存
            </el-button>
        </template>
    </el-dialog>
</template>
<script setup>
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { fieldRules } from '@ztzf/utils'
import {
    gdDataEvaluationDetailApi,
    gdDataEvaluationSubmitApi,
} from '@/views/orderView/orderDataManage/evaluate/evaluateApi'
// 初始化表单数据
const initForm = () => ({
    title: '',
    dataName: '',
    proposeDeptId: '',
    dataProvideDeptId: '',
    score: null,
    isResolved: '',
    evaluationContent: '',
})
const deptTree = inject('deptTree')
const treeProps = inject('treeProps')
const isResolvedOptions = inject('isResolvedOptions')
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 rules = {
    title: fieldRules(true),
    dataName: fieldRules(true),
    proposeDeptId: fieldRules(true),
    dataProvideDeptId: fieldRules(true),
    score: fieldRules(true),
    isResolved: fieldRules(true),
    evaluationContent: fieldRules(true),
}
// 提交新增/编辑
async function handleSubmit() {
    const isValid = await formRef.value?.validate().catch(() => false)
    if (!isValid) return
    submitting.value = true
    try {
        await gdDataEvaluationSubmitApi(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 gdDataEvaluationDetailApi({ id: formData.value.id })
    formData.value = res?.data?.data ?? {}
}
// 打开弹框
async function open({ mode = 'add', row } = {}) {
    dialogMode.value = mode
    formData.value = dialogMode.value === 'add' ? initForm() : row
    if (dialogMode.value !== 'add') {
        await loadDetail()
    }
}
defineExpose({ open })
</script>
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/evaluateApi.js
New file
@@ -0,0 +1,37 @@
import request from '@/axios'
// 列表
export const gdDataEvaluationPageApi = params => {
    return request({
        url: `/drone-gd/orderdata/gdDataEvaluation/page`,
        method: 'get',
        params: { descs: 'update_time', ...params },
    })
}
// 新增或编辑
export const gdDataEvaluationSubmitApi = data => {
    return request({
        url: `/drone-gd/orderdata/gdDataEvaluation/submit`,
        method: 'post',
        data,
    })
}
// 删除
export const gdDataEvaluationRemoveApi = params => {
    return request({
        url: `/drone-gd/orderdata/gdDataEvaluation/remove`,
        method: 'post',
        params,
    })
}
// 详情
export const gdDataEvaluationDetailApi = params => {
    return request({
        url: `/drone-gd/orderdata/gdDataEvaluation/detail`,
        method: 'get',
        params,
    })
}
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
@@ -1,9 +1,177 @@
<template>
  <basic-container>
    评价管理
  </basic-container>
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
            <el-form-item label="标题" prop="title">
                <el-input class="gd-input" v-model="searchParams.title" placeholder="请输入" clearable @clear="handleSearch" />
            </el-form-item>
            <el-form-item label="是否解决" prop="isResolved">
                <el-select
                    class="gd-select"
                    popper-class="gd-select-popper"
                    v-model="searchParams.isResolved"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option v-for="item in isResolvedOptions" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
            </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="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</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" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column prop="title" show-overflow-tooltip label="标题" />
                    <el-table-column prop="dataName" show-overflow-tooltip label="数据名称" />
                    <el-table-column prop="proposeDeptName" show-overflow-tooltip label="提出部门" />
                    <el-table-column prop="dataProvideDeptName" show-overflow-tooltip label="数据提供部门" />
                    <el-table-column prop="score" show-overflow-tooltip label="评分" />
                    <el-table-column prop="isResolved" show-overflow-tooltip label="是否解决">
                        <template v-slot="{ row }">
                            {{ row.isResolved === '1' ? '是' : '否' }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="evaluationContent" show-overflow-tooltip label="评价内容" />
                    <el-table-column label="操作" class-name="operation-btns">
                        <template v-slot="{ row }">
                            <el-link @click="openForm('view', row)">查看</el-link>
                            <el-link @click="openForm('edit', row)">编辑</el-link>
                            <el-link @click="handleDelete(row)">删除</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" />
    </basic-container>
</template>
<script setup>
import { Search, RefreshRight, Plus, Delete } from '@element-plus/icons-vue'
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getDeptTree } from '@/api/system/dept'
import FormDiaLog from './FormDiaLog.vue'
import {
    gdDataEvaluationPageApi,
    gdDataEvaluationRemoveApi,
} from '@/views/orderView/orderDataManage/evaluate/evaluateApi'
// 初始化查询参数
const initSearchParams = () => ({
    title: '', // 标题
    isResolved: '', // 是否解决
    current: 1, // 当前页
    size: 10, // 每页大小
})
const searchParams = ref(initSearchParams()) // 查询参数
const total = ref(0) // 总条数
const loading = ref(true) // 列表加载中
const list = ref([]) // 列表数据
const selectedIds = ref([]) // 勾选的ID列表
const queryParamsRef = ref(null) // 查询表单实例
const dialogRef = ref(null) // 弹框实例
const dialogVisible = ref(false)
const deptTree = ref([]) // 部门树
const treeProps = {
    label: 'name',
    children: 'children',
}
const isResolvedOptions = [
    { label: '否', value: '0' },
    { label: '是', value: '1' },
]
provide('deptTree', deptTree)
provide('treeProps', treeProps)
provide('isResolvedOptions', isResolvedOptions)
// 获取列表
async function getList() {
    loading.value = true
    try {
        const res = await gdDataEvaluationPageApi(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) {
    const tips = row ? '该条' : '选中的项'
    await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', {
        type: 'warning',
        customClass: 'gd-confirm-custom',
        confirmButtonClass: 'gd-confirm-button',
        cancelButtonClass: 'gd-confirm-cancel-button',
    })
    const ids = row ? row.id : selectedIds.value.join(',')
    await gdDataEvaluationRemoveApi({ ids })
    ElMessage.success('删除成功')
    selectedIds.value = []
    getList()
}
// 勾选值设置
function handleSelectionChange(rows) {
    selectedIds.value = rows.map(item => item.id)
}
// 获取部门树
function getDeptTreeFun() {
    getDeptTree().then(res => {
        deptTree.value = res.data.data
    })
}
onMounted(() => {
    getList()
    getDeptTreeFun()
})
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue
New file
@@ -0,0 +1,310 @@
<template>
    <el-dialog
        class="gd-dialog"
        v-model="visible"
        :title="titleEnum[dialogMode]"
        @closed="visible = false"
        destroy-on-close
    >
        <div class="detail-container" v-if="dialogReadonly">
            <el-row>
                <el-col :span="12">
                    <div class="label">需求名称</div>
                    <div class="val">{{ formData.demandName }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">需求类型</div>
                    <div class="val">{{ getDictLabel(formData.demandType, dictObj.requirementType) }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">需求联系人</div>
                    <div class="val">{{ formData.contactPerson }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">需求联系人电话</div>
                    <div class="val">{{ formData.contactPhone }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">需求邮箱</div>
                    <div class="val">{{ formData.contactEmail }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">更新周期</div>
                    <div class="val">{{ formData.updateCycle }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">申请依据</div>
                    <div class="val">{{ formData.applyBasis }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">共享类型</div>
                    <div class="val">{{ getDictLabel(formData.shareType, dictObj.sharedType) }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">应用场景类型</div>
                    <div class="val">{{ getDictLabel(formData.applicationScene, dictObj.appSceneType) }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">责任部门</div>
                    <div class="val">{{ formData.responsibleDeptName }}</div>
                </el-col>
                <el-col :span="12">
                    <div class="label">数据来源依据</div>
                    <div class="val">{{ formData.dataSource }}</div>
                </el-col>
                <el-col :span="24">
                    <div class="label">需求信息项</div>
                    <div class="val">{{ formData.demandInfo }}</div>
                </el-col>
            </el-row>
        </div>
        <el-form
            class="dialog-form"
            v-else
            ref="formRef"
            :model="formData"
            :rules="rules"
            :disabled="dialogReadonly"
            label-width="120px"
        >
            <el-row>
                <el-col :span="12">
                    <el-form-item label="需求名称" prop="demandName">
                        <el-input class="gd-input" v-model="formData.demandName" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="需求类型" prop="demandType">
                        <el-select
                            class="gd-select"
                            popper-class="gd-select-popper"
                            v-model="formData.demandType"
                            placeholder="请选择"
                            clearable
                        >
                            <el-option
                                v-for="item in dictObj.requirementType"
                                :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="contactPerson">
                        <el-input class="gd-input" v-model="formData.contactPerson" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="需求联系人电话" prop="contactPhone">
                        <el-input class="gd-input" v-model="formData.contactPhone" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="需求邮箱" prop="contactEmail">
                        <el-input class="gd-input" v-model="formData.contactEmail" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="更新周期" prop="updateCycle">
                        <el-input class="gd-input" v-model="formData.updateCycle" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="申请依据" prop="applyBasis">
                        <el-input class="gd-input" v-model="formData.applyBasis" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="共享类型" prop="shareType">
                        <el-select
                            class="gd-select"
                            popper-class="gd-select-popper"
                            v-model="formData.shareType"
                            placeholder="请选择"
                            clearable
                        >
                            <el-option
                                v-for="item in dictObj.sharedType"
                                :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="applicationScene">
                        <el-select
                            class="gd-select"
                            popper-class="gd-select-popper"
                            v-model="formData.applicationScene"
                            placeholder="请选择"
                            clearable
                        >
                            <el-option
                                v-for="item in dictObj.appSceneType"
                                :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="responsibleDeptId">
                        <el-tree-select
                            class="gd-select"
                            popper-class="gd-tree-select-popper"
                            v-model="formData.responsibleDeptId"
                            node-key="id"
                            :data="deptTree"
                            :props="treeProps"
                            check-strictly
                            clearable
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="数据来源依据" prop="dataSource">
                        <el-input class="gd-input" v-model="formData.dataSource" placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="需求信息项" prop="demandInfo">
                        <el-input
                            class="gd-input"
                            v-model="formData.demandInfo"
                            type="textarea"
                            :rows="4"
                            placeholder="请输入"
                            clearable
                        />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <el-button
                class="save-btn"
                color="#4C34FF"
                v-if="!dialogReadonly"
                :loading="submitting"
                :disabled="submitting"
                @click="handleSubmit"
            >
                保存
            </el-button>
            <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button>
        </template>
    </el-dialog>
</template>
<script setup>
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { fieldRules } from '@ztzf/utils'
import { getDictLabel } from '@ztzf/utils'
import {
    gdSupplyDemandDetailApi,
    gdSupplyDemandSubmitApi,
} from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi'
// 初始化表单数据
const initForm = () => ({
    demandName: '',
    demandType: '',
    contactPerson: '',
    contactPhone: '',
    contactEmail: '',
    updateCycle: '',
    applyBasis: '',
    shareType: '',
    applicationScene: '',
    responsibleDeptId: '',
    dataSource: '',
    demandInfo: '',
    demandStatus: '0'
})
const dictObj = inject('dictObj')
const deptTree = inject('deptTree')
const treeProps = inject('treeProps')
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 rules = {
    demandName: fieldRules(true),
    demandType: fieldRules(true),
    contactPerson: fieldRules(true),
    contactPhone: fieldRules(true),
    contactEmail: fieldRules(true),
    updateCycle: fieldRules(true),
    applyBasis: fieldRules(true),
    shareType: fieldRules(true),
    applicationScene: fieldRules(true),
    responsibleDeptId: fieldRules(true),
    dataSource: fieldRules(true),
    demandInfo: fieldRules(true),
}
// 提交新增/编辑
async function handleSubmit() {
    const isValid = await formRef.value?.validate().catch(() => false)
    if (!isValid) return
    submitting.value = true
    try {
        formData.value.demandStatus = '0'
        await gdSupplyDemandSubmitApi(formData.value)
        ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
        visible.value = false
        emit('success')
    } finally {
        submitting.value = false
    }
}
// 申请提交
async function handleApply() {
    const isValid = await formRef.value?.validate().catch(() => false)
    if (!isValid) return
    submitting.value = true
    try {
        formData.value.demandStatus = '1'
        await gdSupplyDemandSubmitApi(formData.value)
        ElMessage.success('申请成功')
        visible.value = false
        emit('success')
    } finally {
        submitting.value = false
    }
}
// 加载详情
async function loadDetail() {
    if (!formData.value.id) return
    const res = await gdSupplyDemandDetailApi({ id: formData.value.id })
    formData.value = res?.data?.data ?? {}
}
// 打开弹框
async function open({ mode = 'add', row } = {}) {
    dialogMode.value = mode
    formData.value = dialogMode.value === 'add' ? initForm() : row
    if (dialogMode.value !== 'add') {
        await loadDetail()
    }
}
defineExpose({ open })
</script>
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
@@ -1,9 +1,217 @@
<template>
  <basic-container>
    供需填报管理
  </basic-container>
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
            <el-form-item label="需求名称" prop="demandName">
                <el-input
                    class="gd-input"
                    v-model="searchParams.demandName"
                    placeholder="请输入"
                    clearable
                    @clear="handleSearch"
                />
            </el-form-item>
            <el-form-item label="需求状态" prop="demandStatus">
                <el-select
                    class="gd-select"
                    popper-class="gd-select-popper"
                    v-model="searchParams.demandStatus"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in dictObj.demandStatus"
                        :key="item.dictKey"
                        :label="item.dictValue"
                        :value="item.dictKey"
                    />
                </el-select>
            </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="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</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" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
                    <el-table-column prop="demandName" show-overflow-tooltip label="需求名称" />
                    <el-table-column prop="demandType" show-overflow-tooltip label="需求类型">
                        <template v-slot="{ row }">
                            {{ getDictLabel(row.demandType, dictObj.requirementType) }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="contactPerson" show-overflow-tooltip label="需求联系人" />
                    <el-table-column prop="contactPhone" show-overflow-tooltip label="需求联系人电话" />
                    <el-table-column prop="contactEmail" show-overflow-tooltip label="需求邮箱" />
                    <el-table-column prop="demandStatus" show-overflow-tooltip label="需求状态">
                        <template v-slot="{ row }">
                            {{ getDictLabel(row.demandStatus, dictObj.demandStatus) }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="updateCycle" show-overflow-tooltip label="更新周期" />
                    <el-table-column prop="applyBasis" show-overflow-tooltip label="申请依据" />
                    <el-table-column prop="shareType" show-overflow-tooltip label="共享类型">
                        <template v-slot="{ row }">
                            {{ getDictLabel(row.shareType, dictObj.sharedType) }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="applicationScene" show-overflow-tooltip label="应用场景类型">
                        <template v-slot="{ row }">
                            {{ getDictLabel(row.applicationScene, dictObj.appSceneType) }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="responsibleDeptName" show-overflow-tooltip label="责任部门" />
                    <el-table-column prop="dataSource" show-overflow-tooltip label="数据来源依据" />
                    <el-table-column prop="demandInfo" show-overflow-tooltip label="需求信息项" />
                    <el-table-column label="操作" class-name="operation-btns">
                        <template v-slot="{ row }">
                            <el-link @click="openForm('view', row)">查看</el-link>
                            <el-link @click="openForm('edit', row)">编辑</el-link>
                            <el-link @click="handleDelete(row)">删除</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" />
    </basic-container>
</template>
<script setup>
import { Search, RefreshRight, Plus, Delete } from '@element-plus/icons-vue'
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getDictionaryByCode } from '@/api/system/dictbiz'
import { getDeptTree } from '@/api/system/dept'
import { getDictLabel } from '@ztzf/utils'
import FormDiaLog from './FormDiaLog.vue'
import {
    gdSupplyDemandPageApi,
    gdSupplyDemandRemoveApi,
} from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi'
// 初始化查询参数
const initSearchParams = () => ({
    demandName: '', // 需求名称
    demandStatus: '', // 需求状态
    current: 1, // 当前页
    size: 10, // 每页大小
})
const searchParams = ref(initSearchParams()) // 查询参数
const total = ref(0) // 总条数
const loading = ref(true) // 列表加载中
const list = ref([]) // 列表数据
const selectedIds = ref([]) // 勾选的ID列表
const queryParamsRef = ref(null) // 查询表单实例
const dialogRef = ref(null) // 弹框实例
const dialogVisible = ref(false)
const dictObj = ref({
    requirementType: [], // 需求类型
    sharedType: [], // 共享类型
    appSceneType: [], // 应用场景类型
})
provide('dictObj', dictObj)
const deptTree = ref([]) // 部门树
const treeProps = {
    label: 'name',
    children: 'children',
}
provide('deptTree', deptTree)
provide('treeProps', treeProps)
// 获取列表
async function getList() {
    loading.value = true
    try {
        const res = await gdSupplyDemandPageApi(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) {
    const tips = row ? '该条' : '选中的项'
    await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', {
        type: 'warning',
        customClass: 'gd-confirm-custom',
        confirmButtonClass: 'gd-confirm-button',
        cancelButtonClass: 'gd-confirm-cancel-button',
    })
    const ids = row ? row.id : selectedIds.value.join(',')
    await gdSupplyDemandRemoveApi({ ids })
    ElMessage.success('删除成功')
    selectedIds.value = []
    getList()
}
// 勾选值设置
function handleSelectionChange(rows) {
    selectedIds.value = rows.map(item => item.id)
}
// 获取字典
function getDictList() {
    getDictionaryByCode('requirementType,sharedType,appSceneType,demandStatus').then(res => {
        dictObj.value = res.data.data
    })
}
// 获取部门树
function getDeptTreeFun() {
    getDeptTree().then(res => {
        deptTree.value = res.data.data
    })
}
onMounted(() => {
    getList()
    getDictList()
    getDeptTreeFun()
})
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/supplyAddApi.js
New file
@@ -0,0 +1,55 @@
import request from '@/axios'
// 获取供需需求列表
export const gdSupplyDemandPageApi = params => {
    return request({
        url: `/drone-gd/orderdata/gdSupplyDemand/page`,
        method: 'get',
        params: { descs: 'update_time', ...params },
    })
}
// 新增或编辑供需需求
export const gdSupplyDemandSubmitApi = data => {
    return request({
        url: `/drone-gd/orderdata/gdSupplyDemand/submit`,
        method: 'post',
        data,
    })
}
// 删除供需需求
export const gdSupplyDemandRemoveApi = params => {
    return request({
        url: `/drone-gd/orderdata/gdSupplyDemand/remove`,
        method: 'post',
        params,
    })
}
// 获取供需需求详情
export const gdSupplyDemandDetailApi = params => {
    return request({
        url: `/drone-gd/orderdata/gdSupplyDemand/detail`,
        method: 'get',
        params,
    })
}
// 审核通过
export const gdSupplyDemandAuditPassApi = data => {
    return request({
        url: `/drone-gd/orderdata/gdSupplyDemand/audit-pass`,
        method: 'post',
        data,
    })
}
// 拒绝申请
export const gdSupplyDemandAuditRejectApi = data => {
    return request({
        url: `/drone-gd/orderdata/gdSupplyDemand/audit-reject`,
        method: 'post',
        data,
    })
}
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
@@ -1,6 +1,6 @@
<template>
  <basic-container>
    基础管理
    基础3管理
  </basic-container>
</template>
<script setup>
applications/task-work-order/src/views/wel/index.vue
@@ -1,6 +1,6 @@
<template>
    <div>
     测试
    </div>
</template>
@@ -10,4 +10,4 @@
<style lang="scss" scoped>
</style>
</style>
uniapps/work-app/src/subPackages/userDetail/infos/index.vue
@@ -25,6 +25,21 @@
                    <div>{{userInfo.deptName}}</div>
                </div>
                <div class="orderRow">
                    <div class="rowTitle">性别</div>
                    <div>
                        <u-radio-group v-model="userInfo.sex">
                            <up-radio
                                v-for="(item, index) in sexList"
                                :key="index"
                                :label="item.label"
                                :name="item.name"
                                @change="radioChange"
                                >
                            </up-radio>
                        </u-radio-group>
                    </div>
                </div>
                <div class="orderRow">
                    <div class="rowTitle">手机号</div>
                    <div>{{userInfo.phone}}</div>
                    <!-- <u-input input-align="right" v-model="userInfo.phone" type="number" placeholder="请输入手机号"
@@ -33,9 +48,9 @@
                </div>
                <div class="orderRow">
                    <div class="rowTitle">邮箱</div>
                    <div>{{userInfo.email}}</div>
                    <!-- <u-input input-align="right" v-model="userInfo.email" type="email" placeholder="请输入邮箱"
                        class="input-item" /> -->
                    <!-- <div>{{userInfo.email}}</div> -->
                    <u-input input-align="right" v-model="userInfo.email" type="email" placeholder="请输入邮箱"
                        class="input-item" />
                </div>
            </div>
        </view>
@@ -61,7 +76,22 @@
        phone: '',
        email: '',
        deptName: '',
        sex: 2,
    });
    const sexList = [
        {
            label: '男',
            name: '0'
        },
        {
            label: '女',
            name: '1'
        },
        {
            label: '未知',
            name: '2'
        }
    ]
    // 校验手机号
    const validatePhone = () => {
        const phone = userInfo.value.phone
@@ -103,6 +133,7 @@
                phone: user.sysDept.phone,
                email: user.sysDept.email,
                deptName: user.sysDept.deptName,
                sex: user.sex || 2,
            };
        });