右侧菜单 电站倾斜摄像和漫游修改,打包配置修改

This commit is contained in:
扈兆增 2026-07-16 17:58:11 +08:00
parent 5b982cf9cd
commit 214a8139a0
17 changed files with 615 additions and 144 deletions

View File

@ -25,7 +25,6 @@ VITE_APP_TEST_ONLINE_URL = 'https://211.99.26.225:12122'
VITE_APP_BASE_API_URL = 'http://10.84.121.21:8093' VITE_APP_BASE_API_URL = 'http://10.84.121.21:8093'
## 开发环境 附件服务地址 ## 开发环境 附件服务地址
VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125' VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125'
attachment
# 地图服务地址 # 地图服务地址
VITE_APP_MAP_URL = 'https://211.99.26.225:18085' VITE_APP_MAP_URL = 'https://211.99.26.225:18085'

View File

@ -13,7 +13,6 @@ VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'
## 开发环境 附件服务地址 ## 开发环境 附件服务地址
VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125' VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125'
attachment
# 地图服务地址 # 地图服务地址
VITE_APP_MAP_URL = 'https://211.99.26.225:18085' VITE_APP_MAP_URL = 'https://211.99.26.225:18085'

View File

@ -10,23 +10,13 @@ VITE_APP_BASE_API = '/dev-api'
VITE_APP_BASE_URL = 'http://localhost:8093' VITE_APP_BASE_URL = 'http://localhost:8093'
# 测试环境 # 测试环境
# VITE_APP_BASE_URL = 'http://172.16.21.142:8093' # VITE_APP_BASE_URL = 'http://172.16.21.142:8093'
# VITE_APP_BASE_URL = 'http://172.16.21.142:8096'
# 汤伟 # 汤伟
VITE_APP_BASE_URL = 'http://10.84.111.235:8093' VITE_APP_BASE_URL = 'http://10.84.111.235:8093'
# 李林 # 李林
# VITE_APP_BASE_URL = 'http://10.84.111.25:8093' # VITE_APP_BASE_URL = 'http://10.84.111.25:8093'
# 测试环境线上10.84.121.122:
VITE_APP_TEST_ONLINE_URL = 'https://211.99.26.225:12122'
# 开发环境导入预览地址
VITE_APP_BASE_API_URL = 'http://10.84.121.21:8093'
## 开发环境 附件服务地址 ## 开发环境 附件服务地址
VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125' VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125'
# 地图服务地址 # 地图服务地址
VITE_APP_MAP_URL = 'https://211.99.26.225:18085' VITE_APP_MAP_URL = 'https://211.99.26.225:18085'
# ?menu=systemManageMenu&page=disposeManage # ?menu=systemManageMenu&page=disposeManage

View File

@ -8,12 +8,7 @@ VITE_APP_BASE_API = '/prod-api'
VITE_APP_BASE_URL = 'http://localhost:8093' VITE_APP_BASE_URL = 'http://localhost:8093'
## 生产环境导入预览地址 ## 生产环境导入预览地址
VITE_APP_BASE_API_URL = 'https://211.99.26.225:12130/prod-api' VITE_APP_BASE_API_URL = 'https://211.99.26.225:12130/prod-api'
## 生产环境预览 图片视频地址 ## 生产环境 附件服务地址
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'
## 开发环境 附件服务地址
VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125' VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125'
attachment
# 地图服务地址 # 地图服务地址
VITE_APP_MAP_URL = 'https://211.99.26.225:18085' VITE_APP_MAP_URL = 'https://211.99.26.225:18085'

View File

@ -1,3 +1,5 @@
registry=https://registry.npmmirror.com registry=https://registry.npmmirror.com
fetch-retries=5 fetch-retries=5
strict-peer-dependencies=false strict-peer-dependencies=false
# 添加 Node.js 内存配置
node-options=--max-old-space-size=4096

View File

@ -320,7 +320,6 @@ const loadRvcdOptions = async () => {
] ]
} }
}); });
const list = Array.isArray(res?.data?.data) const list = Array.isArray(res?.data?.data)
? res.data.data ? res.data.data
: Array.isArray(res?.data) : Array.isArray(res?.data)

