diff --git a/package.json b/package.json index b87c26fac951f50f5ec8215297394e57f55cab93..5492cd6e61f3962e565ac01b5668fea1b5a3d231 100755 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "lodash-decorators": "^4.4.1", "moment": "^2.19.1", "numeral": "^2.0.6", + "omit.js": "^1.0.0", "prop-types": "^15.5.10", "qs": "^6.5.0", "rc-drawer-menu": "^0.5.0", diff --git a/src/components/Login/LoginItem.js b/src/components/Login/LoginItem.js new file mode 100644 index 0000000000000000000000000000000000000000..b7332b2e22e927c371d39edc4ed021e41010a4a1 --- /dev/null +++ b/src/components/Login/LoginItem.js @@ -0,0 +1,104 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { Form, Button, Row, Col } from 'antd'; +import omit from 'omit.js'; +import styles from './index.less'; +import map from './map'; + +const FormItem = Form.Item; + +function generator({ defaultProps, defaultRules, type }) { + return (WrappedComponent) => { + return class BasicComponent extends Component { + static contextTypes = { + form: PropTypes.object, + updateActive: PropTypes.func, + }; + constructor(props) { + super(props); + this.state = { + count: 0, + }; + } + componentDidMount() { + if (this.context.updateActive) { + this.context.updateActive(this.props.name); + } + } + componentWillUnmount() { + clearInterval(this.interval); + } + onGetCaptcha = () => { + let count = 59; + this.setState({ count }); + if (this.props.onGetCaptcha) { + this.props.onGetCaptcha(); + } + this.interval = setInterval(() => { + count -= 1; + this.setState({ count }); + if (count === 0) { + clearInterval(this.interval); + } + }, 1000); + } + render() { + const { getFieldDecorator } = this.context.form; + const options = {}; + let otherProps = {}; + const { onChange, defaultValue, rules, name, ...restProps } = this.props; + const { count } = this.state; + options.rules = rules || defaultRules; + if (onChange) { + options.onChange = onChange; + } + if (defaultValue) { + options.initialValue = defaultValue; + } + otherProps = restProps || otherProps; + if (type === 'Captcha') { + const inputProps = omit(otherProps, ['onGetCaptcha']); + return ( + + + + {getFieldDecorator(name, options)( + + )} + + + + + + + ); + } + return ( + + {getFieldDecorator(name, options)( + + )} + + ); + } + }; + }; +} + +const LoginItem = {}; +Object.keys(map).forEach((item) => { + LoginItem[item] = generator({ + defaultProps: map[item].props, + defaultRules: map[item].rules, + type: item, + })(map[item].component); +}); + +export default LoginItem; diff --git a/src/components/Login/LoginSubmit.js b/src/components/Login/LoginSubmit.js new file mode 100644 index 0000000000000000000000000000000000000000..8770a97386e5edf526be071e3d863c76c4aed421 --- /dev/null +++ b/src/components/Login/LoginSubmit.js @@ -0,0 +1,15 @@ +import React from 'react'; +import classNames from 'classnames'; +import { Button, Form } from 'antd'; +import styles from './index.less'; + +const FormItem = Form.Item; + +export default ({ className, ...rest }) => { + const clsString = classNames(styles.submit, className); + return ( + + - - - - - - - {getFieldDecorator('remember', { - valuePropName: 'checked', - initialValue: true, - })( - 自动登录 - )} - 忘记密码 - - - -
- 其他登录方式 - {/* 需要加到 Icon 中 */} - - - - 注册账户 -
+ + + { + login.status === 'error' && + login.type === 'account' && + login.submitting === false && + this.renderMessage('账户或密码错误') + } + + + + + { + login.status === 'error' && + login.type === 'mobile' && + login.submitting === false && + this.renderMessage('验证码错误') + } + + + +
+ 自动登录 + 忘记密码 +
+ 登录 +
+ 其他登录方式 + + + + 注册账户 +
+
); } diff --git a/src/routes/User/Login.less b/src/routes/User/Login.less index 53af1321b4569fdd93081e27aff07fb970df2a32..b539db6e1790020a2f73663662e4157d49fc7dc7 100644 --- a/src/routes/User/Login.less +++ b/src/routes/User/Login.less @@ -4,92 +4,16 @@ width: 368px; margin: 0 auto; - .tabs { - padding: 0 2px; - margin: 0 -2px; - :global { - .ant-tabs-tab { - font-size: 16px; - line-height: 24px; - } - .ant-input-affix-wrapper .ant-input:not(:first-child) { - padding-left: 34px; - } - } - } - - :global { - .ant-tabs .ant-tabs-bar { - border-bottom: 0; - margin-bottom: 24px; - text-align: center; - } - - .ant-form-item { - margin-bottom: 24px; - } - } - - .prefixIcon { - font-size: @font-size-base; - color: @disabled-color; - } - - .getCaptcha { - display: block; - width: 100%; - } - - .additional { - text-align: left; - - .forgot { - float: right; - } - - .submit { - width: 100%; - margin-top: 24px; - } - - :global { - .ant-form-item-control { - line-height: 22px; - } - } - } - - .iconAlipay, .iconTaobao, .iconWeibo { - display: inline-block; - width: 24px; - height: 24px; - background: url('https://gw.alipayobjects.com/zos/rmsportal/itDzjUnkelhQNsycranf.svg'); + .icon { + font-size: 24px; + color: rgba(0, 0, 0, 0.2); margin-left: 16px; vertical-align: middle; cursor: pointer; - } - - .iconAlipay { - background-position: -24px 0; - - &:hover { - background-position: 0 0; - } - } - - .iconTaobao { - background-position: -24px -24px; - - &:hover { - background-position: 0 -24px; - } - } - - .iconWeibo { - background-position: -24px -48px; &:hover { - background-position: 0 -48px; + color: @primary-color; + transition: color .3s; } }