fix: 超级管理员不显示新增的菜单

之前显示因为系统管理员角色绑定菜单,超级管理员查询的时候无视条件查询的是系统管理员和其他角色绑定的菜单合集
This commit is contained in:
haoxr
2024-12-16 17:06:43 +08:00
parent eb0a96358e
commit fe163b7275
6 changed files with 51 additions and 141 deletions

View File

@@ -57,9 +57,8 @@ public class MenuController {
@Operation(summary = "菜单路由列表") @Operation(summary = "菜单路由列表")
@GetMapping("/routes") @GetMapping("/routes")
public Result<List<RouteVO>> listRoutes() { public Result<List<RouteVO>> getCurrentUserRoutes() {
Set<String> roles = SecurityUtils.getRoles(); List<RouteVO> routeList = menuService.getCurrentUserRoutes();
List<RouteVO> routeList = menuService.listRoutes(roles);
return Result.success(routeList); return Result.success(routeList);
} }

View File

@@ -1,7 +1,6 @@
package com.youlai.boot.system.mapper; package com.youlai.boot.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.youlai.boot.system.model.bo.RouteBO;
import com.youlai.boot.system.model.entity.Menu; import com.youlai.boot.system.model.entity.Menu;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@@ -20,7 +19,9 @@ public interface MenuMapper extends BaseMapper<Menu> {
/** /**
* 获取菜单路由列表 * 获取菜单路由列表
*
* @param roleCodes 角色编码集合
*/ */
List<RouteBO> listRoutes(Set<String> roles); List<Menu> getMenusByRoleCodes(Set<String> roleCodes);
} }

View File

@@ -1,84 +0,0 @@
package com.youlai.boot.system.model.bo;
import com.youlai.boot.system.enums.MenuTypeEnum;
import lombok.Data;
/**
* 路由
*/
@Data
public class RouteBO {
private Long id;
/**
* 父菜单ID
*/
private Long parentId;
/**
* 菜单名称
*/
private String name;
/**
* 菜单类型(1-菜单 2-目录 3-外链 4-按钮)
*/
private MenuTypeEnum type;
/**
* 路由名称Vue Router 中定义的路由名称)
*/
private String routeName;
/**
* 路由路径Vue Router 中定义的 URL 路径)
*/
private String routePath;
/**
* 组件路径(vue页面完整路径省略.vue后缀)
*/
private String component;
/**
* 权限标识
*/
private String perm;
/**
* 显示状态(1:显示;0:隐藏)
*/
private Integer visible;
/**
* 排序
*/
private Integer sort;
/**
* 菜单图标
*/
private String icon;
/**
* 跳转路径
*/
private String redirect;
/**
* 【目录】只有一个子路由是否始终显示(1:是 0:否)
*/
private Integer alwaysShow;
/**
* 【菜单】是否开启页面缓存(1:是 0:否)
*/
private Integer keepAlive;
/**
* 【菜单】路由参数
*/
private String params;
}

View File

