From 74ded8aed7bd5f2e4f3008a4566d8e3dd0510566 Mon Sep 17 00:00:00 2001
From: LooSheng <30114549+loosheng@users.noreply.github.com>
Date: 星期五, 24 三月 2023 17:48:35 +0800
Subject: [PATCH] perf: respect the writing style of pinia getters (#2645)

---
 src/store/modules/user.ts |  321 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 170 insertions(+), 151 deletions(-)

diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index 35f94b1..ea16c40 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -1,158 +1,177 @@
-import type {
-  LoginParams,
-  GetUserInfoByUserIdModel,
-  GetUserInfoByUserIdParams,
-} from '/@/api/sys/model/userModel';
-
-import store from '/@/store/index';
-import { VuexModule, Module, getModule, Mutation, Action } from 'vuex-module-decorators';
-import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
-
-import { PageEnum } from '/@/enums/pageEnum';
+import type { UserInfo } from '/#/store';
+import type { ErrorMessageMode } from '/#/axios';
+import { defineStore } from 'pinia';
+import { store } from '/@/store';
 import { RoleEnum } from '/@/enums/roleEnum';
-import { CacheTypeEnum, ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
-
-import { useMessage } from '/@/hooks/web/useMessage';
-
-import router from '/@/router';
-
-import { loginApi, getUserInfoById } from '/@/api/sys/user';
-
-import { setLocal, getLocal, getSession, setSession } from '/@/utils/helper/persistent';
-import { useProjectSetting } from '/@/hooks/setting';
+import { PageEnum } from '/@/enums/pageEnum';
+import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
+import { getAuthCache, setAuthCache } from '/@/utils/auth';
+import { GetUserInfoModel, LoginParams } from '/@/api/sys/model/userModel';
+import { doLogout, getUserInfo, loginApi } from '/@/api/sys/user';
 import { useI18n } from '/@/hooks/web/useI18n';
-import { ErrorMessageMode } from '/@/utils/http/axios/types';
+import { useMessage } from '/@/hooks/web/useMessage';
+import { router } from '/@/router';
+import { usePermissionStore } from '/@/store/modules/permission';
+import { RouteRecordRaw } from 'vue-router';
+import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
+import { isArray } from '/@/utils/is';
+import { h } from 'vue';
 
-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;
+interface UserState {
+  userInfo: Nullable<UserInfo>;
+  token?: string;
+  roleList: RoleEnum[];
+  sessionTimeout?: boolean;
+  lastUpdateTime: number;
 }
 
-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
-  private userInfoState: UserInfo | null = null;
-
-  // token
-  private tokenState = '';
-
-  // roleList
-  private roleListState: RoleEnum[] = [];
-
-  get getUserInfoState(): UserInfo {
-    return this.userInfoState || getCache<UserInfo>(USER_INFO_KEY) || {};
-  }
-
-  get getTokenState(): string {
-    return this.tokenState || getCache<string>(TOKEN_KEY);
-  }
-
-  get getRoleListState(): RoleEnum[] {
-    return this.roleListState.length > 0 ? this.roleListState : getCache<RoleEnum[]>(ROLES_KEY);
-  }
-
-  @Mutation
-  commitResetState(): void {
-    this.userInfoState = null;
-    this.tokenState = '';
-    this.roleListState = [];
-  }
-
-  @Mutation
-  commitUserInfoState(info: UserInfo): void {
-    this.userInfoState = info;
-    setCache(USER_INFO_KEY, info);
-  }
-
-  @Mutation
-  commitRoleListState(roleList: RoleEnum[]): void {
-    this.roleListState = roleList;
-    setCache(ROLES_KEY, roleList);
-  }
-
-  @Mutation
-  commitTokenState(info: string): void {
-    this.tokenState = info;
-    setCache(TOKEN_KEY, info);
-  }
-
-  /**
-   * @description: login
-   */
-  @Action
-  async login(
-    params: LoginParams & {
-      goHome?: boolean;
-      mode?: ErrorMessageMode;
-    }
-  ): Promise<GetUserInfoByUserIdModel | null> {
-    try {
-      const { goHome = true, mode, ...loginParams } = params;
-      const data = await loginApi(loginParams, mode);
-
-      const { token, userId } = data;
-
-      // save token
-      this.commitTokenState(token);
-
-      // get user info
-      const userInfo = await this.getUserInfoAction({ userId });
-
-      goHome && (await router.replace(PageEnum.BASE_HOME));
-      return userInfo;
-    } catch (error) {
-      return null;
-    }
-  }
-
-  @Action
-  async getUserInfoAction({ userId }: GetUserInfoByUserIdParams) {
-    const userInfo = await getUserInfoById({ userId });
-    const { roles } = userInfo;
-    const roleList = roles.map((item) => item.value) as RoleEnum[];
-    this.commitUserInfoState(userInfo);
-    this.commitRoleListState(roleList);
-    return userInfo;
-  }
-
-  /**
-   * @description: login out
-   */
-  @Action
-  async loginOut(goLogin = false) {
-    goLogin && router.push(PageEnum.BASE_LOGIN);
-  }
-
-  /**
-   * @description: Confirm before logging out
-   */
-  @Action
-  async confirmLoginOut() {
-    const { createConfirm } = useMessage();
-    const { t } = useI18n();
-    createConfirm({
-      iconType: 'warning',
-      title: t('sys.app.loginOutTip'),
-      content: t('sys.app.loginOutMessage'),
-      onOk: async () => {
-        await this.loginOut(true);
+export const useUserStore = defineStore({
+  id: 'app-user',
+  state: (): UserState => ({
+    // user info
+    userInfo: null,
+    // token
+    token: undefined,
+    // roleList
+    roleList: [],
+    // Whether the login expired
+    sessionTimeout: false,
+    // Last fetch time
+    lastUpdateTime: 0,
+  }),
+  getters: {
+    getUserInfo(state): UserInfo {
+      return state.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
+    },
+    getToken(state): string {
+      return state.token || getAuthCache<string>(TOKEN_KEY);
+    },
+    getRoleList(state): RoleEnum[] {
+      return state.roleList.length > 0 ? state.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY);
+    },
+    getSessionTimeout(state): boolean {
+      return !!state.sessionTimeout;
+    },
+    getLastUpdateTime(state): number {
+      return state.lastUpdateTime;
+    },
+  },
+  actions: {
+    setToken(info: string | undefined) {
+      this.token = info ? info : ''; // for null or undefined value
+      setAuthCache(TOKEN_KEY, info);
+    },
+    setRoleList(roleList: RoleEnum[]) {
+      this.roleList = roleList;
+      setAuthCache(ROLES_KEY, roleList);
+    },
+    setUserInfo(info: UserInfo | null) {
+      this.userInfo = info;
+      this.lastUpdateTime = new Date().getTime();
+      setAuthCache(USER_INFO_KEY, info);
+    },
+    setSessionTimeout(flag: boolean) {
+      this.sessionTimeout = flag;
+    },
+    resetState() {
+      this.userInfo = null;
+      this.token = '';
+      this.roleList = [];
+      this.sessionTimeout = false;
+    },
+    /**
+     * @description: login
+     */
+    async login(
+      params: LoginParams & {
+        goHome?: boolean;
+        mode?: ErrorMessageMode;
       },
-    });
-  }
+    ): Promise<GetUserInfoModel | null> {
+      try {
+        const { goHome = true, mode, ...loginParams } = params;
+        const data = await loginApi(loginParams, mode);
+        const { token } = data;
+
+        // save token
+        this.setToken(token);
+        return this.afterLoginAction(goHome);
+      } catch (error) {
+        return Promise.reject(error);
+      }
+    },
+    async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> {
+      if (!this.getToken) return null;
+      // get user info
+      const userInfo = await this.getUserInfoAction();
+
+      const sessionTimeout = this.sessionTimeout;
+      if (sessionTimeout) {
+        this.setSessionTimeout(false);
+      } else {
+        const permissionStore = usePermissionStore();
+        if (!permissionStore.isDynamicAddedRoute) {
+          const routes = await permissionStore.buildRoutesAction();
+          routes.forEach((route) => {
+            router.addRoute(route as unknown as RouteRecordRaw);
+          });
+          router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
+          permissionStore.setDynamicAddedRoute(true);
+        }
+        goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME));
+      }
+      return userInfo;
+    },
+    async getUserInfoAction(): Promise<UserInfo | null> {
+      if (!this.getToken) return null;
+      const userInfo = await getUserInfo();
+      const { roles = [] } = userInfo;
+      if (isArray(roles)) {
+        const roleList = roles.map((item) => item.value) as RoleEnum[];
+        this.setRoleList(roleList);
+      } else {
+        userInfo.roles = [];
+        this.setRoleList([]);
+      }
+      this.setUserInfo(userInfo);
+      return userInfo;
+    },
+    /**
+     * @description: logout
+     */
+    async logout(goLogin = false) {
+      if (this.getToken) {
+        try {
+          await doLogout();
+        } catch {
+          console.log('娉ㄩ攢Token澶辫触');
+        }
+      }
+      this.setToken(undefined);
+      this.setSessionTimeout(false);
+      this.setUserInfo(null);
+      goLogin && router.push(PageEnum.BASE_LOGIN);
+    },
+
+    /**
+     * @description: Confirm before logging out
+     */
+    confirmLoginOut() {
+      const { createConfirm } = useMessage();
+      const { t } = useI18n();
+      createConfirm({
+        iconType: 'warning',
+        title: () => h('span', t('sys.app.logoutTip')),
+        content: () => h('span', t('sys.app.logoutMessage')),
+        onOk: async () => {
+          await this.logout(true);
+        },
+      });
+    },
+  },
+});
+
+// Need to be used outside the setup
+export function useUserStoreWithOut() {
+  return useUserStore(store);
 }
-export const userStore = getModule<User>(User);

--
Gitblit v1.8.0