@@ -3,6 +3,9 @@ import type {
|
||||
GuideLocationPreviewPlan,
|
||||
MuseumPoi
|
||||
} from '@/domain/museum'
|
||||
import {
|
||||
resolvePoiCategory
|
||||
} from '@/domain/poiCategories'
|
||||
|
||||
export interface FacilityResultViewModel {
|
||||
id: string
|
||||
@@ -16,10 +19,22 @@ export interface FacilityResultViewModel {
|
||||
export interface FacilityDetailViewModel {
|
||||
id: string
|
||||
name: string
|
||||
status: string
|
||||
location: string
|
||||
traffic: string
|
||||
tags: string[]
|
||||
category: string
|
||||
floor: string
|
||||
description: string
|
||||
}
|
||||
|
||||
export interface FacilityDetailSearchContext {
|
||||
source: 'search' | 'direct'
|
||||
searchOrigin: 'home' | 'page' | ''
|
||||
searchKeyword: string
|
||||
searchCategoryId: string
|
||||
searchFloorId: string
|
||||
searchFloorLabel: string
|
||||
resultCount: number
|
||||
floorResultCount: number
|
||||
visiblePoiIds: string[]
|
||||
listScrollTop: number
|
||||
}
|
||||
|
||||
export interface TargetPoiFocusRequestViewModel extends GuideLocationPreview {
|
||||
@@ -42,21 +57,53 @@ export const toFacilityResultViewModel = (poi: MuseumPoi): FacilityResultViewMod
|
||||
})
|
||||
|
||||
export const toFacilityDetailViewModel = (
|
||||
poi: MuseumPoi,
|
||||
routeUnavailableMessage: string
|
||||
poi: MuseumPoi
|
||||
): FacilityDetailViewModel => ({
|
||||
id: poi.id,
|
||||
name: poi.name,
|
||||
status: '可预览',
|
||||
location: `${poi.floorLabel} · ${poi.primaryCategory.label}`,
|
||||
traffic: routeUnavailableMessage,
|
||||
tags: [
|
||||
poi.floorLabel,
|
||||
poi.primaryCategory.label,
|
||||
poi.accessible ? '无障碍相关' : '展示点位'
|
||||
]
|
||||
category: resolvePoiCategory(poi)?.label || poi.primaryCategory.label || '未分类',
|
||||
floor: poi.floorLabel || '楼层信息缺失',
|
||||
description: ''
|
||||
})
|
||||
|
||||
const decodeQueryText = (value: unknown) => {
|
||||
if (typeof value !== 'string') return ''
|
||||
|
||||
try {
|
||||
return decodeURIComponent(value)
|
||||
} catch {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
const parseNonNegativeInteger = (value: unknown) => {
|
||||
const parsed = Number.parseInt(decodeQueryText(value), 10)
|
||||
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0
|
||||
}
|
||||
|
||||
export const parseFacilityDetailSearchContext = (
|
||||
options: Record<string, unknown> = {}
|
||||
): FacilityDetailSearchContext => {
|
||||
const searchOrigin = decodeQueryText(options.searchOrigin)
|
||||
const visiblePoiIds = decodeQueryText(options.visiblePoiIds)
|
||||
.split(',')
|
||||
.map((id) => id.trim())
|
||||
.filter(Boolean)
|
||||
|
||||
return {
|
||||
source: decodeQueryText(options.source) === 'search' ? 'search' : 'direct',
|
||||
searchOrigin: searchOrigin === 'home' || searchOrigin === 'page' ? searchOrigin : '',
|
||||
searchKeyword: decodeQueryText(options.searchKeyword),
|
||||
searchCategoryId: decodeQueryText(options.searchCategoryId),
|
||||
searchFloorId: decodeQueryText(options.searchFloorId),
|
||||
searchFloorLabel: decodeQueryText(options.searchFloorLabel),
|
||||
resultCount: parseNonNegativeInteger(options.resultCount),
|
||||
floorResultCount: parseNonNegativeInteger(options.floorResultCount),
|
||||
visiblePoiIds: Array.from(new Set(visiblePoiIds)),
|
||||
listScrollTop: parseNonNegativeInteger(options.listScrollTop)
|
||||
}
|
||||
}
|
||||
|
||||
export const toTargetFocusRequestViewModel = (
|
||||
targetLocation: GuideLocationPreview,
|
||||
requestId: number | string
|
||||
|
||||
Reference in New Issue
Block a user