feat(scan-checkin-detail): 新增签到位置权限确认弹窗流程
为扫码签到功能新增位置权限确认弹窗流程,当活动开启位置验证时弹出弹窗请求用户授权,处理用户的同意或拒绝操作,拒绝时显示提示并终止签到流程。
Showing
1 changed file
with
80 additions
and
1 deletions
| ... | @@ -47,11 +47,39 @@ | ... | @@ -47,11 +47,39 @@ |
| 47 | {{ actionButtonText }} | 47 | {{ actionButtonText }} |
| 48 | </nut-button> | 48 | </nut-button> |
| 49 | </view> | 49 | </view> |
| 50 | + | ||
| 51 | + <nut-dialog v-model:visible="showLocationConfirmDialog" title="位置权限申请"> | ||
| 52 | + <template #default> | ||
| 53 | + <view class="text-gray-700 leading-loose text-sm text-left"> | ||
| 54 | + {{ locationConfirmContent }} | ||
| 55 | + </view> | ||
| 56 | + </template> | ||
| 57 | + <template #footer> | ||
| 58 | + <nut-row :gutter="10"> | ||
| 59 | + <nut-col :span="12"> | ||
| 60 | + <nut-button @click="handleLocationConfirmCancel" type="default" size="normal" block> | ||
| 61 | + 暂不开启 | ||
| 62 | + </nut-button> | ||
| 63 | + </nut-col> | ||
| 64 | + <nut-col :span="12"> | ||
| 65 | + <nut-button | ||
| 66 | + @click="handleLocationConfirmAgree" | ||
| 67 | + type="primary" | ||
| 68 | + size="normal" | ||
| 69 | + color="#DF7750" | ||
| 70 | + block | ||
| 71 | + > | ||
| 72 | + 同意并继续 | ||
| 73 | + </nut-button> | ||
| 74 | + </nut-col> | ||
| 75 | + </nut-row> | ||
| 76 | + </template> | ||
| 77 | + </nut-dialog> | ||
| 50 | </view> | 78 | </view> |
| 51 | </template> | 79 | </template> |
| 52 | 80 | ||
| 53 | <script setup> | 81 | <script setup> |
| 54 | -import { reactive, computed } from 'vue' | 82 | +import { reactive, computed, ref } from 'vue' |
| 55 | import Taro, { useLoad } from '@tarojs/taro' | 83 | import Taro, { useLoad } from '@tarojs/taro' |
| 56 | import './index.less' | 84 | import './index.less' |
| 57 | import RichTextRenderer from '@/components/RichTextRenderer.vue' | 85 | import RichTextRenderer from '@/components/RichTextRenderer.vue' |
| ... | @@ -99,6 +127,10 @@ const actionButtonText = computed(() => | ... | @@ -99,6 +127,10 @@ const actionButtonText = computed(() => |
| 99 | detail.entryMode === 'direct_submit' ? '点击打卡' : '扫码打卡' | 127 | detail.entryMode === 'direct_submit' ? '点击打卡' : '扫码打卡' |
| 100 | ) | 128 | ) |
| 101 | const isApiSuccess = code => Number(code) === 1 | 129 | const isApiSuccess = code => Number(code) === 1 |
| 130 | +const showLocationConfirmDialog = ref(false) | ||
| 131 | +const pendingLocationConfirmResolver = ref(null) | ||
| 132 | +const locationConfirmContent = | ||
| 133 | + '为了完成扫码打卡,我们需要获取您的位置信息,用于验证您是否在当前打卡点范围内。我们会严格保护您的位置隐私,仅用于本次扫码打卡。' | ||
| 102 | 134 | ||
| 103 | const normalizedRichTextContent = computed(() => { | 135 | const normalizedRichTextContent = computed(() => { |
| 104 | const content = detail.discountContentRaw | 136 | const content = detail.discountContentRaw |
| ... | @@ -195,6 +227,46 @@ const ensureOpenid = async () => { | ... | @@ -195,6 +227,46 @@ const ensureOpenid = async () => { |
| 195 | return openid | 227 | return openid |
| 196 | } | 228 | } |
| 197 | 229 | ||
| 230 | +const waitForLocationConfirm = async () => { | ||
| 231 | + if (detail.geoEnabled !== true) { | ||
| 232 | + return true | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + const authSetting = await Taro.getSetting() | ||
| 236 | + const hasLocationPermission = authSetting?.authSetting?.['scope.userLocation'] | ||
| 237 | + | ||
| 238 | + if (hasLocationPermission === true) { | ||
| 239 | + return true | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + showLocationConfirmDialog.value = true | ||
| 243 | + | ||
| 244 | + return new Promise(resolve => { | ||
| 245 | + pendingLocationConfirmResolver.value = resolve | ||
| 246 | + }) | ||
| 247 | +} | ||
| 248 | + | ||
| 249 | +const resolveLocationConfirm = confirmed => { | ||
| 250 | + showLocationConfirmDialog.value = false | ||
| 251 | + | ||
| 252 | + if (pendingLocationConfirmResolver.value) { | ||
| 253 | + pendingLocationConfirmResolver.value(confirmed) | ||
| 254 | + pendingLocationConfirmResolver.value = null | ||
| 255 | + } | ||
| 256 | +} | ||
| 257 | + | ||
| 258 | +const handleLocationConfirmCancel = () => { | ||
| 259 | + Taro.showToast({ | ||
| 260 | + title: '需要位置权限才能参与活动', | ||
| 261 | + icon: 'none', | ||
| 262 | + }) | ||
| 263 | + resolveLocationConfirm(false) | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +const handleLocationConfirmAgree = () => { | ||
| 267 | + resolveLocationConfirm(true) | ||
| 268 | +} | ||
| 269 | + | ||
| 198 | const handleScanCheckin = async () => { | 270 | const handleScanCheckin = async () => { |
| 199 | detail.scanSubmitting = true | 271 | detail.scanSubmitting = true |
| 200 | 272 | ||
| ... | @@ -208,6 +280,13 @@ const handleScanCheckin = async () => { | ... | @@ -208,6 +280,13 @@ const handleScanCheckin = async () => { |
| 208 | return | 280 | return |
| 209 | } | 281 | } |
| 210 | 282 | ||
| 283 | + const hasConfirmedLocation = await waitForLocationConfirm() | ||
| 284 | + | ||
| 285 | + if (!hasConfirmedLocation) { | ||
| 286 | + detail.scanSubmitting = false | ||
| 287 | + return | ||
| 288 | + } | ||
| 289 | + | ||
| 211 | // 点击扫码时重新静默拉一次当前位置,避免依赖进入页面时的旧定位缓存。 | 290 | // 点击扫码时重新静默拉一次当前位置,避免依赖进入页面时的旧定位缓存。 |
| 212 | const rangeCheck = await verifyCheckinRangeWithCurrentLocation({ | 291 | const rangeCheck = await verifyCheckinRangeWithCurrentLocation({ |
| 213 | geoEnabled: detail.geoEnabled, | 292 | geoEnabled: detail.geoEnabled, | ... | ... |
-
Please register or login to post a comment