From d8420fc7c22299b56c6facb1f16af650ae666971 Mon Sep 17 00:00:00 2001 From: lyf <2514544224@qq.com> Date: Sun, 12 Jul 2026 03:07:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=90=9C=E7=B4=A2=E4=B8=8E?= =?UTF-8?q?=E7=82=B9=E4=BD=8D=E5=AE=9A=E4=BD=8D=E9=97=AD=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/map/ThreeMap.vue | 59 +- src/components/navigation/GuideMapShell.vue | 3 + src/components/search/PoiSearchPanel.vue | 1034 ++++++++++++------- src/data/adapters/sgsSdkGuideAdapter.ts | 102 +- src/domain/poiCategories.ts | 288 ++++++ src/domain/poiSearch.ts | 29 + src/pages/facility/detail.vue | 309 +++--- src/pages/index/index.vue | 154 ++- src/pages/search/index.vue | 22 +- src/repositories/GuideRepository.ts | 239 ++++- src/usecases/guideUseCase.ts | 2 +- src/view-models/guideViewModels.ts | 75 +- tests/unit/FacilityDetail.spec.ts | 319 ++++++ tests/unit/GuideMapShell.spec.ts | 74 ++ tests/unit/GuideRepository.spec.ts | 166 +++ tests/unit/IndexPoiSearchFlow.spec.ts | 283 +++++ tests/unit/PoiSearchPanel.spec.ts | 357 +++++++ tests/unit/SearchPage.spec.ts | 67 ++ 18 files changed, 2961 insertions(+), 621 deletions(-) create mode 100644 src/domain/poiCategories.ts create mode 100644 src/domain/poiSearch.ts create mode 100644 tests/unit/FacilityDetail.spec.ts create mode 100644 tests/unit/GuideMapShell.spec.ts create mode 100644 tests/unit/GuideRepository.spec.ts create mode 100644 tests/unit/IndexPoiSearchFlow.spec.ts create mode 100644 tests/unit/PoiSearchPanel.spec.ts create mode 100644 tests/unit/SearchPage.spec.ts diff --git a/src/components/map/ThreeMap.vue b/src/components/map/ThreeMap.vue index f2e287f..dd0b6f8 100644 --- a/src/components/map/ThreeMap.vue +++ b/src/components/map/ThreeMap.vue @@ -329,6 +329,7 @@ const props = withDefaults(defineProps<{ initialView?: ViewMode showControls?: boolean showPoi?: boolean + visiblePoiIds?: string[] | null targetFocus?: TargetPoiFocusRequest | null touchGestureMode?: TouchGestureMode targetFocusDistanceFactor?: number @@ -345,6 +346,7 @@ const props = withDefaults(defineProps<{ initialView: 'overview', showControls: true, showPoi: false, + visiblePoiIds: null, targetFocus: null, touchGestureMode: 'pan', targetFocusDistanceFactor: 0.36, @@ -395,7 +397,21 @@ const floors = computed(() => ( label: formatFloorLabel(floor.floorId) })) )) -const shouldRenderPoiMarkers = computed(() => props.showPoi || props.showControls || Boolean(props.targetFocus)) +const shouldRenderPoiMarkers = computed(() => ( + props.showPoi + || props.showControls + || props.visiblePoiIds !== null + || Boolean(props.targetFocus) +)) +const visiblePoiIdFilter = computed(() => ( + props.visiblePoiIds === null + ? null + : new Set(props.visiblePoiIds) +)) + +const isPoiIncludedByVisibleFilter = (poi: RenderPoi) => ( + visiblePoiIdFilter.value === null || visiblePoiIdFilter.value.has(poi.id) +) let scene: THREE.Scene | null = null let camera: THREE.PerspectiveCamera | null = null @@ -1480,8 +1496,28 @@ const updatePoiVisibilityByDistance = () => { .sort((a, b) => (b.poi ? getPoiPriority(b.poi) : 0) - (a.poi ? getPoiPriority(a.poi) : 0)) candidates.forEach(({ sprite, poi, screenPosition }) => { - if (!poi) { + if (!poi || !isPoiIncludedByVisibleFilter(poi)) { sprite.visible = false + const hitTarget = getPoiSpriteUserData(sprite).hitTarget + const labelSprite = getPoiSpriteUserData(sprite).labelSprite + if (hitTarget) { + hitTarget.visible = false + } + if (labelSprite) { + labelSprite.visible = false + } + return + } + + // 分类结果模式直接展示列表对应点位,避免密度策略再次裁剪结果。 + if (visiblePoiIdFilter.value !== null) { + sprite.visible = true + const hitTarget = getPoiSpriteUserData(sprite).hitTarget + if (hitTarget) { + hitTarget.visible = true + } + acceptedPositions.push(screenPosition) + visibleCount += 1 return } @@ -2182,7 +2218,12 @@ const getPoiHitTargets = () => { const sprites: THREE.Sprite[] = [] poiGroup?.traverse((child) => { - if (isPoiHitTargetSprite(child)) { + const poi = child.userData.poi as RenderPoi | undefined + if ( + isPoiHitTargetSprite(child) + && child.visible + && Boolean(poi && isPoiIncludedByVisibleFilter(poi)) + ) { sprites.push(child) } }) @@ -4513,7 +4554,11 @@ const createPoiMarkerGroup = ( labelSprite.position.copy(getPoiAmbientLabelPosition(displayPosition, markerSize)) labelSprite.visible = false } - sprite.visible = shouldShowPoiAtDistance(poi, getPoiVisibilityTier()) + sprite.visible = isPoiIncludedByVisibleFilter(poi) + && ( + visiblePoiIdFilter.value !== null + || shouldShowPoiAtDistance(poi, getPoiVisibilityTier()) + ) hitTarget.visible = sprite.visible group.add(sprite) group.add(hitTarget) @@ -5294,6 +5339,12 @@ watch(() => props.targetFocus, (request) => { immediate: true }) +watch(() => props.visiblePoiIds, () => { + refreshPoiVisibilityByDistance() +}, { + deep: true +}) + watch(() => [props.routePreview, props.showRoute], () => { renderRoutePreview() }, { diff --git a/src/components/navigation/GuideMapShell.vue b/src/components/navigation/GuideMapShell.vue index be1f818..0ac1a3d 100644 --- a/src/components/navigation/GuideMapShell.vue +++ b/src/components/navigation/GuideMapShell.vue @@ -13,6 +13,7 @@ :initial-view="indoorView" :show-controls="false" :show-poi="shouldShowIndoorPois" + :visible-poi-ids="visiblePoiIds" :target-focus="targetFocusRequest" :touch-gesture-mode="touchGestureMode" :target-focus-distance-factor="targetFocusDistanceFactor" @@ -351,6 +352,7 @@ const props = withDefaults(defineProps<{ normalizeFloorId?: (labelOrId: string) => string dimmed?: boolean targetFocusRequest?: TargetPoiFocusRequest | null + visiblePoiIds?: string[] | null touchGestureMode?: TouchGestureMode targetFocusDistanceFactor?: number routePreview?: GuideRouteResult | null @@ -403,6 +405,7 @@ const props = withDefaults(defineProps<{ normalizeFloorId: (labelOrId: string) => labelOrId, dimmed: false, targetFocusRequest: null, + visiblePoiIds: null, touchGestureMode: 'pan', targetFocusDistanceFactor: 0.36, routePreview: null, diff --git a/src/components/search/PoiSearchPanel.vue b/src/components/search/PoiSearchPanel.vue index 5db0b93..964d8d4 100644 --- a/src/components/search/PoiSearchPanel.vue +++ b/src/components/search/PoiSearchPanel.vue @@ -1,7 +1,11 @@