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

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代码到这里就结束了,希望对有需要的码友有帮助,如果文章中有任何语义解释错误的地方还请各位海涵!!欢迎大佬批评指正

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot+SpringSecurity+Vue中实现动态路由的过程如下: 1. 在后端(SpringBoot)中,首先需要定义一个权限表,用于存储所有的权限信息,包括权限名称、权限标识等。 2. 在前端(Vue)中,需要定义一个路由表,用于存储所有的路由信息,包括路由路径、组件名称等。 3. 后端需要提供一个接口,用于获取当前用户的权限列表。该接口会根据用户的角色查询对应的权限,并返回给前端。 4. 前端在登录成功后,会调用后端接口获取当前用户的权限列表,并将权限列表存储到本地(如localStorage或vuex)中。 5. 前端在路由跳转时,会根据当前用户的权限列表动态生成路由。可以通过遍历权限列表,根据权限标识匹配路由表中的路由信息,将匹配到的路由添加到路由表中。 6. 前端在生成路由后,需要使用Vue Router的addRoutes方法将动态生成的路由添加到路由表中。 7. 前端在路由跳转时,会根据用户的权限判断是否有权限访问该路由。可以通过导航守卫的beforeEach方法,在路由跳转前进行权限判断。 8. 后端可以使用Spring Security的注解对接口进行权限控制。可以通过在接口上添加注解,指定需要的权限才能访问该接口。 9. 后端在接口调用时,可以通过从redis中获取当前用户的权限列表,并进行权限判断。 10. 前端和后端通过接口交互,实现动态路由的权限控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值