Skip to content

❤Node19-菜单管理增删改查接口

1、菜单表的创建

接下来我们新建一个菜单表 sys_menu,实现对于菜单部分的管理功能接口

菜单表用于存储系统菜单的相关信息。

接下来我们就根据菜单的功能我们创建一个对应的 SQL 数据表

该表使用InnoDB引擎,字符集为utf8mb4,排序规则为utf8mb4_0900_ai_ci。

javascript
CREATE TABLE `sys_menu`  (
  `menu_id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
  `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称',
  `parent_id` bigint NULL DEFAULT 0 COMMENT '父菜单ID',
  `order_num` int NULL DEFAULT 0 COMMENT '显示顺序',
  `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由地址',
  `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '组件路径',
  `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '路由参数',
  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)',
  `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '权限标识',
  `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#' COMMENT '菜单图标',
  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
  PRIMARY KEY (`menu_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '菜单权限表' ROW_FORMAT = DYNAMIC;

接下来我们先插入两个菜单信息,然后方便我们功能的实现

javascript
INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 1, 'system', NULL, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', '2024-05-28 13:43:38', '', NULL, '系统管理目录');
INSERT INTO `sys_menu` VALUES (3, '系统工具', 0, 3, 'tool', NULL, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', '2024-05-28 13:43:38', '', NULL, '系统工具目录');

创建好之后的菜单数据表是这样子的

接下来我们就根据对应的表的结构和内容来帮助我们生成一下我们的菜单功能部分的api接口

实现菜单功能其实跟我们其他管理的部分差不多

菜单功能主要是我们在pc端用户进行登陆以后可以对于角色菜单权限进行控制,然后可以通过角色对用户进行权限的统一管理

2、菜单的搜索接口

接下来我们就参照用户的列表查询部分同样的去开发一个查询列表,在这里我们也可以先试试数据库查询的条件是否可以用

javascript
SELECT * FROM sys_menu

查找我们的菜单是没有问题的

把查询数据库的部分放进去我们的接口里面,然后进行优化和接口的处理

javascript
app.get('/menus', (req, res) => {
  const query = 'SELECT * FROM sys_menu';
  connection.query(query, (error, results, fields) => {
    if (error) {
      res.status(500).json({ error: error.message });
    } else {
      res.json(results);
    }
  });
});

验证一下我们的查询接口 ,查询没问题

3、菜单增加接口

接下来尝试一下我们的添加功能,我们先来做一个简单的菜单增加

先来试试我们的数据库插入语言,看是否正确

javascript
INSERT INTO `sys_menu` VALUES (107, '通知公告', 1, 8, 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', '2024-05-28 13:43:38', '', NULL, '通知公告菜单');

数据库之中的数据已经进行了相应的更改

接下来我们将数据库语言放入我们的语句之中

所以我们的新增接口就是:

javascript
// 创建新菜单
app.post('/menus', (req, res) => {
  const newMenu = req.body;
  const query = 'INSERT INTO sys_menu SET ?';
  connection.query(query, newMenu, (error, results, fields) => {
    if (error) {
      res.status(500).json({ error: error.message });
    } else {
      res.json({ message: 'Menu created successfully' });
    }
  });
});

尝试一下我们的新增接口

缺少参数,我们再次进行一下优化

javascript
// 新增接口  
router.post('/', (req, res) => {
  const { 
    menu_name, parent_id,order_num, path,component, is_frame,beginTime,endTime,menu_type,visible,status,perms,icon,create_by,create_time,update_by,
     remark 
 } = req.body;
  const newdictData = {
     menu_name, parent_id,order_num, path,component, is_frame,beginTime,endTime,menu_type,visible,status,perms,icon,create_by,create_time,update_by,
     update_time: new Date(),remark
  };
  console.log(newdictData,'newdictData');
  connectionPool.query('INSERT INTO sys_menu SET ?', newdictData, (error, results, fields) => {
    if (error) {
        res.send({
            code: 500,
            data: results,
            message:'添加失败!'
        });
        return;
    } else {
        res.send({
            code: 200,
            data: results,
            message:'添加成功!'
        });
    }
  });
});

主键menu_id重复处理

javascript
 > 1062 - Duplicate entry '1' for key 'sys_menu.PRIMARY'

这个意思就是我们数据库里有重复的主键添加了,这个时候我们去掉参数里面的主键menu_id

参数处理

javascript
1054 - Unknown column 'beginTime' in 'field list'

就是因为我们多了一个参数beginTime ,再次去掉以后尝试

增加功能ok,并且能正确返回我们想要的东西

4、菜单详情接口

详情,通过id然后查到对应的内容

接下来我们简单写一个详情

javascript
 // 获取详情 
router.get('/:id', (req, res) => {
    // console.log(req.query,'req.query');
    console.log(req,'req');
    const { id } = req.params;
    const values = [id];
    let query = 'SELECT * FROM  sys_menu WHERE menu_id = ?';
    connectionPool.query(query, values, (err, results) => {
        // console.log(err,'err');
        if (err) {
            console.error('Error querying database:', err);
            res.status(500).json({ error: 'Internal server error' });
            return;
        }
        res.json({
            code: 200,
            data: results ? results[0] : {},
        });
    });
});

简单测试一下,详情接口没问题,情我们采用的也是通过ID的方式进行获取的

另外一种方式就是当我们的列表存在数据的时候,我们可以直接利用列表的数据直接渲染到表单上,而不需要额外的去再次调用接口!

5、菜单修改接口

接下来我们完善一下我们的修改接口:

javascript
// 更新菜单
app.put('/menus/:id', (req, res) => {
  const menuId = req.params.id;
  const updatedMenu = req.body;
  const query = 'UPDATE sys_menu SET ? WHERE menu_id = ?';
  connection.query(query, [updatedMenu, menuId], (error, results, fields) => {
    if (error) {
      res.status(500).json({ error: error.message });
    } else {
      res.json({ message: 'Menu updated successfully' });
    }
  });
});

测试一下修改接口

javascript
const sql = "UPDATE user sys_menu title = ?, author = ? WHERE id = ?";

修改接口没问题

5、菜单删除接口

删除部分参照我们之前的就可以了

javascript
// 删除菜单
app.delete('/menus/:id', (req, res) => {
  const menuId = req.params.id;
  const query = 'DELETE FROM sys_menu WHERE menu_id = ?';
  connection.query(query, [menuId], (error, results, fields) => {
    if (error) {
      res.status(500).json({ error: error.message });
    } else {
      res.json({ message: 'Menu deleted successfully' });
    }
  });
});

点击删除按钮测试一下我们的接口

测试可以发现,我们的删除功能已经好了!

Released under the MIT License.