renderings
Online address: https://codesandbox.io/s/authorizedbyrole-yzy4r2?file=/src/util/directive.js
The current user has a non-admin role
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-has
to 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-circle
is displayed with the icon
Determine whether the current row has mdi-alpha-a-circle
a 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
necessary conditions
- There is a
admin
column where the data created by the administrator rolemdi-alpha-a-circle
is displayed with an icon. - Must follow
tr
>> DOMtd
structuretemplate>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
, userName
so all the roles must be queried userId
and stored in store
. For example userIdByAdminList
, to determine whether the current user is admin
a 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 createUser
fields, which is suitable for all pages that have not yet been authorized.