import '@wisdom-utils/utils/lib/helpers/format'; import React, { forwardRef, useEffect, useRef, useState } from 'react'; import { connect } from 'react-redux'; import { Modal } from 'antd'; import { Helmet, HelmetProvider } from 'react-helmet-async'; import classNames from 'classnames'; import { dom } from '@wisdom-utils/utils/lib/helpers'; import { useHistory, withRouter } from '@wisdom-utils/runtime'; import Cookies from 'js-cookie'; import { actionCreators } from '@/containers/App/store'; import { LOGIN_WAY, LOGIN_DISPLAY } from '@/constants'; import defaultSetting from '../../../../../../config/defaultSetting'; import LoginAction from '../../login'; import styles from './index.less'; import useRenderQcode from '../../js/useRenderQcode'; import Account from '../../js/useAccount'; import IotComponent from '../../js/useIOTComponent'; import CloudForm from './cloudForm'; import { initMicroApps } from '../../../../../micro'; import useTime from '../../js/useTime'; const isRQcodeFunc = loginFunc => { const rqcodeFuncs = [LOGIN_DISPLAY.WeChart, LOGIN_DISPLAY.WeCom]; return !!(loginFunc && rqcodeFuncs.indexOf(loginFunc) !== -1); }; const loginFuncImg = loginFunc => { if (isRQcodeFunc(loginFunc)) { return require('@/assets/images/login/cloud/func_pwd.png'); } return require('@/assets/images/login/cloud/func_rqcode.png'); }; const Login = forwardRef((props, _ref) => { const videoRef = useRef(); const loginRef = useRef(); const timeRef = useRef(); const titleRef = useRef(); const sliVerify = useRef(); const loginFormRef = useRef(); const formRef = useRef(null); const footerRef = useRef(); const currentDate = useTime(); // 计时时间 const [status, setStatus] = useState('normal'); const [autoLogin, setAutoLogin] = useState(false); // 是否记住密码 const [submitting, setSubmitting] = useState(false); // 提交状态 const [type, setType] = useState(LOGIN_DISPLAY.Account); // 登录方式,type是LOGIN_DISPLAY的value,也是LOGIN_WAY的key,根据type决定loginModel const [visible, setVisible] = useState(false); const history = useHistory(); const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, true)); const handleSubmit = values => { /* eslint-disable */ action && (type === 'Account' ? action.loginHandler(values.userName, values.password, null, autoLogin, sliVerify) : type === 'Mobile' ? action.phoneLoginFormHandler(values.mobile, values.captcha) : null); setSubmitting(true); props.updateCurrentIndex && props.updateCurrentIndex(-1); }; useEffect(() => { // if (props.loginMode === LOGIN_WAY.WeChart) { action && action.events.on('loginSuccess', event => { setSubmitting(false); props.updateCurrentIndex && props.updateCurrentIndex(0); props.history.push(`/?client=${props.global.client}`); // window.share.event.emit('triggerMicro', props.global); initMicroApps(); }); action && action.events.on('loginError', event => { setVisible(false); setSubmitting(false); }); action && action.events.on('loginVisible', status => { setVisible(status); }); // } return () => { action && action.events && action.events.removeAllListeners('loginSuccess'); action && action.events && action.events.removeAllListeners('loginError'); action && action.events && action.events.removeAllListeners('loginVisible'); }; }, [props.loginMode]); let videoTimeout = null; useEffect(() => { if (videoRef && videoRef.current) { videoRef.current.addEventListener('ended', function() { dom.removeClass(loginRef.current, styles.caseHide); dom.addClass(loginRef.current, styles.loginTimeShow); videoTimeout = setTimeout(() => { dom.removeClass(timeRef.current, styles.caseHide); dom.addClass(timeRef.current, 'animate__fadeIn'); dom.removeClass(loginFormRef.current, styles.caseHide); dom.addClass(loginFormRef.current, 'animate__fadeInUp'); dom.removeClass(footerRef.current, styles.caseHide); dom.addClass(footerRef.current, 'animate__slideInUp'); dom.removeClass(titleRef.current, styles.caseHide); dom.addClass(titleRef.current, 'animte__fadeInUp'); }, 500); }); } return () => { videoTimeout && clearTimeout(videoTimeout); videoRef.current.removeEventListener('ended', () => {}); }; }, [videoRef]); useEffect(() => { setSubmitting(false); }, [visible]); const renderAddons = useRenderQcode({ ...props.global, styles }); const renderPlatform = () => { const template = props.global.loginTemplate; const params = { fromRef: formRef, type, setType, status, submitting, autoLogin, setAutoLogin, action, onSubmit: handleSubmit, loginMode: props.loginMode, updateLoginMode: props.updateLoginMode, }; switch (template) { case 'DarkCloud.html': case 'Dark.html': return <CloudForm {...params} />; case 'Dark - IOTMultiLogin.html': return <IotComponent {...params} />; default: return <Account {...params} />; } }; /* eslint-disable */ const toggleLoginFunc = e => { e && e.stopPropagation && e.stopPropagation(); setType(isRQcodeFunc(type) ? LOGIN_DISPLAY.Account : LOGIN_DISPLAY.WeCom); props.updateLoginMode(isRQcodeFunc(type) ? LOGIN_WAY[LOGIN_DISPLAY.Account] : LOGIN_WAY[LOGIN_DISPLAY.WeCom]); Cookies.set('loginMode', isRQcodeFunc(type) ? LOGIN_WAY[LOGIN_DISPLAY.Account] : LOGIN_WAY[LOGIN_DISPLAY.WeCom], { expires: 5 * 60 * 1000, path: '/', }); }; return ( <HelmetProvider> <Helmet> <title>{props.global.title || defaultSetting.title}</title> <meta name="description" content={props.global.title || defaultSetting.title} /> </Helmet> <div className={styles.main}> <video src={require('@/assets/videos/beforPage.mp4')} className={styles.videLayer} autoPlay="autoPlay" muted playsInline="playsinline" ref={videoRef} /> {/* main content */} <div className={styles.inner}> <div className={classNames(styles.loginTime, styles.caseHide)} ref={loginRef}> <img role="logo" src={ props.global && props.global.transformDevAssetsBaseURL && props.global.transformDevAssetsBaseURL(props.global.logo) } /> <div className={classNames(styles.titleCase, styles.caseHide, 'animated')} ref={titleRef}> <span className={styles.title}>{props.global.title}</span> <span className={styles.subtitle}>{window.globalConfig.subtitle}</span> </div> </div> <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> {/* login container */} <div className={classNames(styles['login-block'], styles.caseHide, 'animate__animated')} ref={loginFormRef}> <div> <img src="https://panda-water.cn/web4/assets/images/login/dark/login.png" /> </div> {/* right form */} <div className={styles['login-form']}> {/* 登录类型切换,扫码/账号密码 */} <div className={styles.loginFunc}> <img title={type ? '密码登录' : '扫码登录'} src={loginFuncImg(type)} onClick={toggleLoginFunc} /> </div> {renderPlatform()} </div> </div> </div> {/* footer */} <div className={classNames(styles.footerCase, styles.caseHide, 'animate__animated')} ref={footerRef}> <div className={classNames(styles.quickMark)}>{renderAddons}</div> <span className={classNames(styles.copyright)}> Copyright © <a target="_blank" href="https://panda-water.cn"> 熊猫智慧水务 </a> {new Date().getFullYear()} All Rights Reserved{' '} <a target="_blank" id="IndexCaseNumber" href=""> 沪ICP备11036640-1 </a> <span className="addons"> <span className="split" /> <a id="qrcode"> <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' }}> <div ref={sliVerify} /> </Modal> </div> </HelmetProvider> ); }); const mapStateToProps = state => ({ global: state.getIn(['global', 'globalConfig']), loginMode: state.getIn(['global', 'loginMode']), }); const mapDispatchToProps = dispatch => ({ updateConfig(config) { dispatch(actionCreators.getConfig(config)); }, createContext(data) { dispatch(actionCreators.createContext(data)); }, updateLoginMode(mode) { dispatch(actionCreators.changeLoginMode(mode)); }, updateCurrentIndex(index) { dispatch(actionCreators.updateCurrentIndex(index)); }, }); export default connect( mapStateToProps, mapDispatchToProps, )(withRouter(Login));