Files
frontend-miniapp/src/domain/guideFloor.ts

71 lines
2.1 KiB
TypeScript

import type {
MuseumFloor,
MuseumPoi
} from '@/domain/museum'
interface FloorLike {
id?: string | number | null
label?: string | null
floorId?: string | number | null
floorCode?: string | null
floorName?: string | null
name?: string | null
modelGroup?: string | null
}
const indoorFloorCodePattern = /^L-?\d+(?:\.\d+)?$/i
const indoorFloorLabelPattern = /^(?:B\d+(?:\.\d+)?|\d+(?:\.\d+)?F)$/i
const rawNumericIdPattern = /^\d{6,}$/
const nonNavigableFloorPattern = /(EXTERIOR|OUTDOOR|BUILDING|FACADE|EXTERNAL|外立面|建筑外观|建筑外立面|室外模型|室外场景|室外底图|室外建筑|室外外观|室外)$/i
const normalizeValue = (value: unknown) => (
value === null || typeof value === 'undefined' ? '' : String(value).trim()
)
export const isNonNavigableFloorToken = (value: unknown) => {
const normalized = normalizeValue(value)
return Boolean(normalized && nonNavigableFloorPattern.test(normalized))
}
export const isIndoorFloorToken = (value: unknown) => {
const normalized = normalizeValue(value)
if (!normalized || isNonNavigableFloorToken(normalized)) return false
return indoorFloorCodePattern.test(normalized)
|| indoorFloorLabelPattern.test(normalized)
|| rawNumericIdPattern.test(normalized)
}
export const isIndoorNavigableFloor = (floor: FloorLike | null | undefined) => {
if (!floor) return false
const tokens = [
floor.id,
floor.label,
floor.floorId,
floor.floorCode,
floor.floorName,
floor.name,
floor.modelGroup
]
if (tokens.some(isNonNavigableFloorToken)) return false
return tokens.some(isIndoorFloorToken)
}
export const isPoiOnIndoorNavigableFloor = (poi: Pick<MuseumPoi, 'floorId' | 'floorLabel'>) => (
isIndoorNavigableFloor({
floorId: poi.floorId,
label: poi.floorLabel
})
)
export const filterIndoorNavigableFloors = <T extends MuseumFloor>(floors: T[]) => (
floors.filter((floor) => isIndoorNavigableFloor(floor))
)
export const filterPoisOnIndoorNavigableFloors = <T extends Pick<MuseumPoi, 'floorId' | 'floorLabel'>>(pois: T[]) => (
pois.filter(isPoiOnIndoorNavigableFloor)
)