diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index 8eb5b09..d88a921 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -303,7 +303,7 @@ public class PermissionServiceImpl implements PermissionService { CollUtil.addAll(result.getDeptIds(), role.getDataScopeDeptIds()); // 自定义可见部门时,保证可以看到自己所在的部门。否则,一些场景下可能会有问题。 // 例如说,登录时,基于 t_user 的 username 查询会可能被 dept_id 过滤掉 - CollUtil.addAll(result.getDeptIds(), userDeptId.get()); + CollectionUtils.addIfNotNull(result.getDeptIds(), userDeptId.get()); continue; } // 情况三,DEPT_ONLY @@ -313,9 +313,14 @@ public class PermissionServiceImpl implements PermissionService { } // 情况四,DEPT_DEPT_AND_CHILD if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_AND_CHILD.getScope())) { - CollUtil.addAll(result.getDeptIds(), deptService.getChildDeptIdListFromCache(userDeptId.get())); + Long deptId = userDeptId.get(); + // 用户未设置部门,直接跳过;否则 getChildDeptIdListFromCache 走缓存注解会因 null key 报错 + if (deptId == null) { + continue; + } + CollUtil.addAll(result.getDeptIds(), deptService.getChildDeptIdListFromCache(deptId)); // 添加本身部门编号 - CollUtil.addAll(result.getDeptIds(), userDeptId.get()); + result.getDeptIds().add(deptId); continue; } // 情况五,SELF diff --git a/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java b/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java index 52ba3f9..87f12b7 100644 --- a/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java +++ b/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java @@ -441,6 +441,34 @@ public class PermissionServiceTest extends BaseDbUnitTest { } @Test + public void testGetDeptDataPermission_DeptCustom_userDeptIdNull() { + try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { + springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class))) + .thenReturn(permissionService); + + // 准备参数 + Long userId = 1L; + // mock 用户的角色编号 + userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L)); + // mock 获得用户的角色 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope()) + .setStatus(CommonStatusEnum.ENABLE.getStatus())); + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO)); + // mock 部门的返回:用户未设置部门 + when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO()); // deptId 为 null + + // 调用 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId); + // 断言:角色配置的可见部门仍正常加入,但 null 不进集合 + assertFalse(result.getAll()); + assertFalse(result.getSelf()); + assertEquals(roleDO.getDataScopeDeptIds().size(), result.getDeptIds().size()); + assertTrue(CollUtil.containsAll(result.getDeptIds(), roleDO.getDataScopeDeptIds())); + assertFalse(result.getDeptIds().contains(null)); + } + } + + @Test public void testGetDeptDataPermission_DeptOnly() { try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class))) @@ -501,6 +529,33 @@ public class PermissionServiceTest extends BaseDbUnitTest { } @Test + public void testGetDeptDataPermission_DeptAndChild_userDeptIdNull() { + try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { + springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class))) + .thenReturn(permissionService); + + // 准备参数 + Long userId = 1L; + // mock 用户的角色编号 + userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L)); + // mock 获得用户的角色 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope()) + .setStatus(CommonStatusEnum.ENABLE.getStatus())); + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO)); + // mock 部门的返回:用户未设置部门 + when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO()); // deptId 为 null + + // 调用 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId); + // 断言:deptId 为 null,整段跳过;deptIds 为空,子部门查询不被触发 + assertFalse(result.getAll()); + assertFalse(result.getSelf()); + assertTrue(CollUtil.isEmpty(result.getDeptIds())); + verify(deptService, never()).getChildDeptIdListFromCache(any()); + } + } + + @Test public void testGetDeptDataPermission_Self() { try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))