{"record":{"id":"84a3a4151baea38c","repo":"elunez/eladmin","slug":"error-84a3a4","errorCode":null,"errorMessage":"所选部门存在角色关联，请解除后再试！","messagePattern":"所选部门存在角色关联，请解除后再试！","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/DeptServiceImpl.java","lineNumber":248,"sourceCode":"        }\n\n        if (CollectionUtil.isEmpty(trees)) {\n            trees = depts;\n        }\n        Map<String,Object> map = new HashMap<>(2);\n        map.put(\"totalElements\",deptDtos.size());\n        map.put(\"content\",CollectionUtil.isEmpty(trees)? deptDtos :trees);\n        return map;\n    }\n\n    @Override\n    public void verification(Set<DeptDto> deptDtos) {\n        Set<Long> deptIds = deptDtos.stream().map(DeptDto::getId).collect(Collectors.toSet());\n        if(userRepository.countByDepts(deptIds) > 0){\n            throw new BadRequestException(\"所选部门存在用户关联，请解除后再试！\");\n        }\n        if(roleRepository.countByDepts(deptIds) > 0){\n            throw new BadRequestException(\"所选部门存在角色关联，请解除后再试！\");\n        }\n    }\n\n    private void updateSubCnt(Long deptId){\n        if(deptId != null){\n            int count = deptRepository.countByPid(deptId);\n            deptRepository.updateSubCntById(count, deptId);\n        }\n    }\n\n    private List<DeptDto> deduplication(List<DeptDto> list) {\n        List<DeptDto> deptDtos = new ArrayList<>();\n        for (DeptDto deptDto : list) {\n            boolean flag = true;\n            for (DeptDto dto : list) {\n                if (dto.getId().equals(deptDto.getPid())) {\n                    flag = false;\n                    break;","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/DeptServiceImpl.java#L230-L266","documentation":"Thrown by DeptServiceImpl.verification (line 248) during dept deletion when roleRepository.countByDepts(deptIds) > 0 — at least one role's data scope still references a selected department. This is the second gate after the user check: roles with custom data-scope (数据权限) must not point at departments being removed.","triggerScenarios":"A role with dataScope = '自定义' whose sys_roles_depts rows include one of the deleted depts; deleting a subtree that a manager role's custom data scope was scoped to; leftover role-dept mappings from an old org structure.","commonSituations":"Org restructures where role data scopes were configured per-department years earlier; admins seeing the user check pass but the role check fail on the same batch; test roles with custom scopes pointing at scratch depts.","solutions":["Edit each affected role's data scope (remove the dept or switch scope to 全部/本级) in the role management UI, then retry.","Find offenders: SELECT role_id, dept_id FROM sys_roles_depts WHERE dept_id IN (...).","For bulk cleanups, script the sys_roles_depts cleanup before calling DELETE /api/dept."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Server-side wrapper before dept delete\ndeptDtos.forEach(d -> {\n  if (userRepository.countByDepts(Set.of(d.getId())) > 0) throw new BadRequestException(\"users attached\");\n  if (roleRepository.countByDepts(Set.of(d.getId())) > 0) throw new BadRequestException(\"roles attached\");\n});\ndeptService.delete(ids);","typeGuard":null,"tryCatchPattern":"Catch the 400 and point the operator to role data-scope editing; the message already says which reference class blocks deletion.","preventionTips":["When deleting depts from an org restructure, first audit sys_roles_depts.","Prefer scoping roles to dept levels ('本级及以下') over custom dept lists to reduce stale mappings."],"tags":["referential-integrity","eladmin","dept","delete","role","data-scope"],"backgroundTag":null,"analyzedSha":"55fbf705956949697dbd68bf9003776609d3d029","analyzedAt":"2026-08-14T11:56:12.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}