后端代码:

若依框架登陆的时候会发送两个请求:getinfo(获取角色和权限)和getrouters(获取路由,路由其实就是边上的菜单),下面是这两个请求的代码。大家其实可以去源码里面去找下这两个controller,自己看下。

/**
 * 获取用户信息(获取角色信息和权限信息)
 * 
 * @return 用户信息
 */
@GetMapping("getInfo")
public AjaxResult getInfo()
{

    SysUser user = SecurityUtils.getLoginUser().getUser();
    // 角色集合
    Set<String> roles = permissionService.getRolePermission(user);
    // 权限集合
    Set<String> permissions = permissionService.getMenuPermission(user);
    AjaxResult ajax = AjaxResult.success();
    ajax.put("user", user);
    ajax.put("roles", roles);
    ajax.put("permissions", permissions);
    return ajax;
}

/**
 * 获取路由信息
 * 
 * @return 路由信息
 */
@GetMapping("getRouters")
public AjaxResult getRouters()
{
    Long userId = SecurityUtils.getUserId();
    List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
    return AjaxResult.success(menuService.buildMenus(menus));
}

获取用户信息我就不说了,点进去selectMenuTreeByUserId方法,这个方法不是核心。

@Override
public List<SysMenu> selectMenuTreeByUserId(Long userId)
{
    List<SysMenu> menus = null;
    if (SecurityUtils.isAdmin(userId))
    {
        menus = menuMapper.selectMenuTreeAll();
    }
    else
    {
        menus = menuMapper.selectMenuTreeByUserId(userId);
    }
    return getChildPerms(menus, 0);
}

点进去getChildPerms方法,开始遍历菜单。这个方法只负责将getParentId为0的放到集合中,集合中最终就会有四个菜单,有人就会奇怪了,有那么多菜单,怎么只有四个,其实就是其他菜单都放到这四个菜单的子菜单集合属性中了,每个菜单都会有子菜单集合属性,一层嵌套一层。

public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId)
{
    List<SysMenu> returnList = new ArrayList<SysMenu>();
    for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext();)
    {
        SysMenu t = (SysMenu) iterator.next();
        // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
        if (t.getParentId() == parentId)
        {
            recursionFn(list, t);
            returnList.add(t);
        }
    }
    return returnList;
}

下面就是循环了,if就是循环出口了。

private void recursionFn(List<SysMenu> list, SysMenu t)
{
    // 得到子节点列表
    List<SysMenu> childList = getChildList(list, t);
    t.setChildren(childList);
    for (SysMenu tChild : childList)
    {
        //循环出口,无子节点即退出
        if (hasChild(list, tChild))
        {
            recursionFn(list, tChild);
        }
    }
}


这是获得子菜单

/**
 * 得到子节点列表
 */
private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t)
{
    List<SysMenu> tlist = new ArrayList<SysMenu>();
    Iterator<SysMenu> it = list.iterator();
    while (it.hasNext())
    {
        SysMenu n = (SysMenu) it.next();
        if (n.getParentId().longValue() == t.getMenuId().longValue())
        {
            tlist.add(n);
        }
    }
    return tlist;
}

前端代码:

前端我不太会,但是就是在下面代码遍历的。这段代码在源码中的路径:src\layout\components\Sidebar\index.vue

<sidebar-item
    v-for="(route, index) in sidebarRouters"
    :key="route.path  + index"
    :item="route"
    :base-path="route.path"
/>
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