import type { Recordable, UserInfo } from '@vben/types'; 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 { notification } from 'ant-design-vue'; import { defineStore } from 'pinia'; import { getUserInfoApi, loginApi, logoutApi } 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 params 登录表单数据 */ async function authLogin( params: Recordable, onSuccess?: () => Promise | void, ) { // 异步处理用户登录操作并获取 accessToken let userInfo: null | UserInfo = null; try { loginLoading.value = true; const loginResult = await loginApi(params as { username: string; password: string }); // 登录成功(根据 API.md,code 200 表示成功) // 如果返回数据中有 accessToken,则使用它;否则使用 Session 认证 const accessToken = loginResult?.accessToken || loginResult?.token || 'session'; // 设置 accessToken(Session 认证时可以使用固定值) accessStore.setAccessToken(accessToken); // 获取用户信息并存储到 accessStore 中 try { userInfo = await fetchUserInfo(); if (userInfo) { userStore.setUserInfo(userInfo); } // 设置权限码为空数组(不使用权限码接口) accessStore.setAccessCodes([]); // 重置路由检查状态,让路由守卫重新生成路由 accessStore.setIsAccessChecked(false); if (accessStore.loginExpired) { accessStore.setLoginExpired(false); } else { if (onSuccess) { await onSuccess?.(); } else { // 跳转到首页,让路由守卫处理路由生成和跳转 const homePath = userInfo?.homePath || '/dashboard/analytics'; await router.push(homePath); } } if (userInfo?.realName) { notification.success({ description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`, duration: 3, message: $t('authentication.loginSuccess'), }); } else { notification.success({ description: $t('authentication.loginSuccessDesc'), duration: 3, message: $t('authentication.loginSuccess'), }); } } catch (error) { console.error('获取用户信息失败:', error); // 重置路由检查状态 accessStore.setIsAccessChecked(false); // 即使获取用户信息失败,也允许跳转 await router.push('/dashboard/analytics'); } } catch (error) { console.error('登录失败:', error); throw error; } finally { loginLoading.value = false; } return { userInfo, }; } async function logout(redirect: boolean = true) { try { await logoutApi(); } catch { // 不做任何处理 } resetAllStores(); 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 rawUserInfo = await getUserInfoApi(); // 将后端的 role 字段转换为 roles 数组 if (rawUserInfo) { const role = (rawUserInfo as any).role; if (role) { // 将 role: 'super' 转换为 roles: ['super_admin'] // 将 role: 'branch' 转换为 roles: ['branch'] const roleMap: Record = { super: 'super_admin', branch: 'branch', }; const mappedRole = roleMap[role] || role; userInfo = { ...rawUserInfo, roles: [mappedRole], } as UserInfo; } else { userInfo = rawUserInfo; } } userStore.setUserInfo(userInfo); return userInfo; } function $reset() { loginLoading.value = false; } return { $reset, authLogin, fetchUserInfo, loginLoading, logout, }; });