开发用户导航栏和权限信息接口

我们先来开发菜单的接口,因为这3个表:用户表、角色表、菜单表,才有菜单表是不需要通过其他表来获取信息的。比如用户需要关联角色,角色需要关联菜单,而菜单不需要主动关联其他表。因此菜单表的增删改查是最简单的。

再回到我们的前端项目,登录完成之后我们通过JWT获取项目的导航菜单和权限,那么接下来我们就先编写这个接口。

获取菜单导航和权限的链接是/sys/menu/nav,然后我们的菜单导航的json数据应该是这样的:

{
   title: '角色管理',
   icon: 'el-icon-rank',
   path: '/sys/roles',
   name: 'SysRoles',
   component: 'sys/Role',
   children: []
}

然后返回的权限数据应该是个数组:

["sys:menu:list","sys:menu:save","sys:user:list"...]

注意导航菜单那里有个children,也就是子菜单,是个树形结构,因为我们的菜单可能这样:

系统管理 - 菜单管理 - 添加菜单

可以看到这就已经有3级了菜单了。
所以在打代码时候要注意这个关系的关联。我们的SysMenu实体类中有个parentId,但是没有children,因此我们可以在SysMenu中添加一个children,当然了其实不添加也可以,因为我们也需要一个dto,这样我们才能按照上面json数据格式返回。

我们还是来添加一个children吧:

@Data
@EqualsAndHashCode(callSuper = true)
public class SysMenu extends BaseEntity {
   ...
   @TableField(exist = false)
   private List<SysMenu> children = new ArrayList<>();
}

然后我们也先来定义一个SysMenuDto吧,知道要返回什么样的数据,我们就只需要去填充数据就好了

@Data
public class SysMenuDto implements Serializable {
   private Long id;
   private String title;
   private String icon;
   private String path;
   private String name;
   private String component;
   List<SysMenuDto> children = new ArrayList<>();
}

ok,我们来开始我们的编码

/**
 * 获取当前用户的菜单栏以及权限
 */
@GetMapping("/nav")
public Result nav(Principal principal) {
   String username = principal.getName();
   SysUser sysUser = sysUserService.getByUsername(username);
   // ROLE_Admin,sys:user:save
   String[] authoritys = StringUtils.tokenizeToStringArray(
         sysUserService.getUserAuthorityInfo(sysUser.getId())
         , ",");
   return Result.succ(
         MapUtil.builder()
               .put("nav", sysMenuService.getcurrentUserNav())
               .put("authoritys", authoritys)
               .map()
   );
}

方法中Principal principal表示注入当前用户的信息,getName就可以获取当当前用户的用户名了。sysUserService.getUserAuthorityInfo方法我们之前已经说过了,就在我们登录完成或者身份认证时候需要返回用户权限时候编写的。然后通过StringUtils.tokenizeToStringArray把字符串通过逗号分开组成数组形式。
重点在与sysMenuService.getcurrentUserNav,获取当前用户的菜单导航,

@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
   ...

   /**
    * 获取当前用户菜单导航
    */
   @Override
   public List<SysMenuDto> getcurrentUserNav() {
      String username = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

      SysUser sysUser = sysUserService.getByUsername(username);

      // 获取用户的所有菜单
      List<Long> menuIds = sysUserMapper.getNavMenuIds(sysUser.getId());

      List<SysMenu> menus = buildTreeMenu(this.listByIds(menuIds));
      return convert(menus);
   }

   /**
    * 把list转成树形结构的数据
    */
   private List<SysMenu> buildTreeMenu(List<SysMenu> menus){
      List<SysMenu> finalMenus = new ArrayList<>();
      for (SysMenu menu : menus) {

         // 先寻找各自的孩子
         for (SysMenu e : menus) {
            if (e.getParentId() == menu.getId()) {
               menu.getChildren().add(e);
            }
         }
         // 提取出父节点
         if (menu.getParentId() == 0L) {
            finalMenus.add(menu);
         }
      }
      return finalMenus;
   }

   /**
    * menu转menuDto
    */
   private List<SysMenuDto> convert(List<SysMenu> menus) {
      List<SysMenuDto> menuDtos = new ArrayList<>();
      menus.forEach(m -> {
         SysMenuDto dto = new SysMenuDto();
         dto.setId(m.getId());
         dto.setName(m.getPerms());
         dto.setTitle(m.getName());
         dto.setComponent(m.getComponent());
         dto.setIcon(m.getIcon());
         dto.setPath(m.getPath());
         if (m.getChildren().size() > 0) {
            dto.setChildren(convert(m.getChildren()));
         }
         menuDtos.add(dto);
      });
      return menuDtos;
   }
}

接口中sysUserMapper.getNavMenuIds我们之前就已经写过的了,通过用户id获取菜单的id,然后后面就是转成树形结构,buildTreeMenu方法的思想很简单,我们现实把菜单循环,让所有菜单先找到各自的子节点,然后我们在把最顶级的菜单获取出来,这样顶级下面有二级,二级也有自己的三级。最后就是convert把menu转成menuDto。这个比较简单,就不说了。
好了,导航菜单已经开发完毕,我们来写菜单管理的增删改查,因为菜单列表也是个树形接口,这次我们就不是获取当前用户的菜单列表的,而是所有菜单然后组成树形结构,一样的思想,数据不一样而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值