View File

@ -1,55 +1,91 @@
<template> <template>
<a-tooltip placement="left" trigger="click" color="transparent"> <div class="calculate-wrapper" :ref="componentRef">
<template #title> <a-tooltip
<div class="calculate"> placement="left"
<a-tooltip color="transparent"
v-for="(item, index) in tools" :open="tooltipVisible"
:key="item.title" @openChange="handleTooltipVisibleChange"
:title="item.title" >
placement="top" <template #title>
> <div class="calculate" :ref="tipRef">
<div class="map-controller-item" :class="{'active': active === index}" @click="calculateClick(index)"> <a-tooltip
<i :class="`icon iconfont icon-${item.icon}`"></i> v-for="(item, index) in tools"
</div> :key="item.title"
</a-tooltip> :title="item.title"
placement="top"
>
<div
class="map-controller-item"
:class="{ active: active === index }"
@click="calculateClick(index)"
>
<i :class="`icon iconfont icon-${item.icon}`"></i>
</div>
</a-tooltip>
</div>
</template>
<div class="map-item" @click="handleClick">
<i class="icon iconfont icon-measuringTool"></i>
</div> </div>
</template> </a-tooltip>
<div class="map-item"> </div>
<i class="icon iconfont icon-measuringTool"></i>
</div>
</a-tooltip>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref, onMounted, onUnmounted, toRef } from 'vue';
const props = defineProps<{ const props = defineProps<{
map: any; map: any;
}>(); }>();
const map = props.map; const map = toRef(props, 'map');
const active = ref(-1); const active = ref(-1);
const tooltipVisible = ref(false);
const componentRef = ref<any | null>(null);
const tipRef = ref<any | null>(null);
const tools = ref([ const tools = ref([
{ title: "测距", icon: "ranging" }, { title: '测距', icon: 'ranging' },
{ title: "测面积", icon: "measure" }, { title: '测面积', icon: 'measure' },
{ title: "清除", icon: "clear" }, { title: '清除', icon: 'clear' }
]); ]);
const calculateClick = (index: number) => { const calculateClick = (index: number) => {
console.log("点击了测量工具", index); console.log('点击了测量工具', index);
active.value = index; active.value = index;
switch (index) { switch (index) {
case 0: case 0:
map.lengthCalculate(); map.value.lengthCalculate();
break; break;
case 1: case 1:
map.areCalculate(); map.value.areCalculate();
break; break;
case 2: case 2:
active.value = -1; active.value = -1;
map.removeQueryLayer(); map.value.removeQueryLayer();
break; break;
default: default:
break; break;
} }
}; };
const handleClick = () => {
tooltipVisible.value = !tooltipVisible.value;
};
const handleTooltipVisibleChange = (visible: boolean) => {
tooltipVisible.value = visible;
};
// tooltip
const handleClickOutside = (event: MouseEvent) => {
if (
componentRef.value &&
!componentRef.value.contains(event.target as Node)
) {
if (tipRef.value && !tipRef.value.contains(event.target as Node)) {
tooltipVisible.value = false;
}
}
};
onMounted(() => {
document.addEventListener('click', handleClickOutside);
});
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.map-item { .map-item {

View File

@ -22,7 +22,11 @@
</div> </div>
</template> </template>
<a-tooltip title="图层管理" placement="left"> <a-tooltip title="图层管理" placement="left">
<div class="map-item" @click="handleClick"> <div
class="map-item"
:class="{ 'is-active': active }"
@click="handleClick"
>
<i class="icon iconfont icon-layer"></i> <i class="icon iconfont icon-layer"></i>
</div> </div>
</a-tooltip> </a-tooltip>
@ -30,11 +34,21 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, computed, onUnmounted } from 'vue'; import { ref, onMounted, computed, onUnmounted, watch } from 'vue';
import { useMapOrchestrator } from '@/modules/map/application/map-orchestrator'; import { useMapOrchestrator } from '@/modules/map/application/map-orchestrator';
import { useMapConfigStore } from '@/modules/map/stores/map-config.store'; import { useMapConfigStore } from '@/modules/map/stores/map-config.store';
import { useMapViewStore } from '@/modules/map/stores/map-view.store'; import { useMapViewStore } from '@/modules/map/stores/map-view.store';
const props = defineProps<{
map?: any;
visible?: boolean;
active?: boolean;
}>();
const emit = defineEmits<{
(e: 'update:visible', v: boolean): void;
}>();
const mapOrchestrator = useMapOrchestrator(); const mapOrchestrator = useMapOrchestrator();
const mapConfigStore = useMapConfigStore(); const mapConfigStore = useMapConfigStore();
const mapViewStore = useMapViewStore(); const mapViewStore = useMapViewStore();
@ -62,6 +76,21 @@ const tooltipVisible = ref(false);
const componentRef = ref<any | null>(null); const componentRef = ref<any | null>(null);
const tipRef = ref<any | null>(null); const tipRef = ref<any | null>(null);
// visible prop tooltipVisible
watch(
() => props.visible,
newVal => {
if (newVal !== undefined && tooltipVisible.value !== newVal) {
tooltipVisible.value = newVal;
}
}
);
// tooltipVisible
watch(tooltipVisible, newVal => {
emit('update:visible', newVal);
});
const onCheck = async (v: any, e: any) => { const onCheck = async (v: any, e: any) => {
await mapOrchestrator.applyLayerSelection({ await mapOrchestrator.applyLayerSelection({
checkedKeys: v, checkedKeys: v,
@ -114,6 +143,10 @@ onUnmounted(() => {
background-color: #005292; background-color: #005292;
color: #ffffff; color: #ffffff;
} }
&.is-active {
background-color: #005292;
color: #ffffff;
}
} }
.ant-tooltip-inner { .ant-tooltip-inner {
height: auto !important; height: auto !important;

View File

@ -0,0 +1,249 @@
<template>
<div class="osbg-controller" :ref="componentRef">
<a-tooltip
:placement="inTransition ? 'left' : 'leftBottom'"
:trigger="inTransition ? 'hover' : 'click'"
:color="inTransition ? '#008BFF' : 'transparent'"
:open="inTransition ? true : tooltipVisible"
@openChange="onOpenChange"
>
<template #title>
<!-- 过渡中倒计时 -->
<div v-if="inTransition" class="countdown-tip">
电站倾斜摄影 {{ countdown }}s
</div>
<!-- 正常模式菜单面板 -->
<div v-else class="osbg-tree" :ref="tipRef">
<div class="osbg-tree-title">电站倾斜摄像列表</div>
<div class="osbg-tree-content">
<a-menu
v-if="treeData && treeData.length > 0"
mode="inline"
:selectable="false"
:defaultOpenKeys="treeData.map(g => g.baseId)"
>
<a-sub-menu v-for="group in treeData" :key="group.baseId">
<template #title>
<span class="group-title">{{ group.baseName }}</span>
</template>
<a-menu-item
v-for="item in group.children"
:key="item.stnm + '_' + group.baseId"
class="leaf-item"
>
<div class="leaf-content">
<span class="leaf-name">{{ item.stnm }}</span>
<a-switch
:checked="item.checked !== false"
size="small"
@click.stop
@change="(checked: boolean) => handleSwitchChange(item, checked)"
/>
</div>
</a-menu-item>
</a-sub-menu>
</a-menu>
<div v-else class="empty-tip">
<span class="leaf-name">暂无数据</span>
</div>
</div>
</div>
</template>
<a-tooltip title="电站倾斜摄影" placement="left">
<div
class="map-item"
:class="{
'is-active': active,
'is-disabled': disabled || inTransition
}"
@click="handleClick"
>
<i class="icon iconfont icon-obliquePhotography"></i>
</div>
</a-tooltip>
</a-tooltip>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue';
const props = defineProps<{
map?: any;
visible?: boolean;
active?: boolean;
treeData?: any[];
disabled?: boolean;
countdown?: number;
inTransition?: boolean;
}>();
const emit = defineEmits<{
(e: 'update:visible', v: boolean): void;
}>();
const tooltipVisible = ref(false);
const componentRef = ref<any | null>(null);
const tipRef = ref<any | null>(null);
// visible prop tooltipVisible
watch(
() => props.visible,
newVal => {
if (newVal !== undefined && tooltipVisible.value !== newVal) {
tooltipVisible.value = newVal;
}
}
);
// tooltipVisible
watch(tooltipVisible, newVal => {
emit('update:visible', newVal);
});
// visible true
watch(
() => props.inTransition,
(transitioning, wasTransitioning) => {
if (wasTransitioning && !transitioning) {
if (!props.visible) {
tooltipVisible.value = false;
}
}
}
);
const handleClick = () => {
if (props.inTransition || props.disabled) return;
tooltipVisible.value = !tooltipVisible.value;
};
const onOpenChange = (visible: boolean) => {
if (props.inTransition) return;
tooltipVisible.value = visible;
};
// a-switch
const handleSwitchChange = (item: any, checked: boolean) => {
item.checked = checked;
};
// tooltip
const handleClickOutside = (event: MouseEvent) => {
if (
componentRef.value &&
!componentRef.value.contains(event.target as Node)
) {
if (tipRef.value && !tipRef.value.contains(event.target as Node)) {
tooltipVisible.value = false;
}
}
};
onMounted(() => {
document.addEventListener('click', handleClickOutside);
});
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
});
</script>
<style lang="scss">
.map-item {
height: 40px;
width: 40px;
color: #000;
line-height: 40px;
text-align: center;
position: relative;
cursor: pointer;
.iconfont {
font-size: 20px;
}
&:hover {
background-color: #005292;
color: #ffffff;
}
&.is-active {
background-color: #005292;
color: #ffffff;
}
&.is-disabled {
pointer-events: none;
opacity: 0.5;
}
}
.ant-tooltip-inner {
height: auto !important;
max-height: 400px !important;
overflow: visible !important;
}
.osbg-tree {
width: 230px;
max-height: 300px;
box-sizing: border-box;
box-shadow: 0 1px 2px #00000026;
background-color: #fff;
cursor: initial;
border: 1px solid #ccdae7;
display: flex;
flex-direction: column;
.osbg-tree-title {
color: rgba(0, 0, 0, 0.85);
text-align: left;
padding-left: 10px;
height: 40px;
line-height: 40px;
font-size: 16px;
border-bottom: 1px dotted #ccc;
flex-shrink: 0;
}
.osbg-tree-content {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
}
}
.countdown-tip {
white-space: nowrap;
font-size: 14px;
}
//
.ant-menu-inline {
border-right: none !important;
}
.group-title {
font-weight: 500;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
}
.leaf-item {
height: 36px !important;
line-height: 36px !important;
padding-left: 32px !important;
margin: 0 !important;
&:hover {
background-color: #f5f5f5;
}
}
.leaf-content {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
.leaf-name {
font-size: 13px;
color: rgba(0, 0, 0, 0.65);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
margin-right: 8px;
}
}
.empty-tip {
padding: 16px;
text-align: center;
color: rgba(0, 0, 0, 0.45);
font-size: 13px;
}
</style>

View File

@ -1,36 +1,69 @@
<template> <template>
<div class="map-controller" :style="{ right: drawerOpen ? '480px' : '12px' }"> <div class="map-controller" :style="{ right: drawerOpen ? '480px' : '12px' }">
<div class="map-controller-group" v-for="item in controllers"> <div
<a-tooltip class="map-controller-group"
:title="child.name" v-for="(item, index) in controllers"
:placement="child.key === 'Calculate' ? 'right' : 'left'" :key="index"
v-for="child in item.children" >
:key="child.key" <template v-for="child in item.children" :key="child.key">
> <!-- 组件项直接渲染自身已有交互逻辑 -->
<component v-if="child.component" :is="child.component" :map="map" /> <component
<div v-if="child.component"
:is="child.component"
:map="map"
:visible="activeKey === child.key"
:active="activeKey === child.key"
:treeData="tiltPhotoTree"
:disabled="is3DTransition && child.key === 'OSBGController'"
:countdown="countdown"
:inTransition="is3DTransition && child.key === 'OSBGController'"
@update:visible="(v: boolean) => handleComponentVisibleToggle(child.key, v)"
/>
<!-- 非组件项包裹 tooltip 显示名称 -->
<a-tooltip
v-else v-else
class="map-controller-item" :title="getTooltipTitle(child)"
:class="{ 'is-active': child.key === 'TJ' && tjVisible }" placement="left"
@click="handleControllerClick(child)" :color="getTooltipColor(child)"
:open="getTooltipOpen(child)"
> >
<i class="icon iconfont" :class="'icon-' + child.icon"></i> <div
</div> class="map-controller-item"
</a-tooltip> :class="{
'is-active':
(child.key === 'TJ' && tjVisible) ||
(activeKey === child.key && child.key !== 'threedRoam'),
'is-disabled': isItemDisabled(child)
}"
@click="handleControllerClick(child)"
>
<i
class="icon iconfont"
:class="
child.key === 'threedRoam' && activeKey === 'threedRoam'
? 'icon-closeCircle'
: 'icon-' + child.icon
"
></i>
</div>
</a-tooltip>
</template>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, computed } from 'vue'; import { ref, watch, toRef, computed, onUnmounted } from 'vue';
import { useUiStore } from '@/store/modules/ui'; import { useUiStore } from '@/store/modules/ui';
import Calculate from './Calculate.vue'; import Calculate from './Calculate.vue';
import LayerController from './LayerController.vue'; import LayerController from './LayerController.vue';
import OSBGController from './OSBGController.vue';
import { getAllTiltPhotoTree } from '@/api/system/map/TiltPhotoManagement';
const props = defineProps<{ const props = defineProps<{
map: any; map: any;
onClick: (key: any, mapType: any) => void; onClick: (key: any, mapType: any) => void;
}>(); }>();
const map = props.map; const map = toRef(props, 'map');
// 使 Pinia store // 使 Pinia store
const uiStore = useUiStore(); const uiStore = useUiStore();
@ -56,6 +89,141 @@ watch(
const isFullScreen = ref(false); const isFullScreen = ref(false);
//
const tiltPhotoTree = ref<any[]>([]);
// API list
const buildTiltPhotoTree = (list: any[]) => {
if (!list || list.length === 0) return [];
const baseMap = new Map<string, { baseName: string; children: any[] }>();
for (const item of list) {
const id = String(item.baseId ?? '');
if (!baseMap.has(id)) {
baseMap.set(id, { baseName: item.baseName || '', children: [] });
}
}
for (const item of list) {
const id = String(item.baseId ?? '');
const group = baseMap.get(id);
if (group) {
group.children.push({ ...item, checked: true });
}
}
return Array.from(baseMap.entries())
.map(([baseId, group]) => ({
baseId,
baseName: group.baseName,
children: group.children
}))
.sort((a, b) => String(a.baseId).localeCompare(String(b.baseId)));
};
//
const fetchTiltPhotoTree = async () => {
try {
const res = await getAllTiltPhotoTree({
filter: {
logic: 'and',
filters: [
{
field: 'url',
operator: 'contains',
dataType: 'string',
value: 'http'
},
{
field: 'sttpCode',
operator: 'eq',
dataType: 'string',
value: 'OSGB'
}
]
},
sort: [
{ field: 'rstcdStepSort', dir: 'asc' },
{ field: 'ttpwr', dir: 'desc' }
]
});
const list = res.data.data;
tiltPhotoTree.value = buildTiltPhotoTree(list);
} catch (err) {
console.error('获取倾斜摄影数据失败:', err);
}
};
// 3D
// layerController / OSBGController / threedRoam
const activeKey = ref<string | null>(null);
const is3DTransition = ref(false);
const countdown = ref(0);
let transitionTimer: ReturnType<typeof setTimeout> | null = null;
const start3DTransition = () => {
cleanup3DTransition();
is3DTransition.value = true;
countdown.value = 5;
const tick = () => {
countdown.value--;
if (countdown.value <= 0) {
//
is3DTransition.value = false;
countdown.value = 0;
// OSBGController
activeKey.value = 'OSBGController';
transitionTimer = null;
} else {
transitionTimer = setTimeout(tick, 1000);
}
};
transitionTimer = setTimeout(tick, 1000);
};
const cleanup3DTransition = () => {
if (transitionTimer) {
clearTimeout(transitionTimer);
transitionTimer = null;
}
is3DTransition.value = false;
countdown.value = 0;
};
// Tooltip threedRoam
const getTooltipTitle = (child: any) => {
if (is3DTransition.value && child.key === 'threedRoam') {
return child.name + ' ' + countdown.value + 's';
}
return child.name;
};
const getTooltipColor = (child: any) => {
if (is3DTransition.value && child.key === 'threedRoam') {
return '#008BFF';
}
return undefined;
};
const getTooltipOpen = (child: any) => {
if (is3DTransition.value && child.key === 'threedRoam') {
return true;
}
return undefined;
};
const isItemDisabled = (child: any) => {
return is3DTransition.value && child.key === 'threedRoam';
};
// open/close
const handleComponentVisibleToggle = (key: string, visible: boolean) => {
activeKey.value = visible ? key : null;
};
onUnmounted(() => {
cleanup3DTransition();
});
// //
const controllers: any = computed(() => [ const controllers: any = computed(() => [
{ {
@ -68,25 +236,27 @@ const controllers: any = computed(() => [
] ]
}, },
{ !uiStore.isRoaming
children: [ ? {
// { children: [
// name: "", // {
// key: "positioning", // name: "",
// icon: "iconGlobal", // key: "positioning",
// }, // icon: "iconGlobal",
{ // },
name: '放大', {
key: 'zoomIn', name: '放大',
icon: 'zoomIn' key: 'zoomIn',
}, icon: 'zoomIn'
{ },
name: '缩小', {
key: 'zoomOut', name: '缩小',
icon: 'zoomOut' key: 'zoomOut',
icon: 'zoomOut'
}
]
} }
] : {},
},
{ {
children: [ children: [
{ {
@ -133,7 +303,7 @@ const controllers: any = computed(() => [
{ {
name: '电站倾斜摄影', name: '电站倾斜摄影',
key: 'OSBGController', key: 'OSBGController',
icon: 'obliquePhotography' component: OSBGController
} }
] ]
} }
@ -187,46 +357,46 @@ const handleControllerClick = (item: any) => {
switch (item.key) { switch (item.key) {
case 'fullScreen': case 'fullScreen':
isFullScreen.value = !isFullScreen.value; isFullScreen.value = !isFullScreen.value;
map.flyTopanto([92.39728, 29.24587], 14); toggleFullScreen();
// console.log(mapClass.hasLayer('eng_point'));
// map.jdPanelControlShowAndHidden("01", false);
// map.mdLayerTreeShowOrHidden('eng_point', false);
// map.mdLayerTreeShowOrHidden('wq_countryWq_point', true);
// map.controlBaseLayerTreeShowAndHidden(
// 'eng_point',
// 'eng_point',
// !isFullScreen.value
// );
// map.controlBaseLayerTreeShowAndHidden('lcj_bhq','lcj_bhq',!isFullScreen.value);
// toggleFullScreen();
break; break;
case 'zoomIn': case 'zoomIn':
map.zoomToggle('in'); map.value.zoomToggle('in');
break; break;
case 'zoomOut': case 'zoomOut':
map.zoomToggle('out'); map.value.zoomToggle('out');
break; break;
case 'dim': case 'dim': // 3D/2D
uiStore.mapType = uiStore.mapType === '2D' ? '3D' : '2D'; {
if (uiStore.mapType === '2D') { const switchingTo3D = uiStore.mapType === '2D';
uiStore.drawerOpen = true; uiStore.mapType = switchingTo3D ? '3D' : '2D';
} else { if (switchingTo3D) {
uiStore.drawerOpen = false; // 2D3D
uiStore.drawerOpen = false;
fetchTiltPhotoTree();
start3DTransition();
} else {
// 3D2D
uiStore.drawerOpen = true;
uiStore.isRoaming = false;
cleanup3DTransition();
activeKey.value = null;
}
props.onClick('dim', uiStore.mapType);
} }
props.onClick('dim', uiStore.mapType);
break; break;
case 'rightDrawer': case 'threedRoam': //
// 使 if (is3DTransition.value) break;
// GlobalEvents.get('rightDrawerState').set(!drawerOpen); // threedRoam
activeKey.value = activeKey.value === 'threedRoam' ? null : 'threedRoam';
uiStore.isRoaming = !uiStore.isRoaming;
break; break;
// //
case 'screenShot': case 'screenShot':
map.mapOutPut(); map.value.mapOutPut();
break; break;
case 'TJ': case 'TJ':
tjVisible.value = !tjVisible.value; tjVisible.value = !tjVisible.value;
props.onClick(4, null); props.onClick(4, null);
// map.addTertiarybasinLayer(servers.Tertiarybasin, '#4DFFDD', '#92A0A5')
break; break;
default: default:
console.log(`点击了控制器: ${item.name}`); console.log(`点击了控制器: ${item.name}`);
@ -264,6 +434,10 @@ const handleControllerClick = (item: any) => {
background-color: #005292; background-color: #005292;
color: #ffffff; color: #ffffff;
} }
&.is-disabled {
pointer-events: none;
opacity: 0.5;
}
} }
} }
.map-controller-group:not(:first-child) { .map-controller-group:not(:first-child) {

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="map-filter-container"> <div class="map-filter-container" v-show="!uiStore.isRoaming">
<div class="toolbar"> <div class="toolbar">
<a-form :model="formModel"> <a-form :model="formModel">
<a-row :gutter="10"> <a-row :gutter="10">

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="mapLegendView"> <div class="mapLegendView" v-show="!uiStore.isRoaming">
<div class="legendTitle"> <div class="legendTitle">
图例 图例
<span class="legendBtn" @click="isOpen = !isOpen"> <span class="legendBtn" @click="isOpen = !isOpen">
@ -70,9 +70,11 @@ import { ref, computed } from 'vue';
import { useMapOrchestrator } from '@/modules/map/application/map-orchestrator'; import { useMapOrchestrator } from '@/modules/map/application/map-orchestrator';
import { useMapConfigStore } from '@/modules/map/stores/map-config.store'; import { useMapConfigStore } from '@/modules/map/stores/map-config.store';
import { useMapStore } from '@/store/modules/map'; import { useMapStore } from '@/store/modules/map';
import { useUiStore } from '@/store/modules/ui';
import LegendItem from '@/components/mapLegend/LegendItem.vue'; import LegendItem from '@/components/mapLegend/LegendItem.vue';
const mapStore = useMapStore(); const mapStore = useMapStore();
const uiStore = useUiStore();
const mapConfigStore = useMapConfigStore(); const mapConfigStore = useMapConfigStore();
const mapOrchestrator = useMapOrchestrator(); const mapOrchestrator = useMapOrchestrator();
const isOpen = ref(true); const isOpen = ref(true);

View File

@ -1,7 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent'; import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
import { useUiStore } from '@/store/modules/ui';
const isOpen = ref(true); const isOpen = ref(true);
const uiStore = useUiStore();
const JidiSelectEventStore = useJidiSelectEventStore(); const JidiSelectEventStore = useJidiSelectEventStore();
const jidiDataNum = ref(9); const jidiDataNum = ref(9);
@ -12,7 +14,7 @@ onMounted(() => {});
</script> </script>
<template> <template>
<div class="jidiSelectorMod"> <div class="jidiSelectorMod" v-show="!uiStore.isRoaming">
<a-spin :spinning="JidiSelectEventStore.loading"> <a-spin :spinning="JidiSelectEventStore.loading">
<div <div
class="qgc-dropdown-select" class="qgc-dropdown-select"
@ -35,6 +37,7 @@ onMounted(() => {});
0, 0,
jidiDataNum jidiDataNum
)" )"
:key="index"
:class="{ selected: i.selected }" :class="{ selected: i.selected }"
@click="itemClick(index)" @click="itemClick(index)"
> >

View File

@ -6,6 +6,8 @@ export const useUiStore = defineStore('ui', () => {
const drawerOpen = ref(true); const drawerOpen = ref(true);
const mapType = ref('2D'); const mapType = ref('2D');
const mapSwitchCompletedTick = ref(0); const mapSwitchCompletedTick = ref(0);
// 3d 流域三维漫游
const isRoaming = ref(false);
// 切换抽屉状态 // 切换抽屉状态
const toggleDrawer = () => { const toggleDrawer = () => {
@ -23,6 +25,7 @@ export const useUiStore = defineStore('ui', () => {
return { return {
drawerOpen, drawerOpen,
isRoaming,
toggleDrawer, toggleDrawer,
setDrawerOpen, setDrawerOpen,
mapType, mapType,

View File

@ -253,7 +253,6 @@ const ruleColumnsMap: any = {
}, },
{ {
key: 'avqSfdb', key: 'avqSfdb',
title: '多年平均流量*10%是否达标',
dataIndex: 'avqSfdbName', dataIndex: 'avqSfdbName',
visible: true, visible: true,
sort: true, sort: true,

View File

@ -11,52 +11,39 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, defineAsyncComponent } from "vue"; import { ref, defineAsyncComponent } from 'vue';
// Tab // Tab
const tabs = [ const tabs = [
{ {
name: "图层管理", name: '图层管理',
value: "layer", value: 'layer'
}, },
{ {
name: "图例结构管理", name: '图例结构管理',
value: "legend", value: 'legend'
}, },
{ {
name: "图例数据管理", name: '图例数据管理',
value: "legendData", value: 'legendData'
}, }
// {
// name: "",
// value: "station",
// },
// {
// name: "沿",
// value: "config",
// },
// {
// name: "",
// value: "tilt",
// },
]; ];
// tab // tab
const activeTab = ref("layer"); const activeTab = ref('layer');
// //
const getComponent = (value: string) => { const getComponent = (value: string) => {
const componentMap: Record<string, any> = { const componentMap: Record<string, any> = {
layer: defineAsyncComponent(() => import("./components/LayerManagement/index.vue")), layer: defineAsyncComponent(
legend: defineAsyncComponent(() => import("./components/LegendStructure/index.vue")), () => import('./components/LayerManagement/index.vue')
legendData: defineAsyncComponent(() => import("./components/LegendData/index.vue")),
station: defineAsyncComponent(
() => import("./components/StationManagement/index.vue")
), ),
config: defineAsyncComponent(() => import("./components/ConfigManagement/index.vue")), legend: defineAsyncComponent(
tilt: defineAsyncComponent( () => import('./components/LegendStructure/index.vue')
() => import("./components/TiltPhotoManagement/index.vue")
), ),
legendData: defineAsyncComponent(
() => import('./components/LegendData/index.vue')
)
}; };
return componentMap[value] || null; return componentMap[value] || null;

View File

@ -120,6 +120,7 @@ export default ({ mode }: ConfigEnv): UserConfig => {
if (id.includes('node_modules')) { if (id.includes('node_modules')) {
// 将 element-plus, lodash 等大型库单独拆分 // 将 element-plus, lodash 等大型库单独拆分
if (id.includes('element-plus')) return 'element-plus'; if (id.includes('element-plus')) return 'element-plus';
if (id.includes('ant-design-vue')) return 'ant-design-vue';
if (id.includes('lodash')) return 'lodash'; if (id.includes('lodash')) return 'lodash';
if (id.includes('cesium')) return 'cesium'; if (id.includes('cesium')) return 'cesium';
// 其他 node_modules 归为 vendor // 其他 node_modules 归为 vendor