jeecgboot/JeecgBoot · error · JeecgBootBizTipException

目标部门不存在

Error message

目标部门不存在

What it means

Thrown by SysDepartServiceImpl.updateChangeDepart when baseMapper.getDepartById(dropId) returns null — the target (drop) department cannot be found. This JeecgBootBizTipException fires after the dragged department is confirmed to exist, halting the transaction before drag validation logic runs.

Solutions

  1. Refresh the department tree to ensure the target node still exists.
  2. Verify the frontend passes the actual department ID (not a tree-component-internal ID) as dropId.
  3. Check for concurrent modifications by other users or sessions.
  4. Confirm the dropId is within the same tenant scope as the logged-in user.

Example fix

// before
SysDepart targetDept = baseMapper.getDepartById(dropId);
if (null == targetDept) {
    throw new JeecgBootBizTipException("目标部门不存在");
}

// after — frontend ensures dropId is valid before API call
// Only allow drop on nodes confirmed to be real departments:
if (!treeNode.isRealDepartment()) {
    ElMessage.warning('目标节点无效,请刷新后重试');
    return;
}
await api.updateChangeDepart({ dragId, dropId: treeNode.id, dropPosition });
Defensive patterns

Strategy: validation

Validate before calling

// Validate dropId exists before calling updateChangeDepart
SysDepart targetDept = baseMapper.getDepartById(dropId);
if (targetDept == null) {
    return Result.error("目标部门不存在,请刷新部门树后重试");
}
service.updateChangeDepart(changeDepartVo);

Type guard

public boolean isDropTargetValid(String dropId) {
    if (dropId == null || dropId.trim().isEmpty()) return false;
    return baseMapper.getDepartById(dropId) != null;
}

Try / catch

try {
    service.updateChangeDepart(changeDepartVo);
} catch (JeecgBootBizTipException e) {
    if (e.getMessage().contains("目标部门不存在")) {
        return Result.error("目标部门已被删除,请刷新后重试");
    }
    throw e;
}

Prevention

When it happens

Trigger: A drag-and-drop where the target department ID (dropId) references a deleted or non-existent department. Happens when the target was removed by another user, or the frontend passes a virtual/internal node ID that has no backing database record.

Common situations: Concurrent deletion of the target department; frontend tree component passes an internal tree-node ID that doesn't correspond to a real SYS_DEPART row; tenant context mismatch during the drop request.

Related errors


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

Appendix: source

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

     * 变更部门位置
     * 
     * @param changeDepartVo
     * @return orgCode 部门id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateChangeDepart(SysChangeDepartVo changeDepartVo) {
        String dragId = changeDepartVo.getDragId();
        // 1. 获取被拖拽的部门
        SysDepart dragDept = baseMapper.getDepartById(dragId);
        if (null == dragDept) {
            throw new JeecgBootBizTipException("被拖拽的部门不存在");
        }
        // 2. 获取目标部门
        String dropId = changeDepartVo.getDropId();
        SysDepart targetDept = baseMapper.getDepartById(dropId);
        if (null == targetDept) {
            throw new JeecgBootBizTipException("目标部门不存在");
        }
        //3. 验证拖拽操作是否合法
        validateDragOperation(dragDept, targetDept, changeDepartVo.getDropPosition());
        //4. 根据dropPosition调整部门顺序
        Integer dropPosition = changeDepartVo.getDropPosition();
        switch (dropPosition) {
            case -1:
                // 拖拽到上方
                moveToAbove(dragDept, targetDept);
                break;
            case 0:
                // 拖拽到内部(作为子部门)
                moveAsChild(dragDept, targetDept);
                break;
            case 1:
                //拖拽到下方
                moveToBelow(dragDept, targetDept, changeDepartVo.getSort());
                break;

View on GitHub (pinned to 96fb33f5ec)