Merge remote-tracking branch 'origin/master'
57 files modified
4 files added
| | |
| | | }) |
| | | } |
| | | |
| | | // 数据驾驶舱地图聚合 |
| | | export const cockpitAggregationApi = () => { |
| | | return request({ |
| | | url: '/drone-fw/device/fwDevice/statisticalDeviceOut', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 区域列表 |
| | | export const areaDivideListApi = (params) => { |
| | | return request({ |
| | |
| | | }, |
| | | zoomToBoundary: { |
| | | type: Boolean, |
| | | default: true, |
| | | default: false, |
| | | }, |
| | | enableStageEmit: { |
| | | type: Boolean, |
| | |
| | | <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> |
| | |
| | | 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: { |
| | |
| | | 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', |
| | |
| | | viewer.entities.removeById(id) |
| | | }) |
| | | deviceEntityIds.clear() |
| | | deviceEntityMap.clear() |
| | | } |
| | | |
| | | const clearDefenseZoneEntities = () => { |
| | |
| | | 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] }) |
| | | }) |
| | | } |
| | | |
| | | |
| | |
| | | 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 |
| | |
| | | const material = new RadialGradientMaterialProperty(color1, color2) |
| | | viewer.entities.add({ |
| | | id: entityId, |
| | | show: visible, |
| | | polygon: { |
| | | hierarchy: new Cesium.PolygonHierarchy(outerPositions, holes), |
| | | material, |
| | |
| | | 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) && |
| | |
| | | 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, |
| | |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM, |
| | | }, |
| | | }) |
| | | deviceEntityMap.set(entityId, { data: item, entity }) |
| | | }) |
| | | if (selectedDeviceEntity && !deviceEntityMap.has(selectedDeviceEntity.id)) { |
| | | closePopup() |
| | | } |
| | | } |
| | | |
| | | const getDefenseZonePositions = geom => { |
| | |
| | | viewer.dataSources.add(defenseZoneSource) |
| | | } |
| | | clearDefenseZoneEntities() |
| | | defenseZoneSource.show = detailVisible.value |
| | | renderZonePolygons({ |
| | | zones, |
| | | source: defenseZoneSource, |
| | |
| | | viewer.dataSources.add(partitionSource) |
| | | } |
| | | clearPartitionEntities() |
| | | partitionSource.show = detailVisible.value |
| | | renderZonePolygons({ |
| | | zones, |
| | | source: partitionSource, |
| | |
| | | } |
| | | } |
| | | |
| | | 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, |
| | |
| | | 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 => { |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | } |
| | | } |
| | | |
| | | .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; |
| | |
| | | } |
| | | } |
| | | |
| | | .command-data-cockpit-date-picker { |
| | | .command-date-picker { |
| | | box-shadow: none !important; |
| | | background: #161B2C; |
| | | border: none; |
| | |
| | | } |
| | | } |
| | | |
| | | .command-data-cockpit-date-picker-popper { |
| | | .command-date-picker-popper { |
| | | background: #161B2C !important; |
| | | border: none !important; |
| | | border-radius: 0px 0px 8px 8px; |
| | |
| | | } |
| | | } |
| | | |
| | | .command-data-cockpit-select { |
| | | .command-select { |
| | | .el-select__input { |
| | | color: #ffffff !important; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | .command-data-cockpit-select-popper.el-select__popper { |
| | | .command-select-popper.el-select__popper { |
| | | border: none; |
| | | background: #2E2E48 !important; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | .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; |
| | | |
| | |
| | | } |
| | | |
| | | // 树形选择 |
| | | .command-data-cockpit-tree-select-popper { |
| | | .command-tree-select-popper { |
| | | background: #2E2E48 !important; |
| | | border: none !important; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | .command-data-cockpit-dialog { |
| | | .command-dialog { |
| | | padding: 20px; |
| | | display: flex; |
| | | flex-direction: column; |
| | |
| | | text-transform: none; |
| | | } |
| | | |
| | | .command-data-cockpit-search-input { |
| | | .command-search-input { |
| | | .el-input__wrapper { |
| | | background: #2E2E48; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | .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 { |
| | |
| | | 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; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | .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 { |
| | |
| | | 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 { |
| | |
| | | } |
| | | } |
| | | |
| | | .command-data-cockpit-table { |
| | | .command-table { |
| | | height: 0; |
| | | flex: 1; |
| | | background: transparent !important; |
| | |
| | | .el-input-number { |
| | | width: 0; |
| | | flex: 1; |
| | | |
| | | .el-input__inner { |
| | | text-align: left; |
| | | |
| | | &::placeholder { |
| | | text-align: left; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-cascader { |
| | |
| | | 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 { |
| | |
| | | .el-input-number { |
| | | width: 0; |
| | | flex: 1; |
| | | |
| | | .el-input__inner { |
| | | text-align: left; |
| | | |
| | | &::placeholder { |
| | | text-align: left; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-textarea { |
| | |
| | | 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 { |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | } |
| | |
| | | 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' |
| | | |
| | |
| | | /** |
| | | * 公共的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 = { |
| | |
| | | } = 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, // 左下角的动画仪表盘 |
| | |
| | | this.viewer?.imageryLayers.remove(imageryLayers) |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | ## 列表 |
| | | ## 信号干扰,诱导驱离 |
| | | |
| | | |
| | | **接口地址**:`/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": "" |
| | | } |
| | | ``` |
| | | |
| | | |
| | | **请求参数**: |
| | |
| | | |
| | | | 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema | |
| | | | -------- | -------- | ----- | -------- | -------- | ------ | |
| | | |filterSelected|是否过滤已被选择的数据(1过滤 0不过滤)|query|false|integer(int32)|| |
| | | |sceneId|场景id|query|false|integer(int64)|| |
| | | |fwEffectEvalParam|fwEffectEvalParam|body|true|FwEffectEvalParam|FwEffectEvalParam| |
| | | |  alarmRecordId|告警记录ID(ja_fw_drone_alarm_record.id)||false|integer(int64)|| |
| | | |  counterWay|反制方式:1.信号干扰/2.诱导驱离/无||false|string|| |
| | | |
| | | |
| | | **响应状态**: |
| | |
| | | |
| | | | 状态码 | 说明 | schema | |
| | | | -------- | -------- | ----- | |
| | | |200|OK|R«List«FwAreaDivide对象»»| |
| | | |200|OK|R| |
| | | |201|Created|| |
| | | |401|Unauthorized|| |
| | | |403|Forbidden|| |
| | | |404|Not Found|| |
| | |
| | | | 参数名称 | 参数说明 | 类型 | schema | |
| | | | -------- | -------- | ----- |----- | |
| | | |code|状态码|integer(int32)|integer(int32)| |
| | | |data|承载数据|array|FwAreaDivide对象| |
| | | |  areaCode|区域编码|string|| |
| | | |  areaName|区域名称|string|| |
| | | |  areaSize|区域面积(km²)|number|| |
| | | |  areaType|区域类型:报警区/重点管制区|string|| |
| | | |  controlLevel|管控级别:日常/重点/严密|string|| |
| | | |  createDept|创建部门|integer(int64)|| |
| | | |  createTime|创建时间|string(date-time)|| |
| | | |  createUser|创建人|integer(int64)|| |
| | | |  deviceIds|关联设备ID,逗号分隔|string|| |
| | | |  flyDateEnd|可飞行日期时间-结束|string(date-time)|| |
| | | |  flyDateStart|可飞行日期时间-开始|string(date-time)|| |
| | | |  geom|经纬度面(存储地理面数据)|string|| |
| | | |  id|主键id|integer(int64)|| |
| | | |  isDeleted|是否已删除|integer(int32)|| |
| | | |  latitude|区域中心纬度|number(double)|| |
| | | |  longitude|区域中心经度|number(double)|| |
| | | |  policeStationContactPerson|派出所联系人|string|| |
| | | |  policeStationContactPhone|派出所联系电话|string|| |
| | | |  policeStationId|关联派出所id|integer(int64)|| |
| | | |  policeStationName|派出所名称|string|| |
| | | |  responseMechanism|响应机制内容|string|| |
| | | |  status|业务状态|integer(int32)|| |
| | | |  triggerCondition|触发条件|string|| |
| | | |  updateTime|更新时间|string(date-time)|| |
| | | |  updateUser|更新人|integer(int64)|| |
| | | |data|承载数据|object|| |
| | | |msg|返回消息|string|| |
| | | |success|是否成功|boolean|| |
| | | |
| | |
| | | ```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 |
| | | } |
| | |
| | | <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" /> |
| | |
| | | </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" /> |
| | |
| | | |
| | | <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="区域类型"> |
| | |
| | | </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> |
| | |
| | | <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 }"> |
| | |
| | | <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"> |
| | |
| | | 关联场景 |
| | | </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" /> |
| | |
| | | <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> |
| | | |
| | |
| | | |
| | | <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="防区名称" /> |
| | |
| | | </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> |
| | |
| | | <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="类型"> |
| | |
| | | <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"> |
| | |
| | | <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" /> |
| | |
| | | 关联设备 |
| | | </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" /> |
| | |
| | | <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" /> |
| | |
| | | |
| | | <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="区域名称" /> |
| | |
| | | </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> |
| | |
| | | <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> |
| | |
| | | <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> |
| | | |
| | |
| | | |
| | | <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="派出所名称" /> |
| | |
| | | </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> |
| | |
| | | <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 }"> |
| | |
| | | <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" /> |
| | |
| | | 关联区域 |
| | | </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" /> |
| | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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="序号" /> |
| | | |
| | |
| | | |
| | | <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" |
| | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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" |
| | |
| | | |
| | | <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="设备类型"> |
| | |
| | | |
| | | <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" |
| | |
| | | <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="选择日期" |
| | |
| | | <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 |
| | |
| | | </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="选择日期" |
| | |
| | | </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> |
| | |
| | | <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="电话" /> |
| | |
| | | </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> |
| | |
| | | <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" /> |
| | |
| | | </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" /> |
| | |
| | | </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> |
| | |
| | | </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> |
| | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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" |
| | |
| | | |
| | | <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="设备名称" /> |
| | |
| | | |
| | | <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" |
| | |
| | | <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="维护内容" /> |
| | |
| | | </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> |
| | |
| | | <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" /> |
| | |
| | | </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" |
| | |
| | | </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" |
| | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | <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="选择日期" |
| | |
| | | <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" /> |
| | |
| | | </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> |
| | |
| | | |
| | | <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="设备类型"> |
| | |
| | | </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> |
| | |
| | | <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" /> |
| | |
| | | |
| | | <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" /> |
| | |
| | | </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> |
| | |
| | | }) |
| | | |
| | | const dialogTitle = computed(() => { |
| | | return `反制设备名称 ${props.device?.name || ''}`.trim() |
| | | return `${props.device?.name || ''}`.trim() |
| | | }) |
| | | |
| | | const initSearchParams = () => ({ |
| | |
| | | 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> |
| | | |
| | |
| | | |
| | | <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> |
| | |
| | | <!-- 搜索区(设计稿红框) --> |
| | | <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" |
| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | .list-content { |
| | | height: 0; |
| | | flex: 1; |
| | | overflow-y: auto; |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | .collapse-btn { |
| | | position: absolute; |
| | | top: 50%; |
| | | bottom: 454px; |
| | | left: 300px; |
| | | cursor: pointer; |
| | | display: flex; |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | height: 0; |
| | | flex: 1; |
| | | margin-top: 20px; |
| | | overflow-x: hidden; |
| | | overflow-y: auto; |
| | | overflow: hidden; |
| | | } |
| | | </style> |
| | |
| | | * @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. |
| | |
| | | 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> |
| | | |
| | |
| | | |
| | | 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) => { |
| | |
| | | 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}失败` }) |
| | | } |
| | |
| | | |
| | | <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> |
| | |
| | | * @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. |
| | |
| | | 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 |
| | |
| | | |
| | | .collapse-btn { |
| | | position: absolute; |
| | | top: 50%; |
| | | bottom: 454px; |
| | | right: 300px; |
| | | cursor: pointer; |
| | | display: flex; |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | <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> |
| | |
| | | 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> |
| | |
| | | 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%; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | </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> |
| | |
| | | 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 || '-' |
| | | } |
| | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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="无人机类型" /> |
| | |
| | | |
| | | <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" |
| | |
| | | <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 |
| | |
| | | </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 |
| | |
| | | </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="请选择位置" |
| | |
| | | </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 |
| | |
| | | </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 |
| | |
| | | </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" |
| | |
| | | } 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 |
| | |
| | | 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: { |
| | |
| | | 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), |
| | | }, |
| | | }) |
| | |
| | | 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 |
| | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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="设备类型"> |
| | |
| | | |
| | | <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" |
| | |
| | | <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="请输入" |
| | |
| | | <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="请输入" |
| | |
| | | <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 |
| | |
| | | <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="请输入" |
| | |
| | | <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 |
| | |
| | | <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 |
| | |
| | | <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 |
| | |
| | | <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="请输入" |
| | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <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 }"> |
| | |
| | | |
| | | <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" |
| | |
| | | <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 |
| | |
| | | <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="选择设备后自动带出" |
| | |
| | | <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 |
| | |
| | | <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 |
| | |
| | | <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="请输入" |
| | |
| | | <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="至" |
| | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | <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 |
| | |
| | | |
| | | <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 |
| | |
| | | |
| | | <el-form-item label="设备编码" prop="deviceSn"> |
| | | <el-input |
| | | class="command-data-cockpit-search-input" |
| | | class="command-search-input" |
| | | v-model="searchParams.deviceSn" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | |
| | | <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="设备名称" /> |
| | |
| | | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | </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> |
| | |
| | | <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 |
| | |
| | | </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> |
| | |
| | | </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> |
| | |
| | | <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 |
| | |
| | | |
| | | <el-form-item label="部门全称" prop="fullName"> |
| | | <el-input |
| | | class="command-data-cockpit-search-input" |
| | | class="command-search-input" |
| | | v-model="searchParams.fullName" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | <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 |
| | |
| | | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | <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 |
| | |
| | | |
| | | <el-form-item label="角色别名" prop="roleAlias"> |
| | | <el-input |
| | | class="command-data-cockpit-search-input" |
| | | class="command-search-input" |
| | | v-model="searchParams.roleAlias" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | <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' }" |
| | |
| | | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | <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" /> |
| | |
| | | <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="请选择" |
| | |
| | | <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" |
| | |
| | | <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" |
| | |
| | | <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="请选择" |
| | |
| | | </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" |
| | |
| | | <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" |
| | |
| | | <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 |
| | |
| | | |
| | | <el-form-item label="用户姓名" prop="realName"> |
| | | <el-input |
| | | class="command-data-cockpit-search-input" |
| | | class="command-search-input" |
| | | v-model="searchParams.realName" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | |
| | | <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" |
| | |
| | | |
| | | <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="登录账号" /> |
| | |
| | | |
| | | <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" |
| | |
| | | <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 |
| | |
| | | </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 |
| | |
| | | </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 |
| | |
| | | </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="至" |
| | |
| | | |
| | | <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="无人机名称" /> |
| | |
| | | |
| | | <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" |
| | |
| | | <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> |
| | |
| | | <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 |
| | |
| | | </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 |
| | |
| | | </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="至" |
| | |
| | | |
| | | <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="无人机序列号" /> |
| | |
| | | |
| | | <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" |
| New file |
| | |
| | | <template> |
| | | <div class="page-container"> |
| | | <div class="map" id="map"></div> |
| | | <!-- <div class="layer-btn" @click="layerChangePopupShow = true" v-show="layerShow"> |
| | | <van-image width="20" height="20" :src="layerIcon" /> |
| | | <div class="label">图层</div> |
| | | </div> |
| | | |
| | | <div class="location-btn" @click="setMapLocation" v-show="locationShow"> |
| | | <van-image width="20" height="20" :src="locationIcon" /> |
| | | <div class="label">定位</div> |
| | | </div> --> |
| | | <slot name="searchBar"></slot> |
| | | <van-popup v-model:show="layerChangePopupShow" position="bottom" round> |
| | | <div class="popup-container"> |
| | | <div class="category-content"> |
| | | <div class="header"> |
| | | <div class="title">底图切换</div> |
| | | </div> |
| | | |
| | | <div class="content"> |
| | | <div |
| | | class="layer-box" |
| | | :class="{ on: setSelectMapLayerKey === item.key }" |
| | | v-for="(item, ind) in layers" |
| | | :key="ind" |
| | | @click="setMapLayer(item)" |
| | | > |
| | | <div class="image"> |
| | | <van-image :src="item.src" width="100%" height="100%"></van-image> |
| | | </div> |
| | | <div class="label">{{ item.name }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </van-popup> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import * as turf from '@turf/turf' |
| | | import addressLocationIcon from '@/appDataSource/leafletMapIcon/address-location.svg' |
| | | import droneIcon from '@/appDataSource/leafletMapIcon/drone-icon.svg' |
| | | import userLocationIcon from '@/appDataSource/leafletMapIcon/user-location.svg' |
| | | import layerIcon from '@/appDataSource/leafletMapIcon/layer-icon.svg' |
| | | import locationIcon from '@/appDataSource/leafletMapIcon/location-icon.svg' |
| | | import { useStore } from 'vuex' |
| | | import { showToast } from 'vant' |
| | | import L from 'leaflet' |
| | | import 'leaflet/dist/leaflet.css' |
| | | import sl from '@/appDataSource/leafletMapIcon/sl.svg' |
| | | import yx from '@/appDataSource/leafletMapIcon/yx.svg' |
| | | import EventBus from '@/utils/eventBus' |
| | | import { getEventImage } from '@/utils/stateToImageMap/event' |
| | | const emit = defineEmits(['location-selected']) |
| | | const { weatherShow, layerShow, locationShow, createWorkShow } = defineProps({ |
| | | weatherShow: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | layerShow: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | locationShow: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | createWorkShow: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | }) |
| | | |
| | | const isProd = import.meta.env.VITE_APP_ENV === 'production' |
| | | |
| | | import { basemapLayer0, basemapLayer1, basemapLayer2, basemapLayer3 } from '@/const/leafletConst' |
| | | |
| | | const basemap0 = L.layerGroup([basemapLayer0, basemapLayer1]) |
| | | const basemap1 = L.layerGroup([basemapLayer2, basemapLayer3]) |
| | | |
| | | let map = null |
| | | const isMapReady = ref(false) |
| | | |
| | | const layers = [ |
| | | { |
| | | src: sl, |
| | | name: '矢量', |
| | | key: 1, |
| | | map: basemap0, |
| | | }, |
| | | { |
| | | src: yx, |
| | | name: '影像', |
| | | key: 2, |
| | | map: basemap1, |
| | | }, |
| | | ] |
| | | |
| | | const layerChangePopupShow = ref(false) |
| | | const setSelectMapLayerKey = ref(1) // 选择的地图图层 |
| | | |
| | | let droneMarkersLayer = null |
| | | let eventMarkersLayer = null |
| | | let addressMarkersLayer = null |
| | | let mapLayerSourceLayer = null // 空域信息 |
| | | |
| | | const initMap = () => { |
| | | if (map) return |
| | | map = L.map('map', { |
| | | preferCanvas: true, |
| | | crs: L.CRS.EPSG4326, |
| | | zoomControl: false, |
| | | attributionControl: false, |
| | | doubleClickZoom: false, |
| | | editable: true, //绘制控件 |
| | | }).setView([27.117445, 114.984917], 10) |
| | | |
| | | map.whenReady(() => { |
| | | isMapReady.value = true |
| | | }) |
| | | |
| | | droneMarkersLayer = L.layerGroup([], { pane: 'drones' }).addTo(map) // 创建一个标注层,便于管理和移除 |
| | | eventMarkersLayer = L.layerGroup([], { pane: 'events' }).addTo(map) // 创建一个标注层,便于管理和移除 |
| | | addressMarkersLayer = L.layerGroup([], { pane: 'addresses' }).addTo(map) // 创建一个标注层,便于管理和移除 |
| | | // 空域信息 |
| | | mapLayerSourceLayer = L.layerGroup([], { pane: 'mapLayerSource' }).addTo(map) |
| | | |
| | | map.on('zoomend', function () { |
| | | var currentZoom = map.getZoom() |
| | | if (currentZoom >= 11) { |
| | | eventMarkersLayer.addTo(map) |
| | | } else { |
| | | eventMarkersLayer.remove() |
| | | } |
| | | }) |
| | | |
| | | if (createWorkShow) { |
| | | getMapLocation() |
| | | } |
| | | } |
| | | |
| | | const getCurMap = () => { |
| | | return map |
| | | } |
| | | |
| | | const setMapLayer = item => { |
| | | map.removeLayer(layers.find(i => i.key === setSelectMapLayerKey.value).map) |
| | | |
| | | map.addLayer(item.map) |
| | | |
| | | setSelectMapLayerKey.value = item.key |
| | | } |
| | | |
| | | let locationFlag = false |
| | | let watchId = null |
| | | let userLocationMarker = null |
| | | const setMapLocation = () => { |
| | | locationFlag = true |
| | | |
| | | // 在WebView加载的网页中 |
| | | // 检查浏览器是否支持 geolocation |
| | | if (navigator.geolocation) { |
| | | if (watchId) { |
| | | // 停止监听位置 |
| | | navigator.geolocation.clearWatch(watchId) |
| | | } |
| | | |
| | | // 开始持续获取用户的位置 |
| | | watchId = navigator.geolocation.watchPosition( |
| | | function (position) { |
| | | // 成功获取位置信息时回调 |
| | | const lat = position.coords.latitude // 纬度 |
| | | const lng = position.coords.longitude // 经度 |
| | | |
| | | if (locationFlag) { |
| | | if (userLocationMarker) { |
| | | userLocationMarker.setLatLng([lat, lng]) |
| | | } else { |
| | | userLocationMarker = L.marker([lat, lng], { |
| | | icon: L.icon({ |
| | | iconUrl: userLocationIcon, // 图片路径 |
| | | iconSize: [24, 24], // 图标尺寸 |
| | | iconAnchor: [12, 12], // 锚点位置 |
| | | }), |
| | | }).addTo(map) |
| | | } |
| | | |
| | | mapSetView({ |
| | | lat, |
| | | lng, |
| | | }) |
| | | |
| | | locationFlag = false |
| | | |
| | | return |
| | | } |
| | | |
| | | if (userLocationMarker) { |
| | | userLocationMarker.setLatLng([lat, lng]) |
| | | } |
| | | }, |
| | | function (error) { |
| | | // 如果获取位置失败,执行回调 |
| | | console.error('Error occurred: ' + error.message) |
| | | }, |
| | | { |
| | | enableHighAccuracy: true, // 尝试获取更高精度的定位 |
| | | timeout: 10000, // 如果10秒内没有获取到位置,就中止 |
| | | maximumAge: 0, // 始终请求新的定位,不使用缓存 |
| | | } |
| | | ) |
| | | } else { |
| | | console.log('该浏览器不支持地理定位功能。') |
| | | } |
| | | } |
| | | let lastLocationMarker = null |
| | | const getMapLocation = () => { |
| | | map.off('click') |
| | | map.on('click', function (e) { |
| | | const { lat, lng } = e.latlng |
| | | |
| | | if (lastLocationMarker) { |
| | | map.removeLayer(lastLocationMarker) |
| | | } |
| | | lastLocationMarker = L.marker([lat, lng]).addTo(map) |
| | | emit('location-selected', { |
| | | latitude: lat, |
| | | longitude: lng, |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const mapSetView = data => { |
| | | const { lat, lng, zoom = 16 } = data |
| | | |
| | | if (!map) return |
| | | |
| | | map.setView([lat, lng], zoom, { |
| | | animate: false, // 使用动画过渡 |
| | | }) |
| | | } |
| | | |
| | | const mapAddMarker = data => { |
| | | if (!map) return |
| | | const { lat, lng, zoom = 16, name = '', customClassName = '' } = data |
| | | mapSetView(data) |
| | | |
| | | // 创建带有图标和文字的 divIcon |
| | | let droneHtmlIcon = L.divIcon({ |
| | | html: ` |
| | | <div class="content ${customClassName}"> |
| | | <img src="${addressLocationIcon}"> |
| | | <span> |
| | | ${name} |
| | | </span> |
| | | </div> |
| | | `, |
| | | className: 'ztzf-address-custom-icon', // 可选,用于添加CSS类 |
| | | iconSize: [24, 38], // 设置图标大小 |
| | | iconAnchor: [12, 19], |
| | | }) |
| | | |
| | | L.marker([lat, lng], { icon: droneHtmlIcon }).addTo(addressMarkersLayer) |
| | | } |
| | | |
| | | // 吉安项目-空域信息 |
| | | // 统一的飞行函数 |
| | | function flyVisual(coordinates) { |
| | | // 确保map对象存在且坐标有效 |
| | | if (!map || !coordinates || !coordinates.length) return; |
| | | |
| | | try { |
| | | // 改进坐标格式判断 |
| | | let isSinglePoint = false; |
| | | let latLng; |
| | | let bounds; |
| | | |
| | | // 处理不同格式的坐标输入 |
| | | if (Array.isArray(coordinates[0])) { |
| | | if (coordinates[0].length === 2) { |
| | | // 格式: [[lng, lat]] - 单个点 |
| | | isSinglePoint = true; |
| | | latLng = [coordinates[0][1], coordinates[0][0]]; // 转换为 [lat, lng] |
| | | } else if (coordinates[0].length > 2 && Array.isArray(coordinates[0][0])) { |
| | | // 格式: [[[lng, lat], [lng, lat], ...]] - 多边形 |
| | | const polygonCoords = coordinates[0].map(coord => [coord[1], coord[0]]); |
| | | bounds = L.latLngBounds(polygonCoords); |
| | | } else { |
| | | // 格式: [[lng, lat], [lng, lat], ...] - 多个点或线 |
| | | if (coordinates.length === 1) { |
| | | // 单个点 |
| | | isSinglePoint = true; |
| | | latLng = [coordinates[0][1], coordinates[0][0]]; |
| | | } else { |
| | | // 多个点 |
| | | const leafletCoords = coordinates.map(coord => [coord[1], coord[0]]); |
| | | bounds = L.latLngBounds(leafletCoords); |
| | | } |
| | | } |
| | | } else if (coordinates.length === 2) { |
| | | // 格式: [lng, lat] - 单个点 |
| | | isSinglePoint = true; |
| | | latLng = [coordinates[1], coordinates[0]]; |
| | | } |
| | | |
| | | if (isSinglePoint && latLng) { |
| | | // 单个坐标点 |
| | | map.flyTo(latLng, 10, { |
| | | duration: 1, |
| | | easeLinearity: 0.2 |
| | | }); |
| | | } else if (bounds) { |
| | | // 多边形或多个点 |
| | | map.flyToBounds(bounds, { |
| | | padding: [30, 30], |
| | | duration: 2, |
| | | maxZoom: 13 |
| | | }); |
| | | } |
| | | } catch (error) { |
| | | console.error('flyVisual 函数执行错误:', error); |
| | | } |
| | | } |
| | | // 点击单个飞行 |
| | | function signFlyToMarker(item) { |
| | | const positionsData = JSON.parse(item.geoJson); |
| | | const coordinates = positionsData.coordinates; |
| | | |
| | | // 更全面的空值检查 |
| | | let hasValidCoordinates = false; |
| | | |
| | | // 检查不同格式的坐标数据 |
| | | if (Array.isArray(coordinates)) { |
| | | if (coordinates.length > 0) { |
| | | // 检查是否有有效的坐标点 |
| | | if (Array.isArray(coordinates[0])) { |
| | | if (coordinates[0].length === 2 || coordinates[0].length === 3) { |
| | | // 格式: [lng, lat] 或 [lng, lat, alt] |
| | | hasValidCoordinates = true; |
| | | } else if (Array.isArray(coordinates[0][0])) { |
| | | // 格式: [[lng, lat], [lng, lat], ...] |
| | | hasValidCoordinates = coordinates[0].length > 0; |
| | | } else if (Array.isArray(coordinates[0][0][0])) { |
| | | // 格式: [[[lng, lat], [lng, lat], ...]] |
| | | hasValidCoordinates = coordinates[0][0].length > 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!hasValidCoordinates) { |
| | | console.log('没有有效的坐标数据,显示提示'); |
| | | return showToast('暂无区域数据'); |
| | | } |
| | | |
| | | // 单个位置飞行 |
| | | flyVisual(coordinates); |
| | | } |
| | | // 清空所有空域信息 |
| | | function mapClearAirMarker() { |
| | | if (!map) return |
| | | // 清空所有图层 |
| | | if (mapLayerSourceLayer) { |
| | | mapLayerSourceLayer.clearLayers(); |
| | | } |
| | | } |
| | | function mapAddAirMarker(data) { |
| | | // 清空所有图层 |
| | | mapClearAirMarker() |
| | | |
| | | data |
| | | .filter(item => item.geoJson) |
| | | .forEach(item => { |
| | | const parseParsed = JSON.parse(item.geoJson); // 转为数组 |
| | | if (parseParsed.type !== 'Polygon') return |
| | | const parsed = parseParsed.coordinates[0] |
| | | |
| | | const grouped = parsed.flat(); // 再展开 |
| | | |
| | | // 3. 计算多边形质心 |
| | | const turfPolygon = turf.polygon([parsed]); |
| | | const center = turf.centerOfMass(turfPolygon); |
| | | const centerLatLng = [center.geometry.coordinates[1], center.geometry.coordinates[0]]; |
| | | |
| | | const labelMarker = L.marker(centerLatLng, { |
| | | icon: L.divIcon({ |
| | | className: 'polygon-label', |
| | | html: ` |
| | | <div style=" |
| | | color: ${item.airspaceType === '0' ? '#008013' : '#ff0000'}; |
| | | font-weight: bold; |
| | | font-size: 12px; |
| | | font-family: 'Source Han Sans CN', 'Source Han Sans CN'; |
| | | white-space: nowrap; |
| | | "> |
| | | ${item.airspaceType === '1' ? '禁飞区' : item.airspaceType === '2' ? '危险区' : item.airspaceType === '3' ? '限制区' : item.airspaceType === '0' ? '适飞区' : '未知'} |
| | | </div> |
| | | `, |
| | | iconSize: null, // 让div决定大小 |
| | | iconAnchor: null // 不需要锚点,用CSS transform居中 |
| | | }), |
| | | interactive: false, // 标签不参与交互 |
| | | // zIndexOffset: 1000 // 确保标签在最上层 |
| | | }); |
| | | |
| | | // 将坐标数组转换为 Leaflet 格式 [lat, lng, lat, lng...] -> [[lat, lng], [lat, lng]...] |
| | | const latLngs = []; |
| | | for (let i = 0; i < grouped.length; i += 2) { |
| | | latLngs.push([grouped[i + 1], grouped[i]]); // 注意:Leaflet 是 [lat, lng] 顺序 |
| | | } |
| | | |
| | | // 创建多边形(填充区域) |
| | | const polygon = L.polygon(latLngs, { |
| | | color: item.airspaceType === '0' ? '#00ff06' : '#ff0000', |
| | | fillColor: item.airspaceType === '0' ? '#00ff06' : '#ff0000', |
| | | fillOpacity: 0.5, |
| | | weight: 0, // 隐藏多边形边框,使用折线作为边框 |
| | | }); |
| | | |
| | | // 创建折线(边框) |
| | | const polyline = L.polyline([...latLngs, latLngs[0]], { // 闭合多边形 |
| | | color: item.airspaceType === '0' ? '#00ff06' : '#ff0000', |
| | | weight: 1.5, |
| | | opacity: 1, |
| | | fill: false |
| | | }); |
| | | |
| | | // 将两个图层组合在一起 |
| | | const group = L.featureGroup([polygon, polyline, labelMarker]); |
| | | // 添加到图层组 |
| | | mapLayerSourceLayer.addLayer(group); |
| | | }); |
| | | } |
| | | |
| | | const mapClearMarker = () => { |
| | | addressMarkersLayer.clearLayers() |
| | | } |
| | | |
| | | // 天气 |
| | | const store = useStore() |
| | | const selectedAreaCode = computed(() => store.state.user.selectedAreaCode) |
| | | |
| | | onMounted(async () => { |
| | | |
| | | await nextTick() |
| | | initMap() |
| | | map.addLayer(layers[0].map) |
| | | |
| | | EventBus.on('mapSetView', mapSetView) |
| | | EventBus.on('mapAddMarker', mapAddMarker) |
| | | EventBus.on('mapAddAirMarker', mapAddAirMarker) |
| | | EventBus.on('signFlyToMarker', signFlyToMarker) |
| | | EventBus.on('mapClearAirMarker', mapClearAirMarker) |
| | | EventBus.on('mapClearMarker', mapClearMarker) |
| | | |
| | | // L.circle([24, 112], { |
| | | // color: 'red', // 边框颜色 |
| | | // fillColor: '#f03', // 填充颜色 |
| | | // fillOpacity: 0.5, // 填充透明度 |
| | | // radius: 5000, // 半径,单位是米 |
| | | // }).addTo(map) |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | | EventBus.off('mapSetView', mapSetView) |
| | | EventBus.off('mapAddMarker', mapAddMarker) |
| | | EventBus.off('mapAddAirMarker', mapAddAirMarker) |
| | | EventBus.off('signFlyToMarker', signFlyToMarker) |
| | | EventBus.off('mapClearAirMarker', mapClearAirMarker) |
| | | EventBus.off('mapClearMarker', mapClearMarker) |
| | | }) |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .page-container { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | |
| | | .map { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | |
| | | .location-btn, |
| | | .layer-btn { |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | position: absolute; |
| | | right: 8px; |
| | | width: 40px; |
| | | height: 40px; |
| | | background: #ffffff; |
| | | box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2); |
| | | border-radius: 6px 6px 6px 6px; |
| | | z-index: 996; |
| | | |
| | | .label { |
| | | font-size: 10px; |
| | | } |
| | | } |
| | | |
| | | .layer-btn { |
| | | bottom: 130px; |
| | | } |
| | | |
| | | .location-btn { |
| | | bottom: 80px; |
| | | } |
| | | } |
| | | |
| | | .popup-container { |
| | | height: 300px; |
| | | overflow-y: auto; |
| | | padding: 10px 22px; |
| | | background: #fff; |
| | | border-radius: 12px 12px 0 0; |
| | | |
| | | .category-content { |
| | | margin-bottom: 10px; |
| | | .header { |
| | | margin-bottom: 10px; |
| | | height: 20px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: bold; |
| | | font-size: 16px; |
| | | color: #222324; |
| | | line-height: 20px; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | .base-header { |
| | | margin-top: 10px; |
| | | } |
| | | .content { |
| | | //padding: 12px; |
| | | display: flex; |
| | | background: #fff; |
| | | border-radius: 16px; |
| | | |
| | | .layer-box { |
| | | margin-left: calc((100% / 3 - 84px) * 3 / 2); |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &.on { |
| | | .image { |
| | | position: relative; |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | border-radius: 4px 4px 4px 4px; |
| | | border: 4px solid #1d6fe9; |
| | | z-index: 1; |
| | | box-sizing: border-box; |
| | | } |
| | | } |
| | | |
| | | .label { |
| | | color: #1d6fe9; |
| | | } |
| | | } |
| | | |
| | | .image { |
| | | width: 84px; |
| | | height: 82px; |
| | | border-radius: 4px 4px 4px 4px; |
| | | overflow: hidden; |
| | | box-sizing: border-box; |
| | | border: none; |
| | | } |
| | | |
| | | .label { |
| | | margin-top: 6px; |
| | | height: 20px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #222324; |
| | | line-height: 20px; |
| | | text-align: center; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | .layer-box:nth-child(3n + 1) { |
| | | margin-left: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | |
| | | responsibleDeptId: '', |
| | | dataSource: '', |
| | | demandInfo: '', |
| | | demandStatus: '0' |
| | | }) |
| | | |
| | | const dictObj = inject('dictObj') |
| | |
| | | if (!isValid) return |
| | | submitting.value = true |
| | | try { |
| | | formData.value.demandStatus = '0' |
| | | await gdSupplyDemandSubmitApi(formData.value) |
| | | ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功') |
| | | visible.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 |
| | |
| | | <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 }"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDictLabel(row.demandStatus, dictObj.demandStatus) }} |
| | | </template> --> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateCycle" show-overflow-tooltip label="更新周期" /> |
| | | <el-table-column prop="applyBasis" show-overflow-tooltip label="申请依据" /> |
| | |
| | | |
| | | // 获取字典 |
| | | function getDictList() { |
| | | getDictionaryByCode('requirementType,sharedType,appSceneType').then(res => { |
| | | getDictionaryByCode('requirementType,sharedType,appSceneType,demandStatus').then(res => { |
| | | dictObj.value = res.data.data |
| | | }) |
| | | } |
| | |
| | | onMounted(async () => { |
| | | getProTypeApi() |
| | | getManufacturerInfoApi() |
| | | // 动态导入xzqhData,确保在使用前已初始化 |
| | | const { xzqhData } = await import('@/static/xzqh/index') |
| | | areaData.value = xzqhData |
| | | // 动态从外部URL导入xzqhData,确保在使用前已初始化 |
| | | // 注意:直接动态导入外部URL可能会有跨域或构建问题,建议检查服务器CORS设置 |
| | | const response = await fetch('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ja-app-wx/xzqh/index.json') |
| | | const text = await response.text() |
| | | areaData.value = JSON.parse(text) |
| | | }) |
| | | </script> |
| | | <style scoped lang="scss"> |