import type { UserInfo } from '/#/store' import type { ErrorMessageMode } from '/#/axios' import { defineStore } from 'pinia' import { store } from '/@/store' import { RoleEnum } from '/@/enums/roleEnum' 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, loginApi, getUserInfo } from '/@/api/sys/user' import { useI18n } from '/@/hooks/web/useI18n' 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' interface UserState { userInfo: Nullable token?: string roleList: RoleEnum[] sessionTimeout?: boolean lastUpdateTime: number permissions: string[] } 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, permissions: [], }), getters: { getUserInfo(): UserInfo { return this.userInfo || getAuthCache(USER_INFO_KEY) || {} }, getToken(): string { return this.token || getAuthCache(TOKEN_KEY) }, getRoleList(): RoleEnum[] { return this.roleList.length > 0 ? this.roleList : getAuthCache(ROLES_KEY) }, getSessionTimeout(): boolean { return !!this.sessionTimeout }, getLastUpdateTime(): number { return this.lastUpdateTime }, getPermissions(): string[] { return this.permissions }, }, 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) }, setPermissions(permissions: string[]) { this.permissions = permissions }, 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 homeRouter?: string }, ): Promise { try { const { goHome = true, mode, homeRouter, ...loginParams } = params const data = await loginApi(loginParams, mode) const { token } = data this.setToken(token) console.log(data) return this.afterLoginAction(goHome, homeRouter) } catch (error) { console.log(error) return Promise.reject(error) } }, async afterLoginAction(goHome?: boolean, homeRouter?: string): Promise { if (!this.getToken) return null 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) } const isAuthData = userInfo?.permissions.includes('endpoint.data_dashboard') if (!isAuthData && homeRouter == '/v') { const { notification } = useMessage() notification.error({ message: '登陆失败', description: `没有权限`, duration: 3, }) return this.logout() } goHome && (await router.replace(homeRouter ?? PageEnum.BASE_HOME)) } return userInfo }, async getUserInfoAction(): Promise { if (!this.getToken) return null const { info, permissions_slug }: GetUserInfoModel = await getUserInfo() const userInfo: UserInfo = Object.assign({}, info, { permissions: permissions_slug, roles: [], }) if (isArray(permissions_slug)) { this.setPermissions(permissions_slug) } else { userInfo.permissions = [] this.setPermissions([]) } if (userInfo.username === 'admin') { this.setRoleList([RoleEnum.SUPER]) } 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.Tip')), 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) }