浏览代码

feat: store 完成

xyh 2 年之前
父节点
当前提交
253dd43ee0

+ 6 - 0
packages/app/src/apis/network.ts

@@ -1,4 +1,5 @@
 import {BaseResultContent} from '@models';
+import {userStore} from '@stores';
 import {NETWORK_ERROR_TIPS, NETWORK_URL} from '@utils';
 import {message} from 'antd';
 import axios from 'axios';
@@ -20,6 +21,11 @@ http.interceptors.request.use(function(config) {
     isExport && (config.responseType = 'blob');
   }
 
+  const {id, token} = userStore.getState();
+
+  config.headers.token = token;
+  config.headers.userId = String(id);
+
   return config;
 });
 

+ 0 - 30
packages/app/src/stores/count.ts

@@ -1,30 +0,0 @@
-import {createStore} from 'zustand';
-
-type State = {
-  count: number;
-};
-
-type Action = {
-  inc: () => void;
-  dec: () => void;
-};
-
-export const countState = createStore<State & Action>(function(set) {
-  return {
-    count: 0,
-    inc() {
-      set(function({count}) {
-        return {
-          count: process.env.IS_E2E ? count + 2 : count + 1,
-        };
-      }, false);
-    },
-    dec() {
-      set(function({count}) {
-        return {
-          count: process.env.IS_E2E ? count - 2 : count - 1,
-        };
-      }, false);
-    },
-  };
-});

+ 3 - 1
packages/app/src/stores/index.ts

@@ -1 +1,3 @@
-export * from './count';
+export * from './user';
+export * from './tab';
+export * from './menu';

+ 28 - 0
packages/app/src/stores/menu.ts

@@ -0,0 +1,28 @@
+import {createStore} from 'zustand/vanilla';
+
+type State = {
+  menus: {
+    id: string;
+    name: string;
+    url: string;
+    pId: string;
+    img: string;
+  }[],
+};
+
+type Action = {
+  setMenu(state: State['menus']): void;
+  clear(): void;
+};
+
+export const menuStore = createStore<State & Action>(function(set) {
+  return {
+    menus: [] as State['menus'],
+    setMenu(menus) {
+      set({menus});
+    },
+    clear() {
+      set({menus: [] as State['menus']});
+    },
+  };
+});

+ 141 - 0
packages/app/src/stores/tab.ts

