Sfoglia il codice sorgente

feat(system): 增强菜单与用户服务以支持平台隔离

- 修改 ISysMenuService 接口,增加 platform 参数用于区分不同平台的菜单列表
- 更新 SysMenuMapper 和相关实现类,支持根据平台筛选菜单数据
- 调整 PlatformDataScopeInterceptor 拦截器逻辑,排除特定表并支持总控平台识别
- 在 PlatformTenantLineHandler 中添加对总控平台跳过租户过滤的支持
- 修改多个实体类继承关系,移除不必要的 platform_code 字段依赖
- 更新 SysUserController 与 SysUserServiceImpl,强化用户操作时的平台控制逻辑
- 调整角色授权接口 insertUserAuth 方法签名,加入 platform 参数传递
- 完善菜单控制器中权限校验注解,允许租户管理员访问部分菜单功能
- 优化菜单查询 SQL 映射文件,动态支持 platform_code 过滤条件
- 调整 SysRoleServiceImpl 中的角色菜单绑定逻辑,确保平台信息同步写入
- 修复 SysTenantServiceImpl 中分组字典数据时字段引用错误的问题
- 强化用户唯一性检查方法,补充 platform_code 条件避免跨平台冲突
HuRongxin 6 giorni fa
parent
commit
e02a2cc922
24 ha cambiato i file con 139 aggiunte e 49 eliminazioni
  1. 12 1
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  2. 14 2
      ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlatformTenantLineHandler.java
  3. 2 1
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOss.java
  4. 2 1
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOssConfig.java
  5. 2 1
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/SysOssBo.java
  6. 2 1
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/SysOssConfigBo.java
  7. 22 8
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
  8. 2 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
  9. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictData.java
  10. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictType.java
  11. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleDept.java
  12. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleMenu.java
  13. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserRole.java
  14. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysConfigBo.java
  15. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictDataBo.java
  16. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java
  17. 3 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMenuMapper.java
  18. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java
  19. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
  20. 16 4
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
  21. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
  22. 3 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java
  23. 33 12
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
  24. 5 1
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml

+ 12 - 1
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java

@@ -12,6 +12,7 @@ import org.apache.ibatis.mapping.MappedStatement;
 import org.apache.ibatis.mapping.SqlCommandType;
 import org.apache.ibatis.plugin.*;
 import org.dromara.common.core.context.PlatformContext;
+import org.dromara.common.core.enums.SysPlatformCode;
 import org.dromara.common.core.utils.StringUtils;
 
 import java.lang.reflect.Field;
@@ -42,6 +43,10 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "sys_post",
         "sys_user_post",
         "sys_config",
+        "sys_dict",
+        "sys_dict_type",
+        "sys_oss",
+        "sys_oss_config",
         "gen_table",
         "gen_table_column",
         "qrtz_"
