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

手把手带你用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:控制后台左侧菜单的显示顺序
创建接口
  1. 新建文件夹然后,当前文件夹下按住shift+右键打开命令窗口执行:npm init -y
  2. npm i epxress mysql body-parser 安装express、mysql、body-parser
  3. 新建mysql.config
javascript 复制代码
//配置链接数据库参数
module.exports = {
    host:'localhost',
    user:'root',
    password:'123456',
    database:'router'
};
  1. 新建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...')
})
  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调用后数据是这个样子的。
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实现一个完整的用户权限管理项目。

相关推荐
大怪v1 小时前
【Virtual World 04】我们的目标,无限宇宙!!
前端·javascript·代码规范
狂炫冰美式1 小时前
不谈技术,搞点文化 🧀 —— 从复活一句明代残诗破局产品迭代
前端·人工智能·后端
xw52 小时前
npm几个实用命令
前端·npm
!win !2 小时前
npm几个实用命令
前端·npm
代码狂想家2 小时前
使用openEuler从零构建用户管理系统Web应用平台
前端
dorisrv4 小时前
优雅的React表单状态管理
前端
蓝瑟4 小时前
告别重复造轮子!业务组件多场景复用实战指南
前端·javascript·设计模式
dorisrv4 小时前
高性能的懒加载与无限滚动实现
前端
韭菜炒大葱4 小时前
别等了!用 Vue 3 让 AI 边想边说,字字蹦到你脸上
前端·vue.js·aigc
StarkCoder5 小时前
求求你,别在 Swift 协程开头写 guard let self = self 了!
前端