@@ -0,0 +1,141 @@
+
+import {createStore} from 'zustand/vanilla';
+
+type State = {
+  activeKey: string;
+  tabList: {
+    key: string;
+    url: string;
+    label: string;
+  }[];
+};
+type DispatchOptions =
+  | {type: 'ADD'; payload: State['tabList'][0]}
+  | {type: 'REMOVE'; payload: string}
+  | {type: 'REMOVE_OTHER'; payload: string}
+  | {type: 'REMOVE_RIGHT'; payload: string}
+  | {type: 'CLEAR'}
+  | {type: 'SORT'; payload: State['tabList']};
+
+type Action = {
+  setActiveKey: (key: string | ((prev: string) => string)) => void;
+  dispatch: (value: DispatchOptions) => void;
+  clear: () => void;
+};
+
+const defaultTab: State['tabList'][0] = {
+  key: '-1',
+  url: '/main',
+  label: '首页',
+};
+
+function reducer(
+  state: State['tabList'],
+  action: DispatchOptions,
+): State['tabList'] {
+  const {type} = action;
+
+  switch (type) {
+    case 'ADD': {
+      const {payload} = action;
+
+      const exist = state.find(val => val.key === payload.key);
+      if (exist)
+        return state;
+
+      return [...state, payload];
+    }
+    case 'REMOVE': {
+      const {payload} = action;
+      const idx = state.findIndex(val => val.key === payload);
+      if (idx < 0)
+        return state;
+
+      const nextState = [...state];
+      nextState.splice(idx, 1);
+      return nextState;
+    }
+    case 'REMOVE_OTHER': {
+      const {payload} = action;
+      const idx = state.findIndex(val => val.key === payload);
+      if (idx < 0)
+        return state;
+
+      return [{...defaultTab}, {...state[idx]}];
+    }
+    case 'REMOVE_RIGHT': {
+      const {payload} = action;
+      const idx = state.findIndex(val => val.key === payload);
+      if (idx < 0)
+        return state;
+
+      const {length} = state;
+      const nextState = [...state];
+      nextState.splice(idx + 1, length - idx - 1);
+
+      return nextState;
+    }
+    case 'CLEAR': {
+      return [{...defaultTab}];
+    }
+    case 'SORT':
+      return action.payload;
+    default:
+      return state;
+  }
+}
+
+export const tabStore = createStore<State & Action>(function(set) {
+  return {
+    activeKey: '',
+    tabList: [],
+    setActiveKey(key) {
+      set(function(prev) {
+        return {activeKey: typeof key === 'string' ? key : key(prev.activeKey)};
+      });
+    },
+    dispatch(value) {
+      set(function(prev) {
+        let nextActiveKey = prev.activeKey;
+        const result = reducer(prev.tabList, value);
+
+        switch (value.type) {
+          case 'ADD': // 新增后key改为最后一个
+            nextActiveKey = value.payload.key;
+            break;
+          case 'REMOVE': {
+            // 如果关闭的是当前active 修改为active的前一个
+            const idx = prev.tabList.findIndex(
+              val => val.key === value.payload,
+            );
+
+            prev.activeKey === prev.tabList[idx].key
+              && (nextActiveKey = prev.tabList[idx - 1].key);
+
+            break;
+          }
+          case 'REMOVE_OTHER': // 修改为关闭的那个
+            nextActiveKey = value.payload;
+            break;
+          case 'REMOVE_RIGHT': {
+            // 判断是否关闭了active 如果关闭了则显示触发的那个
+            result.findIndex(val => val.key === prev.activeKey) < 0
+              && (nextActiveKey = value.payload);
+            break;
+          }
+          case 'CLEAR': // 显示首页
+            nextActiveKey = '-1';
+            break;
+          case 'SORT':
+            // 不需要操作
+            break;
+        }
+
+        return {tabList: result, activeKey: nextActiveKey};
+      });
+    },
+    clear() {
+      set({activeKey: '-1', tabList: []});
+    },
+  };
+});

+ 49 - 0
packages/app/src/stores/user.ts

@@ -0,0 +1,49 @@
+import {QUERY_CLIENT, USER_TOKEN_STORAGE} from '@utils';
+import {createStore} from 'zustand/vanilla';
+import {tabStore} from './tab';
+import {menuStore} from './menu';
+
+type UserStoreState = {
+  id: number,
+  token: string,
+};
+
+type UserStoreAction = {
+  init(data: UserStoreState): void;
+  logout(): void;
+};
+
+function defaultValue(): UserStoreState {
+  return {
+    id: 0,
+    token: '',
+  };
+}
+
+export const userStore = createStore<UserStoreState & UserStoreAction>(
+  function(set) {
+    // 刷新时不会丢掉用户状态
+    const sessionData = sessionStorage.getItem(USER_TOKEN_STORAGE);
+    const initValue = sessionData
+      ? (JSON.parse(sessionData) as UserStoreState)
+      : defaultValue();
+
+    return {
+      ...initValue,
+      init(data) {
+        set(data);
+      },
+      logout() {
+        // 清除用户缓存
+        sessionStorage.removeItem(USER_TOKEN_STORAGE);
+        set(defaultValue());
+        // 清除请求缓存
+        QUERY_CLIENT.clear();
+        // 清除菜单缓存
+        menuStore.getState().clear();
+        // 清除tab状态
+        tabStore.getState().clear();
+      },
+    };
+  },
+);

+ 2 - 0
packages/app/src/utils/constants.ts

@@ -12,3 +12,5 @@ export const PAGE_SIZE_LIST = [
 ];
 /** 接口请求地址 */
 export const NETWORK_URL = '';
+/** 用户状态本地缓存 */
+export const USER_TOKEN_STORAGE = 'userInfo';