From 540bb8627fabcb1dfdc514697dac2bf89f9fcbf5 Mon Sep 17 00:00:00 2001 From: lyf <2514544224@qq.com> Date: Tue, 28 Jul 2026 18:37:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E7=A7=BB=E5=8A=A8=E7=AB=AF?= =?UTF-8?q?=E6=BA=90=E7=A0=81=E5=B9=B6=E4=BF=AE=E5=A4=8D=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E5=B5=8C=E5=85=A5=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/generate-guide-floor-basemaps.mjs | 22 +- scripts/verify-arrival-navigation-build.cjs | 44 +- src/App.vue | 2 + .../explain/ExplainGuideStopCatalog.vue | 14 +- src/components/explain/ExplainHallSelect.vue | 79 +- src/components/map/TencentJsMap.vue | 608 ++++++++++++ src/components/map/ThreeMap.vue | 100 +- .../map/WeakNetworkGuideFallback.vue | 32 +- src/components/navigation/ArrivalPanel.vue | 904 ++++++++---------- src/components/navigation/GuideMapShell.vue | 47 +- .../navigation/OutdoorArrivalRoutePanel.vue | 716 ++++++++++++++ src/components/search/PoiSearchPanel.vue | 6 +- src/data/arrivalSearchTargets.ts | 11 +- src/domain/guideSemanticZoom.ts | 61 ++ src/domain/poiCategories.ts | 23 +- src/pages.json | 2 +- src/pages/exhibit/detail.vue | 73 +- src/pages/explain/guide-stop-list.vue | 36 +- src/pages/explain/list.vue | 88 +- src/pages/index/index.vue | 818 +++++++++++++--- .../WechatMiniProgramBridgeService.ts | 69 -- src/services/model/GuideFloorBasemap.ts | 15 +- .../outdoor/BrowserLocationService.ts | 81 ++ src/services/outdoor/OutdoorMapAppService.ts | 180 ++++ src/services/outdoor/TencentJsMapLoader.ts | 99 ++ src/services/tencent/TencentMapService.ts | 85 +- src/utils/explainNavigation.ts | 11 +- ...rtho-yaw54-v2.compact-floor-center-v1.webp | Bin 0 -> 186188 bytes ...rtho-yaw54-v2.compact-floor-center-v1.webp | Bin 0 -> 37380 bytes ...rtho-yaw54-v2.compact-floor-center-v1.webp | Bin 0 -> 114736 bytes ...rtho-yaw54-v2.compact-floor-center-v1.webp | Bin 0 -> 76696 bytes static/guide-floor-basemaps/manifest.json | 190 ++-- static/icons/halls/custom-cards/earth.png | Bin 38324 -> 48009 bytes static/icons/halls/custom-cards/universe.png | Bin 41100 -> 48005 bytes static/icons/halls/portal-icons/biology.png | Bin 0 -> 25228 bytes static/icons/halls/portal-icons/dinosaur.png | Bin 0 -> 43220 bytes static/icons/halls/portal-icons/earth.png | Bin 0 -> 51233 bytes static/icons/halls/portal-icons/ecology.png | Bin 0 -> 38108 bytes static/icons/halls/portal-icons/evolution.png | Bin 0 -> 26553 bytes static/icons/halls/portal-icons/homeland.png | Bin 0 -> 25774 bytes static/icons/halls/portal-icons/human.png | Bin 0 -> 23454 bytes static/icons/halls/portal-icons/universe.png | Bin 0 -> 37223 bytes static/icons/marker-bus.svg | 7 + static/icons/marker-location.svg | 11 +- static/icons/marker-metro.svg | 7 + static/icons/marker-parking.svg | 4 + static/icons/marker-selected.svg | 6 + static/icons/marker-user-location.svg | 11 +- tests/e2e/explain-hall-page.spec.ts | 29 +- tests/unit/ArrivalPanel.spec.ts | 128 +-- tests/unit/ExhibitDetailAudioFirst.spec.ts | 75 +- .../ExplainGuideStopListNavigation.spec.ts | 63 +- tests/unit/ExplainListNavigation.spec.ts | 79 +- tests/unit/GuideFloorBasemap.spec.ts | 31 + tests/unit/GuideMapShell.spec.ts | 62 +- tests/unit/GuideSemanticZoom.spec.ts | 52 + tests/unit/IndexPoiSearchFlow.spec.ts | 414 +++++++- tests/unit/OutdoorArrivalRoutePanel.spec.ts | 118 +++ tests/unit/PoiIconRegistry.spec.ts | 1 + tests/unit/WeakNetworkGuideFallback.spec.ts | 41 +- .../WechatMiniProgramBridgeService.spec.ts | 47 - tests/unit/hostEnvironment.spec.ts | 4 +- 62 files changed, 4196 insertions(+), 1410 deletions(-) create mode 100644 src/components/map/TencentJsMap.vue create mode 100644 src/components/navigation/OutdoorArrivalRoutePanel.vue create mode 100644 src/domain/guideSemanticZoom.ts create mode 100644 src/services/outdoor/BrowserLocationService.ts create mode 100644 src/services/outdoor/OutdoorMapAppService.ts create mode 100644 src/services/outdoor/TencentJsMapLoader.ts create mode 100644 static/guide-floor-basemaps/EXTERIOR.V20260727122824_bcbc9_LIGHTWEIGHT_MODEL.ortho-yaw54-v2.compact-floor-center-v1.webp create mode 100644 static/guide-floor-basemaps/EXTERIOR_L1.V20260727122824_bcbc9_SAME_GROUND_COMPOSITE.ortho-yaw54-v2.compact-floor-center-v1.webp create mode 100644 static/guide-floor-basemaps/L-2.V20260727122824_bcbc9_LIGHTWEIGHT_MODEL.ortho-yaw54-v2.compact-floor-center-v1.webp create mode 100644 static/guide-floor-basemaps/L1.V20260727122824_bcbc9_LIGHTWEIGHT_MODEL.ortho-yaw54-v2.compact-floor-center-v1.webp create mode 100644 static/icons/halls/portal-icons/biology.png create mode 100644 static/icons/halls/portal-icons/dinosaur.png create mode 100644 static/icons/halls/portal-icons/earth.png create mode 100644 static/icons/halls/portal-icons/ecology.png create mode 100644 static/icons/halls/portal-icons/evolution.png create mode 100644 static/icons/halls/portal-icons/homeland.png create mode 100644 static/icons/halls/portal-icons/human.png create mode 100644 static/icons/halls/portal-icons/universe.png create mode 100644 static/icons/marker-bus.svg create mode 100644 static/icons/marker-metro.svg create mode 100644 static/icons/marker-parking.svg create mode 100644 static/icons/marker-selected.svg create mode 100644 tests/unit/GuideSemanticZoom.spec.ts create mode 100644 tests/unit/OutdoorArrivalRoutePanel.spec.ts diff --git a/scripts/generate-guide-floor-basemaps.mjs b/scripts/generate-guide-floor-basemaps.mjs index 60b4a7f..8c8be71 100644 --- a/scripts/generate-guide-floor-basemaps.mjs +++ b/scripts/generate-guide-floor-basemaps.mjs @@ -411,10 +411,28 @@ const main = async () => { await mkdir(outputDir, { recursive: true }) const sdkManifest = await getJson(`${apiRoot}/gis/sdk/maps/${encodeURIComponent(mapId)}/manifest`) - const accessibleFloors = (sdkManifest.floors || []).filter((floor) => { + const selectedFloors = (sdkManifest.floors || []).filter((floor) => { const code = String(floor.floorCode || '').trim().toUpperCase() - return Boolean(code && floor.modelUrl && (!requestedFloors.size || requestedFloors.has(code))) + return Boolean(code && (!requestedFloors.size || requestedFloors.has(code))) }) + const accessibleFloors = (await Promise.all(selectedFloors.map(async (floor) => { + if (floor.modelUrl) return floor + + const bundle = await getJson( + `${apiRoot}/gis/sdk/floors/${encodeURIComponent(String(floor.floorId))}/bundle` + ) + const modelUrl = String(bundle?.model?.modelUrl || '').trim() + if (!modelUrl) { + throw new Error(`${floor.floorCode}: SDK manifest and floor bundle both lack a model URL`) + } + return { + ...floor, + modelUrl, + modelVersion: String( + bundle?.model?.modelVersion || bundle?.dataVersion || floor.modelVersion || sdkManifest.dataVersion || 'unversioned' + ) + } + }))).filter(Boolean) const sdkFloorsByCode = new Map((sdkManifest.floors || []).map((floor) => ( [String(floor.floorCode || '').trim().toUpperCase(), floor] ))) diff --git a/scripts/verify-arrival-navigation-build.cjs b/scripts/verify-arrival-navigation-build.cjs index 79fa90a..d0a9274 100644 --- a/scripts/verify-arrival-navigation-build.cjs +++ b/scripts/verify-arrival-navigation-build.cjs @@ -43,20 +43,28 @@ const h5JavaScriptCode = h5JavaScriptFiles .map((filePath) => readText(filePath)) .join('\n') +// H5 uses the embedded Tencent JS map and the backend route service. The +// historical external-map handoff must not be required by this bundle check. for (const required of [ - '第三方', - '打开地图', - 'jweixin', - 'miniProgram', - '/pages/open-location/index', - 'baidumap://', - 'iosamap://', - 'androidamap://' + '/gis/outdoor-map', + '/routes/plan', + '/places/suggestions', + '/geocoding/reverse', + '重新检测', + '手动选择起点', + '地图选点', + 'semanticEnterBuilding' ]) { assertContains(h5JavaScriptCode, required, 'H5 全量 JS') } -for (const forbidden of ['native-location']) { +for (const forbidden of [ + 'OutdoorNavigationPanel', + '打开地图导航', + 'baidumap://', + 'iosamap://', + 'androidamap://' +]) { assertNotContains(h5JavaScriptCode, forbidden, 'H5 全量 JS') } @@ -78,32 +86,22 @@ const mpArrivalPanelTemplatePath = path.join( 'ArrivalPanel.wxml' ) const mpArrivalPanelTemplate = readText(mpArrivalPanelTemplatePath) -assertContains(mpArrivalPanelCode, '打开地图导航', 'mp-weixin 来馆组件') -assertContains( - mpArrivalPanelCode, - '../../services/WechatOpenLocationService.js', - 'mp-weixin 来馆组件' -) +assertContains(mpArrivalPanelCode, 'typeChange', 'mp-weixin 来馆组件') +assertContains(mpArrivalPanelTemplate, '去这里', 'mp-weixin 来馆模板') assertNotContains(mpArrivalPanelCode, 'third-party-providers', 'mp-weixin 来馆组件') assertNotContains(mpArrivalPanelTemplate, 'provider-sheet', 'mp-weixin 来馆模板') assertNotContains(mpArrivalPanelTemplate, '第三方导航', 'mp-weixin 来馆模板') -const mpAppConfigPath = path.join(mpRoot, 'app.json') -const mpAppConfig = JSON.parse(readText(mpAppConfigPath)) -if (!mpAppConfig.pages?.includes('pages/open-location/index')) { - throw new Error('mp-weixin app.json 未注册 open-location 页面') -} - console.log(JSON.stringify({ h5: { html: path.relative(projectRoot, htmlPath), entry: path.relative(projectRoot, entryPath), pageChunk: path.relative(projectRoot, pageChunkPath), - navigationMode: 'third-party-providers' + navigationMode: 'embedded-tencent-map' }, mpWeixin: { component: path.relative(projectRoot, mpArrivalPanelPath), template: path.relative(projectRoot, mpArrivalPanelTemplatePath), - navigationMode: 'native-location' + navigationMode: 'arrival-target-selection' } }, null, 2)) diff --git a/src/App.vue b/src/App.vue index 3dbe05d..5249e09 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,9 @@ diff --git a/src/components/explain/ExplainGuideStopCatalog.vue b/src/components/explain/ExplainGuideStopCatalog.vue index fda056b..639259f 100644 --- a/src/components/explain/ExplainGuideStopCatalog.vue +++ b/src/components/explain/ExplainGuideStopCatalog.vue @@ -1,11 +1,11 @@