@ -0,0 +1,421 @@ |
|||||||
|
<template> |
||||||
|
<view class="yd-check" :style="{'width': winWidth+'px', 'height': winHeight+'px'}"> |
||||||
|
<view class="check-preview"> |
||||||
|
<view class="check-preview__content"> |
||||||
|
<camera_preview ref="aliveDetect" class="check-preview__camera"></camera_preview> |
||||||
|
<image class="check-preview__mask" :style="{ backgroundColor: maskColor }" |
||||||
|
src="/static/shibie/alive_mask@3x.png" @load="handleImgLoad"></image> |
||||||
|
</view> |
||||||
|
<view class="check-preview__audio" @click="toggleAudioSwitch"> |
||||||
|
<image class="check-preview__switch" |
||||||
|
:src="enableAudio ? '/static/shibie/audio_open@3x.png' : '/static/shibie/audio_close@3x.png'"></image> |
||||||
|
</view> |
||||||
|
<view class="check-preview__timer progress-timer"> |
||||||
|
<text class="txt">{{ restSec }}</text> |
||||||
|
<view class="progress-timer__right"> |
||||||
|
<view ref="rightCircle" class="progress-timer__circle progress-timer__circle--right"></view> |
||||||
|
</view> |
||||||
|
<view class="progress-timer__left"> |
||||||
|
<view ref="leftCircle" class="progress-timer__circle progress-timer__circle--left"></view> |
||||||
|
</view> |
||||||
|
</view> |
||||||
|
</view> |
||||||
|
<view class="check-process"> |
||||||
|
<view class="check-process__tip">{{ curAction.tip }}</view> |
||||||
|
<image class="check-process__img" :src="`/static/shibie/${curAction.image}`"></image> |
||||||
|
<view class="check-steps"> |
||||||
|
<view v-for="(item,index) in commands" :key="index" |
||||||
|
:class="['check-steps__item', curAction.step === index ? 'check-steps__item--active' : '']"> |
||||||
|
<text v-if="curAction.step === index" class="check-steps__text">{{ index+1 }}</text> |
||||||
|
</view> |
||||||
|
</view> |
||||||
|
</view> |
||||||
|
</view> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import api from '@/api/index.js' |
||||||
|
const DETECT_ACTION_TYPES = { |
||||||
|
'1': ['向右转头', 'turn_right.gif', 'turn_right.wav'], |
||||||
|
'2': ['向左转头', 'turn_left.gif', 'turn_left.wav'], |
||||||
|
'3': ['张嘴动作', 'open_mouth.gif', 'open_mouth.wav'], |
||||||
|
'4': ['眨眼动作', 'open_eyes.gif', 'open_eyes.wav'] |
||||||
|
} |
||||||
|
const innerAudioContext = uni.createInnerAudioContext() |
||||||
|
innerAudioContext.onPlay(() => { |
||||||
|
console.log('音频开始播放') |
||||||
|
}) |
||||||
|
innerAudioContext.onError((res) => { |
||||||
|
console.log(res.errMsg) |
||||||
|
console.log(res.errCode) |
||||||
|
}) |
||||||
|
const animation = weex.requireModule('animation') |
||||||
|
|
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
curAction: { |
||||||
|
step: 0, |
||||||
|
tip: '', |
||||||
|
image: 'pic_front.png' |
||||||
|
}, |
||||||
|
restSec: 0, |
||||||
|
enableAudio: true, |
||||||
|
timer: null, |
||||||
|
maskColor: '#fff', |
||||||
|
isTimeout: false, |
||||||
|
commands: [], |
||||||
|
winWidth: 0, |
||||||
|
winHeight: 0, |
||||||
|
idCard: "", |
||||||
|
realName: "" |
||||||
|
}; |
||||||
|
}, |
||||||
|
onLoad(o) { |
||||||
|
this.realName = decodeURIComponent(o.realName); |
||||||
|
this.idCard = o.idCard; |
||||||
|
console.log(o) |
||||||
|
this.winWidth = uni.getSystemInfoSync().windowWidth; |
||||||
|
this.winHeight = uni.getSystemInfoSync().windowHeight; |
||||||
|
}, |
||||||
|
onReady() { |
||||||
|
console.log("页面初次渲染完成"); |
||||||
|
this.initAliveDetect() |
||||||
|
}, |
||||||
|
onBackPress() { |
||||||
|
this.$refs.aliveDetect.stopDetect() |
||||||
|
}, |
||||||
|
onUnload() { |
||||||
|
console.log("页面卸载"); |
||||||
|
if (innerAudioContext != null && !innerAudioContext.paused) { |
||||||
|
innerAudioContext.pause() |
||||||
|
innerAudioContext.stop() |
||||||
|
innerAudioContext.destroy() |
||||||
|
innerAudioContext = null |
||||||
|
} |
||||||
|
this.timer && clearInterval(this.timer) |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
initAliveDetect() { |
||||||
|
this.timer && (clearInterval(this.timer)) |
||||||
|
this.curAction = { |
||||||
|
step: 0, |
||||||
|
tip: '', |
||||||
|
image: 'pic_front.png' |
||||||
|
} |
||||||
|
this.$refs.aliveDetect.init({ |
||||||
|
'businessID': '043948b2576b41dc9d23d14b4e500b7a', |
||||||
|
'timeout': 60, |
||||||
|
'isDebug': true |
||||||
|
}, this.handleCheck) |
||||||
|
this.$refs.aliveDetect.startDetect() |
||||||
|
this.restSec = 60 |
||||||
|
this.timer = setInterval(() => { |
||||||
|
if (this.restSec <= 0) { |
||||||
|
clearInterval(this.timer) |
||||||
|
this.timer = null |
||||||
|
} else { |
||||||
|
this.restSec = this.restSec - 1 |
||||||
|
} |
||||||
|
}, 1000) |
||||||
|
|
||||||
|
// nvue不支持css animatin和uni的animation,所以使用weex内置的动画 |
||||||
|
animation.transition(this.$refs.leftCircle, { |
||||||
|
styles: { |
||||||
|
transform: 'rotate(135deg)' |
||||||
|
}, |
||||||
|
duration: 15000, |
||||||
|
timingFunction: 'linear', |
||||||
|
needLayout: false, |
||||||
|
delay: 15000 |
||||||
|
}) |
||||||
|
animation.transition(this.$refs.rightCircle, { |
||||||
|
styles: { |
||||||
|
transform: 'rotate(225deg)' |
||||||
|
}, |
||||||
|
duration: 15000, |
||||||
|
timingFunction: 'linear', |
||||||
|
needLayout: false, |
||||||
|
delay: 0 |
||||||
|
}) |
||||||
|
}, |
||||||
|
//去登录 |
||||||
|
async toReg(token) { |
||||||
|
const res = await api.realNameAuth({ |
||||||
|
userId: uni.getStorageSync("userInfo").id, |
||||||
|
realName: this.realName, |
||||||
|
idCard: this.idCard, |
||||||
|
token |
||||||
|
}) |
||||||
|
console.log({ |
||||||
|
userId: uni.getStorageSync("userInfo").id, |
||||||
|
realName: this.realName, |
||||||
|
idCard: this.idCard, |
||||||
|
token |
||||||
|
}) |
||||||
|
console.log(res) |
||||||
|
if(res.code == 200){ |
||||||
|
uni.showToast({ |
||||||
|
title: "提交成功" |
||||||
|
}) |
||||||
|
setTimeout(()=>{ |
||||||
|
uni.navigateBack({ |
||||||
|
delta: 2 |
||||||
|
}) |
||||||
|
},2000) |
||||||
|
}else{ |
||||||
|
uni.showToast({ |
||||||
|
icon: "none", |
||||||
|
position: "bottom", |
||||||
|
title: res.msg |
||||||
|
}) |
||||||
|
} |
||||||
|
}, |
||||||
|
handleCheck(ev) { |
||||||
|
// 初始化活体检测引擎成功 |
||||||
|
if (typeof ev !== 'object') { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
const method = ev['method'] |
||||||
|
const data = ev['data'] |
||||||
|
|
||||||
|
if (method == "onReady") { |
||||||
|
const result = data['initResult'] |
||||||
|
console.log(result ? "引擎初始化成功" : "引擎初始化失败") |
||||||
|
} else if (method == "onConfig") { |
||||||
|
// 动作序列 |
||||||
|
let commands = []; |
||||||
|
for (let i = 0; i < data['actions'].length; i++) { |
||||||
|
commands.push(parseInt(data['actions'][i])) |
||||||
|
}; |
||||||
|
this.commands = commands; |
||||||
|
} else if (method == "onChecking") { |
||||||
|
// 检测提示 |
||||||
|
const actionType = data['currentStep'] + '' |
||||||
|
if (Object.keys(DETECT_ACTION_TYPES).includes(actionType) && |
||||||
|
actionType !== this.curAction.type) { |
||||||
|
const hit = DETECT_ACTION_TYPES[actionType] |
||||||
|
this.curAction = { |
||||||
|
step: this.curAction.step + 1, |
||||||
|
type: actionType, |
||||||
|
tip: hit[0], |
||||||
|
image: hit[1] |
||||||
|
} |
||||||
|
console.log(this.curAction) |
||||||
|
console.log(data) |
||||||
|
this.playAudioIfEnable(hit[2]) |
||||||
|
} |
||||||
|
} else if (method == "onChecked") { |
||||||
|
// // 检测结果 |
||||||
|
console.log(data) |
||||||
|
this.toReg(data.token) |
||||||
|
clearInterval(this.timer) |
||||||
|
this.timer = null |
||||||
|
return |
||||||
|
} else if (method == "onError") { |
||||||
|
// 检测失败 |
||||||
|
console.log("错误码为:" + data['code']); |
||||||
|
console.log("错误信息为:" + data['message']); |
||||||
|
uni.showToast({ |
||||||
|
icon: 'none', |
||||||
|
title: data['message'] |
||||||
|
}) |
||||||
|
} else if (method == "overTime") { |
||||||
|
// 超时 |
||||||
|
clearInterval(this.timer) |
||||||
|
this.timer = null |
||||||
|
uni.showModal({ |
||||||
|
title: '检测超时', |
||||||
|
content: '请在规定时间内完成动作', |
||||||
|
cancelText: '返回上一页', |
||||||
|
confirmText: '重试', |
||||||
|
success: (res) => { |
||||||
|
if (res.confirm) { |
||||||
|
this.initAliveDetect() |
||||||
|
} else { |
||||||
|
uni.navigateBack() |
||||||
|
} |
||||||
|
}, |
||||||
|
fail: () => { |
||||||
|
uni.navigateBack() |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
}, |
||||||
|
playAudioIfEnable(src) { |
||||||
|
if (!this.enableAudio) return |
||||||
|
innerAudioContext.src = `/static/shibie/audio/${src}` |
||||||
|
innerAudioContext.play() |
||||||
|
}, |
||||||
|
toggleAudioSwitch() { |
||||||
|
this.enableAudio = !this.enableAudio |
||||||
|
}, |
||||||
|
handleImgLoad() { |
||||||
|
setTimeout(() => { |
||||||
|
this.maskColor = 'transparent' |
||||||
|
}, 120) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss"> |
||||||
|
.yd-check { |
||||||
|
background-color: #ffffff; |
||||||
|
} |
||||||
|
|
||||||
|
.check-preview { |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.check-preview__content { |
||||||
|
width: 504rpx; |
||||||
|
height: 672rpx; |
||||||
|
margin-top: 6rpx; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.check-preview__mask { |
||||||
|
width: 504rpx; |
||||||
|
height: 672rpx; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
z-index: 9999; |
||||||
|
transition: backgroundColor 0.3s; |
||||||
|
background-color: #ffffff; |
||||||
|
} |
||||||
|
|
||||||
|
.check-preview__camera { |
||||||
|
width: 504rpx; |
||||||
|
height: 672rpx; |
||||||
|
border-radius: 50%; |
||||||
|
} |
||||||
|
|
||||||
|
.check-preview__audio { |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
right: 40rpx; |
||||||
|
width: 48rpx; |
||||||
|
height: 48rpx; |
||||||
|
} |
||||||
|
|
||||||
|
.check-preview__switch { |
||||||
|
width: 48rpx; |
||||||
|
height: 48rpx; |
||||||
|
} |
||||||
|
|
||||||
|
.check-preview__timer { |
||||||
|
position: absolute; |
||||||
|
top: 80rpx; |
||||||
|
right: 40rpx; |
||||||
|
width: 60rpx; |
||||||
|
height: 60rpx; |
||||||
|
line-height: 60rpx; |
||||||
|
color: #222; |
||||||
|
font-size: 26rpx; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
.txt{ |
||||||
|
font-size: 26rpx; |
||||||
|
color: #000; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.progress-timer__right, |
||||||
|
.progress-timer__left { |
||||||
|
width: 30rpx; |
||||||
|
height: 60rpx; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.progress-timer__right { |
||||||
|
right: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.progress-timer__left { |
||||||
|
left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.progress-timer__circle { |
||||||
|
width: 60rpx; |
||||||
|
height: 60rpx; |
||||||
|
border-style: solid; |
||||||
|
border-width: 6rpx; |
||||||
|
border-color: #000000; |
||||||
|
border-radius: 50%; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.progress-timer__circle--right { |
||||||
|
border-right-color: #ccc; |
||||||
|
border-top-color: #ccc; |
||||||
|
right: 0; |
||||||
|
transform: rotate(45deg); |
||||||
|
} |
||||||
|
|
||||||
|
.progress-timer__circle--left { |
||||||
|
border-left-color: #ccc; |
||||||
|
border-top-color: #ccc; |
||||||
|
left: 0; |
||||||
|
transform: rotate(-45deg); |
||||||
|
} |
||||||
|
|
||||||
|
.check-process { |
||||||
|
padding-top: 90rpx; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.check-process__tip { |
||||||
|
opacity: 0.85; |
||||||
|
font-size: 40rpx; |
||||||
|
color: #000; |
||||||
|
text-align: center; |
||||||
|
line-height: 56rpx; |
||||||
|
height: 56rpx; |
||||||
|
} |
||||||
|
|
||||||
|
.check-process__img { |
||||||
|
width: 280rpx; |
||||||
|
height: 280rpx; |
||||||
|
margin-top: 8rpx; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.check-steps { |
||||||
|
flex-direction: row; |
||||||
|
justify-content: space-around; |
||||||
|
align-items: center; |
||||||
|
width: 240rpx; |
||||||
|
margin-top: 32rpx; |
||||||
|
} |
||||||
|
|
||||||
|
.check-steps__item { |
||||||
|
font-size: 0px; |
||||||
|
width: 20rpx; |
||||||
|
height: 20rpx; |
||||||
|
background-color: #DDE3EF; |
||||||
|
border-radius: 50%; |
||||||
|
} |
||||||
|
|
||||||
|
.check-steps__item--active { |
||||||
|
width: 40rpx; |
||||||
|
height: 40rpx; |
||||||
|
background-color: #000000; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
.check-steps__text { |
||||||
|
color: #FFFFFF; |
||||||
|
line-height: 40rpx; |
||||||
|
font-size: 28rpx; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
</style> |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 647 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 271 KiB |
After Width: | Height: | Size: 258 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 647 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 271 KiB |
After Width: | Height: | Size: 258 KiB |
After Width: | Height: | Size: 2.3 KiB |