feat: add explain guide stop page
This commit is contained in:
@@ -30,6 +30,22 @@
|
|||||||
"navigationStyle": "custom"
|
"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",
|
"path": "pages/hall/detail",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
160
src/pages/explain/guide-stop-list.vue
Normal file
160
src/pages/explain/guide-stop-list.vue
Normal 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>
|
||||||
Reference in New Issue
Block a user