fix: 删除菜单包括子级

This commit is contained in:
2026-07-09 13:52:53 +08:00
parent 5749b95327
commit 5486f6e79d
11 changed files with 75 additions and 22 deletions

View File

@@ -52,8 +52,9 @@ public class MenuController {
@Operation(summary = "删除菜单")
@Parameter(name = "id", description = "菜单编号", required= true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:menu:delete')")
public CommonResult<Boolean> deleteMenu(@RequestParam("id") Long id) {
menuService.deleteMenu(id);
public CommonResult<Boolean> deleteMenu(@RequestParam("id") Long id,
@RequestParam(value = "cascade", defaultValue = "false") boolean cascade) {
menuService.deleteMenu(id, cascade);
return success(true);
}

View File

@@ -32,9 +32,10 @@ public interface MenuService {
/**
* 删除菜单
*
* @param id 菜单编号
* @param id 菜单编号
* @param cascade 是否级联删除子菜单
*/
void deleteMenu(Long id);
void deleteMenu(Long id, boolean cascade);
/**
* 批量删除菜单

View File

@@ -89,21 +89,43 @@ public class MenuServiceImpl implements MenuService {
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为此时不知道 id 对应的 permission 是多少。直接清理,简单有效
public void deleteMenu(Long id) {
// 校验是否还有子菜单
if (menuMapper.selectCountByParentId(id) > 0) {
throw exception(MENU_EXISTS_CHILDREN);
}
public void deleteMenu(Long id, boolean cascade) {
// 校验删除的菜单是否存在
if (menuMapper.selectById(id) == null) {
throw exception(MENU_NOT_EXISTS);
}
// 校验是否还有子菜单
if (menuMapper.selectCountByParentId(id) > 0) {
if (!cascade) {
throw exception(MENU_EXISTS_CHILDREN);
}
// 级联删除:递归收集所有子菜单 ID
List<Long> childIds = new ArrayList<>();
collectChildMenuIds(id, childIds);
// 先删除子菜单,再删父菜单
menuMapper.deleteByIds(childIds);
childIds.forEach(childId -> permissionService.processMenuDeleted(childId));
}
// 标记删除
menuMapper.deleteById(id);
// 删除授予给角色的权限
permissionService.processMenuDeleted(id);
}
/**
* 递归收集所有子菜单 ID
*
* @param parentId 父菜单 ID
* @param result 收集结果
*/
private void collectChildMenuIds(Long parentId, List<Long> result) {
List<MenuDO> children = menuMapper.selectList(MenuDO::getParentId, parentId);
for (MenuDO child : children) {
result.add(child.getId());
collectChildMenuIds(child.getId(), result);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST,

View File

@@ -96,6 +96,9 @@ xxl:
job:
admin:
addresses: http://192.168.10.14:8080/xxl-job-admin # 调度中心部署跟地址
executor:
ip: 192.168.10.14
port: 9992
--- #################### 服务保障相关配置 ####################

View File

@@ -124,7 +124,7 @@ xxl:
executor:
appname: ${spring.application.name} # 执行器 AppName
logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径
accessToken: default_token # 执行器通讯TOKEN
accessToken: 123456 # 执行器通讯TOKEN
--- #################### 验证码相关配置 ####################