当前位置: 首页 > news >正文

黑马智数Day8

获取用户权限数据

权限数据也属于当前用户相关的信息,使用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)}}
}

permission文件触发action

async getProfile(ctx) {const res = await getProfileAPI()ctx.commit('setProfile', res.data)return res.data.permissions
}
// 权限控制
import router from './router'
import { getCookie } from './utils/auth'
import store from './store'
​
const WHITE_LIST = ['/login', '/404']
​
router.beforeEach(async(to, from, next) => {const token = getCookie('park_token')// 有tokenif (token) {next()// 获取用户信息if (!store.state.user.profile.id) {// 获取原始权限列表const permissions = await store.dispatch('user/getProfile')console.log(permissions)}} else {// 没有tokenif (WHITE_LIST.includes(to.path)) {next()} else {next('/login')}}
})

 

处理一级和二级菜单标识

// 权限控制
import router from './router'
import { getCookie } from './utils/auth'
import store from './store'
​
const WHITE_LIST = ['/login', '/404']
​
// 处理一级路由权限数据
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) => {const token = getCookie('park_token')// 有tokenif (token) {next()// 获取用户信息if (!store.state.user.profile.id) {// 1. 调用action函数获取用户权限数据const perms = await store.dispatch('user/getUserProfile')// 2. 把后端的权限数组格式化成我们自己的俩个权限数据console.log('当前的权限数据为:', perms)const firstRoutePerms = getFirstRoutePerms(perms)console.log(firstRoutePerms)const secondRoutePerms = getSecondRoutePerms(perms)console.log(secondRoutePerms)}} else {// 没有tokenif (WHITE_LIST.includes(to.path)) {next()} else {next('/login')}}
})

 

拆分静态和动态路由表

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

拆分动态路由表导出使用

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: '员工管理' }}]}
]

初始化时只处理静态路由表 

import Vue from 'vue'
import Router from 'vue-router'
​
Vue.use(Router)
​
/* Layout */
import Layout from '@/layout'
​
// 俩种路由
​
export const routes = [{path: '/login',component: () => import('@/views/Login/index'),hidden: true},{path: '/addCard',component: () => import('@/views/Car/CarCard/add-card'),hidden: true},{path: '/addEnterprise',component: () => import('@/views/Park/Enterprise/AddEnterprise'),hidden: true},{path: '/enterpriseDetail',component: () => import('@/views/Park/Enterprise/EnterpriseDetail'),hidden: true},{path: '/addRole',component: () => import('@/views/System/Role/AddRole'),hidden: true},{path: '/',component: Layout,redirect: '/workbench'},// 只有一级路由// 一级路由:负责把layout架子渲染出来// 二级路由:path为空 会作为默认的二级路由一上来就渲染出来{path: '/workbench',component: Layout,children: [{path: '',component: () => import('@/views/Workbench/index'),meta: { title: '工作台', icon: 'el-icon-data-board' }}]},
​{path: '/404',component: () => import('@/views/404'),hidden: true}
]
​
const createRouter = () => new Router({// mode: 'history', // require service supportmode: 'history',scrollBehavior: () => ({ y: 0 }),routes: [...routes]
})
​
const router = createRouter()
​
// 重置路由方法
export function resetRouter() {// 得到一个全新的router实例对象const newRouter = createRouter()// 使用新的路由记录覆盖掉老的路由记录router.matcher = newRouter.matcher
}
​
export default router

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

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

编写处理函数

// 根据权限标识过滤路由表
function getRoutes(firstRoutePerms, secondRoutePerms, asyncRoutes) {// 根据一级和二级对动态路由表做过滤 return出去过滤之后的路由表// 1. 根据一级路由对动态路由表做过滤return asyncRoutes.filter(route => {return firstRoutePerms.includes(route.permission)}).map(item => {// 2. 对二级路由做过滤return {...item,children: item.children.filter(item => secondRoutePerms.includes(item.permission))}})
}

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

