chore: solidify guide P1 snapshot
This commit is contained in:
@@ -1,18 +1,9 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<view class="content-tabs">
|
||||
<view
|
||||
v-for="tab in contentTabs"
|
||||
:key="tab.id"
|
||||
class="content-tab"
|
||||
:class="{ active: currentTab === tab.id }"
|
||||
@tap="handleTabChange(tab.id)"
|
||||
>
|
||||
<view v-if="currentTab === tab.id" class="content-tab-indicator"></view>
|
||||
<text class="content-tab-label">{{ tab.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<GuidePageFrame
|
||||
:active-tab="currentTab"
|
||||
variant="overlay"
|
||||
@tab-change="handleTabChange"
|
||||
>
|
||||
<GuideMapShell
|
||||
v-if="currentTab === 'guide'"
|
||||
:search-text="guideSearchText"
|
||||
@@ -25,10 +16,18 @@
|
||||
:map-type="guideMapType"
|
||||
:outdoor-variant="guideOutdoorVariant"
|
||||
:indoor-asset-base-url="indoorNavAssetBaseUrl"
|
||||
:show-floor="false"
|
||||
indoor-initial-view="overview"
|
||||
:indoor-view="indoorView"
|
||||
:active-floor="activeGuideFloor"
|
||||
indoor-view-toggle-top="154px"
|
||||
floor-top="244px"
|
||||
:show-indoor-view-toggle="is3DMode"
|
||||
:show-floor="is3DMode && indoorView === 'floor'"
|
||||
:tools="[]"
|
||||
@search-tap="handleGuideSearchTap"
|
||||
@mode-change="handleModeChange"
|
||||
@floor-change="handleFloorChange"
|
||||
@indoor-view-change="handleIndoorViewChange"
|
||||
>
|
||||
<template #overlay>
|
||||
<view v-if="guideOutdoorState === 'entrance' && !is3DMode" class="entrance-tip">
|
||||
@@ -66,7 +65,7 @@
|
||||
<view v-if="guideOutdoorState === 'entrance' && !is3DMode" class="entrance-bottom-card">
|
||||
<text class="entrance-card-title">主入口</text>
|
||||
<text class="entrance-card-desc">
|
||||
可到达入口后自动切换,也可手动进入室内3D并选择楼层/区域。
|
||||
可参考主入口位置,也可手动进入室内3D并选择楼层/区域。
|
||||
</text>
|
||||
<view class="entrance-actions">
|
||||
<view class="entrance-btn secondary" @tap="handleSwitchEntrance">
|
||||
@@ -102,15 +101,21 @@
|
||||
@pause="handleAudioPause"
|
||||
@ended="handleAudioEnded"
|
||||
/>
|
||||
</view>
|
||||
</GuidePageFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import GuidePageFrame from '@/components/navigation/GuidePageFrame.vue'
|
||||
import GuideMapShell from '@/components/navigation/GuideMapShell.vue'
|
||||
import ExplainList from '@/components/explain/ExplainList.vue'
|
||||
import FloatingAudioButton from '@/components/audio/FloatingAudioButton.vue'
|
||||
import AudioPlayer, { type AudioItem } from '@/components/audio/AudioPlayer.vue'
|
||||
import {
|
||||
isGuideTopTab,
|
||||
type GuideTopTab
|
||||
} from '@/utils/guideTopTabs'
|
||||
import {
|
||||
NAV_ASSET_BASE_URL,
|
||||
NAV_ROUTE_UNAVAILABLE_MESSAGE
|
||||
@@ -119,20 +124,17 @@ import {
|
||||
// 3D 模式状态
|
||||
const is3DMode = ref(false)
|
||||
const guideOutdoorState = ref<'home' | 'entrance'>('home')
|
||||
const indoorView = ref<'overview' | 'floor'>('overview')
|
||||
const activeGuideFloor = ref('1F')
|
||||
|
||||
// 状态
|
||||
const searchKeyword = ref('')
|
||||
const currentTab = ref('guide')
|
||||
const currentTab = ref<GuideTopTab>('guide')
|
||||
const searchBarFocused = ref(false)
|
||||
const showMarkerDetail = ref(false)
|
||||
const showAreaSelector = ref(false)
|
||||
const selectedAreaId = ref('service')
|
||||
|
||||
const contentTabs = [
|
||||
{ id: 'guide', label: '导览' },
|
||||
{ id: 'explain', label: '讲解' }
|
||||
]
|
||||
|
||||
const indoorNavAssetBaseUrl = NAV_ASSET_BASE_URL
|
||||
|
||||
const shortcutItems = [
|
||||
@@ -171,7 +173,7 @@ const markerDataMap: Record<string, MarkerDetail> = {
|
||||
}
|
||||
|
||||
// Tab 切换处理
|
||||
const handleTabChange = (tabId: string) => {
|
||||
const handleTabChange = (tabId: GuideTopTab) => {
|
||||
currentTab.value = tabId
|
||||
console.log('切换标签:', tabId)
|
||||
|
||||
@@ -181,6 +183,13 @@ const handleTabChange = (tabId: string) => {
|
||||
searchBarFocused.value = false
|
||||
}
|
||||
|
||||
onLoad((options: any = {}) => {
|
||||
const tab = Array.isArray(options.tab) ? options.tab[0] : options.tab
|
||||
if (isGuideTopTab(tab)) {
|
||||
currentTab.value = tab
|
||||
}
|
||||
})
|
||||
|
||||
// 搜索处理
|
||||
const handleSearchFocus = () => {
|
||||
searchBarFocused.value = true
|
||||
@@ -284,12 +293,19 @@ const handleCollectMarker = (marker: MarkerDetail) => {
|
||||
}
|
||||
|
||||
const handleFloorChange = (floor: string) => {
|
||||
activeGuideFloor.value = floor
|
||||
indoorView.value = 'floor'
|
||||
console.log('切换楼层:', floor)
|
||||
}
|
||||
|
||||
const handleIndoorViewChange = (view: 'overview' | 'floor') => {
|
||||
indoorView.value = view
|
||||
}
|
||||
|
||||
// 进入 3D 室内模式
|
||||
const handleEnter3DMode = () => {
|
||||
console.log('进入 3D 室内模式')
|
||||
indoorView.value = 'overview'
|
||||
is3DMode.value = true
|
||||
guideOutdoorState.value = 'home'
|
||||
}
|
||||
@@ -298,32 +314,37 @@ const handleModeChange = (mode: '2d' | '3d') => {
|
||||
is3DMode.value = mode === '3d'
|
||||
|
||||
if (mode === '2d') {
|
||||
indoorView.value = 'overview'
|
||||
guideOutdoorState.value = 'home'
|
||||
} else {
|
||||
indoorView.value = 'overview'
|
||||
}
|
||||
}
|
||||
|
||||
const guideStatusLabel = computed(() => {
|
||||
if (is3DMode.value) {
|
||||
return '馆内定位'
|
||||
return indoorView.value === 'overview' ? '室内全馆' : '室内楼层'
|
||||
}
|
||||
|
||||
if (guideOutdoorState.value === 'entrance') {
|
||||
return '推荐入口'
|
||||
}
|
||||
|
||||
return '馆外定位'
|
||||
return '室外参考'
|
||||
})
|
||||
|
||||
const guideTaskTitle = computed(() => {
|
||||
if (is3DMode.value) {
|
||||
return '规划馆内路线'
|
||||
return indoorView.value === 'overview' ? '查看完整建筑' : '查看楼层位置'
|
||||
}
|
||||
return '从室外进入馆内'
|
||||
})
|
||||
|
||||
const guideTaskSubtitle = computed(() => {
|
||||
if (is3DMode.value) {
|
||||
return '选择目标设施后,系统会优先推荐最近路径'
|
||||
return indoorView.value === 'overview'
|
||||
? '切换到楼层后,可查看 POI 与三维位置预览'
|
||||
: '选择目标设施后,可查看楼层与三维位置预览'
|
||||
}
|
||||
|
||||
return ''
|
||||
@@ -413,7 +434,7 @@ const handleAudioEnded = (audio: AudioItem) => {
|
||||
const handleExplainExhibitClick = (exhibit: any) => {
|
||||
console.log('点击讲解展品:', exhibit)
|
||||
uni.navigateTo({
|
||||
url: `/pages/exhibit/detail?id=${exhibit.id}`
|
||||
url: `/pages/exhibit/detail?id=${exhibit.id}&tab=explain`
|
||||
})
|
||||
}
|
||||
|
||||
@@ -438,16 +459,6 @@ const handleExplainFeaturedClick = (exhibit: any) => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
overflow: hidden;
|
||||
isolation: isolate;
|
||||
background: var(--museum-bg-map);
|
||||
}
|
||||
|
||||
.explain-page {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -546,59 +557,6 @@ const handleExplainFeaturedClick = (exhibit: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
.content-tabs {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
border-bottom: 1px solid #eceee8;
|
||||
box-sizing: border-box;
|
||||
z-index: 2000;
|
||||
transform: translateZ(0);
|
||||
backface-visibility: hidden;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.content-tab {
|
||||
position: relative;
|
||||
width: 75px;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.content-tab-label {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
font-weight: 400;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.content-tab.active .content-tab-label {
|
||||
font-weight: 500;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.content-tab-indicator {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 26px;
|
||||
width: 39px;
|
||||
height: 6px;
|
||||
background: var(--museum-accent);
|
||||
border-radius: 3px;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.search-bar-wrapper {
|
||||
position: absolute;
|
||||
top: 44px;
|
||||
@@ -809,11 +767,4 @@ const handleExplainFeaturedClick = (exhibit: any) => {
|
||||
color: var(--museum-accent);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.page-container {
|
||||
max-width: 430px;
|
||||
margin: 0 auto;
|
||||
box-shadow: 0 12px 36px rgba(36, 49, 42, 0.16);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user