乐趣区

vue权限管理系统

vue 权限系统
后台管理系统一般都会有权限模块,用来控制用户能访问哪些页面和哪些数据接口。大多数管理系统的页面都长这样。

左边为菜单,分为两级,右边为图表显示区域,有增删改查的按钮。
表的结构
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

— —————————-
— Table structure for t_auth_rule
— —————————-
DROP TABLE IF EXISTS `t_auth_rule`;
CREATE TABLE `t_auth_rule` (
`id_pk` bigint(20) NOT NULL AUTO_INCREMENT,
`auth_id` varchar(128) NOT NULL COMMENT ‘ 权限 Id’,
`pauth_id` varchar(128) DEFAULT NULL COMMENT ‘ 父级 Id’,
`auth_name` varchar(255) NOT NULL COMMENT ‘ 权限名称 ’,
`auth_icon` varchar(255) NOT NULL COMMENT ‘ 权限图标 ’,
`auth_type` smallint(6) NOT NULL COMMENT ‘ 权限类型,BIT 表示其属性 \r\n 0x00 表示可显示的菜单权限节点;\r\n 0x01 表示普通节点 ’,
`auth_condition` text COMMENT ‘ 条件 ’,
`remark` varchar(255) DEFAULT NULL COMMENT ‘ 备注 ’,
`is_menu` smallint(255) DEFAULT ‘0’ COMMENT ‘ 是否为菜单,0 表示非,1 表示是 ’,
`weight` int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘ 权重 ’,
`rule` varchar(256) DEFAULT NULL COMMENT ‘ 规则路径主要对应菜单或方法的路径名称 ’,
`cr_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘ 创建时间 ’,
`up_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘ 更新时间 ’,
PRIMARY KEY (`id_pk`),
UNIQUE KEY `AK_auth_id` (`auth_id`)
) ENGINE=InnoDB AUTO_INCREMENT=264 DEFAULT CHARSET=utf8 COMMENT=’ 权限规则表,记录权限相关的信息,权限以父子关系存在,菜单是权限的一种。’;

SET FOREIGN_KEY_CHECKS = 1;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

— —————————-
— Table structure for t_role_auth
— —————————-
DROP TABLE IF EXISTS `t_role_auth`;
CREATE TABLE `t_role_auth` (
`id_pk` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id_fk` varchar(32) DEFAULT NULL COMMENT ‘ 角色 id’,
`auth_id_fk` varchar(128) DEFAULT NULL COMMENT ‘ 权限 id’,
`aa` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id_pk`)
) ENGINE=InnoDB AUTO_INCREMENT=77 DEFAULT CHARSET=utf8 COMMENT=’ 角色与权限的关系表 ’;

SET FOREIGN_KEY_CHECKS = 1;
对于菜单的权限,通过路由表匹配
addRouters(menuMap) {
let routerArr = [];
for (let j = 0; j < routerList.length; j++) {
let obj;
if (menuMap[‘AuthRule::’ + routerList[j].path]) {// 找到一级菜单
obj = {
path: routerList[j].path,
component: routerList[j].component,
redirect: routerList[j].redirect,
name: routerList[j].name,
meta: routerList[j].meta,
children: []
};

if (routerList[j].children.length) {
for (let k = 0; k < routerList[j].children.length; k++) {
let _fullpath = routerList[j].children[k].path
if (routerList[j].children[k].meta) {
_fullpath = routerList[j].children[k].meta.parentPath + ‘/’ + _fullpath
}
if (menuMap[‘AuthRule::’ + _fullpath]) {// 找到二级菜单
obj.children.push(routerList[j].children[k]);
}
}
}
}
if (obj) {
routerArr.push(obj);
this.$router.options.routes.push(obj);
}
}

storage.set(“routerArr”, routerArr);
this.$router.addRoutes(routerArr);
this.$router.push({path: “/”});
},
menuMap 为登录时获取的权限菜单,是一个对象;routerList 为前端定义的路由表;遍历 routerList,如果 routerList 的 key 在 menuMap 里能找到的话,就表示该路由存在。最后生成一个过滤后的路由表,用 vue 提供的 addRoutes 方法动态添加到路由中,并把过滤后的路由表存到本地。
const menuMap = {
‘/dashboard’: {path: ‘/dashboard’, name: ‘ 首页 ’}
}
const routerList = [
{path: ‘/dashboard’, name: ‘ 首页 ’, component: ..}
]
在页面刷新的时候,从本地获取路由表,添加到路由表中,代码如下,constRouterArr 为基础路由表,比如登录,404 等
const routerList = storage.get(‘routerArr’)
const routerArr = constRouterArr.concat(routerList);
对于按钮的权限
if (res.data.auth_rule_map) {
let obj = {}
Object.keys(res.data.auth_rule_map).forEach(i => {
// 将所有的按钮放到一个 obj 里 key 为接口地址
if (res.data.auth_rule_map[i].is_menu === 0) {// 如果是按钮
obj[res.data.auth_rule_map[i].rule] = 1
}
})
storage.set(“btnList”, obj);
storage.set(“menuTree”, res.data.auth_rule_map);
}
auth_rule_map 为接口返回权限 map,把按钮的权限过滤出来存到本地。将 map 添加到每个路由组件的 data 里,(这里有一个问题,怎么判断一个组件是否是路由组件),目前想到的是通过组件 name 来判断,把所有的路由组件放到一个数组里做判断。
在组件内部的按钮上加上 v -if,如果 this.uri__里的 uri 在 uriMap 里存在就显示。
uri = {
ADD_MEMBER: ‘/api/add_member’
}

export default function install (Vue) {
const uriMap = storage.get(‘btnList’)
//uriMap[‘/admin/api/auth_rule/update_auth_rule.action’] = 1
Vue.mixin({
created() {
const arr = [‘MemberManage’, ‘PayManage’, ‘…’]
if (arr.indexOf(this.$options.name) !== -1) {
this.dataUri__ = uriMap
this.uri__ = uri
}
},
data() {
return {
dataUri__: {}
}
},
})
}

<Button v-if=”dataUri__[uri__.ADD_MEMBER]”> 添加会员 </Button>

退出移动版