diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/factory/MenuPathCalcFactory.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/factory/MenuPathCalcFactory.java new file mode 100644 index 000000000..4246cac6d --- /dev/null +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/factory/MenuPathCalcFactory.java @@ -0,0 +1,63 @@ +package cn.stylefeng.roses.kernel.sys.modular.menu.factory; + +import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * 菜单路径计算 + * + * @author fengshuonan + * @since 2024/6/24 12:52 + */ +public class MenuPathCalcFactory { + + /** + * 获取指定菜单id对应的父级id路径上,父级id没有其他子菜单的情况下,所有id的集合 + * + * @return 返回的id集合包含参数的menuId + * @author fengshuonan + * @since 2024/6/24 12:52 + */ + public static Set getMenuParentIds(Long menuId, Map menuIdParentIdMap) { + Set uniquePathMenuIds = new HashSet<>(); + uniquePathMenuIds.add(menuId); + + findUniquePathMenuIdsRecursive(menuId, menuIdParentIdMap, uniquePathMenuIds); + return uniquePathMenuIds; + } + + /** + * 递归查询 + * + * @author fengshuonan + * @since 2024/6/24 13:01 + */ + private static void findUniquePathMenuIdsRecursive(Long currentMenuId, Map menuParentMap, Set uniquePathMenuIds) { + + // 获取当前菜单的父菜单ID + Long parentId = menuParentMap.get(currentMenuId); + + // 如果父菜单ID为null或者-1,说明已经到达顶级节点,结束递归 + if (parentId == null || TreeConstants.DEFAULT_PARENT_ID.equals(parentId)) { + return; + } + + // 检查父菜单是否有其他子节点 + boolean hasOtherChildren = menuParentMap.entrySet().stream() + .anyMatch(entry -> entry.getValue().equals(parentId) && !entry.getKey().equals(currentMenuId)); + + // 如果父菜单没有其他子节点,则继续递归处理父菜单 + if (!hasOtherChildren) { + + // 将当前菜单ID加入结果集合 + uniquePathMenuIds.add(parentId); + + // 继续递归向上找 + findUniquePathMenuIdsRecursive(parentId, menuParentMap, uniquePathMenuIds); + } + } + +} diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java index b8154112d..71a9269da 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java @@ -7,6 +7,7 @@ import cn.stylefeng.roses.kernel.sys.modular.menu.pojo.response.AppGroupDetail; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -124,4 +125,13 @@ public interface SysMenuService extends IService, SysMenuServiceApi { */ List getMenuCodeList(List menuIdList); + /** + * 获取所有菜单的id和父级id的映射关系 + * + * @return 菜单id和父级id的映射关系 + * @author fengshuonan + * @since 2024/6/24 12:38 + */ + Map getMenuIdParentIdMap(); + } \ No newline at end of file diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java index ca8c0edd2..09bd1b6f5 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java @@ -271,6 +271,19 @@ public class SysMenuServiceImpl extends ServiceImpl impl return result; } + @Override + public Map getMenuIdParentIdMap() { + LambdaQueryWrapper sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>(); + sysMenuLambdaQueryWrapper.select(SysMenu::getMenuId, SysMenu::getMenuParentId); + List sysMenuList = this.list(sysMenuLambdaQueryWrapper); + + if (ObjectUtil.isEmpty(sysMenuList)) { + return new HashMap<>(); + } + + return sysMenuList.stream().collect(Collectors.toMap(SysMenu::getMenuId, SysMenu::getMenuParentId)); + } + @Override public List getAppMenuGroupDetail(SysMenuRequest sysMenuRequest) { diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/RoleBindMenuImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/RoleBindMenuImpl.java index c9a465697..50f73a1de 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/RoleBindMenuImpl.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/RoleBindMenuImpl.java @@ -3,6 +3,7 @@ package cn.stylefeng.roses.kernel.sys.modular.role.service.impl; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; import cn.stylefeng.roses.kernel.sys.modular.menu.entity.SysMenuOptions; +import cn.stylefeng.roses.kernel.sys.modular.menu.factory.MenuPathCalcFactory; import cn.stylefeng.roses.kernel.sys.modular.menu.service.SysMenuOptionsService; import cn.stylefeng.roses.kernel.sys.modular.menu.service.SysMenuService; import cn.stylefeng.roses.kernel.sys.modular.role.action.RoleAssignOperateAction; @@ -67,9 +68,13 @@ public class RoleBindMenuImpl implements RoleAssignOperateAction, RoleBindLimitA return; } + // 【2024年6月24日】获取菜单的所有id和parentId,后续判断删除的节点的父级没有其他自己节点时候使用 + Map menuIdParentIdMap = sysMenuService.getMenuIdParentIdMap(); + Set needToDelete = MenuPathCalcFactory.getMenuParentIds(menuId, menuIdParentIdMap); + // 1. 先取消绑定角色和菜单 LambdaQueryWrapper sysRoleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>(); - sysRoleMenuLambdaQueryWrapper.eq(SysRoleMenu::getMenuId, menuId); + sysRoleMenuLambdaQueryWrapper.in(SysRoleMenu::getMenuId, needToDelete); sysRoleMenuLambdaQueryWrapper.eq(SysRoleMenu::getRoleId, roleId); this.sysRoleMenuService.remove(sysRoleMenuLambdaQueryWrapper);