diff --git a/src/router/permission.ts b/src/router/permission.ts index 880dc0a..fc6205c 100644 --- a/src/router/permission.ts +++ b/src/router/permission.ts @@ -22,19 +22,13 @@ router.beforeEach(async (to, _from, next) => { // 判断该用户是否已经登录 if (!token) { // 如果在免登录的白名单中,则直接进入 - if (isWhiteList(to)) { - next() - } else { - // 其他没有访问权限的页面将被重定向到登录页面 - NProgress.done() - next("/login") - } - return + if (isWhiteList(to)) return next() + // 其他没有访问权限的页面将被重定向到登录页面 + return next("/login") } // 如果已经登录,并准备进入 Login 页面,则重定向到主页 if (to.path === "/login") { - NProgress.done() return next({ path: "/" }) } @@ -44,16 +38,11 @@ router.beforeEach(async (to, _from, next) => { // 否则要重新获取权限角色 try { await userStore.getInfo() - if (routeSettings.async) { - // 注意:角色必须是一个数组! 例如: ['admin'] 或 ['developer', 'editor'] - const roles = userStore.roles - // 根据角色生成可访问的 Routes(可访问路由 = 常驻路由 + 有访问权限的动态路由) - permissionStore.setRoutes(roles) - } else { - // 没有开启动态路由功能,则启用默认角色来生成 - permissionStore.setRoutes(routeSettings.defaultRoles) - } - // 将'有访问权限的动态路由' 添加到 Router 中 + // 注意:角色必须是一个数组! 例如: ["admin"] 或 ["developer", "editor"] + const roles = userStore.roles + // 生成可访问的 Routes + routeSettings.async ? permissionStore.setRoutes(roles) : permissionStore.setAllRoutes() + // 将 "有访问权限的动态路由" 添加到 Router 中 permissionStore.dynamicRoutes.forEach((route) => router.addRoute(route)) // 确保添加路由已完成 // 设置 replace: true, 因此导航将不会留下历史记录 @@ -62,7 +51,6 @@ router.beforeEach(async (to, _from, next) => { // 过程中发生任何错误,都直接重置 Token,并重定向到登录页面 userStore.resetToken() ElMessage.error(err.message || "路由守卫过程发生错误") - NProgress.done() next("/login") } }) diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index a7c364e..4af385a 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -29,13 +29,23 @@ export const usePermissionStore = defineStore("permission", () => { const routes = ref([]) const dynamicRoutes = ref([]) + /** 根据角色生成可访问的 Routes(可访问路由 = 常驻路由 + 有访问权限的动态路由) */ const setRoutes = (roles: string[]) => { - const accessedRoutes = routeSettings.async ? filterAsyncRoutes(asyncRoutes, roles) : asyncRoutes + const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) + _set(accessedRoutes) + } + + /** 所有路由 = 所有常驻路由 + 所有动态路由 */ + const setAllRoutes = () => { + _set(asyncRoutes) + } + + const _set = (accessedRoutes: RouteRecordRaw[]) => { routes.value = constantRoutes.concat(accessedRoutes) dynamicRoutes.value = routeSettings.thirdLevelRouteCache ? flatMultiLevelRoutes(accessedRoutes) : accessedRoutes } - return { routes, dynamicRoutes, setRoutes } + return { routes, dynamicRoutes, setRoutes, setAllRoutes } }) /** 在 setup 外使用 */ diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 231a303..90cfe12 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -1,14 +1,12 @@ import { ref } from "vue" import store from "@/store" import { defineStore } from "pinia" -import { usePermissionStore } from "./permission" import { useTagsViewStore } from "./tags-view" import { useSettingsStore } from "./settings" import { getToken, removeToken, setToken } from "@/utils/cache/cookies" -import router, { resetRouter } from "@/router" +import { resetRouter } from "@/router" import { loginApi, getUserInfoApi } from "@/api/login" import { type LoginRequestData } from "@/api/login/types/login" -import { type RouteRecordRaw } from "vue-router" import routeSettings from "@/config/route" export const useUserStore = defineStore("user", () => { @@ -16,7 +14,6 @@ export const useUserStore = defineStore("user", () => { const roles = ref([]) const username = ref("") - const permissionStore = usePermissionStore() const tagsViewStore = useTagsViewStore() const settingsStore = useSettingsStore() @@ -33,18 +30,13 @@ export const useUserStore = defineStore("user", () => { // 验证返回的 roles 是否为一个非空数组,否则塞入一个没有任何作用的默认角色,防止路由守卫逻辑进入无限循环 roles.value = data.roles?.length > 0 ? data.roles : routeSettings.defaultRoles } - /** 切换角色 */ + /** 模拟角色变化 */ const changeRoles = async (role: string) => { const newToken = "token-" + role token.value = newToken setToken(newToken) - await getInfo() - permissionStore.setRoutes(roles.value) - resetRouter() - permissionStore.dynamicRoutes.forEach((item: RouteRecordRaw) => { - router.addRoute(item) - }) - _resetTagsView() + // 用刷新页面代替重新登陆 + window.location.reload() } /** 登出 */ const logout = () => { diff --git a/src/views/permission/components/SwitchRoles.vue b/src/views/permission/components/SwitchRoles.vue index ef8ba9d..7f25d00 100644 --- a/src/views/permission/components/SwitchRoles.vue +++ b/src/views/permission/components/SwitchRoles.vue @@ -2,16 +2,10 @@ import { ref, watch } from "vue" import { useUserStore } from "@/store/modules/user" -/** Vue 3.3+ defineEmits 语法 */ -const emit = defineEmits<{ - change: [] -}>() - const userStore = useUserStore() const switchRoles = ref(userStore.roles[0]) -watch(switchRoles, async (value) => { - await userStore.changeRoles(value) - emit("change") +watch(switchRoles, (value) => { + userStore.changeRoles(value) }) @@ -19,7 +13,7 @@ watch(switchRoles, async (value) => {
你的权限:{{ userStore.roles }}
- 切换权限: + 切换权限(模拟权限变化后重新登陆): diff --git a/src/views/permission/directive.vue b/src/views/permission/directive.vue index 2e4b204..1de6bf8 100644 --- a/src/views/permission/directive.vue +++ b/src/views/permission/directive.vue @@ -1,20 +1,13 @@