SpringBoot分页查询所有菜单,包含子菜单等

        前些天写的一个小模块了,记录一下,后面还会用到~

这是一个查询菜单接口,要求是:分页查询,一级菜单(父),二级菜单(子)等。这里接口是post类型,传参为:pagenum和pagesize为我们要分页查询的必须值,返回值为如下样式:

//实例
{
  "code": 200,
  "message": "操作成功!",
  "data": {
    "total": 12,
    "pageSize": 2,
    "list": [
      {
        "id": "04f29f26-2eb8-4dfb-bfb2-856937b1d454",
        "name": "订单管理",
        "pid": null,
        "pathUrl": "/layout/sysmanager/dictionary",
        "iconUrl": "123",
        "type": false,
        "desc": null,
        "applicationId": null,
        "tenantName": "龙傲天",
        "tenantId": "1",
        "ordernum": "1",
        "createUser": "demo",
        "updateUser": "demo",
        "createTime": "2024-12-24T16:00:00.000+00:00",
        "updateTime": "2025-02-05T00:40:34.464+00:00",
        "children": [
          {
            "id": "7006eaf2-a479-43c7-876c-d8d9541a28c8",
            "name": "订单管理",
            "pid": "04f29f26-2eb8-4dfb-bfb2-856937b1d454",
            "pathUrl": "/layout/sysmanager/user",
            "iconUrl": "223",
            "type": false,
            "desc": null,
            "applicationId": null,
            "tenantName": "龙傲天",
            "tenantId": "1",
            "ordernum": "1",
            "createUser": "demo",
            "updateUser": "demo",
            "createTime": "2024-12-24T16:00:00.000+00:00",
            "updateTime": "2024-12-29T16:00:00.000+00:00",
            "children": [],
            "deleted": false,
            "pagenum": 0,
            "pagesize": 0
          }
        ],
        "deleted": false,
        "pagenum": 0,
        "pagesize": 0
      }
    ],
    "pageNum": 1
  }
}

        弄清楚我们的想法后,接下来是代码实现:

  1. controller层:
    /**
         * 查询所有菜单
         * @param queryMenuListDTO
         * @return
         */
        @PostMapping("/getAllMenu")
        public ApiResponse getAllMenu(@RequestBody QueryMenuListDTO queryMenuListDTO){
             return ApiResponse.success(menuService.getAllMenu(queryMenuListDTO));
        }

  2. service层:
    /**
         * 获取所有菜单
         * @param queryMenuListDTO
         * @return
         */
        @Override
        public Map getAllMenu(QueryMenuListDTO queryMenuListDTO) {
            log.info("getAllMenu 开始执行,参数:{}", queryMenuListDTO);
            // 创建分页对象
            Page<QueryMenuListDTO> page = new Page<>(queryMenuListDTO.getPageNum(), queryMenuListDTO.getPageSize());
            try {
                // 执行分页查询
                Page<QueryMenuListDTO> menuPage = menuMapper.selectMenusWithPagination1(page, queryMenuListDTO);
                List<QueryMenuListDTO> allMenus = menuPage.getRecords();
                // 打印分页信息用于调试
                log.info("分页信息 - 当前页:{}, 每页大小:{}, 总记录数:{}",
                        menuPage.getCurrent(), menuPage.getSize(), menuPage.getTotal());
                if (allMenus.isEmpty()) {
                    Map<String, Object> emptyResult = new HashMap<>();
                    emptyResult.put("total", 0);
                    emptyResult.put("list", new ArrayList<>());
                    emptyResult.put("pageNum", queryMenuListDTO.getPageNum());
                    emptyResult.put("pageSize", queryMenuListDTO.getPageSize());
                    return emptyResult;
                }
                // 构建菜单树
                Map<String, QueryMenuListDTO> menuMap = new HashMap<>();
                for (QueryMenuListDTO menu : allMenus) {
                    menu.setChildren(new ArrayList<>());
                    menuMap.put(menu.getId(), menu);
                }
                List<QueryMenuListDTO> menuTree = new ArrayList<>();
                for (QueryMenuListDTO menu : allMenus) {
                    String pid = menu.getPid();
                    if (pid == null || pid.trim().isEmpty()) {
                        menuTree.add(menu);
                    } else {
                        QueryMenuListDTO parentMenu = menuMap.get(pid);
                        if (parentMenu != null) {
                            parentMenu.getChildren().add(menu);
                        } else {
                            log.warn("找不到菜单[{}]的父菜单[{}],作为一级菜单处理", menu.getName(), pid);
                            menuTree.add(menu);
                        }
                    }
                }
                // 构建返回结果
                Map<String, Object> result = new HashMap<>();
                result.put("total", menuPage.getTotal());
                result.put("list", menuTree);
                result.put("pageNum", menuPage.getCurrent());
                result.put("pageSize", menuPage.getSize());
    
                log.info("getAllMenu 执行完成,返回数据大小:{}", menuTree.size());
                return result;
    
            } catch (ServiceException e) {
                log.error("getAllMenu 执行异常", e);
                throw new ServiceException("获取菜单失败");
            }
        }

  3. Mapper层:
    <select id="selectMenusWithPagination1" resultType="org.xxx.domain.dto.QueryMenuListDTO">
            SELECT DISTINCT m.* ,t.name as tenant_name
            FROM ycb_server_admin.tb_function m
            LEFT JOIN ycb_server_admin.tb_tenant t ON m.tenant_id = t.id
            WHERE m.deleted = 0
            <if test="queryMenuListDTO.tenantId != null and queryMenuListDTO.tenantId != ''">
                AND m.tenant_id = #{queryMenuListDTO.tenantId}
            </if>
            <if test="queryMenuListDTO.id != null and queryMenuListDTO.id != ''">
                AND m.id = #{queryMenuListDTO.id}
                || m.pid = #{queryMenuListDTO.id}
            </if>
            <if test="queryMenuListDTO.type != null and queryMenuListDTO.type != ''">
                AND m.type = #{queryMenuListDTO.type}
            </if>
            ORDER BY m.ordernum ASC, m.create_time ASC
        </select>

  4. 总结:关键点在于构建菜单树,我是有一个字段pid,如果a数据的id在数据库中查询pid,查到有数据的pid等于该id,那他就有子菜单,把该数据存为children数据里,如果数据的pid字段没有数据,那么就存为一级菜单(父)来构建,最后保存到一起返回这个菜单树,最终的效果在最上面已经展示了,效果还可以,下次还用哈哈哈
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值