@@ -52,7 +57,6 @@ public class PlatformDataScopeInterceptor implements Interceptor {
     public Object intercept(Invocation invocation) throws Throwable {
         StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
 
-        // 获取 mappedStatement
         Object delegate = ReflectUtil.getFieldValue(statementHandler, "delegate");
         MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
 
@@ -61,6 +65,13 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         }
 
         String platform = PlatformContext.getPlatform();
+
+        // 总控平台:直接放行,不注入任何条件
+        if (SysPlatformCode.MAIN.getCode().equals(platform)) {
+            return invocation.proceed(); // ← 核心:提前返回
+        }
+
+        // 原有逻辑:仅对非 main 平台生效
         if (StringUtils.isBlank(platform)) {
             return invocation.proceed();
         }

+ 14 - 2
ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlatformTenantLineHandler.java

@@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.StringValue;
 import org.dromara.common.core.context.PlatformContext;
+import org.dromara.common.core.enums.SysPlatformCode;
 import org.dromara.common.core.utils.StringUtils;
 
 import java.util.Arrays;
@@ -20,7 +21,7 @@ import java.util.Set;
 @Slf4j
 public class PlatformTenantLineHandler implements TenantLineHandler {
 
-    // 直接写死:不需要平台隔离的表(即不自动添加 platform_code 条件)
+    // 直接写死:不需要平台隔离的表(即不自动添加 platform_code 条件)
     private static final Set<String> PLATFORM_EXCLUDES = new HashSet<>(Arrays.asList(
         "sys_login_log",
         "sys_oper_log",
@@ -29,6 +30,10 @@ public class PlatformTenantLineHandler implements TenantLineHandler {
         "sys_post",
         "sys_user_post",
         "sys_config",
+        "sys_dict",
+        "sys_dict_type",
+        "sys_oss",
+        "sys_oss_config",
         "gen_table",
         "gen_table_column",
         "qrtz_"
@@ -42,10 +47,17 @@ public class PlatformTenantLineHandler implements TenantLineHandler {
     @Override
     public Expression getTenantId() {
         String platform = PlatformContext.getPlatform();
+
+        // 总控平台不加任何 platform_code 条件
+        if (SysPlatformCode.MAIN.getCode().equals(platform)) {
+            return null; // 核心:返回 null 表示禁用租户过滤
+        }
+
         if (StringUtils.isBlank(platform)) {
             log.debug("未设置平台上下文,跳过 platform_code 隔离");
-            return null; // 不注入任何条件
+            return null;
         }
+
         return new StringValue(platform);
     }
 

+ 2 - 1
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOss.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.tenant.core.TenantEntity;
+import org.dromara.common.tenant.core.TenantEntityWithoutPlatformCode;
 
 /**
  * OSS对象存储对象
@@ -14,7 +15,7 @@ import org.dromara.common.tenant.core.TenantEntity;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_oss")
-public class SysOss extends TenantEntity {
+public class SysOss extends TenantEntityWithoutPlatformCode {
 
     /**
      * 对象存储主键

+ 2 - 1
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOssConfig.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 
 /**
  * 对象存储配置对象 sys_oss_config
@@ -14,7 +15,7 @@ import org.dromara.common.mybatis.core.domain.BaseEntity;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_oss_config")
-public class SysOssConfig extends BaseEntity {
+public class SysOssConfig extends BaseEntityWithoutPlatform {
 
     /**
      * 主键

+ 2 - 1
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/SysOssBo.java

@@ -4,6 +4,7 @@ import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 import org.dromara.resource.domain.SysOss;
 
 /**
@@ -14,7 +15,7 @@ import org.dromara.resource.domain.SysOss;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @AutoMapper(target = SysOss.class, reverseConvertGenerate = false)
-public class SysOssBo extends BaseEntity {
+public class SysOssBo extends BaseEntityWithoutPlatform {
 
     /**
      * ossId

+ 2 - 1
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/SysOssConfigBo.java

@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 import org.dromara.resource.domain.SysOssConfig;
 
 import jakarta.validation.constraints.NotBlank;
@@ -22,7 +23,7 @@ import jakarta.validation.constraints.Size;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @AutoMapper(target = SysOssConfig.class, reverseConvertGenerate = false)
-public class SysOssConfigBo extends BaseEntity {
+public class SysOssConfigBo extends BaseEntityWithoutPlatform {
 
     /**
      * 主键

+ 22 - 8
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java

@@ -94,8 +94,9 @@ public class SysMenuController extends BaseController {
      */
     @SaCheckPermission("system:menu:query")
     @GetMapping(value = "/roleMenuTreeselect/{roleId}")
-    public R<MenuTreeSelectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
-        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
+    public R<MenuTreeSelectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId,
+                                                  @RequestParam(value = "platformCode", required = false) String platformCode) {
+        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId(), platformCode);
         MenuTreeSelectVo selectVo = new MenuTreeSelectVo(
             menuService.selectMenuListByRoleId(roleId),
             menuService.buildMenuTreeSelect(menus));
@@ -107,11 +108,15 @@ public class SysMenuController extends BaseController {
      *
      * @param packageId 租户套餐ID
      */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckRole(value = {
+        TenantConstants.SUPER_ADMIN_ROLE_KEY,
+        TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
     @SaCheckPermission("system:menu:query")
     @GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}")
-    public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) {
-        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
+    public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId,
+                                                           @RequestParam(value = "platformCode", required = false) String platformCode) {
+        List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId(), platformCode);
         List<Tree<Long>> list = menuService.buildMenuTreeSelect(menus);
         // 删除租户管理菜单
         list.removeIf(menu -> menu.getId() == 6L);
@@ -126,7 +131,10 @@ public class SysMenuController extends BaseController {
     /**
      * 新增菜单
      */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckRole(value = {
+        TenantConstants.SUPER_ADMIN_ROLE_KEY,
+        TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
     @SaCheckPermission("system:menu:add")
     @Log(title = "菜单管理", businessType = BusinessType.INSERT)
     @PostMapping
@@ -142,7 +150,10 @@ public class SysMenuController extends BaseController {
     /**
      * 修改菜单
      */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckRole(value = {
+        TenantConstants.SUPER_ADMIN_ROLE_KEY,
+        TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
     @SaCheckPermission("system:menu:edit")
     @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
     @PutMapping
@@ -162,7 +173,10 @@ public class SysMenuController extends BaseController {
      *
      * @param menuId 菜单ID
      */
-    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @SaCheckRole(value = {
+        TenantConstants.SUPER_ADMIN_ROLE_KEY,
+        TenantConstants.TENANT_ADMIN_ROLE_KEY
+    }, mode = SaMode.OR)
     @SaCheckPermission("system:menu:remove")
     @Log(title = "菜单管理", businessType = BusinessType.DELETE)
     @DeleteMapping("/{menuId}")

+ 2 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java

@@ -156,7 +156,7 @@ public class SysUserController extends BaseController {
     @SaCheckPermission("system:user:add")
     @Log(title = "用户管理", businessType = BusinessType.INSERT)
     @PostMapping
-    public R<Void> add(@Validated @RequestBody SysUserBo user) {
+    public R<Void> add(@Validated @RequestBody SysUserBo user ) {
         deptService.checkDeptDataScope(user.getDeptId());
         if (!userService.checkUserNameUnique(user)) {
             return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
@@ -276,7 +276,7 @@ public class SysUserController extends BaseController {
     @PutMapping("/authRole")
     public R<Void> insertAuthRole(Long userId, Long[] roleIds) {
         userService.checkUserDataScope(userId);
-        userService.insertUserAuth(userId, roleIds);
+        userService.insertUserAuth(userId, roleIds,null);
         return R.ok();
     }
 

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictData.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.core.constant.SystemConstants;
 import org.dromara.common.tenant.core.TenantEntity;
+import org.dromara.common.tenant.core.TenantEntityWithoutPlatformCode;
 
 /**
  * 字典数据表 sys_dict_data
@@ -16,7 +17,7 @@ import org.dromara.common.tenant.core.TenantEntity;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_dict_data")
-public class SysDictData extends TenantEntity {
+public class SysDictData extends TenantEntityWithoutPlatformCode {
 
     /**
      * 字典编码

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDictType.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.tenant.core.TenantEntity;
+import org.dromara.common.tenant.core.TenantEntityWithoutPlatformCode;
 
 /**
  * 字典类型表 sys_dict_type
@@ -15,7 +16,7 @@ import org.dromara.common.tenant.core.TenantEntity;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_dict_type")
-public class SysDictType extends TenantEntity {
+public class SysDictType extends TenantEntityWithoutPlatformCode {
 
     /**
      * 字典主键

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleDept.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
+import org.dromara.common.tenant.core.PlatformEntity;
 
 /**
  * 角色和部门关联 sys_role_dept
@@ -13,7 +14,7 @@ import lombok.Data;
 
 @Data
 @TableName("sys_role_dept")
-public class SysRoleDept {
+public class SysRoleDept extends PlatformEntity {
 
     /**
      * 角色ID

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRoleMenu.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
+import org.dromara.common.tenant.core.PlatformEntity;
 
 /**
  * 角色和菜单关联 sys_role_menu
@@ -13,7 +14,7 @@ import lombok.Data;
 
 @Data
 @TableName("sys_role_menu")
-public class SysRoleMenu {
+public class SysRoleMenu extends PlatformEntity {
 
     /**
      * 角色ID

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUserRole.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
+import org.dromara.common.tenant.core.PlatformEntity;
 
 /**
  * 用户和角色关联 sys_user_role
@@ -13,7 +14,7 @@ import lombok.Data;
 
 @Data
 @TableName("sys_user_role")
-public class SysUserRole {
+public class SysUserRole extends PlatformEntity {
 
     /**
      * 用户ID

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysConfigBo.java

@@ -7,6 +7,7 @@ import jakarta.validation.constraints.Size;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 import org.dromara.system.domain.SysConfig;
 
 /**
@@ -18,7 +19,7 @@ import org.dromara.system.domain.SysConfig;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @AutoMapper(target = SysConfig.class, reverseConvertGenerate = false)
-public class SysConfigBo extends BaseEntity {
+public class SysConfigBo extends BaseEntityWithoutPlatform {
 
     /**
      * 参数主键

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictDataBo.java

@@ -7,6 +7,7 @@ import jakarta.validation.constraints.Size;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 import org.dromara.system.domain.SysDictData;
 
 /**
@@ -18,7 +19,7 @@ import org.dromara.system.domain.SysDictData;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @AutoMapper(target = SysDictData.class, reverseConvertGenerate = false)
-public class SysDictDataBo extends BaseEntity {
+public class SysDictDataBo extends BaseEntityWithoutPlatform {
 
     /**
      * 字典编码

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java

@@ -8,6 +8,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.core.constant.RegexConstants;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 import org.dromara.system.domain.SysDictType;
 
 /**
@@ -19,7 +20,7 @@ import org.dromara.system.domain.SysDictType;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @AutoMapper(target = SysDictType.class, reverseConvertGenerate = false)
-public class SysDictTypeBo extends BaseEntity {
+public class SysDictTypeBo extends BaseEntityWithoutPlatform {
 
     /**
      * 字典主键

+ 3 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMenuMapper.java

@@ -47,10 +47,11 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
      *
      * @return 菜单列表
      */
-    default List<SysMenu> selectMenuTreeAll() {
+    default List<SysMenu> selectMenuTreeAll(String platform) {
         LambdaQueryWrapper<SysMenu> lqw = new LambdaQueryWrapper<SysMenu>()
             .in(SysMenu::getMenuType, SystemConstants.TYPE_DIR, SystemConstants.TYPE_MENU)
             .eq(SysMenu::getStatus, SystemConstants.NORMAL)
+            .eq(SysMenu::getPlatformCode, platform)
             .orderByAsc(SysMenu::getParentId)
             .orderByAsc(SysMenu::getOrderNum);
         return this.selectList(lqw);
@@ -62,7 +63,7 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
      * @param userId 用户ID
      * @return 菜单列表
      */
-    List<SysMenu> selectMenuTreeByUserId(Long userId);
+    List<SysMenu> selectMenuTreeByUserId(Long userId, String platform);
 
     /**
      * 根据角色ID查询菜单树信息

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java

@@ -22,7 +22,7 @@ public interface ISysMenuService {
      * @param userId 用户ID
      * @return 菜单列表
      */
-    List<SysMenuVo> selectMenuList(Long userId);
+    List<SysMenuVo> selectMenuList(Long userId,String platform);
 
     /**
      * 根据用户查询系统菜单列表

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java

@@ -1,5 +1,6 @@
 package org.dromara.system.service;
 
+import org.apache.ibatis.jdbc.Null;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.system.domain.bo.SysUserBo;
@@ -165,7 +166,7 @@ public interface ISysUserService {
      * @param userId  用户ID
      * @param roleIds 角色组
      */
-    void insertUserAuth(Long userId, Long[] roleIds);
+    void insertUserAuth(Long userId, Long[] roleIds, String platform);
 
     /**
      * 修改用户状态

+ 16 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.context.PlatformContext;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -54,8 +55,10 @@ public class SysMenuServiceImpl implements ISysMenuService {
      * @return 菜单列表
      */
     @Override
-    public List<SysMenuVo> selectMenuList(Long userId) {
-        return selectMenuList(new SysMenuBo(), userId);
+    public List<SysMenuVo> selectMenuList(Long userId, String platformCode) {
+        SysMenuBo sysMenuBo = new SysMenuBo();
+        sysMenuBo.setPlatformCode(platformCode);
+        return selectMenuList(sysMenuBo, userId);
     }
 
     /**
@@ -73,6 +76,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
                 .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
                 .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
                 .eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
+                .eq(StringUtils.isNotBlank(menu.getPlatformCode()), SysMenu::getPlatformCode, menu.getPlatformCode())
                 .eq(StringUtils.isNotBlank(menu.getMenuType()), SysMenu::getMenuType, menu.getMenuType())
                 .eq(ObjectUtil.isNotNull(menu.getParentId()), SysMenu::getParentId, menu.getParentId())
                 .orderByAsc(SysMenu::getParentId)
@@ -83,6 +87,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
                 .like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
                 .eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
                 .eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
+                .eq(StringUtils.isNotBlank(menu.getPlatformCode()), "m.platform_code", menu.getPlatformCode())
                 .eq(StringUtils.isNotBlank(menu.getMenuType()), "m.menu_type", menu.getMenuType())
                 .eq(ObjectUtil.isNotNull(menu.getParentId()), "m.parent_id", menu.getParentId())
                 .orderByAsc("m.parent_id")
@@ -138,10 +143,12 @@ public class SysMenuServiceImpl implements ISysMenuService {
     @Override
     public List<SysMenu> selectMenuTreeByUserId(Long userId) {
         List<SysMenu> menus;
+        /*当前平台标识*/
+        String platform = PlatformContext.getPlatform();
         if (LoginHelper.isSuperAdmin(userId)) {
-            menus = baseMapper.selectMenuTreeAll();
+            menus = baseMapper.selectMenuTreeAll(platform);
         } else {
-            menus = baseMapper.selectMenuTreeByUserId(userId);
+            menus = baseMapper.selectMenuTreeByUserId(userId, platform);
         }
         return getChildPerms(menus, Constants.TOP_PARENT_ID);
     }
@@ -362,9 +369,14 @@ public class SysMenuServiceImpl implements ISysMenuService {
      */
     @Override
     public boolean checkMenuNameUnique(SysMenuBo menu) {
+        String platformCode = menu.getPlatformCode();
+        if (StringUtils.isBlank(platformCode)) {
+            platformCode = PlatformContext.getPlatform();
+        }
         boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysMenu>()
             .eq(SysMenu::getMenuName, menu.getMenuName())
             .eq(SysMenu::getParentId, menu.getParentId())
+            .eq(SysMenu::getPlatformCode, platformCode)
             .ne(ObjectUtil.isNotNull(menu.getMenuId()), SysMenu::getMenuId, menu.getMenuId()));
         return !exist;
     }

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java

@@ -218,7 +218,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
         if (ObjectUtil.isNotNull(role.getRoleId()) && LoginHelper.isSuperAdmin(role.getRoleId())) {
             throw new ServiceException("不允许操作超级管理员角色");
         }
-        String[] keys = new String[]{TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.TENANT_ADMIN_ROLE_KEY};
+        String[] keys = new String[]{TenantConstants.SUPER_ADMIN_ROLE_KEY};
         // 新增不允许使用 管理员标识符
         if (ObjectUtil.isNull(role.getRoleId())
             && StringUtils.equalsAny(role.getRoleKey(), keys)) {
@@ -356,6 +356,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
             SysRoleMenu rm = new SysRoleMenu();
             rm.setRoleId(role.getRoleId());
             rm.setMenuId(menuId);
+            rm.setPlatformCode(role.getPlatformCode());
             list.add(rm);
         }
         if (list.size() > 0) {

+ 3 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java

@@ -24,6 +24,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.redis.utils.CacheUtils;
 import org.dromara.common.tenant.core.TenantEntity;
+import org.dromara.common.tenant.core.TenantEntityWithoutPlatformCode;
 import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.system.domain.*;
 import org.dromara.system.domain.bo.SysTenantBo;
@@ -412,9 +413,9 @@ public class SysTenantServiceImpl implements ISysTenantService {
             dictTypeList.addAll(dictTypeMapper.selectList());
             dictDataList.addAll(dictDataMapper.selectList());
         });
-        Map<String, List<SysDictType>> typeMap = StreamUtils.groupByKey(dictTypeList, TenantEntity::getTenantId);
+        Map<String, List<SysDictType>> typeMap = StreamUtils.groupByKey(dictTypeList, SysDictType::getTenantId);
         Map<String, Map<String, List<SysDictData>>> typeDataMap = StreamUtils.groupBy2Key(
-            dictDataList, TenantEntity::getTenantId, SysDictData::getDictType);
+            dictDataList, SysDictData::getTenantId, SysDictData::getDictType);
         // 管理租户字典数据
         List<SysDictType> defaultTypeMap = typeMap.get(TenantConstants.DEFAULT_TENANT_ID);
         Map<String, List<SysDictData>> defaultTypeDataMap = typeDataMap.get(TenantConstants.DEFAULT_TENANT_ID);

+ 33 - 12
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java

@@ -14,6 +14,8 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.constant.CacheNames;
 import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.context.PlatformContext;
+import org.dromara.common.core.enums.SysPlatformCode;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.*;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -241,6 +243,7 @@ public class SysUserServiceImpl implements ISysUserService {
     public boolean checkUserNameUnique(SysUserBo user) {
         boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
             .eq(SysUser::getUserName, user.getUserName())
+            .eq(SysUser::getPlatformCode, user.getPhonenumber())
             .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
         return !exist;
     }
@@ -254,6 +257,7 @@ public class SysUserServiceImpl implements ISysUserService {
     public boolean checkPhoneUnique(SysUserBo user) {
         boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
             .eq(SysUser::getPhonenumber, user.getPhonenumber())
+            .eq(SysUser::getPlatformCode, user.getPlatformCode())
             .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
         return !exist;
     }
@@ -267,6 +271,7 @@ public class SysUserServiceImpl implements ISysUserService {
     public boolean checkEmailUnique(SysUserBo user) {
         boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
             .eq(SysUser::getEmail, user.getEmail())
+            .eq(SysUser::getPlatformCode, user.getPlatformCode())
             .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
         return !exist;
     }
@@ -311,9 +316,14 @@ public class SysUserServiceImpl implements ISysUserService {
     @Transactional(rollbackFor = Exception.class)
     public int insertUser(SysUserBo user) {
         SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
-
+       // 1. 校验当前是否为总控平台(main),否则不能指定 platformCode
+        String currentPlatform = PlatformContext.getPlatform();
+        String targetPlatform = currentPlatform;
+        if (SysPlatformCode.MAIN.getCode().equals(currentPlatform)) {
+            targetPlatform = user.getPlatformCode();
+        }
         //在 "main" 平台上下文中执行插入,并获取返回值
-        Integer rows = PlatformContextUtil.executeWithPlatform("main", () -> {
+        Integer rows = PlatformContextUtil.executeWithPlatform(targetPlatform, () -> {
             return baseMapper.insert(sysUser); // MyBatis-Plus insert 返回 int(实际是 Integer)
         });
 
@@ -323,10 +333,9 @@ public class SysUserServiceImpl implements ISysUserService {
         // 后续操作(岗位、角色)是否也需要在 "main" 平台下执行?
         // 如果这些表也受 platform_code 控制,则同样需要包裹!
 
-        PlatformContextUtil.runWithPlatform("main", () -> {
             insertUserPost(user, false);
-            insertUserRole(user, false);
-        });
+            insertUserRole(user, false,targetPlatform);
+
         return rows;
     }
 
@@ -355,13 +364,24 @@ public class SysUserServiceImpl implements ISysUserService {
     @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#user.userId")
     @Transactional(rollbackFor = Exception.class)
     public int updateUser(SysUserBo user) {
+        // 1. 校验当前是否为总控平台(main),否则不能指定 platformCode
+        String currentPlatform = PlatformContext.getPlatform();
+        String targetPlatform = currentPlatform;
+        if (SysPlatformCode.MAIN.getCode().equals(currentPlatform)) {
+            targetPlatform = user.getPlatformCode();
+        }
+
         // 新增用户与角色管理
-        insertUserRole(user, true);
+        insertUserRole(user, true,targetPlatform);
         // 新增用户与岗位管理
         insertUserPost(user, true);
         SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
+
+        //在 "main" 平台上下文中执行插入,并获取返回值
         // 防止错误更新后导致的数据误删除
-        int flag = baseMapper.updateById(sysUser);
+        Integer flag = PlatformContextUtil.executeWithPlatform(targetPlatform, () -> {
+            return baseMapper.updateById(sysUser); // MyBatis-Plus insert 返回 int(实际是 Integer)
+        });
         if (flag < 1) {
             throw new ServiceException("修改用户" + user.getUserName() + "信息失败");
         }
@@ -376,8 +396,8 @@ public class SysUserServiceImpl implements ISysUserService {
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void insertUserAuth(Long userId, Long[] roleIds) {
-        insertUserRole(userId, roleIds, true);
+    public void insertUserAuth(Long userId, Long[] roleIds,String platformCode) {
+        insertUserRole(userId, roleIds, true,platformCode);
     }
 
     /**
@@ -449,8 +469,8 @@ public class SysUserServiceImpl implements ISysUserService {
      * @param user  用户对象
      * @param clear 清除已存在的关联数据
      */
-    private void insertUserRole(SysUserBo user, boolean clear) {
-        this.insertUserRole(user.getUserId(), user.getRoleIds(), clear);
+    private void insertUserRole(SysUserBo user, boolean clear,String platformCode) {
+        this.insertUserRole(user.getUserId(), user.getRoleIds(), clear,platformCode);
     }
 
     /**
@@ -484,7 +504,7 @@ public class SysUserServiceImpl implements ISysUserService {
      * @param roleIds 角色组
      * @param clear   清除已存在的关联数据
      */
-    private void insertUserRole(Long userId, Long[] roleIds, boolean clear) {
+    private void insertUserRole(Long userId, Long[] roleIds, boolean clear,String platformCode) {
         if (ArrayUtil.isNotEmpty(roleIds)) {
             List<Long> roleList = new ArrayList<>(List.of(roleIds));
             if (!LoginHelper.isSuperAdmin(userId)) {
@@ -505,6 +525,7 @@ public class SysUserServiceImpl implements ISysUserService {
                 SysUserRole ur = new SysUserRole();
                 ur.setUserId(userId);
                 ur.setRoleId(roleId);
+                ur.setPlatformCode(platformCode);
                 return ur;
             });
             userRoleMapper.insertBatch(list);

+ 5 - 1
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml

@@ -16,7 +16,7 @@
         ${ew.getCustomSqlSegment}
     </select>
 
-    <select id="selectMenuTreeByUserId" parameterType="Long" resultMap="SysMenuResult">
+    <select id="selectMenuTreeByUserId" parameterType="map" resultMap="SysMenuResult">
         select distinct m.menu_id,
                         m.parent_id,
                         m.menu_name,
@@ -37,6 +37,10 @@
         left join sys_role r on rm.role_id = r.role_id and r.status = '0'
         where m.menu_type in ('M', 'C')
             and r.role_id in (select role_id from sys_user_role where user_id = #{userId})
+        <!-- 如果传入了 platform,则按平台过滤;如果为 null 或空,则不过滤 -->
+        <if test="platform != null and platform != ''">
+            AND m.platform_code = #{platform}
+        </if>
         order by m.parent_id, m.order_num
     </select>