# 权限控制

该项目的权限控制基于角色的权限控制RBAC(role-based access control),指对于不同角色的用户,拥有不同的权限 。用户对应一个角色,一个角色拥有若干权限,形成用户-角色-权限的关系。当一个用户进行访问数据时,根据其角色判断其拥有的权限,限定其操作。

image-20210106165030394

# 菜单权限

项目支持菜单权限动态配置,后台通过获取当前用户的权限去加载配置的菜单信息和路由信息,生成当前用户具有的权限可访问的侧边栏菜单和对应的路由,通过 router.addRoutes 动态挂载到 router 上。现在路由层面权限的控制代码都在 src/permission.js 中,如果想修改逻辑,直接在适当的判断逻辑中 next() 释放钩子即可。

// get user info
// note: permissions must be a object array! such as: ['user:list','role:create'] 
const { permissions } = await store.dispatch('user/getInfo')

const asyncRoutes = filterAsyncRouter(await buildMenus())
asyncRoutes.push({ path: '*', redirect: '/404', hidden: true })

// // generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes',
  { asyncRoutes, permissions })

// // dynamically add accessible routes
router.addRoutes(accessRoutes)

// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
next({ ...to, replace: true })

# 控件权限

src/directive/permission/permission.js这里封装了权限指令,能简单快速的实现控件级别的权限判断,本项目只是根据权限控制当前标记的控件是否显示,如果需要实现譬如下拉选择项的权限控制,可以自行扩展。

function checkPermission(el, binding) {
  const { value } = binding
  const permissions = store.getters && store.getters.permissions

  if (value && value instanceof Array) {
    if (value.length > 0) {
      const hasPermission = permissions.some(permission => {
        return value.includes(permission)
      })

      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    }
  } else {
    throw new Error(`使用方式: v-permission="['admin','editor']"`)
  }
}