import { unref, nextTick } from 'vue'; import { defineStore } from 'pinia'; import { REFRESH_TOKEN_COUNT } from '@/config'; import { router } from '@/router'; import type { AdminLoginParams } from '@/service'; import { fetchLogin, fetchUserInfo, fetchStudentLogin } from '@/service'; import { useRouterPush } from '@/composables'; import { localStg } from '@/utils'; import { useTabStore } from '../tab'; import { useRouteStore } from '../route'; import { getToken, getUserInfo, clearAuthStorage } from './helpers'; interface AuthState { /** 用户信息 */ userInfo: Auth.UserInfo; /** 用户token */ token: string; /** 登录的加载状态 */ loginLoading: boolean; } export const useAuthStore = defineStore('auth-store', { state: (): AuthState => ({ userInfo: getUserInfo(), token: getToken() as string, loginLoading: false }), getters: { /** 是否登录 */ isLogin(state) { return Boolean(state.token); } }, actions: { /** 重置auth状态 */ resetAuthStore() { const { toLogin } = useRouterPush(false); const { resetTabStore } = useTabStore(); const { resetRouteStore } = useRouteStore(); const route = unref(router.currentRoute); clearAuthStorage(); REFRESH_TOKEN_COUNT.length = 0; this.$reset(); if (route.meta.requiresAuth) { toLogin(); } nextTick(() => { resetTabStore(); resetRouteStore(); }); }, /** * 处理登录后成功或失败的逻辑 * @param backendToken - 返回的token */ async handleActionAfterLogin(backendToken: ApiAuth.Token) { const route = useRouteStore(); const { toLoginRedirect } = useRouterPush(false); const loginSuccess = await this.loginByToken(backendToken); if (loginSuccess) { await route.initAuthRoute(); // 跳转登录后的地址 toLoginRedirect(); // 登录成功弹出欢迎提示 if (route.isInitAuthRoute) { window.$notification?.success({ title: '登录成功!', content: `欢迎回来,${this.userInfo.username}!`, duration: 3000 }); } return; } // 不成功则重置状态 this.resetAuthStore(); }, /** * 根据token进行登录 * @param backendToken - 返回的token */ async loginByToken(backendToken: ApiAuth.Token) { let successFlag = false; // 先把token存储到缓存中(后面接口的请求头需要token) const { token, refreshToken } = backendToken; localStg.set('token', token); localStg.set('refreshToken', refreshToken); // 获取用户信息 const { data } = await fetchUserInfo(); if (data) { // 成功后把用户信息存储到缓存中 localStg.set('userInfo', data as Auth.UserInfo); // 更新状态 this.userInfo = data as Auth.UserInfo; this.token = token; successFlag = true; } return successFlag; }, async studentLogin(params: AdminLoginParams) { this.loginLoading = true; const { data, status, code } = await fetchStudentLogin(params); if (status && code === 200) { await this.handleActionAfterLogin(data as ApiAuth.Token); return true; } this.loginLoading = false; return false; }, /** * 登录 * @param userName - 用户名 * @param password - 密码 */ async login(params: AdminLoginParams) { this.loginLoading = true; const { code, status, data } = await fetchLogin(params); if (status && code === 200) { await this.handleActionAfterLogin(data as ApiAuth.Token); return true; } this.loginLoading = false; return false; } } });