From a5da8d5788154931e76e5097cf7721a592b52222 Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Fri, 15 Aug 2025 09:35:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20:recycle:=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E4=B8=8D=E5=86=8D=E6=9C=AC=E5=9C=B0=E6=8C=81?= =?UTF-8?q?=E4=B9=85=E5=8C=96=EF=BC=8C=E6=94=B9=E4=B8=BA=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=80=81=EF=BC=9A=E5=88=B7=E6=96=B0=E9=A1=B5=E9=9D=A2=E5=90=8E?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E9=87=8D=E6=96=B0=E8=AF=B7=E6=B1=82=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/composables/useOnlineCount.ts | 2 +- src/composables/useStomp.ts | 2 +- src/plugins/websocket.ts | 2 +- src/store/modules/user.store.ts | 17 ++++---- src/utils/auth.ts | 61 ++++++---------------------- src/utils/request.ts | 6 +-- src/views/login/components/Login.vue | 4 +- 8 files changed, 31 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index 43f5dc8e..2da53666 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vue3-element-admin", "description": "Vue3 + Vite + TypeScript + Element-Plus 的后台管理模板,vue-element-admin 的 Vue3 版本", - "version": "3.2.0", + "version": "3.2.2", "private": true, "type": "module", "scripts": { diff --git a/src/composables/useOnlineCount.ts b/src/composables/useOnlineCount.ts index 906278c6..504f98cc 100644 --- a/src/composables/useOnlineCount.ts +++ b/src/composables/useOnlineCount.ts @@ -1,7 +1,7 @@ import { ref, onMounted, onUnmounted, watch, getCurrentInstance } from "vue"; import { useStomp } from "./useStomp"; import { registerWebSocketInstance } from "@/plugins/websocket"; -import { Auth } from "@/utils/auth"; +import { AuthStorage } from "@/utils/auth"; // 全局单例实例 let globalInstance: ReturnType | null = null; diff --git a/src/composables/useStomp.ts b/src/composables/useStomp.ts index c1c0b390..b0dbe313 100644 --- a/src/composables/useStomp.ts +++ b/src/composables/useStomp.ts @@ -1,5 +1,5 @@ import { Client, type IMessage, type StompSubscription } from "@stomp/stompjs"; -import { Auth } from "@/utils/auth"; +import { AuthStorage } from "@/utils/auth"; export interface UseStompOptions { /** WebSocket 地址,不传时使用 VITE_APP_WS_ENDPOINT 环境变量 */ diff --git a/src/plugins/websocket.ts b/src/plugins/websocket.ts index 692d457a..a7224ac2 100644 --- a/src/plugins/websocket.ts +++ b/src/plugins/websocket.ts @@ -1,5 +1,5 @@ import { useDictSync } from "@/composables/useDictSync"; -import { Auth } from "@/utils/auth"; +import { AuthStorage } from "@/utils/auth"; // 不直接导入 store 或 userStore // 全局 WebSocket 实例管理 diff --git a/src/store/modules/user.store.ts b/src/store/modules/user.store.ts index 7d714b8d..0a40fddc 100644 --- a/src/store/modules/user.store.ts +++ b/src/store/modules/user.store.ts @@ -3,16 +3,17 @@ import { store } from "@/store"; import AuthAPI, { type LoginFormData } from "@/api/auth.api"; import UserAPI, { type UserInfo } from "@/api/system/user.api"; -import { Auth } from "@/utils/auth"; +import { AuthStorage } from "@/utils/auth"; import { usePermissionStoreHook } from "@/store/modules/permission.store"; import { useDictStoreHook } from "@/store/modules/dict.store"; import { useTagsViewStore } from "@/store"; import { cleanupWebSocket } from "@/plugins/websocket"; export const useUserStore = defineStore("user", () => { - const userInfo = useStorage("userInfo", {} as UserInfo); + // 用户信息 + const userInfo = ref({} as UserInfo); // 记住我状态 - const rememberMe = ref(Auth.getRememberMe()); + const rememberMe = ref(AuthStorage.getRememberMe()); /** * 登录 @@ -27,7 +28,7 @@ export const useUserStore = defineStore("user", () => { const { accessToken, refreshToken } = data; // 保存记住我状态和token rememberMe.value = LoginFormData.rememberMe; - Auth.setTokens(accessToken, refreshToken, rememberMe.value); + AuthStorage.setTokens(accessToken, refreshToken, rememberMe.value); resolve(); }) .catch((error) => { @@ -104,7 +105,7 @@ export const useUserStore = defineStore("user", () => { */ function resetUserState() { // 清除用户凭证 - Auth.clearAuth(); + AuthStorage.clearAuth(); // 重置用户信息 userInfo.value = {} as UserInfo; } @@ -113,7 +114,7 @@ export const useUserStore = defineStore("user", () => { * 刷新 token */ function refreshToken() { - const refreshToken = Auth.getRefreshToken(); + const refreshToken = AuthStorage.getRefreshToken(); if (!refreshToken) { return Promise.reject(new Error("没有有效的刷新令牌")); @@ -124,7 +125,7 @@ export const useUserStore = defineStore("user", () => { .then((data) => { const { accessToken, refreshToken: newRefreshToken } = data; // 更新令牌,保持当前记住我状态 - Auth.setTokens(accessToken, newRefreshToken, Auth.getRememberMe()); + AuthStorage.setTokens(accessToken, newRefreshToken, AuthStorage.getRememberMe()); resolve(); }) .catch((error) => { @@ -137,7 +138,7 @@ export const useUserStore = defineStore("user", () => { return { userInfo, rememberMe, - isLoggedIn: () => !!Auth.getAccessToken(), + isLoggedIn: () => !!AuthStorage.getAccessToken(), getUserInfo, login, logout, diff --git a/src/utils/auth.ts b/src/utils/auth.ts index ff354916..c3f67531 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -1,78 +1,43 @@ import { Storage } from "./storage"; import { AUTH_KEYS } from "@/constants"; -/** - * 身份验证工具类 - * 集中管理所有与认证相关的功能,包括: - * - 登录状态判断 - * - Token 的存取 - * - 记住我功能的状态管理 - */ -export class Auth { - /** - * 获取当前有效的访问令牌 - * 会根据"记住我"状态从适当的存储位置获取 - * @returns 当前有效的访问令牌 - */ - static getAccessToken(): string { +// 更语义化的命名:仅负责本地凭证与偏好的读写 +export const AuthStorage = { + getAccessToken(): string { const isRememberMe = Storage.get(AUTH_KEYS.REMEMBER_ME, false); - // 根据"记住我"状态决定从哪个存储位置获取token return isRememberMe ? Storage.get(AUTH_KEYS.ACCESS_TOKEN, "") : Storage.sessionGet(AUTH_KEYS.ACCESS_TOKEN, ""); - } + }, - /** - * 获取刷新令牌 - * @returns 当前有效的刷新令牌 - */ - static getRefreshToken(): string { + getRefreshToken(): string { const isRememberMe = Storage.get(AUTH_KEYS.REMEMBER_ME, false); return isRememberMe ? Storage.get(AUTH_KEYS.REFRESH_TOKEN, "") : Storage.sessionGet(AUTH_KEYS.REFRESH_TOKEN, ""); - } + }, - /** - * 设置访问令牌和刷新令牌 - * @param accessToken 访问令牌 - * @param refreshToken 刷新令牌 - * @param rememberMe 是否记住我 - */ - static setTokens(accessToken: string, refreshToken: string, rememberMe: boolean): void { - // 保存"记住我"状态 + setTokens(accessToken: string, refreshToken: string, rememberMe: boolean): void { Storage.set(AUTH_KEYS.REMEMBER_ME, rememberMe); - if (rememberMe) { - // 使用localStorage长期保存 Storage.set(AUTH_KEYS.ACCESS_TOKEN, accessToken); Storage.set(AUTH_KEYS.REFRESH_TOKEN, refreshToken); } else { - // 使用sessionStorage临时保存 Storage.sessionSet(AUTH_KEYS.ACCESS_TOKEN, accessToken); Storage.sessionSet(AUTH_KEYS.REFRESH_TOKEN, refreshToken); - // 清除localStorage中可能存在的token Storage.remove(AUTH_KEYS.ACCESS_TOKEN); Storage.remove(AUTH_KEYS.REFRESH_TOKEN); } - } + }, - /** - * 清除所有身份验证相关的数据 - */ - static clearAuth(): void { + clearAuth(): void { Storage.remove(AUTH_KEYS.ACCESS_TOKEN); Storage.remove(AUTH_KEYS.REFRESH_TOKEN); Storage.sessionRemove(AUTH_KEYS.ACCESS_TOKEN); Storage.sessionRemove(AUTH_KEYS.REFRESH_TOKEN); - // 不清除记住我设置,保留用户偏好 - } + }, - /** - * 获取"记住我"状态 - * @returns 是否记住我 - */ - static getRememberMe(): boolean { + getRememberMe(): boolean { return Storage.get(AUTH_KEYS.REMEMBER_ME, false); - } -} + }, +}; diff --git a/src/utils/request.ts b/src/utils/request.ts index 4baf361f..9af2061e 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -2,7 +2,7 @@ import axios, { type InternalAxiosRequestConfig, type AxiosResponse } from "axio import qs from "qs"; import { useUserStoreHook } from "@/store/modules/user.store"; import { ResultEnum } from "@/enums/api/result.enum"; -import { Auth } from "@/utils/auth"; +import { AuthStorage } from "@/utils/auth"; import router from "@/router"; /** @@ -20,7 +20,7 @@ const httpRequest = axios.create({ */ httpRequest.interceptors.request.use( (config: InternalAxiosRequestConfig) => { - const accessToken = Auth.getAccessToken(); + const accessToken = AuthStorage.getAccessToken(); // 如果 Authorization 设置为 no-auth,则不携带 Token if (config.headers.Authorization !== "no-auth" && accessToken) { @@ -104,7 +104,7 @@ async function refreshTokenAndRetry(config: InternalAxiosRequestConfig): Promise return new Promise((resolve, reject) => { // 封装需要重试的请求 const retryRequest = () => { - const newToken = Auth.getAccessToken(); + const newToken = AuthStorage.getAccessToken(); if (newToken && config.headers) { config.headers.Authorization = `Bearer ${newToken}`; } diff --git a/src/views/login/components/Login.vue b/src/views/login/components/Login.vue index 5c1b54d4..fa125c1c 100644 --- a/src/views/login/components/Login.vue +++ b/src/views/login/components/Login.vue @@ -115,7 +115,7 @@ import AuthAPI, { type LoginFormData } from "@/api/auth.api"; import router from "@/router"; import { useUserStore } from "@/store"; import CommonWrapper from "@/components/CommonWrapper/index.vue"; -import { Auth } from "@/utils/auth"; +import { AuthStorage } from "@/utils/auth"; const { t } = useI18n(); const userStore = useUserStore(); @@ -130,7 +130,7 @@ const isCapsLock = ref(false); // 验证码图片Base64字符串 const captchaBase64 = ref(); // 记住我 -const rememberMe = Auth.getRememberMe(); +const rememberMe = AuthStorage.getRememberMe(); const loginFormData = ref({ username: "admin",