UNPKG

react-app-shell

Version:

react打包脚本和example, 这里的版本请忽略

329 lines (301 loc) 10.1 kB
import React, {PureComponent} from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import {userService} from '../../service'; import {localStore, message, monitor, myToast} from '../../utils'; import styles from './login.less'; const phoneReg = /^1\d{10}$/; const maxNumber = 60; // 默认账号 let defaultAccount = { phone: '', code: '', }; /** * 发送短信接口响应CODE码 */ const SMG_RESULT_CODE = { OK: 'OK', // 成功 INVALID_CODE: 'INVALID_CODE', // 需要输入图文验证码 PHONE_ALEARDY_REGISTED: 'PHONE_ALEARDY_REGISTED', // 手机号已经注册 EXCEED_MAX_COUNT: 'EXCEED_MAX_COUNT', // 超过获取手机验证码最大次数 }; /** * 本地开发环境默认账号 */ if (process.env.NODE_ENV === 'development') { defaultAccount = { phone: '18910210381', code: '', }; } /** * 登录页面 */ class Login extends PureComponent { static propTypes = { onOk: PropTypes.func, // 登录成功的callback onCancel: PropTypes.func, grf: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // 团长的id 如果没有传给我空字符串或者-1 rf: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // rf码 如果没有传给我空字符串或者 -1 }; static defaultProps = { onOk: () => { console.log('您点击了确定'); }, onCancel: () => { console.log('您点击了取消'); }, grf: -1, rf: -1 }; constructor(props) { super(props); this.allow = true; // 请接口状态 this.state = { captchaVisible: false, // 是否显示验证码 countDown: 0, phone: defaultAccount.phone, code: defaultAccount.code, icode: '', loadAnimation: false, }; } componentDidMount() { setTimeout(() => { this.setState({ loadAnimation: true }); }, 200); } componentWillUnmount() { if (this.countTimer) { clearInterval(this.countTimer); } } handleInputChange = (key, e) => { this.setState({ [key]: e.target.value }); }; handleLogin = () => { if (!this.allow) { return false; } const {phone, code} = this.state; if (!this.verifyLogin(phone, code)) { return false; } const {grf, rf} = this.props; this.allow = false; userService.login(phone, code, grf, rf) .then(({userId, passToken}) => { localStore.setToken(userId, passToken); this.allow = true; monitor.login(); this.loginSucceed(); }) .catch(error => { message.error(error.msg || '登录失败'); this.allow = true; }); }; /** * 发送验证码短信 */ handleSendCode = () => { if (!this.allow) return false; let {phone, captchaVisible, icode} = this.state; if (captchaVisible && !icode) { message.info('请输入图片验证码'); return false; } this.setState({loading: true}); this.allow = false; userService.sendMessageCode(phone, icode) .then(data => { this.allow = true; myToast.success('发送成功', 1500); this.startCountDown(); }) .catch(error => { this.allow = true; let {loading} = this.state; loading = false; // 需要图片验证码验证 switch (error.code) { // 超过获取手机验证码最大次数 case SMG_RESULT_CODE.EXCEED_MAX_COUNT: monitor.log(phone, '超过获取手机验证码最大次数'); message.error('超过获取手机验证码最大次数'); break; // 该手机号已注册 case SMG_RESULT_CODE.PHONE_ALEARDY_REGISTED: monitor.log(phone, '该手机号已注册'); message.error('该手机号已注册'); break; // 需要输入图文验证码 case SMG_RESULT_CODE.INVALID_CODE: if (captchaVisible) { message.info('验证码错误'); } else { captchaVisible = true; } break; default: message.error(error.msg || '获取验证码失败'); break; } this.setState({ loading, captchaVisible }, this.handleRefreshCode); }); }; /** * 开始验证码倒计时 */ startCountDown = () => { this.setState({ loading: false, countDown: maxNumber, }); // 倒计时 this.countTimer = setInterval(() => { const {countDown} = this.state; if (countDown === 1) { clearInterval(this.countTimer); } this.setState({ countDown: countDown - 1 }); }, 1000); }; /** * 登录成功后执行 */ loginSucceed = () => { const {onOk} = this.props; message.info('登录成功'); this.setState({ loadAnimation: false }); setTimeout(() => { onOk && onOk(); }, 300); }; /** * 关闭登录 */ handleCancel = () => { const {onCancel} = this.props; this.setState({ loadAnimation: false }); setTimeout(() => { onCancel && onCancel(); }, 300); } /** * 校验用户输入 */ verifyLogin = (phone, code) => { if (!phone) { message.info('请输入手机号码'); return false; } if (!phoneReg.test(phone)) { message.info('手机号格式错误'); return false; } if (!code) { message.info('请输入验证码'); return false; } if (code.length < 4) { message.info('请输入正确的验证码'); return false; } return true; }; /** * 刷新图片验证码 */ handleRefreshCode = () => { const {captchaVisible} = this.state; if (captchaVisible) { this.refs.captchaImg.src = '/captcha/get?t=' + Math.random(); } }; /** * render发送验证码按钮 */ renderSendMsgBtn = () => { const {phone, countDown} = this.state; let sendMsgText = countDown < 1 ? '获取验证码' : '秒后重新获取'; if (phoneReg.test(phone) && countDown < 1) { return ( <div className={classNames(styles.sendMsgBtn, styles.active)} onClick={this.handleSendCode}>{sendMsgText}</div> ); } return <div className={styles.sendMsgBtn}>{countDown ? (countDown + sendMsgText) : sendMsgText}</div>; }; /** * render图片验证码 */ renderCaptchaCode = () => { let {icode, captchaVisible} = this.state; if (!captchaVisible) return null; return ( <div className={classNames(styles.setItem, styles.icodeWrap, 'clearfix')}> <label/> <input type="text" maxLength="4" value={icode} onChange={this.handleInputChange.bind(null, 'icode')} placeholder="请输入图片验证码" autoComplete="off" /> <div className={styles['captchaImg']} onClick={this.handleRefreshCode}> <img src={''} ref="captchaImg" alt=""/> </div> </div> ); } render() { const {phone, code, loadAnimation} = this.state; return ( <div className={classNames(styles.loginWrapper, loadAnimation ? styles.animation : '')}> <div className={styles.content}> <div className={styles.section}> <div className={classNames(styles.setItem, styles.phoneWarp, 'clearfix')}> <label/> <input type="tel" maxLength="11" value={phone} onChange={this.handleInputChange.bind(null, 'phone')} placeholder="手机号码" autoComplete="off" /> </div> {this.renderCaptchaCode()} <div className={classNames(styles.setItem, styles.codeWrap, 'clearfix')}> <label/> <input type="text" maxLength="4" value={code} pattern="[0-9]*" onChange={this.handleInputChange.bind(null, 'code')} placeholder="验证码" autoComplete="off" /> {this.renderSendMsgBtn()} </div> </div> <div className={styles.function}> <div className={styles.closeBtn} onClick={this.handleCancel}>关闭</div> <div className={styles.loginBtn} onClick={this.handleLogin}>登录</div> </div> </div> </div> ); } } export default Login;