支付宝上架

This commit is contained in:
2026-03-26 09:47:22 +08:00
parent 802aee59cb
commit 337a92d8c1
8 changed files with 222 additions and 40 deletions
+184 -16
View File
@@ -17,16 +17,11 @@
</view>
<!-- 内容区域 -->
<!-- #ifdef MP-ALIPAY -->
<view class="main-content" :style="{ paddingTop: (navBarHeight + noticeHeight) + 'px' }">
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<view class="main-content" :style="{ paddingTop: (statusBarHeight + navBarHeight + noticeHeight) + 'px' }">
<!-- #endif -->
<view class="main-content" :style="mainContentStyle">
<!-- 全屏地图组件 -->
<!-- 支付宝小程序使用专用组件 -->
<!-- #ifdef MP-ALIPAY -->
<MapComponentAlipay v-if="!isLoading && userLocation" ref="mapRef" :userLocation="userLocation"
<MapComponentAlipay v-if="!isLoading && userLocation && !locationPermissionDenied" ref="mapRef" :userLocation="userLocation"
:positionList="positionList" :filteredPositions="filteredPositions" :searchKeyword="searchKeyword"
:enableMarkers="true" :bannerImages="bannerImages"
:hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup" @relocate="handleRelocate"
@@ -35,7 +30,7 @@
<!-- #endif -->
<!-- 非支付宝小程序使用通用组件 -->
<!-- #ifndef MP-ALIPAY -->
<MapComponent v-if="!isLoading && userLocation" ref="mapRef" :userLocation="userLocation"
<MapComponent v-if="!isLoading && userLocation && !locationPermissionDenied" ref="mapRef" :userLocation="userLocation"
:positionList="positionList" :filteredPositions="filteredPositions" :searchKeyword="searchKeyword"
:enableMarkers="true" :bannerImages="bannerImages"
:hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup" @relocate="handleRelocate"
@@ -44,12 +39,26 @@
<!-- #endif -->
<!-- 地图加载状态 -->
<!-- #ifdef MP-ALIPAY -->
<view v-if="!userLocation" class="location-denied-placeholder">
<view class="denied-content">
<text class="denied-text">{{ $t('home.locationPermissionOffTip') }}</text>
<view class="denied-enable-btn" @click="handleEnableLocation">
<text class="denied-enable-btn-text">{{ $t('home.enableLocation') }}</text>
</view>
</view>
</view>
<!-- 支付宝端拒绝定位后直接展示提示不展示 common.loadingLocation -->
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<view v-if="isLoading || !userLocation" class="map-loading-placeholder">
<view class="loading-content">
<view class="loading-spinner"></view>
<text>{{ $t('common.loadingLocation') }}</text>
</view>
</view>
<!-- #endif -->
</view>
<!-- 底部操作栏附近设备 / 扫码使用 / 我的 -->
@@ -282,6 +291,7 @@
const filteredPositions = ref([])
const isExpanded = ref(false)
const isLoading = ref(false)
const locationPermissionDenied = ref(false) // MP-ALIPAY:定位权限拒绝后展示引导文案
const showPhoneAuthPopup = ref(false)
const pendingScan = ref(false) // 是否是扫码流程触发的手机号校验
const expectedUserPhone = ref('') // 当前登录态下绑定的手机号(用于支付宝一致性校验)
@@ -324,6 +334,16 @@
// #endif
})
// 主内容区域样式:不同端适配不同的 paddingTop
const mainContentStyle = computed(() => {
// #ifdef MP-ALIPAY
return { paddingTop: (navBarHeight.value + noticeHeight.value) + 'px' }
// #endif
// #ifndef MP-ALIPAY
return { paddingTop: (statusBarHeight.value + navBarHeight.value + noticeHeight.value) + 'px' }
// #endif
})
// 使用指南步骤
const guideSteps = ref([{
title: '扫码使用',
@@ -619,6 +639,7 @@
// 方法
const init = async () => {
locationPermissionDenied.value = false
isLoading.value = true
try {
// 清理旧版本的缓存键(兼容性处理)
@@ -651,6 +672,14 @@
} catch (error) {
console.error('初始化失败:', error)
// #ifdef MP-ALIPAY
if (isLocationPermissionDenied(error)) {
locationPermissionDenied.value = true
userLocation.value = null
positionList.value = []
filteredPositions.value = []
}
// #endif
// uni.showToast({
// title: t('home.getLocationFailed'),
// icon: 'none'
@@ -660,6 +689,12 @@
}
}
const isLocationPermissionDenied = (error) => {
const msg = String(error?.errMsg || error?.message || error || '')
// 覆盖常见文案:permission denied / auth deny / 拒绝 / 未授权
return /permission\s*denied|auth\s*deny|auth\s*denied|denied|拒绝|未授权|not\s*allowed|not\s*permitted/i.test(msg)
}
const getUserLocationAndAddress = async () => {
// 使用腾讯地图SDK获取位置(若失败抛出,由调用方统一处理)
const location = await getUserLocation()
@@ -719,6 +754,55 @@
return userLocation.value
}
const handleEnableLocation = async () => {
isLoading.value = true
try {
// #ifdef MP-ALIPAY
// 支付宝:用权限指引弹窗引导用户开启定位(showAuthGuide 在权限被拒后更可靠)
// 说明:调用后系统会弹出引导/授权界面;用户授权成功后再尝试获取定位。
try {
if (typeof my !== 'undefined' && my.showAuthGuide) {
await new Promise((resolve) => {
my.showAuthGuide({
authType: 'LBS',
success: () => resolve(true),
fail: () => resolve(false)
})
})
} else if (typeof my !== 'undefined' && my.authorize) {
// 兜底:如果 showAuthGuide 不可用,再尝试 authorize 触发授权
await new Promise((resolve) => {
my.authorize({
scope: 'scope.userLocation',
success: () => resolve(true),
fail: () => resolve(false)
})
})
}
} catch (_) {}
// #endif
// 重新触发定位授权/获取流程
await getUserLocationAndAddress()
await loadPositions()
// 成功拿到定位后,再隐藏权限提示
locationPermissionDenied.value = false
} catch (error) {
console.error('开启定位失败:', error)
// #ifdef MP-ALIPAY
if (isLocationPermissionDenied(error)) {
locationPermissionDenied.value = true // 保持在页面上提示,避免出现空白区
userLocation.value = null
positionList.value = []
filteredPositions.value = []
}
// #endif
} finally {
isLoading.value = false
}
}
const loadPositions = async () => {
try {
if (!userLocation.value || !userLocation.value.latitude || !userLocation.value.longitude) {
@@ -1118,6 +1202,39 @@
await doScan()
}
// 统一提取 deviceNo,兼容 URL、编码文本、纯设备号
const extractDeviceNoFromText = (rawText) => {
if (!rawText) return ''
const text = String(rawText).trim()
if (!text) return ''
const candidates = [text]
try {
const decoded = decodeURIComponent(text)
if (decoded && decoded !== text) {
candidates.push(decoded)
}
} catch (e) {}
for (const item of candidates) {
const fromQuery =
getQueryString(item, 'deviceNo') ||
getQueryString(item, 'deviceno')
if (fromQuery) {
return String(fromQuery).trim()
}
}
// 二维码内容本身就是设备号时,直接使用原文
for (const item of candidates) {
if (!item.includes('=') && !item.includes('&') && !item.includes('?')) {
return item
}
}
return ''
}
const processScanResult = async (scanResult) => {
try {
console.log('===== 处理扫码结果 =====');
@@ -1126,17 +1243,20 @@
console.log('result:', scanResult.result);
console.log('path:', scanResult.path);
let deviceNo;
let deviceNo = ''
if (scanResult.scanType == 'MANUAL') {
deviceNo = scanResult.result;
console.log('手动输入模式,设备号:', deviceNo);
deviceNo = extractDeviceNoFromText(scanResult.result)
console.log('手动输入模式,设备号:', deviceNo)
} else if (scanResult.scanType == 'QR_CODE') {
// 修复:移除多余的引号
deviceNo = getQueryString(scanResult.result, 'deviceNo');
console.log('二维码扫描模式,提取设备号:', deviceNo);
deviceNo =
extractDeviceNoFromText(scanResult.result) ||
extractDeviceNoFromText(scanResult.path)
console.log('二维码扫描模式,提取设备号:', deviceNo)
} else {
deviceNo = getQueryString(scanResult.path || scanResult.result, 'deviceNo');
console.log('其他模式,提取设备号:', deviceNo);
deviceNo =
extractDeviceNoFromText(scanResult.path) ||
extractDeviceNoFromText(scanResult.result)
console.log('其他模式,提取设备号:', deviceNo)
}
console.log('最终设备号:', deviceNo);
@@ -1986,6 +2106,54 @@
}
}
/* 支付宝:定位权限拒绝后的引导文案 */
.location-denied-placeholder {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 180rpx;
background: #f6f7fb;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
padding: 0 40rpx;
box-sizing: border-box;
}
.denied-content {
width: 100%;
background: #ffffff;
border-radius: 16rpx;
padding: 40rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}
.denied-text {
display: block;
font-size: 28rpx;
color: #333;
line-height: 1.6;
}
.denied-enable-btn {
margin-top: 28rpx;
width: 100%;
height: 88rpx;
background: #3EAB64;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
}
.denied-enable-btn-text {
font-size: 32rpx;
font-weight: 700;
color: #ffffff;
}
/* 手机号授权弹窗 */
.phone-auth-popup {
position: fixed;