Compare commits

...

2 Commits

Author SHA1 Message Date
lyf
6a0fa61c8e 优化首页点位搜索收缩态布局
Some checks failed
CI / verify (push) Has been cancelled
2026-07-09 01:28:58 +08:00
lyf
1fa1ac2906 隐藏腾讯地图鉴权页面提示 2026-07-09 00:51:16 +08:00
3 changed files with 185 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
<template> <template>
<view class="map-component"> <view ref="mapComponentRef" class="map-component">
<map <map
id="museum-map" id="museum-map"
class="map" class="map"
@@ -59,7 +59,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, onMounted } from 'vue' import { computed, ref, onBeforeUnmount, onMounted, nextTick } from 'vue'
import { getMuseumEntranceLocation } from '@/services/tencent/TencentMapService' import { getMuseumEntranceLocation } from '@/services/tencent/TencentMapService'
const isH5 = typeof window !== 'undefined' const isH5 = typeof window !== 'undefined'
@@ -137,6 +137,10 @@ const mapScale = ref(17)
// 当前楼层 // 当前楼层
const currentFloor = ref(props.activeFloor) const currentFloor = ref(props.activeFloor)
const mapComponentRef = ref<unknown>(null)
let mapAuthErrorObserver: MutationObserver | null = null
let mapAuthErrorLogged = false
const mapAuthErrorText = '鉴权失败请传入正确的key'
// 楼层列表 // 楼层列表
const floors = computed(() => props.floors) const floors = computed(() => props.floors)
@@ -384,7 +388,81 @@ const handleEnter3D = () => {
emit('enter3DMode') emit('enter3DMode')
} }
const getMapComponentElement = () => {
const rawRef = mapComponentRef.value
if (rawRef instanceof HTMLElement) return rawRef
const maybeComponent = rawRef as { $el?: Element } | null
if (maybeComponent?.$el instanceof HTMLElement) return maybeComponent.$el
if (typeof document === 'undefined') return null
return document.querySelector<HTMLElement>('.map-component')
}
const hideAuthErrorElement = (element: Element) => {
const target = element instanceof HTMLElement ? element : element.parentElement
if (!target) return
target.style.setProperty('display', 'none', 'important')
target.style.setProperty('visibility', 'hidden', 'important')
target.style.setProperty('opacity', '0', 'important')
target.style.setProperty('pointer-events', 'none', 'important')
target.setAttribute('aria-hidden', 'true')
}
const hasDirectAuthErrorText = (element: Element) => {
return Array.from(element.childNodes).some((node) => (
node.nodeType === Node.TEXT_NODE
&& (node.textContent || '').trim() === mapAuthErrorText
))
}
const detectAndHideMapAuthError = () => {
const root = getMapComponentElement()
if (!root) return
const text = root.textContent || ''
if (!text.includes('鉴权失败')) return
root.querySelectorAll('*').forEach((element) => {
const elementText = (element.textContent || '').trim()
if (elementText === mapAuthErrorText && hasDirectAuthErrorText(element)) {
hideAuthErrorElement(element)
}
})
if (!mapAuthErrorLogged) {
mapAuthErrorLogged = true
console.error('腾讯地图鉴权失败,已隐藏页面内置错误提示:', text.trim())
}
}
const startMapAuthErrorMonitor = () => {
if (typeof window === 'undefined') return
void nextTick(() => {
detectAndHideMapAuthError()
const root = getMapComponentElement()
if (!root || typeof MutationObserver === 'undefined') return
mapAuthErrorObserver = new MutationObserver(() => {
detectAndHideMapAuthError()
})
mapAuthErrorObserver.observe(root, {
childList: true,
subtree: true,
characterData: true
})
window.setTimeout(detectAndHideMapAuthError, 600)
window.setTimeout(detectAndHideMapAuthError, 1600)
window.setTimeout(detectAndHideMapAuthError, 3000)
})
}
onMounted(async () => { onMounted(async () => {
startMapAuthErrorMonitor()
console.log('地图组件已挂载,开始获取入口位置...') console.log('地图组件已挂载,开始获取入口位置...')
// 从腾讯地图 API 获取入口位置 // 从腾讯地图 API 获取入口位置
@@ -399,6 +477,11 @@ onMounted(async () => {
console.log('已更新入口位置:', entranceLocation) console.log('已更新入口位置:', entranceLocation)
} }
}) })
onBeforeUnmount(() => {
mapAuthErrorObserver?.disconnect()
mapAuthErrorObserver = null
})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -1,7 +1,7 @@
<template> <template>
<view <view
class="poi-search-panel" class="poi-search-panel"
:class="[`variant-${variant}`, { expanded: showSearchContent }]" :class="[`variant-${variant}`, { expanded: showSearchContent, 'is-collapsed': isHomeCollapsed }]"
@touchstart="handlePanelTouchStart" @touchstart="handlePanelTouchStart"
@touchend="handlePanelTouchEnd" @touchend="handlePanelTouchEnd"
@touchcancel="resetPanelTouch" @touchcancel="resetPanelTouch"
@@ -237,6 +237,7 @@ const initialSpaceLoadError = ref('')
let searchRequestSeq = 0 let searchRequestSeq = 0
const showSearchContent = computed(() => props.variant === 'page' || homeExpanded.value) const showSearchContent = computed(() => props.variant === 'page' || homeExpanded.value)
const isHomeCollapsed = computed(() => props.variant === 'home' && !showSearchContent.value)
const collapseDragThreshold = 48 const collapseDragThreshold = 48
const homeExpandTapGuardMs = 360 const homeExpandTapGuardMs = 360
@@ -833,6 +834,13 @@ defineExpose({
box-shadow: none; box-shadow: none;
} }
.variant-home.is-collapsed .search-box {
height: 38px;
flex-basis: 38px;
padding: 0 12px;
border-radius: 7px;
}
.home-category-strip { .home-category-strip {
margin-top: 10px; margin-top: 10px;
display: flex; display: flex;
@@ -844,6 +852,12 @@ defineExpose({
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
} }
.variant-home.is-collapsed .home-category-strip {
margin-top: 7px;
gap: 7px;
padding-bottom: 1px;
}
.home-category-strip::-webkit-scrollbar { .home-category-strip::-webkit-scrollbar {
display: none; display: none;
} }
@@ -867,6 +881,17 @@ defineExpose({
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.16); box-shadow: 0 8px 18px rgba(0, 0, 0, 0.16);
} }
.variant-home.is-collapsed .home-category-chip {
min-width: 76px;
height: 42px;
flex-basis: 76px;
justify-content: center;
gap: 5px;
padding: 0 7px;
border-radius: 7px;
box-shadow: none;
}
.home-category-chip:nth-child(2) { .home-category-chip:nth-child(2) {
background-color: #18c2b6; background-color: #18c2b6;
} }
@@ -917,6 +942,17 @@ defineExpose({
transform-origin: center; transform-origin: center;
} }
.variant-home.is-collapsed .home-category-icon,
.variant-home.is-collapsed .home-category-icon.line-icon {
width: 20px;
height: 19px;
flex-basis: 20px;
}
.variant-home.is-collapsed .home-category-icon .icon-part {
transform: scale(0.68);
}
.home-category-label { .home-category-label {
min-width: 0; min-width: 0;
max-width: 70px; max-width: 70px;
@@ -929,6 +965,12 @@ defineExpose({
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.variant-home.is-collapsed .home-category-label {
max-width: 42px;
font-size: 11px;
line-height: 14px;
}
.search-icon { .search-icon {
width: 19px; width: 19px;
height: 19px; height: 19px;
@@ -952,6 +994,19 @@ defineExpose({
transform: rotate(45deg); transform: rotate(45deg);
} }
.variant-home.is-collapsed .search-icon {
width: 17px;
height: 17px;
margin-right: 11px;
border-width: 2px;
}
.variant-home.is-collapsed .search-icon::after {
right: -6px;
bottom: -4px;
width: 9px;
}
.search-input { .search-input {
min-width: 0; min-width: 0;
flex: 1; flex: 1;
@@ -968,10 +1023,21 @@ defineExpose({
line-height: 22px; line-height: 22px;
} }
.variant-home.is-collapsed .search-input,
.variant-home.is-collapsed .search-input :deep(input),
.variant-home.is-collapsed .search-input :deep(.uni-input-input) {
font-size: 14px;
line-height: 19px;
}
.search-placeholder { .search-placeholder {
color: #8b8d85; color: #8b8d85;
} }
.variant-home.is-collapsed .search-placeholder {
font-size: 14px;
}
.clear-button, .clear-button,
.voice-icon { .voice-icon {
width: 26px; width: 26px;
@@ -987,6 +1053,17 @@ defineExpose({
background: #eef0e8; background: #eef0e8;
} }
.variant-home.is-collapsed .clear-button,
.variant-home.is-collapsed .voice-icon {
width: 32px;
height: 32px;
}
.variant-home.is-collapsed .clear-text {
font-size: 17px;
line-height: 18px;
}
.clear-text { .clear-text {
font-size: 18px; font-size: 18px;
line-height: 20px; line-height: 20px;
@@ -997,6 +1074,20 @@ defineExpose({
position: relative; position: relative;
} }
.variant-home.is-collapsed .voice-icon::before {
left: 11px;
top: 7px;
width: 10px;
height: 13px;
}
.variant-home.is-collapsed .voice-icon::after {
left: 10px;
bottom: 6px;
width: 12px;
height: 7px;
}
.voice-icon::before { .voice-icon::before {
content: ''; content: '';
position: absolute; position: absolute;

View File

@@ -1779,17 +1779,17 @@ const handleExplainBack = () => {
--museum-h5-page-width: min(100vw, 430px); --museum-h5-page-width: min(100vw, 430px);
left: 50%; left: 50%;
right: auto; right: auto;
width: calc(var(--museum-h5-page-width) - 24px); width: calc(var(--museum-h5-page-width) - 20px);
bottom: calc(env(safe-area-inset-bottom) + 14px); bottom: calc(env(safe-area-inset-bottom) + 10px);
padding: 10px; padding: 7px;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden; overflow: hidden;
background: background:
linear-gradient(180deg, rgba(224, 225, 0, 0.22) 0, rgba(224, 225, 0, 0) 58px), linear-gradient(180deg, rgba(224, 225, 0, 0.18) 0, rgba(224, 225, 0, 0) 46px),
#060704; #060704;
border: 1px solid rgba(224, 225, 0, 0.34); border: 1px solid rgba(224, 225, 0, 0.34);
border-radius: 8px; border-radius: 8px;
box-shadow: 0 18px 38px rgba(0, 0, 0, 0.34); box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
transform: translateX(-50%); transform: translateX(-50%);
z-index: 1003; z-index: 1003;
} }
@@ -1797,10 +1797,10 @@ const handleExplainBack = () => {
.guide-home-dock::before { .guide-home-dock::before {
content: ''; content: '';
position: absolute; position: absolute;
left: 10px; left: 7px;
right: 10px; right: 7px;
top: 0; top: 0;
height: 4px; height: 3px;
background: var(--museum-accent); background: var(--museum-accent);
} }