From f55c865ab13eb8ad4aa9ef46501980a5906f435f Mon Sep 17 00:00:00 2001 From: chenxing Date: Tue, 11 Aug 2026 22:43:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=9D=83=E9=99=90=E4=BF=AE?= =?UTF-8?q?=E8=AE=A2=EF=BC=8C=E8=B6=85=E7=AE=A1=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userbase/controller/oapi/UserController.java | 6 +++--- .../userbase/service/impl/GroupAuthzService.java | 6 ++++++ .../userbase/service/impl/GroupAuthzServiceTest.java | 12 ++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java b/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java index de6438d..7fddf7e 100644 --- a/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java +++ b/src/main/java/com/yunhai/userbase/controller/oapi/UserController.java @@ -76,9 +76,9 @@ public class UserController { return Collections.emptyList(); } Integer effectiveGroupId = resolveEffectiveGroupId(userId, schId); - if (effectiveGroupId == null) { - return Collections.emptyList(); - } + // 注意:超管即使没有学校/归属组,service.findUserPermissionTree 内部也会走超管短路返回全部权限, + // 因此这里不能因 effectiveGroupId 为 null 直接返回空,否则超管在 oapi/user/modules 永远拿不到权限; + // 普通用户无组/无学校时,findUserPermissionTree 同样会返回空列表,行为一致。 List tree = groupAuthzService.findUserPermissionTree(effectiveGroupId, userId); if (tree == null || tree.isEmpty()) { return Collections.emptyList(); diff --git a/src/main/java/com/yunhai/userbase/service/impl/GroupAuthzService.java b/src/main/java/com/yunhai/userbase/service/impl/GroupAuthzService.java index 2922d5e..fc4c51d 100644 --- a/src/main/java/com/yunhai/userbase/service/impl/GroupAuthzService.java +++ b/src/main/java/com/yunhai/userbase/service/impl/GroupAuthzService.java @@ -1188,6 +1188,12 @@ public class GroupAuthzService implements IGroupAuthzService { public boolean hasModulePermission(Integer userId, Integer moduleId) { Objects.requireNonNull(userId, "用户ID不能为空"); Objects.requireNonNull(moduleId, "模块ID不能为空"); + // 超级管理员(UserTypeEnum.SUPER_ADMIN / 基石账号):直接赋予全部模块权限, + // 不做任何组/角色/继承判定——避免「超管不归属任何组 → userRels 为空 → 直接返回 false(即无任何权限)」的 bug。 + SysUser user = sysUserRepository.findById(userId).orElse(null); + if (user != null && isSuperAdmin(user.getType(), userId)) { + return true; + } AppModule module = appModuleRepository.findById(moduleId).orElse(null); if (module == null) { return false; diff --git a/src/test/java/com/yunhai/userbase/service/impl/GroupAuthzServiceTest.java b/src/test/java/com/yunhai/userbase/service/impl/GroupAuthzServiceTest.java index b342f68..25ef956 100644 --- a/src/test/java/com/yunhai/userbase/service/impl/GroupAuthzServiceTest.java +++ b/src/test/java/com/yunhai/userbase/service/impl/GroupAuthzServiceTest.java @@ -429,6 +429,18 @@ class GroupAuthzServiceTest { "教师组29勾选的模块10应可访问"); } + @Test + void hasModulePermission_whenSuperAdmin_shouldReturnTrueRegardlessOfGroup() { + // 超级管理员:type=SUPER_ADMIN,且不归属任何组(超管通常不在任何组下) + when(sysUserRepository.findById(1)).thenReturn(Optional.of(user(1, UserTypeEnum.SUPER_ADMIN))); + when(sysUserGroupRelRepository.findByUserId(1)).thenReturn(Collections.emptyList()); + + assertTrue(groupAuthzService.hasModulePermission(1, 8), + "超级管理员应直接拥有全部模块权限,无需归属组/角色(修复「超管无组→返回false」的 bug)"); + assertTrue(groupAuthzService.hasModulePermission(1, 100), + "超级管理员对任意模块都应返回 true"); + } + // ===================== helper ===================== private SysGroup group(Integer id, String name, Integer parentId, GroupTypeEnum type) {