权限管理之admin数据不可编辑

效果图

在线地址:https://codesandbox.io/s/authorizedbyrole-yzy4r2?file=/src/util/directive.js

当前用户为非管理员角色

权限管理之admin数据不可编辑_第1张图片

环境

[email protected] vuex javascript

事情经过

一般的系统,都是采用**RBAC模型:基于用户-角色-权限控制**

所以在菜单管理中给角色授权,就可以实现对应的操作

但是最近,我接到了一个需求,管理员角色创建的数据,非管理员无论前端授权情况,都不可操作

于是,我的想法是在v-has控制授权按钮指令里面做操作

但是,我发现,无法拿到当条数据

于是,开始了投机取巧之类的想法

创建了一个admin列,管理员角色创建的数据用图标mdi-alpha-a-circle 显示

判断当前行有没有mdi-alpha-a-circle class类,来判断是不是管理员创建的数据

然后判断当前角色是不是非管理员,若是,删除节点

流程图

权限管理之admin数据不可编辑_第2张图片

必要条件

  1. 有个admin列,管理员角色创建的数据用图标mdi-alpha-a-circle 显示
  2. 必须按照 tr >td>template>btn DOM结构,如下

实现思路

创建admin列

一般来说,接口是不可能把创建者所属角色返回的,一般返回的是userIduserName,所以必须根据角色查询所有userId,存储在store中,如userIdByAdminList ,判断当前用户是否是admin角色

实现思路:


给按钮添加v-has


v-has实现

递归寻找adminIcon

结束递归的条件:满足之一即可

  • item.childNodes.length===0
  • iconNode不为null
let iconNode = null
const getAdminIcon = (nodeList) => {
  //  console.log('nodeList', nodeList)
  if(iconNode){
    return iconNode
  }
   
   for (let i = 0; i < nodeList.length; i++) {
      let item = nodeList[i]
      let bool = item.classList && item.classList.contains('mdi-alpha-a-circle')
      // console.log('item', item)
      // console.log('bool', bool)
      if (bool) {
         iconNode = item
         break
      }
      if (item.childNodes.length === 0) {
         continue
      }
      iconNode = getAdminIcon(item.childNodes)
   }
   return iconNode
}

v-has指令实现

// v-has:search
const has = {
   inserted(el, binding, vnode) {
      let isForceDel = false
      // 第一种实现方式
      let trNodes = el.parentNode.parentNode.childNodes
      if (trNodes) {
         const iconEle = getAdminIcon(trNodes)
         if (iconEle) {
            console.log(iconEle) // 管理员创建的数据
            let roleId = store.state.userInfo.roleId
            isForceDel = roleId !== 'admin'
         }
      }

      const value = binding.arg || binding.value || binding.value.arg

      const permissions = vnode.context.$route.meta.buttons || []
      
      if (value) {
         if (!permissions.includes(value) || isForceDel) {
          
            ;(el.parentNode && el.parentNode.removeChild(el)) ||
               (el.style.display = 'none')
         }
      }
   }
}

第二种实现思路

传入当前记录函数:v-has:del = "item"

主要逻辑代码:

if (binding.value) {
  let record = binding.value;
  let isAdmin = store.state.userIdByAdminList.includes(record.createUser);
  let userId = store.state.userInfo.userId;

  if (isAdmin) {
    isForceDel = !store.state.userIdByAdminList.includes(userId);
  }
}

这样子做的一个不好的点就是,每个按钮都要传参,并且必须有createUser字段,适合所有页面还没有授权的情况

踩坑记录

https://segmentfault.com/q/1010000044084082?_ea=312694630

你可能感兴趣的:(javascript,vue.js,前端,css)