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);