专家人脸整合已有登录页面
This commit is contained in:
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user