修复导览与讲解位置预览逻辑

This commit is contained in:
lyf
2026-06-30 11:00:49 +08:00
parent f2a33888b1
commit 1c2cc788d1
29 changed files with 1111 additions and 756 deletions

View File

@@ -14,7 +14,7 @@
<text class="hall-meta">{{ hall.floorLabel }} · {{ explainCountText }}</text>
<view
class="location-action"
:class="{ disabled: !hall.poiId }"
:class="{ disabled: !hallLocationPoiId }"
@tap="handleNavigate"
>
<svg class="location-icon" width="16" height="16" viewBox="0 0 24 24" fill="none">
@@ -99,6 +99,7 @@ import {
const activeTopTab = ref<GuideTopTab>('explain')
const loading = ref(false)
const error = ref('')
const resolvedHallPoiId = ref('')
const hall = ref<HallDetailViewModel>({
id: '',
@@ -116,6 +117,37 @@ const explainCountText = computed(() => (
exhibits.value.length > 0 ? `${exhibits.value.length} 条讲解` : '暂无讲解'
))
const hallLocationPoiId = computed(() => hall.value.poiId || resolvedHallPoiId.value)
const normalizePoiName = (value: string) => value
.trim()
.replace(/[\s()【】[\]_-]/g, '')
.toLowerCase()
// 展厅数据里可能没有直接写入 poiId优先走内容层映射再按展厅名称兜底匹配导览点位。
const resolveHallGuidePoi = async () => {
const directPoiId = hall.value.location?.poiId || hall.value.poiId
if (directPoiId) {
const directPoi = await guideUseCase.getPoiById(directPoiId)
if (directPoi) return directPoi
}
const normalizedTarget = normalizePoiName(hall.value.name)
if (!normalizedTarget) return null
const candidates = await guideUseCase.searchPois(hall.value.name)
return candidates.find((candidate) => {
const candidateName = normalizePoiName(candidate.name)
const candidateHallName = normalizePoiName(candidate.hallName || '')
return candidate.kind === 'hall'
|| candidate.primaryCategory.id === 'exhibition_hall'
|| candidateName === normalizedTarget
|| candidateHallName === normalizedTarget
|| candidateName.includes(normalizedTarget)
|| normalizedTarget.includes(candidateName)
}) || candidates[0] || null
}
onLoad(async (options: any = {}) => {
const tab = Array.isArray(options.tab) ? options.tab[0] : options.tab
if (isGuideTopTab(tab)) {
@@ -141,6 +173,25 @@ 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: '已定位到该展厅的三维点位。'
}
}
}
} catch (err) {
console.error('加载展厅讲解失败:', err)
error.value = '展厅讲解加载失败,请稍后重试'
@@ -163,7 +214,8 @@ const handleExhibitClick = (exhibit: ExplainExhibitViewModel) => {
}
const handleNavigate = async () => {
if (!hall.value.poiId) {
const matchedPoi = await resolveHallGuidePoi()
if (!matchedPoi) {
uni.showToast({
title: '该展厅暂无三维位置数据',
icon: 'none'
@@ -171,17 +223,24 @@ const handleNavigate = async () => {
return
}
const matchedPoi = await guideUseCase.getPoiById(hall.value.poiId)
if (!matchedPoi) {
uni.showToast({
title: '该展厅位置尚未映射到当前三维导览资源',
icon: 'none'
})
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: '已定位到该展厅的三维点位。'
}
}
uni.navigateTo({
url: `/pages/route/detail?facilityId=${encodeURIComponent(hall.value.poiId)}&target=${encodeURIComponent(hall.value.name)}&state=preview`
url: `/pages/route/detail?facilityId=${encodeURIComponent(matchedPoi.id)}&target=${encodeURIComponent(hall.value.name)}&state=preview`
})
}