From 26b6109ca08a28c37355474bf8593f2e2b741ef6 Mon Sep 17 00:00:00 2001
From: vben <anncwb@126.com>
Date: 星期三, 25 十一月 2020 21:26:10 +0800
Subject: [PATCH] feat: add permissionCacheType setting

---
 src/settings/projectSetting.ts                  |    6 +
 src/store/modules/app.ts                        |    2 
 src/utils/helper/persistent.ts                  |   35 ++++++--
 src/layouts/default/multitabs/useAffixTabs.ts   |   35 ++++++++
 src/store/modules/user.ts                       |   40 ++++++---
 src/hooks/web/useLockPage.ts                    |    2 
 src/hooks/setting/useTransitionSetting.ts       |    2 
 src/types/config.d.ts                           |    4 
 src/hooks/core/useTimeout.ts                    |    2 
 src/enums/cacheEnum.ts                          |    5 +
 src/layouts/default/multitabs/useTabDropdown.ts |    1 
 src/layouts/default/multitabs/index.tsx         |   49 ++---------
 src/router/guard/index.ts                       |    2 
 src/layouts/default/multitabs/index.less        |    7 -
 src/setup/App.ts                                |   18 ++--
 15 files changed, 123 insertions(+), 87 deletions(-)

diff --git a/src/enums/cacheEnum.ts b/src/enums/cacheEnum.ts
index 77cfdbd..4e6f43e 100644
--- a/src/enums/cacheEnum.ts
+++ b/src/enums/cacheEnum.ts
@@ -18,3 +18,8 @@
 
 // base global session key
 export const BASE_SESSION_CACHE_KEY = 'SESSION__CACHE__KEY__';
