From 2c3214f1494337886a7fe2b5be3ce0eaa1588c41 Mon Sep 17 00:00:00 2001 From: lyingd Date: Tue, 5 Jun 2018 01:09:38 +0800 Subject: [PATCH] =?UTF-8?q?Login.Captcha=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81countDown=EF=BC=8ConGetCaptcha=E6=94=AF=E6=8C=81Promis?= =?UTF-8?q?e=20(#1305)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .roadhogrc.mock.js | 51 ++++++++++++++++------------- mock/api.js | 9 +++++ src/components/Login/LoginItem.js | 31 +++++++++++------- src/components/Login/index.en-US.md | 3 +- src/components/Login/index.zh-CN.md | 3 +- src/models/login.js | 5 ++- src/routes/User/Login.js | 29 ++++++++++++++-- src/services/api.js | 4 +++ 8 files changed, 97 insertions(+), 38 deletions(-) diff --git a/.roadhogrc.mock.js b/.roadhogrc.mock.js index 1950a7f4..e39179b4 100644 --- a/.roadhogrc.mock.js +++ b/.roadhogrc.mock.js @@ -1,6 +1,6 @@ import mockjs from 'mockjs'; import { getRule, postRule } from './mock/rule'; -import { getActivities, getNotice, getFakeList, postFakeList } from './mock/api'; +import { getActivities, getNotice, getFakeList, postFakeList, getFakeCaptcha } from './mock/api'; import { getFakeChartData } from './mock/chart'; import { getProfileBasicData } from './mock/profile'; import { getProfileAdvancedData } from './mock/profile'; @@ -24,32 +24,38 @@ const proxy = { }, $body: { name: 'Serati Ma', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', userid: '00000001', email: 'antdesign@alipay.com', signature: '海纳百川,有容乃大', title: '交互专家', group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', - tags: [{ - key: '0', - label: '很有想法的', - }, { - key: '1', - label: '专注设计', - }, { - key: '2', - label: '辣~', - }, { - key: '3', - label: '大长腿', - }, { - key: '4', - label: '川妹子', - }, { - key: '5', - label: '海纳百川', - }], + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], notifyCount: 12, country: 'China', geographic: { @@ -176,6 +182,7 @@ const proxy = { }, 'GET /api/geographic/province': getProvince, 'GET /api/geographic/city/:province': getCity, + 'GET /api/captcha': getFakeCaptcha, }; export default (noProxy ? {} : delay(proxy, 1000)); diff --git a/mock/api.js b/mock/api.js index abbfdb6a..654aba9b 100644 --- a/mock/api.js +++ b/mock/api.js @@ -332,9 +332,18 @@ export const getActivities = [ }, ]; +export function getFakeCaptcha(req, res) { + if (res && res.json) { + res.json('captcha-xxx'); + } else { + return 'captcha-xxx'; + } +} + export default { getNotice, getActivities, getFakeList, postFakeList, + getFakeCaptcha, }; diff --git a/src/components/Login/LoginItem.js b/src/components/Login/LoginItem.js index a4554032..8ba9a5a8 100644 --- a/src/components/Login/LoginItem.js +++ b/src/components/Login/LoginItem.js @@ -23,18 +23,16 @@ class WarpFormItem extends Component { clearInterval(this.interval); } onGetCaptcha = () => { - let count = 59; - this.setState({ count }); - if (this.props.onGetCaptcha) { - this.props.onGetCaptcha(); + const { onGetCaptcha } = this.props; + const result = onGetCaptcha ? onGetCaptcha() : null; + if (result === false) { + return; + } + if (result instanceof Promise) { + result.then(this.runGetCaptchaCountDown); + } else { + this.runGetCaptchaCountDown(); } - this.interval = setInterval(() => { - count -= 1; - this.setState({ count }); - if (count === 0) { - clearInterval(this.interval); - } - }, 1000); }; getFormItemOptions = ({ onChange, defaultValue, rules }) => { const options = { @@ -48,6 +46,17 @@ class WarpFormItem extends Component { } return options; }; + runGetCaptchaCountDown = () => { + let count = this.props.countDown || 59; + this.setState({ count }); + this.interval = setInterval(() => { + count -= 1; + this.setState({ count }); + if (count === 0) { + clearInterval(this.interval); + } + }, 1000); + }; render() { const { count } = this.state; diff --git a/src/components/Login/index.en-US.md b/src/components/Login/index.en-US.md index bc38579f..c1fbc518 100644 --- a/src/components/Login/index.en-US.md +++ b/src/components/Login/index.en-US.md @@ -38,7 +38,8 @@ Apart from the above properties, Login.Username also support all properties of a Property | Description | Type | Default ----|------|-----|------ -onGetCaptcha | callback on getting a new Captcha | () => void | - +onGetCaptcha | callback on getting a new Captcha | () => (void \| false \| Promise) | - +countDown | count down | number |- Apart from the above properties, _Login.Captcha_ support the same properties with _Login.UserName_. diff --git a/src/components/Login/index.zh-CN.md b/src/components/Login/index.zh-CN.md index 98f0f624..bf9fb7fe 100644 --- a/src/components/Login/index.zh-CN.md +++ b/src/components/Login/index.zh-CN.md @@ -39,7 +39,8 @@ rules | 校验规则,同 Form getFieldDecorator(id, options) 中 [option.rules 参数 | 说明 | 类型 | 默认值 ----|------|-----|------ -onGetCaptcha | 点击获取校验码的回调 | () => void | - +onGetCaptcha | 点击获取校验码的回调 | () => (void \| false \| Promise) | - +countDown | 倒计时 | number |- 除上述属性以外,Login.Captcha 支持的属性与 Login.UserName 相同。 diff --git a/src/models/login.js b/src/models/login.js index ea9fd30a..b4b1d11a 100644 --- a/src/models/login.js +++ b/src/models/login.js @@ -1,5 +1,5 @@ import { routerRedux } from 'dva/router'; -import { fakeAccountLogin } from '../services/api'; +import { fakeAccountLogin, getFakeCaptcha } from '../services/api'; import { setAuthority } from '../utils/authority'; import { reloadAuthorized } from '../utils/Authorized'; @@ -43,6 +43,9 @@ export default { yield put(routerRedux.push('/user/login')); } }, + *getCaptcha({ payload }, { call }) { + yield call(getFakeCaptcha, payload); + }, }, reducers: { diff --git a/src/routes/User/Login.js b/src/routes/User/Login.js index ade5a11d..5d03da0b 100644 --- a/src/routes/User/Login.js +++ b/src/routes/User/Login.js @@ -21,6 +21,24 @@ export default class LoginPage extends Component { this.setState({ type }); }; + onGetCaptcha = () => { + return new Promise((resolve, reject) => { + this.loginForm.validateFields(['mobile'], {}, (err, values) => { + if (err) { + reject(err); + } else { + this.props + .dispatch({ + type: 'login/getCaptcha', + payload: values.mobile, + }) + .then(resolve) + .catch(reject); + } + }); + }); + }; + loginForm; handleSubmit = (err, values) => { const { type } = this.state; if (!err) { @@ -49,7 +67,14 @@ export default class LoginPage extends Component { const { type } = this.state; return (
- + { + this.loginForm = form; + }} + > {login.status === 'error' && login.type === 'account' && @@ -64,7 +89,7 @@ export default class LoginPage extends Component { !login.submitting && this.renderMessage('验证码错误')} - +
diff --git a/src/services/api.js b/src/services/api.js index b2a42623..2281cd34 100644 --- a/src/services/api.js +++ b/src/services/api.js @@ -120,3 +120,7 @@ export async function fakeRegister(params) { export async function queryNotices() { return request('/api/notices'); } + +export async function getFakeCaptcha(mobile) { + return request(`/api/captcha?mobile=${mobile}`); +} -- GitLab