专家人脸整合已有登录页面

This commit is contained in:
袁帅
2022-08-17 17:21:01 +08:00
parent f58c6f942c
commit 946939b850
3 changed files with 232 additions and 13 deletions

View File

@ -3,19 +3,19 @@
<head>
<meta charset="utf-8">
<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 src="jquery.webcam.min.js"></script>
</head>
<body>
<div id="webcam" style="float: left; clear: both;"></div>
<input id="snapBtn" type="button" value="人脸识别" style="float: left; clear: both;"/>
<img id="base64image" src='' width="450" height="320" style="float: left; clear: both;"/>
<!-- <input id="snapBtn" type="button" value="人脸识别" style="float: left; clear: both;"/>
<img id="base64image" src='' width="450" height="320" style="float: left; clear: both;"/> -->
<script type="text/javascript">
var image = new Array();
var pos = 0;
var w = 480;//图片的宽高,无论图片的尺寸是否大于画布的尺寸都能自适应
var h = 320;
var w = 382;//图片的宽高,无论图片的尺寸是否大于画布的尺寸都能自适应
var h = 200;
$(document).ready(function() {
$("#webcam").webcam({
width: w,
@ -50,12 +50,13 @@
});
$('#snapBtn').on('click', function() {
webcam.capture();
});
// $('#snapBtn').on('click', function() {
// webcam.capture();
// });
function receiveMessageFromParent ( event ) {
$('#base64image').attr('src', 'data:image/jpg;base64,' + event.data.data);
webcam.capture();
//$('#base64image').attr('src', 'data:image/jpg;base64,' + event.data.data);
};
window.addEventListener('message', receiveMessageFromParent, false);

View File

@ -26,7 +26,7 @@ export default class FrameFaceLogin extends React.Component {
return (
<div style={{ height: "100%" }}>
{/* 设置Iframe 盒子的宽度 */}
<div style={{ minHeight: "calc(70vh - 100px)", position: "relative" }}>
<div style={{ minHeight: "200px", position: "relative" }}>
{/* 这个是打包后的Iframe 地址要到webpack中配置打包地址 */}
<FrameLoader url="/faceLoginIE/index.html" />
</div>

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { Form, Button, Input, Row, Col, Modal, Spin, message } from 'antd';
import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons';
import { UserOutlined, LockOutlined, SafetyCertificateOutlined, VideoCameraOutlined } from '@ant-design/icons';
import './style.less';
import { changePass } from './service';
import logo from '@/images/login/logoPic.png';
@ -8,6 +8,7 @@ import { refreshTokenApi, ZjfakeAccountLogin } from '@/services/login';
import { history } from 'umi';
import cookie from 'react-cookies';
import moment from 'moment';
import FrameFaceLogin from '../faceLogin/FrameFaceLogin';
const layout = {
labelCol: { span: 7 },
@ -22,6 +23,9 @@ const Index: React.FC<{}> = () => {
const [changeForm] = Form.useForm();
const [isModalVisible, setIsModalVisible] = useState<boolean>(false)
const [spinning, setSping] = useState<boolean>(false);//加载遮罩
const [isFaceLogin, setIsFaceLogin] = useState<boolean>(false);
const video = useRef();
const whetherIE = useRef<boolean>(false);
const genRandomString = (len: number) => {
const text = 'abcdefghijklmnopqrstuvwxyz0123456789';
@ -101,6 +105,186 @@ const Index: React.FC<{}> = () => {
}
}
//登录模式改变事件
const LoginModeChangeEvent = (mode: any) => {
switch(mode){
case 1:
setIsFaceLogin(true);
InitMedia();
break;
case 2:
setIsFaceLogin(false);
break;
}
}
//浏览器类型
const BrowserType = () =>{
//取得浏览器的userAgent字符串
var userAgent = navigator.userAgent;
//判断是否IE<11
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1;
//判断是否IE的Edge浏览器
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE;
//判断是否IE11
var isIE11 = userAgent.indexOf("Trident") > -1 && userAgent.indexOf("rv:11.0") > -1;
if(isIE){
var reIE = new RegExp("MSIE(\\d+\\.\\d+);");
reIE.test(userAgent);
var fIEVersion = parseFloat(RegExp["$1"]);
if(fIEVersion == 7){
return 7;
}else if(fIEVersion == 8){
return 8;
}else if(fIEVersion == 9){
return 9;
}else if(fIEVersion == 10){
return 10;
}else{
//IE版本<=7
return 6;
}
}else if(isEdge){
return 'edge';
}else if(isIE11){
//IE11
whetherIE.current = true;
return 11;
}else{
//不是IE浏览器
return -1;
}
}
//初始化video
const InitMedia = () => {
BrowserType();
if(!whetherIE.current){
InitUserMedia({video : {width: 480, height: 320}}, success, error);
}
};
//访问用户媒体设备的兼容方法
const InitUserMedia = (constraints: any, success: any, error: any) => {
if (navigator.mediaDevices.getUserMedia) {
//最新的标准API
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints,success, error);
} else if (navigator.mozGetUserMedia) {
//firfox浏览器
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
//旧版API
navigator.getUserMedia(constraints, success, error);
}
}
//调用媒体设备成功回调方法
const success = (stream: any) => {
//兼容webkit核心浏览器
const CompatibleURL = window.URL || window.webkitURL;
//将视频流设置为video元素的源
console.log(stream);
//video.src = CompatibleURL.createObjectURL(stream);
video.current.srcObject = stream;
video.current.play();
}
//调用媒体设备失败回调方法
const error = (error:any) => {
message.warn('无法获取到摄像头权限,请确认是否存在摄像头及是否授权使用摄像头');
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
}
//base64转blob
const base64ToBlob = (base64:string) =>{
const parts = base64.split(";base64,");
const contentType = parts[0].split(":")[1];
const raw = window.atob(parts[1]);
const rawLength = raw.length;
const uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; i += 1) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
};
//人脸比对
const Recog=(image:any) =>{
if(!whetherIE.current){
setSping(true);
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);
canvas.toBlob(function (result:any) {
var formData = new FormData();
formData.append('multipartFiles', result, 'upload_face.jpeg');
const url = 'http://127.0.0.1:8081/outer/v1.0/stock/logicStock/importStockDepotRelation';
window.fetch(url,{
method:'post',
mode:'cors',
body : formData
}).then(res => res.json()).then(res => {
if (null != res) {
setSping(false);
var _data = eval("(" + res['data'] + ")");
var _similarity = _data['UNI_BSS_BODY']['FACE_COMPARE_RSP']['SIMILARITY'];
message.success('人脸比对成功:相似度' + _similarity);
//关闭摄像头
//video.current.srcObject.getTracks()[0].stop();
} else {
setSping(false);
message.error('人脸比对失败');
}
}).catch(e =>{
console.log(e);
}).finally(() => {
setSping(false);
});
});
}else{
setSping(true);
const url = 'http://127.0.0.1:8081/outer/v1.0/stock/logicStock/rgbArray2Base64';
window.fetch(url,{
method:'post',
body : JSON.stringify({//post请求参数
type: 'pixel',
rgb: image
})
}).then(res => res.json()).then(res => {
//base64图片进行人脸比对
var formData = new FormData();
formData.append('multipartFiles', base64ToBlob( 'data:image/jpg;base64,' + res.data), 'upload_face.jpeg');
console.log(3);
const url2 = 'http://127.0.0.1:8081/outer/v1.0/stock/logicStock/importStockDepotRelation';
window.fetch(url2,{
method:'post',
mode:'cors',
body : formData
}).then(res => res.json()).then(res => {
if (null != res) {
setSping(false);
var _data = eval("(" + res['data'] + ")");
var _similarity = _data['UNI_BSS_BODY']['FACE_COMPARE_RSP']['SIMILARITY'];
message.success('人脸比对成功:相似度' + _similarity);
//关闭摄像头
//video.current.srcObject.getTracks()[0].stop();
} else {
setSping(false);
message.error('人脸比对失败');
}
}).catch(e =>{
console.log(e);
}).finally(() => {
setSping(false);
});
})
}
}
//发送拍照请求
const SendRequestToCapture = () => {
const childFrameObj = document.getElementById('faceLoginFrame');
childFrameObj.contentWindow.postMessage('capture', '*');
}
useEffect(() => {
cookie.remove('mall3_token');
sessionStorage.clear();
@ -118,6 +302,7 @@ const Index: React.FC<{}> = () => {
<div className="main">
<div className="text">
<h3> </h3>
{!isFaceLogin ? (
<Form
name="basic"
className="form-box"
@ -148,6 +333,7 @@ const Index: React.FC<{}> = () => {
<LockOutlined style={{ fontSize: '18px' }} className="site-form-item-icon" />
}
placeholder="请输入密码"
addonAfter={<VideoCameraOutlined onClick={() => LoginModeChangeEvent(1)}/>}
/>
</Form.Item>
@ -182,7 +368,38 @@ const Index: React.FC<{}> = () => {
</Button>
</Form.Item>
</Form>
</Form>):(
<Form
name="basic"
className="form-box"
initialValues={{ remember: true }}
form={form}
//onFinish={handleSubmit}
// onFinishFailed={onFinishFailed}
>
<Form.Item
label=""
name="userName"
rules={[{ required: true, message: '请输入用户名!' }]}
>
<Input
prefix={
<UserOutlined style={{ fontSize: '18px' }} className="site-form-item-icon" />
}
placeholder="请输入用户名"
addonAfter = {<LockOutlined onClick={() => LoginModeChangeEvent(2)}/>}
/>
</Form.Item>
{/* 加载摄像头 */}
<Form.Item>
{!whetherIE.current ? (<video ref={video} width="382" height="200"></video>):(<FrameFaceLogin faceCompareEvent = {Recog}/>)}
</Form.Item>
<Form.Item>
<Button type="primary" className="w100" htmlType="submit" onClick={()=> SendRequestToCapture()}>
</Button>
</Form.Item>
</Form>)}
</div>
</div>
{/* <div className="footer">版权所有:中国联合网络通信有限公司</div> */}
@ -309,3 +526,4 @@ const Index: React.FC<{}> = () => {
};
export default Index;