SpringBoot+layuimini实现左侧菜单动态展示

news2024/9/21 7:31:51

layuimini左侧菜单动态显示

首先我们看一下layuimini的原有菜单显示格式

{
  "homeInfo": {
    "title": "首页",
    "href": "page/welcome-2.html?t=2"
  },
  "logoInfo": {
    "title": "LAYUI MINI",
    "image": "images/logo.png",
    "href": ""
  },
  "menuInfo": [
    {
      "title": "系统管理",
      "icon": "fa fa-address-book",
      "href": "",
      "target": "_self",
      "child": [
        {
          "title": "权限管理",
          "href": "",
          "icon": "fa fa-home",
          "target": "_self",
          "child": [
            {
              "title": "账户信息管理",
              "href": "page/account.html",
              "icon": "fa fa-tachometer",
              "target": "_self"
            },
            {
              "title": "主页二",
              "href": "page/welcome-2.html",
              "icon": "fa fa-tachometer",
              "target": "_self"
            },
            {
              "title": "三",
              "href": "page/welcome-3.html",
              "icon": "fa fa-tachometer",
              "target": "_self"
            }
          ]
        }
      ]
    }
  ]
}

接下来是HTML显示页面

var options = {
            //后端动态生成的接口
            // iniUrl: "/auth/getResources",    // 初始化接口
            //原有的接口链接
            iniUrl:"api/init.json",
            clearUrl: "api/clear.json", // 缓存清理接口
            urlHashLocation: true,      // 是否打开hash定位
            bgColorDefault: false,      // 主题默认配置
            multiModule: false,          // 是否开启多模块
            menuChildOpen: false,       // 是否默认展开菜单
            loadingTime: 0,             // 初始化加载时间
            pageAnim: true,             // iframe窗口动画
            maxTabNum: 20,              // 最大的tab打开数量
        };
        miniAdmin.render(options);

这是layuimini给出的左侧菜单
在这里插入图片描述

接下来开始我们的改变,将静态菜单改为动态菜单

1.数据库准备,这里我们需要四张数据库表
在这里插入图片描述

  1. sys_role_resource
    在这里插入图片描述 在这里插入图片描述

2.sys_role

在这里插入图片描述
在这里插入图片描述
3.sys_user
在这里插入图片描述
在这里插入图片描述
4.sys_resource
在这里插入图片描述
在这里插入图片描述

后端代码块实现(后端主要需要的实现类就只要,资源和角色资源两个类即可)

1.ResourceEntity

package com.example.erp_project.entity;

import lombok.Data;

import java.util.List;

/**
 * @author Lolo don‘t feel
 */
@Data
public class ResourceEntity {
    //资源id编号
    private Integer resourceId;
    //资源名称
    private String title;
    //资源图标
    private String icon;
    //页面资源跳转链接
    private String href;
    //父级资源
    private Integer parentId;
    //排序
    private Integer  sort;
    //ztree会检查返回的数据中有没有 checked 属性 如果为true就会把这个节点设为选中状态
    private String checked;
    //子菜单,这里可以使用vo类来代替
    private List<ResourceEntity> child;

}

2.RoleResourceEntity

package com.example.erp_project.entity;

import lombok.Data;

import java.util.List;

/**
 * @author Lolo don‘t feel
 */
@Data
public class RoleResourceEntity {
    //id编号
    private Integer roleResourceId;
    //权限id
    private Integer roleId;
    //资源id
    private Integer resourceId;

}

3.loginConreoller
在这里插入图片描述

  /*
    * 根据角色id获取对应的权限
    * */
    @GetMapping("/getResources")
    // 定义一个方法,用于获取资源信息
    public Map<String, Object> getResources(HttpSession session) {
        // 创建一个map对象,用于存储资源信息
        Map<String, Object> map = new HashMap<>();
        // 创建一个homeInfo对象,用于存储首页信息
        Map<String, Object> homeInfo = new HashMap<>();
        homeInfo.put("title", "首页");
        homeInfo.put("icon", "fa fa-home");
        homeInfo.put("href", "welcome");
        // 将homeInfo对象添加到map中
        map.put("homeInfo", homeInfo);
        // 创建一个logoInfo对象,用于存储logo信息
        Map<String, Object> logoInfo = new HashMap<>();
        logoInfo.put("title", "暖意ERP");
        logoInfo.put("image", "images/logo.png");
        logoInfo.put("href", "");
        // 将logoInfo对象添加到map中
        map.put("logoInfo", logoInfo);
        // 创建一个menuInfo列表,用于存储菜单信息
        List<Object> menuInfo = new ArrayList<>();
        // 获取当前登录人保存的getRoleId信息
        Integer roleId = (Integer) session.getAttribute("roleId");
        // 打印测试当前登陆的角色id是多少是否与数据库中id相对应。
        System.out.println(roleId);
        // 根据roleId查询后面对应的资源菜单
        List<ResourceEntity> resource = roleResourceService.getAllResourcesByRoleId(roleId);
        // 测试查询到的菜单
        System.out.println(resource);
        // 遍历资源列表,将资源添加到menuInfo中
        resource.forEach(t -> {
            menuInfo.add(t);
            System.out.println(t);
        });
        // 将menuInfo添加到map中
        map.put("menuInfo", menuInfo);
        // 返回map对象
        return map;
    }

