Explorar el Código

【功能优化】System:componentName 重复校验,避免 vue3 router 初始化有问题

YunaiV hace 5 meses
padre
commit
803da9ed9e

+ 1 - 0
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, "角色不存在");

+ 5 - 0
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<MenuDO> {
     default List<MenuDO> selectListByPermission(String permission) {
         return selectList(MenuDO::getPermission, permission);
     }
+
+    default MenuDO selectByComponentName(String componentName) {
+        return selectOne(MenuDO::getComponentName, componentName);
+    }
+
 }

+ 30 - 3
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);
+        }
+    }
+
     /**
      * 初始化菜单的通用属性。
      * <p>

+ 4 - 4
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);
     }