From e4d6e1da117266a7418e887ab9e58a4631a2cd96 Mon Sep 17 00:00:00 2001 From: chenxing Date: Thu, 20 Aug 2026 19:05:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B7=BB=E5=8A=A0=E9=A1=B6?= =?UTF-8?q?=E5=B1=82=E7=BB=84=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SysGroupService.java | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/yunhai/userbase/service/impl/SysGroupService.java b/src/main/java/com/yunhai/userbase/service/impl/SysGroupService.java index fbb7cd5..48b327c 100644 --- a/src/main/java/com/yunhai/userbase/service/impl/SysGroupService.java +++ b/src/main/java/com/yunhai/userbase/service/impl/SysGroupService.java @@ -127,18 +127,23 @@ public class SysGroupService implements ISysGroupService { @Transactional public BoaGroup add(SysGroupRequest request) { Integer parentId = request.getParentId(); - // 允许在根节点(教育云中心)下建组:parentId 为 null 或 0 视为根 + // parentId 为 null 或 0 表示「挂在根节点(教育云中心)下」; + // 新组必须挂到真实根节点的 id 之下,绝不能把 parentId 写成 0(否则会生成第二个伪根节点)。 GroupTypeEnum parentType = null; // null 表示根节点 + int realPid; if (parentId != null && parentId != ROOT_PARENT_ID) { SysGroup parent = sysGroupRepository.findById(parentId) .orElseThrow(() -> new DException("父组不存在")); parentType = parent.getType(); + realPid = parentId; + } else { + // 解析唯一真实根节点,取其真实 id 作为挂载点 + realPid = resolveRootGroup().getId(); } GroupTypeEnum typeEnum = resolveType(request.getType()); // 层级类型约束:当前父组是否允许创建该子类型 validateParentChild(parentType, typeEnum); - int realPid = (parentId == null) ? ROOT_PARENT_ID : parentId; SysGroup entity = new SysGroup(); entity.setName(request.getName()); entity.setParentId(realPid); @@ -446,8 +451,9 @@ public class SysGroupService implements ISysGroupService { parentType = parent.getType(); realPid = pid; } else { - // 允许在根节点下批量建组 - realPid = ROOT_PARENT_ID; + // pid 为 null 或 0 表示「挂在根节点(教育云中心)下」:解析真实根节点 id 作为挂载点, + // 绝不能写成 ROOT_PARENT_ID(0),否则批量建出的组都会变成伪根节点。 + realPid = resolveRootGroup().getId(); } GroupTypeEnum typeEnum = resolveType(request.getType()); // 层级类型约束 @@ -678,6 +684,25 @@ public class SysGroupService implements ISysGroupService { return entity.getParentId() != null && entity.getParentId() == ROOT_PARENT_ID; } + /** + * 解析唯一真实根节点(parentId=0 中 id 最小者,与 {@link #getGroups()} 约定一致)。
+ * 用于「parentId/ pid 为 0 或 null 表示挂根下」场景:必须把新组挂到该根节点的真实 id 下, + * 而非把 parentId 写成 0(0 仅属于根本身,写成 0 会生成第二个伪根节点)。 + * + * @return 根节点实体 + * @throws DException 当不存在任何根节点时 + */ + private SysGroup resolveRootGroup() { + List roots = sysGroupRepository.findByParentIdOrderBySortAsc(ROOT_PARENT_ID); + if (roots.isEmpty()) { + throw new DException("根节点不存在,无法在根下建组"); + } + // 与 getGroups 约定一致:pid=0 中 id 最小者为唯一真实根节点 + return roots.stream() + .min(Comparator.comparingInt(SysGroup::getId)) + .orElse(roots.get(0)); + } + private SysGroupVo convertToVo(SysGroup entity) { SysGroupVo vo = new SysGroupVo(); BeanUtils.copyProperties(entity, vo);