@@ -296,7 +296,7 @@ const floorLoadError = ref('')
|
|||||||
const excludedPoiCount = ref(0)
|
const excludedPoiCount = ref(0)
|
||||||
const duplicatePoiCount = ref(0)
|
const duplicatePoiCount = ref(0)
|
||||||
const resultListScrollTop = ref(0)
|
const resultListScrollTop = ref(0)
|
||||||
const resultListRef = ref<HTMLElement | null>(null)
|
const resultListRef = ref<HTMLElement | { $el?: HTMLElement } | null>(null)
|
||||||
let cachedPoiPool: PreparedPoiResults | null = null
|
let cachedPoiPool: PreparedPoiResults | null = null
|
||||||
let searchRequestSeq = 0
|
let searchRequestSeq = 0
|
||||||
|
|
||||||
@@ -807,8 +807,15 @@ const handleResultListScroll = (event: any) => {
|
|||||||
resultListScrollTop.value = Number.isFinite(scrollTop) ? Math.max(0, scrollTop) : 0
|
resultListScrollTop.value = Number.isFinite(scrollTop) ? Math.max(0, scrollTop) : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getResultListElement = (): HTMLElement | null => {
|
||||||
|
const target = resultListRef.value
|
||||||
|
if (!target) return null
|
||||||
|
if ('$el' in target) return target.$el || null
|
||||||
|
return target as HTMLElement
|
||||||
|
}
|
||||||
|
|
||||||
const captureResultListScroll = () => {
|
const captureResultListScroll = () => {
|
||||||
const scrollTop = Number(resultListRef.value?.scrollTop)
|
const scrollTop = Number(getResultListElement()?.scrollTop)
|
||||||
if (Number.isFinite(scrollTop)) resultListScrollTop.value = Math.max(0, scrollTop)
|
if (Number.isFinite(scrollTop)) resultListScrollTop.value = Math.max(0, scrollTop)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +824,8 @@ const restoreResultListScroll = async () => {
|
|||||||
if (scrollTop <= 0) return
|
if (scrollTop <= 0) return
|
||||||
|
|
||||||
await nextTick()
|
await nextTick()
|
||||||
if (resultListRef.value) resultListRef.value.scrollTop = scrollTop
|
const resultListElement = getResultListElement()
|
||||||
|
if (resultListElement) resultListElement.scrollTop = scrollTop
|
||||||
}
|
}
|
||||||
|
|
||||||
const poiDisplayName = (poi: MuseumPoi) => poi.name?.trim() || '未命名点位'
|
const poiDisplayName = (poi: MuseumPoi) => poi.name?.trim() || '未命名点位'
|
||||||
|
|||||||
@@ -672,6 +672,13 @@ const categoryForSgsSpace = (space: SgsSpacePayload): MuseumCategory => {
|
|||||||
return spaceCategory
|
return spaceCategory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createCanonicalSpacePoiId = (space: SgsSpacePayload) => {
|
||||||
|
const spaceId = stringifyId(space.id)
|
||||||
|
if (!spaceId) return ''
|
||||||
|
|
||||||
|
return `${isExhibitionHallSpace(space) ? 'hall' : 'space'}-${spaceId}`
|
||||||
|
}
|
||||||
|
|
||||||
export const toMuseumSpacePointFromSgs = (
|
export const toMuseumSpacePointFromSgs = (
|
||||||
space: SgsSpacePayload,
|
space: SgsSpacePayload,
|
||||||
floors: SgsSdkFloorSummaryPayload[],
|
floors: SgsSdkFloorSummaryPayload[],
|
||||||
@@ -686,9 +693,11 @@ export const toMuseumSpacePointFromSgs = (
|
|||||||
if (!spaceId || !name || !spacePosition) return null
|
if (!spaceId || !name || !spacePosition) return null
|
||||||
|
|
||||||
const category = categoryForSgsSpace(space)
|
const category = categoryForSgsSpace(space)
|
||||||
|
const poiId = createCanonicalSpacePoiId(space)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: `space-${spaceId}`,
|
// 可生成展厅类 marker 的空间统一使用 hall ID,确保弱网回退结果仍可直接定位。
|
||||||
|
id: poiId,
|
||||||
name,
|
name,
|
||||||
floorId,
|
floorId,
|
||||||
floorLabel: floorLabelForSgs(floorId, floors),
|
floorLabel: floorLabelForSgs(floorId, floors),
|
||||||
@@ -734,8 +743,8 @@ const createHallEntrance = (
|
|||||||
const createHallPoiId = (
|
const createHallPoiId = (
|
||||||
space: SgsSpacePayload
|
space: SgsSpacePayload
|
||||||
) => {
|
) => {
|
||||||
const spaceId = stringifyId(space.id)
|
const canonicalId = createCanonicalSpacePoiId(space)
|
||||||
if (spaceId) return `hall-${spaceId}`
|
if (canonicalId) return canonicalId
|
||||||
|
|
||||||
const ownerName = normalizedHallName(space.name)
|
const ownerName = normalizedHallName(space.name)
|
||||||
const floorIdentity = normalizedHallName(stringifyId(space.floorId) || 'unknown-floor')
|
const floorIdentity = normalizedHallName(stringifyId(space.floorId) || 'unknown-floor')
|
||||||
@@ -756,15 +765,16 @@ const createSpaceFallbackHallPoi = (
|
|||||||
const hallId = stringifyId(space.id)
|
const hallId = stringifyId(space.id)
|
||||||
|
|
||||||
if (!hallId || !normalizedText(space.name) || !position) return null
|
if (!hallId || !normalizedText(space.name) || !position) return null
|
||||||
|
const category = categoryForSgsSpace(space)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: `hall-${hallId}`,
|
id: `hall-${hallId}`,
|
||||||
name: normalizedText(space.name),
|
name: normalizedText(space.name),
|
||||||
floorId,
|
floorId,
|
||||||
floorLabel: floorLabelForSgs(floorId, floors),
|
floorLabel: floorLabelForSgs(floorId, floors),
|
||||||
primaryCategory: hallCategory,
|
primaryCategory: category,
|
||||||
categories: [
|
categories: [
|
||||||
hallCategory
|
category
|
||||||
],
|
],
|
||||||
positionGltf: position,
|
positionGltf: position,
|
||||||
sourceObjectName: space.sourceNodeName || undefined,
|
sourceObjectName: space.sourceNodeName || undefined,
|
||||||
@@ -807,6 +817,7 @@ export const toMuseumHallPoisFromSgs = (
|
|||||||
const hallId = stringifyId(matchedSpace?.id) || undefined
|
const hallId = stringifyId(matchedSpace?.id) || undefined
|
||||||
const poiId = createHallPoiId(matchedSpace)
|
const poiId = createHallPoiId(matchedSpace)
|
||||||
const hallName = normalizedText(matchedSpace?.name) || placeHallName(place) || entrance.name
|
const hallName = normalizedText(matchedSpace?.name) || placeHallName(place) || entrance.name
|
||||||
|
const category = categoryForSgsSpace(matchedSpace)
|
||||||
const existing = halls.get(poiId)
|
const existing = halls.get(poiId)
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
@@ -843,10 +854,10 @@ export const toMuseumHallPoisFromSgs = (
|
|||||||
name: hallName,
|
name: hallName,
|
||||||
floorId: usesSpaceCenter ? fallbackFloorIdForPoi : entrance.floorId,
|
floorId: usesSpaceCenter ? fallbackFloorIdForPoi : entrance.floorId,
|
||||||
floorLabel: usesSpaceCenter ? fallbackFloorLabel : entrance.floorLabel,
|
floorLabel: usesSpaceCenter ? fallbackFloorLabel : entrance.floorLabel,
|
||||||
primaryCategory: hallCategory,
|
primaryCategory: category,
|
||||||
categories: [
|
categories: [
|
||||||
hallCategory,
|
category,
|
||||||
hallEntranceCategory
|
...(category.id === hallCategory.id ? [hallEntranceCategory] : [])
|
||||||
],
|
],
|
||||||
positionGltf,
|
positionGltf,
|
||||||
sourceObjectName: usesSpaceCenter
|
sourceObjectName: usesSpaceCenter
|
||||||
|
|||||||
@@ -86,14 +86,18 @@ const toGuideRenderPoi = (poi: MuseumPoi): GuideRenderPoi => ({
|
|||||||
|
|
||||||
const toSgsRenderPoi = (poi: ReturnType<typeof toMuseumPoiFromSgs>) => toGuideRenderPoi(poi)
|
const toSgsRenderPoi = (poi: ReturnType<typeof toMuseumPoiFromSgs>) => toGuideRenderPoi(poi)
|
||||||
|
|
||||||
const getRenderPoiDedupeKeys = (poi: GuideRenderPoi) => [
|
const getRenderPoiDedupeKeys = (poi: GuideRenderPoi) => {
|
||||||
|
const stableKeys = [
|
||||||
poi.id ? `id:${poi.id}` : '',
|
poi.id ? `id:${poi.id}` : '',
|
||||||
poi.sourceSpaceId ? `space:${poi.floorId}:${poi.sourceSpaceId}` : '',
|
poi.sourceSpaceId ? `space:${poi.floorId}:${poi.sourceSpaceId}` : '',
|
||||||
poi.spaceId ? `space:${poi.floorId}:${poi.spaceId}` : '',
|
poi.spaceId ? `space:${poi.floorId}:${poi.spaceId}` : '',
|
||||||
poi.sourcePlaceId ? `place:${poi.floorId}:${poi.sourcePlaceId}` : '',
|
poi.sourcePlaceId ? `place:${poi.floorId}:${poi.sourcePlaceId}` : ''
|
||||||
poi.sourceObjectName ? `object:${poi.floorId}:${poi.sourceObjectName}` : ''
|
|
||||||
].filter(Boolean)
|
].filter(Boolean)
|
||||||
|
|
||||||
|
if (stableKeys.length) return stableKeys
|
||||||
|
return poi.sourceObjectName ? [`object:${poi.floorId}:${poi.sourceObjectName}`] : []
|
||||||
|
}
|
||||||
|
|
||||||
const dedupeRenderPoisById = (pois: GuideRenderPoi[]) => {
|
const dedupeRenderPoisById = (pois: GuideRenderPoi[]) => {
|
||||||
const seen = new Set<string>()
|
const seen = new Set<string>()
|
||||||
return pois.filter((poi) => {
|
return pois.filter((poi) => {
|
||||||
@@ -523,7 +527,7 @@ export class SgsSdkGuideModelRepository implements GuideModelRepository {
|
|||||||
fallbackHallY: floorPoiMedianY ?? null
|
fallbackHallY: floorPoiMedianY ?? null
|
||||||
})
|
})
|
||||||
|
|
||||||
if (hallDiagnostics.hallPoiWithPositionCount > 0 && !renderPois.some((poi) => poi.primaryCategory === 'exhibition_hall')) {
|
if (hallDiagnostics.hallPoiWithPositionCount > 0 && !renderHallPois.length) {
|
||||||
warnSgsGuideModelDiagnostics('render POI filter removed all hall POIs', {
|
warnSgsGuideModelDiagnostics('render POI filter removed all hall POIs', {
|
||||||
floorId: resolvedFloorId,
|
floorId: resolvedFloorId,
|
||||||
...hallDiagnostics,
|
...hallDiagnostics,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type {
|
|||||||
GuideLocationPreview,
|
GuideLocationPreview,
|
||||||
GuideMapDiagnostics,
|
GuideMapDiagnostics,
|
||||||
GuideRouteReadiness,
|
GuideRouteReadiness,
|
||||||
|
MuseumCategory,
|
||||||
MuseumFloor,
|
MuseumFloor,
|
||||||
MuseumPoi
|
MuseumPoi
|
||||||
} from '@/domain/museum'
|
} from '@/domain/museum'
|
||||||
@@ -132,9 +133,28 @@ const dedupePoisById = (pois: MuseumPoi[]) => {
|
|||||||
|
|
||||||
const getPoiSpaceIdentity = (poi: MuseumPoi) => poi.sourceSpaceId || poi.spaceId || ''
|
const getPoiSpaceIdentity = (poi: MuseumPoi) => poi.sourceSpaceId || poi.spaceId || ''
|
||||||
|
|
||||||
|
const getPoiLookupIdentities = (id: string) => {
|
||||||
|
const normalizedId = id.trim()
|
||||||
|
return new Set([
|
||||||
|
normalizedId,
|
||||||
|
normalizedId.replace(/^(?:hall|space)-/, '')
|
||||||
|
].filter(Boolean))
|
||||||
|
}
|
||||||
|
|
||||||
|
const mergePoiCategories = (...categoryGroups: MuseumCategory[][]) => {
|
||||||
|
const seenIds = new Set<string>()
|
||||||
|
return categoryGroups.flat().filter((category) => {
|
||||||
|
const categoryId = category.id.trim()
|
||||||
|
if (!categoryId || seenIds.has(categoryId)) return false
|
||||||
|
seenIds.add(categoryId)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const mergeSearchablePois = (pois: MuseumPoi[], spacePoints: MuseumPoi[]) => {
|
const mergeSearchablePois = (pois: MuseumPoi[], spacePoints: MuseumPoi[]) => {
|
||||||
const hallPoisBySpaceId = new Map(
|
const hallPoisBySpaceId = new Map(
|
||||||
pois
|
pois
|
||||||
|
.filter((poi) => poi.kind === 'hall' || Boolean(poi.hallId))
|
||||||
.map((poi) => [getPoiSpaceIdentity(poi), poi] as const)
|
.map((poi) => [getPoiSpaceIdentity(poi), poi] as const)
|
||||||
.filter(([spaceId]) => Boolean(spaceId))
|
.filter(([spaceId]) => Boolean(spaceId))
|
||||||
)
|
)
|
||||||
@@ -144,24 +164,30 @@ const mergeSearchablePois = (pois: MuseumPoi[], spacePoints: MuseumPoi[]) => {
|
|||||||
.filter(([spaceId]) => Boolean(spaceId))
|
.filter(([spaceId]) => Boolean(spaceId))
|
||||||
)
|
)
|
||||||
|
|
||||||
const filteredPois = pois.filter((poi) => {
|
const mergedPois = pois.map((poi) => {
|
||||||
const spaceId = getPoiSpaceIdentity(poi)
|
const spaceId = getPoiSpaceIdentity(poi)
|
||||||
const matchingSpacePoint = spaceId ? spacePointsBySpaceId.get(spaceId) : null
|
const matchingSpacePoint = spaceId ? spacePointsBySpaceId.get(spaceId) : null
|
||||||
if (!matchingSpacePoint) return true
|
const matchingHallPoi = spaceId ? hallPoisBySpaceId.get(spaceId) : null
|
||||||
|
if (!matchingSpacePoint || matchingHallPoi?.id !== poi.id) return poi
|
||||||
|
|
||||||
return matchingSpacePoint.primaryCategory.id === 'exhibition_hall'
|
return {
|
||||||
|
...poi,
|
||||||
|
primaryCategory: matchingSpacePoint.primaryCategory,
|
||||||
|
categories: mergePoiCategories(
|
||||||
|
[matchingSpacePoint.primaryCategory],
|
||||||
|
matchingSpacePoint.categories
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
const filteredSpacePoints = spacePoints.filter((poi) => {
|
const unmatchedSpacePoints = spacePoints.filter((poi) => {
|
||||||
const spaceId = getPoiSpaceIdentity(poi)
|
const spaceId = getPoiSpaceIdentity(poi)
|
||||||
const matchingHallPoi = spaceId ? hallPoisBySpaceId.get(spaceId) : null
|
const matchingHallPoi = spaceId ? hallPoisBySpaceId.get(spaceId) : null
|
||||||
if (!matchingHallPoi) return true
|
return !matchingHallPoi
|
||||||
|
|
||||||
return poi.primaryCategory.id !== 'exhibition_hall'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return dedupePoisById([
|
return dedupePoisById([
|
||||||
...filteredPois,
|
...mergedPois,
|
||||||
...filteredSpacePoints
|
...unmatchedSpacePoints
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,7 +553,12 @@ export class SgsSdkGuideRepository implements GuideRepository {
|
|||||||
|
|
||||||
async getPoiById(id: string) {
|
async getPoiById(id: string) {
|
||||||
const pois = await this.searchPois()
|
const pois = await this.searchPois()
|
||||||
return pois.find((poi) => poi.id === id || poi.spaceId === id || poi.sourceSpaceId === id)
|
const lookupIdentities = getPoiLookupIdentities(id)
|
||||||
|
return pois.find((poi) => (
|
||||||
|
lookupIdentities.has(poi.id)
|
||||||
|
|| lookupIdentities.has(poi.spaceId || '')
|
||||||
|
|| lookupIdentities.has(poi.sourceSpaceId || '')
|
||||||
|
))
|
||||||
|| findPoiByNavIdNameFallback(pois, id)
|
|| findPoiByNavIdNameFallback(pois, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ import type {
|
|||||||
SgsSdkManifestPayload
|
SgsSdkManifestPayload
|
||||||
} from '@/data/providers/sgsSdkApiProvider'
|
} from '@/data/providers/sgsSdkApiProvider'
|
||||||
import { SgsSdkGuideRepository } from '@/repositories/GuideRepository'
|
import { SgsSdkGuideRepository } from '@/repositories/GuideRepository'
|
||||||
|
import { SgsSdkGuideModelRepository } from '@/repositories/GuideModelRepository'
|
||||||
import { toMuseumPoiFromSgs } from '@/data/adapters/sgsSdkGuideAdapter'
|
import { toMuseumPoiFromSgs } from '@/data/adapters/sgsSdkGuideAdapter'
|
||||||
|
import {
|
||||||
|
getPoiCategoryById,
|
||||||
|
matchesPoiCategory,
|
||||||
|
resolvePoiCategory
|
||||||
|
} from '@/domain/poiCategories'
|
||||||
|
import { toFacilityDetailViewModel } from '@/view-models/guideViewModels'
|
||||||
|
|
||||||
const manifest: SgsSdkManifestPayload = {
|
const manifest: SgsSdkManifestPayload = {
|
||||||
mapId: 'museum',
|
mapId: 'museum',
|
||||||
@@ -88,7 +95,7 @@ describe('SgsSdkGuideRepository 点位搜索', () => {
|
|||||||
|
|
||||||
expect(theaterResults).toHaveLength(1)
|
expect(theaterResults).toHaveLength(1)
|
||||||
expect(theaterResults[0]).toMatchObject({
|
expect(theaterResults[0]).toMatchObject({
|
||||||
id: 'space-space-theater',
|
id: 'hall-space-theater',
|
||||||
floorId: '101',
|
floorId: '101',
|
||||||
floorLabel: '1F',
|
floorLabel: '1F',
|
||||||
primaryCategory: {
|
primaryCategory: {
|
||||||
@@ -96,9 +103,99 @@ describe('SgsSdkGuideRepository 点位搜索', () => {
|
|||||||
},
|
},
|
||||||
positionGltf: [5, 12, 5]
|
positionGltf: [5, 12, 5]
|
||||||
})
|
})
|
||||||
|
expect(resolvePoiCategory(theaterResults[0])?.id).toBe('cinema')
|
||||||
|
expect(matchesPoiCategory(
|
||||||
|
theaterResults[0],
|
||||||
|
getPoiCategoryById('cinema')!
|
||||||
|
)).toBe(true)
|
||||||
|
expect(matchesPoiCategory(
|
||||||
|
theaterResults[0],
|
||||||
|
getPoiCategoryById('exhibition-hall')!
|
||||||
|
)).toBe(false)
|
||||||
|
expect(toFacilityDetailViewModel(theaterResults[0]).category).toBe('影院')
|
||||||
expect(results.some((poi) => poi.id === 'poi-toilet')).toBe(true)
|
expect(results.some((poi) => poi.id === 'poi-toilet')).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('搜索可定位 ID 与同楼层地图 marker ID 保持一致', async () => {
|
||||||
|
const provider = createProvider()
|
||||||
|
const guideRepository = new SgsSdkGuideRepository(provider)
|
||||||
|
const modelRepository = new SgsSdkGuideModelRepository(provider, guideRepository)
|
||||||
|
|
||||||
|
const [searchResults, renderPois] = await Promise.all([
|
||||||
|
guideRepository.searchPois(),
|
||||||
|
modelRepository.loadFloorPois('101')
|
||||||
|
])
|
||||||
|
const renderPoiIds = new Set(renderPois.map((poi) => poi.id))
|
||||||
|
const locatableSearchIds = searchResults
|
||||||
|
.filter((poi) => poi.floorId === '101' && poi.positionGltf)
|
||||||
|
.map((poi) => poi.id)
|
||||||
|
|
||||||
|
expect(locatableSearchIds.length).toBeGreaterThan(0)
|
||||||
|
expect(locatableSearchIds.every((poiId) => renderPoiIds.has(poiId))).toBe(true)
|
||||||
|
expect(renderPois.find((poi) => poi.id === 'hall-space-theater')).toMatchObject({
|
||||||
|
primaryCategory: 'space_theater',
|
||||||
|
iconType: 'theater'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('核心点位来源短暂失败时仍返回可直接定位的稳定空间 ID', async () => {
|
||||||
|
const getFloorPois = vi.fn()
|
||||||
|
.mockResolvedValueOnce([floorPoi])
|
||||||
|
.mockRejectedValueOnce(new Error('pois offline'))
|
||||||
|
.mockResolvedValue([floorPoi])
|
||||||
|
const getFloorSpaces = vi.fn()
|
||||||
|
.mockResolvedValueOnce([theaterSpace])
|
||||||
|
.mockRejectedValueOnce(new Error('spaces offline'))
|
||||||
|
.mockResolvedValue([theaterSpace])
|
||||||
|
const provider = createProvider({ getFloorPois, getFloorSpaces })
|
||||||
|
const guideRepository = new SgsSdkGuideRepository(provider)
|
||||||
|
const modelRepository = new SgsSdkGuideModelRepository(provider, guideRepository)
|
||||||
|
vi.spyOn(console, 'warn').mockImplementation(() => undefined)
|
||||||
|
|
||||||
|
await guideRepository.listSpacePoints()
|
||||||
|
const fallbackResults = await guideRepository.searchPois()
|
||||||
|
const fallbackTheater = fallbackResults.find((poi) => poi.name === '球幕影院')
|
||||||
|
|
||||||
|
expect(fallbackTheater?.id).toBe('hall-space-theater')
|
||||||
|
const recoveredTheater = (await guideRepository.searchPois())
|
||||||
|
.find((poi) => poi.name === '球幕影院')
|
||||||
|
expect(recoveredTheater?.id).toBe(fallbackTheater?.id)
|
||||||
|
await expect(guideRepository.getPoiById('space-space-theater'))
|
||||||
|
.resolves.toMatchObject({ id: 'hall-space-theater' })
|
||||||
|
|
||||||
|
const renderPois = await modelRepository.loadFloorPois('101')
|
||||||
|
expect(renderPois.some((poi) => poi.id === fallbackTheater?.id)).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('相同模型对象名不会删除不同稳定 ID 和坐标的普通点位', async () => {
|
||||||
|
const provider = createProvider({
|
||||||
|
getFloorSpaces: vi.fn().mockResolvedValue([]),
|
||||||
|
getFloorPois: vi.fn().mockResolvedValue([
|
||||||
|
{
|
||||||
|
...floorPoi,
|
||||||
|
id: '5625',
|
||||||
|
name: '男卫生间001',
|
||||||
|
sourceNodeName: 'L2_男卫生间001',
|
||||||
|
position: { x: 1, y: 12, z: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...floorPoi,
|
||||||
|
id: '5629',
|
||||||
|
name: '卫生间01',
|
||||||
|
sourceNodeName: 'L2_男卫生间001',
|
||||||
|
position: { x: 9, y: 12, z: 9 }
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
const guideRepository = new SgsSdkGuideRepository(provider)
|
||||||
|
const modelRepository = new SgsSdkGuideModelRepository(provider, guideRepository)
|
||||||
|
|
||||||
|
const renderPois = await modelRepository.loadFloorPois('101')
|
||||||
|
|
||||||
|
expect(renderPois.filter((poi) => poi.id === '5625' || poi.id === '5629'))
|
||||||
|
.toHaveLength(2)
|
||||||
|
})
|
||||||
|
|
||||||
it('部分来源失败时继续返回可用点位,并在后续搜索重试失败来源', async () => {
|
it('部分来源失败时继续返回可用点位,并在后续搜索重试失败来源', async () => {
|
||||||
const getFloorSpaces = vi.fn()
|
const getFloorSpaces = vi.fn()
|
||||||
.mockRejectedValueOnce(new Error('spaces offline'))
|
.mockRejectedValueOnce(new Error('spaces offline'))
|
||||||
@@ -112,7 +209,7 @@ describe('SgsSdkGuideRepository 点位搜索', () => {
|
|||||||
expect(firstResults.map((poi) => poi.id)).toEqual(['poi-toilet'])
|
expect(firstResults.map((poi) => poi.id)).toEqual(['poi-toilet'])
|
||||||
|
|
||||||
const secondResults = await repository.searchPois()
|
const secondResults = await repository.searchPois()
|
||||||
expect(secondResults.some((poi) => poi.id === 'space-space-theater')).toBe(true)
|
expect(secondResults.some((poi) => poi.id === 'hall-space-theater')).toBe(true)
|
||||||
expect(getFloorSpaces).toHaveBeenCalledTimes(4)
|
expect(getFloorSpaces).toHaveBeenCalledTimes(4)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -148,7 +245,7 @@ describe('SgsSdkGuideRepository 点位搜索', () => {
|
|||||||
await expect(repository.searchPois()).rejects.toThrow('点位数据加载失败,请检查网络后重试')
|
await expect(repository.searchPois()).rejects.toThrow('点位数据加载失败,请检查网络后重试')
|
||||||
|
|
||||||
const recoveredResults = await repository.searchPois()
|
const recoveredResults = await repository.searchPois()
|
||||||
expect(recoveredResults.find((poi) => poi.id === 'space-space-theater')?.positionGltf)
|
expect(recoveredResults.find((poi) => poi.id === 'hall-space-theater')?.positionGltf)
|
||||||
.toEqual([5, 12, 5])
|
.toEqual([5, 12, 5])
|
||||||
expect(getFloorPois).toHaveBeenCalledTimes(4)
|
expect(getFloorPois).toHaveBeenCalledTimes(4)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user