@@ -6,6 +6,15 @@
|
||||
@back="handleBack"
|
||||
>
|
||||
<view class="explain-detail-page">
|
||||
<view v-if="detailState !== 'ready'" class="detail-page-state" :class="`is-${detailState}`" data-testid="exhibit-detail-state">
|
||||
<text class="detail-page-state-title">{{ detailState === 'loading' ? '正在加载讲解对象' : detailState === 'missing' ? '缺少讲解对象参数' : '讲解对象加载失败' }}</text>
|
||||
<text class="detail-page-state-desc">{{ detailState === 'loading' ? '请稍候' : detailStateMessage }}</text>
|
||||
<view v-if="detailState !== 'loading'" class="detail-page-state-actions">
|
||||
<button v-if="detailState === 'error'" class="detail-page-state-button" @tap="retryDetail">重新加载</button>
|
||||
<button class="detail-page-state-button secondary" @tap="handleBack">返回讲解列表</button>
|
||||
</view>
|
||||
</view>
|
||||
<template v-else>
|
||||
<view class="immersive-hero" :class="{ 'has-real-image': heroImage }">
|
||||
<image
|
||||
v-if="heroImage"
|
||||
@@ -129,6 +138,7 @@
|
||||
<text class="location-text">查看位置</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</GuidePageFrame>
|
||||
</template>
|
||||
@@ -183,6 +193,8 @@ const defaultDetail: ExplainDetailPageViewModel = {
|
||||
}
|
||||
|
||||
const exhibit = ref<ExplainDetailPageViewModel>(defaultDetail)
|
||||
const detailState = ref<'idle' | 'loading' | 'ready' | 'missing' | 'error'>('idle')
|
||||
const detailStateMessage = ref('请检查链接后重试。')
|
||||
const globalAudioPlayer = useGlobalAudioPlayer()
|
||||
const activeTopTab = ref<GuideTopTab>('explain')
|
||||
const resolvedHallId = ref('')
|
||||
@@ -467,6 +479,7 @@ const loadExplainDetail = async (
|
||||
request: NonNullable<typeof detailEntryRequest.value>,
|
||||
lang: AudioLanguage
|
||||
) => {
|
||||
detailState.value = 'loading'
|
||||
const exhibitData = await explainUseCase.enterExplainDetail({
|
||||
...request,
|
||||
lang
|
||||
@@ -487,6 +500,7 @@ const loadExplainDetail = async (
|
||||
}
|
||||
|
||||
void loadFullDetailTextForLanguage(request, resolvedLanguage, exhibit.value)
|
||||
detailState.value = 'ready'
|
||||
}
|
||||
|
||||
onLoad(async (options: any = {}) => {
|
||||
@@ -497,7 +511,10 @@ onLoad(async (options: any = {}) => {
|
||||
}
|
||||
|
||||
const exhibitId = Array.isArray(options.id) ? options.id[0] : options.id
|
||||
if (!exhibitId) return
|
||||
if (!exhibitId) {
|
||||
detailState.value = 'missing'
|
||||
return
|
||||
}
|
||||
|
||||
const rawTargetType = Array.isArray(options.targetType) ? options.targetType[0] : options.targetType
|
||||
const targetType: AudioPlayTargetType | undefined = rawTargetType === 'ITEM'
|
||||
@@ -527,13 +544,21 @@ onLoad(async (options: any = {}) => {
|
||||
await loadExplainDetail(detailEntryRequest.value, lang)
|
||||
} catch (error) {
|
||||
console.error('讲解详情加载失败:', error)
|
||||
uni.showToast({
|
||||
title: '讲解详情加载失败,请稍后重试',
|
||||
icon: 'none'
|
||||
})
|
||||
detailState.value = 'error'
|
||||
detailStateMessage.value = error instanceof Error ? error.message : '请检查网络后重试。'
|
||||
}
|
||||
})
|
||||
|
||||
const retryDetail = async () => {
|
||||
if (!detailEntryRequest.value || detailState.value === 'loading') return
|
||||
try {
|
||||
await loadExplainDetail(detailEntryRequest.value, selectedAudioLanguage.value)
|
||||
} catch (error) {
|
||||
detailState.value = 'error'
|
||||
detailStateMessage.value = error instanceof Error ? error.message : '请检查网络后重试。'
|
||||
}
|
||||
}
|
||||
|
||||
// iOS H5 may hide a uni page before its route is fully unloaded.
|
||||
onHide(closeDetailAudioOnExit)
|
||||
onUnload(closeDetailAudioOnExit)
|
||||
|
||||
Reference in New Issue
Block a user