From 9a9650c758bd84bef0739aa8949627af666bb1c1 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期五, 31 七月 2020 10:07:42 +0800 Subject: [PATCH] 2020-07-31 --- src/views/login/loginform.jsx | 327 +++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 262 insertions(+), 65 deletions(-) diff --git a/src/views/login/loginform.jsx b/src/views/login/loginform.jsx index 4aa10ca..4b56cf6 100644 --- a/src/views/login/loginform.jsx +++ b/src/views/login/loginform.jsx @@ -1,33 +1,91 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' -import { Form, Icon, Input, Button, Checkbox, Select, Modal } from 'antd' +import { is, fromJS } from 'immutable' +import { Form, Icon, Input, Button, Checkbox, Select, Modal, Tabs, message } from 'antd' +import md5 from 'md5' +import moment from 'moment' + +import Api from '@/api' +import options from '@/store/options.js' import './index.scss' const { warning } = Modal +const { TabPane } = Tabs +let LoginVerCodeTimer = null -class MainSearch extends Component { +class LoginTabForm extends Component { static propTpyes = { isDisabled: PropTypes.bool, changelang: PropTypes.func, handleSubmit: PropTypes.func, dict: PropTypes.object, auth: PropTypes.bool, + touristLogin: PropTypes.bool, lang: PropTypes.string, langList: PropTypes.array, + loginWays: PropTypes.array, platName: PropTypes.string } state = { + activeKey: 'uname_pwd', username: '', - password: '' + password: '', + delay: null, + loginWays: [], + smsId: '', + verdisabled: false + } + + UNSAFE_componentWillMount () { + const { loginWays } = this.props + + let smsId = '' + let _loginWays = [] + loginWays.forEach(item => { + if (item.type === 'sms_vcode') { + smsId = item.smsId + _loginWays.push(item) + } else if (item.type === 'uname_pwd') { + _loginWays.push(item) + } + }) + + this.setState({ + smsId: smsId, + loginWays: _loginWays, + activeKey: _loginWays[0].type + }) + } + + UNSAFE_componentWillReceiveProps (nextProps) { + if (!is(fromJS(this.props.loginWays), fromJS(nextProps.loginWays))) { + let smsId = '' + let _loginWays = [] + nextProps.loginWays.forEach(item => { + if (item.type === 'sms_vcode') { + smsId = item.smsId + _loginWays.push(item) + } else if (item.type === 'uname_pwd') { + _loginWays.push(item) + } + }) + + this.setState({ + smsId: smsId, + loginWays: _loginWays, + activeKey: _loginWays[0].type + }) + } } handleConfirm = () => { + const { activeKey } = this.state // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� return new Promise((resolve, reject) => { this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { - resolve(values) + resolve({type: activeKey, ...values}) } else { reject(err) } @@ -40,6 +98,7 @@ } handleSubmit = e => { + const { activeKey } = this.state // 鐧诲綍鍙傛暟妫�楠� e.preventDefault() if (!this.props.auth) { @@ -53,18 +112,34 @@ return } - if (!this.props.form.getFieldValue('username')) { - const input = document.getElementById('username') - if (input) { - input.focus() + if (activeKey === 'uname_pwd') { + if (!this.props.form.getFieldValue('username')) { + const input = document.getElementById('username') + if (input) { + input.focus() + } + } else if (!this.props.form.getFieldValue('password')) { + const input = document.getElementById('password') + if (input) { + input.focus() + } + } else { + this.props.handleSubmit() } - } else if (!this.props.form.getFieldValue('password')) { - const input = document.getElementById('password') - if (input) { - input.focus() + } else if (activeKey === 'sms_vcode') { + if (!this.props.form.getFieldValue('phone')) { + const input = document.getElementById('phone') + if (input) { + input.focus() + } + } else if (!this.props.form.getFieldValue('vercode')) { + const input = document.getElementById('vercode') + if (input) { + input.focus() + } + } else { + this.props.handleSubmit() } - } else { - this.props.handleSubmit() } } @@ -99,63 +174,185 @@ } } + onChangeTab = (activeKey) => { + this.setState({activeKey}) + } + + getvercode = () => { + const { smsId } = this.state + let _phone = this.props.form.getFieldValue('phone') + if (!_phone) { + message.warning('璇疯緭鍏ユ墜鏈哄彿锛�') + return + } else if (!/^1[3456789]\d{9}$/.test(_phone)) { + message.warning('鎵嬫満鍙锋牸寮忛敊璇紝璇烽噸濉紒') + return + } else if (!this.props.touristLogin) { + message.warning('鏈幏鍙栭獙璇佺爜璁剧疆锛岃绋嶅悗鎴栧埛鏂伴噸璇曪紒') + return + } + + let param = { + func: 'MSN_sms_send_code', + send_type: 'login', + mob: _phone, + timestamp: moment().format('YYYY-MM-DD HH:mm:ss') + '.000', + ID: smsId + } + + param.LText = md5(`${_phone}mingke${window.GLOB.appkey}${param.timestamp}`) + param.secretkey = md5(`${param.LText}mingke${param.timestamp}`) + + this.setState({ + verdisabled: true, + delay: 60 + }) + LoginVerCodeTimer = setTimeout(this.resetVerCodeDelay, 1000) + + Api.getSystemConfig(param).then(res => { + if (res.status) { + + } else { + if (LoginVerCodeTimer) { + clearTimeout(LoginVerCodeTimer) + } + this.setState({ + verdisabled: false, + delay: null + }) + message.warning(res.message) + } + }, () => { + if (LoginVerCodeTimer) { + clearTimeout(LoginVerCodeTimer) + } + this.setState({ + verdisabled: false, + delay: null + }) + }) + } + + resetVerCodeDelay = () => { + const { delay } = this.state + if (delay && delay > 1) { + this.setState({delay: delay - 1}) + LoginVerCodeTimer = setTimeout(this.resetVerCodeDelay, 1000) + } else { + this.setState({ + verdisabled: false, + delay: null + }) + } + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊 + */ + componentWillUnmount () { + this.setState = () => { + return + } + } + render() { const { getFieldDecorator } = this.props.form + const { activeKey, verdisabled, delay, loginWays } = this.state return ( - <Form onSubmit={this.handleSubmit} className="login-form" id="login-form"> - <h4>{this.props.platName}</h4> - <Form.Item> - {getFieldDecorator('username', { - rules: [{ required: true, message: this.props.dict['login.username.empty'] }], - initialValue: this.state.username || '', - })( - <Input - prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} - placeholder={this.props.dict['login.username']} - autoComplete="off" - />, - )} - </Form.Item> - <Form.Item> - {getFieldDecorator('password', { - initialValue: this.state.password || '', - rules: [ - { - required: true, - message: this.props.dict['login.password.empty'], - } - ] - })(<Input.Password placeholder={this.props.dict['login.password']} prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} />)} - </Form.Item> - <Form.Item className="minline"> - {getFieldDecorator('remember', { - valuePropName: 'checked', - initialValue: true, - })(<Checkbox>{this.props.dict['login.remember']}</Checkbox>)} - </Form.Item> - {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right"> - {getFieldDecorator('lang', { - initialValue: this.props.lang, - })( - <Select - onChange={(value) => {this.changelang(value)}} - getPopupContainer={() => document.getElementById('login-form')} - > - {this.props.langList.map((item, index) => { - return <Select.Option key={index} value={item.Lang}>{item.LangName}</Select.Option> - })} - </Select> - )} - </Form.Item> : null} - <Form.Item className="btn-login"> - <Button type="primary" htmlType="submit" className="login-form-button" disabled={this.props.isDisabled} loading={this.props.isDisabled}> - {this.props.dict['login.submit']} - </Button> - </Form.Item> + <Form className={`login-form login-form-${loginWays.length}`} id="login-form" onSubmit={this.handleSubmit}> + <Tabs type="card" activeKey={activeKey} onChange={this.onChangeTab}> + {loginWays.map(item => (<TabPane tab={item.label} key={item.type}></TabPane>))} + </Tabs> + <div className="form-item-wrap"> + {activeKey === 'uname_pwd' ? <Form.Item> + {getFieldDecorator('username', { + rules: [{ required: true, message: this.props.dict['login.username.empty'] }], + initialValue: this.state.username || '', + })( + <Input + prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} + placeholder={this.props.dict['login.username']} + autoComplete="off" + />, + )} + </Form.Item> : null} + {activeKey === 'uname_pwd' ? <Form.Item> + {getFieldDecorator('password', { + initialValue: this.state.password || '', + rules: [ + { + required: true, + message: this.props.dict['login.password.empty'], + } + ] + })(<Input.Password placeholder={this.props.dict['login.password']} prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} />)} + </Form.Item> : null} + {activeKey === 'sms_vcode' ? <Form.Item> + {getFieldDecorator('phone', { + rules: [{ required: true, message: this.props.dict['login.phone.empty'] }], + initialValue: '', + })( + <Input + placeholder={this.props.dict['login.phone']} + autoComplete="off" + /> + )} + </Form.Item> : null} + {activeKey === 'sms_vcode' ? <Form.Item> + {getFieldDecorator('vercode', { + initialValue: '', + rules: [ + { + required: true, + message: this.props.dict['login.vercode.empty'], + } + ] + })( + <Input + addonAfter={ + <Button type="link" className="vercode" size="small" disabled={verdisabled} onClick={this.getvercode}> + {delay ? this.props.dict['login.vercode.queryagain'].replace('@', delay) : this.props.dict['login.vercode.query']} + </Button> + } + placeholder={this.props.dict['login.vercode']} + autoComplete="off" + /> + )} + </Form.Item> : null} + {activeKey === 'uname_pwd' ? <Form.Item className="minline"> + {getFieldDecorator('remember', { + valuePropName: 'checked', + initialValue: true, + })(<Checkbox>{this.props.dict['login.remember']}</Checkbox>)} + </Form.Item> : null} + {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right"> + {getFieldDecorator('lang', { + initialValue: this.props.lang, + })( + <Select + onChange={(value) => {this.changelang(value)}} + getPopupContainer={() => document.getElementById('login-form')} + > + {this.props.langList.map((item, index) => { + return <Select.Option key={index} value={item.Lang}>{item.LangName}</Select.Option> + })} + </Select> + )} + </Form.Item> : null} + {['uname_pwd', 'sms_vcode'].includes(activeKey) ? <Form.Item className="btn-login"> + <Button type="primary" htmlType="submit" className="login-form-button" disabled={this.props.isDisabled} loading={this.props.isDisabled}> + {this.props.dict['login.submit']} + </Button> + </Form.Item> : null} + {options.sysType === 'cloud' ? <Form.Item className="register-line"> + <a href="http://minkesoft.com/#/signup" target="_blank" rel="noopener noreferrer" className="register">娉ㄥ唽</a> + <a href="http://minkesoft.com/#/forgotPwd" target="_blank" rel="noopener noreferrer" className="forgot">蹇樿瀵嗙爜锛�</a> + </Form.Item> : null} + </div> </Form> ) } } -export default Form.create()(MainSearch) \ No newline at end of file +export default Form.create()(LoginTabForm) \ No newline at end of file -- Gitblit v1.8.0