index.tsx 10.4 KB
Newer Older
陈帅's avatar
陈帅 committed
1 2
import { Button, Col, Form, Input, Popover, Progress, Row, Select, message } from 'antd';
import { FormattedMessage, formatMessage } from 'umi-plugin-react/locale';
3
import React, { Component } from 'react';
陈帅's avatar
陈帅 committed
4

陈帅's avatar
陈帅 committed
5
import { Dispatch } from 'redux';
陈帅's avatar
陈帅 committed
6
import { FormComponentProps } from 'antd/es/form';
陈帅's avatar
陈帅 committed
7 8
import Link from 'umi/link';
import { connect } from 'dva';
陈帅's avatar
陈帅 committed
9
import router from 'umi/router';
陈帅's avatar
陈帅 committed
10
import { StateType } from './model';
陈帅's avatar
陈帅 committed
11
import styles from './style.less';
12 13

const FormItem = Form.Item;
afc163's avatar
afc163 committed
14
const { Option } = Select;
15 16 17
const InputGroup = Input.Group;

const passwordStatusMap = {
18 19
  ok: (
    <div className={styles.success}>
20
      <FormattedMessage id="BLOCK_NAME.strength.strong" />
21 22 23 24
    </div>
  ),
  pass: (
    <div className={styles.warning}>
25
      <FormattedMessage id="BLOCK_NAME.strength.medium" />
26 27 28 29
    </div>
  ),
  poor: (
    <div className={styles.error}>
30
      <FormattedMessage id="BLOCK_NAME.strength.short" />
31 32
    </div>
  ),
33 34
};

陈帅's avatar
陈帅 committed
35 36 37 38 39
const passwordProgressMap: {
  ok: 'success';
  pass: 'normal';
  poor: 'exception';
} = {
40 41
  ok: 'success',
  pass: 'normal',
jim's avatar
jim committed
42
  poor: 'exception',
43 44
};

陈帅's avatar
陈帅 committed
45
interface BLOCK_NAME_CAMEL_CASEProps extends FormComponentProps {
陈帅's avatar
陈帅 committed
46
  dispatch: Dispatch<any>;
陈帅's avatar
陈帅 committed
47
  BLOCK_NAME_CAMEL_CASE: StateType;
陈帅's avatar
陈帅 committed
48 49 50 51 52 53 54 55 56 57
  submitting: boolean;
}
interface BLOCK_NAME_CAMEL_CASEState {
  count: number;
  confirmDirty: boolean;
  visible: boolean;
  help: string;
  prefix: string;
}

陈帅's avatar
陈帅 committed
58
export interface UserRegisterParams {
陈帅's avatar
陈帅 committed
59 60 61 62 63 64 65 66 67 68 69 70 71
  mail: string;
  password: string;
  confirm: string;
  mobile: string;
  captcha: string;
  prefix: string;
}

@connect(
  ({
    BLOCK_NAME_CAMEL_CASE,
    loading,
  }: {
陈帅's avatar
陈帅 committed
72
    BLOCK_NAME_CAMEL_CASE: StateType;
陈帅's avatar
陈帅 committed
73 74 75 76 77 78 79 80
    loading: {
      effects: {
        [key: string]: string;
      };
    };
  }) => ({
    BLOCK_NAME_CAMEL_CASE,
    submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submit'],
陈帅's avatar
陈帅 committed
81
  }),
陈帅's avatar
陈帅 committed
82 83 84 85 86 87
)
class PAGE_NAME_UPPER_CAMEL_CASE extends Component<
  BLOCK_NAME_CAMEL_CASEProps,
  BLOCK_NAME_CAMEL_CASEState
