diff --git a/package.json b/package.json index db9bcf8..a2dfccf 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "fuse.js": "6.6.2", "js-cookie": "3.0.1", "jsencrypt": "3.3.1", + "lodash-es": "^4.17.21", "nprogress": "0.2.0", "pinia": "2.0.22", "pinia-plugin-persistedstate": "^3.1.0", diff --git a/src/api/login.js b/src/api/login.js index c49a5fa..429763b 100644 --- a/src/api/login.js +++ b/src/api/login.js @@ -1,4 +1,6 @@ import request from '@/utils/request' +import usePermissionStore from "@/store/modules/permission"; +import useUserStore from "@/store/modules/user"; // 登录方法 export function login(username, password, code, uuid) { @@ -32,6 +34,11 @@ export function register(data) { // 获取用户详细信息 export function getInfo() { + if (useUserStore().userInfoRes) { + return new Promise((resolve, reject) => { + resolve(useUserStore().userInfoRes) + }) + } return request({ url: '/getInfo', method: 'get' @@ -60,6 +67,11 @@ export function getCodeImg() { // 获取路由 export const getRouters = () => { + if (usePermissionStore().routesRes) { + return new Promise((resolve, reject) => { + resolve(usePermissionStore().routesRes) + }) + } return request({ url: '/getRouters', method: 'get' diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 62469cb..0b04e1f 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -1,138 +1,150 @@ import auth from '@/plugins/auth' -import router, { constantRoutes, dynamicRoutes } from '@/router' +import router, {constantRoutes, dynamicRoutes} from '@/router' import Layout from '@/layout/index' import ParentView from '@/components/ParentView' import InnerLink from '@/layout/components/InnerLink' import {getRouters} from "@/api/login"; +import {cloneDeep} from 'lodash-es' // 匹配views里面所有的.vue文件 const modules = import.meta.glob('./../../views/**/*.vue') const usePermissionStore = defineStore( - 'permission', - { - state: () => ({ - routes: [], - addRoutes: [], - defaultRoutes: [], - topbarRouters: [], - sidebarRouters: [] - }), - actions: { - setRoutes(routes) { - this.addRoutes = routes - this.routes = constantRoutes.concat(routes) - }, - setDefaultRoutes(routes) { - this.defaultRoutes = constantRoutes.concat(routes) - }, - setTopbarRoutes(routes) { - this.topbarRouters = routes - }, - setSidebarRouters(routes) { - this.sidebarRouters = routes - }, - generateRoutes(roles) { - return new Promise(resolve => { - // 向后端请求路由数据 - getRouters().then(res => { - const sdata = JSON.parse(JSON.stringify(res.data)) - const rdata = JSON.parse(JSON.stringify(res.data)) - const defaultData = JSON.parse(JSON.stringify(res.data)) - const sidebarRoutes = filterAsyncRouter(sdata) - const rewriteRoutes = filterAsyncRouter(rdata, false, true) - const defaultRoutes = filterAsyncRouter(defaultData) - const asyncRoutes = filterDynamicRoutes(dynamicRoutes) - asyncRoutes.forEach(route => { router.addRoute(route) }) - this.setRoutes(rewriteRoutes) - this.setSidebarRouters(constantRoutes.concat(sidebarRoutes)) - this.setDefaultRoutes(sidebarRoutes) - this.setTopbarRoutes(defaultRoutes) - resolve(rewriteRoutes) - }) - }) - } - } - }) + 'permission', + { + state: () => ({ + routesRes: null, + routes: [], + addRoutes: [], + defaultRoutes: [], + topbarRouters: [], + sidebarRouters: [] + }), + actions: { + setRoutesRes(res) { + this.routesRes = cloneDeep(res) + }, + setRoutes(routes) { + this.addRoutes = routes + this.routes = constantRoutes.concat(routes) + }, + setDefaultRoutes(routes) { + this.defaultRoutes = constantRoutes.concat(routes) + }, + setTopbarRoutes(routes) { + this.topbarRouters = routes + }, + setSidebarRouters(routes) { + this.sidebarRouters = routes + }, + generateRoutes(roles) { + return new Promise(resolve => { + // 向后端请求路由数据 + getRouters().then(res => { + if (!this.routesRes) { + this.setRoutesRes(res) + } + const sdata = JSON.parse(JSON.stringify(res.data)) + const rdata = JSON.parse(JSON.stringify(res.data)) + const defaultData = JSON.parse(JSON.stringify(res.data)) + const sidebarRoutes = filterAsyncRouter(sdata) + const rewriteRoutes = filterAsyncRouter(rdata, false, true) + const defaultRoutes = filterAsyncRouter(defaultData) + const asyncRoutes = filterDynamicRoutes(dynamicRoutes) + asyncRoutes.forEach(route => { + router.addRoute(route) + }) + this.setRoutes(rewriteRoutes) + this.setSidebarRouters(constantRoutes.concat(sidebarRoutes)) + this.setDefaultRoutes(sidebarRoutes) + this.setTopbarRoutes(defaultRoutes) + resolve(rewriteRoutes) + }) + }) + } + }, persist: [ + {paths: ['routesRes'], storage: localStorage} + ] + }) // 遍历后台传来的路由字符串,转换为组件对象 function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { - return asyncRouterMap.filter(route => { - if (type && route.children) { - route.children = filterChildren(route.children) - } - if (route.component) { - // Layout ParentView 组件特殊处理 - if (route.component === 'Layout') { - route.component = Layout - } else if (route.component === 'ParentView') { - route.component = ParentView - } else if (route.component === 'InnerLink') { - route.component = InnerLink - } else { - route.component = loadView(route.component) - } - } - if (route.children != null && route.children && route.children.length) { - route.children = filterAsyncRouter(route.children, route, type) - } else { - delete route['children'] - delete route['redirect'] - } - return true - }) + return asyncRouterMap.filter(route => { + if (type && route.children) { + route.children = filterChildren(route.children) + } + if (route.component) { + // Layout ParentView 组件特殊处理 + if (route.component === 'Layout') { + route.component = Layout + } else if (route.component === 'ParentView') { + route.component = ParentView + } else if (route.component === 'InnerLink') { + route.component = InnerLink + } else { + route.component = loadView(route.component) + } + } + if (route.children != null && route.children && route.children.length) { + route.children = filterAsyncRouter(route.children, route, type) + } else { + delete route['children'] + delete route['redirect'] + } + return true + }) } function filterChildren(childrenMap, lastRouter = false) { - var children = [] - childrenMap.forEach((el, index) => { - if (el.children && el.children.length) { - if (el.component === 'ParentView' && !lastRouter) { - el.children.forEach(c => { - c.path = el.path + '/' + c.path - if (c.children && c.children.length) { - children = children.concat(filterChildren(c.children, c)) - return - } - children.push(c) - }) - return - } - } - if (lastRouter) { - el.path = lastRouter.path + '/' + el.path - } - children = children.concat(el) - }) - return children + var children = [] + childrenMap.forEach((el, index) => { + if (el.children && el.children.length) { + if (el.component === 'ParentView' && !lastRouter) { + el.children.forEach(c => { + c.path = el.path + '/' + c.path + if (c.children && c.children.length) { + children = children.concat(filterChildren(c.children, c)) + return + } + children.push(c) + }) + return + } + } + if (lastRouter) { + el.path = lastRouter.path + '/' + el.path + } + children = children.concat(el) + }) + return children } // 动态路由遍历,验证是否具备权限 export function filterDynamicRoutes(routes) { - const res = [] - routes.forEach(route => { - if (route.permissions) { - if (auth.hasPermiOr(route.permissions)) { - res.push(route) - } - } else if (route.roles) { - if (auth.hasRoleOr(route.roles)) { - res.push(route) - } - } - }) - return res + const res = [] + routes.forEach(route => { + if (route.permissions) { + if (auth.hasPermiOr(route.permissions)) { + res.push(route) + } + } else if (route.roles) { + if (auth.hasRoleOr(route.roles)) { + res.push(route) + } + } + }) + return res } export const loadView = (view) => { - let res; - for (const path in modules) { - const dir = path.split('views/')[1].split('.vue')[0]; - if (dir === view) { - res = () => modules[path](); + let res; + for (const path in modules) { + const dir = path.split('views/')[1].split('.vue')[0]; + if (dir === view) { + res = () => modules[path](); + } } - } - return res; + return res; } export default usePermissionStore diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 7c8f485..3bba168 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -1,6 +1,7 @@ import {getInfo, login, logout} from '@/api/login' import {getToken, removeToken, setToken} from '@/utils/auth' import defAva from '@/assets/images/profile.jpg' +import {cloneDeep} from "lodash-es"; const useUserStore = defineStore( 'user', @@ -11,9 +12,13 @@ const useUserStore = defineStore( avatar: '', roles: [], tenant: '', - permissions: [] + permissions: [], + userInfoRes: null }), actions: { + setUserInfoRes(res) { + this.userInfoRes = cloneDeep(res) + }, // 登录 login(userInfo) { const username = userInfo.username.trim() @@ -36,6 +41,9 @@ const useUserStore = defineStore( getInfo() { return new Promise((resolve, reject) => { getInfo().then(res => { + if (!this.userInfoRes) { + this.setUserInfoRes(res) + } const user = res.user const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar; @@ -60,6 +68,7 @@ const useUserStore = defineStore( this.token = '' this.roles = [] this.permissions = [] + this.userInfoRes = null removeToken() resolve() }).catch(error => { @@ -69,7 +78,7 @@ const useUserStore = defineStore( } }, persist: [ - {paths: ['tenant'],storage:localStorage} + {paths: ['tenant', 'userInfoRes'], storage: localStorage} ] }, )