feat: add explain guide stop page

This commit is contained in:
lyf
2026-07-10 15:56:40 +08:00
parent 3eeeccd635
commit 764146338a
2 changed files with 176 additions and 0 deletions

View File

@@ -30,6 +30,22 @@
"navigationStyle": "custom"
}
},
{
"path": "pages/explain/business-unit-list",
"style": {
"navigationBarTitleText": "业务单元",
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom"
}
},
{
"path": "pages/explain/guide-stop-list",
"style": {
"navigationBarTitleText": "讲解点",
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom"
}
},
{
"path": "pages/hall/detail",
"style": {

View File

@@ -0,0 +1,160 @@
<template>
<GuidePageFrame
active-tab="explain"
variant="static"
:show-top-tabs="false"
show-back
@tab-change="handleTopTabChange"
@back="handleBack"
>
<view class="explain-guide-stop-page">
<ExplainHallSelect
:guide-stops="explainGuideStopItems"
stage="stop"
:selected-business-unit-name="selectedExplainBusinessUnitName"
:loading="explainLoading"
:error="explainError"
@guide-stop-click="handleExplainGuideStopClick"
@back="handleBack"
/>
</view>
</GuidePageFrame>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import GuidePageFrame from '@/components/navigation/GuidePageFrame.vue'
import ExplainHallSelect, {
type ExplainGuideStopSelectItem
} from '@/components/explain/ExplainHallSelect.vue'
import {
explainUseCase
} from '@/usecases/explainUseCase'
import type {
ExplainBusinessUnit
} from '@/domain/museum'
import {
normalizeExplainDetailTargetFromGuideStop
} from '@/domain/explainDetailTarget'
import {
navigateToGuideTopTab,
type GuideTopTab
} from '@/utils/guideTopTabs'
const selectedExplainHallId = ref('')
const selectedExplainHallName = ref('')
const selectedExplainBusinessUnitId = ref('')
const selectedExplainBusinessUnitName = ref('')
const explainGuideStopItems = ref<ExplainGuideStopSelectItem[]>([])
const explainLoading = ref(false)
const explainError = ref('')
const toGuideStopItems = (unit: ExplainBusinessUnit): ExplainGuideStopSelectItem[] => (
unit.stops.map((stop) => ({
id: stop.id,
name: stop.name,
hallId: stop.hallId,
hallName: stop.hallName,
floorId: stop.floorId,
poiId: stop.poiId,
mapX: stop.mapX,
mapY: stop.mapY,
coverImageUrl: stop.coverImageUrl,
description: stop.description,
hasAudio: stop.hasAudio,
audioStatus: stop.audioStatus,
guideLevel: stop.guideLevel,
playTargetType: stop.playTargetType,
playTargetId: stop.playTargetId
}))
)
const syncPageTitle = (title: string) => {
uni.setNavigationBarTitle({ title })
if (typeof document !== 'undefined') document.title = title
}
onLoad(async (options: any = {}) => {
selectedExplainHallId.value = Array.isArray(options.hallId) ? options.hallId[0] : options.hallId || ''
selectedExplainHallName.value = Array.isArray(options.hallName) ? options.hallName[0] : options.hallName || ''
selectedExplainBusinessUnitId.value = Array.isArray(options.unitId) ? options.unitId[0] : options.unitId || ''
selectedExplainBusinessUnitName.value = Array.isArray(options.unitName) ? options.unitName[0] : options.unitName || '讲解点'
syncPageTitle(selectedExplainBusinessUnitName.value)
if (!selectedExplainHallId.value || !selectedExplainBusinessUnitId.value) {
explainError.value = '缺少业务单元参数,请返回上一级后重试'
return
}
explainLoading.value = true
try {
const unit = await explainUseCase.selectBusinessUnit(
selectedExplainHallId.value,
selectedExplainBusinessUnitId.value
)
if (!unit) {
explainError.value = '未找到对应业务单元,请返回上一级后重试'
return
}
selectedExplainBusinessUnitName.value = unit.name || selectedExplainBusinessUnitName.value
syncPageTitle(selectedExplainBusinessUnitName.value)
explainGuideStopItems.value = toGuideStopItems(unit)
} catch (error) {
explainError.value = '讲解点加载失败,请稍后重试'
} finally {
explainLoading.value = false
}
})
const handleExplainGuideStopClick = (stop: ExplainGuideStopSelectItem) => {
const target = stop.playTargetType && stop.playTargetId
? { targetType: stop.playTargetType, targetId: stop.playTargetId }
: normalizeExplainDetailTargetFromGuideStop({ id: stop.id })
const params = new URLSearchParams({
id: stop.id,
tab: 'explain',
targetType: target.targetType,
targetId: target.targetId
})
uni.navigateTo({
url: `/pages/exhibit/detail?${params.toString()}`
})
}
const goBackToBusinessUnitList = () => {
const params = new URLSearchParams({
hallId: selectedExplainHallId.value,
hallName: selectedExplainHallName.value
})
uni.redirectTo({
url: `/pages/explain/business-unit-list?${params.toString()}`,
fail: () => {
uni.reLaunch({ url: `/pages/explain/business-unit-list?${params.toString()}` })
}
})
}
const handleBack = () => {
uni.navigateBack({
delta: 1,
fail: goBackToBusinessUnitList
})
}
const handleTopTabChange = (tab: GuideTopTab) => {
navigateToGuideTopTab(tab)
}
</script>
<style scoped lang="scss">
.explain-guide-stop-page {
position: absolute;
inset: 0;
background: #edf0ea;
}
</style>