当前位置: 首页> 科技> 名企 > 福建建筑人才市场官网_今朝装饰口碑怎么样_谷歌香港google搜索引擎入口_seo综合

福建建筑人才市场官网_今朝装饰口碑怎么样_谷歌香港google搜索引擎入口_seo综合

时间:2025/7/14 13:17:50来源:https://blog.csdn.net/weixin_67448099/article/details/145918567 浏览次数:0次
福建建筑人才市场官网_今朝装饰口碑怎么样_谷歌香港google搜索引擎入口_seo综合

什么是菜单路由权限

不同角色的员工进入到系统中看到的左侧菜单是不一样的,根据不同的员工登录控制显示与之对应的左侧菜单就叫做菜单路由权限控制,需要实现2个方面的功能:

  1. 动态添加路由:没有权限的菜单,要防止直接从浏览器地址栏输入url来访问到页面
  2. 渲染左侧菜单:没有权限的菜单,要从左侧菜单列表中隐藏

基于RBAC的权限解决方案

RBAC,全称为Role-Based Access Control,即基于角色的访问控制,是一种广泛应用的安全管理模式
核心思路:给角色分配功能权限,把角色分配给员工,那员工就自动拥有了角色下面的所有功能权限

说明:我们新增了一个前端讲师的角色,给这个角色分配了很多功能权限点,然后在新增员工的时候把前端讲师的角色绑定给了xx老师这个员工,那xx老师这个员工就有了前端讲师下的所有功能权限点

权限控制流程梳理

获取用户权限数据

权限数据也属于当前用户相关的信息,使用Vuex进行维护

封装接口

/*** @description: 获取用户信息* @param {*} data {}* @return {*} promise*/
export function getProfileAPI() {return request({url: '/park/user/profile',method: 'GET'})
}

Vuex逻辑编写

