From 7ba5c1b1db83594b34802a55d8f277ec29c025e5 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 3 Aug 2026 10:05:56 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qgc_base/mapper/SdFpssBHMapper.java | 3 +- .../system/controller/LoginController.java | 13 +++- .../controller/SmsVerifyCodeController.java | 15 +++- .../system/controller/SysMenuController.java | 2 +- .../system/controller/UserController.java | 57 +++++++++++++- .../yfd/platform/system/domain/LoginUser.java | 29 ++++++- .../platform/system/domain/SysUserTenant.java | 30 ++++++++ .../platform/system/mapper/SysMenuMapper.java | 2 +- .../system/mapper/SysUserTenantMapper.java | 47 ++++++++++++ .../platform/system/service/IUserService.java | 19 +++++ .../service/impl/AdminAuthServiceImpl.java | 16 ++-- .../impl/SmsVerifyCodeServiceImpl.java | 4 +- .../service/impl/UserDetailsServiceImpl.java | 70 +++++++++++++---- .../system/service/impl/UserServiceImpl.java | 75 +++++++++++++++++-- .../com/yfd/platform/utils/SecurityUtils.java | 37 +++++++++ .../resources/mapper/system/SysMenuMapper.xml | 7 +- .../resources/mapper/system/SysUserMapper.xml | 3 +- .../mapper/system/SysUserTenantMapper.xml | 57 ++++++++++++++ 18 files changed, 439 insertions(+), 47 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java create mode 100644 backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java create mode 100644 backend/src/main/resources/mapper/system/SysUserTenantMapper.xml diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java index e12224c6..941f39ee 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/SdFpssBHMapper.java @@ -17,7 +17,8 @@ public interface SdFpssBHMapper extends BaseMapper { "WHERE 1=1 " + " AND E.BASE_ID = #{baseId} " + " AND F.RSTCD = #{rstcd} " + - " AND E.REACHCD = #{rvcd} " + + " AND E.RVCD = #{rvcd} " + + " AND E.REACHCD = #{reachcd} " + // " AND F.RSTCD = #{rstcd} " + " AND F.STNM LIKE '%' || #{stnm} || '%' " + "ORDER BY F.ORDER_INDEX DESC" + diff --git a/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java b/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java index 82ed2e6f..d341fcbd 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/LoginController.java @@ -37,6 +37,7 @@ import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import java.sql.Timestamp; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -100,8 +101,12 @@ public class LoginController { Integer status = loginUser.getUser().getStatus(); String regStatus = loginUser.getUser().getRegStatus(); - if (StrUtil.isNotBlank(tenantId)&&!tenantId.equals(loginUser.getUser().getTenantId())) { - return ResponseResult.error("账号不存在或密码错误"); + // 多门户:验证用户是否有权限访问指定门户 + if (!loginUser.isSuperAdmin() && StrUtil.isNotBlank(tenantId)) { + List accessibleIds = loginUser.getAccessibleTenantIds(); + if (accessibleIds == null || !accessibleIds.contains(tenantId)) { + return ResponseResult.error("账号不存在或密码错误"); + } } if (StrUtil.isNotBlank(regStatus)&&"REJECTED".equals(regStatus)) { @@ -149,6 +154,10 @@ public class LoginController { String token = JWTUtil.createToken(map, "12345678".getBytes()); map.put("token", token); + // 返回可访问门户列表和超级管理员标识 + map.put("accessibleTenantIds", loginUser.getAccessibleTenantIds()); + map.put("superAdmin", loginUser.isSuperAdmin()); + map.put("currentTenantId", tenantId); //把完整的用户信息存入到HuTool缓存中,userId作为key String jsonStr = JSONUtil.toJsonStr(loginUser); webConfig.loginuserCache().put("login:" + userId, jsonStr); diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java index 5bf84847..8680affe 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java @@ -11,6 +11,7 @@ import com.yfd.platform.qgc_base.service.ISdEngInfoBHService; import com.yfd.platform.qgc_base.service.ISdHbrvDicService; import com.yfd.platform.system.domain.*; import com.yfd.platform.system.mapper.SysMenuMapper; +import com.yfd.platform.system.mapper.SysUserTenantMapper; import com.yfd.platform.system.service.ISmsVerifyCodeService; import com.yfd.platform.system.service.ISysLogService; import com.yfd.platform.system.service.IUserService; @@ -66,6 +67,10 @@ public class SmsVerifyCodeController { @Resource private ISdEngInfoBHService engInfoBHService; + @Resource + private SysUserTenantMapper sysUserTenantMapper; + + @Resource private ISdHbrvDicService hbrvDicService; @@ -441,8 +446,14 @@ public class SmsVerifyCodeController { loginUser.setUser(user); loginUser.setUsername(user.getUsername()); //Todo 根据用户查询权限信息 添加到LoginUser中 - List permissions = - sysMenuMapper.selectPermsByUserId(user.getId()); + // 加载权限:超级管理员加载全部权限,普通用户按门户过滤 + boolean isSuperAdmin = userService.isSuperAdmin(user.getId()); + List permissions; + if (isSuperAdmin) { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null); + } else { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId); + } loginUser.setPermissions( permissions); HttpServletRequest request = RequestHolder.getHttpServletRequest(); SysLog sysLog = new SysLog(); diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java index bb4f90c6..4ffe9fed 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysMenuController.java @@ -115,7 +115,7 @@ public class SysMenuController { if (0 != userInfo.getUsertype()) { id = userInfo.getId(); } - return sysMenuService.getMenuTree(id, StrUtil.isNotBlank(tenantId) ? StrUtil.trimToNull(tenantId) : userInfo.getTenantId()); + return sysMenuService.getMenuTree(id, tenantId); } /*********************************** diff --git a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java index ce4945b4..4e0838cc 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java @@ -17,6 +17,7 @@ import org.springframework.web.multipart.MultipartFile; import jakarta.annotation.Resource; import java.sql.Timestamp; +import java.util.List; import java.util.Map; /** @@ -60,7 +61,7 @@ public class UserController { if (StrUtil.isEmpty(user.getId())) { return ResponseResult.error("没有用户ID"); } - user.setTenantId(StrUtil.trimToNull(tenantId)); +// user.setTenantId(StrUtil.trimToNull(tenantId)); //填写 当前用户名称 user.setLastmodifier(userService.getUsername()); //填写 当前日期 @@ -115,8 +116,8 @@ public class UserController { public ResponseResult queryUserById(String id, @RequestHeader(value = "Tenant_id", required = false) String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysUser::getId, id) - .eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, StrUtil.trim(tenantId)); + queryWrapper.eq(SysUser::getId, id); +// .eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, StrUtil.trim(tenantId)); SysUser user = userService.getOne(queryWrapper); return ResponseResult.successData(user); } @@ -251,4 +252,54 @@ public class UserController { Page result = userService.queryPendingAuditUsers(page, name, regStatus, StrUtil.trimToNull(tenantId)); return ResponseResult.successData(result); } + + // ==================== 多门户管理 ==================== + + /*********************************** + * 用途说明:为用户分配门户 + * 参数说明 userId 用户ID, tenantIds 门户ID列表(逗号分隔) + ************************************/ + @Log(module = "系统用户", value = "分配门户") + @PostMapping("/assignTenant") + @Operation(summary = "为用户分配门户") + @ResponseBody + public ResponseResult assignTenant(String userId, String tenantIds) { + if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantIds)) { + return ResponseResult.error("用户ID和门户ID不能为空"); + } + List tenantIdList = List.of(tenantIds.split(",")); + userService.assignTenantsToUser(userId, tenantIdList); + return ResponseResult.success(); + } + + /*********************************** + * 用途说明:移除用户的门户关联 + * 参数说明 userId 用户ID, tenantId 门户ID + ************************************/ + @Log(module = "系统用户", value = "移除门户") + @PostMapping("/removeTenant") + @Operation(summary = "移除用户的门户关联") + @ResponseBody + public ResponseResult removeTenant(String userId, String tenantId) { + if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantId)) { + return ResponseResult.error("用户ID和门户ID不能为空"); + } + userService.removeTenantFromUser(userId, tenantId); + return ResponseResult.success(); + } + + /*********************************** + * 用途说明:获取用户关联的门户列表 + * 参数说明 userId 用户ID + ************************************/ + @GetMapping("/getUserTenants") + @Operation(summary = "获取用户关联的门户列表") + @ResponseBody + public ResponseResult getUserTenants(String userId) { + if (StrUtil.isBlank(userId)) { + return ResponseResult.error("用户ID不能为空"); + } + List tenants = userService.getUserTenants(userId); + return ResponseResult.successData(tenants); + } } diff --git a/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java b/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java index baf4258a..95c37a01 100644 --- a/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java +++ b/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java @@ -22,19 +22,44 @@ public class LoginUser implements UserDetails { private String username; - private List permissions=new ArrayList<>(); + private List permissions = new ArrayList<>(); + + /** + * 当前登录的门户ID + */ + private String currentTenantId; + + /** + * 用户可访问的门户ID列表(用于门户切换) + */ + private List accessibleTenantIds; + + /** + * 是否超级管理员(LEVEL=1) + */ + private boolean superAdmin; /** * 自定义构造函数(如果需要特殊逻辑) */ public LoginUser(SysUser user, List permissions) { this.user = user; - // 4. 增加非空判断,确保 permissions 永远不为 null if (permissions != null) { this.permissions = permissions; } } + public LoginUser(SysUser user, List permissions, + String currentTenantId, List accessibleTenantIds, boolean superAdmin) { + this.user = user; + if (permissions != null) { + this.permissions = permissions; + } + this.currentTenantId = currentTenantId; + this.accessibleTenantIds = accessibleTenantIds; + this.superAdmin = superAdmin; + } + @JSONField(serialize = false) private List authorities; diff --git a/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java b/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java new file mode 100644 index 00000000..b5b8cfac --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/domain/SysUserTenant.java @@ -0,0 +1,30 @@ +package com.yfd.platform.system.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 用户-门户关联表 + *

+ */ +@Data +@TableName("SYS_USER_TENANT") +public class SysUserTenant implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 主键 */ + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + /** 用户ID */ + private String userId; + + /** 门户ID */ + private String tenantId; +} diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java index 9ea863fa..ab657e45 100644 --- a/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java +++ b/backend/src/main/java/com/yfd/platform/system/mapper/SysMenuMapper.java @@ -44,7 +44,7 @@ public interface SysMenuMapper extends BaseMapper { @Param("tenantId") String tenantId); - List selectPermsByUserId(String userId); + List selectPermsByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId); //List selectMenuByUserId(String userId); List selectMenuByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId); diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java new file mode 100644 index 00000000..f7961522 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/mapper/SysUserTenantMapper.java @@ -0,0 +1,47 @@ +package com.yfd.platform.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.system.domain.SysUserTenant; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 用户-门户关联表 Mapper 接口 + *

