From 96855a8565bfa57b5ce55ed8f79b3a147be66382 Mon Sep 17 00:00:00 2001 From: chenxing Date: Fri, 9 Oct 2026 17:36:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(identity):=20=E5=8F=AF=E9=80=89=E8=BA=AB?= =?UTF-8?q?=E4=BB=BD=E5=88=97=E8=A1=A8=E6=8E=92=E5=BA=8F=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E3=80=8C=E4=B8=BB=E6=A0=A1=E7=BD=AE=E9=A1=B6=E2=86=92=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E6=A0=A1=20schId=20=E5=8D=87=E5=BA=8F=E2=86=92?= =?UTF-8?q?=E6=A0=A1=E5=86=85=20roleId=20=E5=8D=87=E5=BA=8F=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复同校多身份被主身份提升拆到头尾(如云海小学教师置顶、管理员落尾)。新增 IdentityService.sortForDisplay 统一 /oapi/user/roles 与 /oapi/identity/available 顺序;主身份行不再单独置顶,主校内部一律按 roleId(老师1→校领导2→管理员7),其余学校按 schId 升序。 --- .../controller/oapi/IdentityController.java | 3 +- .../service/impl/IdentityService.java | 30 ++++++++++++++----- .../userbase/service/impl/SysUserService.java | 15 ++++------ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/yunhai/userbase/controller/oapi/IdentityController.java b/src/main/java/com/yunhai/userbase/controller/oapi/IdentityController.java index dac5fe5..7dda4e8 100644 --- a/src/main/java/com/yunhai/userbase/controller/oapi/IdentityController.java +++ b/src/main/java/com/yunhai/userbase/controller/oapi/IdentityController.java @@ -56,7 +56,8 @@ public class IdentityController { } /** - * 用户全部可选身份(正常态),按 主身份优先 → sortNo → id 排序,供「切换身份」页渲染。 + * 用户全部可选身份(正常态),按 主身份所在学校置顶 → 其他学校 schoolId 升序 → 校内 roleId 升序, + * 供「切换身份」页渲染。 */ @GetMapping("available") public List available(@RequestParam("userId") Integer userId) { diff --git a/src/main/java/com/yunhai/userbase/service/impl/IdentityService.java b/src/main/java/com/yunhai/userbase/service/impl/IdentityService.java index ae26459..bde825f 100644 --- a/src/main/java/com/yunhai/userbase/service/impl/IdentityService.java +++ b/src/main/java/com/yunhai/userbase/service/impl/IdentityService.java @@ -76,17 +76,12 @@ public class IdentityService { /** * 用户全部可选身份(正常态),用于「切换身份」页渲染。 - * 排序:主身份优先 → sortNo 升序 → id 升序(「未切换默认第一个」的确定性保证)。 + * 排序见 {@link #sortForDisplay}:主身份所在学校置顶 → 其他学校 schoolId 升序 → 校内 roleId 升序。 */ public List listAvailable(Integer userId) { List rels = sysUserRoleRelRepository.findByUserIdAndStatus(userId, StatusEnum.NORMAL); SysUserRoleRel main = resolveMainIdentity(userId); - List sorted = rels.stream() - .sorted(Comparator.comparingInt((SysUserRoleRel r) -> - main != null && Objects.equals(r.getId(), main.getId()) ? 0 : 1) - .thenComparingInt(SysUserRoleRel::getSortNo) - .thenComparingInt(SysUserRoleRel::getId)) - .collect(Collectors.toList()); + List sorted = sortForDisplay(rels, main); List result = new ArrayList<>(sorted.size()); for (SysUserRoleRel rel : sorted) { result.add(toBoaRoleInfo(rel.getRoleId(), rel.getSchoolId())); @@ -94,6 +89,27 @@ public class IdentityService { return result; } + /** + * 身份列表展示排序({@link #listAvailable} 与 {@code SysUserService#findUserRoles} 共用,保证两接口同序):
+ * ① 主身份所在学校整体置顶(主身份是该校教师或管理员均成立);
+ * ② 其余学校按 schoolId 升序;
+ * ③ 校内按 roleId 升序(老师1 → 校领导2 → 管理员7);
+ * ④ 兜底 id 升序。
+ * 主身份行不再单独置顶:主校内部一律按 roleId,故主身份为管理员时该校教师仍排其前。 + * 「未切换默认激活身份」由 {@link #getCurrent} 独立解析,不依赖本列表首元素。 + */ + public static List sortForDisplay(List rels, SysUserRoleRel main) { + Integer mainSchoolId = main != null ? main.getSchoolId() : null; + return rels.stream() + .sorted(Comparator + .comparingInt((SysUserRoleRel r) -> + Objects.equals(r.getSchoolId(), mainSchoolId) ? 0 : 1) + .thenComparingInt(SysUserRoleRel::getSchoolId) + .thenComparingInt(SysUserRoleRel::getRoleId) + .thenComparingInt(SysUserRoleRel::getId)) + .collect(Collectors.toList()); + } + /** * 当前激活身份:优先读 sys_user_current_role;无切换记录时兜底主身份(动态解析,替代 is_main 物化字段)。 * 连主身份都没有时返回 null(前端引导创建身份)。

diff --git a/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java b/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java index 17fd987..8a4fde2 100644 --- a/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java +++ b/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java @@ -727,7 +727,8 @@ public class SysUserService implements ISysUserService { return new HashSet<>(sysGroupService.resolveSchoolIds(groupIds).values()); } - /** 身份行展示顺序:主身份优先 → sortNo → id(与 IdentityService.getUserRoles 同序)。 */ + /** 管理端列表「用户身份」单值列取首行用的顺序:主身份优先 → sortNo → id。 + * 注意:这与面向用户的身份列表 {@link IdentityService#sortForDisplay}(主校置顶 → 校内 roleId)不同,刻意保持。 */ private Comparator identityRowOrder(SysUserRoleRel mainRel) { return Comparator.comparingInt((SysUserRoleRel r) -> mainRel != null && Objects.equals(r.getId(), mainRel.getId()) ? 0 : 1) @@ -1486,16 +1487,12 @@ public class SysUserService implements ISysUserService { if (userId == null) { throw new DException("用户ID不能为空"); } - // 数据源:sys_user_role_rel(平台身份角色权威源),内存排序 主身份优先 → sortNo → id - // (修正:此前误读 sys_user_app_role_rel 业务权限角色 + 主归属组当学校,导致「本组」bug) + // 数据源:sys_user_role_rel(平台身份角色权威源),内存排序与 /oapi/identity/available 同序: + // 主身份所在学校置顶 → 其他学校 schoolId 升序 → 校内 roleId 升序(见 IdentityService#sortForDisplay) + // (修正历史:此前误读 sys_user_app_role_rel 业务权限角色 + 主归属组当学校,导致「本组」bug) List rels = sysUserRoleRelRepository.findByUserIdAndStatus(userId, StatusEnum.NORMAL); SysUserRoleRel mainRel = identityService.resolveMainIdentity(userId); - List sorted = rels.stream() - .sorted(Comparator.comparingInt((SysUserRoleRel r) -> - mainRel != null && Objects.equals(r.getId(), mainRel.getId()) ? 0 : 1) - .thenComparingInt(SysUserRoleRel::getSortNo) - .thenComparingInt(SysUserRoleRel::getId)) - .collect(Collectors.toList()); + List sorted = IdentityService.sortForDisplay(rels, mainRel); List result = new ArrayList<>(sorted.size()); for (SysUserRoleRel rel : sorted) { BoaRoleInfo info = new BoaRoleInfo();