手把手带你用vue-admin-template实现动态权限管理(二)

手把手带你用vue-admin-template实现动态权限管理(二)

前言

手把手带你用vue-admin-template实现动态权限管理(一)如果没有看过上一篇文章的同学,建议看一下上一篇文章。

前期储备

本项目技术栈node.js、express、mysql

本节目标

要实现动态权限让后台返回,那势必需要将路由表存入到数据库。现在项目中一般采用的是前后端分离的模式,你跑过去跟你们的后台java、php开发人员说一通他不一定听的懂。所以这节我们就通过node.js、express、mysql实现权限表的设计、接口开发。到时候你让后台开发人员照着这些个表设计即可。

mysql表
用户表
idnameaccountpasswordrole_id
1刘备liubei1234561
2张飞zhangfei1234563
3关羽guanyu1234562
  • id:自增
  • name:用户昵称
  • account:用户登录的账号
  • password:用户登录的密码(这里为了方便直接存储的是明文)
  • role_id:角色id(后面用于关联角色表)
角色表
idrole_nameremarkmenus
1admin超级管理员[3,2,4,7,12]
2editor编辑人员[2,14,3,12]
3visitor游客[4,7,14,3,12]
  • id:自增
  • role_name:角色名(英文名称,作为唯一标识)
  • remarl:角色名的中文名称
  • menus:对应角色拥有的菜单权限(id数组存储menus表中的id)
菜单表
idtitleparentidcomponenttypeiconhiddennameredirectpathnumber
2用户列表3permission/user1el-icon-user1usersNullusers4
3权限管理NullLayout0el-icon-lock1permission/permission/users/permission3
4角色列表3permission/roles1el-icon-set-up1rolesNullroles5
7菜单管理3permission/caidan1el-icon-collection1caidanNullcaidan6
12工单管理NullLayout0el-icon-document0ticket/ticket/contract/ticket7
14合同管理12ticket/contract1el-icon-document-add1contractNullcontract8
15过户管理12ticket/transfer1el-icon-office-building1transferNulltransfer9
  • id:自增
  • title:后台左侧菜单显示的标题
  • parentid:上一级id是多少
  • component:组件(主要是Layout和其他,前端路由导入就会使用resolve => require([@/views/${subView}], resolve)动态生成)
  • type:1是菜单,0是目录
  • icon:饿了么图标
  • hidden:左侧导航栏是否显示此菜单(例如一个列表页面有一个详情按钮跳转,这时候这个详情的导航是不需要在左侧菜单显示的)
  • name:唯一标识(用于项目中的keep-alive路由缓存,我暂时没用到)
  • redirect:重定向,一般用于路由指到父目录,重定向到第一个菜单
  • path:路由中的path
  • number:控制后台左侧菜单的显示顺序
创建接口
  1. 新建文件夹然后,当前文件夹下按住shift+右键打开命令窗口执行:npm init -y
  2. npm i epxress mysql body-parser 安装express、mysql、body-parser
  3. 新建mysql.config
//配置链接数据库参数
module.exports = {
    host:'localhost',
    user:'root',
    password:'123456',
    database:'router'
};
  1. 新建app.js
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...')
})
  1. node app.js启动项目
  2. 当用户调用http://127.0.0.1:4321/permission的时候就会进入app.js的app.post(’/permission’,functuin(req,res))方法
  3. 根据用户传递过来的角色id查询role表中的role.menus字段
  4. 然后根据role.menus中的菜单id数组在menus中查询并排序,如图
    在这里插入图片描述
  5. 然后通过两层for循环,循环出parentid为空作为父节点和parenteid不为空的子节点
  6. 我们通过postman调用后数据是这个样子的。
[
    {
        "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实现一个完整的用户权限管理项目。

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值