import type { UserInfo } from '/#/store'; import type { ErrorMessageMode } from '/#/axios'; import { defineStore } from 'pinia'; import { store } from '/@/store'; 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, RoleInfo } from '/@/api/system/login/model'; import { doLogout, getUserInfo, loginApi, singleLoginApi } from '/@/api/system/login'; 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 { h } from 'vue'; import { getAppEnvConfig } from '/@/utils/env'; interface UserState { userInfo: Nullable; token?: string; roleList: RoleInfo[]; sessionTimeout?: boolean; lastUpdateTime: number; } 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(): UserInfo { return this.userInfo || getAuthCache(USER_INFO_KEY) || {}; }, getToken(): string { return this.token || getAuthCache(TOKEN_KEY); }, getRoleList(): RoleInfo[] { return this.roleList && this.roleList.length > 0 ? this.roleList : getAuthCache(ROLES_KEY); }, getSessionTimeout(): boolean { return !!this.sessionTimeout; }, getLastUpdateTime(): number { return this.lastUpdateTime; }, }, actions: { setToken(info: string | undefined) { this.token = info ? info : ''; // for null or undefined value setAuthCache(TOKEN_KEY, info); }, setRoleList(roleList: RoleInfo[]) { 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: OAUTH Login */ async oauthLogin( params: { token: string; } & { goHome?: boolean; mode?: ErrorMessageMode; }, ): Promise { try { const { goHome = true, token } = params; // save token this.setToken(token); return this.afterLoginAction(goHome); } catch (error) { return Promise.reject(error); } }, /** * @description: login */ async login( params: LoginParams & { goHome?: boolean; mode?: ErrorMessageMode; }, ): Promise { try { const { goHome = true, mode, ...loginParams } = params; const data = await loginApi(loginParams, mode); const { token } = data; // save token this.setToken(token); return await this.afterLoginAction(goHome); } catch (error) { return Promise.reject(error); } }, /** * @description: singleLogin */ async singleLogin( params: any ): Promise { try { const data = await singleLoginApi(params, params.mode); const userInfo = await this.getUserInfoAction(); const { token } = data; // save token this.setToken(token); router.replace(params.targetURL || params.redirect || userInfo?.homePath || PageEnum.BASE_HOME) return await this.afterLoginAction(false); } catch (error) { return Promise.reject(error); } }, async afterLoginAction(goHome?: boolean): Promise { if (!this.getToken) return null; // get user info const userInfo = await this.getUserInfoAction(); // setOtherToken(this.getToken); const sessionTimeout = this.sessionTimeout; if (sessionTimeout) { this.setSessionTimeout(false); } else { const permissionStore = usePermissionStore(); if (!permissionStore.getIsDynamicAddedRoute) { permissionStore.setDynamicAddedRoute(true); 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); } goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME)); } setOtherToken(this.getToken); return Promise.resolve(userInfo); }, async getUserInfoAction(): Promise { if (!this.getToken) return null; const userInfoResult = await getUserInfo(); const { roles = [] } = userInfoResult; const userInfo = userInfoResult as unknown as UserInfo; this.setUserInfo(userInfo); this.setRoleList(roles); return Promise.resolve(userInfoResult); }, /** * @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('温馨提醒')), content: () => h('span', t('是否确认退出系统?')), onOk: async () => { await this.logout(true); }, okText: () => t('确认'), cancelText: () => t('取消'), }); }, }, }); // Need to be used outside the setup export function useUserStoreWithOut() { return useUserStore(store); } //设置其他url 项目 token function setOtherToken(token: string) { // console.log('other token', getAppEnvConfig()); // something like: "https://codegeex.cn" or "https://codegeex.cn" or getAppEnvConfig() .VITE_GLOB_OUT_LINK_URL?.split(',') ?.forEach((item) => { // 创建子域的iframe, 用于传送数据 const iframe = document.createElement('iframe'); iframe.src = `${item}`; iframe.style.display = 'none'; document.body.append(iframe); // 使用postMessage()发送数据到子系统 setTimeout(function () { iframe.contentWindow?.postMessage(token, item); }, 2000); // 销毁iframe setTimeout(function () { iframe.remove(); }, 4000); }); }