diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index a3cc1cefa0..6db0e567c4 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -24,6 +24,7 @@ public interface ErrorCodeConstants { ErrorCode MENU_NOT_EXISTS = new ErrorCode(1_002_001_003, "菜单不存在"); ErrorCode MENU_EXISTS_CHILDREN = new ErrorCode(1_002_001_004, "存在子菜单,无法删除"); ErrorCode MENU_PARENT_NOT_DIR_OR_MENU = new ErrorCode(1_002_001_005, "父菜单的类型必须是目录或者菜单"); + ErrorCode MENU_COMPONENT_NAME_DUPLICATE = new ErrorCode(1_002_001_006, "已经存在该组件名的菜单"); // ========== 角色模块 1-002-002-000 ========== ErrorCode ROLE_NOT_EXISTS = new ErrorCode(1_002_002_000, "角色不存在"); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java index 8458faa67a..31eb117d26 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java @@ -28,4 +28,9 @@ public interface MenuMapper extends BaseMapperX { default List selectListByPermission(String permission) { return selectList(MenuDO::getPermission, permission); } + + default MenuDO selectByComponentName(String componentName) { + return selectOne(MenuDO::getComponentName, componentName); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java index 98052eb650..5378108dd1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.permission; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; @@ -53,7 +54,8 @@ public class MenuServiceImpl implements MenuService { // 校验父菜单存在 validateParentMenu(createReqVO.getParentId(), null); // 校验菜单(自己) - validateMenu(createReqVO.getParentId(), createReqVO.getName(), null); + validateMenuName(createReqVO.getParentId(), createReqVO.getName(), null); + validateMenuComponentName(createReqVO.getComponentName(), null); // 插入数据库 MenuDO menu = BeanUtils.toBean(createReqVO, MenuDO.class); @@ -74,7 +76,8 @@ public class MenuServiceImpl implements MenuService { // 校验父菜单存在 validateParentMenu(updateReqVO.getParentId(), updateReqVO.getId()); // 校验菜单(自己) - validateMenu(updateReqVO.getParentId(), updateReqVO.getName(), updateReqVO.getId()); + validateMenuName(updateReqVO.getParentId(), updateReqVO.getName(), updateReqVO.getId()); + validateMenuComponentName(updateReqVO.getComponentName(), updateReqVO.getId()); // 更新到数据库 MenuDO updateObj = BeanUtils.toBean(updateReqVO, MenuDO.class); @@ -228,7 +231,7 @@ public class MenuServiceImpl implements MenuService { * @param id 菜单编号 */ @VisibleForTesting - void validateMenu(Long parentId, String name, Long id) { + void validateMenuName(Long parentId, String name, Long id) { MenuDO menu = menuMapper.selectByParentIdAndName(parentId, name); if (menu == null) { return; @@ -242,6 +245,30 @@ public class MenuServiceImpl implements MenuService { } } + /** + * 校验菜单组件名是否合法 + * + * @param componentName 组件名 + * @param id 菜单编号 + */ + @VisibleForTesting + void validateMenuComponentName(String componentName, Long id) { + if (StrUtil.isBlank(componentName)) { + return; + } + MenuDO menu = menuMapper.selectByComponentName(componentName); + if (menu == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的菜单 + if (id == null) { + return; + } + if (!menu.getId().equals(id)) { + throw exception(MENU_COMPONENT_NAME_DUPLICATE); + } + } + /** * 初始化菜单的通用属性。 *

diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java index 27f1efb36c..cc393796cc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java @@ -275,7 +275,7 @@ public class MenuServiceImplTest extends BaseDbUnitTest { } @Test - public void testValidateMenu_success() { + public void testValidateMenu_Name_success() { // mock 父子菜单 MenuDO sonMenu = createParentAndSonMenu(); // 准备参数 @@ -284,11 +284,11 @@ public class MenuServiceImplTest extends BaseDbUnitTest { String otherSonMenuName = randomString(); // 调用,无需断言 - menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId); + menuService.validateMenuName(parentId, otherSonMenuName, otherSonMenuId); } @Test - public void testValidateMenu_sonMenuNameDuplicate() { + public void testValidateMenu_sonMenuNameNameDuplicate() { // mock 父子菜单 MenuDO sonMenu = createParentAndSonMenu(); // 准备参数 @@ -297,7 +297,7 @@ public class MenuServiceImplTest extends BaseDbUnitTest { String otherSonMenuName = sonMenu.getName(); //相同名称 // 调用,并断言异常 - assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId), + assertServiceException(() -> menuService.validateMenuName(parentId, otherSonMenuName, otherSonMenuId), MENU_NAME_DUPLICATE); }