@@ -42,7 +42,7 @@ public interface MenuService extends IService<Menu> {
/** /**
* 获取路由列表 * 获取路由列表
*/ */
List<RouteVO> listRoutes( Set<String> roles); List<RouteVO> getCurrentUserRoutes();
/** /**
* 修改菜单显示状态 * 修改菜单显示状态

View File

@@ -10,9 +10,9 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.youlai.boot.core.security.util.SecurityUtils;
import com.youlai.boot.system.converter.MenuConverter; import com.youlai.boot.system.converter.MenuConverter;
import com.youlai.boot.system.mapper.MenuMapper; import com.youlai.boot.system.mapper.MenuMapper;
import com.youlai.boot.system.model.bo.RouteBO;
import com.youlai.boot.shared.codegen.model.entity.GenConfig; import com.youlai.boot.shared.codegen.model.entity.GenConfig;
import com.youlai.boot.system.model.entity.Menu; import com.youlai.boot.system.model.entity.Menu;
import com.youlai.boot.system.model.form.MenuForm; import com.youlai.boot.system.model.form.MenuForm;
@@ -35,9 +35,9 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* 菜单务实现类 * 菜单务实现类
* *
* @author haoxr * @author Ray.Hao
* @since 2020/11/06 * @since 2020/11/06
*/ */
@Service @Service
@@ -142,13 +142,22 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
* 获取菜单路由列表 * 获取菜单路由列表
*/ */
@Override @Override
public List<RouteVO> listRoutes(Set<String> roles) { public List<RouteVO> getCurrentUserRoutes() {
if (CollectionUtil.isEmpty(roles)) { Set<String> roleCodes = SecurityUtils.getRoles();
if (CollectionUtil.isEmpty(roleCodes)) {
return Collections.emptyList(); return Collections.emptyList();
} }
List<Menu> menuList;
List<RouteBO> menuList = this.baseMapper.listRoutes(roles); if (SecurityUtils.isRoot()) {
// 超级管理员获取所有菜单
menuList = this.list(new LambdaQueryWrapper<Menu>().ne(
Menu::getType, MenuTypeEnum.BUTTON.getValue()
));
} else {
menuList = this.baseMapper.getMenusByRoleCodes(roleCodes);
}
return buildRoutes(SystemConstants.ROOT_NODE_ID, menuList); return buildRoutes(SystemConstants.ROOT_NODE_ID, menuList);
} }
@@ -159,10 +168,10 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
* @param menuList 菜单列表 * @param menuList 菜单列表
* @return 路由层级列表 * @return 路由层级列表
*/ */
private List<RouteVO> buildRoutes(Long parentId, List<RouteBO> menuList) { private List<RouteVO> buildRoutes(Long parentId, List<Menu> menuList) {
List<RouteVO> routeList = new ArrayList<>(); List<RouteVO> routeList = new ArrayList<>();
for (RouteBO menu : menuList) { for (Menu menu : menuList) {
if (menu.getParentId().equals(parentId)) { if (menu.getParentId().equals(parentId)) {
RouteVO routeVO = toRouteVo(menu); RouteVO routeVO = toRouteVo(menu);
List<RouteVO> children = buildRoutes(menu.getId(), menuList); List<RouteVO> children = buildRoutes(menu.getId(), menuList);
@@ -179,34 +188,34 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
/** /**
* 根据RouteBO创建RouteVO * 根据RouteBO创建RouteVO
*/ */
private RouteVO toRouteVo(RouteBO routeBO) { private RouteVO toRouteVo(Menu menu) {
RouteVO routeVO = new RouteVO(); RouteVO routeVO = new RouteVO();
// 获取路由名称 // 获取路由名称
String routeName = routeBO.getRouteName(); String routeName = menu.getRouteName();
if (StrUtil.isBlank(routeName)) { if (StrUtil.isBlank(routeName)) {
// 路由 name 需要驼峰,首字母大写 // 路由 name 需要驼峰,首字母大写
routeName = StringUtils.capitalize(StrUtil.toCamelCase(routeBO.getRoutePath(), '-')); routeName = StringUtils.capitalize(StrUtil.toCamelCase(menu.getRoutePath(), '-'));
} }
// 根据name路由跳转 this.$router.push({name:xxx}) // 根据name路由跳转 this.$router.push({name:xxx})
routeVO.setName(routeName); routeVO.setName(routeName);
// 根据path路由跳转 this.$router.push({path:xxx}) // 根据path路由跳转 this.$router.push({path:xxx})
routeVO.setPath(routeBO.getRoutePath()); routeVO.setPath(menu.getRoutePath());
routeVO.setRedirect(routeBO.getRedirect()); routeVO.setRedirect(menu.getRedirect());
routeVO.setComponent(routeBO.getComponent()); routeVO.setComponent(menu.getComponent());
RouteVO.Meta meta = new RouteVO.Meta(); RouteVO.Meta meta = new RouteVO.Meta();
meta.setTitle(routeBO.getName()); meta.setTitle(menu.getName());
meta.setIcon(routeBO.getIcon()); meta.setIcon(menu.getIcon());
meta.setHidden(StatusEnum.DISABLE.getValue().equals(routeBO.getVisible())); meta.setHidden(StatusEnum.DISABLE.getValue().equals(menu.getVisible()));
// 【菜单】是否开启页面缓存 // 【菜单】是否开启页面缓存
if (MenuTypeEnum.MENU.equals(routeBO.getType()) if (MenuTypeEnum.MENU.equals(menu.getType())
&& ObjectUtil.equals(routeBO.getKeepAlive(), 1)) { && ObjectUtil.equals(menu.getKeepAlive(), 1)) {
meta.setKeepAlive(true); meta.setKeepAlive(true);
} }
meta.setAlwaysShow(ObjectUtil.equals(routeBO.getAlwaysShow(), 1)); meta.setAlwaysShow(ObjectUtil.equals(menu.getAlwaysShow(), 1));
String paramsJson = routeBO.getParams(); String paramsJson = menu.getParams();
// 将 JSON 字符串转换为 Map<String, String> // 将 JSON 字符串转换为 Map<String, String>
if (StrUtil.isNotBlank(paramsJson)) { if (StrUtil.isNotBlank(paramsJson)) {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
@@ -241,7 +250,7 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
menuForm.setComponent(null); menuForm.setComponent(null);
} }
if (Objects.equals(menuForm.getParentId(), menuForm.getId())){ if (Objects.equals(menuForm.getParentId(), menuForm.getId())) {
throw new RuntimeException("父级菜单不能为当前菜单"); throw new RuntimeException("父级菜单不能为当前菜单");
} }
Menu entity = menuConverter.toEntity(menuForm); Menu entity = menuConverter.toEntity(menuForm);
@@ -262,7 +271,7 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
.eq(Menu::getRouteName, entity.getRouteName()) .eq(Menu::getRouteName, entity.getRouteName())
.ne(menuForm.getId() != null, Menu::getId, menuForm.getId()) .ne(menuForm.getId() != null, Menu::getId, menuForm.getId())
), "路由名称已存在"); ), "路由名称已存在");
}else{ } else {
// 其他类型时 给路由名称赋值为空 // 其他类型时 给路由名称赋值为空
entity.setRouteName(null); entity.setRouteName(null);
} }
@@ -281,6 +290,7 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
/** /**
* 更新子菜单树路径 * 更新子菜单树路径
*
* @param id 当前菜单ID * @param id 当前菜单ID
* @param treePath 当前菜单树路径 * @param treePath 当前菜单树路径
*/ */

View File

@@ -4,26 +4,8 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.youlai.boot.system.mapper.MenuMapper"> <mapper namespace="com.youlai.boot.system.mapper.MenuMapper">
<!-- 菜单路由映射 -->
<resultMap id="RouteMap" type="com.youlai.boot.system.model.bo.RouteBO">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="parentId" column="parent_id" jdbcType="BIGINT"/>
<result property="routeName" column="route_name" jdbcType="VARCHAR"/>
<result property="routePath" column="route_path" jdbcType="VARCHAR"/>
<result property="component" column="component" jdbcType="VARCHAR"/>
<result property="redirect" column="redirect" jdbcType="VARCHAR"/>
<result property="icon" column="icon" jdbcType="VARCHAR"/>
<result property="sort" column="sort" jdbcType="INTEGER"/>
<result property="visible" column="visible" jdbcType="BOOLEAN"/>
<result property="type" column="type" jdbcType="OTHER"/>
<result property="alwaysShow" column="always_show" jdbcType="INTEGER"/>
<result property="keepAlive" column="keep_alive" jdbcType="INTEGER"/>
<result property="params" column="params" jdbcType="VARCHAR"/>
</resultMap>
<!-- 获取路由列表 --> <!-- 获取路由列表 -->
<select id="listRoutes" resultMap="RouteMap"> <select id="getMenusByRoleCodes" resultType="com.youlai.boot.system.model.entity.Menu">
SELECT SELECT
DISTINCT t1.id, DISTINCT t1.id,
t1.name, t1.name,
@@ -45,15 +27,17 @@
INNER JOIN sys_role t3 ON t2.role_id = t3.id AND t3.status = 1 AND t3.is_deleted = 0 INNER JOIN sys_role t3 ON t2.role_id = t3.id AND t3.status = 1 AND t3.is_deleted = 0
WHERE WHERE
t1.type != '${@com.youlai.boot.system.enums.MenuTypeEnum@BUTTON.getValue()}' t1.type != '${@com.youlai.boot.system.enums.MenuTypeEnum@BUTTON.getValue()}'
<if test="roles != null and roles.size() > 0"> <choose>
<!-- ROOT 可查看所有菜单 --> <when test="roleCodes != null and roleCodes.size() > 0">
<if test="!roles.contains('ROOT')">
AND t3.code IN AND t3.code IN
<foreach collection="roles" item="role" open="(" close=")" separator=","> <foreach item="roleCode" open="(" close=")" separator="," collection="roleCodes" >
#{role} #{roleCode}
</foreach> </foreach>
</if> </when>
</if> <otherwise>
AND 1 = 0
</otherwise>
</choose>
ORDER BY ORDER BY
t1.sort t1.sort
</select> </select>