外露导览与来馆快捷入口
This commit is contained in:
@@ -39,8 +39,6 @@
|
|||||||
tools-bottom="54px"
|
tools-bottom="54px"
|
||||||
show-zoom-controls
|
show-zoom-controls
|
||||||
zoom-controls-top="calc(100vh - 284px)"
|
zoom-controls-top="calc(100vh - 284px)"
|
||||||
show-more-control
|
|
||||||
more-control-bottom="54px"
|
|
||||||
:route-preview="activeRoutePreview"
|
:route-preview="activeRoutePreview"
|
||||||
:show-route="Boolean(activeRoutePreview)"
|
:show-route="Boolean(activeRoutePreview)"
|
||||||
:auto-switch-threshold-low="0.58"
|
:auto-switch-threshold-low="0.58"
|
||||||
@@ -52,7 +50,6 @@
|
|||||||
@indoor-view-change="handleIndoorViewChange"
|
@indoor-view-change="handleIndoorViewChange"
|
||||||
@poi-click="handleGuidePoiClick"
|
@poi-click="handleGuidePoiClick"
|
||||||
@selection-clear="handleGuideSelectionClear"
|
@selection-clear="handleGuideSelectionClear"
|
||||||
@more-click="handleGuideMoreClick"
|
|
||||||
@auto-switch="handleAutoSwitch"
|
@auto-switch="handleAutoSwitch"
|
||||||
@map-tap="handleMapTapForOutdoorNav"
|
@map-tap="handleMapTapForOutdoorNav"
|
||||||
>
|
>
|
||||||
@@ -110,25 +107,14 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view
|
<view
|
||||||
v-if="showGuideMoreMenu && !showRoutePlanner"
|
v-if="showGuideQuickActions"
|
||||||
class="guide-more-popover"
|
class="guide-quick-actions"
|
||||||
@touchstart.stop="handleGuideMoreTouchStart"
|
|
||||||
@touchmove.stop="handleGuideMoreTouchMove"
|
|
||||||
@touchend.stop="handleGuideMoreTouchEnd"
|
|
||||||
@mousedown.stop="handleGuideMoreMouseStart"
|
|
||||||
@mousemove.stop="handleGuideMoreMouseMove"
|
|
||||||
@mouseup.stop="handleGuideMoreMouseEnd"
|
|
||||||
>
|
>
|
||||||
<view class="more-popover-handle" @tap.stop="closeGuideMoreMenu"></view>
|
<view class="guide-quick-action primary" @tap="handleMoreRouteGuide">
|
||||||
<view class="more-popover-grid">
|
<text class="guide-quick-action-text primary">室内导览</text>
|
||||||
<view class="more-action" @tap="handleMoreRouteGuide">
|
</view>
|
||||||
<text class="more-action-title">{{ routePlannerEntryTitle }}</text>
|
<view class="guide-quick-action" @tap="handleMoreOutdoorNav">
|
||||||
<text class="more-action-desc">{{ routePlannerEntryDesc }}</text>
|
<text class="guide-quick-action-text">来馆</text>
|
||||||
</view>
|
|
||||||
<view class="more-action" @tap="handleMoreOutdoorNav">
|
|
||||||
<text class="more-action-title">来馆</text>
|
|
||||||
<text class="more-action-desc">导航到博物馆</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -313,11 +299,8 @@ const routePlanError = ref('')
|
|||||||
const routePreviewUnavailableMessage = ref('')
|
const routePreviewUnavailableMessage = ref('')
|
||||||
const routeReady = ref(false)
|
const routeReady = ref(false)
|
||||||
const activeRoutePreview = ref<GuideRouteResult | null>(null)
|
const activeRoutePreview = ref<GuideRouteResult | null>(null)
|
||||||
const showGuideMoreMenu = ref(false)
|
|
||||||
const isSimulatingRoute = ref(false)
|
const isSimulatingRoute = ref(false)
|
||||||
const isPoiCardCollapsed = ref(false)
|
const isPoiCardCollapsed = ref(false)
|
||||||
const guideMoreTouchStartY = ref(0)
|
|
||||||
const guideMoreTouchCurrentY = ref(0)
|
|
||||||
|
|
||||||
// GuideMapShell 组件引用,用于显式调用路线清除方法
|
// GuideMapShell 组件引用,用于显式调用路线清除方法
|
||||||
const guideMapShellRef = ref<{
|
const guideMapShellRef = ref<{
|
||||||
@@ -359,10 +342,12 @@ const routePlanSummary = computed(() => {
|
|||||||
|
|
||||||
const routePanelError = computed(() => routePlanError.value)
|
const routePanelError = computed(() => routePlanError.value)
|
||||||
|
|
||||||
const routePlannerEntryTitle = computed(() => '室内导览')
|
const showGuideQuickActions = computed(() => (
|
||||||
|
currentTab.value === 'guide'
|
||||||
const routePlannerEntryDesc = computed(() => (
|
&& !showRoutePlanner.value
|
||||||
routeReady.value ? '开始路线规划' : '查看室内位置'
|
&& !showOutdoorNavPanel.value
|
||||||
|
&& !selectedGuidePoi.value
|
||||||
|
&& !isSimulatingRoute.value
|
||||||
))
|
))
|
||||||
|
|
||||||
const toRoutePointOption = (target: GuideRouteTarget): RoutePointOption => ({
|
const toRoutePointOption = (target: GuideRouteTarget): RoutePointOption => ({
|
||||||
@@ -432,7 +417,6 @@ const handleTabChange = (tabId: GuideTopTab) => {
|
|||||||
console.log('切换标签:', tabId)
|
console.log('切换标签:', tabId)
|
||||||
|
|
||||||
// 关闭可能打开的面板
|
// 关闭可能打开的面板
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
isSimulatingRoute.value = false
|
isSimulatingRoute.value = false
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
@@ -449,7 +433,6 @@ const syncTopTabFromHash = () => {
|
|||||||
currentTab.value = tab
|
currentTab.value = tab
|
||||||
loadTopTabData(tab)
|
loadTopTabData(tab)
|
||||||
if (tabChanged) {
|
if (tabChanged) {
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
isSimulatingRoute.value = false
|
isSimulatingRoute.value = false
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
@@ -625,7 +608,6 @@ const handleGuidePoiClick = (poi: GuideRenderPoi) => {
|
|||||||
selectedGuidePoi.value = poi
|
selectedGuidePoi.value = poi
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
indoorView.value = 'floor'
|
indoorView.value = 'floor'
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
isSimulatingRoute.value = false
|
isSimulatingRoute.value = false
|
||||||
const matchedFloor = guideFloors.value.find((floor) => floor.id === poi.floorId)
|
const matchedFloor = guideFloors.value.find((floor) => floor.id === poi.floorId)
|
||||||
activeGuideFloor.value = matchedFloor?.label || poi.floorId
|
activeGuideFloor.value = matchedFloor?.label || poi.floorId
|
||||||
@@ -682,7 +664,6 @@ const handlePreviewSelectedPoi = () => {
|
|||||||
if (!selectedGuidePoi.value) return
|
if (!selectedGuidePoi.value) return
|
||||||
indoorView.value = 'floor'
|
indoorView.value = 'floor'
|
||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
isSimulatingRoute.value = false
|
isSimulatingRoute.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,7 +720,6 @@ const openRoutePlanner = () => {
|
|||||||
is3DMode.value = true
|
is3DMode.value = true
|
||||||
indoorView.value = indoorView.value === 'overview' ? 'floor' : indoorView.value
|
indoorView.value = indoorView.value === 'overview' ? 'floor' : indoorView.value
|
||||||
guideOutdoorState.value = 'home'
|
guideOutdoorState.value = 'home'
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
isSimulatingRoute.value = false
|
isSimulatingRoute.value = false
|
||||||
if (!routePointOptions.value.length) {
|
if (!routePointOptions.value.length) {
|
||||||
@@ -850,7 +830,6 @@ const handleRouteSimulate = () => {
|
|||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
selectedGuidePoi.value = null
|
selectedGuidePoi.value = null
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
isSimulatingRoute.value = true
|
isSimulatingRoute.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,7 +839,6 @@ const handleEnter3DMode = () => {
|
|||||||
indoorView.value = 'overview'
|
indoorView.value = 'overview'
|
||||||
is3DMode.value = true
|
is3DMode.value = true
|
||||||
guideOutdoorState.value = 'home'
|
guideOutdoorState.value = 'home'
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
if (!routePointOptions.value.length) {
|
if (!routePointOptions.value.length) {
|
||||||
void loadRouteTargets()
|
void loadRouteTargets()
|
||||||
}
|
}
|
||||||
@@ -875,7 +853,6 @@ const handleModeChange = (mode: '2d' | '3d') => {
|
|||||||
selectedGuidePoi.value = null
|
selectedGuidePoi.value = null
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
isSimulatingRoute.value = false
|
isSimulatingRoute.value = false
|
||||||
clearRoutePreviewState()
|
clearRoutePreviewState()
|
||||||
} else {
|
} else {
|
||||||
@@ -904,60 +881,6 @@ const handleSwitchEntrance = () => {
|
|||||||
guideOutdoorState.value = 'home'
|
guideOutdoorState.value = 'home'
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleGuideMoreClick = () => {
|
|
||||||
showGuideMoreMenu.value = !showGuideMoreMenu.value
|
|
||||||
selectedGuidePoi.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeGuideMoreMenu = () => {
|
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
showOutdoorNavPanel.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const getGestureClientY = (event: TouchEvent | MouseEvent) => {
|
|
||||||
if ('changedTouches' in event) {
|
|
||||||
return event.changedTouches?.[0]?.clientY
|
|
||||||
?? event.touches?.[0]?.clientY
|
|
||||||
?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return event.clientY
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGuideMoreTouchStart = (event: TouchEvent) => {
|
|
||||||
const clientY = getGestureClientY(event)
|
|
||||||
guideMoreTouchStartY.value = clientY
|
|
||||||
guideMoreTouchCurrentY.value = clientY
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGuideMoreTouchMove = (event: TouchEvent) => {
|
|
||||||
guideMoreTouchCurrentY.value = getGestureClientY(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGuideMoreTouchEnd = (event: TouchEvent) => {
|
|
||||||
guideMoreTouchCurrentY.value = getGestureClientY(event)
|
|
||||||
if (guideMoreTouchCurrentY.value - guideMoreTouchStartY.value > 48) {
|
|
||||||
closeGuideMoreMenu()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGuideMoreMouseStart = (event: MouseEvent) => {
|
|
||||||
const clientY = getGestureClientY(event)
|
|
||||||
guideMoreTouchStartY.value = clientY
|
|
||||||
guideMoreTouchCurrentY.value = clientY
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGuideMoreMouseMove = (event: MouseEvent) => {
|
|
||||||
guideMoreTouchCurrentY.value = getGestureClientY(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGuideMoreMouseEnd = (event: MouseEvent) => {
|
|
||||||
guideMoreTouchCurrentY.value = getGestureClientY(event)
|
|
||||||
if (guideMoreTouchCurrentY.value - guideMoreTouchStartY.value > 48) {
|
|
||||||
closeGuideMoreMenu()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleMoreRouteGuide = () => {
|
const handleMoreRouteGuide = () => {
|
||||||
openRoutePlanner()
|
openRoutePlanner()
|
||||||
}
|
}
|
||||||
@@ -965,7 +888,6 @@ const handleMoreRouteGuide = () => {
|
|||||||
// 室外导航处理函数
|
// 室外导航处理函数
|
||||||
const openOutdoorNavPanel = () => {
|
const openOutdoorNavPanel = () => {
|
||||||
showOutdoorNavPanel.value = true
|
showOutdoorNavPanel.value = true
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
selectedGuidePoi.value = null
|
selectedGuidePoi.value = null
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
@@ -1159,7 +1081,6 @@ const handleExplainBack = () => {
|
|||||||
currentTab.value = 'guide'
|
currentTab.value = 'guide'
|
||||||
syncTopTabToUrl('guide')
|
syncTopTabToUrl('guide')
|
||||||
loadTopTabData('guide')
|
loadTopTabData('guide')
|
||||||
showGuideMoreMenu.value = false
|
|
||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
isSimulatingRoute.value = false
|
isSimulatingRoute.value = false
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
@@ -1177,8 +1098,7 @@ const handleExplainBack = () => {
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.guide-poi-card,
|
.guide-poi-card {
|
||||||
.guide-more-popover {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
@@ -1199,8 +1119,7 @@ const handleExplainBack = () => {
|
|||||||
padding: 8px 10px 10px;
|
padding: 8px 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.poi-card-handle,
|
.poi-card-handle {
|
||||||
.more-popover-handle {
|
|
||||||
width: 38px;
|
width: 38px;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
margin: 0 auto 10px;
|
margin: 0 auto 10px;
|
||||||
@@ -1342,42 +1261,46 @@ const handleExplainBack = () => {
|
|||||||
color: var(--museum-accent);
|
color: var(--museum-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.guide-more-popover {
|
.guide-quick-actions {
|
||||||
padding: 10px 12px 12px;
|
position: absolute;
|
||||||
}
|
right: 18px;
|
||||||
|
bottom: calc(env(safe-area-inset-bottom) + 54px);
|
||||||
.more-popover-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.more-action {
|
|
||||||
min-height: 64px;
|
|
||||||
padding: 10px 8px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
align-items: stretch;
|
||||||
gap: 4px;
|
gap: 10px;
|
||||||
box-sizing: border-box;
|
z-index: 1002;
|
||||||
background: #f6f7f4;
|
|
||||||
border: 1px solid #e5e6de;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-action-title {
|
.guide-quick-action {
|
||||||
font-size: 14px;
|
width: 84px;
|
||||||
line-height: 20px;
|
min-height: 38px;
|
||||||
font-weight: 700;
|
padding: 0 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
border: 1px solid #dde5df;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 8px 18px rgba(110, 127, 115, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-quick-action.primary {
|
||||||
|
background: #151713;
|
||||||
|
border-color: #151713;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-quick-action-text {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 18px;
|
||||||
|
font-weight: 600;
|
||||||
color: #151713;
|
color: #151713;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-action-desc {
|
.guide-quick-action-text.primary {
|
||||||
font-size: 11px;
|
color: var(--museum-accent);
|
||||||
line-height: 15px;
|
|
||||||
color: #696962;
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.route-sim-top-pill {
|
.route-sim-top-pill {
|
||||||
|
|||||||
Reference in New Issue
Block a user