+ */ +@Mapper +public interface SysUserTenantMapper extends BaseMapper { + + /** + * 查询用户可访问的门户ID列表 + */ + List getTenantIdsByUserId(@Param("userId") String userId); + + /** + * 批量删除用户-门户关联 + */ + int deleteByUserId(@Param("userId") String userId); + + /** + * 批量新增用户-门户关联 + */ + int batchInsert(@Param("userId") String userId, @Param("tenantIds") List tenantIds); + + /** + * 查询某门户下的所有用户ID + */ + List getUserIdsByTenantId(@Param("tenantId") String tenantId); + + /** + * 删除指定用户和指定门户的关联 + */ + int deleteByUserIdAndTenantId(@Param("userId") String userId, @Param("tenantId") String tenantId); + + /** + * 批量查询用户-门户关联(用于用户列表展示) + */ + List> getTenantIdsByUserIds(@Param("userIds") List userIds); +} diff --git a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java index 863fa04c..99d8c4f3 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java @@ -184,4 +184,23 @@ public interface IUserService extends IService { Page queryPendingAuditUsers(Page page, String name, String regStatus, String tenantId); List queryUsersList(String name, String tenantId); + + // ==================== 多门户管理 ==================== + + /** + * 为用户分配门户 + */ + void assignTenantsToUser(String userId, List tenantIds); + + /** + * 移除用户的某个门户关联 + */ + void removeTenantFromUser(String userId, String tenantId); + + /** + * 获取用户关联的门户ID列表 + */ + List getUserTenants(String userId); + + boolean isSuperAdmin(String userId); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java index 046de510..3b6579f9 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/AdminAuthServiceImpl.java @@ -38,17 +38,17 @@ public class AdminAuthServiceImpl implements IAdminAuthService { public List getSuperAdminUsernames() { // 获取当前请求 - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); +// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysUser::getUsertype, 0).select(SysUser::getUsername); //根据用户名称或手机号查询用户信息 - if (attributes != null) { - HttpServletRequest request = attributes.getRequest(); - String tenantId = request.getHeader("Tenant_Id"); - if(StrUtil.isNotBlank(tenantId)){ - queryWrapper.eq(SysUser::getTenantId, tenantId); - } - } +// if (attributes != null) { +// HttpServletRequest request = attributes.getRequest(); +// String tenantId = request.getHeader("Tenant_Id"); +// if(StrUtil.isNotBlank(tenantId)){ +// queryWrapper.eq(SysUser::getTenantId, tenantId); +// } +// } List userList = userMapper.selectList(queryWrapper); if (CollUtil.isEmpty(userList)) { return new ArrayList<>(); diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java index 4331f80a..390ada64 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java @@ -48,7 +48,7 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SmsVerifyCode::getPhone, phone) .eq(SmsVerifyCode::getType, type) - .gt(SmsVerifyCode::getTenantId, tenantId) + .eq(SmsVerifyCode::getTenantId, tenantId) .eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED); this.remove(queryWrapper); @@ -161,7 +161,7 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl ids = userIds.stream().distinct().toList(); List sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper().in(SysUser::getId, ids) - .eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getTenantId, tenantId).eq(SysUser::getStatus,1).select(SysUser::getPhone)); + .eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getStatus,1).select(SysUser::getPhone)); if (sysUsers.isEmpty()) { log.warn("催促短信发送失败:未找到有效的手机号,userIds: {}", ids); diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java index b860f0bd..c1c9c6d6 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java @@ -3,12 +3,12 @@ package com.yfd.platform.system.service.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.yfd.platform.datasource.DataSource; -import com.yfd.platform.datasource.DataSourceKeys; import com.yfd.platform.datasource.TargetDataSource; import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysMenuMapper; +import com.yfd.platform.system.mapper.SysUserMapper; +import com.yfd.platform.system.mapper.SysUserTenantMapper; import com.yfd.platform.system.service.IUserService; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.core.userdetails.UserDetails; @@ -20,11 +20,14 @@ import jakarta.annotation.Resource; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import java.util.ArrayList; import java.util.List; /** *

* 用户服务实现类 继承UserDetailsService 实现接口 + * 支持多门户登录:用户可关联多个门户,登录时选择其中一个门户 + * 超级管理员(LEVEL=1)拥有跨所有门户的权限 *

* * @author zhengsl @@ -39,31 +42,68 @@ public class UserDetailsServiceImpl implements UserDetailsService { @Resource private SysMenuMapper sysMenuMapper; + @Resource + private SysUserTenantMapper sysUserTenantMapper; + + @Resource + private SysUserMapper sysUserMapper; + @Override @TargetDataSource() public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 获取当前请求 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - //根据用户名称或手机号查询用户信息 + + // 根据用户名称或手机号查询用户信息(不加tenantId过滤,支持跨门户登录) QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.and(wrapper -> wrapper.eq("username", username).or().eq("phone", username)); - if (attributes != null) { - HttpServletRequest request = attributes.getRequest(); - String tenantId = request.getHeader("Tenant_Id"); - if(StrUtil.isNotBlank(tenantId)){ - queryWrapper.eq("TENANT_ID", tenantId); - } - } SysUser user = userService.getOne(queryWrapper); if (ObjectUtil.isEmpty(user)) { throw new RuntimeException("用户账号不存在!"); } - //Todo 根据用户查询权限信息 添加到LoginUser中 - List permissions = - sysMenuMapper.selectPermsByUserId(user.getId()); - //封装成UserDetails对象返回 - return new LoginUser(user,permissions); + // 获取请求中的门户ID + String tenantId = null; + if (attributes != null) { + HttpServletRequest request = attributes.getRequest(); + tenantId = request.getHeader("Tenant_Id"); + } + + // 判断是否为超级管理员(LEVEL=1) + boolean isSuperAdmin = isSuperAdmin(user.getId()); + + // 查询用户可访问的门户列表 + List accessibleTenantIds = sysUserTenantMapper.getTenantIdsByUserId(user.getId()); + + // 非超级管理员必须指定门户,且必须在可访问列表中 + if (!isSuperAdmin) { + if (StrUtil.isBlank(tenantId)) { + throw new RuntimeException("普通用户登录必须指定门户(Tenant_Id)"); + } + if (accessibleTenantIds == null || !accessibleTenantIds.contains(tenantId)) { + throw new RuntimeException("用户无权限访问该门户"); + } + } + + // 加载权限:超级管理员加载全部权限,普通用户按门户过滤 + List permissions; + if (isSuperAdmin) { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null); + } else { + permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId); + } + + // 封装成UserDetails对象返回,包含当前门户和可访问门户列表 + return new LoginUser(user, permissions, tenantId, accessibleTenantIds, isSuperAdmin); + } + + /** + * 判断用户是否为超级管理员(拥有LEVEL=1的角色) + */ + private boolean isSuperAdmin(String userId) { + String maxLevel = sysUserMapper.getMaxLevel(userId); + return "1".equals(maxLevel); } } + diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index a50a6d83..0226eea6 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -22,6 +22,7 @@ import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysUserMapper; +import com.yfd.platform.system.mapper.SysUserTenantMapper; import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.system.service.IUserService; import com.yfd.platform.utils.FileUtil; @@ -81,6 +82,9 @@ public class UserServiceImpl extends ServiceImpl impleme @Resource private SysUserDataScopeMapper sysUserDataScopeMapper; + @Resource + private SysUserTenantMapper sysUserTenantMapper; + @Resource private IAdminAuthService adminAuthService; @@ -169,7 +173,7 @@ public class UserServiceImpl extends ServiceImpl impleme //账号有效 sysUser.setStatus(1); //判断注册的登录账号是否存在 - if (isExistAccount(sysUser.getUsername(),sysUser.getTenantId() )) { + if (isExistAccount(sysUser.getUsername())) { //新增用户 boolean ok = this.save(sysUser); //新增用户分配权限 @@ -185,6 +189,13 @@ public class UserServiceImpl extends ServiceImpl impleme } //判断新增是否成功 消息提示 if (ok) { + // 插入用户-门户关联 + String tenantId = sysUser.getTenantId(); + if (StrUtil.isNotBlank(tenantId)) { + List tenantIds = new ArrayList<>(); + tenantIds.add(tenantId); + sysUserTenantMapper.batchInsert(sysUser.getId(), tenantIds); + } result.put("status", "sucess"); result.put("msg", "新增用户成功!"); @@ -434,6 +445,8 @@ public class UserServiceImpl extends ServiceImpl impleme if (isOk) { //根据用户id 删除该用户角色关联 sysUserMapper.delRoleUsersByUserid(id); + // 删除用户-门户关联 + sysUserTenantMapper.deleteByUserId(id); //判断是否存在 账号头像 存在删除 if (StrUtil.isNotEmpty(sysUser.getAvatar())) { FileUtil.del(imgName); @@ -636,6 +649,10 @@ public class UserServiceImpl extends ServiceImpl impleme } // 根据ID删除用户与角色的关联信息 sysUserMapper.delRoleUsersByUserIds(ids); + // 删除用户-门户关联 + for (String userId : ids) { + sysUserTenantMapper.deleteByUserId(userId); + } List avatars = sysUsers.stream().map(SysUser::getAvatar).collect(Collectors.toList()); if (avatars.size() > 0) { @@ -654,7 +671,7 @@ public class UserServiceImpl extends ServiceImpl impleme public SysUser getUserByPhone(String phone,String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysUser::getPhone, phone); - queryWrapper.eq(SysUser::getTenantId, tenantId); +// queryWrapper.eq(SysUser::getTenantId, tenantId); return this.getOne(queryWrapper); } @@ -893,15 +910,14 @@ public class UserServiceImpl extends ServiceImpl impleme } /*********************************** - * 用途说明:比较登录名称是否有重复 + * 用途说明:比较登录名称是否有重复(全局唯一,不区分门户) * 参数说明 * account 登录名称 * 返回值说明: 重复返回 false 否则返回 true ************************************/ - private boolean isExistAccount(String username,String tenantId) { + private boolean isExistAccount(String username) { QueryWrapper queryWrapper = new QueryWrapper<>(); - if (this.list(queryWrapper.eq("username", username).eq("TENANT_ID", tenantId)).size() > 0) { - //判断 查询登录账号 结果集是否为null 重复返回 false 否则返回 tree + if (this.list(queryWrapper.eq("username", username)).size() > 0) { return false; } else { return true; @@ -912,7 +928,7 @@ public class UserServiceImpl extends ServiceImpl impleme @Override public List queryUsersList(String name, String tenantId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, tenantId); +// queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, tenantId); queryWrapper.eq(SysUser::getStatus, 1); queryWrapper.and(StrUtil.isNotBlank(name), wrapper -> wrapper.like(SysUser::getNickname, name) @@ -923,4 +939,49 @@ public class UserServiceImpl extends ServiceImpl impleme List sysUserList = this.list( queryWrapper); return sysUserList; } + + // ==================== 多门户管理 ==================== + + /** + * 为用户分配门户 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void assignTenantsToUser(String userId, List tenantIds) { + if (StrUtil.isBlank(userId) || tenantIds == null || tenantIds.isEmpty()) { + throw new RuntimeException("用户ID和门户ID列表不能为空"); + } + sysUserTenantMapper.batchInsert(userId, tenantIds); + } + + /** + * 移除用户的某个门户关联 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void removeTenantFromUser(String userId, String tenantId) { + if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantId)) { + throw new RuntimeException("用户ID和门户ID不能为空"); + } + sysUserTenantMapper.deleteByUserIdAndTenantId(userId, tenantId); + } + + /** + * 获取用户关联的门户ID列表 + */ + @Override + public List getUserTenants(String userId) { + if (StrUtil.isBlank(userId)) { + return new ArrayList<>(); + } + return sysUserTenantMapper.getTenantIdsByUserId(userId); + } + + + public boolean isSuperAdmin(String userId) { +// String maxLevel = sysUserMapper.getMaxLevel(userId); + SysUser sysUser = sysUserMapper.selectById(userId); + return sysUser!=null && sysUser.getUsertype()==0; + } + } diff --git a/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java b/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java index 8d667c15..8c90a931 100644 --- a/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java +++ b/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java @@ -19,6 +19,7 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.yfd.platform.exception.BadRequestException; +import com.yfd.platform.system.domain.LoginUser; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; @@ -105,4 +106,40 @@ public class SecurityUtils { .anyMatch(auth -> permission.equals(auth.getAuthority())); } + /** + * 获取当前登录用户的门户ID + * @return 门户ID,超级管理员可能返回null + */ + public static String getCurrentTenantId() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) { + return null; + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + return loginUser.getCurrentTenantId(); + } + + /** + * 判断当前用户是否为超级管理员 + */ + public static boolean isSuperAdmin() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) { + return false; + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + return loginUser.isSuperAdmin(); + } + + /** + * 获取当前用户可访问的门户ID列表 + */ + public static List getAccessibleTenantIds() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) { + return null; + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + return loginUser.getAccessibleTenantIds(); + } } diff --git a/backend/src/main/resources/mapper/system/SysMenuMapper.xml b/backend/src/main/resources/mapper/system/SysMenuMapper.xml index a65f0c7f..797c7314 100644 --- a/backend/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/backend/src/main/resources/mapper/system/SysMenuMapper.xml @@ -27,7 +27,7 @@ diff --git a/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml b/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml new file mode 100644 index 00000000..ce2a99c8 --- /dev/null +++ b/backend/src/main/resources/mapper/system/SysUserTenantMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + DELETE FROM SYS_USER_TENANT WHERE USER_ID = #{userId} + + + + + MERGE INTO SYS_USER_TENANT T + USING ( + + SELECT + #{userId, jdbcType=VARCHAR} AS USER_ID, + #{tenantId, jdbcType=VARCHAR} AS TENANT_ID + FROM DUAL + + ) S + ON (T.USER_ID = S.USER_ID AND T.TENANT_ID = S.TENANT_ID) + WHEN NOT MATCHED THEN + INSERT (ID, USER_ID, TENANT_ID) + VALUES (SYS_GUID(), S.USER_ID, S.TENANT_ID) + + + + + DELETE FROM SYS_USER_TENANT WHERE USER_ID = #{userId} AND TENANT_ID = #{tenantId} + + + + + + + + +