global.ts 5 KB
Newer Older
陈帅's avatar
陈帅 committed
1
import { Reducer } from 'redux';
陈帅's avatar
陈帅 committed
2
import { Effect } from './connect.d';
duanledexianxianxian's avatar
duanledexianxianxian committed
3 4 5 6 7 8
import { Subscription } from 'dva';
import { routerRedux } from 'dva/router';
import store from '@/utils/store';
import { getPageQuery } from '@/utils';
import { setAuthority } from '@/utils/authority';
import { reloadAuthorized } from '@/utils/Authorized';
陈帅's avatar
陈帅 committed
9
import { NoticeIconData } from '@/components/NoticeIcon';
陈帅's avatar
陈帅 committed
10
import { queryNotices } from '@/services/user';
duanledexianxianxian's avatar
duanledexianxianxian committed
11
import { login, logout } from '@/services/global';
何乐's avatar
何乐 committed
12

何乐's avatar
何乐 committed
13
export interface NoticeItem extends NoticeIconData {
何乐's avatar
何乐 committed
14 15
  id: string;
  type: string;
16
  status: string;
何乐's avatar
何乐 committed
17
}
18

陈小聪's avatar
陈小聪 committed
19 20
export interface GlobalModelState {
  collapsed: boolean;
何乐's avatar
何乐 committed
21
  notices: NoticeItem[];
陈小聪's avatar
陈小聪 committed
22 23 24 25 26 27 28 29 30
}

export interface GlobalModelType {
  namespace: 'global';
  state: GlobalModelState;
  effects: {
    fetchNotices: Effect;
    clearNotices: Effect;
    changeNoticeReadState: Effect;
duanledexianxianxian's avatar
duanledexianxianxian committed
31
    login: Effect;
陈小聪's avatar
陈小聪 committed
32 33
  };
  reducers: {
何乐's avatar
何乐 committed
34 35 36
    changeLayoutCollapsed: Reducer<GlobalModelState>;
    saveNotices: Reducer<GlobalModelState>;
    saveClearedNotices: Reducer<GlobalModelState>;
duanledexianxianxian's avatar
duanledexianxianxian committed
37
    changeLoginStatus: Reducer<GlobalModelState>;
陈小聪's avatar
陈小聪 committed
38 39 40 41 42
  };
  subscriptions: { setup: Subscription };
}

const GlobalModel: GlobalModelType = {
43 44 45 46 47 48 49 50
  namespace: 'global',

  state: {
    collapsed: false,
    notices: [],
  },

  effects: {
duanledexianxianxian's avatar
duanledexianxianxian committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    *login({ payload }, { call, put }) {
      const { code, data } = yield call(login, payload);
      if (code === 'sys.success') {
        yield put({
          type: 'changeLoginStatus',
          payload: {},
        });
        reloadAuthorized();
        const { token, userId } = data;
        store.set('token', token);
        store.set('userId', userId);

        const urlParams = new URL(window.location.href);
        const params = getPageQuery();
        // 是否需要重定向
        let { redirect } = params;
        if (redirect) {
          const redirectUrlParams = new URL(redirect);
          // origin相同
          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;
          }
        }
        // else {
        //   redirect = config.homePage;
        // }
        yield put(routerRedux.replace(redirect || '/'));
      }
    },
86
    *fetchNotices(_, { call, put, select }) {
87 88 89
      const data = yield call(queryNotices);
      yield put({
        type: 'saveNotices',
Yu's avatar
Yu committed
90
        payload: data,
91
      });
何乐's avatar
何乐 committed
92 93
      const unreadCount: number = yield select(
        state => state.global.notices.filter(item => !item.read).length,
94
      );
Xiaoming Liu's avatar
Xiaoming Liu committed
95 96
      yield put({
        type: 'user/changeNotifyCount',
97 98 99 100
        payload: {
          totalCount: data.length,
          unreadCount,
        },
Xiaoming Liu's avatar
Xiaoming Liu committed
101
      });
102
    },
afc163's avatar
afc163 committed
103
    *clearNotices({ payload }, { put, select }) {
104 105 106 107
      yield put({
        type: 'saveClearedNotices',
        payload,
      });
何乐's avatar
何乐 committed
108 109 110
      const count: number = yield select(state => state.global.notices.length);
      const unreadCount: number = yield select(
        state => state.global.notices.filter(item => !item.read).length,
111
      );
afc163's avatar
afc163 committed
112 113
      yield put({
        type: 'user/changeNotifyCount',
114 115 116 117 118 119 120
        payload: {
          totalCount: count,
          unreadCount,
        },
      });
    },
    *changeNoticeReadState({ payload }, { put, select }) {
何乐's avatar
何乐 committed
121
      const notices: NoticeItem[] = yield select(state =>
122 123 124 125 126 127
        state.global.notices.map(item => {
          const notice = { ...item };
          if (notice.id === payload) {
            notice.read = true;
          }
          return notice;
何乐's avatar
何乐 committed
128
        }),
129
      );
陈帅's avatar
陈帅 committed
130

131 132 133 134
      yield put({
        type: 'saveNotices',
        payload: notices,
      });
陈帅's avatar
陈帅 committed
135

136 137 138 139 140 141
      yield put({
        type: 'user/changeNotifyCount',
        payload: {
          totalCount: notices.length,
          unreadCount: notices.filter(item => !item.read).length,
        },
afc163's avatar
afc163 committed
142 143
      });
    },
144 145 146
  },

  reducers: {
duanledexianxianxian's avatar
duanledexianxianxian committed
147 148 149 150 151 152
    changeLoginStatus(state, { payload }) {
      setAuthority('user');
      return {
        ...state,
      };
    },
陈帅's avatar
陈帅 committed
153
    changeLayoutCollapsed(state = { notices: [], collapsed: true }, { payload }): GlobalModelState {
154 155 156 157 158
      return {
        ...state,
        collapsed: payload,
      };
    },
陈帅's avatar
陈帅 committed
159
    saveNotices(state, { payload }): GlobalModelState {
160
      return {
陈帅's avatar
陈帅 committed
161
        collapsed: false,
162 163 164 165
        ...state,
        notices: payload,
      };
    },
陈帅's avatar
陈帅 committed
166
    saveClearedNotices(state = { notices: [], collapsed: true }, { payload }): GlobalModelState {
167
      return {
陈帅's avatar
陈帅 committed
168
        collapsed: false,
169
        ...state,
陈帅's avatar
陈帅 committed
170
        notices: state.notices.filter((item): boolean => item.type !== payload),
171 172 173
      };
    },
  },
afc163's avatar
afc163 committed
174 175

  subscriptions: {
陈帅's avatar
陈帅 committed
176
    setup({ history }): void {
afc163's avatar
afc163 committed
177
      // Subscribe history(url) change, trigger `load` action if pathname is `/`
陈帅's avatar
陈帅 committed
178
      history.listen(({ pathname, search }): void => {
陈小聪's avatar
陈小聪 committed
179 180
        if (typeof (window as any).ga !== 'undefined') {
          (window as any).ga('send', 'pageview', pathname + search);
afc163's avatar
afc163 committed
181 182 183 184
        }
      });
    },
  },
185
};
陈小聪's avatar
陈小聪 committed
186 187

export default GlobalModel;