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