接入H5讲解后端数据闭环
This commit is contained in:
@@ -76,7 +76,7 @@
|
||||
ref="audioPlayerRef"
|
||||
:visible="showAudioPlayer"
|
||||
:audio="currentAudio"
|
||||
:auto-play="true"
|
||||
:auto-play="false"
|
||||
@update:visible="handleAudioVisibleChange"
|
||||
@play="handleAudioPlay"
|
||||
@pause="handleAudioPause"
|
||||
@@ -189,6 +189,18 @@ onLoad(async (options: any = {}) => {
|
||||
if (exhibitData.hallId) {
|
||||
resolvedHallId.value = exhibitData.hallId
|
||||
}
|
||||
void explainUseCase.enrichExhibitDetailAudio(exhibitId)
|
||||
.then((enrichedExhibit) => {
|
||||
if (!enrichedExhibit || exhibit.value.id !== exhibitId) return
|
||||
|
||||
exhibit.value = toExplainDetailPageViewModel(enrichedExhibit)
|
||||
if (enrichedExhibit.hallId) {
|
||||
resolvedHallId.value = enrichedExhibit.hallId
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('讲解详情音频正文后台补充失败:', error)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -210,11 +222,7 @@ const handlePlayAudio = async () => {
|
||||
|
||||
showAudioPlayer.value = true
|
||||
currentAudio.value = audio
|
||||
await nextTick()
|
||||
|
||||
if (!isPlaying.value) {
|
||||
audioPlayerRef.value?.play(audio)
|
||||
}
|
||||
audioPlayerRef.value?.play(audio)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -247,10 +255,10 @@ const handlePlayAudio = async () => {
|
||||
showAudioPlayer.value = true
|
||||
currentAudio.value = audio
|
||||
await nextTick()
|
||||
|
||||
if (!isPlaying.value) {
|
||||
audioPlayerRef.value?.play(audio)
|
||||
}
|
||||
uni.showToast({
|
||||
title: '音频已准备好,请点击底部播放按钮',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
const handleAudioVisibleChange = (visible: boolean) => {
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
/>
|
||||
|
||||
<AudioPlayer
|
||||
ref="audioPlayerRef"
|
||||
:visible="showAudioPlayer"
|
||||
:audio="currentAudio"
|
||||
:auto-play="true"
|
||||
:auto-play="false"
|
||||
avoid-bottom-nav
|
||||
@update:visible="handleAudioVisibleChange"
|
||||
@play="handleAudioPlay"
|
||||
@@ -66,8 +67,14 @@ const explainError = ref('')
|
||||
const showAudioPlayer = ref(false)
|
||||
const isAudioPlaying = ref(false)
|
||||
const currentAudio = ref<AudioItem | null>(null)
|
||||
const audioPlayerRef = ref<AudioPlayerExpose | null>(null)
|
||||
let explainLoadPromise: Promise<void> | null = null
|
||||
|
||||
interface AudioPlayerExpose {
|
||||
play: (audio: AudioItem) => void
|
||||
pause: () => void
|
||||
}
|
||||
|
||||
const loadExplainExhibits = async () => {
|
||||
if (explainExhibits.value.length) return
|
||||
if (explainLoadPromise) return explainLoadPromise
|
||||
@@ -129,14 +136,23 @@ const handleExplainHallClick = (hallId: string) => {
|
||||
|
||||
const handleAudioClick = async (exhibit: Exhibit) => {
|
||||
if (exhibit.audioUrl) {
|
||||
currentAudio.value = {
|
||||
const audio: AudioItem = {
|
||||
id: `media-${exhibit.id}`,
|
||||
name: exhibit.title,
|
||||
audioUrl: exhibit.audioUrl,
|
||||
image: exhibit.coverImage,
|
||||
duration: exhibit.audioDuration
|
||||
}
|
||||
|
||||
const isSameAudio = currentAudio.value?.id === audio.id
|
||||
if (showAudioPlayer.value && isSameAudio && isAudioPlaying.value) {
|
||||
audioPlayerRef.value?.pause()
|
||||
return
|
||||
}
|
||||
|
||||
currentAudio.value = audio
|
||||
showAudioPlayer.value = true
|
||||
audioPlayerRef.value?.play(audio)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -158,6 +174,10 @@ const handleAudioClick = async (exhibit: Exhibit) => {
|
||||
duration: selection.media.duration
|
||||
}
|
||||
showAudioPlayer.value = true
|
||||
uni.showToast({
|
||||
title: '音频已准备好,请点击底部播放按钮',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
const clearAudioState = () => {
|
||||
|
||||
@@ -125,6 +125,26 @@ const normalizePoiName = (value: string) => value
|
||||
.toLowerCase()
|
||||
|
||||
// 展厅数据里可能没有直接写入 poiId,优先走内容层映射,再按展厅名称兜底匹配导览点位。
|
||||
const applyMatchedHallPoi = (matchedPoi: Awaited<ReturnType<typeof guideUseCase.getPoiById>>) => {
|
||||
if (!matchedPoi) return
|
||||
|
||||
resolvedHallPoiId.value = matchedPoi.id
|
||||
hall.value = {
|
||||
...hall.value,
|
||||
poiId: matchedPoi.id,
|
||||
location: hall.value.location || {
|
||||
status: 'exact',
|
||||
poiId: matchedPoi.id,
|
||||
sourcePoiId: matchedPoi.id,
|
||||
actionText: '查看三维位置',
|
||||
previewOnly: true,
|
||||
floorId: matchedPoi.floorId,
|
||||
floorLabel: matchedPoi.floorLabel,
|
||||
note: '已定位到该展厅的三维点位。'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const resolveHallGuidePoi = async () => {
|
||||
const directPoiId = hall.value.location?.poiId || hall.value.poiId
|
||||
if (directPoiId) {
|
||||
@@ -148,6 +168,14 @@ const resolveHallGuidePoi = async () => {
|
||||
}) || candidates[0] || null
|
||||
}
|
||||
|
||||
const resolveHallGuidePoiInBackground = () => {
|
||||
void resolveHallGuidePoi()
|
||||
.then(applyMatchedHallPoi)
|
||||
.catch((err) => {
|
||||
console.warn('展厅三维位置后台匹配失败:', err)
|
||||
})
|
||||
}
|
||||
|
||||
onLoad(async (options: any = {}) => {
|
||||
const tab = Array.isArray(options.tab) ? options.tab[0] : options.tab
|
||||
if (isGuideTopTab(tab)) {
|
||||
@@ -173,25 +201,8 @@ onLoad(async (options: any = {}) => {
|
||||
hall.value = toHallDetailViewModel(hallData)
|
||||
const hallExhibits = await explainUseCase.listExhibitsByHallId(hallData.id)
|
||||
exhibits.value = hallExhibits.map(toExplainExhibitViewModel)
|
||||
|
||||
const matchedPoi = await resolveHallGuidePoi()
|
||||
if (matchedPoi) {
|
||||
resolvedHallPoiId.value = matchedPoi.id
|
||||
hall.value = {
|
||||
...hall.value,
|
||||
poiId: matchedPoi.id,
|
||||
location: hall.value.location || {
|
||||
status: 'exact',
|
||||
poiId: matchedPoi.id,
|
||||
sourcePoiId: matchedPoi.id,
|
||||
actionText: '查看三维位置',
|
||||
previewOnly: true,
|
||||
floorId: matchedPoi.floorId,
|
||||
floorLabel: matchedPoi.floorLabel,
|
||||
note: '已定位到该展厅的三维点位。'
|
||||
}
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
resolveHallGuidePoiInBackground()
|
||||
} catch (err) {
|
||||
console.error('加载展厅讲解失败:', err)
|
||||
error.value = '展厅讲解加载失败,请稍后重试'
|
||||
@@ -224,20 +235,7 @@ const handleNavigate = async () => {
|
||||
}
|
||||
|
||||
resolvedHallPoiId.value = matchedPoi.id
|
||||
hall.value = {
|
||||
...hall.value,
|
||||
poiId: matchedPoi.id,
|
||||
location: hall.value.location || {
|
||||
status: 'exact',
|
||||
poiId: matchedPoi.id,
|
||||
sourcePoiId: matchedPoi.id,
|
||||
actionText: '查看三维位置',
|
||||
previewOnly: true,
|
||||
floorId: matchedPoi.floorId,
|
||||
floorLabel: matchedPoi.floorLabel,
|
||||
note: '已定位到该展厅的三维点位。'
|
||||
}
|
||||
}
|
||||
applyMatchedHallPoi(matchedPoi)
|
||||
|
||||
uni.navigateTo({
|
||||
url: `/pages/route/detail?facilityId=${encodeURIComponent(matchedPoi.id)}&target=${encodeURIComponent(hall.value.name)}&state=preview`
|
||||
|
||||
Reference in New Issue
Block a user