From 40780bc04d8747f0918ee7e2a551776e69c44232 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Wed, 25 Feb 2026 17:08:08 +0800
Subject: [PATCH] feat:图层控制面板调整
---
applications/drone-command/src/components/map-container/device-map-container.vue | 219 +++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 156 insertions(+), 63 deletions(-)
diff --git a/applications/drone-command/src/components/map-container/device-map-container.vue b/applications/drone-command/src/components/map-container/device-map-container.vue
index a16f191..59adb40 100644
--- a/applications/drone-command/src/components/map-container/device-map-container.vue
+++ b/applications/drone-command/src/components/map-container/device-map-container.vue
@@ -7,30 +7,41 @@
@stage-change="handleStageChange" />
<div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.rightCollapsed }">
<div class="layer-control-wrap" ref="layerWrapRef">
- <div class="layer-control" @click="toggleLayerPanel">
+ <div class="layer-control" @click.stop="toggleLayerPanel">
<img :src="layerControlIcon" alt="图层控制" />
</div>
<transition name="layer-panel-slide">
<div v-if="showLayerPanel" class="layer-panel">
- <div class="panel-title">底图切换</div>
- <div class="base-map-options">
- <div class="base-map-card" :class="{ active: baseLayerKey === 'base-standard' }"
- @click="handleBaseLayerSelect('base-standard')">
- <img class="base-map-thumb standard" :src="dzIcon" alt="">
- <div class="base-map-label">标准地图</div>
- </div>
- <div class="base-map-card" :class="{ active: baseLayerKey === 'base-satellite' }"
- @click="handleBaseLayerSelect('base-satellite')">
- <img class="base-map-thumb satellite" :src="yxIcon" alt="">
- <div class="base-map-label">卫星地图</div>
- </div>
- </div>
-
<div class="panel-title">图层管理</div>
<div class="panel-content">
- <el-tree ref="layerTreeRef" class="command-tree map-layer-tree" :data="layerTree" show-checkbox
- default-expand-all node-key="key" :props="layerTreeProps"
+ <el-tree ref="layerTreeRef" class="command-tree map-layer-tree" :data="layerTree"
+ show-checkbox default-expand-all node-key="key" :props="layerTreeProps"
:default-checked-keys="treeCheckedKeys" @check="handleLayerCheck" />
+ </div>
+ </div>
+ </transition>
+ </div>
+ </div>
+ <div v-if="props.showLayerControl" class="base-layer-switch-root" :class="{ collapsed: props.rightCollapsed }">
+ <div class="base-layer-switch-wrap" @mouseenter="showBaseLayerPanel = true"
+ @mouseleave="showBaseLayerPanel = false">
+ <div class="base-layer-trigger">
+ <img class="base-layer-trigger-thumb" :src="currentBaseLayer.icon" :alt="currentBaseLayer.label">
+ <div class="base-layer-trigger-label">{{ currentBaseLayer.shortLabel }}</div>
+ </div>
+ <transition name="layer-panel-slide">
+ <div v-if="showBaseLayerPanel" class="base-layer-panel">
+ <div class="base-map-options">
+ <div class="base-map-card" :class="{ active: baseLayerKey === 'base-satellite' }"
+ @click="handleBaseLayerSelect('base-satellite')">
+ <img class="base-map-thumb" :src="yxIcon" alt="">
+ <div class="base-map-label">卫星地图</div>
+ </div>
+ <div class="base-map-card" :class="{ active: baseLayerKey === 'base-standard' }"
+ @click="handleBaseLayerSelect('base-standard')">
+ <img class="base-map-thumb" :src="dzIcon" alt="">
+ <div class="base-map-label">标准地图</div>
+ </div>
</div>
</div>
</transition>
@@ -141,6 +152,7 @@
const clusterVisible = ref(false)
const countyCenterMap = new Map()
const showLayerPanel = ref(false)
+const showBaseLayerPanel = ref(false)
const layerWrapRef = ref(null)
const layerTreeRef = ref(null)
const selectedDevice = ref(null)
@@ -155,6 +167,11 @@
const baseLayerKeys = ['base-standard', 'base-satellite']
const defaultCheckedKeys = ['ja-terrain', 'admin', 'city-base']
const baseLayerKey = ref('base-satellite')
+const baseLayerMeta = {
+ 'base-standard': { icon: dzIcon, label: '标准地图', shortLabel: '标准' },
+ 'base-satellite': { icon: yxIcon, label: '卫星地图', shortLabel: '影像' },
+}
+const currentBaseLayer = computed(() => baseLayerMeta[baseLayerKey.value] || baseLayerMeta['base-satellite'])
const treeCheckedKeys = ref([...defaultCheckedKeys])
const layerTree = ref([
{
@@ -1294,7 +1311,9 @@
watch(
() => props.rightCollapsed,
isCollapsed => {
- if (isCollapsed) showLayerPanel.value = false
+ if (!isCollapsed) return
+ showLayerPanel.value = false
+ showBaseLayerPanel.value = false
}
)
@@ -1333,7 +1352,7 @@
setDroneVisibility(!showCluster)
}
-const handleMapReady = async ({ viewer: mapViewer, publicCesium: mapPublic }) => {
+const handleMapReady = async ({ viewer: mapViewer, publicCesium: mapPublic }) => {
if (mapReadyHandled) return
mapReadyHandled = true
viewer = mapViewer
@@ -1355,7 +1374,7 @@
updateStageDisplay(stage)
}
-const handleClickOutside = event => {
+const handleLayerClickOutside = event => {
if (!showLayerPanel.value) return
const target = event.target
if (layerWrapRef.value?.contains(target)) return
@@ -1363,13 +1382,13 @@
}
onMounted(() => {
- document.addEventListener('click', handleClickOutside)
+ document.addEventListener('click', handleLayerClickOutside)
const map = mapRef.value?.getMap()
if (map?.viewer) handleMapReady(map)
})
onBeforeUnmount(() => {
- document.removeEventListener('click', handleClickOutside)
+ document.removeEventListener('click', handleLayerClickOutside)
clearDeviceEntities()
clearPartitionEntities()
clearAggregationEntities()
@@ -1480,51 +1499,125 @@
overflow: auto;
}
- .base-map-title {
- margin-bottom: 8px;
- font-size: 12px;
- color: #ffffff;
- font-weight: 600;
- }
+}
- .base-map-options {
- padding: 16px;
- display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
- gap: 8px;
- }
+.base-layer-switch-root {
+ position: absolute;
+ right: 337px;
+ bottom: 78px;
+ z-index: 11;
+ transition: transform 0.3s ease-in-out;
+ pointer-events: none;
- .base-map-card {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 6px;
+ &.collapsed {
+ transform: translateX(317px);
+ }
+}
+
+.base-layer-switch-wrap {
+ position: relative;
+ pointer-events: auto;
+}
+
+.base-layer-trigger {
+ width: 55px;
+ padding: 8px 0;
+ border-radius: 8px;
+ background: #191932;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 6px;
+ cursor: pointer;
+}
+
+.base-layer-trigger-thumb {
+ width: 36px;
+ height: 36px;
+ border-radius: 6px;
+ display: block;
+ // border: 2px solid #fff;
+ background-size: cover;
+ background-position: center;
+ box-sizing: border-box;
+}
+
+.base-layer-trigger-label {
+ margin-top: 8px;
+ font-size: 12px;
+ line-height: 1;
+ color: #ffffff;
+ font-weight: 700;
+}
+
+.base-layer-panel {
+ position: absolute;
+ right: calc(100% + 10px);
+ bottom: 0;
+ margin-bottom: 0;
+ width: 160px;
+ background: #191932;
+ border-radius: 8px;
+ z-index: 99;
+
+ &::after {
+ content: '';
+ position: absolute;
+ right: -10px;
+ top: 0;
+ width: 10px;
+ height: 100%;
+ background: transparent;
+ }
+}
+
+.base-map-options {
+ padding: 8px;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px;
+}
+
+.base-map-card {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ border-radius: 6px;
+ color: #d8e6ff;
+ font-size: 12px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ .base-map-thumb {
+ width: 36px;
+ height: 36px;
border-radius: 6px;
- color: #d8e6ff;
- font-size: 12px;
- cursor: pointer;
- transition: all 0.2s ease;
-
- .base-map-thumb {
- width: 46px;
- height: 46px;
- border-radius: 4px;
- background-size: cover;
- background-position: center;
- box-sizing: border-box;
- }
-
- &.active {
- .base-map-thumb {
- border: 2px solid #2ea8ff;
- }
-
- .base-map-label {
- color: #2ea8ff;
- }
- }
+ // border: 2px solid #fff;
+ background-size: cover;
+ background-position: center;
+ box-sizing: border-box;
}
+
+ .base-map-label {
+ margin-top: 8px;
+ font-size: 12px;
+ line-height: 1;
+ color: #ffffff;
+ font-weight: 700;
+ }
+
+
+ // &.active {
+ // .base-map-thumb {
+ // border: 2px solid #2ea8ff;
+ // }
+
+ // .base-map-label {
+ // color: #2ea8ff;
+ // }
+ // }
}
.layer-panel-slide-enter-active,
--
Gitblit v1.9.3