import type { AuthPermissionInfo, Recordable, UserInfo } from '@vben/types'; import type { AuthApi } from '#/api'; import { ref } from 'vue'; import { useRouter } from 'vue-router'; import { LOGIN_PATH } from '@vben/constants'; import { preferences } from '@vben/preferences'; import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; import { ElNotification } from 'element-plus'; import { defineStore } from 'pinia'; import { getAuthPermissionInfoApi, loginApi, logoutApi, register, smsLogin, socialLogin, } from '#/api'; import { $t } from '#/locales'; export const useAuthStore = defineStore('auth', () => { const accessStore = useAccessStore(); const userStore = useUserStore(); const router = useRouter(); const loginLoading = ref(false); /** * 异步处理登录操作 * Asynchronously handle the login process * @param type 登录类型 * @param params 登录表单数据 * @param onSuccess 登录成功后的回调函数 */ async function authLogin( type: 'mobile' | 'register' | 'social' | 'username', params: Recordable, onSuccess?: () => Promise | void, ) { // 异步处理用户登录操作并获取 accessToken let userInfo: null | UserInfo = null; try { loginLoading.value = true; const { accessToken, refreshToken } = type === 'mobile' ? await smsLogin(params as AuthApi.SmsLoginParams) : type === 'register' ? await register(params as AuthApi.RegisterParams) : // eslint-disable-next-line unicorn/no-nested-ternary type === 'social' ? await socialLogin(params as AuthApi.SocialLoginParams) : await loginApi(params); // 如果成功获取到 accessToken if (accessToken) { accessStore.setAccessToken(accessToken); accessStore.setRefreshToken(refreshToken); // 获取用户信息并存储到 userStore、accessStore 中 // TODO @芋艿:清理掉 accessCodes 相关的逻辑 // const [fetchUserInfoResult, accessCodes] = await Promise.all([ // fetchUserInfo(), // // getAccessCodesApi(), // ]); const fetchUserInfoResult = await fetchUserInfo(); userInfo = fetchUserInfoResult.user; if (accessStore.loginExpired) { accessStore.setLoginExpired(false); } else { onSuccess ? await onSuccess?.() : await router.push( userInfo.homePath || preferences.app.defaultHomePath, ); } if (userInfo?.nickname) { ElNotification.success({ message: `${$t('authentication.loginSuccessDesc')}:${userInfo?.nickname}`, duration: 3, title: $t('authentication.loginSuccess'), }); } } } finally { loginLoading.value = false; } return { userInfo, }; } async function logout(redirect: boolean = true) { try { const accessToken = accessStore.accessToken as string; if (accessToken) { await logoutApi(accessToken); } } catch { // 不做任何处理 } resetAllStores(); accessStore.setLoginExpired(false); // 回登录页带上当前路由地址 await router.replace({ path: LOGIN_PATH, query: redirect ? { redirect: encodeURIComponent(router.currentRoute.value.fullPath), } : {}, }); } async function fetchUserInfo() { // 加载 let authPermissionInfo: AuthPermissionInfo | null; authPermissionInfo = await getAuthPermissionInfoApi(); // userStore userStore.setUserInfo(authPermissionInfo.user); userStore.setUserRoles(authPermissionInfo.roles); // accessStore accessStore.setAccessMenus(authPermissionInfo.menus); accessStore.setAccessCodes(authPermissionInfo.permissions); return authPermissionInfo; } function $reset() { loginLoading.value = false; } return { $reset, authLogin, fetchUserInfo, loginLoading, logout, }; });