From 2ed06cc2d5f47ad60860967ca220aca7dc7e6a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=87=AF?= <2448379534@qq.com> Date: Thu, 27 Aug 2026 13:44:10 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=B5=E7=AB=99=E4=B8=93=E9=A2=98=E5=BC=95?= =?UTF-8?q?=E5=85=A5=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/dianZhanZhuanTi/dianZhanZhuanTi.vue | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/dianZhanZhuanTi/dianZhanZhuanTi.vue b/frontend/src/views/dianZhanZhuanTi/dianZhanZhuanTi.vue index ef954280..ebe3eebd 100644 --- a/frontend/src/views/dianZhanZhuanTi/dianZhanZhuanTi.vue +++ b/frontend/src/views/dianZhanZhuanTi/dianZhanZhuanTi.vue @@ -44,6 +44,7 @@ import { useMapViewStore } from '@/modules/map/stores/map-view.store'; import { getModuleComponent } from './moduleMap'; import { LAYOUT_GRID_SKELETONS } from './layoutGridSkeletons'; import { setMapLegendPos } from '@/components/gis/gisUtils'; +// import add from '@/modules' defineOptions({ name: 'DianZhanZhuanTi' }); @@ -243,11 +244,50 @@ function switchToVector() { mapViewStore.setActiveBaseLayerKey('s_province_boundaries'); } catch {} } +// ==================== 模块组件解析 ==================== +// 后端返回的 code 格式不固定(如 dianzhanzhuantiMod/ShuiDianZhanJieShao/、 +// ../../modules/xxx/index.vue、@/modules/xxx/index.vue 等),统一归一化后再匹配。 +// 构建时用 import.meta.glob 静态收集 @/modules 下所有 index.vue,线上打包后仍可正常按需加载 +// (不能用运行时字符串 import(url),Vite 无法静态分析,打包后浏览器会直接请求 .vue 源文件导致失败) +const moduleLoaders = import.meta.glob('@/modules/**/index.vue'); + +/** 将各种来源的模块路径归一化为统一格式:modules/xxx/index.vue */ +function canonicalModulePath(p: string): string { + let s = p + .replace(/^@\//, '') + .replace(/^\.\.\/\.\.\//, '') + .replace(/^\.\//, '') + .replace(/^\//, '') + .replace(/^src\//, '') + .replace(/\/+$/, ''); + if (!s.startsWith('modules/')) s = `modules/${s}`; + if (!s.endsWith('.vue')) s = `${s}/index.vue`; + return s; +} + +/** 归一化路径 → 加载器索引(只构建一次) */ +const moduleLoaderIndex = new Map Promise>(); +Object.entries(moduleLoaders).forEach(([key, loader]) => { + moduleLoaderIndex.set(canonicalModulePath(key), loader); +}); + //处理返回来的路径(按 code 缓存组件,避免每次渲染都新建导致面板反复卸载重挂载) const moduleComponentCache = new Map(); const getModuleComponenturl = (url: string) => { if (!moduleComponentCache.has(url)) { - moduleComponentCache.set(url, defineAsyncComponent(() => import(url))); + // 优先取构建期静态收集的模块组件;未命中再回退 moduleMap 的手工映射 + const loader = moduleLoaderIndex.get(canonicalModulePath(url)); + const mapped = getModuleComponent(url); + moduleComponentCache.set( + url, + loader + ? defineAsyncComponent(loader) + : mapped + ? mapped + : defineAsyncComponent(() => + Promise.reject(new Error(`未找到模块组件: ${url}`)) + ) + ); } return moduleComponentCache.get(url); }; @@ -300,6 +340,7 @@ watch( (items || []).forEach((item: any) => { if (item.code) map[item.code] = getModuleComponenturl(item.code); }); + console.log('panelComponents', map) panelComponents.value = map; }, { deep: true }