连云港陪玩陪聊
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chunwan/pages/users/renzheng/camera.nvue

427 lines
9.6 KiB

<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',
position: "bottom",
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;
margin-top: 20rpx;
overflow: hidden;
}
.check-preview__mask {
width: 504rpx;
height: 672rpx;
position: absolute;
display: block;
top: 0;
left: 0;
z-index: 55;
transition: backgroundColor 0.3s;
background-color: #ffffff;
}
.check-preview__camera {
width: 504rpx;
height: 672rpx;
border-radius: 50%;
margin-top: 20rpx;
overflow: hidden;
}
.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>