Commit 0e5eecd5 authored by 周宏民's avatar 周宏民

fix: 验证码登录

parent 464eb3b2
Pipeline #94688 passed with stages
......@@ -92,7 +92,12 @@ const appReducer = (state = initialState, action) => {
window.__INITIAL_STATE__.menu = 'banner-left';
const temp = AppConfig(window.__INITIAL_STATE__);
temp.displayMode = window.__INITIAL_STATE__?.displayMode || '';
// 验证码开启 系统配置表里配置
temp.isVerification = action.data.isVerification || '';
// 验证码配置 站点设置里配置 只针对该站点
temp.isVerificationCode = action.data.VerificationConfig?.IsVerificationCode || false;
temp.verificationCodeTimeOut = action.data.VerificationConfig?.VerificationCodeTimeOut || 1;
temp.verificationCodeType = action.data.VerificationConfig?.VerificationCodeType || '';
window.globalConfig = temp;
// eslint-disable-next-line no-undef
......
......@@ -2,7 +2,7 @@ import 'kit_logger';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import { FieldNumberOutlined, ReloadOutlined } from '@ant-design/icons';
import { Button, Form, Input, message } from 'antd';
import { Button, Form, Input, message, Space } from 'antd';
import omit from 'omit.js';
import { useIntl } from '@wisdom-utils/components';
......@@ -38,6 +38,8 @@ const ValidateCode = props => {
const codeUrl = window?.globalConfig?.hasGateWay
? '/PandaCore/Identity/GetVerificationCode'
: '/PandaCore/GCK/BussinessAuth/GetVerificationCode';
const verificationCodeTimeOut = (window?.globalConfig?.verificationCodeTimeOut || 1) * 60;
const onTimeOver = () => {
console.log('超时了');
setIsOver(true);
......@@ -75,14 +77,13 @@ const ValidateCode = props => {
}, []);
useEffect(() => {
if (!isOver) {
console.log('开始计时');
if (timer.current) {
clearInterval(timer.current);
timer.current = null;
}
timer.current = setTimeout(() => {
onTimeOver();
}, 60 * 1000);
}, verificationCodeTimeOut * 1000);
}
return () => {
if (timer.current) {
......@@ -119,7 +120,8 @@ const ValidateCode = props => {
};
const LoginItem = props => {
const [count, setCount] = useState(props.countDown || 0);
const { isVerificationCode, verificationCodeType, verificationCodeTimeOut } = window.globalConfig;
const [count, setCount] = useState(props.countDown || (verificationCodeTimeOut || 1) * 60);
const [timing, setTiming] = useState(false);
const [ext, setExt] = useState('');
const intl = useIntl();
......@@ -136,7 +138,9 @@ const LoginItem = props => {
tabUtil,
...restProps
} = props;
if (isVerificationCode && (verificationCodeType && verificationCodeType !== '图片验证码') && customProps?.size) {
customProps.size = '';
}
const onGetCaptcha = useCallback(mobile => {
// eslint-disable-next-line no-undef
if (window.globalConfig?.hasGateWay) {
......@@ -178,21 +182,23 @@ const LoginItem = props => {
useEffect(() => {
let interval = 0;
const { countDown } = props;
const timeDown = countDown || (verificationCodeTimeOut || 1) * 60;
if (timing) {
interval = window.setInterval(() => {
setCount(preSecond => {
if (preSecond <= 1) {
setTiming(false);
clearInterval(interval);
return countDown || 60;
return timeDown;
}
return preSecond - 1;
});
}, 1000);
}
return () => clearInterval(interval);
}, [props, timing]);
}, [props.countDown, timing]);
if (!name) {
return null;
......@@ -256,6 +262,46 @@ const LoginItem = props => {
}
if (type === 'Validate') {
// 短信验证码
if (verificationCodeType === '阿里云短信验证码') {
const inputProps = omit(otherProps, ['onGetCaptcha', 'countDown']);
return (
<>
<FormItem name="mobile" rules={ItemMap.Mobile.rules}>
<Input {...ItemMap.Mobile.props} size="middle" placeholder="请输入手机号码" />
</FormItem>
<FormItem shouldUpdate style={{ marginBottom: '0px' }}>
{({ getFieldValue, validateFields }) => (
<Space align="start">
<FormItem name={name} {...options} rules={rules}>
<Input {...customProps} {...inputProps} />
</FormItem>
<Button
disabled={timing}
className={styles.getCaptcha}
style={{ lineHeight: '32px', width: '110px', textAlign: 'center' }}
size="large"
onClick={() => {
validateFields(['mobile'])
.then(values => {
onGetCaptcha(values.mobile);
})
.catch(error => {
Logger.log(error);
});
}}
>
{timing
? `${intl.formatMessage({ id: 'pages.login.phoneLogin.sendCationCode' })}(${count})`
: intl.formatMessage({ id: 'pages.login.phoneLogin.getVerificationCode' })}
</Button>
</Space>
)}
</FormItem>
</>
);
}
// 图形验证码
return (
<Form.Item name={name} {...options}>
<ValidateCode {...customProps} {...otherProps} />
......
......@@ -14,6 +14,7 @@ const Login = props => {
const intl = useIntl();
const { className } = props;
const otherChildren = [];
React.Children.forEach(props.children, child => {
if (!child) {
return;
......@@ -25,7 +26,9 @@ const Login = props => {
<div className={classNames(className, styles.login)}>
{props.welcome === void 0 ? (
<div className={styles.desc}>{intl.formatMessage({ id: 'pages.login.welcome' })}</div>
) : props.welcome}
) : (
props.welcome
)}
<Form
form={props.from}
onFinish={values => {
......
......@@ -113,6 +113,7 @@
width: 100%;
height: 100%;
object-fit: contain;
margin: 0;
}
.validate_invalid {
......
......@@ -44,16 +44,11 @@ const useAccount = props => (
/>
{props?.isValidate ? <Validate name="validate" /> : null}
<div>
<Checkbox
checked={props.autoLogin}
onChange={e => props.setAutoLogin(e.target.checked)}
>
<Checkbox checked={props.autoLogin} onChange={e => props.setAutoLogin(e.target.checked)}>
{useIntl().formatMessage({ id: 'pages.login.rememberMe' })}
</Checkbox>
</div>
<Submit loading={props.submitting}>
{useIntl().formatMessage({ id: 'pages.login.submit' })}
</Submit>
<Submit loading={props.submitting}>{useIntl().formatMessage({ id: 'pages.login.submit' })}</Submit>
</LoginForm>
);
......
......@@ -1567,7 +1567,8 @@ class Login {
loginHandlerValidate(user, pwd, userPhone, isRememberPWD, ref, validateCode = '') {
const self = this;
if ((this.globalConfig?.isVerification || 0) * 1 === 1)
// isVerification 取自系统配置表,isVerificationCode 取自 站点配置,isVerificationCode为1 会默认把 isVerificationCode改为true
if ((this.globalConfig?.isVerification || 0) * 1 === 1 || this.globalConfig.isVerificationCode)
return self.loginValidate(user, pwd, userPhone, isRememberPWD, SERVICE_APP_LOGIN_MODE.password, validateCode);
if (user && pwd) {
if (self.loginFailed && self.captchaObj) {
......
......@@ -37,23 +37,19 @@ const Login = forwardRef((props, _ref) => {
const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, false));
const [showVideo, setShowVideo] = useState(false);
let { ddCode } = props.global;
const { isVerificationCode, isVerification, verificationCodeType } = window.globalConfig;
const isValidate = (isVerification || 0) * 1 === 1 || isVerificationCode;
const loginMode = Cookies.get('loginMode') || null;
if (loginMode && loginMode === 'iotWechat') ddCode = null;
// useEffect(() => {
// action.globalConfig = props.global;
// }, [props.global]);
const handleSubmit = values => {
/* eslint-disable */
action &&
(type === 'Account'
? action.loginHandler(
values.userName,
values.password,
null,
autoLogin,
sliVerify,
)
? isValidate
? action.loginHandlerValidate(values.userName, values.password, null, autoLogin, 'none', values?.validate)
: action.loginHandler(values.userName, values.password, null, autoLogin, sliVerify)
: type === 'Mobile'
? action.phoneLoginFormHandler(values.mobile, values.captcha)
: null);
......@@ -85,7 +81,7 @@ const Login = forwardRef((props, _ref) => {
});
action.events.on('loginHomePage', () => {
props.history.push(`/homePage`);
})
});
action.events.on('loginIndustry', () => {
props.history.push(`/industry`);
});
......@@ -95,24 +91,19 @@ const Login = forwardRef((props, _ref) => {
action && action.events && action.events.removeAllListeners('loginVisible');
action && action.events && action.events.removeAllListeners('loginHomePage');
action && action.events && action.events.removeAllListeners('loginIndustry');
}
};
}, [props.loginMode]);
let loginTimeInterval = null;
let videoTimeout = null;
useEffect(() => {
if (loginTimeInterval)
clearInterval(loginTimeInterval), (loginTimeInterval = null);
if (loginTimeInterval) clearInterval(loginTimeInterval), (loginTimeInterval = null);
loginTimeInterval = setInterval(() => {
const date = new Date();
const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const time = `${
date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
}:${
const time = `${date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()}:${
date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()
}:${
date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()
}`;
}:${date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()}`;
setCurrentDate({
time,
dayofweek: weekday[date.getDay()],
......@@ -125,7 +116,7 @@ const Login = forwardRef((props, _ref) => {
}, []);
useEffect(() => {
if(ddCode && loginMode === 'qywx') {
if (ddCode && loginMode === 'qywx') {
setShowVideo(false);
} else {
setShowVideo(true);
......@@ -176,11 +167,11 @@ const Login = forwardRef((props, _ref) => {
switch (template) {
case 'DarkCloud.html':
case 'Dark.html':
return <Account {...params} />;
return <Account {...params} isValidate={isValidate} />;
case 'Dark - IOTMultiLogin.html':
return <IotComponent {...params} />;
default:
return <Account {...params} />;
return <Account {...params} isValidate={isValidate} />;
}
};
/* eslint-disable */
......@@ -192,78 +183,45 @@ const Login = forwardRef((props, _ref) => {
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={styles.main}>
{showVideo && <video
src={require("../../../../assets/videos/beforPage.mp4") }
{showVideo && (
<video
src={require('../../../../assets/videos/beforPage.mp4')}
className={styles.videLayer}
autoPlay="autoPlay"
muted
playsInline="playsinline"
ref={videoRef}
/>}
/>
)}
<div className={styles.inner}>
<div
className={classNames(styles.loginTime, styles.caseHide)}
ref={loginRef}
>
<div className={classNames(styles.loginTime, styles.caseHide)} ref={loginRef}>
<img
role="logo"
src={props.global && props.global.transformDevAssetsBaseURL && props.global.transformDevAssetsBaseURL(props.global.logo)}
src={
props.global &&
props.global.transformDevAssetsBaseURL &&
props.global.transformDevAssetsBaseURL(props.global.logo)
}
/>
<div
className={classNames(
styles.titleCase,
styles.caseHide,
'animated',
)}
ref={titleRef}
>
<div className={classNames(styles.titleCase, styles.caseHide, 'animated')} ref={titleRef}>
<span className={styles.title}>{props.global.title}</span>
<span className={styles.subtitle}>
{window.globalConfig && window.globalConfig.subtitle}
</span>
<span className={styles.subtitle}>{window.globalConfig && window.globalConfig.subtitle}</span>
</div>
</div>
<span
className={classNames(
styles.divider,
styles.caseHide,
'animate__animated',
)}
/>
<div
className={classNames(
styles.timeCase,
styles.caseHide,
'animate__animated',
)}
ref={timeRef}
>
<span className={classNames(styles.divider, styles.caseHide, 'animate__animated')} />
<div className={classNames(styles.timeCase, styles.caseHide, 'animate__animated')} ref={timeRef}>
<span className={styles.time}>{currentDate.time}</span>
<span className={styles.dayofweek}>{currentDate.dayofweek}</span>
<span className={styles.date}>{currentDate.date}</span>
</div>
<div
className={classNames(
styles['login-block'],
styles.caseHide,
'animate__animated',
)}
ref={loginFormRef}
>
<div className={classNames(styles['login-block'], styles.caseHide, 'animate__animated')} ref={loginFormRef}>
<div>
<img src={require('@/assets/images/login/dark/login.png')} />
</div>
<div className={styles['login-form']}>{renderPlatform()}</div>
</div>
</div>
<div
className={classNames(
styles.footerCase,
styles.caseHide,
'animate__animated',
)}
ref={footerRef}
>
<div className={classNames(styles.footerCase, styles.caseHide, 'animate__animated')} ref={footerRef}>
<div className={classNames(styles.quickMark)}>{renderAddons}</div>
<span className={classNames(styles.copyright)}>
Copyright ©
......@@ -271,32 +229,22 @@ const Login = forwardRef((props, _ref) => {
熊猫智慧水务
</a>
{new Date().getFullYear()} All Rights Reserved{' '}
{
window.location.host.includes("panda-water") ?
{window.location.host.includes('panda-water') ? (
<a target="_blank" id="IndexCaseNumber" href="https://beian.miit.gov.cn">
ICP18045097-1
</a> : ""
}
</a>
) : (
''
)}
<span className="addons">
<span className="split" />
<a id="qrcode">
<span
className="glyphicon glyphicon-qrcode"
role="button"
title="手持APP下载"
/>
<span className="glyphicon glyphicon-qrcode" role="button" title="手持APP下载" />
</a>
</span>
</span>
</div>
<Modal
centered
visible={visible}
width={340}
footer={null}
closable={false}
bodyStyle={{ padding: '15px' }}
>
<Modal centered visible={visible} width={340} footer={null} closable={false} bodyStyle={{ padding: '15px' }}>
<div ref={sliVerify} />
</Modal>
</div>
......@@ -326,4 +274,4 @@ const mapDispatchToProps = dispatch => ({
export default connect(
mapStateToProps,
mapDispatchToProps,
)((Login));
)(Login);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment