diff --git a/frontend/src/api/axios.ts b/frontend/src/api/axios.ts index a3d95c25..f4e9bb5d 100644 --- a/frontend/src/api/axios.ts +++ b/frontend/src/api/axios.ts @@ -1,10 +1,13 @@ import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios"; import { ElMessage } from "element-plus"; import router from "../router"; -import { getToken, clearToken } from "../utils/auth"; +import { getToken } from "../utils/auth"; +import { useAuthStore } from "../store/auth"; import type { ApiError } from "../types/api"; import { useStudyStore } from "../store/study"; +let unauthorizedNotified = false; + const instance: AxiosInstance = axios.create({ baseURL: "/", timeout: 15000, @@ -24,6 +27,19 @@ instance.interceptors.response.use( async (error: AxiosError) => { const status = error.response?.status; const data = error.response?.data; + // 401 统一处理:同步清理本地 token,并防止重复弹窗 + const handleUnauthorized = () => { + const auth = useAuthStore(); + auth.logout(); + if (!unauthorizedNotified) { + unauthorizedNotified = true; + ElMessage.error(data?.message || "登录已过期,请重新登录"); + setTimeout(() => { + unauthorizedNotified = false; + }, 1000); + } + router.push("/login"); + }; // 如果当前项目不存在或已失效,清理项目并跳到项目列表 if (status === 404 && typeof data?.message === "string" && data.message.toLowerCase().includes("study")) { try { @@ -35,9 +51,7 @@ instance.interceptors.response.use( router.push("/studies"); } if (status === 401) { - clearToken(); - ElMessage.error(data?.message || "登录已过期,请重新登录"); - router.push("/login"); + handleUnauthorized(); } else if (data?.message) { ElMessage.error(data.message); } else { diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 88c1d8e4..33838cdd 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -242,7 +242,8 @@ router.beforeEach(async (to, _from, next) => { try { await auth.fetchMe(); } catch { - /* ignore */ + // token 失效或用户不可用时立即登出,避免重复 401 + auth.logout(); } } if (!to.meta.public && !token) { diff --git a/pg_data/base/1/pg_internal.init b/pg_data/base/1/pg_internal.init new file mode 100644 index 00000000..2a1bfcbe Binary files /dev/null and b/pg_data/base/1/pg_internal.init differ diff --git a/pg_data/base/16384/2619 b/pg_data/base/16384/2619 index e98cd6db..7dce59c4 100644 Binary files a/pg_data/base/16384/2619 and b/pg_data/base/16384/2619 differ diff --git a/pg_data/base/16384/pg_internal.init b/pg_data/base/16384/pg_internal.init index a910745d..54aaaa7d 100644 Binary files a/pg_data/base/16384/pg_internal.init and b/pg_data/base/16384/pg_internal.init differ diff --git a/pg_data/base/5/pg_internal.init b/pg_data/base/5/pg_internal.init index 4bbb6d04..faaae29a 100644 Binary files a/pg_data/base/5/pg_internal.init and b/pg_data/base/5/pg_internal.init differ diff --git a/pg_data/global/pg_control b/pg_data/global/pg_control index 01f28223..f5130d35 100644 Binary files a/pg_data/global/pg_control and b/pg_data/global/pg_control differ diff --git a/pg_data/global/pg_internal.init b/pg_data/global/pg_internal.init index 1f1235d8..e0bda2e8 100644 Binary files a/pg_data/global/pg_internal.init and b/pg_data/global/pg_internal.init differ diff --git a/pg_data/pg_stat/pgstat.stat b/pg_data/pg_stat/pgstat.stat deleted file mode 100644 index 05bbb61e..00000000 Binary files a/pg_data/pg_stat/pgstat.stat and /dev/null differ diff --git a/pg_data/pg_wal/000000010000000000000001 b/pg_data/pg_wal/000000010000000000000001 index 6463f07e..6dda9242 100644 Binary files a/pg_data/pg_wal/000000010000000000000001 and b/pg_data/pg_wal/000000010000000000000001 differ diff --git a/pg_data/postmaster.pid b/pg_data/postmaster.pid new file mode 100644 index 00000000..d555b0a6 --- /dev/null +++ b/pg_data/postmaster.pid @@ -0,0 +1,8 @@ +1 +/var/lib/postgresql/data +1766032076 +5432 +/var/run/postgresql +* + 52727 0 +ready