忘记密码
This commit is contained in:
@@ -41,6 +41,7 @@ export default {
|
|||||||
'check.setPwd': '设置登录密码',
|
'check.setPwd': '设置登录密码',
|
||||||
'check.confirmPwd': '确认登录密码',
|
'check.confirmPwd': '确认登录密码',
|
||||||
'check.invite': '邀请码',
|
'check.invite': '邀请码',
|
||||||
|
'check.resetSuccess': '密码已成功重置,请使用新密码登录。',
|
||||||
|
|
||||||
'home.tabHome': 'Home',
|
'home.tabHome': 'Home',
|
||||||
'home.tabEstate': '矿场',
|
'home.tabEstate': '矿场',
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default {
|
|||||||
'check.setPwd': '设置登录密码',
|
'check.setPwd': '设置登录密码',
|
||||||
'check.confirmPwd': '确认登录密码',
|
'check.confirmPwd': '确认登录密码',
|
||||||
'check.invite': '邀请码',
|
'check.invite': '邀请码',
|
||||||
|
'check.resetSuccess': '密码已成功重置,请使用新密码登录。',
|
||||||
|
|
||||||
'home.tabHome': '首页',
|
'home.tabHome': '首页',
|
||||||
'home.tabEstate': '矿场',
|
'home.tabEstate': '矿场',
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import styles from './style.less';
|
|||||||
import CheckPage from './check';
|
import CheckPage from './check';
|
||||||
import LoginPage from './login';
|
import LoginPage from './login';
|
||||||
import RegisterPage from './register';
|
import RegisterPage from './register';
|
||||||
|
import ResetPage from './reset';
|
||||||
import { formatMessage } from 'umi-plugin-locale';
|
import { formatMessage } from 'umi-plugin-locale';
|
||||||
|
|
||||||
const Page: React.FC<DispatchProp & CheckModelState> = ({
|
const Page: React.FC<DispatchProp & CheckModelState> = ({
|
||||||
@@ -74,7 +75,7 @@ const Page: React.FC<DispatchProp & CheckModelState> = ({
|
|||||||
[PageStep.Check]: <CheckPage />,
|
[PageStep.Check]: <CheckPage />,
|
||||||
[PageStep.Login]: <LoginPage />,
|
[PageStep.Login]: <LoginPage />,
|
||||||
[PageStep.Register]: <RegisterPage />,
|
[PageStep.Register]: <RegisterPage />,
|
||||||
[PageStep.Reset]: null,
|
[PageStep.Reset]: <ResetPage />,
|
||||||
[PageStep.ResetSuccess]: null,
|
[PageStep.ResetSuccess]: null,
|
||||||
}[pageStep]}
|
}[pageStep]}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { Button, Input } from 'antd';
|
import { Button, Input } from 'antd';
|
||||||
import { connect, DispatchProp } from 'dva';
|
import { connect, DispatchProp } from 'dva';
|
||||||
import { formatMessage } from 'umi-plugin-locale';
|
import { formatMessage } from 'umi-plugin-locale';
|
||||||
import { CheckModelState } from './model';
|
import { CheckModelState, PageStep } from './model';
|
||||||
|
|
||||||
const LoginPage: React.FC<DispatchProp & CheckModelState> = ({
|
const LoginPage: React.FC<DispatchProp & CheckModelState> = ({
|
||||||
password,
|
password,
|
||||||
@@ -20,6 +20,14 @@ const LoginPage: React.FC<DispatchProp & CheckModelState> = ({
|
|||||||
type="password"
|
type="password"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="item"
|
||||||
|
style={{ textAlign: 'right' }}
|
||||||
|
onClick={() => dispatch({ type: 'check/onUpdateState', pageStep: PageStep.Reset })}
|
||||||
|
>
|
||||||
|
{formatMessage({ id: 'check.forget' })}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="item gradient submit"
|
className="item gradient submit"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Model } from "dva";
|
import { Model } from "dva";
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { message } from 'antd';
|
import { message, Modal } from 'antd';
|
||||||
import { delay } from 'dva/saga';
|
import { delay } from 'dva/saga';
|
||||||
import { PageState, AreaCode, AreaCodes } from '@/types/common';
|
import { PageState, AreaCode, AreaCodes } from '@/types/common';
|
||||||
import { getAreaCodes, getUserInfo } from '@/services/common';
|
import { getAreaCodes, getUserInfo } from '@/services/common';
|
||||||
import { validPhoneInput, validPwdInput, validPhone, validPwd } from '@/utils/validate';
|
import { validPhoneInput, validPwdInput, validPhone, validPwd } from '@/utils/validate';
|
||||||
import { checkExistence, CheckResult, signIn, signUp, sendCode } from './service';
|
import { checkExistence, CheckResult, signIn, signUp, sendCode, reset } from './service';
|
||||||
import { formatMessage } from 'umi-plugin-locale';
|
import { formatMessage } from 'umi-plugin-locale';
|
||||||
|
import { dispatch } from '@/utils/utils';
|
||||||
|
|
||||||
export enum PageStep {
|
export enum PageStep {
|
||||||
Check = 'check',
|
Check = 'check',
|
||||||
@@ -121,7 +122,7 @@ const model: Model = {
|
|||||||
try {
|
try {
|
||||||
const token = yield call(signIn, areacode, phone, password);
|
const token = yield call(signIn, areacode, phone, password);
|
||||||
yield put({ type: 'user/updateToken', payload: token });
|
yield put({ type: 'user/updateToken', payload: token });
|
||||||
yield delay(0);
|
yield delay(10);
|
||||||
const user = yield call(getUserInfo, true);
|
const user = yield call(getUserInfo, true);
|
||||||
yield put({ type: 'user/updateUser', payload: user });
|
yield put({ type: 'user/updateUser', payload: user });
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@@ -145,7 +146,7 @@ const model: Model = {
|
|||||||
try {
|
try {
|
||||||
const token = yield call(signUp, areacode, phone, password, verifyCode, inviter);
|
const token = yield call(signUp, areacode, phone, password, verifyCode, inviter);
|
||||||
yield put({ type: 'user/updateToken', payload: token });
|
yield put({ type: 'user/updateToken', payload: token });
|
||||||
yield delay(0);
|
yield delay(10);
|
||||||
const user = yield call(getUserInfo, true);
|
const user = yield call(getUserInfo, true);
|
||||||
yield put({ type: 'user/updateUser', payload: user });
|
yield put({ type: 'user/updateUser', payload: user });
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@@ -156,14 +157,38 @@ const model: Model = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
*sendCode(_, { select, put, call }) {
|
*submitReset(_, { put, select, call }) {
|
||||||
|
const { areacode, phone, password, verifyCode, pwdConfirm } = yield select((state: any) => state.check);
|
||||||
|
if (!areacode) return message.warn(formatMessage({ id: 'check.msgArea' }));
|
||||||
|
if (!validPhone(phone)) return message.warn(formatMessage({ id: 'check.msgPhone' }));
|
||||||
|
if (!verifyCode) return message.warn(formatMessage({ id: 'check.msgCode' }));
|
||||||
|
if (!validPwd(password)) return message.warn(formatMessage({ id: 'check.msgPwd' }));
|
||||||
|
if (password !== pwdConfirm) return message.warn(formatMessage({ id: 'check.msgConfirm' }));
|
||||||
|
|
||||||
|
yield put({ type: 'onUpdateState', submitting: true });
|
||||||
|
try {
|
||||||
|
yield call(reset, areacode, phone, password, verifyCode);
|
||||||
|
Modal.success({
|
||||||
|
okText: formatMessage({ id: 'common.iknow' }),
|
||||||
|
title: formatMessage({ id: 'common.prompt' }),
|
||||||
|
content: formatMessage({ id: 'check.resetSuccess' }),
|
||||||
|
onOk: () => dispatch({ type: 'check/back' }),
|
||||||
|
});
|
||||||
|
} catch(e) {
|
||||||
|
message.error(e.message);
|
||||||
|
} finally {
|
||||||
|
yield put({ type: 'onUpdateState', submitting: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
*sendCode({ payload }, { select, put, call }) {
|
||||||
const { areacode, phone } = yield select((state: any) => state.check);
|
const { areacode, phone } = yield select((state: any) => state.check);
|
||||||
if (!areacode) return message.warn(formatMessage({ id: 'check.msgArea' }));
|
if (!areacode) return message.warn(formatMessage({ id: 'check.msgArea' }));
|
||||||
if (!validPhone(phone)) return message.warn(formatMessage({ id: 'check.msgPhone' }));
|
if (!validPhone(phone)) return message.warn(formatMessage({ id: 'check.msgPhone' }));
|
||||||
|
|
||||||
yield put({ type: 'onUpdateState', sendingCode: true });
|
yield put({ type: 'onUpdateState', sendingCode: true });
|
||||||
try {
|
try {
|
||||||
yield call(sendCode, areacode, phone);
|
yield call(sendCode, areacode, phone, payload);
|
||||||
yield put({ type: 'timer', payload: 60 });
|
yield put({ type: 'timer', payload: 60 });
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
message.error(e.message);
|
message.error(e.message);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { formatMessage } from 'umi-plugin-locale';
|
|||||||
import { CheckModelState } from './model';
|
import { CheckModelState } from './model';
|
||||||
|
|
||||||
import styles from './style.less';
|
import styles from './style.less';
|
||||||
|
import { SendCodeType } from '@/types/common';
|
||||||
|
|
||||||
const RegisterPage: React.FC<DispatchProp & CheckModelState> = ({
|
const RegisterPage: React.FC<DispatchProp & CheckModelState> = ({
|
||||||
password,
|
password,
|
||||||
@@ -43,7 +44,7 @@ const RegisterPage: React.FC<DispatchProp & CheckModelState> = ({
|
|||||||
size="large"
|
size="large"
|
||||||
loading={sendingCode}
|
loading={sendingCode}
|
||||||
disabled={codeTimer > 0}
|
disabled={codeTimer > 0}
|
||||||
onClick={() => dispatch({ type: 'check/sendCode' })}
|
onClick={() => dispatch({ type: 'check/sendCode', payload: SendCodeType.SignUp })}
|
||||||
>{btnText}</Button>
|
>{btnText}</Button>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
|
|
||||||
|
|||||||
82
src/pages/check/reset.tsx
Normal file
82
src/pages/check/reset.tsx
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Button, Input } from 'antd';
|
||||||
|
import { connect, DispatchProp } from 'dva';
|
||||||
|
import { formatMessage } from 'umi-plugin-locale';
|
||||||
|
import { CheckModelState } from './model';
|
||||||
|
|
||||||
|
import styles from './style.less';
|
||||||
|
import { SendCodeType } from '@/types/common';
|
||||||
|
|
||||||
|
const ResetPage: React.FC<DispatchProp & CheckModelState> = ({
|
||||||
|
password,
|
||||||
|
inviter,
|
||||||
|
pwdConfirm,
|
||||||
|
verifyCode,
|
||||||
|
submitting,
|
||||||
|
dispatch,
|
||||||
|
codeTimer,
|
||||||
|
sendingCode,
|
||||||
|
}) => {
|
||||||
|
let btnText;
|
||||||
|
if (codeTimer < 0) {
|
||||||
|
btnText = formatMessage({ id: 'check.getCode1' });
|
||||||
|
} else if (codeTimer === 0) {
|
||||||
|
btnText = formatMessage({ id: 'check.getCode3' });
|
||||||
|
} else {
|
||||||
|
btnText = formatMessage({ id: 'check.getCode2' }, { time: codeTimer })
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.reset}>
|
||||||
|
<Input.Group
|
||||||
|
className="item"
|
||||||
|
compact={true}
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
style={{ width: '40%' }}
|
||||||
|
placeholder={formatMessage({ id: 'common.codeHolder' })}
|
||||||
|
value={verifyCode}
|
||||||
|
onChange={e => dispatch({ type: 'check/onUpdateState', verifyCode: e.target.value })}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
style={{ width: '60%' }}
|
||||||
|
size="large"
|
||||||
|
loading={sendingCode}
|
||||||
|
disabled={codeTimer > 0}
|
||||||
|
onClick={() => dispatch({ type: 'check/sendCode', payload: SendCodeType.ForgetPwd })}
|
||||||
|
>{btnText}</Button>
|
||||||
|
</Input.Group>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
className="item"
|
||||||
|
placeholder={formatMessage({ id: 'check.setPwd' })}
|
||||||
|
value={password}
|
||||||
|
onChange={e => dispatch({ type: 'check/onUpdatePassword', payload: e.target.value })}
|
||||||
|
size="large"
|
||||||
|
type="password"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
className="item"
|
||||||
|
placeholder={formatMessage({ id: 'check.confirmPwd' })}
|
||||||
|
value={pwdConfirm}
|
||||||
|
onChange={e => dispatch({ type: 'check/onUpdateState', pwdConfirm: e.target.value })}
|
||||||
|
size="large"
|
||||||
|
type="password"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
className="item gradient submit"
|
||||||
|
type="primary"
|
||||||
|
loading={submitting}
|
||||||
|
onClick={() => dispatch({ type: 'check/submitReset' })}
|
||||||
|
size="large"
|
||||||
|
>{formatMessage({ id: 'check.reset' })}</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
({ check } : any) => ({ ...check })
|
||||||
|
)(ResetPage) as any;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import http from '@/utils/http';
|
import http from '@/utils/http';
|
||||||
import { AreaCode } from '@/types/common';
|
import { AreaCode, SendCodeType } from '@/types/common';
|
||||||
import { encodePhone } from '@/utils/transform';
|
import { encodePhone } from '@/utils/transform';
|
||||||
|
|
||||||
export enum CheckResult {
|
export enum CheckResult {
|
||||||
@@ -45,12 +45,26 @@ export async function signUp(areacode: AreaCode, phone: string, password: string
|
|||||||
return data.token;
|
return data.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sendCode(areacode: AreaCode, phone: string) {
|
export async function reset(areacode: AreaCode, phone: string, password: string, code: string): Promise<void> {
|
||||||
|
const { ok, msg, data } = await http.post(
|
||||||
|
'/sign/forget',
|
||||||
|
{
|
||||||
|
phone: encodePhone(areacode, phone),
|
||||||
|
password,
|
||||||
|
code,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (!ok) {
|
||||||
|
throw Error(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendCode(areacode: AreaCode, phone: string, type: SendCodeType) {
|
||||||
const { ok, msg } = await http.post(
|
const { ok, msg } = await http.post(
|
||||||
'/sign/send',
|
'/sign/send',
|
||||||
{
|
{
|
||||||
phone: encodePhone(areacode, phone),
|
phone: encodePhone(areacode, phone),
|
||||||
type: 'signUp',
|
type,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@import '../../global.less';
|
||||||
|
|
||||||
.check {
|
.check {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -57,7 +58,14 @@
|
|||||||
|
|
||||||
.register {
|
.register {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-top: 160px;
|
padding-top: @header-height;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reset {
|
||||||
|
height: 100%;
|
||||||
|
padding-top: @header-height;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ export interface User {
|
|||||||
inviteCode: string;
|
inviteCode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SendCodeType {
|
||||||
|
SignUp = 'signUp',
|
||||||
|
ForgetPwd = 'forgetPasswd',
|
||||||
|
}
|
||||||
|
|
||||||
export interface AreaCode {
|
export interface AreaCode {
|
||||||
id: string;
|
id: string;
|
||||||
areacode: string;
|
areacode: string;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
|
|||||||
import { formatMessage } from 'umi-plugin-locale';
|
import { formatMessage } from 'umi-plugin-locale';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { globalState } from '@/services/common';
|
import { globalState } from '@/services/common';
|
||||||
import { isDev } from './utils';
|
import { isDev, dispatch } from './utils';
|
||||||
|
|
||||||
export interface AppResp<T = any> {
|
export interface AppResp<T = any> {
|
||||||
ok: boolean,
|
ok: boolean,
|
||||||
@@ -55,6 +55,9 @@ async function filter<T>(
|
|||||||
}
|
}
|
||||||
const { status, data } = await (instance[method] as (...args: any[]) => Promise<AxiosResponse<AppResp>>)(...args);
|
const { status, data } = await (instance[method] as (...args: any[]) => Promise<AxiosResponse<AppResp>>)(...args);
|
||||||
replaceId(data);
|
replaceId(data);
|
||||||
|
if (data && data.code === 401) {
|
||||||
|
dispatch({ type: 'user/logout' });
|
||||||
|
}
|
||||||
ret = {
|
ret = {
|
||||||
ok: status >= 200 && status < 300 && data && data.code === 0,
|
ok: status >= 200 && status < 300 && data && data.code === 0,
|
||||||
code: data && data.code,
|
code: data && data.code,
|
||||||
|
|||||||
Reference in New Issue
Block a user