4.建立service接口

//根据角色id查询资源数据
  List<ResourceEntity> getAllResourcesByRoleId(Integer roleId);

5.service实现类

import com.example.erp_project.entity.RoleResourceEntity;
import com.example.erp_project.mapper.RoleResourceMapper;
import com.example.erp_project.service.RoleResourceService;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Lolo don‘t feel
 */
@Service
public class RoleResourceServiceImpl implements RoleResourceService {

    // 定义一个私有的RoleResourceMapper对象,用于操作角色资源映射表
    private final RoleResourceMapper roleResourceMapper;

    // 构造函数,接收一个RoleResourceMapper对象作为参数,并将其赋值给当前对象的roleResourceMapper属性
    public RoleResourceServiceImpl(RoleResourceMapper roleResourceMapper) {
        this.roleResourceMapper = roleResourceMapper;
    }


    @Override
    // 获取指定角色ID的所有资源列表
    public List<ResourceEntity> getAllResourcesByRoleId(Integer roleId) {
        // 这里返回的resourceEntityList 没有实现排序
        // 以后 可以考虑下 返回 resourceEntityList之前 根据resource对象的sort进行排序
        // 那么左侧显示的菜单就可以排序了
        List<ResourceEntity> resourceEntityList = new ArrayList<>();
        // roleResourceEntity里面就是一个中间表 两个字段 roleId resourceId 关联起来
        List<RoleResourceEntity> roleResourceEntities = roleResourceMapper.selectRoleResourceByRoleId(roleId);
        System.out.println("impl输出测试目录"+roleResourceEntities);
        // 新建一个对象数组继续宁条件判断资源
        // 用for循环遍历,如果i=0且小于资源则菜单资源进行想相加在循环
        if (roleResourceEntities != null && roleResourceEntities.size() > 0) {
            List<ResourceEntity> noChildrenResourceEntities = new ArrayList<>();
            // 进行资源判断是否为空或者大于0
            for (int i = 0; i < roleResourceEntities.size(); i++) {
                // 获取roleResource(资源中间表)中的resourceId(资源id)
                ResourceEntity resourceEntity = roleResourceMapper.getResourceById(roleResourceEntities.get(i).getResourceId());
                // 就是根据这个登陆者的roleId 所拥有的资源取出来
                noChildrenResourceEntities.add(resourceEntity);
            }
            for (int i = 0; i < noChildrenResourceEntities.size(); i++) {
                if (noChildrenResourceEntities.get(i).getParentId() == 0) {
                    // 说明这个菜单是一级菜单 没有上一级菜单
                    // 如果这里不为0 表示这个菜单是二级菜单 或者三级菜单 ParentId对应了属于哪个上级菜
                    ResourceEntity resourceEntity = new ResourceEntity();
                    // 把这个一级菜单取出来
                    resourceEntity = noChildrenResourceEntities.get(i);
                    List<ResourceEntity> resourceEntities = new ArrayList<>();
                    // for把所有菜单过一遍
                    for (int j = 0; j < noChildrenResourceEntities.size(); j++)
                    {
                        // 如果有菜单属于这个一级菜单
                        if (Objects.equals(noChildrenResourceEntities.get(j).getParentId(), noChildrenResourceEntities.get(i).getResourceId())) {
                            ResourceEntity resourceEntity2 = new ResourceEntity();
                            // 取出这个二级菜单
                            resourceEntity2 = noChildrenResourceEntities.get(j);
                            resourceEntities.add(resourceEntity2);
                        }
                    }
                    resourceEntity.setChild(resourceEntities);
                    resourceEntityList.add(resourceEntity);
                }
            }
        }
        // 下面是根据资源的sort进行排序 升序排列 这样左侧菜单就会按照升序排列
        Collections.sort(resourceEntityList, new Comparator<ResourceEntity>() {
            @Override
            public int compare(ResourceEntity o1, ResourceEntity o2) {
                return o1.getSort().compareTo(o2.getSort());
            }
        });
        return resourceEntityList;
    }


}