import { getProfileAPI } from '@/apis/user'
export default {namespaced: true,state: () => {return {profile: {}}},mutations: {setProfile(state, profile) {state.profile = profile}},actions: {async getProfile(ctx) {const res = await getProfileAPI()ctx.commit('setProfile', res.data)// return后,可以直接在  const perms = await store.dispatch('user/getUserProfile')// 时接收到返回的数据return res.data.permissions }}
}

路由守卫触发action


import router from '@/router/index.js'
import store from '@/store'// 路由守卫
router.beforeEach(async (to, from, next) => {// 登录页面直接放行if (to.path === '/login') {next()} else {const token = store.state.user.token// 判断是否有tokenif (token) {// 放行next()// 获取权限列表if (!store.state.user.profile.id) {const permissions = await store.dispatch('user/getProfile')console.log('权限列表', permissions);}} else {// 跳转回登录页next('/login')}}
})

处理一级和二级菜单标识


import router from '@/router/index.js'
import store from '@/store'// 处理一级路由权限数据
function getFirstRoutePerms(permsArr) {const newArr = permsArr.map(item => {return item.split(':')[0]})return [...new Set(newArr)]
}// 处理二级路由权限数据
function getSecondRoutePerms(permsArr) {const newArr = permsArr.map(item => {const arr = item.split(':')return `${arr[0]}:${arr[1]}`})return [...new Set(newArr)]
}// 路由守卫
router.beforeEach(async (to, from, next) => {// 登录页面直接放行if (to.path === '/login') {next()} else {const token = store.state.user.token// 判断是否有tokenif (token) {// 放行next()// 获取权限列表if (!store.state.user.profile.id) {const permissions = await store.dispatch('user/getProfile')console.log('权限列表', permissions);// 处理一级和二级菜单标识const firstRoutePerms = getFirstRoutePerms(permissions)console.log(firstRoutePerms)const secondRoutePerms = getSecondRoutePerms(permissions)console.log(secondRoutePerms)}} else {// 跳转回登录页next('/login')}}
})

拆分静态和动态路由表

核心思路:把需要做动态权限控制的路由放到一起,把不需要做权限控制的路由放到一起

拆分动态路由表导出使用

将src\router\index.js中的带有permission标记的路由规则,提取到单独的js文件中

import Layout from '@/layout'// 1. 动态路由: 需要做权限控制 可以根据不同的权限 数量上的变化
// 2. 静态路由: 不需要做权限控制 每一个用户都可以看到 初始化的时候初始化一次// 动态路由表
export const asyncRoutes = [{path: '/park',component: Layout,permission: 'park',meta: { title: '园区管理', icon: 'el-icon-office-building' },children: [{path: 'building',permission: 'park:building',meta: { title: '楼宇管理' },component: () => import('@/views/Park/Building/index')},{path: 'enterprise',permission: 'park:enterprise',meta: { title: '企业管理' },component: () => import('@/views/Park/Enterprise/index')}]},{path: '/parking',component: Layout,permission: 'parking',meta: { title: '行车管理', icon: 'el-icon-guide' },children: [{path: 'area',permission: 'parking:area',component: () => import('@/views/Car/CarArea'),meta: { title: '区域管理' }}, {path: 'card',permission: 'parking:card',component: () => import('@/views/Car/CarCard'),meta: { title: '月卡管理' }}, {path: 'pay',permission: 'parking:payment',component: () => import('@/views/Car/CarPay'),meta: { title: '停车缴费管理' }},{path: 'rule',permission: 'parking:rule',component: () => import('@/views/Car/CarRule'),meta: { title: '计费规则管理' }}]},{path: '/pole',component: Layout,permission: 'pole',meta: { title: '一体杆管理', icon: 'el-icon-refrigerator' },children: [{path: 'info',permission: 'pole:info',component: () => import('@/views/Rod/RodManage'),meta: { title: '一体杆管理' }}, {path: 'waring',permission: 'pole:warning',component: () => import('@/views/Rod/RodWarn'),meta: { title: '告警记录' }}]},{path: '/sys',component: Layout,permission: 'sys',meta: { title: '系统管理', icon: 'el-icon-setting' },children: [{path: 'role',permission: 'sys:role',component: () => import('@/views/System/Role/index'),meta: { title: '角色管理' }}, {path: 'user',permission: 'sys:user',component: () => import('@/views/System/Employee/index'),meta: { title: '员工管理' }}]}
]

router/index.js保留静态路由表

src\router\index.js保留静态路由规则

import Vue from 'vue'
import Router from 'vue-router'import store from '@/store'Vue.use(Router)/* Layout */
import Layout from '@/layout'// 保留静态路由规则表
export const staticRoutes = [{path: '/login',component: () => import('@/views/Login/index'),hidden: true  //true表示将这个路由在左边菜单中进行隐藏},{path: '/roleAdd',component: () => import('@/views/System/Role/AddRole')},{path: '/roleEdit',component: () => import('@/views/System/Role/editRole')},{path: '/park/enterprise/add',component: () => import('@/views/Park/Enterprise/add'),hidden: true  //true表示将这个路由在左边菜单中进行隐藏},{path: '/',component: Layout,redirect: '/workbench'},{// 特殊的二级路由(一级路由)path: '/workbench',component: Layout,children: [{path: '',component: () => import('@/views/Workbench/index'),meta: { title: '工作台', icon: 'el-icon-data-board' }}]},{path: '*',component: () => import('@/views/404'),hidden: true}
]const createRouter = () => new Router({// mode: 'history', // require service supportmode: 'history',scrollBehavior: () => ({ y: 0 }),routes: staticRoutes
})const router = createRouter()// 重置路由方法
export function resetRouter() {// 得到一个全新的router实例对象const newRouter = createRouter()// 使用新的路由记录覆盖掉老的路由记录router.matcher = newRouter.matcher
}export default router

根据菜单标识过滤动态路由表

核心思路:使用一级权限点过滤一级路由,使用二级权限点过滤二级路由

编写处理函数

// 根据权限标识过滤路由表
/** * * @param {*} firstRoutePerms ['park','parking',...]* @param {*} secondRoutePerms  ['park:building','parking:area',...]* @param {*} dinamicRoutes 动态路由规则表* @returns */
function getRoutes(firstRoutePerms, secondRoutePerms, dinamicRoutes) {// 根据一级和二级对动态路由表做过滤 return出去过滤之后的路由表// 1. 根据一级路由对动态路由表做过滤return dinamicRoutes.filter(route => {return firstRoutePerms.includes(route.permission)}).map(item => {// 2. 对二级路由做过滤return {...item,children: item.children.filter(item => secondRoutePerms.includes(item.permission))}})
}

调用函数获取最终动态路由

import router from '@/router/index.js'
import store from '@/store'import { asyncRoutes } from '@/router/dynamicRoute'// 路由守卫
router.beforeEach(async (to, from, next) => {// 登录页面直接放行if (to.path === '/login') {next()} else {const token = store.state.user.token// 判断是否有tokenif (token) {// 放行next()// 获取权限列表if (!store.state.user.profile.id) {const permissions = await store.dispatch('user/getProfile')console.log('权限列表', permissions);// 处理一级和二级菜单标识const firstRoutePerms = getFirstRoutePerms(permissions)console.log(firstRoutePerms)const secondRoutePerms = getSecondRoutePerms(permissions)console.log(secondRoutePerms)// 根据权限标识过滤路由表const filterRoutes = getRoutes(firstRoutePerms, secondRoutePerms, asyncRoutes)//addRoute动态添加路由// '*:*:*' 表示管理员,拥有所有的权限if (permissions.includes('*:*:*')) {// 添加路由asyncRoutes.forEach(item => router.addRoute(item))                  } else {// 添加路由filterRoutes.forEach(item => router.addRoute(item))                  }}} else {// 跳转回登录页next('/login')}}
})

渲染左侧菜单

核心思路:左侧的菜单应该和路由是同步的,使用的同一份数据,因为要动态变化渲染,所以可以通过Vuex进行维护

  1. vuex新增一个menu模块,先以静态的路由表作为初始值
  1. 在得到过滤之后的动态路由表之后,和之前的静态做一个结合
  1. 在组件(src\layout\components\Sidebar\index.vue)中结合v-for指令做使用Vuex中的数据做渲染

编写vuex逻辑

import { staticRoutes } from '@/router'export default {namespaced: true,state() {return {menuList: [...staticRoutes]}},mutations: {setMenuList(state, filterRoutes) {state.menuList = [...staticRoutes, ...filterRoutes]}}
}

触发mutation


// 路由守卫
router.beforeEach(async (to, from, next) => {// 登录页面直接放行if (to.path === '/login') {next()} else {const token = store.state.user.token// 判断是否有tokenif (token) {// 放行next()// 获取权限列表if (!store.state.user.profile.id) {const permissions = await store.dispatch('user/getProfile')console.log('权限列表', permissions);// 处理一级和二级菜单标识const firstRoutePerms = getFirstRoutePerms(permissions)console.log(firstRoutePerms)const secondRoutePerms = getSecondRoutePerms(permissions)console.log(secondRoutePerms)// 根据权限标识过滤路由表const filterRoutes = getRoutes(firstRoutePerms, secondRoutePerms, asyncRoutes)// 调用vuex完成静态路由和动态路由的合并形成当前登录用户最终的完整路由规则表// '*:*:*' 表示管理员,拥有所有的权限if (permissions.includes('*:*:*')) {// 添加路由asyncRoutes.forEach(item => router.addRoute(item))store.commit('menu/setMenuList', asyncRoutes)} else {// 添加路由filterRoutes.forEach(item => router.addRoute(item))store.commit('menu/setMenuList', filterRoutes)}}} else {// 跳转回登录页next('/login')}}
})

改写组件中的菜单渲染数据

computed: {routes() {// return this.$router.options.routesreturn this.$store.state.menu.menuList}
}

退出登录重置

业务背景:在切换不同权限的用户时,新用户会直接使用老用户的路由实例,表现效果就是左侧菜单没有发生变化
解决方案:在退出登录也就是要切换用户时,清空原本的路由记录

user模块中清除用户信息

clearUserInfo(state) {// 清除Tokenstate.token = ''state.profile = {}
}

menu模块添加重置逻辑

import { staticRoutes, resetRouter } from '@/router'
export default {mutations: {resetMenu(state) {// 重置左侧菜单state.menuList = staticRoutes// 重置路由系统resetRouter()}}
}

退出登录时重置路由

logout() {// 增加代码this.$store.commit('menu/resetMenu')
}

补充权限点对照表

添加/编辑楼宇	park:building:add_edit
楼宇管理	park:building:list
删除楼宇	park:building:remove
添加/编辑企业	park:enterprise:add_edit
企业管理	park:enterprise:list
查看企业详情	park:enterprise:query
删除企业	park:enterprise:remove
添加账单	park:propertyFee:add
物业费管理	property:propertyFee:list
查看账单详情	park:propertyFee:query
删除账单	park:propertyFee:remove
添加、续签、退租合同	park:rent:add_surrender
删除合同	park:rent:remove
添加/编辑区域	parking:area:add_edit
区域管理	parking:area:list
删除区域	parking:area:remove
添加/编辑月卡	parking:card:add_edit
月卡管理	parking:card:list
查看月卡	parking:card:query
续费月卡	parking:card:recharge
删除/批量删除月卡	parking:card:remove
停车缴费管理	parking:payment:list
添加或编辑规则	parking:rule:add_edit
计费规则管理	parking:rule:list
删除规则	parking:rule:remove
添加或者编辑一体杆	pole:info:add_edit
一体杆管理	pole:info:list
删除或批量删除一体杆	pole:info:remove
告警记录	pole:warning:list
查看详情	pole:warning:query
删除记录	pole:warning:remove
派单	pole:warning:send
添加/编辑角色	sys:role:add_edit
角色管理	sys:role:list
删除角色	sys:role:remove
添加/编辑员工	sys:user:add_edit
员工管理	sys:user:list
删除员工	sys:user:remove
重置密码	sys:user:resetPwd

 

关键字:福建建筑人才市场官网_今朝装饰口碑怎么样_谷歌香港google搜索引擎入口_seo综合

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: