修复 H5 来馆第三方导航构建边界
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-12 00:30:18 +08:00
parent e99d713dd0
commit e006333c0a
13 changed files with 560 additions and 523 deletions

View File

@@ -77,6 +77,7 @@
</template>
</view>
<!-- #ifndef MP-WEIXIN -->
<view
v-if="providerSheetVisible && selectedTarget"
class="provider-scrim"
@@ -109,6 +110,24 @@
<text class="provider-action">打开</text>
</view>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view
v-if="buildDiagnostics"
class="arrival-build-diagnostics"
data-testid="arrival-build-diagnostics"
>
<text class="arrival-build-diagnostics-title">H5 构建诊断</text>
<text class="arrival-build-diagnostics-line">构建 ID{{ buildDiagnostics.buildId }}</text>
<text class="arrival-build-diagnostics-line">Git commit{{ buildDiagnostics.gitCommit }}</text>
<text class="arrival-build-diagnostics-line">构建平台{{ buildDiagnostics.platform }}</text>
<text class="arrival-build-diagnostics-line">navigationMode{{ buildDiagnostics.navigationMode }}</text>
<text class="arrival-build-diagnostics-line">页面 chunk{{ buildDiagnostics.chunkFileName }}</text>
<text class="arrival-build-diagnostics-line">location.href{{ buildDiagnostics.href }}</text>
<text class="arrival-build-diagnostics-line">UA{{ buildDiagnostics.userAgent }}</text>
</view>
<!-- #endif -->
</template>
<script setup lang="ts">
@@ -118,17 +137,19 @@ import {
type ArrivalSearchTarget,
type ArrivalTargetType
} from '@/data/arrivalSearchTargets'
// #ifndef MP-WEIXIN
import {
openThirdPartyMapSearch,
openWechatMiniProgramLocation,
THIRD_PARTY_MAP_PROVIDERS,
type ThirdPartyMapProviderOption
} from '@/services/ThirdPartyMapSearchService'
import { isNativeWechatMiniProgram } from '@/utils/hostEnvironment'
import {
getArrivalNavigationActionText,
resolveArrivalNavigationMode
} from '@/components/navigation/arrivalNavigationPolicy'
// #endif
// #ifdef MP-WEIXIN
import { openWechatHostLocation } from '@/services/WechatOpenLocationService'
import { validateWechatOpenLocationTarget } from '@/utils/wechatOpenLocationProtocol'
// #endif
type ArrivalNavigationMode = 'third-party-providers' | 'native-location'
const props = withDefaults(defineProps<{
visible?: boolean
@@ -151,17 +172,64 @@ const emit = defineEmits<{
}>()
const typeOptions = computed(() => ARRIVAL_TARGET_TYPES)
// #ifndef MP-WEIXIN
const mapProviders = computed(() => THIRD_PARTY_MAP_PROVIDERS)
const navigationMode = resolveArrivalNavigationMode(isNativeWechatMiniProgram())
const primaryActionText = computed(() => (
getArrivalNavigationActionText(navigationMode, isOpeningNavigation.value)
))
// #endif
const navigationMode: ArrivalNavigationMode = __APP_BUILD_PLATFORM__ === 'mp-weixin'
? 'native-location'
: 'third-party-providers'
const arrivalPanelRef = ref<unknown>(null)
const isCollapsed = ref(false)
const providerSheetVisible = ref(false)
const isOpeningNavigation = ref(false)
let resizeObserver: ResizeObserver | null = null
const primaryActionText = computed(() => {
// #ifdef MP-WEIXIN
if (navigationMode === 'native-location') {
return isOpeningNavigation.value ? '正在打开...' : '打开地图导航'
}
// #endif
return '第三方导航'
})
// #ifdef H5
const hasDebugBuildFlag = () => {
if (typeof window === 'undefined') return false
const searchParams = new URLSearchParams(window.location.search)
if (searchParams.get('debug-build') === '1') return true
const hash = window.location.hash || ''
const hashQueryStart = hash.indexOf('?')
if (hashQueryStart < 0) return false
return new URLSearchParams(hash.slice(hashQueryStart + 1)).get('debug-build') === '1'
}
const resolveCurrentChunkFileName = () => {
try {
const pathname = new URL(import.meta.url).pathname
return decodeURIComponent(pathname.split('/').pop() || pathname)
} catch {
return import.meta.url
}
}
const buildDiagnostics = hasDebugBuildFlag()
? {
buildId: __APP_BUILD_ID__,
gitCommit: __APP_GIT_COMMIT__,
platform: __APP_BUILD_PLATFORM__,
navigationMode,
chunkFileName: resolveCurrentChunkFileName(),
href: window.location.href,
userAgent: window.navigator.userAgent
}
: null
// #endif
const activeTypeLabel = computed(() => (
typeOptions.value.find((option) => option.type === props.activeType)?.label || '来馆'
))
@@ -246,7 +314,8 @@ const startLayoutObserver = () => {
const handleNavigateTap = async () => {
if (isOpeningNavigation.value) return
if (!props.selectedTarget) {
const selectedTarget = props.selectedTarget
if (!selectedTarget) {
uni.showToast({
title: '请先选择点位',
icon: 'none'
@@ -254,26 +323,44 @@ const handleNavigateTap = async () => {
return
}
// H5含小程序 web-view统一由用户选择第三方地图。
if (navigationMode === 'third-party-providers') {
// #ifndef MP-WEIXIN
if (__APP_BUILD_PLATFORM__ !== 'mp-weixin') {
providerSheetVisible.value = true
return
}
// #endif
const target = {
latitude: props.selectedTarget.latitude,
longitude: props.selectedTarget.longitude,
name: props.selectedTarget.title,
address: props.selectedTarget.subtitle
// #ifdef MP-WEIXIN
const validation = validateWechatOpenLocationTarget({
latitude: selectedTarget.latitude,
longitude: selectedTarget.longitude,
name: selectedTarget.title,
address: selectedTarget.subtitle
})
if (!validation.ok) {
uni.showToast({
title: validation.message,
icon: 'none'
})
return
}
isOpeningNavigation.value = true
try {
await openWechatMiniProgramLocation(target)
const result = await openWechatHostLocation(validation.value)
if (result.status !== 'opened') {
uni.showToast({
title: result.reason === 'timeout' ? '微信地图响应超时' : '无法打开微信地图',
icon: 'none'
})
}
} finally {
isOpeningNavigation.value = false
}
// #endif
}
// #ifndef MP-WEIXIN
const handleProviderSelect = (provider: ThirdPartyMapProviderOption) => {
const target = props.selectedTarget
if (!target) return
@@ -283,6 +370,7 @@ const handleProviderSelect = (provider: ThirdPartyMapProviderOption) => {
region: target.region
})
}
// #endif
watch(
() => props.visible,
@@ -722,4 +810,36 @@ defineExpose({
font-weight: 600;
color: #696962;
}
.arrival-build-diagnostics {
position: fixed;
top: calc(env(safe-area-inset-top) + 8px);
left: 8px;
right: 8px;
z-index: 9999;
max-height: 42vh;
padding: 10px 12px;
display: flex;
flex-direction: column;
gap: 3px;
overflow: auto;
box-sizing: border-box;
border: 1px solid rgba(224, 225, 0, 0.75);
border-radius: 6px;
background: rgba(20, 22, 19, 0.94);
pointer-events: none;
}
.arrival-build-diagnostics-title,
.arrival-build-diagnostics-line {
overflow-wrap: anywhere;
font-size: 11px;
line-height: 16px;
color: #ffffff;
}
.arrival-build-diagnostics-title {
font-weight: 700;
color: #e0e100;
}
</style>