修复 SGS SDK 导览数据源与模型加载
升级 SDK API 数据契约,补齐 guideStops、业务 POI、诊断与路线数据接口。 修复 SDK 模式下 POI/模型/楼层混用静态数据的问题,并为 ThreeMap 模型加载增加短退避重试。
This commit is contained in:
@@ -255,7 +255,6 @@ export class SgsSdkGuideRepository implements GuideRepository {
|
||||
private floorsCache: MuseumFloor[] | null = null
|
||||
private poiCache: MuseumPoi[] | null = null
|
||||
private floorAliases: Map<string, string> | null = null
|
||||
private readonly staticFallback = new StaticGuideRepository()
|
||||
|
||||
constructor(private readonly provider: SgsSdkApiProvider = defaultSgsSdkApiProvider) {}
|
||||
|
||||
@@ -331,7 +330,7 @@ export class SgsSdkGuideRepository implements GuideRepository {
|
||||
const pois = await this.listPois()
|
||||
return pois.find((poi) => poi.id === id)
|
||||
|| findPoiByNavIdNameFallback(pois, id)
|
||||
|| this.staticFallback.getPoiById(id)
|
||||
|| null
|
||||
}
|
||||
|
||||
async searchPois(keyword = '') {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from '@/repositories/GuideRouteRepository'
|
||||
import {
|
||||
defaultSgsSdkApiProvider,
|
||||
type SgsFloorDiagnosticsPayload,
|
||||
type SgsNavigablePlacePayload,
|
||||
type SgsSdkApiProvider
|
||||
} from '@/data/providers/sgsSdkApiProvider'
|
||||
@@ -29,13 +30,40 @@ const createUnavailableReadiness = (message: string): GuideRouteReadiness => ({
|
||||
})
|
||||
|
||||
const logSdkRouteReadinessIssue = (message: string, payload: Record<string, unknown>) => {
|
||||
console.error(`[SDKRouteReadiness] ${message}`, payload)
|
||||
console.warn(`[SDKRouteReadiness] ${message}`, payload)
|
||||
}
|
||||
|
||||
const toNumber = (value: unknown) => (
|
||||
Number.isFinite(Number(value)) ? Number(value) : undefined
|
||||
)
|
||||
|
||||
const isPositiveNumber = (value: unknown) => {
|
||||
const numberValue = toNumber(value)
|
||||
return typeof numberValue === 'number' && numberValue > 0
|
||||
}
|
||||
|
||||
const hasRouteNodeId = (place: SgsNavigablePlacePayload) => (
|
||||
place.nodeId !== null && place.nodeId !== undefined && place.nodeId !== ''
|
||||
)
|
||||
|
||||
const hasRouteGraphEvidence = (floor: Pick<SgsFloorDiagnosticsPayload, 'routePlanningReady' | 'routeNodeCount' | 'routeEdgeCount'>) => (
|
||||
floor.routePlanningReady === true
|
||||
|| (isPositiveNumber(floor.routeNodeCount) && isPositiveNumber(floor.routeEdgeCount))
|
||||
)
|
||||
|
||||
const hasRouteTargetEvidence = (
|
||||
floor: Pick<SgsFloorDiagnosticsPayload, 'navigablePlaceCount'>,
|
||||
routeTargetCount?: number
|
||||
) => {
|
||||
if (typeof routeTargetCount === 'number') return routeTargetCount > 0
|
||||
return floor.navigablePlaceCount === undefined || isPositiveNumber(floor.navigablePlaceCount)
|
||||
}
|
||||
|
||||
const isRouteReadyFromDiagnostics = (
|
||||
floor: Pick<SgsFloorDiagnosticsPayload, 'routePlanningReady' | 'routeNodeCount' | 'routeEdgeCount' | 'navigablePlaceCount'>,
|
||||
routeTargetCount?: number
|
||||
) => hasRouteGraphEvidence(floor) && hasRouteTargetEvidence(floor, routeTargetCount)
|
||||
|
||||
const positionFromPlace = (place: SgsNavigablePlacePayload): [number, number, number] | undefined => {
|
||||
const source = place.position || {
|
||||
x: place.x,
|
||||
@@ -70,36 +98,42 @@ export class SdkGuideRouteRepository {
|
||||
return createUnavailableReadiness('SDK 地图楼层数据为空')
|
||||
}
|
||||
|
||||
// 收集有路线数据的楼层
|
||||
const readyFloors = floors.filter(
|
||||
(floor) =>
|
||||
floor.routePlanningReady &&
|
||||
floor.routeNodeCount &&
|
||||
floor.routeNodeCount > 0 &&
|
||||
floor.routeEdgeCount &&
|
||||
floor.routeEdgeCount > 0
|
||||
)
|
||||
// 地图级 diagnostics 的楼层摘要只保证 routePlanningReady/navigablePlaceCount;
|
||||
// routeNodeCount/routeEdgeCount 可能只出现在 floor diagnostics 或 summary 中。
|
||||
let readyFloors = floors.filter((floor) => isRouteReadyFromDiagnostics(floor))
|
||||
let notReadyFloors = floors.filter((floor) => !isRouteReadyFromDiagnostics(floor))
|
||||
|
||||
if (readyFloors.length === 0) {
|
||||
const floorEvidence = await Promise.all(
|
||||
floors.map((floor) => this.loadFloorRouteEvidence(floor))
|
||||
)
|
||||
readyFloors = floorEvidence
|
||||
.filter((item) => item.ready)
|
||||
.map((item) => item.floor)
|
||||
notReadyFloors = floorEvidence
|
||||
.filter((item) => !item.ready)
|
||||
.map((item) => item.floor)
|
||||
}
|
||||
|
||||
// 没有楼层有路线数据时不可用
|
||||
if (readyFloors.length === 0) {
|
||||
logSdkRouteReadinessIssue('SDK 路线数据不完整', {
|
||||
logSdkRouteReadinessIssue('SDK 路线数据未达到位置关系生成条件', {
|
||||
floorCount: floors.length,
|
||||
readyFloorCount: readyFloors.length,
|
||||
summary: diagnostics.summary,
|
||||
floors: floors.map((floor) => ({
|
||||
floorId: floor.floorId,
|
||||
floorName: floor.floorName,
|
||||
floorCode: floor.floorCode,
|
||||
routePlanningReady: floor.routePlanningReady,
|
||||
routeNodeCount: floor.routeNodeCount,
|
||||
routeEdgeCount: floor.routeEdgeCount
|
||||
routeEdgeCount: floor.routeEdgeCount,
|
||||
navigablePlaceCount: floor.navigablePlaceCount
|
||||
}))
|
||||
})
|
||||
return createUnavailableReadiness('无法定位,当前仅支持点位位置预览')
|
||||
}
|
||||
|
||||
// 收集未就绪的楼层
|
||||
const notReadyFloors = floors.filter((floor) => !floor.routePlanningReady)
|
||||
|
||||
// 如果有楼层未就绪,给出警告但仍然可用
|
||||
if (notReadyFloors.length > 0) {
|
||||
const floorLabels = notReadyFloors
|
||||
@@ -125,6 +159,25 @@ export class SdkGuideRouteRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private async loadFloorRouteEvidence(floor: SgsFloorDiagnosticsPayload) {
|
||||
const rawFloorId = stringifyId(floor.floorId)
|
||||
const [floorDiagnostics, navigablePlaces] = await Promise.all([
|
||||
this.sdkApiProvider.getFloorDiagnostics(rawFloorId).catch(() => null),
|
||||
this.sdkApiProvider.getNavigablePlaces(rawFloorId).catch(() => [])
|
||||
])
|
||||
const routeTargetCount = navigablePlaces.filter(hasRouteNodeId).length
|
||||
const evidence = floorDiagnostics || floor
|
||||
|
||||
return {
|
||||
floor: {
|
||||
...floor,
|
||||
...floorDiagnostics
|
||||
},
|
||||
ready: isRouteReadyFromDiagnostics(evidence, routeTargetCount),
|
||||
routeTargetCount
|
||||
}
|
||||
}
|
||||
|
||||
async listRouteTargets(): Promise<GuideRouteTarget[]> {
|
||||
if (this.targetsCache) return this.targetsCache
|
||||
|
||||
@@ -141,7 +194,7 @@ export class SdkGuideRouteRepository {
|
||||
|
||||
for (const place of places) {
|
||||
// 过滤掉没有 nodeId 的点位,这些无法用于路线规划
|
||||
if (place.nodeId === null || place.nodeId === undefined || place.nodeId === '') {
|
||||
if (!hasRouteNodeId(place)) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user