Files
frontend-miniapp/src/domain/museum.ts
2026-07-22 19:40:17 +08:00

418 lines
8.8 KiB
TypeScript

export interface MuseumFloor {
id: string
label: string
order: number
}
export type GuideDiagnosticsStatus = 'OK' | 'WARN' | 'ERROR'
export type GuideDataIssueSeverity = 'info' | 'warn' | 'error'
export interface GuideFloorDetail extends MuseumFloor {
sourceCode?: string
sourceName?: string
modelReady?: boolean
poiCount?: number
spaceCount?: number
guideStopCount?: number
navigablePlaceCount?: number
routeNodeCount?: number
routeEdgeCount?: number
routePlanningReady?: boolean
warnings: string[]
}
export interface GuideMapDiagnosticsSummary {
floorCount: number
modelReadyFloorCount: number
poiCount: number
spaceCount: number
guideStopCount: number
navigablePlaceCount: number
routeNodeCount: number
routeEdgeCount: number
}
export interface GuideMapDiagnostics {
mapId: string
mapName: string
sdkVersion?: string
status: GuideDiagnosticsStatus
floors: GuideFloorDetail[]
summary: GuideMapDiagnosticsSummary
warnings: string[]
}
export interface GuideDataIntegrityIssue {
id: string
scope: 'floor' | 'poi'
severity: GuideDataIssueSeverity
message: string
floorId?: string
floorLabel?: string
poiId?: string
fields?: string[]
}
export interface GuideDataIntegrityReport {
status: GuideDiagnosticsStatus
summary: {
floorCount: number
poiCount: number
issueCount: number
errorCount: number
warningCount: number
}
issues: GuideDataIntegrityIssue[]
warnings: string[]
}
export interface MuseumCategory {
id: string
label: string
iconType?: string
}
export type MuseumPoiKind = 'facility' | 'hall' | 'hall_entrance' | 'guide' | 'space'
export interface MuseumPoiEntrance {
id: string
name: string
floorId: string
floorLabel: string
positionGltf?: [number, number, number]
sourceObjectName?: string
sourcePlaceId?: string
routeNodeId?: string
}
export interface MuseumPoi {
id: string
name: string
floorId: string
floorLabel: string
primaryCategory: MuseumCategory
categories: MuseumCategory[]
positionGltf?: [number, number, number]
sourceObjectName?: string
sourceConfidence?: string
navigationReadiness?: string
/** Explicit visitor-search eligibility supplied by the source or adapter policy. */
visitorVisible?: boolean
accessible: boolean
kind?: MuseumPoiKind
hallId?: string
hallName?: string
spaceId?: string
sourcePlaceId?: string
sourceSpaceId?: string
entrances?: MuseumPoiEntrance[]
displayPolicy?: import('@/domain/poiDisplay').PoiDisplayPolicy
}
export type GuideLocationResolutionStatus = 'exact' | 'hallFallback' | 'candidate' | 'unavailable'
export interface GuideLocationResolution {
status: GuideLocationResolutionStatus
poiId?: string
sourcePoiId?: string
actionText: string
previewOnly: boolean
confidence?: string
method?: string
floorId?: string
floorLabel?: string
note?: string
}
export interface MuseumHall {
id: string
name: string
floorId?: string
floorLabel?: string
description?: string
image?: string
exhibitCount?: number
outlineCount?: number
stopCount?: number
linkedExhibitCount?: number
audioReadyStopCount?: number
hasAudio?: boolean
audioStatus?: string
supportedLanguages?: string[]
area?: string
poiId?: string
location?: GuideLocationResolution
}
export interface MuseumExhibit {
id: string
name: string
hallId?: string
hallName?: string
floorId?: string
floorLabel?: string
image?: string
description?: string
poiId?: string
sourcePoiId?: string
mapX?: number
mapY?: number
location?: GuideLocationResolution
artist?: string
year?: string
material?: string
size?: string
tags?: string[]
guideContentId?: string
guideTitle?: string
guideText?: string
audioUrl?: string
audioDuration?: number
audioLanguage?: string
audioSubtitleUrl?: string
audioHasText?: boolean
audioText?: string
audioTextLength?: number
audioTextHash?: string
audioNarrationTier?: 'STANDARD' | 'EXTENDED'
audioUnavailableReason?: string
audioAvailable?: boolean
audioStatus?: string
supportedLanguages?: string[]
audioVariants?: Record<string, {
title?: string
text?: string
textAvailable?: boolean
textLength?: number
textHash?: string
audioUrl?: string
audioDuration?: number
format?: string
audioId?: string
narrationTier?: 'STANDARD' | 'EXTENDED'
hasText?: boolean
enabled?: boolean
playable?: boolean
available?: boolean
audioStatus?: string
fallback?: boolean
reason?: string
}>
imageStatus?: string
imageSource?: string
galleryUrls?: string[]
linkedExhibitCount?: number
isSharedStop?: boolean
linkedExhibits?: Array<{
id: string
name: string
nameEn?: string
code?: string
exhibitCode?: string
coverImageUrl?: string
galleryUrls?: string[]
sortOrder?: number
}>
stopInfoAvailable?: boolean
stopInfoReason?: string
resolvedStopId?: string
playTargetType?: AudioPlayTargetType
playTargetId?: string
}
export interface ExplainGuideStop {
id: string
name: string
hallId?: string
hallName?: string
floorId?: string
targetType?: AudioPlayTargetType
targetId?: string
coverImageUrl?: string
description?: string
hasAudio?: boolean
audioStatus?: string
supportedLanguages?: string[]
hasTextRecord?: boolean
poiId?: string
mapX?: number
mapY?: number
outlineId?: string
outlineName?: string
sort?: number
guideLevel?: string
imageStatus?: string
linkedExhibitCount?: number
isSharedStop?: boolean
linkedExhibits?: Array<{
id: string
name: string
nameEn?: string
code?: string
exhibitCode?: string
coverImageUrl?: string
galleryUrls?: string[]
sortOrder?: number
}>
playTargetType?: AudioPlayTargetType
playTargetId?: string
}
export interface ExplainGuideStopPage {
items: ExplainGuideStop[]
total: number
pageNo: number
pageSize: number
hasMore: boolean
}
export interface ExplainBusinessUnit {
id: string
name: string
hallId: string
parentId?: string
code?: string
description?: string
sort?: number
level?: number
previewImageUrl?: string
guideStopCount: number
linkedExhibitCount?: number
audioReadyStopCount?: number
hasAudio?: boolean
audioStatus?: string
supportedLanguages?: string[]
stops: ExplainGuideStop[]
}
export interface GuideLocationPreview {
poiId: string
name: string
floorId: string
floorLabel: string
primaryCategoryZh?: string
positionGltf?: [number, number, number]
sourceObjectName?: string
kind?: MuseumPoiKind
hallId?: string
hallName?: string
entrances?: MuseumPoiEntrance[]
}
export interface GuideStartLocation {
label: string
floor?: string
source?: string
}
export interface GuidePreviewStep {
id: string
text: string
}
export interface GuideLocationPreviewPlan {
id: string
facilityId: string
target: string
summary: string
steps: GuidePreviewStep[]
targetLocation: GuideLocationPreview | null
startLocation: GuideStartLocation | null
}
export interface GuideRouteReadiness {
ready: boolean
message: string
requiredData: string[]
}
export interface GuideRouteTarget {
poiId: string
name: string
floorId: string
floorLabel: string
categoryLabel?: string
positionGltf?: [number, number, number]
routeNodeId: string
}
export interface GuideRoutePoint {
nodeId: string
floorId: string
position: [number, number, number]
}
export interface GuideRouteFloorSegment {
floorId: string
floorLabel: string
points: GuideRoutePoint[]
}
export interface GuideRouteConnectorPoint {
nodeId: string
floorId: string
floorLabel: string
position: [number, number, number]
connectorType?: string
}
export interface GuideRouteEndpoint {
poiId: string
name: string
floorId: string
floorLabel: string
routeNodeId: string
position: [number, number, number]
}
export interface GuideRouteResult {
id: string
start: GuideRouteEndpoint
end: GuideRouteEndpoint
distanceMeters: number
nodeIds: string[]
points: GuideRoutePoint[]
floorSegments: GuideRouteFloorSegment[]
connectorPoints: GuideRouteConnectorPoint[]
}
export interface MediaAsset {
id: string
type: 'audio' | 'image' | 'transcript'
url?: string
duration?: number
language?: string
available: boolean
unavailableReason?: string
}
export type AudioPlayTargetType = 'ITEM' | 'STOP'
export interface ExplainTrack {
id: string
exhibitId?: string
hallId?: string
title: string
summary?: string
mediaId?: string
coverImage?: string
poiId?: string
sourcePoiId?: string
location?: GuideLocationResolution
floorId?: string
available: boolean
playTargetType?: AudioPlayTargetType
playTargetId?: string
}
export interface SearchIndexItem {
id: string
name: string
desc: string
type: 'exhibit' | 'hall' | 'facility'
poiId?: string
floorId?: string
exhibitId?: string
hallId?: string
}