页面树状结构展示

在springboot项目中,我们经常需要把界面中的菜单来进行树状结构来展示,层次分明,条例清晰,本文章将从controller层到mapper层逐一编写代码来实现页面的树状结构展示

Controller层

/**  以下为controller层代码编写 

/**
 * 系统权限控制层
 */
@Api(tags = "系统权限管理")
@RequestMapping ("sys/mene")
@RestController
public Result<MenuAndAuth> loadUserMenuAndAuth(){
        //获取当前登录用户的标识   //之前在各个资源服务器之前配置了token转换器,存放到了security上下文当中
        //从security上下文当中获取用户标识
        SecurityUser loginUser = AuthUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        //根据用户标识查询操作权限集合
        Set<String> loginUserPerms = AuthUtils.getLoginUserPerms();
        //根据用户标识查询菜单权限集合
        Set<SysMenu> sysMenusPerms = sysMenuService.queryUserMenuListByUserId(userId);
        //把两种权限集合封装到视图对象,来进行返回
        MenuAndAuth menuAndAuth = new MenuAndAuth(sysMenusPerms, loginUserPerms);
        return  Result.success(menuAndAuth);
    }
}

 Service层(主要操作)

以下为Service层代码编写

@Service
@CacheConfig(cacheNames = "com.powernode.service.impl.SysMenuServiceImpl")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService{

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    @Cacheable(key = "#loginUserId")
    public Set<SysMenu> queryUserMenuListByUserId(Long loginUserId) {
        // 根据用户标识查询菜单权限集合
        Set<SysMenu> menus = sysMenuMapper.selectUserMenuListByUserId(loginUserId);
        // 将菜单权限集合的数据转换为树结构(即:数据结构应该为层级关系的)

        return transformTree(menus,0L);
    }

    /**
     * 集合转换为树结构   很常见  让前端展示的页面是树状结构,分层显示
     *  1.已知菜单深度 <=2
     *
     *  2.未知菜单深度  可能会一直往下写
     *
     * @param menus
     * @param pid
     * @return
     */
    private Set<SysMenu> transformTree(Set<SysMenu> menus, Long pid) {
        // 已知菜单深度<=2
        // 从菜单集合中获取根节点集合    数据有,只是把表现形式换一下
        /*Set<SysMenu> roots = menus.stream()
                .filter(m -> m.getParentId().equals(pid))
                .collect(Collectors.toSet());
        // 循环遍历根节点集合
        roots.forEach(root -> {
            // 从菜单集合中过滤出它的父节点值与当前根节点的id值一致的菜单集合
            Set<SysMenu> child = menus.stream()
                    .filter(m -> m.getParentId().equals(root.getMenuId()))
                    .collect(Collectors.toSet());
            root.setList(child);
        });*/

        // 未知菜单深度
        // 获取根节点集合
        Set<SysMenu> roots = menus.stream()
                .filter(m -> m.getParentId().equals(pid))
                .collect(Collectors.toSet());
        // 循环节点集合  利用递归,把子节点继续当为根节点,查找所有节点中父节点的id与当前
        //根节点的id相同的节点,并setlist  
        roots.forEach(r -> r.setList(transformTree(menus,r.getMenuId())));
        return roots;
    }
}

 SysMenu类  (菜单类)

/**
    * 菜单管理
    */
@ApiModel(value="com-powernode-domain-SysMenu")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "sys_menu")
public class SysMenu implements Serializable {
    @TableId(value = "menu_id", type = IdType.AUTO)
    @ApiModelProperty(value="")
    private Long menuId;

    /**
     * 父菜单ID,一级菜单为0
     */
    @TableField(value = "parent_id")
    @ApiModelProperty(value="父菜单ID,一级菜单为0")
    private Long parentId;

    /**
     * 菜单名称
     */
    @TableField(value = "name")
    @ApiModelProperty(value="菜单名称")
    private String name;

    /**
     * 菜单URL
     */
    @TableField(value = "url")
    @ApiModelProperty(value="菜单URL")
    private String url;

    /**
     * 授权(多个用逗号分隔,如:user:list,user:create)
     */
    @TableField(value = "perms")
    @ApiModelProperty(value="授权(多个用逗号分隔,如:user:list,user:create)")
    private String perms;

    /**
     * 类型   0:目录   1:菜单   2:按钮
     */
    @TableField(value = "type")
    @ApiModelProperty(value="类型   0:目录   1:菜单   2:按钮")
    private Integer type;

    /**
     * 菜单图标
     */
    @TableField(value = "icon")
    @ApiModelProperty(value="菜单图标")
    private String icon;

    /**
     * 排序
     */
    @TableField(value = "order_num")
    @ApiModelProperty(value="排序")
    private Integer orderNum;


    // 子节点集合
    @TableField(exist = false)  //告诉mybatisplus 该属性没有在数据库表中存在映射
    @ApiModelProperty("子节点集合")
    private Set<SysMenu> list;

    private static final long serialVersionUID = 1L;
}

Mapper层 

Mapper层

public interface SysMenuMapper extends BaseMapper<SysMenu> {

    /**
     * 根据用户标识查询菜单权限集合
     * @param loginUserId
     * @return
     */
    Set<SysMenu> selectUserMenuListByUserId(Long loginUserId);
}

Mapper.xml文件

<select id="selectUserMenuListByUserId" resultType="com.powernode.domain.SysMenu">
    SELECT
      t1.*
    FROM
      sys_menu t1
        JOIN sys_role_menu t2
        JOIN sys_user_role t3 ON ( t1.menu_id = t2.menu_id AND t2.role_id = t3.role_id )
    WHERE
      t3.user_id = #{loginUserId}
      AND ( t1.type = 0 OR t1.type = 1 );
  </select>

封装的返回给前端的视图对象



/**
 * 菜单和操作权限对象
 */
@ApiModel("菜单和操作权限对象")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MenuAndAuth {

    @ApiModelProperty("菜单权限集合")
    private Set<SysMenu> menuList;
    @ApiModelProperty("操作权限集合")
    private Set<String> authorities;
}

 

以上即为页面展示树状结构的全部代码实现,主要为在service层中对查询到的菜单集合进行操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值