import { Model, routerRedux } from "dva"; import _ from 'lodash'; import { delay } from 'dva/saga'; import { PageState, AreaCode, AreaCodes } from '@/types/common'; import { getAreaCodes } from '@/services/common'; import { message, Modal } from 'antd'; import { formatMessage } from 'umi-plugin-locale'; import { validPwd, validPhone, validPhoneInput } from '@/utils/validate'; import { changePhone, sendCode } from './service'; import { dispatch } from '@/utils/utils'; import { encodePhone } from '@/utils/transform'; export interface ChphoneModelState { pageState: PageState; areacodes: AreaCodes, areacode: AreaCode | undefined, // 选中的地区 phone: string; code: string; submitting: boolean; sendingCode: boolean; codeTimer: number; } const initState: ChphoneModelState = { pageState: PageState.Pending, areacodes: [], areacode: undefined, phone: '', code: '', submitting: false, sendingCode: false, codeTimer: -1, }; const model: Model = { namespace: 'chphone', state: initState, effects: { *load(_, { put, call }) { yield put({ type: 'onUpdateState', pageState: PageState.Pending }); try { const areacodes = yield call(getAreaCodes); yield put({ type: 'onUpdateState', pageState: PageState.Success, areacodes, areacode: areacodes[0], phone: '', code: '', submitting: false, sendingCode: false, codeTimer: -1, }); } catch (e) { yield put({ type: 'onUpdateState', pageState: PageState.Failure, }); } }, *submit(_, { put, call, select }) { const { areacode, phone, code, submitting, } = (yield select((state: any) => state.chphone)) as ChphoneModelState; if (submitting) return; if (!areacode) return message.warn(formatMessage({ id: 'check.msgArea' })); if (!validPhone(phone)) return message.warn(formatMessage({ id: 'check.msgPhone' })); if (!code) return message.warn(formatMessage({ id: 'check.msgCode' })); yield put({ type: 'onUpdateState', submitting: true }); try { yield call(changePhone, areacode, phone, code); yield put({ type: 'user/updateUser', payload: { phone: encodePhone(areacode, phone) } }); Modal.success({ okText: formatMessage({ id: 'common.iknow' }), title: formatMessage({ id: 'common.prompt' }), content: formatMessage({ id: 'chphone.success' }), onOk: () => dispatch(routerRedux.goBack()), maskClosable: false, }); } catch (e) { message.error(e.message); } finally { yield put({ type: 'onUpdateState', submitting: false }) } }, *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 }); } }, *sendCode(_, { select, put, call }) { const { areacode, phone } = yield select((state: any) => state.chphone); 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); yield put({ type: 'timer', payload: 60 }); } catch(e) { message.error(e.message); } finally { yield put({ type: 'onUpdateState', sendingCode: false }); } }, }, reducers: { onUpdateState(state, payload) { return { ...state, ...payload, }; }, onUpdatePhone(state, { payload } : any) { const phone = validPhoneInput(payload) ? payload : state.phone; return { ...state, phone, }; }, }, }; export default model;