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
- Add a frontend check that disables drop on any descendant of the dragged node (traverse children client-side).
- Provide clear visual feedback when hovering over an invalid (descendant) drop target.
- 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
- Traverse the client-side tree to disable descendant drop targets.
- Provide visual feedback (red highlight) on invalid drop targets.
- Cache the department hierarchy for efficient descendant checks.
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.