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.

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)

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.