链首即自身({@link #ancestorChain} 由自身向根排列),天然「就近优先」;遍历时第一个 + *
+ * 链首即自身({@link #ancestorChain} 由自身向根排列),天然「就近优先」;遍历时第一个 * 「groupConfiguredApps 中包含该应用」的组即作为该应用在本组范围内的唯一权限来源返回。 * - *
学校截止:遇到学校组(无论是否已配置)即作为继承上限,不再向教育局/根越级,避免跨学校继承到未开通的应用。 + *
+ * 学校截止:遇到学校组(无论是否已配置)即作为继承上限,不再向教育局/根越级,避免跨学校继承到未开通的应用。 * - *
找不到返回 null(该应用在此范围内没有任何组的显式配置,对应模块不许可)。 + *
+ * 找不到返回 null(该应用在此范围内没有任何组的显式配置,对应模块不许可)。
*/
private Integer findNearestAuthorityGroup(Integer groupId, List 规则(修复「父级未勾子组继承却仍被继承」的 bug):
+ *
+ * 规则(修复「父级未勾子组继承却仍被继承」的 bug):
* ① 来源组 == 本组:本组自身勾选的模块直接生效——{@code inheritFlag} 只约束是否下放到子组,不影响本组自己;
* ② 来源组为祖先(往上回溯得来):必须勾选了「子组继承」({@code inheritFlag=true}) 才会下放到本组,
* 否则该模块不继承。即「只过滤勾选了子组继承的模块;若来源组对该应用所有模块都没勾子组继承,则本组对该应用返回空」。
@@ -933,7 +1138,8 @@ public class GroupAuthzService implements IGroupAuthzService {
/**
* 用户维度权限判定:用户对指定模块是否有权限(就近原则 + 学校截止 + 角色授权并集 + 超管兜底)。
*
- * 就近原则(统一了「本组覆盖」与「最近祖先继承」两种情形,修复两类合并 bug):
+ *
+ * 就近原则(统一了「本组覆盖」与「最近祖先继承」两种情形,修复两类合并 bug):
* 沿 selfGroupId 的祖先链(含自身)向上,找到「离它最近、且对 appId 有任意显式模块配置」的组作为
* 该应用的唯一权限来源;该模块被许可,当且仅当这个来源组对它自身有显式 {@code sys_group_module_perm} 记录。
* 这样:
@@ -941,13 +1147,16 @@ public class GroupAuthzService implements IGroupAuthzService {
* ② 本组无配置(如英语组为空)→ 取最近的有配置祖先(如教师组)为来源,不再越级到更远的学校组;
* ③ 来源组的模块集合即最终集合,更上层同应用模块(如学校组多勾的模块8)一律不合并。
*
- * 子组继承闸门(修复「父级未勾子组继承仍被继承」的 bug):来源组若是本组,本组勾选的模块直接生效;
+ *
+ * 子组继承闸门(修复「父级未勾子组继承仍被继承」的 bug):来源组若是本组,本组勾选的模块直接生效;
* 来源组若是祖先,必须该模块记录 {@code inheritFlag=true}(勾选子组继承)才下放到本组,否则不继承——
* 即「只过滤勾选了子组继承的模块;若来源组对该应用所有模块都没勾子组继承,则本组对该应用返回空」。
*
- * 学校截止:祖先链只查到第一个学校组(含)为止,不跨学校到教育局/根。
+ *
+ * 学校截止:祖先链只查到第一个学校组(含)为止,不跨学校到教育局/根。
*
- * 其余:归属组需已开通该模块所属应用(双保险,防越权)。
+ *
+ * 其余:归属组需已开通该模块所属应用(双保险,防越权)。
*/
private boolean hasUserModulePermission(Integer moduleId, Integer appId,
Set