Files
yunzerwebsiteallinone/uniapp/pages/login/geetest-webview.vue
T

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>