1、用户名、身份证号
<template>
<view class="phone_login">
<uni-nav-bar :border="false" :fixed="true" statusBar="true" color="#FFFFFF" title="实名认证" backgroundColor="rgba(0, 0, 0, 0.1)"></uni-nav-bar>
<!-- 文字说明 -->
<view class="tips">
<image class="img" mode="widthFix" src="../../../static/mine/rz-icon1.png"></image>
</view>
<view class="input_1 view_input">
<input type="text" placeholder="请输入真实姓名" maxlength="-1" placeholder-class="aaa" v-model="name" />
</view>
<view class="input_3 view_input">
<input type="text" placeholder="请输入身份证号" v-model="code" placeholder-class="aaa" :adjust-position="true" />
</view>
<view class="btn_5">
<view><text>* 身份证仅支持绑定一次,请勿输入错误。</text></view>
</view>
<view class="btn_1 box_bg zongse" @click="submitIdcard()">提交</view>
</view>
</template>
<script>
export default {
data() {
return {
name: '',
code: '',
}
},
onLoad() {
},
onShow() {
// 开启禁止截屏
// #ifdef APP
uni.getSystemInfo({
success: function (info) {
if (info.platform == 'android') {
uni.setUserCaptureScreen({
enable: false
});
}
},
})
// #endif
},
methods: {
//根据身份证号计算年龄
getAgeFromIdCard(idCard) {
// 身份证号码为18位,前6位为地址码,接下来的8位为出生日期,最后的是验证码
// 提取出生日期(yyyyMMdd)
var birthDateString = idCard.substring(6, 14);
var today = new Date();
var todayYear = today.getFullYear();
var todayMonth = today.getMonth() + 1; // 月份从0开始
var todayDay = today.getDate();
var birthYear = parseInt(birthDateString.substring(0, 4), 10);
var birthMonth = parseInt(birthDateString.substring(4, 6), 10);
var birthDay = parseInt(birthDateString.substring(6, 8), 10);
var age = todayYear - birthYear;
if (todayMonth < birthMonth || (todayMonth == birthMonth && todayDay < birthDay)) {
age--; // 今天还没到生日,年龄减一
}
return age;
},
//提交身份证信息
submitIdcard(){
let that=this;
if (that.name == '') {
uni.showToast({
title: "请输入姓名!",
icon: 'none'
})
return false;
}
if (that.code == "") {
uni.showToast({
title: "请输入身份证号码!",
icon: 'none'
})
return false;
}
const regExp = /(^\d{15}$)|(^\d{17}(\d|X)$)/;
if(!regExp.test(that.code)){
uni.showToast({
title: "请输入正确的身份证号码!",
icon: 'none'
})
return false;
}
let age=that.getAgeFromIdCard(that.code);
// console.log(age);
if(age<18){
uni.showToast({
title: "您还未满18岁,无法实名认证!",
icon: 'none'
})
return false;
}
},
},
}
</script>
<style lang="scss">
.tips{
width:90%;
margin:40rpx auto 40rpx auto;
padding:40rpx;
font-size:28rpx;
line-height: 150%;
text-align: center;
.img{
width:40%;
}
}
.btn_4 {
width: 500rpx;
height: 64rpx;
display: flex;
justify-content: space-around;
margin: 48rpx auto 0;
color: #999999;
font-size: 24rpx;
>view {
text-align: center;
}
image {
width: 80rpx;
height: 80rpx;
}
}
.btn_3 {
text-align: center;
font-size: 28rpx;
font-weight: 400;
color: #999999;
margin: 100rpx auto 0;
}
.aaa {
font-size: 28rpx;
}
.text_head {
font-size: 36rpx;
font-weight: bold;
padding-left: 30rpx;
box-sizing: border-box;
margin-top: 48rpx;
}
button::after {
border: none;
background: none;
color: none;
}
.btn_5 {
width: 670rpx;
height: 25rpx;
font-size: 26rpx;
font-weight: 400;
// color: #999999;
display: flex;
margin: 42rpx auto;
/* justify-content: center; */
image {
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
}
text {
color: #FF3535;
}
}
.btn_1 {
width: 690rpx;
height: 98rpx;
border-radius: 10rpx;
margin: 88rpx auto 0;
font-size: 32rpx;
font-weight: 400;
color: #FFFFFF;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
}
.input_3_btn {
position: absolute;
top: 16rpx;
right: 16rpx;
color: #FFFFFF;
font-size: 26rpx;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 188rpx;
height: 60rpx;
border-radius: 10rpx;
}
.input_1 {
margin-top: 50rpx !important;
width:750rpx;
.uni-input-input{
width:750rpx;
}
}
.view_input {
width: 690rpx;
height: 90rpx;
margin: 24rpx auto;
font-size: 30rpx;
position: relative;
display: flex;
align-items: center;
background: rgba(#FFFFFF, .2);
border-radius: 10rpx;
padding-left: 20rpx;
.uni-input-input{
width:750rpx;
font-size: 32rpx;
border: none;
}
}
.logo {
margin: 100rpx auto 50rpx;
border-radius: 10px;
font-size: 64rpx;
font-weight: bold;
text-align: center;
>image {
width: 170rpx;
height: 170rpx;
/* border: 1px solid salmon; */
}
>view {
/* position: absolute;
width: 24rpx;
height: 24rpx;
border: 4rpx solid #FDC83E;
border-radius: 50%;
left: 400rpx;
top: 6rpx; */
font-size: 32rpx;
}
}
.phone_login {
// padding-bottom: 200rpx;
width: 100vw;
min-height: 100vh;
box-sizing: border-box;
position: relative;
}
</style>
2、初始化livepusher并调用
<template>
<view class="phone_login">
<uni-nav-bar :border="false" :fixed="true" left-icon="left" @clickLeft="back" statusBar="true" color="#FFFFFF" title="拍照认证" backgroundColor="rgba(0, 0, 0, 0.1)"></uni-nav-bar>
<view class="face-icon">
<image class="icon" mode="widthFix" src="../../../static/mine/face-icon.png"></image>
</view>
<view class="btn_1 box_bg zongse" v-if="showP" @click="snapshotPusher()">拍照认证</view>
</view>
</template>
<script>
// #ifdef APP
import permission from "@/util/permission.js";
// #endif
export default {
data() {
return {
realname: '',
idcard: '',
image:'',
imgData: '',
pusher: null,
scanWin: null,
faceInitTimeout: null,
snapshTimeout: null,
uploadFileTask: null,
cilckSwitch: false, //防止多次点击
showP:false
}
},
onLoad(options) {
this.idcard=options.idcard;
this.realname=options.realname;
//#ifdef APP-PLUS
this.faceInit();
//#endif
},
onShow() {
})
// #endif
},
onHide() {
// console.log('hide')
this.faceInitTimeout && clearTimeout(this.faceInitTimeout);
this.snapshTimeout && clearTimeout(this.snapshTimeout);
//this.scanWin.hide();
},
methods: {
//初始化
faceInit() {
let that=this;
uni.showLoading({
title:'加载中...'
})
this.faceInitTimeout = setTimeout(async () => {
//创建livepusher
if (uni.getSystemInfoSync().platform === 'android') {
const data1 = await permission.requestAndroidPermission(
"android.permission.RECORD_AUDIO")
const data2 = await permission.requestAndroidPermission("android.permission.CAMERA")
if (data1 == 1 && data2 == 1) {
this.pusherInit();
}
} else {
this.pusherInit();
}
// 覆盖在视频之上的内容,根据实际情况编写
// 利用plus.webview.create将扫描框页面及扫描动画(xxx.html)覆盖在视频之上;
// this.scanWin = plus.webview.create('/static/456.html', '', {
// background: 'transparent'
// });
// //新引入的webView显示
// this.scanWin.show();
},2000);
},
//初始化播放器
pusherInit() {
// 获取当前窗口
const currentWebview = this.$mp.page.$getAppWebview();
// 创建推流,url不填写代表不上传
this.pusher = plus.video.createLivePusher('livepusher',{
url: '',
top: '10%',
left: '15%',
width: '70%',
height: '300px',
position: 'absolute',
muted: true,
orientation:'vertical',
'z-index': 999,
});
// 将推流对象加到当前页面中
currentWebview.append(this.pusher);
// 4.异步反转摄像头和执行快照
this.faceTimeout = setTimeout(() => {
//反转摄像头
this.pusher.switchCamera();
this.pusher.orientation
//开始预览
this.pusher.preview();
this.showP=true;
uni.hideLoading();
}, 1000)
},
//快照
snapshotPusher() {
if (this.cilckSwitch) {
uni.showToast({
title: '请勿频繁点击',
icon: 'none'
})
return
}
this.cilckSwitch = true
let that = this
uni.showLoading({
title:'人脸采集中,请拿稳设备',
icon:'none'
})
that.snapshTimeout = setTimeout(() => {
that.pusher.snapshot(
e => {
//拿到本地文件路径
var src = e.tempImagePath;
uni.hideLoading();
//获取图片base64
that.getMinImage(src);
that.cilckSwitch = false
},
function(e) {
plus.nativeUI.alert('snapshot error: ' + JSON.stringify(e));
that.cilckSwitch = false
}
);
}, 3000);
},
//使用plus.zip.compressImage压缩图片
getMinImage(imgPath) {
let that=this;
uni.showLoading({
title: '数据对比中...',
icon: 'none'
})
let zipParams={};
uni.getSystemInfo({
success: function (info) {
if (info.platform == 'ios') {
zipParams={
src: imgPath,
dst: imgPath,
overwrite: true,
quality:70,
width:'300px',
height:'400px'
}
} else {
zipParams={
src: imgPath,
dst: imgPath,
overwrite: true,
quality:70,
rotate:270,
width:'400px',
height:'300px'
}
}
}
});
plus.zip.compressImage(zipParams,
zipRes => {
setTimeout(() => {
var reader = new plus.io.FileReader();
reader.onloadend = res => {
//获取图片base64
var speech = res.target.result; //base64图片
// console.log(speech)
that.imgData = speech;
uni.hideLoading();
that.goFace();
};
//一定要使用plus.io.convertLocalFileSystemURL将target地址转换为本地文件地址,否则readAsDataURL会找不到文件
reader.readAsDataURL(plus.io.convertLocalFileSystemURL(zipRes.target));
}, 1000);
},
function(error) {
console.log('Compress error!', error);
}
);
},
//人脸照片校验
goFace(){
let that=this;
let images=that.imgData;
// #ifdef APP
// uni.getSystemInfo({
// success: function (info) {
// if (info.platform == 'ios') {
// images=images.replace('data:image/png;base64,','');
// } else {
// images=images.replace('data:image/jpeg;base64,','');
// }
// }
// });
images=images.replace('data:image/jpeg;base64,','');
// console.log(images);
// return false;
that.req({
url: 'xxxxxxxxxxxxx',
Loading: true,
data: {
realname: that.realname,
idcard: that.idcard,
image:images
},
success(res) {
if (res.code == 200) {
uni.setStorageSync('is_realuser','1');//0 未实名 1已实名
uni.showToast({
title: "恭喜您,认证成功!",
duration:2000
})
setTimeout(function() {
uni.switchTab({
url:'/pages/shouye/index'
})
}, 2000);
}else{
uni.showToast({
title: res.msg,
icon: 'none',
duration:3000
})
setTimeout(function(){
uni.navigateBack();
},2000)
}
}
})
// #endif
},
},
}
</script>
<style lang="scss">
.text_head {
font-size: 36rpx;
font-weight: bold;
padding-left: 30rpx;
box-sizing: border-box;
margin-top: 48rpx;
}
button::after {
border: none;
background: none;
color: none;
}
.btn_1 {
width: 690rpx;
height: 98rpx;
border-radius: 10rpx;
margin:300rpx auto 0;
font-size: 32rpx;
font-weight: 400;
color: #FFFFFF;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
}
.face-icon{
margin:80rpx auto;
display:flex;
flex-direction: row;
align-items: center;
justify-content: center;
.icon{
width:300rpx;
height:300rpx;
}
}
.phone_login {
// padding-bottom: 200rpx;
width: 100vw;
min-height: 100vh;
box-sizing: border-box;
position: relative;
}
</style>