hookehuyr

feat(scan-checkin-detail): 新增签到位置权限确认弹窗流程

为扫码签到功能新增位置权限确认弹窗流程,当活动开启位置验证时弹出弹窗请求用户授权,处理用户的同意或拒绝操作,拒绝时显示提示并终止签到流程。
......@@ -47,11 +47,39 @@
{{ actionButtonText }}
</nut-button>
</view>
<nut-dialog v-model:visible="showLocationConfirmDialog" title="位置权限申请">
<template #default>
<view class="text-gray-700 leading-loose text-sm text-left">
{{ locationConfirmContent }}
</view>
</template>
<template #footer>
<nut-row :gutter="10">
<nut-col :span="12">
<nut-button @click="handleLocationConfirmCancel" type="default" size="normal" block>
暂不开启
</nut-button>
</nut-col>
<nut-col :span="12">
<nut-button
@click="handleLocationConfirmAgree"
type="primary"
size="normal"
color="#DF7750"
block
>
同意并继续
</nut-button>
</nut-col>
</nut-row>
</template>
</nut-dialog>
</view>
</template>
<script setup>
import { reactive, computed } from 'vue'
import { reactive, computed, ref } from 'vue'
import Taro, { useLoad } from '@tarojs/taro'
import './index.less'
import RichTextRenderer from '@/components/RichTextRenderer.vue'
......@@ -99,6 +127,10 @@ const actionButtonText = computed(() =>
detail.entryMode === 'direct_submit' ? '点击打卡' : '扫码打卡'
)
const isApiSuccess = code => Number(code) === 1
const showLocationConfirmDialog = ref(false)
const pendingLocationConfirmResolver = ref(null)
const locationConfirmContent =
'为了完成扫码打卡,我们需要获取您的位置信息,用于验证您是否在当前打卡点范围内。我们会严格保护您的位置隐私,仅用于本次扫码打卡。'
const normalizedRichTextContent = computed(() => {
const content = detail.discountContentRaw
......@@ -195,6 +227,46 @@ const ensureOpenid = async () => {
return openid
}
const waitForLocationConfirm = async () => {
if (detail.geoEnabled !== true) {
return true
}
const authSetting = await Taro.getSetting()
const hasLocationPermission = authSetting?.authSetting?.['scope.userLocation']
if (hasLocationPermission === true) {
return true
}
showLocationConfirmDialog.value = true
return new Promise(resolve => {
pendingLocationConfirmResolver.value = resolve
})
}
const resolveLocationConfirm = confirmed => {
showLocationConfirmDialog.value = false
if (pendingLocationConfirmResolver.value) {
pendingLocationConfirmResolver.value(confirmed)
pendingLocationConfirmResolver.value = null
}
}
const handleLocationConfirmCancel = () => {
Taro.showToast({
title: '需要位置权限才能参与活动',
icon: 'none',
})
resolveLocationConfirm(false)
}
const handleLocationConfirmAgree = () => {
resolveLocationConfirm(true)
}
const handleScanCheckin = async () => {
detail.scanSubmitting = true
......@@ -208,6 +280,13 @@ const handleScanCheckin = async () => {
return
}
const hasConfirmedLocation = await waitForLocationConfirm()
if (!hasConfirmedLocation) {
detail.scanSubmitting = false
return
}
// 点击扫码时重新静默拉一次当前位置,避免依赖进入页面时的旧定位缓存。
const rangeCheck = await verifyCheckinRangeWithCurrentLocation({
geoEnabled: detail.geoEnabled,
......