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 ddb82da..de7645e 100644 --- a/src/main/java/com/yunhai/userbase/service/impl/GroupAuthzService.java +++ b/src/main/java/com/yunhai/userbase/service/impl/GroupAuthzService.java @@ -597,16 +597,22 @@ public class GroupAuthzService implements IGroupAuthzService { // ============================================================ // 超级管理员(UserTypeEnum.SUPER_ADMIN,type=1):直接返回所有已开通应用下的全部模块,不做任何组/继承判定 // ============================================================ - if (isSuperAdmin(user.getType())) { + if (isSuperAdmin(user.getType(), userId)) { return buildSuperAdminAllPermissions(); } // AI-FIX(角色授权): 先取用户经「启用」角色获得的模块ID集合,与组授权做并集; // 角色授权不依赖组归属与组开通应用,故下方不再因无组归属而提前返回 Set roleModuleIds = collectEnabledRoleModuleIds(userId); - // 1. 用户所属的全部组 + // 1. 用户所属的全部组 + 【强制包含接口传入的 groupId 上下文】 + // 场景修复:管理员在「组8的授权面板」给模块M打勾(写 sys_group_module_perm 组8的记录), + // 然后同面板点「用户权限一览」UserPermissionTree?userId=X&groupId=8,必须读到组8的设置, + // 即便用户X还没加入组8(预览模式、或界面只做"组视角下的权限查询");否则"本组设置"不生效。 List userRels = sysUserGroupRelRepository.findByUserId(userId); Set selfGroupIds = new LinkedHashSet<>(); + if (groupId != null) { + selfGroupIds.add(groupId); + } for (SysUserGroupRel rel : userRels) { if (rel.getGroupId() != null) { selfGroupIds.add(rel.getGroupId()); @@ -890,7 +896,14 @@ public class GroupAuthzService implements IGroupAuthzService { if (selfPerm != null) { return true; } - // 第二段:本组无记录 → 向上继承查找;遇到第一个学校组(SCHOOL_GROUP)就包含它自己,处理完停止(不跨学校) + // 本组无记录 → 第二段:继承查找。 + // 如果「本组本身就是学校组」:学校组已经是继承上限,学校组之上(区域/教育局/根)不再允许查找,直接跳过本段。 + // 否则(本组是班级/年级/教师/学生等学校内子组):沿祖先向上,直到包含第一个学校组为止,出了学校组立刻break,不跨学校。 + SysGroup selfG = allGroupMap.get(selfGroupId); + boolean selfIsSchool = selfG != null && selfG.getType() == GroupTypeEnum.SCHOOL_GROUP; + if (selfIsSchool) { + continue; + } for (Integer ancestorId : chain) { if (Objects.equals(ancestorId, selfGroupId)) { continue; @@ -913,10 +926,16 @@ public class GroupAuthzService implements IGroupAuthzService { // ===================== 超级管理员 & 工具方法 ===================== /** - * 超级管理员 type=1(UserTypeEnum.SUPER_ADMIN / DicUtil.USER_TYPE_SUPER_MANAGER=1) + * 超级管理员判定: + * ① 用户记录的 type = UserTypeEnum.SUPER_ADMIN(1);或 + * ② userId = DicUtil.SUPER_ADMIN_ID(100000,系统内置基石超级管理员账号)。 + * 任一命中即可视为超级管理员,直接授予全部模块权限。 */ - private static boolean isSuperAdmin(UserTypeEnum userType) { - return userType != null && UserTypeEnum.SUPER_ADMIN.getKey().equals(userType.getKey()); + private static boolean isSuperAdmin(UserTypeEnum userType, Integer userId) { + if (userType != null && UserTypeEnum.SUPER_ADMIN.getKey().equals(userType.getKey())) { + return true; + } + return userId != null && com.yunhai.userbase.utils.DicUtil.SUPER_ADMIN_ID.equals(userId); } /**