feat(menu): 添加菜单唯一标识功能

- 新增 menuKey 字段到 SysMenu 实体类
- 在菜单服务接口和服务实现中添加 checkMenuKeyUnique、selectMenuByMenuKey 和 generateMenuKeys 方法
- 在控制器中增加 getByKey 和 generateMenuKeys 接口用于通过唯一标识获取菜单和批量生成菜单标识
- 在数据库映射中添加对 menuKey 字段的支持
- 在新增和修改菜单时验证 menuKey 唯一性
- 实现自动生成菜单唯一标识的功能,支持基于路径或菜单名称生成
This commit is contained in:
2026-07-01 13:23:18 +08:00
parent ad1fa08561
commit 62f6362d61
6 changed files with 159 additions and 1 deletions

View File

@@ -84,6 +84,8 @@ public class SysMenuController extends BaseController {
public R<Void> add(@Validated @RequestBody SysMenu menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (StringUtils.isNotBlank(menu.getMenuKey()) && !menuService.checkMenuKeyUnique(menu)) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单唯一标识'" + menu.getMenuKey() + "'已存在");
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
@@ -99,6 +101,8 @@ public class SysMenuController extends BaseController {
public R<Void> edit(@Validated @RequestBody SysMenu menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (StringUtils.isNotBlank(menu.getMenuKey()) && !menuService.checkMenuKeyUnique(menu)) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,菜单唯一标识'" + menu.getMenuKey() + "'已存在");
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
} else if (menu.getMenuId().equals(menu.getParentId())) {
@@ -124,4 +128,29 @@ public class SysMenuController extends BaseController {
}
return toAjax(menuService.deleteMenuById(menuId));
}
/**
* 根据 menuKey 获取菜单信息(供流程图等外部固定引用跳转)
*
* @param menuKey 菜单唯一标识
*/
@GetMapping("/getByKey")
public R<SysMenu> getByKey(@RequestParam String menuKey) {
SysMenu menu = menuService.selectMenuByMenuKey(menuKey);
if (menu == null) {
return R.fail("菜单唯一标识 '" + menuKey + "' 不存在");
}
return R.ok(menu);
}
/**
* 为现有菜单自动生成 menu_key仅处理 menu_key 为空且类型为 C/M 的菜单)
*/
@SaCheckPermission("system:menu:edit")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@PostMapping("/generateMenuKeys")
public R<Void> generateMenuKeys() {
int count = menuService.generateMenuKeys();
return R.ok("成功为 " + count + " 个菜单生成 menu_key");
}
}