Compare commits
2 Commits
d165e17b4d
...
6a0fa61c8e
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a0fa61c8e | |||
| 1fa1ac2906 |
@@ -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">
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user