> {
  state: BLOCK_NAME_CAMEL_CASEState = {
88 89 90 91
    count: 0,
    confirmDirty: false,
    visible: false,
    help: '',
ddcat1115's avatar
ddcat1115 committed
92 93
    prefix: '86',
  };
陈帅's avatar
陈帅 committed
94

jim's avatar
jim committed
95
  componentDidUpdate() {
陈帅's avatar
陈帅 committed
96 97
    const { BLOCK_NAME_CAMEL_CASE, form } = this.props;
    const account = form.getFieldValue('mail');
98
    if (BLOCK_NAME_CAMEL_CASE.status === 'ok') {
陈帅's avatar
陈帅 committed
99
      message.success('注册成功!');
陈帅's avatar
陈帅 committed
100 101 102 103 104 105
      router.push({
        pathname: '/user/register-result',
        state: {
          account,
        },
      });
106 107
    }
  }
陈帅's avatar
陈帅 committed
108

109 110 111
  componentWillUnmount() {
    clearInterval(this.interval);
  }
陈帅's avatar
陈帅 committed
112

113 114 115
  onGetCaptcha = () => {
    let count = 59;
    this.setState({ count });
陈帅's avatar
陈帅 committed
116
    this.interval = window.setInterval(() => {
117 118 119 120 121 122
      count -= 1;
      this.setState({ count });
      if (count === 0) {
        clearInterval(this.interval);
      }
    }, 1000);
ddcat1115's avatar
ddcat1115 committed
123
  };
124 125

  getPasswordStatus = () => {
afc163's avatar
afc163 committed
126
    const { form } = this.props;
127 128 129 130 131 132 133
    const value = form.getFieldValue('password');
    if (value && value.length > 9) {
      return 'ok';
    }
    if (value && value.length > 5) {
      return 'pass';
    }
jim's avatar
jim committed
134
    return 'poor';
ddcat1115's avatar
ddcat1115 committed
135
  };
136

陈帅's avatar
陈帅 committed
137
  handleSubmit = (e: React.FormEvent) => {
138
    e.preventDefault();
陈帅's avatar
陈帅 committed
139 140
    const { form, dispatch } = this.props;
    form.validateFields({ force: true }, (err, values) => {
ddcat1115's avatar
ddcat1115 committed
141
      if (!err) {
陈帅's avatar
陈帅 committed
142 143
        const { prefix } = this.state;
        dispatch({
144
          type: 'BLOCK_NAME_CAMEL_CASE/submit',
ddcat1115's avatar
ddcat1115 committed
145 146
          payload: {
            ...values,
陈帅's avatar
陈帅 committed
147
            prefix,
ddcat1115's avatar
ddcat1115 committed
148 149
          },
        });
150
      }
ddcat1115's avatar
ddcat1115 committed
151 152
    });
  };
153

陈帅's avatar
陈帅 committed
154
  checkConfirm = (rule: any, value: string, callback: (messgae?: string) => void) => {
afc163's avatar
afc163 committed
155
    const { form } = this.props;
156
    if (value && value !== form.getFieldValue('password')) {
157
      callback(formatMessage({ id: 'BLOCK_NAME.password.twice' }));
158 159 160
    } else {
      callback();
    }
ddcat1115's avatar
ddcat1115 committed
161
  };
162

陈帅's avatar
陈帅 committed
163
  checkPassword = (rule: any, value: string, callback: (messgae?: string) => void) => {
陈帅's avatar
陈帅 committed
164
    const { visible, confirmDirty } = this.state;
165 166
    if (!value) {
      this.setState({
167
        help: formatMessage({ id: 'BLOCK_NAME.password.required' }),
168 169 170 171 172 173 174
        visible: !!value,
      });
      callback('error');
    } else {
      this.setState({
        help: '',
      });
陈帅's avatar
陈帅 committed
175
      if (!visible) {
176 177 178 179 180 181 182
        this.setState({
          visible: !!value,
        });
      }
      if (value.length < 6) {
        callback('error');
      } else {
afc163's avatar
afc163 committed
183
        const { form } = this.props;
陈帅's avatar
陈帅 committed
184
        if (value && confirmDirty) {
185 186 187 188 189
          form.validateFields(['confirm'], { force: true });
        }
        callback();
      }
    }
ddcat1115's avatar
ddcat1115 committed
190 191
  };

陈帅's avatar
陈帅 committed
192
  changePrefix = (value: string) => {
ddcat1115's avatar
ddcat1115 committed
193 194 195 196
    this.setState({
      prefix: value,
    });
  };
197

陈帅's avatar
陈帅 committed
198 199
  interval: number | undefined;

200
  renderPasswordProgress = () => {
afc163's avatar
afc163 committed
201
    const { form } = this.props;
202 203
    const value = form.getFieldValue('password');
    const passwordStatus = this.getPasswordStatus();
ddcat1115's avatar
ddcat1115 committed
204
    return value && value.length ? (
205 206 207 208 209 210 211 212
      <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
213 214 215
      </div>
    ) : null;
  };
216 217

  render() {
Andreas Cederström's avatar
Andreas Cederström committed
218
    const { form, submitting } = this.props;
219
    const { getFieldDecorator } = form;
陈帅's avatar
陈帅 committed
220
    const { count, prefix, help, visible } = this.state;
221 222
    return (
      <div className={styles.main}>
223
        <h3>
224
          <FormattedMessage id="BLOCK_NAME.register.register" />
225
        </h3>
226 227 228
        <Form onSubmit={this.handleSubmit}>
          <FormItem>
            {getFieldDecorator('mail', {
ddcat1115's avatar
ddcat1115 committed
229 230 231
              rules: [
                {
                  required: true,
232
                  message: formatMessage({ id: 'BLOCK_NAME.email.required' }),
ddcat1115's avatar
ddcat1115 committed
233 234 235
                },
                {
                  type: 'email',
236
                  message: formatMessage({ id: 'BLOCK_NAME.email.wrong-format' }),
ddcat1115's avatar
ddcat1115 committed
237 238
                },
              ],
239
            })(
xiaohuoni's avatar
xiaohuoni committed
240 241 242
              <Input
                size="large"
                placeholder={formatMessage({ id: 'BLOCK_NAME.email.placeholder' })}
陈帅's avatar
陈帅 committed
243
              />,
244
            )}
245
          </FormItem>
陈帅's avatar
陈帅 committed
246
          <FormItem help={help}>
247
            <Popover
陈帅's avatar
陈帅 committed
248 249 250 251 252 253
              getPopupContainer={node => {
                if (node && node.parentNode) {
                  return node.parentNode as HTMLElement;
                }
                return node;
              }}
254
              content={
ddcat1115's avatar
ddcat1115 committed
255
                <div style={{ padding: '4px 0' }}>
256 257
                  {passwordStatusMap[this.getPasswordStatus()]}
                  {this.renderPasswordProgress()}
ddcat1115's avatar
ddcat1115 committed
258
                  <div style={{ marginTop: 10 }}>
259
                    <FormattedMessage id="BLOCK_NAME.strength.msg" />
ddcat1115's avatar
ddcat1115 committed
260
                  </div>
261 262 263 264
                </div>
              }
              overlayStyle={{ width: 240 }}
              placement="right"
陈帅's avatar
陈帅 committed
265
              visible={visible}
266 267
            >
              {getFieldDecorator('password', {
ddcat1115's avatar
ddcat1115 committed
268 269 270 271 272
                rules: [
                  {
                    validator: this.checkPassword,
                  },
                ],
273 274 275 276
              })(
                <Input
                  size="large"
                  type="password"
277
                  placeholder={formatMessage({ id: 'BLOCK_NAME.password.placeholder' })}
陈帅's avatar
陈帅 committed
278
                />,
279
              )}
280 281 282 283
            </Popover>
          </FormItem>
          <FormItem>
            {getFieldDecorator('confirm', {
ddcat1115's avatar
ddcat1115 committed
284 285 286
              rules: [
                {
                  required: true,
287
                  message: formatMessage({ id: 'BLOCK_NAME.confirm-password.required' }),
ddcat1115's avatar
ddcat1115 committed
288 289 290 291 292
                },
                {
                  validator: this.checkConfirm,
                },
              ],
293 294 295 296
            })(
              <Input
                size="large"
                type="password"
297
                placeholder={formatMessage({ id: 'BLOCK_NAME.confirm-password.placeholder' })}
陈帅's avatar
陈帅 committed
298
              />,
299
            )}
300 301
          </FormItem>
          <FormItem>
ddcat1115's avatar
ddcat1115 committed
302 303 304 305 306 307 308 309 310 311 312 313 314 315
            <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,
316
                    message: formatMessage({ id: 'BLOCK_NAME.phone-number.required' }),
ddcat1115's avatar
ddcat1115 committed
317 318
                  },
                  {
319
                    pattern: /^\d{11}$/,
320
                    message: formatMessage({ id: 'BLOCK_NAME.phone-number.wrong-format' }),
ddcat1115's avatar
ddcat1115 committed
321 322
                  },
                ],
323 324 325 326
              })(
                <Input
                  size="large"
                  style={{ width: '80%' }}
327
                  placeholder={formatMessage({ id: 'BLOCK_NAME.phone-number.placeholder' })}
陈帅's avatar
陈帅 committed
328
                />,
329
              )}
