jeecgboot/JeecgBoot · warning · RuntimeException

不能拖拽到自身子部门

Error message

不能拖拽到自身子部门

What it means

Thrown by validateDragOperation when isDescendant(dragDept, targetDept.getId()) returns true — the target is a child of the dragged department, which would create a cycle if the move were allowed. This RuntimeException is the second check after the self-drop guard, preventing circular parent-child relationships.

Source

Thrown at jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java:2060

        //5. 清空缓存
        redisUtil.removeAll(CommonConstant.DEPART_NAME_REDIS_KEY_PRE);
    }

    /**
     * 验证拖拽操作是否合法
     *
     * @param dragDept     被拖拽的部门
     * @param targetDept   目标部门
     * @param dropPosition 拖拽位置
     */
    private void validateDragOperation(SysDepart dragDept, SysDepart targetDept, Integer dropPosition) {
        // 禁止拖拽到自身
        if (dragDept.getId().equals(targetDept.getId())) {
            throw new RuntimeException("不能拖拽到自身");
        }
        // 禁止拖拽到自身子部门
        if (isDescendant(dragDept, targetDept.getId())) {
            throw new RuntimeException("不能拖拽到自身子部门");
        }
        //公司岗位判断
        String orgCategory = targetDept.getOrgCategory();
        String oldOrgCategory = dragDept.getOrgCategory();
        //部门为公司
        if(0 != dropPosition && DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(orgCategory)){
            //当前部门不能为子公司、部门和岗位
            if(!DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(oldOrgCategory)){
                throw new JeecgBootBizTipException("当前部门类型为【"+DepartCategoryEnum.getNameByValue(oldOrgCategory)+"】,不允许移动到公司");
            }
        }
        //部门为岗位不允许移入
        if(0 == dropPosition && DepartCategoryEnum.DEPART_CATEGORY_POST.getValue().equals(orgCategory)) {
            throw new JeecgBootBizTipException("岗位不允许存在子级");
        }
        //公司不能做为子级
        if(oConvertUtils.isNotEmpty(targetDept.getParentId()) && DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(oldOrgCategory)){
            throw new JeecgBootBizTipException("公司不允许作为子级");

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Add a frontend check that disables drop on any descendant of the dragged node (traverse children client-side).
  2. Provide clear visual feedback when hovering over an invalid (descendant) drop target.
  3. Ensure the isDescendant check handles deep trees efficiently — if it's slow on large trees, consider caching the hierarchy.

Example fix

// before
if (isDescendant(dragDept, targetDept.getId())) {
    throw new RuntimeException("不能拖拽到自身子部门");
}

// after — frontend disables descendant drop targets
function isDescendant(dragNode, candidateId) {
    if (dragNode.id === candidateId) return true;
    return (dragNode.children || []).some(c => isDescendant(c, candidateId));
}
function allowDrop(dragNode, dropNode) {
    return !isDescendant(dragNode, dropNode.id);
}
Defensive patterns

Strategy: validation

Validate before calling

// Frontend: check if drop target is a descendant of drag node
function isDescendantOf(dragNode, candidateId) {
    if (dragNode.id === candidateId) return true;
    return (dragNode.children || []).some(c => isDescendantOf(c, candidateId));
}
if (isDescendantOf(dragNode, dropNode.id)) {
    ElMessage.warning('不能拖拽到自身子部门');
    return;
}

Type guard

public boolean isSafeDropTarget(SysDepart dragDept, String targetId) {
    return !dragDept.getId().equals(targetId) && !isDescendant(dragDept, targetId);
}

Try / catch

try {
    service.updateChangeDepart(changeDepartVo);
} catch (RuntimeException e) {
    if (e.getMessage().contains("不能拖拽到自身子部门")) {
        return Result.error("目标部门是当前部门的子级,不允许拖拽");
    }
    throw e;
}

Prevention

When it happens

Trigger: Dragging a parent department onto one of its own descendants. The isDescendant method recursively checks children via departMapper.getDepartByParentId. This prevents creating a cycle where a node becomes its own ancestor.

Common situations: User drags a top-level department into a sub-department below it; large tree where the hierarchy isn't visually obvious; tree component allows dropping on any node without hierarchy awareness.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/2e3f5edc399aec92. Report an issue: GitHub.