- 同步讲解列表层级标题到宿主导航栏 - 嵌入小程序时为展厅/业务单元层级写入 H5 历史 - 保留普通 H5 自绘标题和返回行为 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,8 +28,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { onLoad, onUnload } from '@dcloudio/uni-app'
|
||||
import GuidePageFrame from '@/components/navigation/GuidePageFrame.vue'
|
||||
import ExplainHallSelect, {
|
||||
type ExplainBusinessUnitSelectItem,
|
||||
@@ -51,6 +51,7 @@ import {
|
||||
navigateToGuideTopTab,
|
||||
type GuideTopTab
|
||||
} from '@/utils/guideTopTabs'
|
||||
import { isEmbeddedInWechatMiniProgram } from '@/utils/hostEnvironment'
|
||||
|
||||
const explainHallItems = ref<ExplainHallSelectItem[]>([])
|
||||
const explainBusinessUnits = ref<ExplainBusinessUnit[]>([])
|
||||
@@ -89,6 +90,24 @@ const buildExplainHallItems = (
|
||||
const selectedExplainBusinessUnit = computed(() => (
|
||||
explainBusinessUnits.value.find((unit) => unit.id === selectedExplainBusinessUnitId.value) || null
|
||||
))
|
||||
const explainPageTitle = computed(() => {
|
||||
if (explainStage.value === 'unit') return selectedExplainHallName.value || '选择业务单元'
|
||||
if (explainStage.value === 'stop') return selectedExplainBusinessUnitName.value || '选择讲解点'
|
||||
return '讲解'
|
||||
})
|
||||
const shouldUseHostNavigation = computed(() => isEmbeddedInWechatMiniProgram())
|
||||
|
||||
const syncHostNavigationTitle = () => {
|
||||
const title = explainPageTitle.value
|
||||
|
||||
if (typeof uni !== 'undefined') {
|
||||
uni.setNavigationBarTitle({ title })
|
||||
}
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
document.title = title
|
||||
}
|
||||
}
|
||||
|
||||
const explainBusinessUnitItems = computed<ExplainBusinessUnitSelectItem[]>(() => (
|
||||
explainBusinessUnits.value.map((unit) => ({
|
||||
@@ -120,6 +139,125 @@ const explainGuideStopItems = computed<ExplainGuideStopSelectItem[]>(() => (
|
||||
})) || []
|
||||
))
|
||||
|
||||
type ExplainHistoryState = {
|
||||
museumExplainList?: boolean
|
||||
stage?: ExplainSelectStage
|
||||
hallId?: string
|
||||
hallName?: string
|
||||
unitId?: string
|
||||
unitName?: string
|
||||
}
|
||||
|
||||
let syncingExplainHistory = false
|
||||
let applyingExplainHistory = false
|
||||
|
||||
const stageRank: Record<ExplainSelectStage, number> = {
|
||||
hall: 0,
|
||||
unit: 1,
|
||||
stop: 2
|
||||
}
|
||||
|
||||
const currentExplainHistoryState = (): ExplainHistoryState => ({
|
||||
museumExplainList: true,
|
||||
stage: explainStage.value,
|
||||
hallId: selectedExplainHallId.value,
|
||||
hallName: selectedExplainHallName.value,
|
||||
unitId: selectedExplainBusinessUnitId.value,
|
||||
unitName: selectedExplainBusinessUnitName.value
|
||||
})
|
||||
|
||||
const writeExplainHistoryState = (replace = false) => {
|
||||
if (!shouldUseHostNavigation.value || typeof window === 'undefined') return
|
||||
|
||||
syncingExplainHistory = true
|
||||
const state = currentExplainHistoryState()
|
||||
const url = window.location.href
|
||||
|
||||
if (replace) {
|
||||
window.history.replaceState(state, '', url)
|
||||
} else {
|
||||
window.history.pushState(state, '', url)
|
||||
}
|
||||
|
||||
window.setTimeout(() => {
|
||||
syncingExplainHistory = false
|
||||
}, 0)
|
||||
}
|
||||
|
||||
const applyExplainHistoryState = async (state: ExplainHistoryState | null) => {
|
||||
if (!state?.museumExplainList || applyingExplainHistory) return
|
||||
|
||||
applyingExplainHistory = true
|
||||
const targetStage = state.stage || 'hall'
|
||||
|
||||
if (targetStage === 'hall') {
|
||||
explainStage.value = 'hall'
|
||||
selectedExplainHallId.value = ''
|
||||
selectedExplainHallName.value = ''
|
||||
selectedExplainBusinessUnitId.value = ''
|
||||
selectedExplainBusinessUnitName.value = ''
|
||||
explainBusinessUnits.value = []
|
||||
explainError.value = ''
|
||||
applyingExplainHistory = false
|
||||
return
|
||||
}
|
||||
|
||||
if (state.hallId) {
|
||||
selectedExplainHallId.value = state.hallId
|
||||
selectedExplainHallName.value = state.hallName || '业务单元'
|
||||
selectedExplainBusinessUnitId.value = ''
|
||||
selectedExplainBusinessUnitName.value = ''
|
||||
explainStage.value = 'unit'
|
||||
|
||||
if (!explainBusinessUnits.value.length || explainBusinessUnits.value[0]?.hallId !== state.hallId) {
|
||||
explainLoading.value = true
|
||||
explainError.value = ''
|
||||
try {
|
||||
explainBusinessUnits.value = await explainUseCase.loadTemporaryBusinessUnitsByHall(state.hallId)
|
||||
} catch (error) {
|
||||
console.error('恢复展厅讲解点失败:', error)
|
||||
explainError.value = '展厅讲解点加载失败,请稍后重试'
|
||||
explainBusinessUnits.value = []
|
||||
} finally {
|
||||
explainLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetStage === 'stop' && state.unitId) {
|
||||
selectedExplainBusinessUnitId.value = state.unitId
|
||||
selectedExplainBusinessUnitName.value = state.unitName || '讲解点'
|
||||
explainStage.value = 'stop'
|
||||
}
|
||||
|
||||
applyingExplainHistory = false
|
||||
}
|
||||
|
||||
const handleExplainHistoryPopState = (event: PopStateEvent) => {
|
||||
if (syncingExplainHistory) return
|
||||
void applyExplainHistoryState((event.state || null) as ExplainHistoryState | null)
|
||||
}
|
||||
|
||||
const pushExplainStageHistory = (previousStage: ExplainSelectStage) => {
|
||||
if (!shouldUseHostNavigation.value || applyingExplainHistory) return
|
||||
if (stageRank[explainStage.value] <= stageRank[previousStage]) return
|
||||
|
||||
writeExplainHistoryState()
|
||||
}
|
||||
|
||||
const replaceExplainStageHistory = () => {
|
||||
writeExplainHistoryState(true)
|
||||
}
|
||||
|
||||
watch(explainPageTitle, syncHostNavigationTitle)
|
||||
|
||||
watch(shouldUseHostNavigation, (value) => {
|
||||
if (value) {
|
||||
syncHostNavigationTitle()
|
||||
replaceExplainStageHistory()
|
||||
}
|
||||
})
|
||||
|
||||
const loadExplainHalls = async () => {
|
||||
if (explainHallItems.value.length) return
|
||||
if (explainLoadPromise) return explainLoadPromise
|
||||
@@ -146,7 +284,19 @@ const loadExplainHalls = async () => {
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
syncHostNavigationTitle()
|
||||
replaceExplainStageHistory()
|
||||
void loadExplainHalls()
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('popstate', handleExplainHistoryPopState)
|
||||
}
|
||||
})
|
||||
|
||||
onUnload(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.removeEventListener('popstate', handleExplainHistoryPopState)
|
||||
}
|
||||
})
|
||||
|
||||
const handleBack = () => {
|
||||
@@ -170,6 +320,7 @@ const handleTopTabChange = (tab: GuideTopTab) => {
|
||||
}
|
||||
|
||||
const handleExplainHallClick = async (hallId: string) => {
|
||||
const previousStage = explainStage.value
|
||||
const hall = explainHallItems.value.find((item) => item.id === hallId)
|
||||
selectedExplainHallId.value = hallId
|
||||
selectedExplainHallName.value = hall?.name || '业务单元'
|
||||
@@ -182,20 +333,24 @@ const handleExplainHallClick = async (hallId: string) => {
|
||||
try {
|
||||
explainBusinessUnits.value = await explainUseCase.loadTemporaryBusinessUnitsByHall(hallId)
|
||||
explainStage.value = 'unit'
|
||||
pushExplainStageHistory(previousStage)
|
||||
} catch (error) {
|
||||
console.error('加载展厅讲解点失败:', error)
|
||||
explainError.value = '展厅讲解点加载失败,请稍后重试'
|
||||
explainStage.value = 'unit'
|
||||
pushExplainStageHistory(previousStage)
|
||||
} finally {
|
||||
explainLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleExplainBusinessUnitClick = (unitId: string) => {
|
||||
const previousStage = explainStage.value
|
||||
const unit = explainBusinessUnits.value.find((item) => item.id === unitId)
|
||||
selectedExplainBusinessUnitId.value = unitId
|
||||
selectedExplainBusinessUnitName.value = unit?.name || '讲解点'
|
||||
explainStage.value = 'stop'
|
||||
pushExplainStageHistory(previousStage)
|
||||
}
|
||||
|
||||
const handleExplainGuideStopClick = (stop: ExplainGuideStopSelectItem) => {
|
||||
@@ -222,6 +377,7 @@ const handlePanelBack = () => {
|
||||
selectedExplainBusinessUnitId.value = ''
|
||||
selectedExplainBusinessUnitName.value = ''
|
||||
explainError.value = ''
|
||||
replaceExplainStageHistory()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -233,6 +389,7 @@ const handlePanelBack = () => {
|
||||
selectedExplainBusinessUnitName.value = ''
|
||||
explainBusinessUnits.value = []
|
||||
explainError.value = ''
|
||||
replaceExplainStageHistory()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user