修复馆内预览状态与点位展示
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-19 14:05:54 +08:00
parent 58887d928a
commit 215428db90
11 changed files with 280 additions and 35 deletions

View File

@@ -0,0 +1,52 @@
import type { MuseumPoi } from '@/domain/museum'
export type VisitorPoiPresentation = Readonly<{
displayName: string
floorLabel: string
locationHint: string
}>
const normalizeDisplayName = (name: string) => {
const normalized = name.trim().replace(/\s+/g, ' ')
const hallMatch = normalized.match(/^展厅\s*\d+\s*(.+厅)$/)
if (hallMatch?.[1]) return hallMatch[1]
return normalized.replace(/(卫生间|洗手间)(\d+)$/, '$1 $2')
}
type VisitorPoiSource = Pick<MuseumPoi, 'id' | 'name' | 'floorId' | 'floorLabel' | 'hallName'> & {
primaryCategory?: { label?: string }
}
const locationHintFor = (poi: VisitorPoiSource) => [
poi.floorLabel?.trim(),
poi.hallName?.trim(),
poi.primaryCategory?.label?.trim()
].filter((value, index, values) => Boolean(value) && values.indexOf(value) === index).join(' · ')
export const createVisitorPoiPresentations = <TPoi extends VisitorPoiSource>(pois: TPoi[]) => {
const baseNames = new Map<string, number>()
pois.forEach((poi) => {
const name = normalizeDisplayName(poi.name || '') || '未命名点位'
baseNames.set(name, (baseNames.get(name) || 0) + 1)
})
const duplicateIndexes = new Map<string, number>()
return new Map(pois.map((poi) => {
const baseName = normalizeDisplayName(poi.name || '') || '未命名点位'
const duplicateCount = baseNames.get(baseName) || 0
const nextIndex = (duplicateIndexes.get(baseName) || 0) + 1
duplicateIndexes.set(baseName, nextIndex)
const locationHint = locationHintFor(poi)
const disambiguation = duplicateCount > 1 ? (locationHint || `设施 ${nextIndex}`) : locationHint
return [poi.id, {
displayName: duplicateCount > 1 ? `${baseName} · ${disambiguation}` : baseName,
floorLabel: poi.floorLabel || poi.floorId,
locationHint: disambiguation
} satisfies VisitorPoiPresentation]
}))
}
export const presentVisitorPoi = <TPoi extends VisitorPoiSource>(poi: TPoi): VisitorPoiPresentation => (
createVisitorPoiPresentations([poi]).get(poi.id)!
)