264 lines
8.5 KiB
TypeScript
264 lines
8.5 KiB
TypeScript
import { Model } from "dva";
|
|
import _ from 'lodash';
|
|
import { message, Modal } from 'antd';
|
|
import { delay } from 'dva/saga';
|
|
import { PageState, AreaCode, AreaCodes } from '@/types/common';
|
|
import { getAreaCodes, getUserInfo } from '@/services/common';
|
|
import { validPhoneInput, validPwdInput, validPhone, validPwd } from '@/utils/validate';
|
|
import { checkExistence, CheckResult, signIn, signUp, sendCode, reset } from './service';
|
|
import { formatMessage } from 'umi-plugin-locale';
|
|
import { dispatch } from '@/utils/utils';
|
|
|
|
export enum PageStep {
|
|
Check = 'check',
|
|
Login = 'login',
|
|
Register = 'register',
|
|
Reset = 'reset',
|
|
ResetSuccess = 'resetSuccess',
|
|
}
|
|
|
|
export interface CheckModelState {
|
|
pageState: PageState,
|
|
pageStep: PageStep,
|
|
areacodes: AreaCodes,
|
|
areacode: AreaCode | undefined, // 选中的地区
|
|
phone: string;
|
|
password: string;
|
|
pwdConfirm: string;
|
|
inviter: string;
|
|
verifyCode: string;
|
|
submitting: boolean;
|
|
sendingCode: boolean;
|
|
codeTimer: number;
|
|
}
|
|
|
|
const initState: CheckModelState = {
|
|
pageState: PageState.Pending,
|
|
pageStep: PageStep.Check,
|
|
areacodes: [],
|
|
areacode: undefined,
|
|
phone: '',
|
|
password: '',
|
|
pwdConfirm: '',
|
|
inviter: '',
|
|
verifyCode: '',
|
|
submitting: false,
|
|
sendingCode: false,
|
|
codeTimer: -1,
|
|
};
|
|
|
|
const model: Model = {
|
|
namespace: 'check',
|
|
|
|
state: initState,
|
|
|
|
effects: {
|
|
*back(_, { select, put }) {
|
|
const { pageStep: prev } = yield select((state: any) => state.check);
|
|
let pageStep = PageStep.Check;
|
|
switch (prev) {
|
|
case PageStep.Login:
|
|
case PageStep.Register:
|
|
case PageStep.ResetSuccess:
|
|
pageStep = PageStep.Check;
|
|
break;
|
|
case PageStep.Reset:
|
|
pageStep = PageStep.Login;
|
|
break;
|
|
}
|
|
yield put({
|
|
type: 'onUpdateState',
|
|
pageStep,
|
|
password: '',
|
|
pwdConfirm: '',
|
|
verifyCode: '',
|
|
});
|
|
},
|
|
|
|
*load(_, { call, put, all, select }) {
|
|
const { location } = yield select((state: any) => state.router);
|
|
let inviter = '';
|
|
if (location.query && location.query.inviteCode) {
|
|
inviter = location.query.inviteCode;
|
|
}
|
|
yield put({ type: 'onUpdateState', pageState: PageState.Pending, inviter });
|
|
|
|
try {
|
|
const areacodes = yield call(getAreaCodes);
|
|
yield all([
|
|
put({ type: 'onUpdatePageState', payload: PageState.Success }),
|
|
put({ type: 'onUpdateAreaCodes', payload: areacodes }),
|
|
]);
|
|
} catch(e) {
|
|
yield put({ type: 'onUpdatePageState', payload: PageState.Failure });
|
|
}
|
|
},
|
|
|
|
*timer({ payload }: any, { put }) {
|
|
yield put({ type: 'onUpdateState', codeTimer: payload });
|
|
yield delay(1000);
|
|
const next = payload - 1;
|
|
if (next >= 0) {
|
|
yield put({ type: 'timer', payload: next });
|
|
}
|
|
},
|
|
|
|
*submitCheck(_, { put, call, select }) {
|
|
const { areacode, phone } = 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' }));
|
|
|
|
yield put({ type: 'onUpdateState', submitting: true });
|
|
try {
|
|
const checkResult: CheckResult = yield call(checkExistence, areacode, phone);
|
|
yield put({
|
|
type: 'onUpdateState',
|
|
pageStep: {
|
|
[CheckResult.Login]: PageStep.Login,
|
|
[CheckResult.Register]: PageStep.Register,
|
|
}[checkResult],
|
|
});
|
|
} catch(e) {
|
|
message.error(e.message);
|
|
} finally {
|
|
yield put({ type: 'onUpdateState', submitting: false });
|
|
}
|
|
},
|
|
|
|
*submitLogin(_, { put, call, select, all }) {
|
|
const { areacode, phone, password } = 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 (!validPwd(password)) return message.warn(formatMessage({ id: 'check.msgPwd' }));
|
|
|
|
yield put({ type: 'onUpdateState', submitting: true });
|
|
try {
|
|
const token = yield call(signIn, areacode, phone, password);
|
|
yield put({ type: 'user/updateToken', payload: token });
|
|
yield delay(10);
|
|
const user = yield call(getUserInfo, true);
|
|
yield all([
|
|
put({ type: 'user/updateUser', payload: user }),
|
|
put({ type: 'onUpdateState', ...initState }),
|
|
]);
|
|
} catch(e) {
|
|
message.error(e.message);
|
|
yield all([
|
|
put({ type: 'user/logout' }),
|
|
put({ type: 'onUpdateState', submitting: false }),
|
|
]);
|
|
}
|
|
},
|
|
|
|
*submitRegister(_, { put, select, call, all }) {
|
|
const { areacode, phone, password, verifyCode, inviter, 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' }));
|
|
// if (!inviter) return message.warn(formatMessage({ id: 'check.msgInviter' }));
|
|
|
|
yield put({ type: 'onUpdateState', submitting: true });
|
|
try {
|
|
const token = yield call(signUp, areacode, phone, password, verifyCode, inviter);
|
|
yield put({ type: 'user/updateToken', payload: token });
|
|
yield delay(10);
|
|
const user = yield call(getUserInfo, true);
|
|
yield all([
|
|
put({ type: 'user/updateUser', payload: user }),
|
|
put({ type: 'onUpdateState', ...initState }),
|
|
]);
|
|
} catch(e) {
|
|
message.error(e.message);
|
|
yield all([
|
|
put({ type: 'user/logout' }),
|
|
put({ type: 'onUpdateState', submitting: false }),
|
|
]);
|
|
}
|
|
},
|
|
|
|
*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);
|
|
if (!areacode) return message.warn(formatMessage({ id: 'check.msgArea' }));
|
|
if (!validPhone(phone)) return message.warn(formatMessage({ id: 'check.msgPhone' }));
|
|
|
|
yield put({ type: 'onUpdateState', sendingCode: true });
|
|
try {
|
|
yield call(sendCode, areacode, phone, payload);
|
|
yield put({ type: 'timer', payload: 60 });
|
|
} catch(e) {
|
|
message.error(e.message);
|
|
} finally {
|
|
yield put({ type: 'onUpdateState', sendingCode: false });
|
|
}
|
|
},
|
|
},
|
|
|
|
reducers: {
|
|
onUpdatePageState(state, { payload: pageState } : any) {
|
|
return {
|
|
...state,
|
|
pageState,
|
|
};
|
|
},
|
|
|
|
onUpdateAreaCodes(state, { payload: areacodes } : any) {
|
|
return {
|
|
...state,
|
|
areacodes,
|
|
areacode: areacodes[0],
|
|
};
|
|
},
|
|
|
|
onUpdatePhone(state, { payload } : any) {
|
|
const phone = validPhoneInput(payload) ? payload : state.phone;
|
|
return {
|
|
...state,
|
|
phone,
|
|
};
|
|
},
|
|
|
|
onUpdatePassword(state, { payload } : any) {
|
|
const password = validPwdInput(payload) ? payload : state.password;
|
|
return {
|
|
...state,
|
|
password,
|
|
};
|
|
},
|
|
|
|
onUpdateState(state, newState) {
|
|
return {
|
|
...state,
|
|
...newState,
|
|
};
|
|
},
|
|
},
|
|
};
|
|
|
|
export default model;
|