330 331 332 333 334 335
            </InputGroup>
          </FormItem>
          <FormItem>
            <Row gutter={8}>
              <Col span={16}>
                {getFieldDecorator('captcha', {
ddcat1115's avatar
ddcat1115 committed
336 337 338
                  rules: [
                    {
                      required: true,
339
                      message: formatMessage({ id: 'BLOCK_NAME.verification-code.required' }),
ddcat1115's avatar
ddcat1115 committed
340 341
                    },
                  ],
342 343 344
                })(
                  <Input
                    size="large"
345
                    placeholder={formatMessage({ id: 'BLOCK_NAME.verification-code.placeholder' })}
陈帅's avatar
陈帅 committed
346
                  />,
347
                )}
348 349 350
              </Col>
              <Col span={8}>
                <Button
ddcat1115's avatar
ddcat1115 committed
351
                  size="large"
陈帅's avatar
陈帅 committed
352
                  disabled={!!count}
353 354 355
                  className={styles.getCaptcha}
                  onClick={this.onGetCaptcha}
                >
356 357
                  {count
                    ? `${count} s`
358
                    : formatMessage({ id: 'BLOCK_NAME.register.get-verification-code' })}
359 360 361 362 363
                </Button>
              </Col>
            </Row>
          </FormItem>
          <FormItem>
ddcat1115's avatar
ddcat1115 committed
364 365
            <Button
              size="large"
Andreas Cederström's avatar
Andreas Cederström committed
366
              loading={submitting}
ddcat1115's avatar
ddcat1115 committed
367 368 369 370
              className={styles.submit}
              type="primary"
              htmlType="submit"
            >
371
              <FormattedMessage id="BLOCK_NAME.register.register" />
372
            </Button>
lijiehua's avatar
lijiehua committed
373
            <Link className={styles.login} to="/user/login">
374
              <FormattedMessage id="BLOCK_NAME.register.sign-in" />
ddcat1115's avatar
ddcat1115 committed
375
            </Link>
376 377 378 379 380 381
          </FormItem>
        </Form>
      </div>
    );
  }
}
lijiehua's avatar
lijiehua committed
382

陈帅's avatar
陈帅 committed
383
export default Form.create<BLOCK_NAME_CAMEL_CASEProps>()(PAGE_NAME_UPPER_CAMEL_CASE);