From 562601736731afd20bb1a5140d856f6515720159 Mon Sep 17 00:00:00 2001 From: hxr <1490493387@qq.com> Date: Sat, 8 Jun 2024 13:11:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20:bug:=20=E4=BF=AE=E5=A4=8D=E6=B3=A8?= =?UTF-8?q?=E9=94=80=E7=99=BB=E5=87=BA=E5=90=8E`redirect`=E8=B7=B3?= =?UTF-8?q?=E8=BD=AC=E8=B7=AF=E7=94=B1=E5=8F=82=E6=95=B0=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/permission.ts | 19 +++++++++++++++--- src/views/login/index.vue | 41 +++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 20 deletions(-) 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 =