Register.js 7.83 KB
Newer Older
1 2
import React, { Component } from 'react';
import { connect } from 'dva';
zinkey's avatar
zinkey committed
3 4
import Link from 'umi/link';
import router from 'umi/router';
5 6 7 8
import { Form, Input, Button, Select, Row, Col, Popover, Progress } from 'antd';
import styles from './Register.less';

const FormItem = Form.Item;
afc163's avatar
afc163 committed
9
const { Option } = Select;
10 11 12
const InputGroup = Input.Group;

const passwordStatusMap = {
afc163's avatar
afc163 committed
13 14
  ok: <div className={styles.success}>强度</div>,
  pass: <div className={styles.warning}>强度</div>,
jim's avatar
jim committed
15
  poor: <div className={styles.error}>强度太短</div>,
16 17 18 19 20
};

const passwordProgressMap = {
  ok: 'success',
  pass: 'normal',
jim's avatar
jim committed
21
  poor: 'exception',
22 23
};

afc163's avatar
afc163 committed
24
export default
Andreas Cederström's avatar
Andreas Cederström committed
25 26 27
@connect(({ register, loading }) => ({
  register,
  submitting: loading.effects['register/submit'],
28 29
}))
@Form.create()
afc163's avatar
afc163 committed
30
class Register extends Component {
31 32 33 34 35
  state = {
    count: 0,
    confirmDirty: false,
    visible: false,
    help: '',
ddcat1115's avatar
ddcat1115 committed
36 37
    prefix: '86',
  };
38

jim's avatar
jim committed
39
  componentDidUpdate() {
陈帅's avatar
陈帅 committed
40 41 42 43
    const { form, register, dispatch } = this.props;
    const account = form.getFieldValue('mail');
    if (register.status === 'ok') {
      dispatch(
zinkey's avatar
zinkey committed
44
        router.push({
愚道's avatar
愚道 committed
45
          pathname: '/user/register-result',
jim's avatar
jim committed
46 47 48 49 50
          state: {
            account,
          },
        })
      );
51 52
    }
  }
陈帅's avatar
陈帅 committed
53

54 55 56 57 58 59 60 61 62 63 64 65 66 67
  componentWillUnmount() {
    clearInterval(this.interval);
  }

  onGetCaptcha = () => {
    let count = 59;
    this.setState({ count });
    this.interval = setInterval(() => {
      count -= 1;
      this.setState({ count });
      if (count === 0) {
        clearInterval(this.interval);
      }
    }, 1000);
ddcat1115's avatar
ddcat1115 committed
68
  };
69 70

  getPasswordStatus = () => {
afc163's avatar
afc163 committed
71
    const { form } = this.props;
72 73 74 75 76 77 78
    const value = form.getFieldValue('password');
    if (value && value.length > 9) {
      return 'ok';
    }
    if (value && value.length > 5) {
      return 'pass';
    }
jim's avatar
jim committed
79
    return 'poor';
ddcat1115's avatar
ddcat1115 committed
80
  };
81

jim's avatar
jim committed
82
  handleSubmit = e => {
83
    e.preventDefault();
陈帅's avatar
陈帅 committed
84 85
    const { form, dispatch } = this.props;
    form.validateFields({ force: true }, (err, values) => {
ddcat1115's avatar
ddcat1115 committed
86
      if (!err) {
陈帅's avatar
陈帅 committed
87 88
        const { prefix } = this.state;
        dispatch({
ddcat1115's avatar
ddcat1115 committed
89 90 91
          type: 'register/submit',
          payload: {
            ...values,
陈帅's avatar
陈帅 committed
92
            prefix,
ddcat1115's avatar
ddcat1115 committed
93 94
          },
        });
95
      }
ddcat1115's avatar
ddcat1115 committed
96 97
    });
  };
98

jim's avatar
jim committed
99
  handleConfirmBlur = e => {
afc163's avatar
afc163 committed
100
    const { value } = e.target;
陈帅's avatar
陈帅 committed
101 102
    const { confirmDirty } = this.state;
    this.setState({ confirmDirty: confirmDirty || !!value });
ddcat1115's avatar
ddcat1115 committed
103
  };
104 105

  checkConfirm = (rule, value, callback) => {
afc163's avatar
afc163 committed
106
    const { form } = this.props;
107 108 109 110 111
    if (value && value !== form.getFieldValue('password')) {
      callback('两次输入的密码不匹配!');
    } else {
      callback();
    }
ddcat1115's avatar
ddcat1115 committed
112
  };
113 114

  checkPassword = (rule, value, callback) => {
陈帅's avatar
陈帅 committed
115
    const { visible, confirmDirty } = this.state;
116 117 118 119 120 121 122 123 124 125
    if (!value) {
      this.setState({
        help: '请输入密码!',
        visible: !!value,
      });
      callback('error');
    } else {
      this.setState({
        help: '',
      });
陈帅's avatar
陈帅 committed
126
      if (!visible) {
127 128 129 130 131 132 133
        this.setState({
          visible: !!value,
        });
      }
      if (value.length < 6) {
        callback('error');
      } else {
afc163's avatar
afc163 committed
134
        const { form } = this.props;
陈帅's avatar
陈帅 committed
135
        if (value && confirmDirty) {
136 137 138 139 140
          form.validateFields(['confirm'], { force: true });
        }
        callback();
      }
    }
ddcat1115's avatar
ddcat1115 committed
141 142
  };

jim's avatar
jim committed
143
  changePrefix = value => {
ddcat1115's avatar
ddcat1115 committed
144 145 146 147
    this.setState({
      prefix: value,
    });
  };
148 149