6.mapper接口

public interface RoleResourceMapper {
    List<RoleResourceEntity> selectRoleResourceByRoleId(Integer roleId);
    }

7.mybatis

 <select id="selectRoleResourceByRoleId" resultType="com.example.erp_project.entity.RoleResourceEntity">
        select *
        from sys_role_resource
        where roleId = #{roleId}
    </select>

8.前端页面代码修改
在这里插入图片描述
9.效果图
在这里插入图片描述
OK代码到这里就结束了,希望对有需要的码友有帮助,如果文章中有任何语义解释错误的地方还请各位海涵!!欢迎大佬批评指正

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1616946.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

苍穹外卖day8(2)用户下单、微信支付

文章目录 前言一、用户下单1. 业务流程2. 接口设计3. 数据库设计3.1 订单表orders3.2 订单明细表 order_detail 4. 代码实现 二、订单支付 前言 用户下单 因为订单信息中包含了其他业务中的数据&#xff0c;在逻辑处理中涉及了多个其他业务&#xff0c;比如要判断地址簿、购物…

ThreeJs模拟工厂生产过程一

上节我们已经通过绘制两条长方体和多个圆柱体成功绘制出传送带&#xff0c;今天根据之前的传送带做个简单的工厂车间生产的demo&#xff0c;然后再不断完善它。 首先分析下工厂生产有哪些部分组成&#xff0c;工厂内是产线&#xff0c;产线需要有设备&#xff0c;传送带以及生产…

要养生也要时尚,益百分满足你的所有需求

要养生也要时尚&#xff0c;益百分满足你的所有需求 艾灸是个好东西&#xff0c;尤其是在近几年的时候&#xff0c;艾灸就像一阵浪潮席卷进了人们的日常生活之中&#xff0c;我们可以在街边看到大大小小的艾灸馆&#xff0c;有些评价比较高的艾灸馆门前甚至还排起了长长的队伍…

Langchain入门到实战-第四弹

Langchain入门到实战 Langchain中的提示词官网地址Langchain概述Langchain的提示词用法更新计划 Langchain中的提示词 语言模型提示模板是预定义的生成语言模型提示的方法。模板可能包括指令、少样本示例、特定任务的上下文和问题。LangChain 提供了创建和处理提示模板的工具。…

TS-namespace(命名空间)#记录

一、命名空间 1、ts 中的 “命名空间” 就是之前的 “内部模块”&#xff0c;任何使用 module 关键字来声明一个内部模块的地方都应该使用 namespace 关键字来替换。 // ts 中的“内部模块” &#xff08;废弃&#xff09; module X { }// ts 中的“命名空间” &#xff08…

系统启动修复和SYSTEM丢失损坏故障处理

系统启动修复和SYSTEM丢失损坏故障处理 一、问题描述 你的电脑/设备需要修复。无法加载应用程序或操作系统&#xff0c;原因是所需文件丢失或包含错误。 文件:\Windows\system32\winload.exe 错误代码: 0xc000000e 二、问题分析 1.查询winload.exe是win7或者win10以上系统…

NX二次开发UF_LAYER(图层相关操作)常用函数

目录 一、概述 二、函数的介绍 2.1 UF_LAYER_ask_category_info &#xff08;查询图层类别信息&#xff09; 2.2 UF_LAYER_ask_category_tag&#xff08;查询图层类别TAG&#xff09; 2.3 UF_LAYER_ask_status&#xff08;查询图层的状态&#xff09; 2.4 UF_LAYER_ask_wo…

护眼灯到底有用吗?实用护眼灯十大品牌推荐

护眼灯有用吗&#xff1f;答案无疑是肯定的。选购到一款合适的护眼台灯&#xff0c;益处多多。这些台灯经过精心设计&#xff0c;运用变频电子镇流器技术&#xff0c;显著提高了光线的频率&#xff0c;使之远超人眼的反应速度&#xff0c;从而有效缓解视觉疲劳。此外&#xff0…

适用于手机蓝牙的热敏晶体FA1612AS

EPSON推出的一款1612小尺寸无源热敏晶体:FA1612AS。FA1612AS的额定频率为38.4Mhz的晶体单元&#xff0c;采用无铅材料&#xff0c;符合ROHS标准&#xff0c;内置热敏电阻&#xff0c;可用于移动电话&#xff0c;蓝牙等。热敏晶体FA1612AS的产品特性:额定频率:38.4MHZ外部尺寸规…

