Commit 3df4f8de765a2ddc97aef18168abbacbee79ed39

Authored by YunaiV
1 parent 48eb3e33

fix(permission):修复用户无部门时 DEPT_AND_CHILD / DEPT_CUSTOM 数据权限的 null 处理,并补单测

yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
... ... @@ -303,7 +303,7 @@ public class PermissionServiceImpl implements PermissionService {
303 303 CollUtil.addAll(result.getDeptIds(), role.getDataScopeDeptIds());
304 304 // 自定义可见部门时,保证可以看到自己所在的部门。否则,一些场景下可能会有问题。
305 305 // 例如说,登录时,基于 t_user 的 username 查询会可能被 dept_id 过滤掉
306   - CollUtil.addAll(result.getDeptIds(), userDeptId.get());
  306 + CollectionUtils.addIfNotNull(result.getDeptIds(), userDeptId.get());
307 307 continue;
308 308 }
309 309 // 情况三,DEPT_ONLY
... ... @@ -313,9 +313,14 @@ public class PermissionServiceImpl implements PermissionService {
313 313 }
314 314 // 情况四,DEPT_DEPT_AND_CHILD
315 315 if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_AND_CHILD.getScope())) {
316   - CollUtil.addAll(result.getDeptIds(), deptService.getChildDeptIdListFromCache(userDeptId.get()));
  316 + Long deptId = userDeptId.get();
  317 + // 用户未设置部门,直接跳过;否则 getChildDeptIdListFromCache 走缓存注解会因 null key 报错
  318 + if (deptId == null) {
  319 + continue;
  320 + }
  321 + CollUtil.addAll(result.getDeptIds(), deptService.getChildDeptIdListFromCache(deptId));
317 322 // 添加本身部门编号
318   - CollUtil.addAll(result.getDeptIds(), userDeptId.get());
  323 + result.getDeptIds().add(deptId);
319 324 continue;
320 325 }
321 326 // 情况五,SELF
... ...
yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
... ... @@ -441,6 +441,34 @@ public class PermissionServiceTest extends BaseDbUnitTest {
441 441 }
442 442  
443 443 @Test
  444 + public void testGetDeptDataPermission_DeptCustom_userDeptIdNull() {
  445 + try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
  446 + springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
  447 + .thenReturn(permissionService);
  448 +
  449 + // 准备参数
  450 + Long userId = 1L;
  451 + // mock 用户的角色编号
  452 + userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L));
  453 + // mock 获得用户的角色
  454 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope())
  455 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  456 + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO));
  457 + // mock 部门的返回:用户未设置部门
  458 + when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO()); // deptId 为 null
  459 +
  460 + // 调用
  461 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
  462 + // 断言:角色配置的可见部门仍正常加入,但 null 不进集合
  463 + assertFalse(result.getAll());
  464 + assertFalse(result.getSelf());
  465 + assertEquals(roleDO.getDataScopeDeptIds().size(), result.getDeptIds().size());
  466 + assertTrue(CollUtil.containsAll(result.getDeptIds(), roleDO.getDataScopeDeptIds()));
  467 + assertFalse(result.getDeptIds().contains(null));
  468 + }
  469 + }
  470 +
  471 + @Test
444 472 public void testGetDeptDataPermission_DeptOnly() {
445 473 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
446 474 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
... ... @@ -501,6 +529,33 @@ public class PermissionServiceTest extends BaseDbUnitTest {
501 529 }
502 530  
503 531 @Test
  532 + public void testGetDeptDataPermission_DeptAndChild_userDeptIdNull() {
  533 + try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
  534 + springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
  535 + .thenReturn(permissionService);
  536 +
  537 + // 准备参数
  538 + Long userId = 1L;
  539 + // mock 用户的角色编号
  540 + userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L));
  541 + // mock 获得用户的角色
  542 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope())
  543 + .setStatus(CommonStatusEnum.ENABLE.getStatus()));
  544 + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO));
  545 + // mock 部门的返回:用户未设置部门
  546 + when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO()); // deptId 为 null
  547 +
  548 + // 调用
  549 + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
  550 + // 断言:deptId 为 null,整段跳过;deptIds 为空,子部门查询不被触发
  551 + assertFalse(result.getAll());
  552 + assertFalse(result.getSelf());
  553 + assertTrue(CollUtil.isEmpty(result.getDeptIds()));
  554 + verify(deptService, never()).getChildDeptIdListFromCache(any());
  555 + }
  556 + }
  557 +
  558 + @Test
504 559 public void testGetDeptDataPermission_Self() {
505 560 try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
506 561 springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
... ...