import { routerRedux } from 'dva/router'; import { getPageQuery, setAuthority } from './utils/utils'; import { fakeAccountLogin, getFakeCaptcha } from './service'; import { stringify } from 'qs'; import { Reducer } from 'redux'; import { EffectsCommandMap } from 'dva'; import { AnyAction } from 'redux'; export interface IStateType { status?: 'ok' | 'error'; type?: string; currentAuthority?: 'user' | 'guest' | 'admin'; } export type Effect = ( action: AnyAction, effects: EffectsCommandMap & { select: (func: (state: IStateType) => T) => T }, ) => void; export interface ModelType { namespace: string; state: IStateType; effects: { login: Effect; getCaptcha: Effect; logout: Effect; }; reducers: { changeLoginStatus: Reducer; }; } const Model: ModelType = { namespace: 'BLOCK_NAME_CAMEL_CASE', state: { status: undefined, }, effects: { *login({ payload }, { call, put }) { const response = yield call(fakeAccountLogin, payload); yield put({ type: 'changeLoginStatus', payload: response, }); // Login successfully if (response.status === 'ok') { const urlParams = new URL(window.location.href); const params = getPageQuery(); let { redirect } = params as { redirect: string }; if (redirect) { const redirectUrlParams = new URL(redirect); if (redirectUrlParams.origin === urlParams.origin) { redirect = redirect.substr(urlParams.origin.length); if (redirect.match(/^\/.*#/)) { redirect = redirect.substr(redirect.indexOf('#') + 1); } } else { window.location.href = redirect; return; } } yield put(routerRedux.replace(redirect || '/')); } }, *getCaptcha({ payload }, { call }) { yield call(getFakeCaptcha, payload); }, *logout(_, { put }) { yield put({ type: 'changeLoginStatus', payload: { status: false, currentAuthority: 'guest', }, }); const { redirect } = getPageQuery(); // redirect if (window.location.pathname !== '/user/login' && !redirect) { yield put( routerRedux.replace({ pathname: '/user/login', search: stringify({ redirect: window.location.href, }), }), ); } }, }, reducers: { changeLoginStatus(state, { payload }) { setAuthority(payload.currentAuthority); return { ...state, status: payload.status, type: payload.type, }; }, }, }; export default Model;