Merge branch 'uat-export-face-live-detection' into 'release_electronic_bid_evaluation_room'
10.31 人脸识别-活体检测 See merge request eshop/fe_service_ebtp_frontend!44
This commit is contained in:
@ -17,6 +17,11 @@ export default {
|
|||||||
// changeOrigin: true,
|
// changeOrigin: true,
|
||||||
// pathRewrite: { '^': '' },
|
// pathRewrite: { '^': '' },
|
||||||
// },
|
// },
|
||||||
|
'/living/api/*': {
|
||||||
|
target: 'https://ai.cubigdata.cn:5001',//连接天宫的ng
|
||||||
|
changeOrigin: true,
|
||||||
|
pathRewrite: { '/living/api': '' },
|
||||||
|
},
|
||||||
'/api/*': {
|
'/api/*': {
|
||||||
target: 'http://10.242.31.158:18022',//连接天宫的ng
|
target: 'http://10.242.31.158:18022',//连接天宫的ng
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
@ -4,8 +4,11 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>jQuery-webcam-master</title>
|
<title>jQuery-webcam-master</title>
|
||||||
<!-- <link href="cs.css" rel="stylesheet" type="text/css"> -->
|
<!-- <link href="cs.css" rel="stylesheet" type="text/css"> -->
|
||||||
<script src="jquery.js"></script>
|
<script type="text/javascript" src="jquery-3.6.1.min.js"></script>
|
||||||
<script src="jquery.webcam.min.js"></script>
|
<script type="text/javascript" src="jquery.webcam.min.js"></script>
|
||||||
|
<script type="text/javascript" src="jsrsasign-latest-all-min.js"></script>
|
||||||
|
<script type="text/javascript" src="moment.js"></script>
|
||||||
|
<script type="text/javascript" src="living-jq.min.js"></script>
|
||||||
<!-- <script src="excanvas.js"></script> -->
|
<!-- <script src="excanvas.js"></script> -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -14,13 +17,10 @@
|
|||||||
<img id="base64image" src='' width="450" height="320" style="float: left; clear: both;"/> -->
|
<img id="base64image" src='' width="450" height="320" style="float: left; clear: both;"/> -->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var pos = 0, ctx = null, saveCB,w = 380,h= 200, image = new Array();
|
var pos = 0, ctx = null, saveCB,w = 380,h= 200, image = new Array();
|
||||||
var canvas = document.createElement("canvas");//创建画布指定宽度和高度
|
var lv = null;
|
||||||
canvas.setAttribute('width', 320);
|
var liveDetectPhoto = null;
|
||||||
canvas.setAttribute('height', 240);
|
var liveDetectPhotoUrl = null;
|
||||||
document.body.appendChild(canvas);
|
var canvas = null;
|
||||||
// canvas = window.G_vmlCanvasManager.initElement(canvas);
|
|
||||||
ctx = canvas.getContext("2d");//设置画布为2d,未来可能支持3d
|
|
||||||
image = ctx.getImageData(0, 0, 320, 240);//截图320*240,即整个画布作为有效区(cutx?)
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$("#webcam").webcam({
|
$("#webcam").webcam({
|
||||||
width: w,
|
width: w,
|
||||||
@ -46,8 +46,9 @@
|
|||||||
if (pos == 4 * 320 * 240) {
|
if (pos == 4 * 320 * 240) {
|
||||||
//把图像放到画布上,输出为png格式
|
//把图像放到画布上,输出为png格式
|
||||||
ctx.putImageData(img, 0, 0);
|
ctx.putImageData(img, 0, 0);
|
||||||
window.parent.postMessage({"image": canvas.toDataURL("image/png")}, '*');
|
//liveDetectPhotoUrl = canvas.toDataURL("image/png");
|
||||||
image = new Array();
|
liveDetectPhoto = base64ToBlob(canvas.toDataURL("image/png"));
|
||||||
|
//window.parent.postMessage({"image": liveDetectPhoto}, '*');
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
// image.push(data);
|
// image.push(data);
|
||||||
@ -59,8 +60,14 @@
|
|||||||
// pos = 0;
|
// pos = 0;
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
|
|
||||||
onCapture: function(data) {
|
onCapture: function(data) {
|
||||||
|
canvas = document.createElement("canvas");//创建画布指定宽度和高度
|
||||||
|
canvas.setAttribute('width', 320);
|
||||||
|
canvas.setAttribute('height', 240);
|
||||||
|
// document.body.appendChild(canvas);
|
||||||
|
// canvas = window.G_vmlCanvasManager.initElement(canvas);
|
||||||
|
ctx = canvas.getContext("2d");//设置画布为2d,未来可能支持3d
|
||||||
|
image = ctx.getImageData(0, 0, 320, 240);//截图320*240,即整个画布作为有效区(cutx?)
|
||||||
webcam.save();
|
webcam.save();
|
||||||
// Show a flash for example
|
// Show a flash for example
|
||||||
},
|
},
|
||||||
@ -79,19 +86,105 @@
|
|||||||
// $('#snapBtn').on('click', function() {
|
// $('#snapBtn').on('click', function() {
|
||||||
// webcam.capture();
|
// webcam.capture();
|
||||||
// });
|
// });
|
||||||
|
window.addEventListener('message', receiveMessageFromParent, false);
|
||||||
|
|
||||||
function receiveMessageFromParent ( event ) {
|
function receiveMessageFromParent ( event ) {
|
||||||
if(event.data == 'releaseCamera'){
|
if(event.data == 'releaseCamera'){
|
||||||
location.reload();
|
location.reload();
|
||||||
}else if(event.data = 'capture'){
|
}else if(event.data = 'capture'){
|
||||||
webcam.capture();
|
liveDetectStart();
|
||||||
|
//webcam.capture();
|
||||||
}
|
}
|
||||||
//$('#base64image').attr('src', 'data:image/jpg;base64,' + event.data.data);
|
//$('#base64image').attr('src', 'data:image/jpg;base64,' + event.data.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('message', receiveMessageFromParent, false);
|
function setLiveDetectToken() {
|
||||||
|
let appKey= 'nkYy3g1yT0alE8pF6a1UTC4I';
|
||||||
|
let appSecrect = 'L30zHpTyAtTlY7tTCpbzdxxKCQgwWIQL';
|
||||||
|
// Header
|
||||||
|
var header = {
|
||||||
|
typ: "JWT", // 声明类型
|
||||||
|
alg: "HS256" // 声明加密的算法 通常直接使用 HMAC SHA256
|
||||||
|
};
|
||||||
|
|
||||||
|
var payload = {
|
||||||
|
iss: appKey,
|
||||||
|
iat: moment().unix(),
|
||||||
|
exp: moment()
|
||||||
|
.add(29, "minutes")
|
||||||
|
.unix()
|
||||||
|
};
|
||||||
|
var sHeader = JSON.stringify(header);
|
||||||
|
var sPayload = JSON.stringify(payload);
|
||||||
|
var sJWT = KJUR.jws.JWS.sign("HS256", sHeader, sPayload, {
|
||||||
|
utf8: appSecrect,
|
||||||
|
});
|
||||||
|
return sJWT;
|
||||||
|
}
|
||||||
|
|
||||||
|
function liveDetectStart () {
|
||||||
|
liveDetectStop();
|
||||||
|
let _lv = new Living(null, {
|
||||||
|
timer: 10000,
|
||||||
|
rate: 1000,
|
||||||
|
action : [1,3,2],
|
||||||
|
token: setLiveDetectToken(),
|
||||||
|
proxy:'/living/api',
|
||||||
|
getFacePicture:function(){
|
||||||
|
webcam.capture();
|
||||||
|
return {file:liveDetectPhoto};
|
||||||
|
},
|
||||||
|
//开始活体检测,此时token已鉴权成功
|
||||||
|
onDetectStart:function(){
|
||||||
|
},
|
||||||
|
//每轮检测开始
|
||||||
|
onDetectActionStart:function(action){
|
||||||
|
},
|
||||||
|
//每轮检测计时
|
||||||
|
onDetectActionProgress:function(action,timer){
|
||||||
|
var actionAndTimer = {
|
||||||
|
arg1: action,
|
||||||
|
arg2: timer
|
||||||
|
};
|
||||||
|
//必须传递字符串
|
||||||
|
window.parent.postMessage({"actionAndTimer": actionAndTimer}, '*');
|
||||||
|
},
|
||||||
|
//每轮检测结束
|
||||||
|
onDetectActionFinish:function(action,data){
|
||||||
|
console.log(data)
|
||||||
|
},
|
||||||
|
//活体检测完成
|
||||||
|
onDetectFinish:function(data){
|
||||||
|
window.parent.postMessage({"detectResult": data}, '*');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//开始检测
|
||||||
|
_lv.start();
|
||||||
|
lv = _lv;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 停止活体检测
|
||||||
|
*/
|
||||||
|
function liveDetectStop (){
|
||||||
|
lv && lv.stop();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* base64Url转blob
|
||||||
|
*/
|
||||||
|
function base64ToBlob(base64) {
|
||||||
|
var parts = base64.split(";base64,");
|
||||||
|
var contentType = parts[0].split(":")[1];
|
||||||
|
var raw = window.atob(parts[1]);
|
||||||
|
var rawLength = raw.length;
|
||||||
|
var uInt8Array = new Uint8Array(rawLength);
|
||||||
|
for (let i = 0; i < rawLength; i += 1) {
|
||||||
|
uInt8Array[i] = raw.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return new Blob([uInt8Array], { type: contentType });
|
||||||
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
2
public/faceLoginIE/jquery-3.6.1.min.js
vendored
Normal file
2
public/faceLoginIE/jquery-3.6.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10881
public/faceLoginIE/jquery.js
vendored
10881
public/faceLoginIE/jquery.js
vendored
File diff suppressed because it is too large
Load Diff
239
public/faceLoginIE/jsrsasign-latest-all-min.js
vendored
Normal file
239
public/faceLoginIE/jsrsasign-latest-all-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/faceLoginIE/living-jq.min.js
vendored
Normal file
1
public/faceLoginIE/living-jq.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(_0x12ba10,_0x363f5a){if(typeof define==='function'&&define['amd']){define(['jquery'],_0x363f5a);}else if(typeof exports==='object'){module['exports']=_0x363f5a(require('./js/jquery-3.6.1.min'));}else{_0x12ba10['Living']=_0x363f5a(_0x12ba10['$']);}}(this,function(_0x2283ac){function _0x28601d(_0x4d0a63,_0x2a999c){this['page']=_0x4d0a63;this['token']=_0x2a999c['token'];this['proxy']=_0x2a999c['proxy'];this['timer']=_0x2a999c['timer']||0xf0f5d^0xf284d;this['rate']=_0x2a999c['rate']||0xaff99^0xafffd;this['action']=_0x2a999c['action']||[];this['onDetectStart']=_0x2a999c['onDetectStart']&&typeof _0x2a999c['onDetectStart']==='function'?_0x2a999c['onDetectStart']:function(){};this['onDetectActionProgress']=_0x2a999c['onDetectActionProgress']&&typeof _0x2a999c['onDetectActionProgress']==='function'?_0x2a999c['onDetectActionProgress']:function(){};this['onDetectActionStart']=_0x2a999c['onDetectActionStart']&&typeof _0x2a999c['onDetectActionStart']==='function'?_0x2a999c['onDetectActionStart']:function(){};this['onDetectActionFinish']=_0x2a999c['onDetectActionFinish']&&typeof _0x2a999c['onDetectActionFinish']==='function'?_0x2a999c['onDetectActionFinish']:function(){};this['onDetectFinish']=_0x2a999c['onDetectFinish']&&typeof _0x2a999c['onDetectFinish']==='function'?_0x2a999c['onDetectFinish']:function(){};this['getFacePicture']=_0x2a999c['getFacePicture']&&typeof _0x2a999c['getFacePicture']==='function'?_0x2a999c['getFacePicture']:function(){};this['requestId']='';this['t']=null;}_0x28601d['prototype']={'start':function(){let _0x3378f0=this;this['getRequestId'](function(_0x5c3b12){_0x3378f0['requestId']=_0x5c3b12;_0x3378f0['checking']();_0x3378f0['onDetectStart']();});},'getRequestId':function(_0x37686a){let _0xfd3f05=this;_0x2283ac['ajax']({'type':'get','url':_0xfd3f05['proxy']+'/openapi/livingDetect/v1/getRequestId','dataType':'json','beforeSend':function(_0x5578ed){_0x5578ed['setRequestHeader']('Authorization','Bearer\x20'+_0xfd3f05['token']);},'success':function(_0x8186d6){if(_0x8186d6['code']==='0'){_0x37686a&&_0x37686a(_0x8186d6['data']['requestId']);}},'error':function(_0x3ed909){console['log'](_0x3ed909);}});},'checkAction':function(_0xe33a8c){let _0x1f4ccb=this;this['timeLoop'](_0x1f4ccb['action'][_0xe33a8c])['then'](function(_0x239a5a){_0x1f4ccb['stopLoop']();_0x1f4ccb['onDetectActionFinish'](_0x1f4ccb['action'][_0xe33a8c],{'code':0x1,'msg':'动作检测成功'});if(_0x1f4ccb['action'][_0xe33a8c+(0x1b77b^0x1b77a)]){_0x1f4ccb['checkAction'](_0xe33a8c+(0xb7504^0xb7505));}if(_0xe33a8c===_0x1f4ccb['action']['length']-(0x5f816^0x5f817)){_0x1f4ccb['stop']();_0x1f4ccb['onDetectFinish']({'code':0x1,'msg':'活体检测成功','file':_0x239a5a});}},function(){_0x1f4ccb['stop']();_0x1f4ccb['onDetectActionFinish'](_0x1f4ccb['action'][_0xe33a8c],{'code':0x0,'msg':'动作检测失败'});_0x1f4ccb['onDetectFinish']({'code':0x0,'msg':'活体检测失败'});});},'checking':function(){if(!this['action']['length']){return;}this['checkAction'](0x8171f^0x8171f);},'timeLoop':function(_0x358c73){let _0x3b2170=this;let _0x3d2180=this['rate'];this['onDetectActionStart'](_0x358c73,_0x3b2170['timer']);let _0x57c115=0xdfcde^0xdfcdf;var _0x3e15bf=_0x2283ac['Deferred']();let _0x19a9c8=_0x3b2170['timer'];_0x3b2170['t']=setInterval(function(){if(_0x19a9c8===(0x3a426^0x3a426)){_0x3b2170['stopLoop']();_0x3e15bf['reject']();return;}_0x19a9c8-=_0x3d2180;_0x3b2170['onDetectActionProgress'](_0x358c73,_0x19a9c8);_0x3b2170['upload'](_0x57c115++,_0x358c73,function(_0x4101fe){_0x3e15bf['resolve'](_0x4101fe);},function(){_0x3e15bf['reject']();});},_0x3d2180);return _0x3e15bf['promise']();},'upload':function(_0x31444d,_0x3278d8,_0x31de13,_0xb8cec1){let _0x21beb0=this;let _0xac3985=this['getFacePicture']();var _0x53190b=new FormData();_0x53190b['append']('picFile',_0xac3985['file']);_0x53190b['append']('requestId',_0x21beb0['requestId']||'');_0x53190b['append']('actionType',_0x3278d8);_0x53190b['append']('picSerialNumber',_0x31444d+'');_0x2283ac['ajax']({'type':'POST','url':_0x21beb0['proxy']+'/openapi/livingDetect/v1/start?time='+new Date()['getTime'](),'contentType':![],'processData':![],'beforeSend':function(_0x57d52c){_0x57d52c['setRequestHeader']('Authorization','Bearer\x20'+_0x21beb0['token']);},'data':_0x53190b,'success':function(_0x2d4654){if(_0x2d4654['code']==='0'){if(_0x2d4654['data']['isLiving']==='1'){_0x31de13&&_0x31de13({'file':_0xac3985['file']});}}},'error':function(_0x2da092){console['log'](_0x2da092);_0xb8cec1&&_0xb8cec1();}});},'stopLoop':function(){clearInterval(this['t']);},'stop':function(){this['stopLoop']();this['requestId']='';}};return _0x28601d;}));
|
4600
public/faceLoginIE/moment.js
Normal file
4600
public/faceLoginIE/moment.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,9 +14,14 @@ export default class FrameFaceLogin extends React.Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// 接收Iframe传递的数据
|
// 接收Iframe传递的数据
|
||||||
window.addEventListener("message", (e) => {
|
window.addEventListener("message", (e) => {
|
||||||
const { image } = e.data || {}; //传递的数据
|
const{image,detectResult,actionAndTimer} = e.data|| {};
|
||||||
if (image) {
|
if(image){
|
||||||
this.props.faceCompareEvent(image);
|
this.props.faceCompareEvent2(image);
|
||||||
|
}
|
||||||
|
else if(detectResult){
|
||||||
|
this.props.faceCompareEvent(detectResult);
|
||||||
|
}else if(actionAndTimer){
|
||||||
|
this.props.faceDetectStatusEvent(actionAndTimer.arg1, actionAndTimer.arg2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import React, { useEffect, useState, useRef } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { Form, Button, Input, Row, Col, Modal, Spin, message, Tabs } from 'antd';
|
import { Form, Button, Input, Row, Col, Modal, Spin, message, Tabs } from 'antd';
|
||||||
import { UserOutlined, LockOutlined, SafetyCertificateOutlined, VideoCameraOutlined } from '@ant-design/icons';
|
import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
import { changePass, rgbToBase64 } from './service';
|
import { changePass } from './service';
|
||||||
import logo from '@/images/login/logoPic.png';
|
import logo from '@/images/login/logoPic.png';
|
||||||
import { refreshTokenApi, ZjfakeAccountLogin, ZjfakeFaceLogin } from '@/services/login';
|
import { refreshTokenApi, ZjfakeAccountLogin, ZjfakeFaceLogin } from '@/services/login';
|
||||||
import { history } from 'umi';
|
import { history } from 'umi';
|
||||||
import cookie from 'react-cookies';
|
import cookie from 'react-cookies';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import FrameFaceLogin from '../faceLogin/FrameFaceLogin';
|
import FrameFaceLogin from '../faceLogin/FrameFaceLogin';
|
||||||
import { fromPairs } from 'lodash';
|
import LivingNotIE from './living.min.js';
|
||||||
|
import { _KJUR } from './jsrsasign-latest-all-min';
|
||||||
|
import { time } from 'echarts';
|
||||||
|
|
||||||
const layout = {
|
const layout = {
|
||||||
labelCol: { span: 7 },
|
labelCol: { span: 7 },
|
||||||
@ -36,6 +38,146 @@ const Index: React.FC<{}> = () => {
|
|||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
|
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
|
||||||
const [faceLoginDisable, setFaceLoginDisable] = useState<boolean>(false);
|
const [faceLoginDisable, setFaceLoginDisable] = useState<boolean>(false);
|
||||||
|
const lv = useRef<LivingNotIE>();
|
||||||
|
const [timerShow, setTimeShow] = useState<boolean>(false);
|
||||||
|
const [itemShow, setItemShow] = useState<boolean>(false);
|
||||||
|
const [action, setAction] = useState<number>(1);
|
||||||
|
const [timer, setTimer] = useState<number>(10000);
|
||||||
|
/**
|
||||||
|
* 设置活体检测token
|
||||||
|
*/
|
||||||
|
const setLiveDetectToken = () =>{
|
||||||
|
let appKey= 'nkYy3g1yT0alE8pF6a1UTC4I'
|
||||||
|
let appSecrect = 'L30zHpTyAtTlY7tTCpbzdxxKCQgwWIQL'
|
||||||
|
// Header
|
||||||
|
var header = {
|
||||||
|
typ: "JWT", // 声明类型
|
||||||
|
alg: "HS256" // 声明加密的算法 通常直接使用 HMAC SHA256
|
||||||
|
};
|
||||||
|
|
||||||
|
var payload = {
|
||||||
|
iss: appKey,
|
||||||
|
iat: moment().unix(),
|
||||||
|
exp: moment()
|
||||||
|
.add(29, "minutes")
|
||||||
|
.unix()
|
||||||
|
};
|
||||||
|
var sHeader = JSON.stringify(header);
|
||||||
|
var sPayload = JSON.stringify(payload);
|
||||||
|
var sJWT = _KJUR.jws.JWS.sign("HS256", sHeader, sPayload, {
|
||||||
|
utf8: appSecrect,
|
||||||
|
});
|
||||||
|
console.log(sJWT);
|
||||||
|
return sJWT;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 开始人脸识别(活体和比对)
|
||||||
|
*/
|
||||||
|
const liveDetectStart = () => {
|
||||||
|
liveDetectStop();
|
||||||
|
let _lv = new LivingNotIE(null, {
|
||||||
|
timer: 10000,
|
||||||
|
action : [1,3,2],
|
||||||
|
token: setLiveDetectToken(),
|
||||||
|
proxy:'/living/api',
|
||||||
|
getFacePicture:()=>{
|
||||||
|
return getLiveDetectFile()
|
||||||
|
},
|
||||||
|
//开始活体检测,此时token已鉴权成功
|
||||||
|
onDetectStart:()=>{
|
||||||
|
setSubmitLoading(true);
|
||||||
|
},
|
||||||
|
//每轮检测开始
|
||||||
|
onDetectActionStart:(action:number)=>{
|
||||||
|
setAction(action);
|
||||||
|
// this.drawCanvas()
|
||||||
|
},
|
||||||
|
//每轮检测计时
|
||||||
|
onDetectActionProgress:(action:number,timer:number)=>{
|
||||||
|
setTimer(timer);
|
||||||
|
},
|
||||||
|
//每轮检测结束
|
||||||
|
onDetectActionFinish:(action:number,data:any)=>{
|
||||||
|
// this.clearCanvas()
|
||||||
|
setTimer(10000);
|
||||||
|
console.log(data)
|
||||||
|
},
|
||||||
|
//活体检测完成
|
||||||
|
onDetectFinish:(data:any)=>{
|
||||||
|
if(data.code == 1){
|
||||||
|
setAction(4);
|
||||||
|
setTimeShow(false);
|
||||||
|
//人脸比对
|
||||||
|
hanleFaceSubmit(data.file.file, null);
|
||||||
|
}else{
|
||||||
|
message.error('活体检测失败');
|
||||||
|
setSubmitLoading(false);
|
||||||
|
}
|
||||||
|
// data.code === 1? message.success('活体检测通过'):message.error('活体检测失败')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//开始检测
|
||||||
|
_lv.start();
|
||||||
|
lv.current = _lv;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 停止活体检测
|
||||||
|
*/
|
||||||
|
const liveDetectStop = () => {
|
||||||
|
lv.current && lv.current.stop();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 给活体检测提供照片
|
||||||
|
* @returns 活体照片
|
||||||
|
*/
|
||||||
|
const getLiveDetectFile = () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.setAttribute('width', '300');
|
||||||
|
canvas.setAttribute('height', '200');
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
context.drawImage(video.current, 0, 0, 300, 200);
|
||||||
|
let _imgURI = canvas.toDataURL("image/jpeg",);
|
||||||
|
console.log(_imgURI);
|
||||||
|
let _file = base64ToBlob(_imgURI);
|
||||||
|
return {
|
||||||
|
file:_file//传给活体检测服务的文件
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const classColor = (action:any) => {
|
||||||
|
let color = '';
|
||||||
|
switch(action){
|
||||||
|
case 1:
|
||||||
|
color = '#409eff';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
color = '#5daf34';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
color = 'gold';
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
color = 'grey';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
const actionText = (action:number, timer:number) => {
|
||||||
|
let text = '';
|
||||||
|
switch(action){
|
||||||
|
case 1:
|
||||||
|
text = '对准摄像头眨眨眼('+ timer + 's)';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
text = '对准摄像头张张嘴('+ timer + 's)';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
text = '对准摄像头摇摇头('+ timer + 's)';
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
text = '请稍候,正在验证中...';
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
const genRandomString = (len: number) => {
|
const genRandomString = (len: number) => {
|
||||||
const text = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
const text = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
@ -138,6 +280,7 @@ const Index: React.FC<{}> = () => {
|
|||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.setAttribute('width', '300');
|
canvas.setAttribute('width', '300');
|
||||||
canvas.setAttribute('height', '200');
|
canvas.setAttribute('height', '200');
|
||||||
|
document.body.appendChild(canvas);
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
context.drawImage(video.current, 0, 0, 300, 200);
|
context.drawImage(video.current, 0, 0, 300, 200);
|
||||||
canvas.toBlob(function (result: any) {
|
canvas.toBlob(function (result: any) {
|
||||||
@ -236,9 +379,9 @@ const Index: React.FC<{}> = () => {
|
|||||||
};
|
};
|
||||||
//访问用户媒体设备的兼容方法
|
//访问用户媒体设备的兼容方法
|
||||||
const InitUserMedia = (constraints: any, success: any, error: any) => {
|
const InitUserMedia = (constraints: any, success: any, error: any) => {
|
||||||
if (navigator.mediaDevices.getUserMedia) {
|
if (navigator.mediaDevices?.getUserMedia) {
|
||||||
//最新的标准API
|
//最新的标准API
|
||||||
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
|
navigator.mediaDevices?.getUserMedia(constraints).then(success).catch(error);
|
||||||
} else if (navigator.webkitGetUserMedia) {
|
} else if (navigator.webkitGetUserMedia) {
|
||||||
//webkit核心浏览器
|
//webkit核心浏览器
|
||||||
navigator.webkitGetUserMedia(constraints, success, error);
|
navigator.webkitGetUserMedia(constraints, success, error);
|
||||||
@ -285,17 +428,28 @@ const Index: React.FC<{}> = () => {
|
|||||||
return new Blob([uInt8Array], { type: contentType });
|
return new Blob([uInt8Array], { type: contentType });
|
||||||
};
|
};
|
||||||
|
|
||||||
//RgbToBase64
|
const IELiveDetectFinish2 = async(data:any) => {
|
||||||
const RgbToBase64 = async (image: any) => {
|
console.log(data);
|
||||||
|
setAction(4);
|
||||||
|
hanleFaceSubmit(data, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//IELiveDetectFinish
|
||||||
|
const IELiveDetectFinish = async (data: any) => {
|
||||||
|
if(data.code != 0){
|
||||||
|
console.log(data);
|
||||||
|
setAction(4);
|
||||||
|
hanleFaceSubmit(data.file.file, null);
|
||||||
|
}else{
|
||||||
|
message.error('活体检测失败');
|
||||||
|
setSubmitLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateDetectStatus = async(action:number, timer:number)=>{
|
||||||
setSubmitLoading(true);
|
setSubmitLoading(true);
|
||||||
// await rgbToBase64({ image }).then(res => {
|
setAction(action);
|
||||||
// const _blob = base64ToBlob('data:image/jpg;base64,' + res.data);
|
setTimer(timer);
|
||||||
// hanleFaceSubmit(_blob, null);
|
|
||||||
// }).catch(e => {
|
|
||||||
// setSubmitLoading(false);
|
|
||||||
// });
|
|
||||||
console.log(1, image);
|
|
||||||
hanleFaceSubmit(base64ToBlob(image), null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//是https或者是本地
|
//是https或者是本地
|
||||||
@ -415,7 +569,8 @@ const Index: React.FC<{}> = () => {
|
|||||||
className="form-box"
|
className="form-box"
|
||||||
initialValues={{ remember: true }}
|
initialValues={{ remember: true }}
|
||||||
form={form2}
|
form={form2}
|
||||||
onFinish={hanleFaceSubmit.bind(this, null)}
|
// onFinish={hanleFaceSubmit.bind(this, null)}
|
||||||
|
onFinish={!whetherIE.current?liveDetectStart:hanleFaceSubmit.bind(this, null)}
|
||||||
// onFinishFailed={onFinishFailed}
|
// onFinishFailed={onFinishFailed}
|
||||||
>
|
>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@ -431,13 +586,20 @@ const Index: React.FC<{}> = () => {
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{/* 加载摄像头 */}
|
{/* 加载摄像头 */}
|
||||||
|
{/* <Form.Item hidden={!itemShow}>
|
||||||
|
<div>
|
||||||
|
<span style={{color:classColor(action)}}>{actionText(action)}</span>
|
||||||
|
<span hidden={!timerShow}>{Math.round(timer/1000)}</span>
|
||||||
|
</div>
|
||||||
|
</Form.Item> */}
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
{!whetherIE.current ? (<video ref={video} width="382" height="200"></video>) : (<FrameFaceLogin faceCompareEvent={RgbToBase64} />)}
|
{!whetherIE.current ? (<video ref={video} width="382" height="200"></video>) : (<FrameFaceLogin faceCompareEvent2={IELiveDetectFinish2} faceCompareEvent={IELiveDetectFinish} faceDetectStatusEvent = {UpdateDetectStatus}/>)}
|
||||||
|
{/* <video ref={video} width="382" height="200"></video> */}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
{/* onClick={() => {hanleFaceSubmit(null, null);}} */}
|
{/* onClick={() => {hanleFaceSubmit(null, null);}} */}
|
||||||
<Button type="primary" className="w100" loading={submitLoading} htmlType="submit">
|
<Button type="primary" className="w100" loading={submitLoading} htmlType="submit">
|
||||||
{submitLoading ? '请稍候,正在验证中...' : '登 录'}
|
{submitLoading ? actionText(action, Math.round(timer/1000)) : '登 录'}
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
240
src/pages/userformal/login/jsrsasign-latest-all-min.js
vendored
Normal file
240
src/pages/userformal/login/jsrsasign-latest-all-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/pages/userformal/login/living.min.js
vendored
Normal file
1
src/pages/userformal/login/living.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/*Obfuscated by JShaman.com*/import _0x4e5570 from'axios';const service=_0x4e5570['create']({'withCredentials':!![],'timeout':0x493e0});service['interceptors']['response']['use'](_0x4576b6=>{const _0x2cf0d2=_0x4576b6['data'];if(_0x2cf0d2['code']!=='0'){return Promise['reject'](_0x2cf0d2);}else{return _0x2cf0d2;}},_0x39797a=>{console['log']('err:'+_0x39797a);return Promise['reject'](_0x39797a);});const Living=function(_0x484981,_0x4b85f7){this['page']=_0x484981;this['token']=_0x4b85f7['token'];this['proxy']=_0x4b85f7['proxy'];this['timer']=_0x4b85f7['timer']||0x1c557^0x1e247;this['action']=_0x4b85f7['action']||[];this['onDetectStart']=_0x4b85f7['onDetectStart']&&typeof _0x4b85f7['onDetectStart']==='function'?_0x4b85f7['onDetectStart']:()=>{};this['onDetectActionProgress']=_0x4b85f7['onDetectActionProgress']&&typeof _0x4b85f7['onDetectActionProgress']==='function'?_0x4b85f7['onDetectActionProgress']:()=>{};this['onDetectActionStart']=_0x4b85f7['onDetectActionStart']&&typeof _0x4b85f7['onDetectActionStart']==='function'?_0x4b85f7['onDetectActionStart']:()=>{};this['onDetectActionFinish']=_0x4b85f7['onDetectActionFinish']&&typeof _0x4b85f7['onDetectActionFinish']==='function'?_0x4b85f7['onDetectActionFinish']:()=>{};this['onDetectFinish']=_0x4b85f7['onDetectFinish']&&typeof _0x4b85f7['onDetectFinish']==='function'?_0x4b85f7['onDetectFinish']:()=>{};this['getFacePicture']=_0x4b85f7['getFacePicture']&&typeof _0x4b85f7['getFacePicture']==='function'?_0x4b85f7['getFacePicture']:()=>{};this['requestId']='';this['t']=null;};Living['prototype']={'start'(){this['getRequestId'](_0x44585a=>{this['requestId']=_0x44585a;this['checking']();this['onDetectStart']();});},'getRequestId'(_0x218dee){service({'url':this['proxy']+'/openapi/livingDetect/v1/getRequestId','method':'get','headers':{'Authorization':'Bearer\x20'+this['token']}})['then'](_0x2f4ef4=>{_0x218dee&&_0x218dee(_0x2f4ef4['data']['requestId']);})['catch'](_0x353d53=>{});},'checkAction'(_0x59c5df){this['timeLoop'](this['action'][_0x59c5df])['then'](_0x54c88a=>{this['stopLoop']();this['onDetectActionFinish'](this['action'][_0x59c5df],{'code':0x1,'msg':'动作检测成功'});if(this['action'][_0x59c5df+(0xdcb67^0xdcb66)]){this['checkAction'](_0x59c5df+(0x74e70^0x74e71));}if(_0x59c5df===this['action']['length']-(0xb950a^0xb950b)){this['stop']();this['onDetectFinish']({'code':0x1,'msg':'活体检测成功','file':_0x54c88a});}},()=>{this['stop']();this['onDetectActionFinish'](this['action'][_0x59c5df],{'code':0x0,'msg':'动作检测失败'});this['onDetectFinish']({'code':0x0,'msg':'活体检测失败'});});},'checking'(){if(!this['action']['length']){return;}this['checkAction'](0xa3a2b^0xa3a2b);},'timeLoop'(_0x32ae49){this['onDetectActionStart'](_0x32ae49,this['timer']);let _0x39ad80=0xd6f06^0xd6f07;return new Promise((_0x303f4c,_0x52626b)=>{let _0x1b2e0e=this['timer'];this['t']=setInterval(()=>{if(_0x1b2e0e===(0x9c1ab^0x9c1ab)){this['stopLoop']();_0x52626b();return;}_0x1b2e0e-=0xc84fd^0xc8499;this['onDetectActionProgress'](_0x32ae49,_0x1b2e0e);this['upload'](_0x39ad80++,_0x32ae49,_0xe84666=>{_0x303f4c(_0xe84666);},()=>{_0x52626b();});},0x55152^0x55136);});},'upload'(_0x5545cb,_0x467698,_0x50c8e0,_0x476b10){let _0x1fb3e5=this['getFacePicture']();var _0x220463=new FormData();_0x220463['append']('picFile',_0x1fb3e5['file']);_0x220463['append']('requestId',this['requestId']||'');_0x220463['append']('actionType',_0x467698);_0x220463['append']('picSerialNumber',_0x5545cb+'');service({'url':this['proxy']+'/openapi/livingDetect/v1/start?time='+new Date()['getTime'](),'method':'post','headers':{'Authorization':'Bearer\x20'+this['token'],'Content-Type':'multipart/form-data'},'data':_0x220463})['then'](_0x40809d=>{if(_0x40809d['data']['isLiving']==='1'){_0x50c8e0&&_0x50c8e0({'file':_0x1fb3e5['file']});}})['catch'](_0x41359d=>{console['log'](_0x41359d);_0x476b10&&_0x476b10();});},'stopLoop'(){clearInterval(this['t']);},'stop'(){this['stopLoop']();this['requestId']='';}};export default Living;
|
Reference in New Issue
Block a user