feat: 实现记住我功能并重构认证逻辑为统一的Auth工具类

This commit is contained in:
Ray.Hao
2025-05-21 17:40:14 +08:00
parent aee9443fe0
commit 521ba98d6a
11 changed files with 194 additions and 73 deletions

View File

@@ -1,15 +1,17 @@
import { store } from "@/store";
import { usePermissionStoreHook } from "@/store/modules/permission.store";
import { useDictStoreHook } from "@/store/modules/dict.store";
import AuthAPI, { type LoginFormData } from "@/api/auth.api";
import UserAPI, { type UserInfo } from "@/api/system/user.api";
import { Storage } from "@/utils/storage";
import { ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY } from "@/constants/cache-keys";
import { Auth } from "@/utils/auth";
import { usePermissionStoreHook } from "@/store/modules/permission.store";
import { useDictStoreHook } from "@/store/modules/dict.store";
import { useTagsViewStore } from "@/store";
export const useUserStore = defineStore("user", () => {
const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
// 记住我状态
const rememberMe = ref(Auth.getRememberMe());
/**
* 登录
@@ -22,8 +24,9 @@ export const useUserStore = defineStore("user", () => {
AuthAPI.login(LoginFormData)
.then((data) => {
const { accessToken, refreshToken } = data;
Storage.set(ACCESS_TOKEN_KEY, accessToken);
Storage.set(REFRESH_TOKEN_KEY, refreshToken);
// 保存记住我状态和token
rememberMe.value = LoginFormData.rememberMe;
Auth.setTokens(accessToken, refreshToken, rememberMe.value);
resolve();
})
.catch((error) => {
@@ -61,7 +64,8 @@ export const useUserStore = defineStore("user", () => {
return new Promise<void>((resolve, reject) => {
AuthAPI.logout()
.then(() => {
clearSessionAndCache();
// 重置所有系统状态
resetAllState();
resolve();
})
.catch((error) => {
@@ -70,17 +74,49 @@ export const useUserStore = defineStore("user", () => {
});
}
/**
* 重置所有系统状态
* 统一处理所有清理工作,包括用户凭证、路由、缓存等
*/
function resetAllState() {
// 1. 重置用户状态
resetUserState();
// 2. 重置其他模块状态
// 重置路由
usePermissionStoreHook().resetRouter();
// 清除字典缓存
useDictStoreHook().clearDictCache();
// 清除标签视图
useTagsViewStore().delAllViews();
return Promise.resolve();
}
/**
* 重置用户状态
* 仅处理用户模块内的状态
*/
function resetUserState() {
// 清除用户凭证
Auth.clearAuth();
// 重置用户信息
userInfo.value = {} as UserInfo;
}
/**
* 刷新 token
*/
function refreshToken() {
const refreshToken = Storage.get(REFRESH_TOKEN_KEY, "");
// 获取刷新令牌
const refreshToken = Auth.getRefreshToken();
return new Promise<void>((resolve, reject) => {
AuthAPI.refreshToken(refreshToken)
.then((data) => {
const { accessToken, refreshToken } = data;
Storage.set(ACCESS_TOKEN_KEY, accessToken);
Storage.set(REFRESH_TOKEN_KEY, refreshToken);
const { accessToken, refreshToken: newRefreshToken } = data;
// 更新令牌,保持当前记住我状态
Auth.setTokens(accessToken, newRefreshToken, Auth.getRememberMe());
resolve();
})
.catch((error) => {
@@ -90,34 +126,21 @@ export const useUserStore = defineStore("user", () => {
});
}
/**
* 清除用户会话和缓存
*/
function clearSessionAndCache() {
return new Promise<void>((resolve) => {
useDictStoreHook().clearDictCache();
usePermissionStoreHook().resetRouter();
Storage.remove(ACCESS_TOKEN_KEY);
Storage.remove(REFRESH_TOKEN_KEY);
userInfo.value = {} as UserInfo;
resolve();
});
}
return {
userInfo,
rememberMe,
getUserInfo,
login,
logout,
clearSessionAndCache,
resetAllState,
resetUserState,
refreshToken,
};
});
/**
* 用于在组件外部如在Pinia Store 中)使用 Pinia 提供的 store 实例。
* 官方文档解释了如何在组件外部使用 Pinia Store
* https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component
* 在组件外部使用UserStore的钩子函数
* @see https://pinia.vuejs.org/core-concepts/outside-component-usage.html
*/
export function useUserStoreHook() {
return useUserStore(store);