108 lines
2.4 KiB
Vue
108 lines
2.4 KiB
Vue
<template>
|
|
<view class="geetest-container">
|
|
<web-view :src="webviewSrc" @message="onMessage" />
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
import { onLoad, onUnload } from '@dcloudio/uni-app'
|
|
|
|
const webviewSrc = ref('')
|
|
let eventChannel = null
|
|
let settled = false
|
|
let pollTimer = null
|
|
|
|
function unwrapMessage(e) {
|
|
const raw = e?.detail?.data
|
|
const first = Array.isArray(raw) ? raw[0] : raw
|
|
if (!first) return {}
|
|
if (first.type) return first
|
|
if (first.data && first.data.type) return first.data
|
|
return first
|
|
}
|
|
|
|
function finish(payload) {
|
|
if (settled || !payload || !payload.type) return
|
|
settled = true
|
|
if (pollTimer) {
|
|
clearInterval(pollTimer)
|
|
pollTimer = null
|
|
}
|
|
try {
|
|
if (typeof plus !== 'undefined' && plus.storage) {
|
|
plus.storage.removeItem('__geetest_payload__')
|
|
plus.storage.removeItem('__geetest_captcha_id__')
|
|
}
|
|
} catch (e) {}
|
|
|
|
if (payload.type === 'success') {
|
|
eventChannel?.emit('geetestSuccess', payload.result || {})
|
|
} else {
|
|
eventChannel?.emit('geetestFail', payload.msg || '人机验证未通过')
|
|
}
|
|
uni.navigateBack({
|
|
delta: 1,
|
|
fail() {}
|
|
})
|
|
}
|
|
|
|
function onMessage(e) {
|
|
finish(unwrapMessage(e))
|
|
}
|
|
|
|
onLoad((query) => {
|
|
const captchaId = decodeURIComponent(query.captchaId || '')
|
|
try {
|
|
if (typeof plus !== 'undefined' && plus.storage) {
|
|
plus.storage.setItem('__geetest_captcha_id__', captchaId)
|
|
plus.storage.removeItem('__geetest_payload__')
|
|
}
|
|
} catch (e) {}
|
|
|
|
webviewSrc.value = `/static/html/geetest-captcha.html?captchaId=${encodeURIComponent(captchaId)}`
|
|
|
|
const pagesList = getCurrentPages()
|
|
const curPage = pagesList[pagesList.length - 1]
|
|
eventChannel = curPage?.getOpenerEventChannel?.()
|
|
|
|
// 轮询 plus.storage 结果(每 60ms 检查一次)
|
|
pollTimer = setInterval(() => {
|
|
if (settled) return
|
|
try {
|
|
if (typeof plus !== 'undefined' && plus.storage) {
|
|
const raw = plus.storage.getItem('__geetest_payload__')
|
|
if (raw) {
|
|
const p = JSON.parse(raw)
|
|
if (p) finish(p)
|
|
}
|
|
}
|
|
} catch (e) {}
|
|
}, 60)
|
|
})
|
|
|
|
onUnload(() => {
|
|
if (pollTimer) {
|
|
clearInterval(pollTimer)
|
|
pollTimer = null
|
|
}
|
|
try {
|
|
if (typeof plus !== 'undefined' && plus.storage) {
|
|
plus.storage.removeItem('__geetest_payload__')
|
|
plus.storage.removeItem('__geetest_captcha_id__')
|
|
}
|
|
} catch (e) {}
|
|
if (!settled) {
|
|
eventChannel?.emit('geetestFail', '已取消人机验证')
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.geetest-container {
|
|
width: 100%;
|
|
height: 100vh;
|
|
background: #f5f7fa;
|
|
}
|
|
</style>
|