Commit 803da9ed9e6bedb209ac8426fff3ea32fa695d4a

Authored by YunaiV
1 parent 0debd8e0

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

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 { @@ -24,6 +24,7 @@ public interface ErrorCodeConstants {
24 ErrorCode MENU_NOT_EXISTS = new ErrorCode(1_002_001_003, "菜单不存在"); 24 ErrorCode MENU_NOT_EXISTS = new ErrorCode(1_002_001_003, "菜单不存在");
25 ErrorCode MENU_EXISTS_CHILDREN = new ErrorCode(1_002_001_004, "存在子菜单,无法删除"); 25 ErrorCode MENU_EXISTS_CHILDREN = new ErrorCode(1_002_001_004, "存在子菜单,无法删除");
26 ErrorCode MENU_PARENT_NOT_DIR_OR_MENU = new ErrorCode(1_002_001_005, "父菜单的类型必须是目录或者菜单"); 26 ErrorCode MENU_PARENT_NOT_DIR_OR_MENU = new ErrorCode(1_002_001_005, "父菜单的类型必须是目录或者菜单");
  27 + ErrorCode MENU_COMPONENT_NAME_DUPLICATE = new ErrorCode(1_002_001_006, "已经存在该组件名的菜单");
27 28
28 // ========== 角色模块 1-002-002-000 ========== 29 // ========== 角色模块 1-002-002-000 ==========
29 ErrorCode ROLE_NOT_EXISTS = new ErrorCode(1_002_002_000, "角色不存在"); 30 ErrorCode ROLE_NOT_EXISTS = new ErrorCode(1_002_002_000, "角色不存在");
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> { @@ -28,4 +28,9 @@ public interface MenuMapper extends BaseMapperX<MenuDO> {
28 default List<MenuDO> selectListByPermission(String permission) { 28 default List<MenuDO> selectListByPermission(String permission) {
29 return selectList(MenuDO::getPermission, permission); 29 return selectList(MenuDO::getPermission, permission);
30 } 30 }
  31 +
  32 + default MenuDO selectByComponentName(String componentName) {
  33 + return selectOne(MenuDO::getComponentName, componentName);
  34 + }
  35 +
31 } 36 }
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; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.permission;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
  5 +import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; 8 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
@@ -53,7 +54,8 @@ public class MenuServiceImpl implements MenuService { @@ -53,7 +54,8 @@ public class MenuServiceImpl implements MenuService {
53 // 校验父菜单存在 54 // 校验父菜单存在
54 validateParentMenu(createReqVO.getParentId(), null); 55 validateParentMenu(createReqVO.getParentId(), null);
55 // 校验菜单(自己) 56 // 校验菜单(自己)
56 - validateMenu(createReqVO.getParentId(), createReqVO.getName(), null); 57 + validateMenuName(createReqVO.getParentId(), createReqVO.getName(), null);
  58 + validateMenuComponentName(createReqVO.getComponentName(), null);
57 59
58 // 插入数据库 60 // 插入数据库
59 MenuDO menu = BeanUtils.toBean(createReqVO, MenuDO.class); 61 MenuDO menu = BeanUtils.toBean(createReqVO, MenuDO.class);
@@ -74,7 +76,8 @@ public class MenuServiceImpl implements MenuService { @@ -74,7 +76,8 @@ public class MenuServiceImpl implements MenuService {
74 // 校验父菜单存在 76 // 校验父菜单存在
75 validateParentMenu(updateReqVO.getParentId(), updateReqVO.getId()); 77 validateParentMenu(updateReqVO.getParentId(), updateReqVO.getId());
76 // 校验菜单(自己) 78 // 校验菜单(自己)
77 - validateMenu(updateReqVO.getParentId(), updateReqVO.getName(), updateReqVO.getId()); 79 + validateMenuName(updateReqVO.getParentId(), updateReqVO.getName(), updateReqVO.getId());
  80 + validateMenuComponentName(updateReqVO.getComponentName(), updateReqVO.getId());
78 81
79 // 更新到数据库 82 // 更新到数据库
80 MenuDO updateObj = BeanUtils.toBean(updateReqVO, MenuDO.class); 83 MenuDO updateObj = BeanUtils.toBean(updateReqVO, MenuDO.class);
@@ -228,7 +231,7 @@ public class MenuServiceImpl implements MenuService { @@ -228,7 +231,7 @@ public class MenuServiceImpl implements MenuService {
228 * @param id 菜单编号 231 * @param id 菜单编号
229 */ 232 */
230 @VisibleForTesting 233 @VisibleForTesting
231 - void validateMenu(Long parentId, String name, Long id) { 234 + void validateMenuName(Long parentId, String name, Long id) {
232 MenuDO menu = menuMapper.selectByParentIdAndName(parentId, name); 235 MenuDO menu = menuMapper.selectByParentIdAndName(parentId, name);
233 if (menu == null) { 236 if (menu == null) {
234 return; 237 return;
@@ -243,6 +246,30 @@ public class MenuServiceImpl implements MenuService { @@ -243,6 +246,30 @@ public class MenuServiceImpl implements MenuService {
243 } 246 }
244 247
245 /** 248 /**
  249 + * 校验菜单组件名是否合法
  250 + *
  251 + * @param componentName 组件名
  252 + * @param id 菜单编号
  253 + */
  254 + @VisibleForTesting
  255 + void validateMenuComponentName(String componentName, Long id) {
  256 + if (StrUtil.isBlank(componentName)) {
  257 + return;
  258 + }
  259 + MenuDO menu = menuMapper.selectByComponentName(componentName);
  260 + if (menu == null) {
  261 + return;
  262 + }
  263 + // 如果 id 为空,说明不用比较是否为相同 id 的菜单
  264 + if (id == null) {
  265 + return;
  266 + }
  267 + if (!menu.getId().equals(id)) {
  268 + throw exception(MENU_COMPONENT_NAME_DUPLICATE);
  269 + }
  270 + }
  271 +
  272 + /**
246 * 初始化菜单的通用属性。 273 * 初始化菜单的通用属性。
247 * <p> 274 * <p>
248 * 例如说,只有目录或者菜单类型的菜单,才设置 icon 275 * 例如说,只有目录或者菜单类型的菜单,才设置 icon
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 { @@ -275,7 +275,7 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
275 } 275 }
276 276
277 @Test 277 @Test
278 - public void testValidateMenu_success() { 278 + public void testValidateMenu_Name_success() {
279 // mock 父子菜单 279 // mock 父子菜单
280 MenuDO sonMenu = createParentAndSonMenu(); 280 MenuDO sonMenu = createParentAndSonMenu();
281 // 准备参数 281 // 准备参数
@@ -284,11 +284,11 @@ public class MenuServiceImplTest extends BaseDbUnitTest { @@ -284,11 +284,11 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
284 String otherSonMenuName = randomString(); 284 String otherSonMenuName = randomString();
285 285
286 // 调用,无需断言 286 // 调用,无需断言
287 - menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId); 287 + menuService.validateMenuName(parentId, otherSonMenuName, otherSonMenuId);
288 } 288 }
289 289
290 @Test 290 @Test
291 - public void testValidateMenu_sonMenuNameDuplicate() { 291 + public void testValidateMenu_sonMenuNameNameDuplicate() {
292 // mock 父子菜单 292 // mock 父子菜单
293 MenuDO sonMenu = createParentAndSonMenu(); 293 MenuDO sonMenu = createParentAndSonMenu();
294 // 准备参数 294 // 准备参数
@@ -297,7 +297,7 @@ public class MenuServiceImplTest extends BaseDbUnitTest { @@ -297,7 +297,7 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
297 String otherSonMenuName = sonMenu.getName(); //相同名称 297 String otherSonMenuName = sonMenu.getName(); //相同名称
298 298
299 // 调用,并断言异常 299 // 调用,并断言异常
300 - assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId), 300 + assertServiceException(() -> menuService.validateMenuName(parentId, otherSonMenuName, otherSonMenuId),
301 MENU_NAME_DUPLICATE); 301 MENU_NAME_DUPLICATE);
302 } 302 }
303 303