diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java index 4dba5d9b1..ccebe588f 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/filter/ValidateCodeFilter.java @@ -133,13 +133,12 @@ public class ValidateCodeFilter extends OncePerRequestFilter { throw new ValidateCodeException("验证码不合法"); } - String saveCode = codeObj; - if (StrUtil.isBlank(saveCode)) { + if (StrUtil.isBlank(codeObj)) { RedisUtils.delete(key); throw new ValidateCodeException("验证码不合法"); } - if (!StrUtil.equals(saveCode, code)) { + if (!StrUtil.equals(codeObj, code)) { RedisUtils.delete(key); throw new ValidateCodeException("验证码不合法"); } diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java index a6edc56ef..c437b9fb0 100644 --- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java +++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java @@ -28,7 +28,7 @@ public interface CacheConstants { /** * 用户信息缓存 */ - String USER_DETAILS = "user_details"; + String USER_DETAILS = GLOBALLY + "user_details"; /** * 移动端用户信息缓存 diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsService.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsService.java index 24c08f5f4..887f98d1c 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsService.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsService.java @@ -16,6 +16,7 @@ */ package com.pig4cloud.pigx.common.security.service; +import cn.hutool.core.collection.CollUtil; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; @@ -98,7 +99,11 @@ public interface PigxUserDetailsService extends UserDetailsService, Ordered { // 构造security用户 - return new PigxUser(info.getUserId(), info.getUsername(), info.getDeptList().get(0).getDeptId(), info.getPhone(), info.getAvatar(), + Long deptId = null; + if (CollUtil.isNotEmpty(info.getDeptList())) { + deptId = CollUtil.getFirst(info.getDeptList()).getDeptId(); + } + return new PigxUser(info.getUserId(), info.getUsername(), deptId, info.getPhone(), info.getAvatar(), info.getNickname(), info.getName(), info.getEmail(), info.getTenantId(), SecurityConstants.BCRYPT + info.getPassword() , true, true, UserTypeEnum.TOB.getStatus() diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysTenantUserDTO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysTenantUserDTO.java new file mode 100644 index 000000000..d9c791a38 --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysTenantUserDTO.java @@ -0,0 +1,38 @@ +package com.pig4cloud.pigx.admin.api.dto; + +import lombok.Data; + +/** + * 系统租户用户数据传输对象 + * + * @author lengleng + * @date 2025/06/30 + */ +@Data +public class SysTenantUserDTO { + + /** + * 租户ID + */ + private Long tenantId; + + /** + * 用户ID数组 + */ + private Long[] userIds; + + /** + * 角色ID + */ + private Long roleId; + + /** + * 帖子ID + */ + private Long postId; + + /** + * 部门ID + */ + private Long deptId; +} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserPost.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserPost.java index 5f9614144..fe163332a 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserPost.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserPost.java @@ -50,4 +50,10 @@ public class SysUserPost extends Model { @Schema(description = "岗位id") private Long postId; + + /** + * 租户ID + */ + @Schema(description = "租户ID") + private Long tenantId; } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java index 6a593e4f6..bfed7e5cd 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java @@ -23,6 +23,8 @@ import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.admin.api.dto.SysTenantUserDTO; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.entity.SysTenant; import com.pig4cloud.pigx.admin.service.SysMenuService; import com.pig4cloud.pigx.admin.service.SysTenantService; @@ -198,4 +200,60 @@ public class SysTenantController { return R.ok(sysTenantService.getUserTenant()); } + @PostMapping("/user-tenant") + @HasPermission("sys_systenant_del") + public R addUserTenant(@RequestBody SysTenantUserDTO tenantUserDTO) { + return R.ok(sysTenantService.saveTenantUser(tenantUserDTO)); + } + + /** + * 获取用户租户分页信息 + * + * @param page 分页参数 + * @param userDTO 用户查询参数 + * @return 租户分页结果 + */ + @GetMapping("/user-tenant/page") + @HasPermission("sys_systenant_del") + public R getUserTenantPage(@ParameterObject Page page, @ParameterObject UserDTO userDTO) { + return R.ok(sysTenantService.getUserTenantPage(page, userDTO)); + } + + /** + * 根据租户用户信息删除用户租户关系 + * + * @param tenantUserDTO 租户用户信息DTO + * @return 操作结果 + */ + @SysLog("删除租户>用户关系") + @DeleteMapping("/remove-users") + @HasPermission("sys_systenant_del") + public R removeUserTenantById(@RequestBody SysTenantUserDTO tenantUserDTO) { + return R.ok(sysTenantService.removeTenantUser(tenantUserDTO)); + } + + /** + * 根据条件查询租户用户列表 + * + * @param userDTO 用户查询条件 + * @return 包含查询结果的响应对象 + */ + @GetMapping("/list-users") + @HasPermission("sys_systenant_del") + public R listTenantUser(@ParameterObject UserDTO userDTO) { + return R.ok(sysTenantService.listTenantUser(userDTO)); + } + + /** + * 获取租户角色列表 + * + * @param userDTO 用户信息参数对象 + * @return 包含租户角色列表的响应结果 + */ + @GetMapping("/list-org") + @HasPermission("sys_systenant_del") + public R listTenantOrg(@ParameterObject UserDTO userDTO) { + return R.ok(sysTenantService.listTenantOrg(userDTO)); + } + } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java index 104ca8c85..fd387bebe 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java @@ -17,10 +17,15 @@ package com.pig4cloud.pigx.admin.service; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.admin.api.dto.SysTenantUserDTO; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.entity.SysTenant; +import com.pig4cloud.pigx.admin.api.entity.SysUser; import java.util.List; +import java.util.Map; /** * 租户管理 @@ -59,4 +64,45 @@ public interface SysTenantService extends IService { * @return 用户所属租户列表 */ List getUserTenant(); + + /** + * 获取用户租户分页信息 + * + * @param page 分页参数 + * @param userDTO 用户信息 + * @return 用户租户分页结果 + */ + Page getUserTenantPage(Page page, UserDTO userDTO); + + /** + * 移除租户用户 + * + * @param tenantUserDTO 租户用户信息 + * @return 是否移除成功 + */ + Boolean removeTenantUser(SysTenantUserDTO tenantUserDTO); + + /** + * 根据用户信息查询租户用户列表 + * + * @param userDTO 用户信息传输对象 + * @return 租户用户列表 + */ + List listTenantUser(UserDTO userDTO); + + /** + * 保存租户用户信息 + * + * @param tenantUserDTO 租户用户信息DTO + * @return 保存是否成功 + */ + Boolean saveTenantUser(SysTenantUserDTO tenantUserDTO); + + /** + * 获取租户角色列表 + * + * @param userDTO 用户信息 + * @return 租户角色列表 + */ + Map listTenantOrg(UserDTO userDTO); } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java index eadbe8bb5..6e0e1d057 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java @@ -21,14 +21,15 @@ import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.pig4cloud.pigx.admin.api.constant.TenantStateEnum; +import com.pig4cloud.pigx.admin.api.dto.SysTenantUserDTO; +import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.entity.*; import com.pig4cloud.pigx.admin.config.ClientDetailsInitRunner; -import com.pig4cloud.pigx.admin.mapper.SysRoleMenuMapper; -import com.pig4cloud.pigx.admin.mapper.SysTenantMapper; -import com.pig4cloud.pigx.admin.mapper.SysTenantUserMapper; +import com.pig4cloud.pigx.admin.mapper.*; import com.pig4cloud.pigx.admin.service.*; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.CommonConstants; @@ -87,7 +88,14 @@ public class SysTenantServiceImpl extends ServiceImpl wrapper = new MPJLambdaWrapper() + .selectAll(SysUser.class) + .innerJoin(SysTenantUser.class, SysTenantUser::getUserId, SysUser::getUserId) + .like(StrUtil.isNotBlank(userDTO.getUsername()), SysUser::getUsername, userDTO.getUsername()) + .like(StrUtil.isNotBlank(userDTO.getPhone()), SysUser::getPhone, userDTO.getPhone()) + .like(StrUtil.isNotBlank(userDTO.getEmail()), SysUser::getEmail, userDTO.getEmail()) + .eq(Objects.nonNull(userDTO.getTenantId()), SysTenantUser::getTenantId, userDTO.getTenantId()); + return TenantBroker.noneAs(() -> sysUserMapper.selectJoinPage(page, wrapper)); + } + + /** + * 移除租户用户 + * + * @param tenantUserDTO 租户用户信息 + * @return 是否移除成功 + */ + @Override + public Boolean removeTenantUser(SysTenantUserDTO tenantUserDTO) { + ArrayList userIdList = CollUtil.toList(tenantUserDTO.getUserIds()); + + // 删除租户用户关系 + sysTenantUserMapper.delete(Wrappers.lambdaQuery() + .eq(SysTenantUser::getTenantId, tenantUserDTO.getTenantId()) + .in(SysTenantUser::getUserId, userIdList) + ); + + TenantBroker.runAs(tenantUserDTO.getTenantId(), (tenantId -> { + // 删除用户岗位 + sysUserPostMapper.delete(Wrappers.lambdaQuery() + .in(SysUserPost::getUserId, userIdList)); + // 删除用户角色 + sysUserRoleMapper.delete(Wrappers.lambdaQuery() + .in(SysUserRole::getUserId, userIdList)); + // 删除用户部门 + sysUserDeptMapper.delete(Wrappers.lambdaQuery() + .in(SysUserDept::getUserId, userIdList)); + })); + return Boolean.TRUE; + } + + /** + * 根据用户信息查询租户用户列表 + * + * @param userDTO 用户信息传输对象 + * @return 租户用户列表 + */ + @Override + public List listTenantUser(UserDTO userDTO) { + return TenantBroker.noneAs(() -> sysUserMapper + .selectList(Wrappers.lambdaQuery().like(StrUtil.isNotBlank(userDTO.getUsername()), SysUser::getUsername, userDTO.getUsername()))); + } + + /** + * 保存租户用户信息 + * + * @param tenantUserDTO 租户用户信息DTO + * @return 保存是否成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean saveTenantUser(SysTenantUserDTO tenantUserDTO) { + TenantBroker.runAs(tenantUserDTO.getTenantId(), (tenantId -> { + for (Long userId : tenantUserDTO.getUserIds()) { + List sysTenantUsers = sysTenantUserMapper.selectList(Wrappers.lambdaQuery() + .eq(SysTenantUser::getTenantId, tenantId) + .eq(SysTenantUser::getUserId, userId)); + if (CollUtil.isEmpty(sysTenantUsers)) { + // 插入租户用户关系 + SysTenantUser sysTenantUser = new SysTenantUser(); + sysTenantUser.setUserId(userId); + sysTenantUser.setTenantId(tenantId); + sysTenantUserMapper.insert(sysTenantUser); + } + + + List userRoleList = sysUserRoleMapper.selectList(Wrappers.lambdaQuery() + .eq(SysUserRole::getUserId, userId) + .eq(SysUserRole::getRoleId, tenantUserDTO.getRoleId())); + if (CollUtil.isEmpty(userRoleList)) { + // 插入用户角色关系 + SysUserRole sysUserRole = new SysUserRole(); + sysUserRole.setUserId(userId); + sysUserRole.setRoleId(tenantUserDTO.getRoleId()); + sysUserRoleMapper.insert(sysUserRole); + } + + + List userDeptList = sysUserDeptMapper.selectList(Wrappers.lambdaQuery() + .eq(SysUserDept::getUserId, userId) + .eq(SysUserDept::getDeptId, tenantUserDTO.getDeptId())); + + if (CollUtil.isEmpty(userDeptList)) { + // 插入用户部门关系 + SysUserDept sysUserDept = new SysUserDept(); + sysUserDept.setUserId(userId); + sysUserDept.setDeptId(tenantUserDTO.getDeptId()); + sysUserDeptMapper.insert(sysUserDept); + } + + List userPostList = sysUserPostMapper.selectList(Wrappers.lambdaQuery() + .eq(SysUserPost::getUserId, userId) + .eq(SysUserPost::getPostId, tenantUserDTO.getPostId())); + + if (CollUtil.isEmpty(userPostList)) { + // 插入用户岗位关系 + SysUserPost sysUserPost = new SysUserPost(); + sysUserPost.setUserId(userId); + sysUserPost.setPostId(tenantUserDTO.getPostId()); + sysUserPostMapper.insert(sysUserPost); + } + } + })); + return Boolean.TRUE; + } + + /** + * 获取租户角色列表 + * + * @param userDTO 用户信息 + * @return 租户角色列表 + */ + @Override + public Map listTenantOrg(UserDTO userDTO) { + return TenantBroker.applyAs(userDTO.getTenantId(), tenantId -> { + // 过滤有权限配置的菜单 + List sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery()).stream() + .filter(role -> roleMenuMapper.exists(Wrappers.lambdaQuery() + .eq(SysRoleMenu::getRoleId, role.getRoleId()))).toList(); + List sysDepts = sysDeptMapper.selectList(Wrappers.lambdaQuery()); + List sysPosts = sysPostMapper.selectList(Wrappers.lambdaQuery()); + return Map.of("sysRoles", sysRoles, "sysDepts", sysDepts, "sysPosts", sysPosts); + }); + } + /** * 保存新的租户菜单,维护成新的菜单 *