From df7eae612588cac5e0fd303925840443977b26d9 Mon Sep 17 00:00:00 2001 From: zhonghua Date: Wed, 8 Apr 2026 11:13:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BA=AF=E8=AF=84=E5=A7=94=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E9=9A=90=E8=97=8F=E6=9C=BA=E6=9E=84=E7=AB=AF=E8=AF=84?= =?UTF-8?q?=E5=A7=94=E7=AE=A1=E7=90=86=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Made-with: Cursor --- .../sys/service/impl/SysMenuServiceImpl.java | 33 ++++++++++++++++--- docs/design/menu-config.md | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/backend-java/src/main/java/com/competition/modules/sys/service/impl/SysMenuServiceImpl.java b/backend-java/src/main/java/com/competition/modules/sys/service/impl/SysMenuServiceImpl.java index da3edfa..ea73828 100644 --- a/backend-java/src/main/java/com/competition/modules/sys/service/impl/SysMenuServiceImpl.java +++ b/backend-java/src/main/java/com/competition/modules/sys/service/impl/SysMenuServiceImpl.java @@ -61,12 +61,11 @@ public class SysMenuServiceImpl extends ServiceImpl impl new LambdaQueryWrapper().eq(SysTenantMenu::getTenantId, tenantId)); Set tenantMenuIds = new HashSet<>(tenantMenus.stream().map(SysTenantMenu::getMenuId).collect(Collectors.toSet())); + List roles = isSuperAdmin ? Collections.emptyList() : userMapper.selectRolesByUserId(userId); + // 租户评委与平台评委共用「我的评审」菜单树:机构租户未在 t_sys_tenant_menu 中配置时,按角色合并评委端菜单 - if (!isSuperAdmin) { - List roles = userMapper.selectRolesByUserId(userId); - if (roles != null && roles.contains("judge")) { - tenantMenuIds.addAll(collectJudgePortalMenuIds(allMenus)); - } + if (!isSuperAdmin && roles != null && roles.contains("judge")) { + tenantMenuIds.addAll(collectJudgePortalMenuIds(allMenus)); } if (isSuperAdmin) { @@ -88,10 +87,14 @@ public class SysMenuServiceImpl extends ServiceImpl impl List userPermissions = userMapper.selectPermissionsByUserId(userId); Set permSet = new HashSet<>(userPermissions); + // 纯评委角色不展示机构端「评委管理」(与 judge:read 权限码重叠,否则侧栏会出现该菜单) + boolean hideTenantJudgeMgmtForPureJudge = shouldHideTenantJudgeManagementMenuForJudge(roles); + // 过滤:菜单必须属于租户,且用户有对应权限(无权限要求的菜单直接放行) List filteredMenus = allMenus.stream() .filter(menu -> tenantMenuIds.contains(menu.getId())) .filter(menu -> menu.getPermission() == null || menu.getPermission().isBlank() || permSet.contains(menu.getPermission())) + .filter(menu -> !hideTenantJudgeMgmtForPureJudge || !isTenantJudgeManagementMenu(menu)) .collect(Collectors.toList()); // 补全父菜单(确保树结构完整) @@ -176,6 +179,26 @@ public class SysMenuServiceImpl extends ServiceImpl impl .collect(Collectors.toList()); } + /** 机构租户「评委管理」页(非评委工作台) */ + private static final String TENANT_JUDGE_MANAGEMENT_COMPONENT = "contests/judges/Index"; + + /** + * 仅评委角色(无 tenant_admin / super_admin)不展示机构端评委管理菜单 + */ + private boolean shouldHideTenantJudgeManagementMenuForJudge(List roles) { + if (roles == null || roles.isEmpty()) { + return false; + } + if (!roles.contains("judge")) { + return false; + } + return !roles.contains("tenant_admin") && !roles.contains("super_admin"); + } + + private boolean isTenantJudgeManagementMenu(SysMenu menu) { + return TENANT_JUDGE_MANAGEMENT_COMPONENT.equals(menu.getComponent()); + } + /** * 评委端菜单:评审任务、预设评语及其父级(与 docs/design/menu-config 一致,不依赖固定菜单 ID) */ diff --git a/docs/design/menu-config.md b/docs/design/menu-config.md index d2907e0..869f899 100644 --- a/docs/design/menu-config.md +++ b/docs/design/menu-config.md @@ -116,7 +116,7 @@ - **平台评委**:在评委租户(`code=judge`)登录,见第三节「评委端」,`t_sys_tenant_menu` 仅含 **34、35、36**。 - **租户评委**:在机构租户(如 `tenantCode=test2`)登录,角色为 `judge`,与平台评委使用**同一套**「我的评审」菜单(仍为 **34、35、36** 对应的 `component`:`activities/Review`、`activities/PresetComments` 及父级)。 -- **实现**:`GET /api/menus/user-menus` 在 `SysMenuServiceImpl.getUserMenus` 中,若当前用户角色含 `judge`,会在 `t_sys_tenant_menu` 基础上**合并**评委端菜单(按组件路径识别,不依赖固定 ID);评委角色权限由 `JudgeRolePermissionConfigurer` 与 `JudgesManagementServiceImpl` 保证与上表「评委端权限码」一致,以便 `/api/auth/user-info` 的 `permissions` 与菜单 `permission` 字段匹配。 +- **实现**:`GET /api/menus/user-menus` 在 `SysMenuServiceImpl.getUserMenus` 中,若当前用户角色含 `judge`,会在 `t_sys_tenant_menu` 基础上**合并**评委端菜单(按组件路径识别,不依赖固定 ID);评委角色权限由 `JudgeRolePermissionConfigurer` 与 `JudgesManagementServiceImpl` 保证与上表「评委端权限码」一致,以便 `/api/auth/user-info` 的 `permissions` 与菜单 `permission` 字段匹配。纯评委(仅有 `judge`、无 `tenant_admin`/`super_admin`)**不展示**机构端「评委管理」菜单(`component=contests/judges/Index`),避免与 `judge:read` 权限码重叠导致误显。 - **可选**:若希望机构租户在「菜单管理」中显式看到评委菜单,也可在 `t_sys_tenant_menu` 中手工追加 **34、35、36**(与第三节一致),与合并逻辑效果相同。 ### 租户端系统设置不包含的子菜单