mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 20:49:00 +08:00
feat(tenant): 新增租户用户管理功能
- 在SysUserPost实体类中添加tenantId字段 - 新增SysTenantUserDTO用于租户用户数据传输 - 在SysTenantController中新增用户租户管理接口 - 实现租户用户的增删改查及分页查询功能 - 优化ValidateCodeFilter中的验证码校验逻辑 - 修复PigxUserDetailsService中空部门列表处理问题
This commit is contained in:
1 parent
db332055ae
commit
c8a8da7497
8 files changed
+312
-9
No files matched your search
+2
-3
@@ -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("验证码不合法");
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public interface CacheConstants {
|
||||
/**
|
||||
* 用户信息缓存
|
||||
*/
|
||||
String USER_DETAILS = "user_details";
|
||||
String USER_DETAILS = GLOBALLY + "user_details";
|
||||
|
||||
/**
|
||||
* 移动端用户信息缓存
|
||||
|
||||
+6
-1
@@ -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()
|
||||
|
||||
+38
@@ -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;
|
||||
}
|
||||
+6
@@ -50,4 +50,10 @@ public class SysUserPost extends Model<SysUserPost> {
|
||||
@Schema(description = "岗位id")
|
||||
private Long postId;
|
||||
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@Schema(description = "租户ID")
|
||||
private Long tenantId;
|
||||
}
|
||||
+58
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -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<SysTenant> {
|
||||
* @return 用户所属租户列表
|
||||
*/
|
||||
List<SysTenant> getUserTenant();
|
||||
|
||||
/**
|
||||
* 获取用户租户分页信息
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param userDTO 用户信息
|
||||
* @return 用户租户分页结果
|
||||
*/
|
||||
Page getUserTenantPage(Page page, UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* 移除租户用户
|
||||
*
|
||||
* @param tenantUserDTO 租户用户信息
|
||||
* @return 是否移除成功
|
||||
*/
|
||||
Boolean removeTenantUser(SysTenantUserDTO tenantUserDTO);
|
||||
|
||||
/**
|
||||
* 根据用户信息查询租户用户列表
|
||||
*
|
||||
* @param userDTO 用户信息传输对象
|
||||
* @return 租户用户列表
|
||||
*/
|
||||
List<SysUser> listTenantUser(UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* 保存租户用户信息
|
||||
*
|
||||
* @param tenantUserDTO 租户用户信息DTO
|
||||
* @return 保存是否成功
|
||||
*/
|
||||
Boolean saveTenantUser(SysTenantUserDTO tenantUserDTO);
|
||||
|
||||
/**
|
||||
* 获取租户角色列表
|
||||
*
|
||||
* @param userDTO 用户信息
|
||||
* @return 租户角色列表
|
||||
*/
|
||||
Map<String, Object> listTenantOrg(UserDTO userDTO);
|
||||
}
|
||||
+155
-4
@@ -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<SysTenantMapper, SysTenant
|
||||
|
||||
private final SysDictService dictService;
|
||||
|
||||
private final SysTenantUserMapper tenantUserMapper;
|
||||
private final SysUserMapper sysUserMapper;
|
||||
private final SysTenantUserMapper sysTenantUserMapper;
|
||||
private final SysUserPostMapper sysUserPostMapper;
|
||||
private final SysUserRoleMapper sysUserRoleMapper;
|
||||
private final SysUserDeptMapper sysUserDeptMapper;
|
||||
private final SysRoleMapper sysRoleMapper;
|
||||
private final SysDeptMapper sysDeptMapper;
|
||||
private final SysPostMapper sysPostMapper;
|
||||
|
||||
/**
|
||||
* 获取正常状态租户
|
||||
@@ -321,6 +329,149 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
return baseMapper.selectJoinList(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户租户分页信息
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param userDTO 用户信息
|
||||
* @return 用户租户分页结果
|
||||
*/
|
||||
@Override
|
||||
public Page getUserTenantPage(Page page, UserDTO userDTO) {
|
||||
MPJLambdaWrapper<SysUser> wrapper = new MPJLambdaWrapper<SysUser>()
|
||||
.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<Long> userIdList = CollUtil.toList(tenantUserDTO.getUserIds());
|
||||
|
||||
// 删除租户用户关系
|
||||
sysTenantUserMapper.delete(Wrappers.<SysTenantUser>lambdaQuery()
|
||||
.eq(SysTenantUser::getTenantId, tenantUserDTO.getTenantId())
|
||||
.in(SysTenantUser::getUserId, userIdList)
|
||||
);
|
||||
|
||||
TenantBroker.runAs(tenantUserDTO.getTenantId(), (tenantId -> {
|
||||
// 删除用户岗位
|
||||
sysUserPostMapper.delete(Wrappers.<SysUserPost>lambdaQuery()
|
||||
.in(SysUserPost::getUserId, userIdList));
|
||||
// 删除用户角色
|
||||
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery()
|
||||
.in(SysUserRole::getUserId, userIdList));
|
||||
// 删除用户部门
|
||||
sysUserDeptMapper.delete(Wrappers.<SysUserDept>lambdaQuery()
|
||||
.in(SysUserDept::getUserId, userIdList));
|
||||
}));
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户信息查询租户用户列表
|
||||
*
|
||||
* @param userDTO 用户信息传输对象
|
||||
* @return 租户用户列表
|
||||
*/
|
||||
@Override
|
||||
public List<SysUser> listTenantUser(UserDTO userDTO) {
|
||||
return TenantBroker.noneAs(() -> sysUserMapper
|
||||
.selectList(Wrappers.<SysUser>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<SysTenantUser> sysTenantUsers = sysTenantUserMapper.selectList(Wrappers.<SysTenantUser>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<SysUserRole> userRoleList = sysUserRoleMapper.selectList(Wrappers.<SysUserRole>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<SysUserDept> userDeptList = sysUserDeptMapper.selectList(Wrappers.<SysUserDept>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<SysUserPost> userPostList = sysUserPostMapper.selectList(Wrappers.<SysUserPost>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<String, Object> listTenantOrg(UserDTO userDTO) {
|
||||
return TenantBroker.applyAs(userDTO.getTenantId(), tenantId -> {
|
||||
// 过滤有权限配置的菜单
|
||||
List<SysRole> sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery()).stream()
|
||||
.filter(role -> roleMenuMapper.exists(Wrappers.<SysRoleMenu>lambdaQuery()
|
||||
.eq(SysRoleMenu::getRoleId, role.getRoleId()))).toList();
|
||||
List<SysDept> sysDepts = sysDeptMapper.selectList(Wrappers.lambdaQuery());
|
||||
List<SysPost> sysPosts = sysPostMapper.selectList(Wrappers.lambdaQuery());
|
||||
return Map.of("sysRoles", sysRoles, "sysDepts", sysDepts, "sysPosts", sysPosts);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存新的租户菜单,维护成新的菜单
|
||||
*
|
||||
|
||||
Reference in new issue
Block a user