+
+export enum CacheTypeEnum {
+  SESSION,
+  LOCAL,
+}
diff --git a/src/hooks/core/useTimeout.ts b/src/hooks/core/useTimeout.ts
index 4fcc19a..119cbe7 100644
--- a/src/hooks/core/useTimeout.ts
+++ b/src/hooks/core/useTimeout.ts
@@ -23,7 +23,7 @@
 export function useTimeoutRef(wait: number) {
   const readyRef = ref(false);
 
-  let timer: ReturnType<typeof setTimeout> | undefined;
+  let timer: TimeoutHandle;
   function stop(): void {
     readyRef.value = false;
     timer && window.clearTimeout(timer);
diff --git a/src/hooks/setting/useTransitionSetting.ts b/src/hooks/setting/useTransitionSetting.ts
index 17039f8..ce7f759 100644
--- a/src/hooks/setting/useTransitionSetting.ts
+++ b/src/hooks/setting/useTransitionSetting.ts
@@ -7,7 +7,7 @@
 export function useTransitionSetting() {
   const getTransitionSetting = computed(() => appStore.getProjectConfig.transitionSetting);
 
-  const getEnableTransition = computed(() => unref(getTransitionSetting).enable);
+  const getEnableTransition = computed(() => unref(getTransitionSetting)?.enable);
 
   const getOpenNProgress = computed(() => unref(getTransitionSetting)?.openNProgress);
 
diff --git a/src/hooks/web/useLockPage.ts b/src/hooks/web/useLockPage.ts
index 1988b4e..c315e67 100644
--- a/src/hooks/web/useLockPage.ts
+++ b/src/hooks/web/useLockPage.ts
@@ -5,7 +5,7 @@
 import { userStore } from '/@/store/modules/user';
 
 export function useLockPage() {
-  let timeId: ReturnType<typeof setTimeout>;
+  let timeId: TimeoutHandle;
 
   function clear(): void {
     window.clearTimeout(timeId);
diff --git a/src/layouts/default/multitabs/index.less b/src/layouts/default/multitabs/index.less
index 1e052ab..ff636b0 100644
--- a/src/layouts/default/multitabs/index.less
+++ b/src/layouts/default/multitabs/index.less
@@ -40,12 +40,9 @@
           height: 12px;
           font-size: 12px;
           color: inherit;
-          visibility: hidden;
           transition: none;
 
           &:hover {
-            visibility: visible;
-
             svg {
               width: 0.8em;
             }
@@ -70,10 +67,6 @@
 
         &::before {
           display: none;
-        }
-
-        .ant-tabs-close-x {
-          visibility: visible;
         }
 
         svg {
diff --git a/src/layouts/default/multitabs/index.tsx b/src/layouts/default/multitabs/index.tsx
index 8b00f61..4defffd 100644
--- a/src/layouts/default/multitabs/index.tsx
+++ b/src/layouts/default/multitabs/index.tsx
@@ -1,10 +1,11 @@
+import './index.less';
+
 import type { TabContentProps } from './tab.data';
 import type { TabItem } from '/@/store/modules/tab';
 import type { AppRouteRecordRaw } from '/@/router/types';
 
-import { defineComponent, watch, computed, unref, toRaw } from 'vue';
+import { defineComponent, watch, computed, unref } from 'vue';
 import { useRouter } from 'vue-router';
-import router from '/@/router';
 
 import { Tabs } from 'ant-design-vue';
 import TabContent from './TabContent';
@@ -18,12 +19,12 @@
 
 import { closeTab } from './useTabDropdown';
 import { useTabs } from '/@/hooks/web/useTabs';
+import { initAffixTabs } from './useAffixTabs';
 
-import './index.less';
 export default defineComponent({
-  name: 'MultiTabs',
+  name: 'MultipleTabs',
   setup() {
-    let isAddAffix = false;
+    initAffixTabs();
 
     const go = useGo();
 
@@ -36,11 +37,6 @@
     watch(
       () => tabStore.getLastChangeRouteState,
       () => {
-        if (!isAddAffix) {
-          addAffixTabs();
-          isAddAffix = true;
-        }
-
         const lastChangeRoute = unref(tabStore.getLastChangeRouteState);
 
         if (!lastChangeRoute || !userStore.getTokenState) return;
@@ -56,39 +52,15 @@
       }
     );
 
-    /**
-     * @description: 杩囨护鎵�鏈夊浐瀹氳矾鐢�
-     */
-    function filterAffixTabs(routes: AppRouteRecordRaw[]) {
-      const tabs: TabItem[] = [];
-      routes &&
-        routes.forEach((route) => {
-          if (route.meta && route.meta.affix) {
-            tabs.push(toRaw(route) as TabItem);
-          }
-        });
-      return tabs;
-    }
-
-    /**
-     * @description: 璁剧疆鍥哄畾tabs
-     */
-    function addAffixTabs(): void {
-      const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as AppRouteRecordRaw[]);
-      for (const tab of affixTabs) {
-        tabStore.commitAddTab(tab);
-      }
-    }
-
     // tab鍒囨崲
     function handleChange(activeKey: any) {
       activeKeyRef.value = activeKey;
       go(activeKey, false);
     }
 
-    // 鍏抽棴褰撳墠ab
+    // 鍏抽棴褰撳墠tab
     function handleEdit(targetKey: string) {
-      // 鏂板鎿嶄綔闅愯棌锛岀洰鍓嶅彧浣跨敤鍒犻櫎鎿嶄綔
+      // Added operation to hide, currently only use delete operation
       const index = unref(getTabsState).findIndex(
         (item) => (item.fullPath || item.path) === targetKey
       );
@@ -107,12 +79,13 @@
         </span>
       );
     }
+
     function renderTabs() {
       return unref(getTabsState).map((item: TabItem) => {
         const key = item.query ? item.fullPath : item.path;
-
+        const closable = !(item && item.meta && item.meta.affix);
         return (
-          <Tabs.TabPane key={key} closable={!(item && item.meta && item.meta.affix)}>
+          <Tabs.TabPane key={key} closable={closable}>
             {{
               tab: () => <TabContent tabItem={item} />,
             }}
diff --git a/src/layouts/default/multitabs/useAffixTabs.ts b/src/layouts/default/multitabs/useAffixTabs.ts
new file mode 100644
index 0000000..24cb4ba
--- /dev/null
+++ b/src/layouts/default/multitabs/useAffixTabs.ts
@@ -0,0 +1,35 @@
+import { toRaw } from 'vue';
+import router from '/@/router';
+import { AppRouteRecordRaw } from '/@/router/types';
+import { TabItem, tabStore } from '/@/store/modules/tab';
+
+export function initAffixTabs() {
+  /**
+   * @description: Filter all fixed routes
+   */
+  function filterAffixTabs(routes: AppRouteRecordRaw[]) {
+    const tabs: TabItem[] = [];
+    routes &&
+      routes.forEach((route) => {
+        if (route.meta && route.meta.affix) {
+          tabs.push(toRaw(route) as TabItem);
+        }
+      });
+    return tabs;
+  }
+
+  /**
+   * @description: Set fixed tabs
+   */
+  function addAffixTabs(): void {
+    const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as AppRouteRecordRaw[]);
+    for (const tab of affixTabs) {
+      tabStore.commitAddTab(tab);
+    }
+  }
+  let isAddAffix = false;
+  if (!isAddAffix) {
+    addAffixTabs();
+    isAddAffix = true;
+  }
+}
diff --git a/src/layouts/default/multitabs/useTabDropdown.ts b/src/layouts/default/multitabs/useTabDropdown.ts
index bfa0350..7fb893b 100644
--- a/src/layouts/default/multitabs/useTabDropdown.ts
+++ b/src/layouts/default/multitabs/useTabDropdown.ts
@@ -203,6 +203,7 @@
   const getTabsState = computed(() => {
     return tabStore.getTabsState;
   });
+
   const { path } = unref(currentRoute);
   if (path !== closedTab.path) {
     // 鍏抽棴鐨勪笉鏄縺娲籺ab
diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts
index 6143d41..98bf617 100644
--- a/src/router/guard/index.ts
+++ b/src/router/guard/index.ts
@@ -14,9 +14,9 @@
 
 import { tabStore } from '/@/store/modules/tab';
 
+const { closeMessageOnSwitch, removeAllHttpPending } = useProjectSetting();
 const globSetting = useGlobSetting();
 export function createGuard(router: Router) {
-  const { closeMessageOnSwitch, removeAllHttpPending } = useProjectSetting();
   let axiosCanceler: AxiosCanceler | null;
   if (removeAllHttpPending) {
     axiosCanceler = new AxiosCanceler();
diff --git a/src/settings/projectSetting.ts b/src/settings/projectSetting.ts
index 6562e72..9a4156d 100644
--- a/src/settings/projectSetting.ts
+++ b/src/settings/projectSetting.ts
@@ -1,6 +1,7 @@
 import type { ProjectConfig } from '/@/types/config';
 
 import { MenuTypeEnum, MenuModeEnum, TriggerEnum } from '/@/enums/menuEnum';
+import { CacheTypeEnum } from '/@/enums/cacheEnum';
 import { ContentEnum, PermissionModeEnum, ThemeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
 import { primaryColor } from '../../build/config/lessModifyVars';
 import { isProdMode } from '/@/utils/env';
@@ -12,6 +13,9 @@
 
   // Permission mode
   permissionMode: PermissionModeEnum.ROLE,
+
+  // Permission-related cache is stored in sessionStorage or localStorage
+  permissionCacheType: CacheTypeEnum.LOCAL,
 
   // color
   // TODO Theme color
@@ -130,7 +134,7 @@
     openPageLoading: true,
 
     // Whether to open the top progress bar
-    openNProgress: true,
+    openNProgress: false,
   },
 
   // Whether to enable KeepAlive cache is best to close during development, otherwise the cache needs to be cleared every time
diff --git a/src/setup/App.ts b/src/setup/App.ts
index 1028159..3ab0db9 100644
--- a/src/setup/App.ts
+++ b/src/setup/App.ts
@@ -20,6 +20,7 @@
 } from '/@/setup/theme';
 
 import { appStore } from '/@/store/modules/app';
+import { deepMerge } from '../utils/index';
 
 // Used to share global app instances
 let app: App;
@@ -50,16 +51,15 @@
 // Initial project configuration
 export function initAppConfigStore() {
   let projCfg: ProjectConfig = getLocal(PROJ_CFG_KEY) as ProjectConfig;
-  if (!projCfg) {
-    projCfg = projectSetting;
-  }
-  const {
-    colorWeak,
-    grayMode,
-    headerSetting: { bgColor: headerBgColor },
-    menuSetting: { bgColor },
-  } = projCfg;
+  projCfg = deepMerge(projectSetting, projCfg || {});
+
   try {
+    const {
+      colorWeak,
+      grayMode,
+      headerSetting: { bgColor: headerBgColor } = {},
+      menuSetting: { bgColor } = {},
+    } = projCfg;
     // if (
     //   themeColor !== primaryColor &&
     //   themeColor &&
diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts
index 6be45f8..b4b6d61 100644
--- a/src/store/modules/app.ts
+++ b/src/store/modules/app.ts
@@ -26,7 +26,7 @@
   isLock: boolean;
 }
 
-let timeId: ReturnType<typeof setTimeout>;
+let timeId: TimeoutHandle;
 const NAME = 'app';
 hotModuleUnregisterModule(NAME);
 @Module({ dynamic: true, namespaced: true, store, name: NAME })
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index c037681..fe4bc97 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -11,7 +11,7 @@
 
 import { PageEnum } from '/@/enums/pageEnum';
 import { RoleEnum } from '/@/enums/roleEnum';
-import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
+import { CacheTypeEnum, ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
 
 import { useMessage } from '/@/hooks/web/useMessage';
 
@@ -19,13 +19,29 @@
 
 import { loginApi, getUserInfoById } from '/@/api/sys/user';
 
-import { setLocal, getLocal } from '/@/utils/helper/persistent';
-// import { FULL_PAGE_NOT_FOUND_ROUTE } from '/@/router/constant';
+import { setLocal, getLocal, getSession, setSession } from '/@/utils/helper/persistent';
+import { useProjectSetting } from '/@/hooks/setting';
 
 export type UserInfo = Omit<GetUserInfoByUserIdModel, 'roles'>;
 
 const NAME = 'user';
 hotModuleUnregisterModule(NAME);
+
+const { permissionCacheType } = useProjectSetting();
+
+function getCache<T>(key: string) {
+  const fn = permissionCacheType === CacheTypeEnum.LOCAL ? getLocal : getSession;
+  return fn(key) as T;
+}
+
+function setCache(USER_INFO_KEY: string, info: any) {
+  if (!info) return;
+  // const fn = permissionCacheType === CacheTypeEnum.LOCAL ? setLocal : setSession;
+  setLocal(USER_INFO_KEY, info, true);
+  // TODO
+  setSession(USER_INFO_KEY, info, true);
+}
+
 @Module({ namespaced: true, name: NAME, dynamic: true, store })
 class User extends VuexModule {
   // user info
@@ -38,15 +54,15 @@
   private roleListState: RoleEnum[] = [];
 
   get getUserInfoState(): UserInfo {
-    return this.userInfoState || (getLocal(USER_INFO_KEY) as UserInfo) || {};
+    return this.userInfoState || getCache<UserInfo>(USER_INFO_KEY) || {};
   }
 
   get getTokenState(): string {
-    return this.tokenState || (getLocal(TOKEN_KEY) as string);
+    return this.tokenState || getCache<string>(TOKEN_KEY);
   }
 
   get getRoleListState(): RoleEnum[] {
-    return this.roleListState.length > 0 ? this.roleListState : (getLocal(ROLES_KEY) as RoleEnum[]);
+    return this.roleListState.length > 0 ? this.roleListState : getCache<RoleEnum[]>(ROLES_KEY);
   }
 
   @Mutation
@@ -59,25 +75,19 @@
   @Mutation
   commitUserInfoState(info: UserInfo): void {
     this.userInfoState = info;
-    if (info) {
-      setLocal(USER_INFO_KEY, info, true);
-    }
+    setCache(USER_INFO_KEY, info);
   }
 
   @Mutation
   commitRoleListState(roleList: RoleEnum[]): void {
     this.roleListState = roleList;
-    if (roleList) {
-      setLocal(ROLES_KEY, roleList, true);
-    }
+    setCache(ROLES_KEY, roleList);
   }
 
   @Mutation
   commitTokenState(info: string): void {
     this.tokenState = info;
-    if (info) {
-      setLocal(TOKEN_KEY, info, true);
-    }
+    setCache(TOKEN_KEY, info);
   }
 
   /**
diff --git a/src/types/config.d.ts b/src/types/config.d.ts
index 2a80b23..43d465b 100644
--- a/src/types/config.d.ts
+++ b/src/types/config.d.ts
@@ -1,6 +1,6 @@
-// 宸︿晶鑿滃崟, 椤堕儴鑿滃崟
 import { MenuTypeEnum, MenuModeEnum, TriggerEnum } from '/@/enums/menuEnum';
 import { ContentEnum, PermissionModeEnum, ThemeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
+import { CacheTypeEnum } from '/@/enums/cacheEnum';
 import type { LocaleType } from '/@/locales/types';
 
 export interface MenuSetting {
@@ -76,6 +76,8 @@
 export interface ProjectConfig {
   locale: LocaleSetting;
 
+  permissionCacheType: CacheTypeEnum;
+
   // 鏄惁鏄剧ず閰嶇疆鎸夐挳
   showSettingButton: boolean;
   // 鏉冮檺妯″紡
diff --git a/src/utils/helper/persistent.ts b/src/utils/helper/persistent.ts
index 62449d1..46f99c8 100644
--- a/src/utils/helper/persistent.ts
+++ b/src/utils/helper/persistent.ts
@@ -29,8 +29,12 @@
 initCache();
 
 export function setLocal(key: string, value: any, immediate = false) {
-  cacheStore.local[BASE_LOCAL_CACHE_KEY] = cacheStore.local[BASE_LOCAL_CACHE_KEY] || {};
+  const local = ls.get(BASE_LOCAL_CACHE_KEY)?.[BASE_LOCAL_CACHE_KEY] || {};
+
+  cacheStore.local[BASE_LOCAL_CACHE_KEY] =
+    { ...local, ...cacheStore.local[BASE_LOCAL_CACHE_KEY] } || {};
   cacheStore.local[BASE_LOCAL_CACHE_KEY][key] = value;
+
   if (immediate) {
     ls.set(BASE_LOCAL_CACHE_KEY, cacheStore.local);
   }
@@ -50,16 +54,21 @@
   }
 }
 
-export function clearLocal() {
+export function clearLocal(immediate = false) {
   cacheStore.local = {};
+  immediate && ls.remove(BASE_LOCAL_CACHE_KEY);
 }
 
 export function setSession(key: string, value: any, immediate = false) {
-  cacheStore.session[BASE_SESSION_CACHE_KEY] = cacheStore.session[BASE_SESSION_CACHE_KEY] || {};
+  const session = ss.get(BASE_SESSION_CACHE_KEY)?.[BASE_SESSION_CACHE_KEY] || {};
+
+  cacheStore.session[BASE_SESSION_CACHE_KEY] =
+    { ...session, ...cacheStore.session[BASE_SESSION_CACHE_KEY] } || {};
+
   cacheStore.session[BASE_SESSION_CACHE_KEY][key] = value;
+
   if (immediate) {
-    const cache = cacheStore.session;
-    ss.set(BASE_SESSION_CACHE_KEY, cache);
+    ss.set(BASE_SESSION_CACHE_KEY, cacheStore.session);
   }
 }
 
@@ -77,8 +86,9 @@
   }
 }
 
-export function clearSession() {
+export function clearSession(immediate = false) {
   cacheStore.session = {};
+  immediate && ss.remove(BASE_SESSION_CACHE_KEY);
 }
 
 export function clearAll() {
@@ -86,14 +96,17 @@
   clearSession();
 }
 
+export function persistentCache() {
+  const localCache = cacheStore.local;
+  const sessionCache = cacheStore.session;
+  ls.set(BASE_LOCAL_CACHE_KEY, localCache);
+  ss.set(BASE_SESSION_CACHE_KEY, sessionCache);
+}
+
 (() => {
   // /** Write to local before closing window */
   window.addEventListener('beforeunload', () => {
-    const localCache = cacheStore.local;
-    const sessionCache = cacheStore.session;
-
-    ls.set(BASE_LOCAL_CACHE_KEY, localCache);
-    ss.set(BASE_SESSION_CACHE_KEY, sessionCache);
+    persistentCache();
   });
 
   function storageChange(e: any) {

--
Gitblit v1.8.0