This commit is contained in:
@@ -373,6 +373,8 @@ const requestedFloorId = ref('')
|
||||
const requestedFloorLabel = ref('')
|
||||
const loadingFloorId = ref('')
|
||||
const renderedFloorId = ref('')
|
||||
// Only GuideMapShell's floor-change confirms that the Three.js floor is usable.
|
||||
const committedFloorId = ref('')
|
||||
const failedFloorId = ref('')
|
||||
const selectedGuidePoi = ref<GuideRenderPoi | null>(null)
|
||||
const selectedGuidePoiDetailTarget = ref<PoiDetailTarget | null>(null)
|
||||
@@ -432,6 +434,8 @@ const homeSearchExpanded = ref(false)
|
||||
const homeCategoryModeActive = ref(false)
|
||||
const searchVisiblePoiIds = ref<string[] | null>(null)
|
||||
const searchTargetFocusRequest = ref<TargetPoiFocusRequestViewModel | null>(null)
|
||||
const homeSearchMapState = ref<PoiCategoryResultState | null>(null)
|
||||
let latestHomeSearchMapRequestId = 0
|
||||
type PoiSearchOverlayHistoryState = {
|
||||
museumGuideOverlay?: 'poi-search'
|
||||
[key: string]: unknown
|
||||
@@ -853,6 +857,9 @@ const handleTabChange = (tabId: GuideTopTab) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (tabId !== currentTab.value) {
|
||||
invalidateHomeSearchFloorCommit()
|
||||
}
|
||||
currentTab.value = tabId
|
||||
syncTopTabToUrl(tabId)
|
||||
loadTopTabData(tabId)
|
||||
@@ -875,6 +882,7 @@ const syncTopTabFromHash = () => {
|
||||
currentTab.value = tab
|
||||
loadTopTabData(tab)
|
||||
if (tabChanged) {
|
||||
invalidateHomeSearchFloorCommit()
|
||||
showRoutePlanner.value = false
|
||||
isSimulatingRoute.value = false
|
||||
isPoiCardCollapsed.value = false
|
||||
@@ -1000,11 +1008,19 @@ const handleFloorRequest = ({ floorId, floorLabel }: { floorId: string; floorLab
|
||||
requestedFloorLabel.value = floorLabel
|
||||
loadingFloorId.value = floorId
|
||||
failedFloorId.value = ''
|
||||
if (homeSearchMapState.value?.active) {
|
||||
searchVisiblePoiIds.value = []
|
||||
}
|
||||
}
|
||||
|
||||
const handleFloorChange = (floorId: string) => {
|
||||
activeGuideFloor.value = floorId
|
||||
renderedFloorId.value = floorId
|
||||
committedFloorId.value = floorId
|
||||
if (requestedFloorId.value === floorId) {
|
||||
requestedFloorId.value = ''
|
||||
requestedFloorLabel.value = ''
|
||||
}
|
||||
if (loadingFloorId.value === floorId) {
|
||||
loadingFloorId.value = ''
|
||||
}
|
||||
@@ -1014,6 +1030,7 @@ const handleFloorChange = (floorId: string) => {
|
||||
indoorView.value = 'floor'
|
||||
selectedGuidePoi.value = null
|
||||
isPoiCardCollapsed.value = false
|
||||
syncHomeSearchMarkersForCommittedFloor(floorId)
|
||||
showIndoorHint(`已切换到 ${getGuideFloorLabel(floorId)},单指平移、双指可缩放`, 3200)
|
||||
console.log('楼层渲染完成:', floorId)
|
||||
}
|
||||
@@ -1023,6 +1040,13 @@ const handleFloorSwitchFailed = ({ floorId, floorLabel }: { floorId: string; flo
|
||||
loadingFloorId.value = ''
|
||||
}
|
||||
failedFloorId.value = floorId
|
||||
if (requestedFloorId.value === floorId) {
|
||||
requestedFloorId.value = ''
|
||||
requestedFloorLabel.value = ''
|
||||
}
|
||||
if (homeSearchMapState.value?.floorId === floorId) {
|
||||
searchVisiblePoiIds.value = []
|
||||
}
|
||||
showIndoorHint(`${floorLabel || getGuideFloorLabel(floorId)} 加载失败,请稍后重试`, 3600)
|
||||
console.warn('楼层渲染失败:', floorId)
|
||||
}
|
||||
@@ -1030,6 +1054,8 @@ const handleFloorSwitchFailed = ({ floorId, floorLabel }: { floorId: string; flo
|
||||
const handleIndoorViewChange = (view: GuideIndoorView) => {
|
||||
indoorView.value = view
|
||||
if (view !== 'floor') {
|
||||
committedFloorId.value = ''
|
||||
syncHomeSearchMarkersForCommittedFloor()
|
||||
selectedGuidePoi.value = null
|
||||
isPoiCardCollapsed.value = false
|
||||
}
|
||||
@@ -1045,6 +1071,8 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
|
||||
console.log('自动切换视图:', event)
|
||||
indoorView.value = event.to
|
||||
if (event.to !== 'floor') {
|
||||
committedFloorId.value = ''
|
||||
syncHomeSearchMarkersForCommittedFloor()
|
||||
selectedGuidePoi.value = null
|
||||
isPoiCardCollapsed.value = false
|
||||
}
|
||||
@@ -1053,6 +1081,11 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
|
||||
|
||||
const handleInitialModelReady = (event: { view: GuideIndoorView; floorId?: string; elapsedMs?: number }) => {
|
||||
const readyFloorId = event.floorId || activeGuideFloor.value
|
||||
indoorView.value = event.view
|
||||
if (event.view !== 'floor') {
|
||||
committedFloorId.value = ''
|
||||
syncHomeSearchMarkersForCommittedFloor()
|
||||
}
|
||||
if (event.view === 'overview' && readyFloorId) {
|
||||
activeGuideFloor.value = readyFloorId
|
||||
renderedFloorId.value = readyFloorId
|
||||
@@ -1092,6 +1125,7 @@ const handleGuidePoiClick = (poi: GuideRenderPoi) => {
|
||||
isSimulatingRoute.value = false
|
||||
activeGuideFloor.value = poi.floorId
|
||||
renderedFloorId.value = poi.floorId
|
||||
committedFloorId.value = poi.floorId
|
||||
showIndoorHint(`${poi.name} · ${getGuideFloorLabel(poi.floorId)}`, 3000)
|
||||
}
|
||||
|
||||
@@ -1519,6 +1553,7 @@ const resetGuideModelToFloorBaseline = async ({
|
||||
if (!guideModelState.isCurrentRequest(resetRequest.requestId)) return
|
||||
if (resetResult === 'applied') {
|
||||
renderedFloorId.value = activeGuideFloor.value
|
||||
committedFloorId.value = activeGuideFloor.value
|
||||
guideModelState.completeViewBaselineReset(resetRequest)
|
||||
console.info('馆内三维模型已恢复楼层视觉基线:', { rendererReason })
|
||||
} else if (resetResult === 'not-ready' || resetResult === undefined) {
|
||||
@@ -1589,12 +1624,20 @@ const clearHomeSearchMapState = () => {
|
||||
homeCategoryModeActive.value = false
|
||||
searchVisiblePoiIds.value = null
|
||||
searchTargetFocusRequest.value = null
|
||||
homeSearchMapState.value = null
|
||||
}
|
||||
|
||||
const invalidateHomeSearchFloorCommit = () => {
|
||||
clearHomeSearchMapState()
|
||||
committedFloorId.value = ''
|
||||
indoorView.value = 'overview'
|
||||
}
|
||||
|
||||
const handleHomeCategoryModeChange = (active: boolean) => {
|
||||
homeCategoryModeActive.value = active
|
||||
if (!active) {
|
||||
searchVisiblePoiIds.value = null
|
||||
homeSearchMapState.value = null
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1604,19 +1647,72 @@ const handleHomeCategoryModeChange = (active: boolean) => {
|
||||
selectedGuidePoi.value = null
|
||||
isPoiCardCollapsed.value = false
|
||||
is3DMode.value = true
|
||||
indoorView.value = 'floor'
|
||||
searchVisiblePoiIds.value = []
|
||||
}
|
||||
|
||||
const handleHomeSearchResultsChange = (state: PoiCategoryResultState) => {
|
||||
if (!state.active) {
|
||||
searchVisiblePoiIds.value = null
|
||||
const isHomeSearchFloorCommitted = (floorId: string) => (
|
||||
Boolean(floorId)
|
||||
&& committedFloorId.value === floorId
|
||||
&& indoorView.value === 'floor'
|
||||
)
|
||||
|
||||
const requestHomeSearchFloor = (floorId: string, floorLabel = '') => {
|
||||
if (!floorId || requestedFloorId.value === floorId || loadingFloorId.value === floorId) return
|
||||
|
||||
requestedFloorId.value = floorId
|
||||
requestedFloorLabel.value = floorLabel || getGuideFloorLabel(floorId)
|
||||
loadingFloorId.value = floorId
|
||||
failedFloorId.value = ''
|
||||
void Promise.resolve(guideMapShellRef.value?.switchFloor?.(floorId))
|
||||
.catch((error) => {
|
||||
console.error('快捷入口楼层切换失败:', error)
|
||||
})
|
||||
}
|
||||
|
||||
const syncHomeSearchMarkersForCommittedFloor = (floorId = committedFloorId.value) => {
|
||||
const state = homeSearchMapState.value
|
||||
if (
|
||||
!state?.active
|
||||
|| state.pending
|
||||
|| state.floorId !== floorId
|
||||
|| indoorView.value !== 'floor'
|
||||
) {
|
||||
searchVisiblePoiIds.value = state?.active ? [] : null
|
||||
return
|
||||
}
|
||||
|
||||
searchVisiblePoiIds.value = [...state.visiblePoiIds]
|
||||
if (state.floorId && !state.pending) {
|
||||
activeGuideFloor.value = state.floorId
|
||||
}
|
||||
|
||||
const handleHomeSearchResultsChange = (state: PoiCategoryResultState) => {
|
||||
if (
|
||||
typeof state.requestId === 'number'
|
||||
&& state.requestId < latestHomeSearchMapRequestId
|
||||
) return
|
||||
if (typeof state.requestId === 'number') {
|
||||
latestHomeSearchMapRequestId = state.requestId
|
||||
}
|
||||
|
||||
if (!state.active) {
|
||||
clearHomeSearchMapState()
|
||||
return
|
||||
}
|
||||
|
||||
homeSearchMapState.value = {
|
||||
...state,
|
||||
visiblePoiIds: [...state.visiblePoiIds]
|
||||
}
|
||||
if (state.pending) {
|
||||
searchVisiblePoiIds.value = []
|
||||
}
|
||||
|
||||
if (!isHomeSearchFloorCommitted(state.floorId)) {
|
||||
searchVisiblePoiIds.value = []
|
||||
requestHomeSearchFloor(state.floorId, state.floorLabel)
|
||||
return
|
||||
}
|
||||
|
||||
syncHomeSearchMarkersForCommittedFloor(state.floorId)
|
||||
}
|
||||
|
||||
const handleHomeSearchResultTap = async (poi: MuseumPoi, context: PoiSearchContext) => {
|
||||
@@ -1672,6 +1768,7 @@ const handleExplainHallClick = async (hallId: string) => {
|
||||
}
|
||||
|
||||
const handleExplainBack = () => {
|
||||
invalidateHomeSearchFloorCommit()
|
||||
currentTab.value = 'guide'
|
||||
syncTopTabToUrl('guide')
|
||||
loadTopTabData('guide')
|
||||
|
||||
Reference in New Issue
Block a user