feat: add authorize directive; 🌟

新增:权限验证指令;
This commit is contained in:
iczer
2020-08-02 18:50:23 +08:00
parent 55358b4107
commit 9b96868586
7 changed files with 190 additions and 13 deletions

View File

@@ -0,0 +1,134 @@
/**
* 获取路由需要的权限
* @param permissions
* @param route
* @returns {*}
*/
const getRoutePermission = (permissions, route) => permissions.find(item => item.id === route.meta.authority.permission)
/**
* 获取路由需要的角色
* @param roles
* @param route
* @returns {*}
*/
const getRouteRole = (roles, route) => roles.find(item => item.id === route.meta.authority.role)
/**
* 判断是否已为方法注入权限认证
* @param method
* @returns {boolean}
*/
const hasInjected = (method) => method.toString().indexOf('//--auth-inject') !== -1
/**
* 操作权限校验
* @param authConfig
* @param permission
* @param role
* @param permissions
* @param roles
* @returns {boolean}
*/
const auth = function(authConfig, permission, role, permissions, roles) {
const {check, type} = authConfig
if (check && typeof check === 'function') {
return check(permission, role, permissions, roles)
} else {
if (type === 'permission') {
return permission && permission.operation && permission.operation.indexOf(check) !== -1
} else if (type === 'role') {
return role && role.operation && role.operation.indexOf(check) !== -1
}
}
return false
}
/**
* 阻止的 click 事件监听
* @param event
* @returns {boolean}
*/
const preventClick = function (event) {
event.stopPropagation()
return false
}
const checkInject = function (el, binding,vnode) {
const type = binding.arg
const check = binding.value
const instance = vnode.componentInstance
const $auth = instance.$auth
if (!$auth || !$auth(check, type)) {
el.classList.add('disabled')
el.setAttribute('title', '无此权限')
el.addEventListener('click', preventClick, true)
} else {
el.classList.remove('disabled')
el.removeAttribute('title')
el.removeEventListener('click', preventClick, true)
}
}
const AuthorityPlugin = {
install(Vue) {
Vue.directive('auth', {
bind(el, binding,vnode) {
checkInject(el, binding, vnode)
},
update(el, binding,vnode) {
checkInject(el, binding, vnode)
}
})
Vue.mixin({
beforeCreate() {
if (this.$options.authorize) {
const authorize = this.$options.authorize
Object.keys(authorize).forEach(key => {
if (this.$options.methods[key]) {
const method = this.$options.methods[key]
if (!hasInjected(method)) {
let authConfig = authorize[key]
authConfig = (typeof authConfig === 'string') ? {check: authConfig} : authConfig
const {check, type, onFailure} = authConfig
this.$options.methods[key] = function () {
//--auth-inject
if (this.$auth(check, type)) {
return method(...arguments)
} else {
if (onFailure && typeof onFailure === 'function') {
this[`$${check}Failure`] = onFailure
return this[`$${check}Failure`](check)
} else {
this.$message.error(`对不起,您没有操作权限:${check}`)
}
return 0
}
}
}
}
})
}
},
methods: {
/**
* 操作权限校验
* @param check 需要校验的操作名
* @param type 校验类型,通过 permission 校验,还是通过 role 校验。
* 如未设置,则自动识别,如匹配到当前路由 permission 则 type = permission否则 type = role
* @returns {boolean} 是否校验通过
*/
$auth(check, type) {
const permissions = this.$store.getters['account/permissions']
const roles = this.$store.getters['account/roles']
const permission = getRoutePermission(permissions, this.$route)
const role = getRouteRole(roles, this.$route)
if (!type) {
type = permission ? 'permission' : 'role'
}
return auth({check, type}, permission, role, permissions, roles)
}
}
})
}
}
export default AuthorityPlugin

View File

@@ -1,7 +1,10 @@
import VueI18nPlugin from '@/plugins/i18n-extend';
import VueI18nPlugin from '@/plugins/i18n-extend'
import AuthorityPlugin from '@/plugins/authority-plugin'
const Plugins = {
install: function (Vue) {
Vue.use(VueI18nPlugin)
Vue.use(AuthorityPlugin)
}
}
export default Plugins