The admin data of permission management cannot be edited.

renderings

Online address: https://codesandbox.io/s/authorizedbyrole-yzy4r2?file=/src/util/directive.js

The current user has a non-admin role

[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-AstPxFPY-1691845473313)(https://s3-us-west-2.amazonaws.com/secure.notion -static.com/e442293a-50a2-4493-8ea5-b5be8bceb566/Untitled.png)]

environment

[email protected] vuex javascript

What happened

General systems adopt the RBAC model: user-role-authority control **

Therefore, by authorizing the role in menu management, you can implement the corresponding operations.

But recently, I received a request. The data created by the administrator role cannot be operated by non-administrators regardless of the front-end authorization status.

So, my idea is v-hasto do the operation in the control authorization button command

However, I found that I could not get the current data

So, I started to think about opportunism and so on.

A column is created admin, and the data created by the administrator role mdi-alpha-a-circleis displayed with the icon

Determine whether the current row has mdi-alpha-a-circlea class class to determine whether the data is created by the administrator.

Then determine whether the current role is a non-administrator. If so, delete the node.

flow chart

[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-7qfLrmrX-1691845473314)(https://s3-us-west-2.amazonaws.com/secure.notion -static.com/2fba390b-e87f-4d4b-946e-f4ec05507807/Untitled.png)]

necessary conditions

  1. There is a admincolumn where the data created by the administrator role mdi-alpha-a-circleis displayed with an icon.
  2. Must follow tr>> DOM tdstructure template>btn, as follows
<template v-slot:item.actions="{ item }">
  <v-btn v-has:edit icon @click.stop="edit(item)">
    <v-icon size="1.25rem"> mdi-pencil </v-icon>
  </v-btn>
  <v-btn v-has:del icon>
    <v-icon size="1.25rem" class="icon-hover-bg ml-2" @click.stop="del(item)"> mdi-delete </v-icon>
  </v-btn>
</template>

Implementation ideas

Create admin column

Generally speaking, it is impossible for the interface to return the role of the creator. Generally, it is returned userId, userNameso all the roles must be queried userIdand stored in store. For example userIdByAdminList, to determine whether the current user is admina role .

Implementation ideas:

<template v-slot:item.createUser="{ item }">
  <v-icon
    v-if="$store.state.userIdByAdminList.includes(item.createUser)"
    size="1.5rem"
    color="primary"
    >mdi-alpha-a-circle</v-icon
  >
  <span v-else>{
   
   { item.createUser }}</span>
</template>

Add v-has to button

<template v-slot:item.actions="{ item }">
  <v-btn v-has:edit icon @click.stop="edit(item)">
    <v-icon size="1.25rem"> mdi-pencil </v-icon>
  </v-btn>
  <v-btn v-has:del icon>
    <v-icon size="1.25rem" class="icon-hover-bg ml-2" @click.stop="del(item)"> mdi-delete </v-icon>
  </v-btn>
</template>

v-has implementation

Recursively look for adminIcon

Conditions for ending recursion: one of them can be met

  • item.childNodes.length===0
  • iconNode is not 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 instruction implementation

// 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')
         }
      }
   }
}

The second implementation idea

Pass in the current record function:v-has:del = "item"

Main logic code:

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);
  }
}

One disadvantage of doing this is that each button must pass parameters and must have createUserfields, which is suitable for all pages that have not yet been authorized.

Trampling on pit records

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

Guess you like

Origin blog.csdn.net/weixin_41886421/article/details/132253505