import type { Recordable, UserInfo } from '@vben/types'; import { ref } from 'vue'; import { useRouter } from 'vue-router'; import { LOGIN_PATH } from '@vben/constants'; import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; import { defineStore } from 'pinia'; import { getAccessCodesApi, loginApi, logoutApi } from '#/api/core/auth'; import { getUserInfoApi } from '#/api/core/user'; import { $t } from '#/locales'; import { normalizeHomePath } from '#/utils/legacy-home'; export const useAuthStore = defineStore('auth', () => { const accessStore = useAccessStore(); const userStore = useUserStore(); const router = useRouter(); const loginLoading = ref(false); /** * 异步处理登录操作 * Asynchronously handle the login process * @param params 登录表单数据 * @param onSuccess */ async function authLogin( params: Recordable, onSuccess?: () => Promise | void, ) { // 异步处理用户登录操作并获取 accessToken let userInfo: null | UserInfo = null; try { loginLoading.value = true; const response = await loginApi(params); // 提取两个 token(支持不同的响应格式) const accessToken = response.accessToken; const refreshToken = response.refreshToken; // 如果成功获取到 accessToken if (accessToken) { // 将 accessToken 存储到 accessStore 中 accessStore.setAccessToken(accessToken); if (refreshToken) { accessStore.setRefreshToken(refreshToken); } // 获取用户信息并存储到 accessStore 中 const [fetchUserInfoResult, accessCodes] = await Promise.all([ fetchUserInfo(), getAccessCodesApi(), ]); userInfo = fetchUserInfoResult; userStore.setUserInfo(userInfo); accessStore.setAccessCodes(accessCodes); if (accessStore.loginExpired) { accessStore.setLoginExpired(false); } else { onSuccess ? await onSuccess?.() : await router.push(normalizeHomePath(userInfo.homePath)); } if (userInfo?.realName) { const { ElNotification } = await import( 'element-plus/es/components/notification/index' ); ElNotification({ message: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`, title: $t('authentication.loginSuccess'), type: 'success', }); } } } finally { loginLoading.value = false; } return { userInfo, }; } async function logout(redirect: boolean = true, callApi: boolean = true) { // 只有在 callApi 为 true 时才调用后端接口 // 当被强制登出(401)时,不需要再调用后端接口 if (callApi) { try { await logoutApi(); } catch { // 不做任何处理 } } try { resetAllStores(); } catch (error) { console.error('Reset stores failed:', error); } accessStore.setLoginExpired(false); // 回登录页带上当前路由地址 await router.replace({ path: LOGIN_PATH, query: redirect ? { redirect: encodeURIComponent(router.currentRoute.value.fullPath), } : {}, }); } async function fetchUserInfo() { let userInfo: null | UserInfo = null; const backendUser = await getUserInfoApi(); userInfo = { ...backendUser, userId: (backendUser as any).id || backendUser.userId, realName: (backendUser as any).name || backendUser.realName || '', avatar: backendUser.avatar || '', roles: (backendUser as any).is_superuser ? ['super'] : ['user'], } as UserInfo; userStore.setUserInfo(userInfo); return userInfo; } function $reset() { loginLoading.value = false; } return { $reset, authLogin, fetchUserInfo, loginLoading, logout, }; });