// 导入原始动态路由表
import { asyncRoutes } from './router/asyncRoute'
​
router.beforeEach(async(to, from, next) => {const token = getCookie('park_token')// 有tokenif (token) {next()// 获取用户信息if (!store.state.user.profile.id) {// 1. 获取原始权限列表const permissions = await store.dispatch('user/getProfile')// 2. 数据处理得到一级二级路由菜单标识const menuPerms = getMenuList(permissions)console.log(menuPerms)// 3. 通过菜单权限过滤一级和二级得到权限菜单列表const filterRoutes = getFilterRoutes(menuPerms, asyncRoutes)console.log(filterRoutes)}} else {// 没有tokenif (WHITE_LIST.includes(to.path)) {next()} else {next('/login')}}
})

 

动态添加路由表

核心思路:vue-router插件提供了 addRoute 方法可以把处理之后的路由添加到路由系统中,让路由生效

router.beforeEach(async(to, from, next) => {const token = getCookie('park_token')// 有tokenif (token) {next()// 获取用户信息if (!store.state.user.profile.id) {// 1. 获取原始权限列表const permissions = await store.dispatch('user/getProfile')// 2. 获取菜单权限列表const menuPerms = getMenuList(permissions)console.log(menuPerms)// 3. 通过菜单权限过滤一级和二级const filterRoutes = getFilterRoutes(menuPerms, asyncRoutes)console.log(filterRoutes)// 4. addRoute动态添加filterRoutes.forEach(route => router.addRoute(route))}} else {// 没有tokenif (WHITE_LIST.includes(to.path)) {next()} else {next('/login')}}
})

 

渲染左侧菜单

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

  1. vuex新增一个模块,menu模块,先以静态的路由表作为初始值

  2. 在得到过滤之后的动态路由表之后,和之前的静态做一个结合

  3. 在组件中结合v-for指令做使用Vuex中的数据做渲染

编写vuex逻辑

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

触发mutation

router.beforeEach(async(to, from, next) => {const token = getCookie('park_token')// 有tokenif (token) {next()// 获取用户信息if (!store.state.user.profile.id) {// 1. 获取原始权限列表const permissions = await store.dispatch('user/getProfile')// 2. 获取菜单权限列表const menuPerms = getMenuList(permissions)console.log(menuPerms)// 3. 通过菜单权限过滤一级和二级const filterRoutes = getFilterRoutes(menuPerms, asyncRoutes)console.log(filterRoutes)// 4. addRoute动态添加filterRoutes.forEach(route => router.addRoute(route))// 5. 存入Vuex渲染左侧菜单store.commit('menu/setMenuList', filterRoutes)}} else {// 没有tokenif (WHITE_LIST.includes(to.path)) {next()} else {next('/login')}}
})

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

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

 

退出登录重置

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

user模块中清除用户信息

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

menu模块添加重置逻辑

import { contantsRoutes, resetRouter } from '@/router'
export default {mutations: {resetMenu(state) {// 重置左侧菜单state.menuList = contantsRoutes// 重置路由系统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

http://www.mrgr.cn/news/75185.html

相关文章:

  • 知识库搭建:大健康产业数字化转型的新引擎
  • JavaWeb-表单-07
  • 介绍一下strncmp(c基础)
  • Rust 智能指针
  • java中的this关键字
  • django——创建 Django 项目和 APP
  • 机器学习 ---模型评估、选择与验证(1)
  • cache中命中率和平均访问时间
  • RK3568平台开发系列讲解(platform虚拟总线驱动篇)platform总线模型
  • Shell脚本的使用
  • CPLD架构
  • KPaaS洞察|统一管理模式下跨系统用户权限修改流程详解
  • python进阶-01-利用Xpath来解析Html
  • 除自身以外数组的乘积
  • 关于GCC内联汇编(也可以叫内嵌汇编)的简单学习
  • 共享旅游卡项目深度解读,风险与机遇并存
  • Java 常见的面试题(Kafka)
  • 三天精通一种算法之移除数组元素(暴力)(快慢指针)
  • MySQL数据库:SQL语言入门 【2】(学习笔记)
  • Spring Security概述
  • 基于树莓派的日志抓取工具制作
  • 代理通讯链实现内网通讯
  • 探秘 RPC:揭开远程过程调用的实现原理
  • 如何在python中模拟重载初始化函数?
  • 下载|阿里云等联合编写的《2024大模型典型示范应用案例集》发布
  • 「Mac玩转仓颉内测版10」PTA刷题篇1 - L1-001 Hello World