  renderPasswordProgress = () => {
afc163's avatar
afc163 committed
150
    const { form } = this.props;
151 152
    const value = form.getFieldValue('password');
    const passwordStatus = this.getPasswordStatus();
ddcat1115's avatar
ddcat1115 committed
153
    return value && value.length ? (
154 155 156 157 158 159 160 161
      <div className={styles[`progress-${passwordStatus}`]}>
        <Progress
          status={passwordProgressMap[passwordStatus]}
          className={styles.progress}
          strokeWidth={6}
          percent={value.length * 10 > 100 ? 100 : value.length * 10}
          showInfo={false}
        />
ddcat1115's avatar
ddcat1115 committed
162 163 164
      </div>
    ) : null;
  };
165 166

  render() {
Andreas Cederström's avatar
Andreas Cederström committed
167
    const { form, submitting } = this.props;
168
    const { getFieldDecorator } = form;
陈帅's avatar
陈帅 committed
169
    const { count, prefix, help, visible } = this.state;
170 171 172 173 174 175
    return (
      <div className={styles.main}>
        <h3>注册</h3>
        <Form onSubmit={this.handleSubmit}>
          <FormItem>
            {getFieldDecorator('mail', {
ddcat1115's avatar
ddcat1115 committed
176 177 178 179 180 181 182 183 184 185 186
              rules: [
                {
                  required: true,
                  message: '请输入邮箱地址!',
                },
                {
                  type: 'email',
                  message: '邮箱地址格式错误!',
                },
              ],
            })(<Input size="large" placeholder="邮箱" />)}
187
          </FormItem>
陈帅's avatar
陈帅 committed
188
          <FormItem help={help}>
189 190
            <Popover
              content={
ddcat1115's avatar
ddcat1115 committed
191
                <div style={{ padding: '4px 0' }}>
192 193
                  {passwordStatusMap[this.getPasswordStatus()]}
                  {this.renderPasswordProgress()}
ddcat1115's avatar
ddcat1115 committed
194 195 196
                  <div style={{ marginTop: 10 }}>
                    请至少输入 6 个字符请不要使用容易被猜到的密码
                  </div>
197 198 199 200
                </div>
              }
              overlayStyle={{ width: 240 }}
              placement="right"
陈帅's avatar
陈帅 committed
201
              visible={visible}
202 203
            >
              {getFieldDecorator('password', {
ddcat1115's avatar
ddcat1115 committed
204 205 206 207 208
                rules: [
                  {
                    validator: this.checkPassword,
                  },
                ],
jim's avatar
jim committed
209
              })(<Input size="large" type="password" placeholder="至少6位密码,区分大小写" />)}
210 211 212 213
            </Popover>
          </FormItem>
          <FormItem>
            {getFieldDecorator('confirm', {
ddcat1115's avatar
ddcat1115 committed
214 215 216 217 218 219 220 221 222 223
              rules: [
                {
                  required: true,
                  message: '请确认密码!',
                },
                {
                  validator: this.checkConfirm,
                },
              ],
            })(<Input size="large" type="password" placeholder="确认密码" />)}
224 225
          </FormItem>
          <FormItem>
ddcat1115's avatar
ddcat1115 committed
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
            <InputGroup compact>
              <Select
                size="large"
                value={prefix}
                onChange={this.changePrefix}
                style={{ width: '20%' }}
              >
                <Option value="86">+86</Option>
                <Option value="87">+87</Option>
              </Select>
              {getFieldDecorator('mobile', {
                rules: [
                  {
                    required: true,
                    message: '请输入手机号!',
                  },
                  {
                    pattern: /^1\d{10}$/,
                    message: '手机号格式错误!',
                  },
                ],
jim's avatar
jim committed
247
              })(<Input size="large" style={{ width: '80%' }} placeholder="11位手机号" />)}
248 249 250 251 252 253
            </InputGroup>
          </FormItem>
          <FormItem>
            <Row gutter={8}>
              <Col span={16}>
                {getFieldDecorator('captcha', {
ddcat1115's avatar
ddcat1115 committed
254 255 256 257 258 259 260
                  rules: [
                    {
                      required: true,
                      message: '请输入验证码!',
                    },
                  ],
                })(<Input size="large" placeholder="验证码" />)}
261 262 263
              </Col>
              <Col span={8}>
                <Button
ddcat1115's avatar
ddcat1115 committed
264
                  size="large"
265 266 267 268 269 270 271 272 273 274
                  disabled={count}
                  className={styles.getCaptcha}
                  onClick={this.onGetCaptcha}
                >
                  {count ? `${count} s` : '获取验证码'}
                </Button>
              </Col>
            </Row>
          </FormItem>
          <FormItem>
ddcat1115's avatar
ddcat1115 committed
275 276
            <Button
              size="large"
Andreas Cederström's avatar
Andreas Cederström committed
277
              loading={submitting}
ddcat1115's avatar
ddcat1115 committed
278 279 280 281
              className={styles.submit}
              type="primary"
              htmlType="submit"
            >
282 283
              注册
            </Button>
xiaohu's avatar
xiaohu committed
284
            <Link className={styles.login} to="/User/Login">
ddcat1115's avatar
ddcat1115 committed
285 286
              使用已有账户登录
            </Link>
287 288 289 290 291 292
          </FormItem>
        </Form>
      </div>
    );
  }
}