手把手带你用vue-admin-template实现动态权限管理(二)
前言
手把手带你用vue-admin-template实现动态权限管理(一)如果没有看过上一篇文章的同学,建议看一下上一篇文章。
前期储备
本项目技术栈node.js、express、mysql
本节目标
要实现动态权限让后台返回,那势必需要将路由表存入到数据库。现在项目中一般采用的是前后端分离的模式,你跑过去跟你们的后台java、php开发人员说一通他不一定听的懂。所以这节我们就通过node.js、express、mysql实现权限表的设计、接口开发。到时候你让后台开发人员照着这些个表设计即可。
mysql表
用户表
id | name | account | password | role_id |
---|---|---|---|---|
1 | 刘备 | liubei | 123456 | 1 |
2 | 张飞 | zhangfei | 123456 | 3 |
3 | 关羽 | guanyu | 123456 | 2 |
- id:自增
- name:用户昵称
- account:用户登录的账号
- password:用户登录的密码(这里为了方便直接存储的是明文)
- role_id:角色id(后面用于关联角色表)
角色表
id | role_name | remark | menus |
---|---|---|---|
1 | admin | 超级管理员 | [3,2,4,7,12] |
2 | editor | 编辑人员 | [2,14,3,12] |
3 | visitor | 游客 | [4,7,14,3,12] |
- id:自增
- role_name:角色名(英文名称,作为唯一标识)
- remarl:角色名的中文名称
- menus:对应角色拥有的菜单权限(id数组存储menus表中的id)
菜单表
id | title | parentid | component | type | icon | hidden | name | redirect | path | number |
---|---|---|---|---|---|---|---|---|---|---|
2 | 用户列表 | 3 | permission/user | 1 | el-icon-user | 1 | users | Null | users | 4 |
3 | 权限管理 | Null | Layout | 0 | el-icon-lock | 1 | permission | /permission/users | /permission | 3 |
4 | 角色列表 | 3 | permission/roles | 1 | el-icon-set-up | 1 | roles | Null | roles | 5 |
7 | 菜单管理 | 3 | permission/caidan | 1 | el-icon-collection | 1 | caidan | Null | caidan | 6 |
12 | 工单管理 | Null | Layout | 0 | el-icon-document | 0 | ticket | /ticket/contract | /ticket | 7 |
14 | 合同管理 | 12 | ticket/contract | 1 | el-icon-document-add | 1 | contract | Null | contract | 8 |
15 | 过户管理 | 12 | ticket/transfer | 1 | el-icon-office-building | 1 | transfer | Null | transfer | 9 |
- id:自增
- title:后台左侧菜单显示的标题
- parentid:上一级id是多少
- component:组件(主要是Layout和其他,前端路由导入就会使用resolve => require([
@/views/${subView}
], resolve)动态生成) - type:1是菜单,0是目录
- icon:饿了么图标
- hidden:左侧导航栏是否显示此菜单(例如一个列表页面有一个详情按钮跳转,这时候这个详情的导航是不需要在左侧菜单显示的)
- name:唯一标识(用于项目中的keep-alive路由缓存,我暂时没用到)
- redirect:重定向,一般用于路由指到父目录,重定向到第一个菜单
- path:路由中的path
- number:控制后台左侧菜单的显示顺序
创建接口
- 新建文件夹然后,当前文件夹下按住shift+右键打开命令窗口执行:npm init -y
- npm i epxress mysql body-parser 安装express、mysql、body-parser
- 新建mysql.config
javascript
//配置链接数据库参数
module.exports = {
host:'localhost',
user:'root',
password:'123456',
database:'router'
};
- 新建app.js
javascript
let express = require('express')
let mysql = require('mysql');
//加载post请求参数处理中间件
let body_parser = require('body-parser');
let mysqlConfig = require('./mysql.config')
mysql.createConnection(mysqlConfig)
let app = express()
//配置post表单解析
app.use(body_parser.json({limit: '50mb'}));
app.use(body_parser.urlencoded({limit: '50mb', extended: true}));
app.use(express.json({limit: '5mb'}));
//设置跨域请求
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
/*
* 获取权限接口
* */
app.post('/permission', function (req, res) {
let permission = []
let mysqlQuery = mysql.createConnection(mysqlConfig)
mysqlQuery.query('select * from role where id = ?', [req.body.roleId], function (error, result, feild) {
if (result) {
let role = result[0]
let meuns = JSON.parse(role.menus)
mysqlQuery.query('SELECT * FROM menu WHERE id in (?) ORDER BY number ASC', [meuns], function (error, result, feild) {
if (result) {
for (let i = 0; i < result.length; i++) {
let sqlItem = result[i]
if (sqlItem.parentid === null || sqlItem.parentid === '') {
let newSqlItem = {}
newSqlItem.path = sqlItem.path
newSqlItem.component = sqlItem.component
newSqlItem.meta = {}
newSqlItem.meta.title = sqlItem.title
newSqlItem.meta.icon = sqlItem.icon
newSqlItem.name = sqlItem.name
newSqlItem.redirect = sqlItem.redirect
newSqlItem.alwaysShow = sqlItem.hidden === 1
newSqlItem.children = []
for (let j = 0; j < result.length; j++) {
let childrenItem = result[j]
let newChildrenItem = {}
if (childrenItem.hasOwnProperty('parentid') && childrenItem.parentid === sqlItem.id) {
newChildrenItem.path = childrenItem.path
newChildrenItem.name = childrenItem.name
newChildrenItem.component = childrenItem.component
newChildrenItem.meta = {}
newChildrenItem.meta.title = childrenItem.title
newChildrenItem.meta.icon = childrenItem.icon
newChildrenItem.newSqlItem = childrenItem.newSqlItem
newChildrenItem.hidden = childrenItem.hidden === 0
newSqlItem.children.push(newChildrenItem)
}
}
permission.push(newSqlItem)
}
}
}
res.send(permission)
})
}
})
})
// 监听4321端口,到时候项目访问就是http://127.0.0.1:4321/
app.listen(4321, function () {
console.log('running...')
})
- node app.js启动项目
- 当用户调用http://127.0.0.1:4321/permission的时候就会进入app.js的app.post('/permission',functuin(req,res))方法
- 根据用户传递过来的角色id查询role表中的role.menus字段
- 然后根据role.menus中的菜单id数组在menus中查询并排序,如图
- 然后通过两层for循环,循环出parentid为空作为父节点和parenteid不为空的子节点
- 我们通过postman调用后数据是这个样子的。
json
[
{
"path": "/permission",
"component": "Layout",
"meta": {
"title": "权限管理",
"icon": "el-icon-lock"
},
"name": "permission",
"redirect": "/permission/users",
"alwaysShow": true,
"children": [
{
"path": "users",
"name": "users",
"component": "permission/user",
"meta": {
"title": "用户列表",
"icon": "el-icon-user"
},
"hidden": false
},
{
"path": "roles",
"name": "roles",
"component": "permission/roles",
"meta": {
"title": "角色列表",
"icon": "el-icon-set-up"
},
"hidden": false
},
{
"path": "caidan",
"name": "caidan",
"component": "permission/caidan",
"meta": {
"title": "菜单管理",
"icon": "el-icon-collection"
},
"hidden": false
}
]
},
{
"path": "/ticket",
"component": "Layout",
"meta": {
"title": "工单管理",
"icon": "el-icon-document"
},
"name": "ticket",
"redirect": "/ticket/contract",
"alwaysShow": false,
"children": [
{
"path": "contract",
"name": "contract",
"component": "ticket/contract",
"meta": {
"title": "合同管理",
"icon": "el-icon-document-add"
},
"hidden": false
},
{
"path": "transfer",
"name": "transfer",
"component": "ticket/transfer",
"meta": {
"title": "过户管理",
"icon": "el-icon-office-building"
},
"hidden": false
}
]
}
]
这个json就是要返回给前端的。
结语
到这里后台权限表的设计和接口处理已经讲完了,下一篇将完善接口,实现结合vue-element-admin实现一个完整的用户权限管理项目。