Git 仓库内容操作

Git 仓库内容操作 | CoderMast编程桅杆Git 仓库内容操作 添加文件到暂存区 使用如下指令将工作区的文件添加到暂存区&#xff0c;告诉 Git 在下次 commit 时哪些文件做出了修改。 commit 指令详看后续 添加一个或多个文件到暂存区&#xff1a; 添加指定目录到暂存区 添加当前目…

山海鲸电力看板:运维数据一目了然

在信息化高速发展的今天&#xff0c;电力行业的运维管理也迎来了前所未有的变革。山海鲸可视化智慧电力运维可视化看板&#xff0c;以其独特的数据整合能力和直观的可视化效果&#xff0c;成为了电力行业运维管理的得力助手&#xff0c;为电力的稳定运行提供了强大的技术支撑。…

namesilo注册与域名购买教程

namesilo 是目前价格较便宜的国外域名平台&#xff0c;Paypal、Visa 等多种付款方式&#xff0c;还可以免费使用域名隐私保护&#xff0c;性价比非常之高。 1. 访问namesilo.com并注册用户账号。 邮箱可以填 QQ 邮箱&#xff0c;国家选择 China&#xff0c;注册信息尽量真实。…

开发同城O2O跑腿系统源码:构建高效便捷的本地服务平台教程

为了满足用户对便捷的需求&#xff0c;今天我们将一同探讨如何开发一个高效便捷的同城O2O跑腿系统&#xff0c;以构建一个功能全面、操作简单的本地服务平台。 一、确定需求和功能 在开发同城O2O跑腿系统之前&#xff0c;首先需要明确系统的需求和功能。用户可以通过该系统发布…

Mamba模型原理与代码精讲

课程链接&#xff1a;Mamba模型原理与代码精讲_在线视频教程-CSDN程序员研修院 Mamba模型是最近提出的可匹敌甚至超越Transformer的前沿序列模型。 Mamba引入了选择性状态空间模型(SSM), 允许SSM参数成为输入的函数&#xff0c;使得模型能够根据输入token沿着序列长度维度选择…

Ubuntu下使用VisualStudioCode进行Java开发

0-1开始Java语言编程之路 一、Ubuntu下Java语言环境搭建 二、Ubuntu下Docker环境安装 三、使用Docker搭建本地Nexus Maven私有仓库 四、Ubuntu下使用VisualStudioCode进行Java开发 Visual Studio Code 下载 点击这个链接Visual Studio Code&#xff0c;进入VisualStudioCode的…

未来已来:解锁AGI的无限潜能与挑战

未来已来&#xff1a;解锁AGI的无限潜能与挑战 引言 假设你有一天醒来&#xff0c;发现你的智能手机不仅提醒你今天的日程&#xff0c;还把你昨晚做的那个奇怪的梦解释了一番&#xff0c;并建议你可能需要减少咖啡摄入量——这不是科幻电影的情节&#xff0c;而是人工通用智能…

ubuntu apt update:The repository ‘xxx‘ is not signed.报错解决办法(未解决)

文章目录 报错原因及解决办法 报错 rootjax:~# apt update Get:1 file:/var/cuda-repo-l4t-11-4-local InRelease [1575 B] Get:2 file:/var/cudnn-local-repo-ubuntu2004-8.4.1.50 InRelease [1575 B] Get:1 file:/var/cuda-repo-l4t-11-4-local InRelease [1575 B] Get:2 …

C/C++ 入门(7)string类(STL)

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 请多多指教&#xff01; 目录 一、标准库中的string 1、了解 2、string类常用接口说明 1、常见的构造函数 2、容量操作 ​编辑 3、访问及遍历操作 4、修改操作 5、非成员函数 二、string类实现 …

电脑回收站恢复,3个靠谱方法(2024版)

“想问问大家&#xff0c;回收站里丢失的文件还能恢复吗&#xff1f;我一不小心就把电脑回收站里的重要数据丢失了&#xff0c;现在不知道怎么操作才能恢复它了。希望大家帮帮我。” 在日常使用电脑的过程中&#xff0c;回收站是我们经常打交道的一个功能&#xff0c;它能帮助我…

【Python创建专属二维码】

1、在PyCharm | Settings | Python Interpreter中添加PDL、PILLOW(注意解释器版本) 2、代码 from PIL import Image import qrcodedef main():# QRCode&#xff08;&#xff09;创建一个对象&#xff1a;qr qrcode.QRCode(version5, error_correctionqrcode.constants.ERROR_…