整改点位搜索数据加载与分类逻辑

This commit is contained in:
cxk
2026-07-20 21:30:55 +08:00
parent 65ba9720f8
commit 7ae539accc
14 changed files with 2352 additions and 812 deletions

View File

@@ -23,6 +23,13 @@ import {
applyRouteReadinessGate,
NAV_ROUTE_READINESS
} from '@/domain/guideReadiness'
import {
getPoiCategoryById
} from '@/domain/poiCategories'
import type {
GuidePoiSearchMode,
GuidePoiSearchViewState
} from '@/domain/poiSearch'
const startSourceLabels: Record<string, string> = {
'facility-detail': '设施详情选择',
@@ -98,6 +105,12 @@ export interface GuideContentLocationRequest {
targetName?: string
}
type PoiSearchModeInput = {
mode: GuidePoiSearchMode
keyword?: string
categoryId?: GuidePoiSearchViewState['categoryId']
}
export class GuideUseCase {
private routeReadinessCache: GuideRouteReadiness | null = null
@@ -139,8 +152,115 @@ export class GuideUseCase {
return this.guide.searchPois(keyword)
}
getInitialSearchSpacePoints() {
return this.guide.searchPois()
getInitialSearchSpacePoints(floorId?: string) {
return this.guide.listDestinationPois(floorId)
}
private async resolvePoiSearchFloor(floorId?: string) {
const floors = await this.guide.getFloors()
const requestedFloorId = floorId?.trim() ? this.guide.normalizeFloorId(floorId) : ''
const floor = floors.find((item) => item.id === requestedFloorId)
|| floors.find((item) => item.label === floorId)
|| floors.find((item) => item.label === '1F')
|| floors[0]
return floor || {
id: requestedFloorId || floorId?.trim() || '',
label: floorId?.trim() || ''
}
}
private async loadPoiSearchView(
floorId: string | undefined,
input: PoiSearchModeInput
): Promise<GuidePoiSearchViewState> {
const floor = await this.resolvePoiSearchFloor(floorId)
const keyword = input.keyword?.trim() || ''
const categoryId = input.categoryId || ''
const category = categoryId ? getPoiCategoryById(categoryId) : null
const mode = input.mode === 'category' && !category
? 'default'
: input.mode
const [availability, results] = await Promise.all([
this.guide.getQuickFindCategoryAvailability(floor.id),
mode === 'category' && category
? this.guide.listQuickFindPois(category.id, floor.id)
: mode === 'keyword'
? this.guide.searchPois(keyword, floor.id)
: this.guide.listDestinationPois(floor.id)
])
return {
mode,
floorId: floor.id,
floorLabel: floor.label,
keyword: mode === 'keyword' ? keyword : category?.label || '',
categoryId: mode === 'category' && category ? category.id : '',
results,
visiblePoiIds: results.map((poi) => poi.id),
categories: availability.map((item) => {
const definition = getPoiCategoryById(item.id)
if (!definition) {
throw new Error(`Unknown quick-find category: ${item.id}`)
}
return {
definition,
count: item.count,
disabled: item.disabled
}
})
}
}
createInitialPoiSearchState(floorId?: string) {
return this.loadPoiSearchView(floorId, { mode: 'default' })
}
selectPoiSearchCategory(
state: GuidePoiSearchViewState | null,
categoryId: GuidePoiSearchViewState['categoryId'],
floorId = state?.floorId
) {
return this.loadPoiSearchView(floorId, {
mode: 'category',
categoryId
})
}
searchPoiKeyword(
state: GuidePoiSearchViewState | null,
keyword: string,
floorId = state?.floorId
) {
const normalizedKeyword = keyword.trim()
return this.loadPoiSearchView(floorId, normalizedKeyword
? {
mode: 'keyword',
keyword: normalizedKeyword
}
: {
mode: 'default'
})
}
clearPoiSearch(
state: GuidePoiSearchViewState | null,
floorId = state?.floorId
) {
return this.loadPoiSearchView(floorId, { mode: 'default' })
}
changePoiSearchFloor(
state: GuidePoiSearchViewState | null,
floorId: string
) {
const mode = state?.mode || 'default'
return this.loadPoiSearchView(floorId, {
mode,
keyword: state?.keyword,
categoryId: state?.categoryId
})
}
getPoiById(id: string) {