手把手带你用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实现一个完整的用户权限管理项目。

相关推荐
吕彬-前端13 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(二)
前端·react.js·前端框架
小白小白从不日白34 分钟前
react hooks--useCallback
前端·react.js·前端框架
恩婧43 分钟前
React项目中使用发布订阅模式
前端·react.js·前端框架·发布订阅模式
mez_Blog44 分钟前
个人小结(2.0)
前端·javascript·vue.js·学习·typescript
珊珊而川1 小时前
【浏览器面试真题】sessionStorage和localStorage
前端·javascript·面试
森叶1 小时前
Electron 安装包 asar 解压定位问题实战
前端·javascript·electron
drebander1 小时前
ubuntu 安装 chrome 及 版本匹配的 chromedriver
前端·chrome
软件技术NINI1 小时前
html知识点框架
前端·html
深情废杨杨1 小时前
前端vue-插值表达式和v-html的区别
前端·javascript·vue.js
GHUIJS1 小时前
【vue3】vue3.3新特性真香
前端·javascript·vue.js