diff --git a/src/plugins/permission.ts b/src/plugins/permission.ts index b6da9120..e3bc46ff 100644 --- a/src/plugins/permission.ts +++ b/src/plugins/permission.ts @@ -46,17 +46,30 @@ export function setupPermission() { } catch (error) { // 移除 token 并跳转登录页 await userStore.resetToken(); - next(`/login?redirect=${to.path}`); + // 重定向到登录页,并携带当前页面路由和参数,作为登录成功后跳转的页面 + const params = new URLSearchParams( + to.query as Record + ); + const queryString = params.toString(); + const redirect = queryString + ? `${to.path}?${queryString}` + : to.path; + next(`/login?redirect=${encodeURIComponent(redirect)}`); NProgress.done(); } } } } else { - // 未登录可以访问白名单页面 + // 未登录 if (whiteList.indexOf(to.path) !== -1) { + // 在白名单,直接进入 next(); } else { - next(`/login?redirect=${to.path}`); + // 不在白名单,重定向到登录页 + const params = new URLSearchParams(to.query as Record); + const queryString = params.toString(); + const redirect = queryString ? `${to.path}?${queryString}` : to.path; + next(`/login?redirect=${encodeURIComponent(redirect)}`); NProgress.done(); } } diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 2d76082c..34952d2b 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -118,14 +118,14 @@ import { useSettingsStore, useUserStore } from "@/store"; import AuthAPI from "@/api/auth"; import { LoginData } from "@/api/auth/model"; import type { FormInstance } from "element-plus"; -import { LocationQuery, LocationQueryValue, useRoute } from "vue-router"; +import { LocationQuery, useRoute } from "vue-router"; import router from "@/router"; import defaultSettings from "@/settings"; import { ThemeEnum } from "@/enums/ThemeEnum"; -// Stores const userStore = useUserStore(); const settingsStore = useSettingsStore(); +const route = useRoute(); // Internationalization const { t } = useI18n(); @@ -183,8 +183,7 @@ function getCaptcha() { }); } -/** 登录 */ -const route = useRoute(); +// 登录 function handleLogin() { loginFormRef.value?.validate((valid: boolean) => { if (valid) { @@ -192,19 +191,8 @@ function handleLogin() { userStore .login(loginData.value) .then(() => { - const query: LocationQuery = route.query; - const redirect = (query.redirect as LocationQueryValue) ?? "/"; - const otherQueryParams = Object.keys(query).reduce( - (acc: any, cur: string) => { - if (cur !== "redirect") { - acc[cur] = query[cur]; - } - return acc; - }, - {} - ); - - router.push({ path: redirect, query: otherQueryParams }); + const { path, queryParams } = parseRedirect(); + router.push({ path: path, query: queryParams }); }) .catch(() => { getCaptcha(); @@ -216,6 +204,25 @@ function handleLogin() { }); } +// 解析 redirect 字符串 为 path 和 queryParams +function parseRedirect(): { + path: string; + queryParams: Record; +} { + const query: LocationQuery = route.query; + const redirect = (query.redirect as string) ?? "/"; + + const url = new URL(redirect, window.location.origin); + const path = url.pathname; + const queryParams: Record = {}; + + url.searchParams.forEach((value, key) => { + queryParams[key] = value; + }); + + return { path, queryParams }; +} + /** 主题切换 */ const toggleTheme = () => { const newTheme =