专家人脸登录开发完成
This commit is contained in:
@ -55,7 +55,11 @@
|
||||
// });
|
||||
|
||||
function receiveMessageFromParent ( event ) {
|
||||
webcam.capture();
|
||||
if(event.data == 'releaseCamera'){
|
||||
location.reload();
|
||||
}else if(event.data = 'capture'){
|
||||
webcam.capture();
|
||||
}
|
||||
//$('#base64image').attr('src', 'data:image/jpg;base64,' + event.data.data);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { Form, Button, Input, Row, Col, Modal, Spin, message } from 'antd';
|
||||
import { Form, Button, Input, Row, Col, Modal, Spin, message, Tabs } from 'antd';
|
||||
import { UserOutlined, LockOutlined, SafetyCertificateOutlined, VideoCameraOutlined } from '@ant-design/icons';
|
||||
import './style.less';
|
||||
import { changePass, rgbToBase64 } from './service';
|
||||
@ -23,15 +23,19 @@ export interface RgbParams {
|
||||
|
||||
const Index: React.FC<{}> = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [form2] = Form.useForm();
|
||||
const [imgUrl, setImgUrl] = useState<any>('');
|
||||
const [tmpToken, setTmpToken] = useState<any>('');
|
||||
const remainingTime = 3 //刷新token的剩余时间,单位小时
|
||||
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 mediaStreamTrack = useRef<any>();
|
||||
const { TabPane } = Tabs;
|
||||
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
|
||||
const [faceLoginDisable, setFaceLoginDisable] = useState<boolean>(false);
|
||||
|
||||
const genRandomString = (len: number) => {
|
||||
const text = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
@ -84,8 +88,28 @@ const Index: React.FC<{}> = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const onChange = (key: string) => {
|
||||
if(key == '2'){
|
||||
BrowserType();
|
||||
InitMedia();
|
||||
}else{
|
||||
if(allowedToFaceLogin()){
|
||||
if(whetherIE.current){
|
||||
releaseCamera('faceLoginFrame');
|
||||
}else{
|
||||
mediaStreamTrack.current?.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const releaseCamera = (id:string) => {
|
||||
const childFrameObj = document.getElementById(id);
|
||||
childFrameObj?.contentWindow?.postMessage('releaseCamera', '*');
|
||||
}
|
||||
|
||||
const hanleFaceSubmit = async (multipartFiles: any, values: any) => {
|
||||
let userName = form.getFieldValue('userName');
|
||||
let userName = form2.getFieldValue('userName');
|
||||
if(whetherIE.current){
|
||||
if(!multipartFiles){
|
||||
const childFrameObj = document.getElementById('faceLoginFrame');
|
||||
@ -96,13 +120,17 @@ const Index: React.FC<{}> = () => {
|
||||
if (moment(res?.data?.expiration).diff(moment(), 'hours') < remainingTime) {
|
||||
refreshToken(res?.data)
|
||||
} else {
|
||||
releaseCamera('faceLoginFrame');
|
||||
sessionStorage.setItem('Authorization', res?.data?.value);
|
||||
sessionStorage.setItem('refreshToken', res?.data?.refreshToken.value);
|
||||
sessionStorage.setItem('scope', res?.data?.scope);
|
||||
history.push('/redirect');
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.finally(
|
||||
() => {setSubmitLoading(false);}
|
||||
);
|
||||
}
|
||||
}
|
||||
else{
|
||||
@ -116,18 +144,23 @@ const Index: React.FC<{}> = () => {
|
||||
hanleFaceSubmit(result, null);
|
||||
})
|
||||
}else{
|
||||
setSubmitLoading(true);
|
||||
await ZjfakeFaceLogin({ userName, multipartFiles }).then((res) => {
|
||||
if (res?.success) {
|
||||
if (moment(res?.data?.expiration).diff(moment(), 'hours') < remainingTime) {
|
||||
refreshToken(res?.data)
|
||||
} else {
|
||||
mediaStreamTrack.current?.stop();
|
||||
sessionStorage.setItem('Authorization', res?.data?.value);
|
||||
sessionStorage.setItem('refreshToken', res?.data?.refreshToken.value);
|
||||
sessionStorage.setItem('scope', res?.data?.scope);
|
||||
history.push('/redirect');
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.finally(
|
||||
() => {setSubmitLoading(false);}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,19 +191,6 @@ const Index: React.FC<{}> = () => {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//登录模式改变事件
|
||||
const LoginModeChangeEvent = (mode: any) => {
|
||||
switch(mode){
|
||||
case 1:
|
||||
setIsFaceLogin(true);
|
||||
InitMedia();
|
||||
break;
|
||||
case 2:
|
||||
setIsFaceLogin(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//浏览器类型
|
||||
const BrowserType = () =>{
|
||||
//取得浏览器的userAgent字符串
|
||||
@ -210,7 +230,6 @@ const Index: React.FC<{}> = () => {
|
||||
}
|
||||
//初始化video
|
||||
const InitMedia = () => {
|
||||
BrowserType();
|
||||
if(!whetherIE.current){
|
||||
InitUserMedia({video : {width: 480, height: 320}}, success, error);
|
||||
}
|
||||
@ -233,13 +252,19 @@ const Index: React.FC<{}> = () => {
|
||||
}
|
||||
//调用媒体设备成功回调方法
|
||||
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();
|
||||
var result = stream.getVideoTracks().some(function(track:any) {
|
||||
return track.enabled && track.readyState === 'live';
|
||||
});
|
||||
if (result) {
|
||||
//兼容webkit核心浏览器
|
||||
const CompatibleURL = window.URL || window.webkitURL;
|
||||
//将视频流设置为video元素的源
|
||||
console.log(stream);
|
||||
//video.src = CompatibleURL.createObjectURL(stream);
|
||||
video.current.srcObject = stream;
|
||||
mediaStreamTrack.current = stream.getTracks()[0];
|
||||
video.current.play();
|
||||
}
|
||||
}
|
||||
//调用媒体设备失败回调方法
|
||||
const error = (error:any) => {
|
||||
@ -262,16 +287,46 @@ const Index: React.FC<{}> = () => {
|
||||
|
||||
//RgbToBase64
|
||||
const RgbToBase64 = async (image:any) =>{
|
||||
setSubmitLoading(true);
|
||||
await rgbToBase64({image}).then(res => {
|
||||
const _blob = base64ToBlob( 'data:image/jpg;base64,' + res.data);
|
||||
hanleFaceSubmit(_blob, null);
|
||||
}).catch(e=>{
|
||||
setSubmitLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
//是https或者是本地
|
||||
const httpsOrLocal = () => {
|
||||
let protocol = document.location.protocol;
|
||||
if(protocol == 'https'){
|
||||
return true;
|
||||
}else{
|
||||
let host = window.location.hostname;
|
||||
if(host == '127.0.0.1' || host == 'localhost'){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//是否允许人脸登录
|
||||
const allowedToFaceLogin = () => {
|
||||
let browseType = BrowserType()
|
||||
if((browseType == 11 || browseType == -1) && httpsOrLocal()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
cookie.remove('mall3_token');
|
||||
sessionStorage.clear();
|
||||
changeCaptcha();
|
||||
if(!allowedToFaceLogin()){
|
||||
setFaceLoginDisable(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@ -284,109 +339,110 @@ const Index: React.FC<{}> = () => {
|
||||
</div>
|
||||
<div className="main">
|
||||
<div className="text">
|
||||
<h3>登 录</h3>
|
||||
{!isFaceLogin ? (
|
||||
<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="请输入用户名"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label=""
|
||||
name="password"
|
||||
rules={[{ required: true, message: '请输入密码!' }]}
|
||||
>
|
||||
<Input.Password
|
||||
prefix={
|
||||
<LockOutlined style={{ fontSize: '18px' }} className="site-form-item-icon" />
|
||||
}
|
||||
placeholder="请输入密码"
|
||||
addonAfter={<VideoCameraOutlined onClick={() => LoginModeChangeEvent(1)}/>}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Row>
|
||||
<Col span={14}>
|
||||
<Tabs defaultActiveKey="1" onChange={onChange} size = {'large'}>
|
||||
<TabPane tab="账号密码登录" key="1">
|
||||
<Form
|
||||
name="basic"
|
||||
className="form-box"
|
||||
initialValues={{ remember: true }}
|
||||
form={form}
|
||||
onFinish={handleSubmit}
|
||||
// onFinishFailed={onFinishFailed}
|
||||
>
|
||||
<Form.Item
|
||||
label=""
|
||||
name="captcha"
|
||||
rules={[{ required: true, message: '请输入验证码!' }]}
|
||||
name="userName"
|
||||
rules={[{ required: true, message: '请输入用户名!' }]}
|
||||
>
|
||||
<Input
|
||||
prefix={
|
||||
<SafetyCertificateOutlined
|
||||
style={{ fontSize: '18px' }}
|
||||
className="site-form-item-icon"
|
||||
/>
|
||||
<UserOutlined style={{ fontSize: '18px' }} className="site-form-item-icon" />
|
||||
}
|
||||
placeholder="请输入验证码"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label=""
|
||||
name="password"
|
||||
rules={[{ required: true, message: '请输入密码!' }]}
|
||||
>
|
||||
<Input.Password
|
||||
prefix={
|
||||
<LockOutlined style={{ fontSize: '18px' }} className="site-form-item-icon" />
|
||||
}
|
||||
placeholder="请输入密码"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={10}>
|
||||
<img className="verification" onClick={() => changeCaptcha()} src={imgUrl} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* <Form.Item className="remember" name="remember" valuePropName="checked">
|
||||
<Checkbox>记住密码</Checkbox>
|
||||
</Form.Item> */}
|
||||
<Form.Item>
|
||||
<Button type="primary" className="w100" htmlType="submit">
|
||||
登 录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>):(
|
||||
<Form
|
||||
name="basic"
|
||||
className="form-box"
|
||||
initialValues={{ remember: true }}
|
||||
form={form}
|
||||
onFinish={hanleFaceSubmit.bind(this, null)}
|
||||
// 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 = {RgbToBase64}/>)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{/* onClick={() => {hanleFaceSubmit(null, null);}} */}
|
||||
<Button type="primary" className="w100" htmlType="submit">
|
||||
登 录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>)}
|
||||
<Row>
|
||||
<Col span={14}>
|
||||
<Form.Item
|
||||
label=""
|
||||
name="captcha"
|
||||
rules={[{ required: true, message: '请输入验证码!' }]}
|
||||
>
|
||||
<Input
|
||||
prefix={
|
||||
<SafetyCertificateOutlined
|
||||
style={{ fontSize: '18px' }}
|
||||
className="site-form-item-icon"
|
||||
/>
|
||||
}
|
||||
placeholder="请输入验证码"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={10}>
|
||||
<img className="verification" onClick={() => changeCaptcha()} src={imgUrl} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* <Form.Item className="remember" name="remember" valuePropName="checked">
|
||||
<Checkbox>记住密码</Checkbox>
|
||||
</Form.Item> */}
|
||||
<Form.Item>
|
||||
<Button type="primary" className="w100" htmlType="submit">
|
||||
登 录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</TabPane>
|
||||
<TabPane tab="人脸识别登录" key="2" disabled = {faceLoginDisable}>
|
||||
<Form
|
||||
name="basic2"
|
||||
className="form-box"
|
||||
initialValues={{ remember: true }}
|
||||
form={form2}
|
||||
onFinish={hanleFaceSubmit.bind(this, null)}
|
||||
// onFinishFailed={onFinishFailed}
|
||||
>
|
||||
<Form.Item
|
||||
label=""
|
||||
name="userName"
|
||||
rules={[{ required: true, message: '请输入用户名!' }]}
|
||||
>
|
||||
<Input
|
||||
prefix={
|
||||
<UserOutlined style={{ fontSize: '18px' }} className="site-form-item-icon" />
|
||||
}
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</Form.Item>
|
||||
{/* 加载摄像头 */}
|
||||
<Form.Item>
|
||||
{!whetherIE.current ? (<video ref={video} width="382" height="200"></video>):(<FrameFaceLogin faceCompareEvent = {RgbToBase64}/>)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{/* onClick={() => {hanleFaceSubmit(null, null);}} */}
|
||||
<Button type="primary" className="w100" loading = {submitLoading} htmlType="submit">
|
||||
登 录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="footer">版权所有:中国联合网络通信有限公司</div> */}
|
||||
<Modal
|
||||
title="修改密码"
|
||||
visible={isModalVisible}
|
||||
|
Reference in New Issue
Block a user