用户租户体系调整,用户支持多租户数据
parent
4ce24a8b65
commit
c01d68aec8
|
|
@ -0,0 +1,59 @@
|
|||
package com.fjrcloud.community.module.system.controller.admin.auth;
|
||||
|
||||
import com.fjrcloud.community.framework.common.enums.UserTypeEnum;
|
||||
import com.fjrcloud.community.framework.common.pojo.CommonResult;
|
||||
import com.fjrcloud.community.framework.tenant.core.util.TenantUtils;
|
||||
import com.fjrcloud.community.module.system.controller.admin.auth.vo.SwitchTenantReqVO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.user.UserTenantRelDO;
|
||||
import com.fjrcloud.community.module.system.enums.ErrorCodeConstants;
|
||||
import com.fjrcloud.community.module.system.enums.oauth2.OAuth2ClientConstants;
|
||||
import com.fjrcloud.community.module.system.service.oauth2.OAuth2TokenService;
|
||||
import com.fjrcloud.community.module.system.service.usertenant.UserTenantRelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.fjrcloud.community.framework.common.pojo.CommonResult.success;
|
||||
import static com.fjrcloud.community.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 认证 - 租户切换")
|
||||
@RestController
|
||||
@RequestMapping("/system/auth")
|
||||
@Validated
|
||||
public class AuthTenantSwitchController {
|
||||
|
||||
@Resource
|
||||
private UserTenantRelService userTenantRelService;
|
||||
|
||||
@Resource
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
|
||||
@PostMapping("/switch-tenant")
|
||||
@Operation(summary = "切换租户")
|
||||
public CommonResult<String> switchTenant(@Valid @RequestBody SwitchTenantReqVO reqVO) {
|
||||
Long userId = getLoginUserId();
|
||||
|
||||
UserTenantRelDO rel = userTenantRelService.getUserTenantRel(userId, reqVO.getTenantId());
|
||||
if (rel == null) {
|
||||
throw exception(ErrorCodeConstants.USER_TENANT_REL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
String newToken = TenantUtils.execute(reqVO.getTenantId(), () -> {
|
||||
OAuth2AccessTokenDO newAccessToken = oauth2TokenService.createAccessToken(
|
||||
userId, UserTypeEnum.ADMIN.getValue(),
|
||||
OAuth2ClientConstants.CLIENT_ID_DEFAULT, null);
|
||||
return newAccessToken.getAccessToken();
|
||||
});
|
||||
|
||||
return success(newToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import lombok.Data;
|
|||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 登录 Response VO")
|
||||
@Data
|
||||
|
|
@ -27,4 +28,7 @@ public class AuthLoginRespVO {
|
|||
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime expiresTime;
|
||||
|
||||
@Schema(description = "用户可访问的租户列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<TenantInfoVO> tenants;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package com.fjrcloud.community.module.system.controller.admin.auth.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 切换租户 Request VO")
|
||||
@Data
|
||||
public class SwitchTenantReqVO {
|
||||
|
||||
@Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "租户ID不能为空")
|
||||
private Long tenantId;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.fjrcloud.community.module.system.controller.admin.auth.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Schema(description = "管理后台 - 租户信息 VO")
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TenantInfoVO {
|
||||
|
||||
@Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description = "租户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "XX小区")
|
||||
private String tenantName;
|
||||
|
||||
@Schema(description = "是否默认租户", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean isDefault;
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package com.fjrcloud.community.module.system.controller.admin.usertenant;
|
||||
|
||||
import com.fjrcloud.community.framework.common.pojo.CommonResult;
|
||||
import com.fjrcloud.community.module.system.controller.admin.auth.vo.TenantInfoVO;
|
||||
import com.fjrcloud.community.module.system.controller.admin.usertenant.vo.UserTenantAssignReqVO;
|
||||
import com.fjrcloud.community.module.system.controller.admin.usertenant.vo.UserTenantBatchAssignReqVO;
|
||||
import com.fjrcloud.community.module.system.controller.admin.usertenant.vo.UserTenantRespVO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.user.UserTenantRelDO;
|
||||
import com.fjrcloud.community.module.system.dal.mysql.tenant.TenantMapper;
|
||||
import com.fjrcloud.community.module.system.service.usertenant.UserTenantRelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.fjrcloud.community.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 用户租户关联")
|
||||
@RestController
|
||||
@RequestMapping("/system/user-tenant")
|
||||
@Validated
|
||||
public class UserTenantRelController {
|
||||
|
||||
@Resource
|
||||
private UserTenantRelService userTenantRelService;
|
||||
|
||||
@Resource
|
||||
private TenantMapper tenantMapper;
|
||||
|
||||
@PostMapping("/assign")
|
||||
@Operation(summary = "分配用户到租户")
|
||||
@PreAuthorize("@ss.hasPermission('system:user-tenant:assign')")
|
||||
public CommonResult<Boolean> assignUserToTenant(@Valid @RequestBody UserTenantAssignReqVO reqVO) {
|
||||
userTenantRelService.assignUserToTenant(reqVO.getUserId(), reqVO.getTenantId(), reqVO.getIsDefault());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/remove")
|
||||
@Operation(summary = "移除用户租户关联")
|
||||
@Parameter(name = "userId", description = "用户ID", required = true, example = "1")
|
||||
@Parameter(name = "tenantId", description = "租户ID", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('system:user-tenant:remove')")
|
||||
public CommonResult<Boolean> removeUserFromTenant(@RequestParam("userId") Long userId,
|
||||
@RequestParam("tenantId") Long tenantId) {
|
||||
userTenantRelService.removeUserFromTenant(userId, tenantId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/batch-assign")
|
||||
@Operation(summary = "批量分配用户到多个租户")
|
||||
@PreAuthorize("@ss.hasPermission('system:user-tenant:assign')")
|
||||
public CommonResult<Boolean> batchAssignUserToTenants(@Valid @RequestBody UserTenantBatchAssignReqVO reqVO) {
|
||||
userTenantRelService.batchAssignUserToTenants(reqVO.getUserId(), reqVO.getTenantIds());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-user")
|
||||
@Operation(summary = "获取用户的租户列表")
|
||||
@Parameter(name = "userId", description = "用户ID", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('system:user-tenant:query')")
|
||||
public CommonResult<List<UserTenantRespVO>> getUserTenants(@RequestParam("userId") Long userId) {
|
||||
List<TenantInfoVO> tenantInfos = userTenantRelService.getUserTenants(userId);
|
||||
List<UserTenantRespVO> result = tenantInfos.stream().map(info -> {
|
||||
UserTenantRelDO rel = userTenantRelService.getUserTenantRel(userId, info.getTenantId());
|
||||
return UserTenantRespVO.builder()
|
||||
.id(rel != null ? rel.getId() : null)
|
||||
.userId(userId)
|
||||
.tenantId(info.getTenantId())
|
||||
.tenantName(info.getTenantName())
|
||||
.isDefault(info.getIsDefault())
|
||||
.createTime(rel != null ? rel.getCreateTime() : null)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
return success(result);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.fjrcloud.community.module.system.controller.admin.usertenant.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 分配用户到租户 Request VO")
|
||||
@Data
|
||||
public class UserTenantAssignReqVO {
|
||||
|
||||
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "租户ID不能为空")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description = "是否默认租户", example = "true")
|
||||
private Boolean isDefault;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.fjrcloud.community.module.system.controller.admin.usertenant.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 批量分配用户到租户 Request VO")
|
||||
@Data
|
||||
public class UserTenantBatchAssignReqVO {
|
||||
|
||||
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "租户ID列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]")
|
||||
@NotEmpty(message = "租户ID列表不能为空")
|
||||
private List<Long> tenantIds;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.fjrcloud.community.module.system.controller.admin.usertenant.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 用户租户关联 Response VO")
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class UserTenantRespVO {
|
||||
|
||||
@Schema(description = "关联ID", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户ID", example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "租户ID", example = "1")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description = "租户名称", example = "XX小区")
|
||||
private String tenantName;
|
||||
|
||||
@Schema(description = "是否默认租户", example = "true")
|
||||
private Boolean isDefault;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.fjrcloud.community.module.system.dal.dataobject.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fjrcloud.community.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.*;
|
||||
|
||||
@TableName("system_user_tenant_rel")
|
||||
@KeySequence("system_user_tenant_rel_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class UserTenantRelDO extends BaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private Long userId;
|
||||
|
||||
private Long tenantId;
|
||||
|
||||
private Boolean defaultTenant;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.fjrcloud.community.module.system.dal.mysql.user;
|
||||
|
||||
import com.fjrcloud.community.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.fjrcloud.community.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.user.UserTenantRelDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface UserTenantRelMapper extends BaseMapperX<UserTenantRelDO> {
|
||||
|
||||
default List<UserTenantRelDO> selectListByUserId(Long userId) {
|
||||
return selectList(UserTenantRelDO::getUserId, userId);
|
||||
}
|
||||
|
||||
default UserTenantRelDO selectByUserIdAndTenantId(Long userId, Long tenantId) {
|
||||
return selectOne(new LambdaQueryWrapperX<UserTenantRelDO>()
|
||||
.eq(UserTenantRelDO::getUserId, userId)
|
||||
.eq(UserTenantRelDO::getTenantId, tenantId));
|
||||
}
|
||||
|
||||
default UserTenantRelDO selectDefaultByUserId(Long userId) {
|
||||
return selectOne(new LambdaQueryWrapperX<UserTenantRelDO>()
|
||||
.eq(UserTenantRelDO::getUserId, userId)
|
||||
.eq(UserTenantRelDO::getDefaultTenant, true));
|
||||
}
|
||||
}
|
||||
|
|
@ -44,7 +44,11 @@ public interface ErrorCodeConstants {
|
|||
ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "名字为【{}】的用户已被禁用");
|
||||
ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过租户最大租户配额({})!");
|
||||
ErrorCode USER_IMPORT_INIT_PASSWORD = new ErrorCode(1_002_003_009, "初始密码不能为空");
|
||||
ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_002_003_010, "该手机号尚未注册");
|
||||
ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_002_010, "手机号未注册用户");
|
||||
|
||||
ErrorCode USER_TENANT_REL_NOT_EXISTS = new ErrorCode(1_002_011, "用户没有该租户的访问权限");
|
||||
ErrorCode USER_TENANT_REL_EXISTS = new ErrorCode(1_002_012, "用户已拥有该租户的访问权限");
|
||||
|
||||
ErrorCode USER_REGISTER_DISABLED = new ErrorCode(1_002_003_011, "注册功能已关闭");
|
||||
|
||||
// ========== 部门模块 1-002-004-000 ==========
|
||||
|
|
|
|||
|
|
@ -3,24 +3,19 @@ package com.fjrcloud.community.module.system.enums.logger;
|
|||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 登录结果的枚举类
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum LoginResultEnum {
|
||||
|
||||
SUCCESS(0), // 成功
|
||||
BAD_CREDENTIALS(10), // 账号或密码不正确
|
||||
USER_DISABLED(20), // 用户被禁用
|
||||
CAPTCHA_NOT_FOUND(30), // 图片验证码不存在
|
||||
CAPTCHA_CODE_ERROR(31), // 图片验证码不正确
|
||||
SUCCESS(0),
|
||||
BAD_CREDENTIALS(10),
|
||||
USER_DISABLED(20),
|
||||
CAPTCHA_NOT_FOUND(30),
|
||||
CAPTCHA_CODE_ERROR(31),
|
||||
TENANT_PERMISSION_DENIED(40),
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* 结果
|
||||
*/
|
||||
private final Integer result;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import com.fjrcloud.community.framework.common.util.object.BeanUtils;
|
|||
import com.fjrcloud.community.framework.common.util.servlet.ServletUtils;
|
||||
import com.fjrcloud.community.framework.common.util.validation.ValidationUtils;
|
||||
import com.fjrcloud.community.framework.datapermission.core.annotation.DataPermission;
|
||||
import com.fjrcloud.community.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.fjrcloud.community.framework.tenant.core.util.TenantUtils;
|
||||
import com.fjrcloud.community.module.system.api.logger.dto.LoginLogCreateReqDTO;
|
||||
import com.fjrcloud.community.module.system.api.sms.SmsCodeApi;
|
||||
import com.fjrcloud.community.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
||||
|
|
@ -20,6 +22,7 @@ import com.fjrcloud.community.module.system.controller.admin.auth.vo.*;
|
|||
import com.fjrcloud.community.module.system.convert.auth.AuthConvert;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.user.UserTenantRelDO;
|
||||
import com.fjrcloud.community.module.system.enums.logger.LoginLogTypeEnum;
|
||||
import com.fjrcloud.community.module.system.enums.logger.LoginResultEnum;
|
||||
import com.fjrcloud.community.module.system.enums.oauth2.OAuth2ClientConstants;
|
||||
|
|
@ -29,6 +32,7 @@ import com.fjrcloud.community.module.system.service.member.MemberService;
|
|||
import com.fjrcloud.community.module.system.service.oauth2.OAuth2TokenService;
|
||||
import com.fjrcloud.community.module.system.service.social.SocialUserService;
|
||||
import com.fjrcloud.community.module.system.service.user.AdminUserService;
|
||||
import com.fjrcloud.community.module.system.service.usertenant.UserTenantRelService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -38,17 +42,13 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Validator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.fjrcloud.community.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
import static com.fjrcloud.community.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* Auth Service 实现类
|
||||
*
|
||||
* @author 福建融云
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
|
|
@ -69,12 +69,11 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||
private CaptchaService captchaService;
|
||||
@Resource
|
||||
private SmsCodeApi smsCodeApi;
|
||||
@Resource
|
||||
private UserTenantRelService userTenantRelService;
|
||||
|
||||
/**
|
||||
* 验证码的开关,默认为 true
|
||||
*/
|
||||
@Value("${fjrcloud.captcha.enable:true}")
|
||||
@Setter // 为了单测:开启或者关闭验证码
|
||||
@Setter
|
||||
private Boolean captchaEnable;
|
||||
|
||||
@Override
|
||||
|
|
@ -112,13 +111,28 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||
socialUserService.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),
|
||||
reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState()));
|
||||
}
|
||||
// 创建 Token 令牌,记录登录日志
|
||||
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
if (tenantId == null) {
|
||||
createLoginLog(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.BAD_CREDENTIALS);
|
||||
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
|
||||
}
|
||||
|
||||
validateUserTenantPermission(user.getId(), tenantId);
|
||||
|
||||
return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
|
||||
}
|
||||
|
||||
private void validateUserTenantPermission(Long userId, Long tenantId) {
|
||||
UserTenantRelDO rel = userTenantRelService.getUserTenantRel(userId, tenantId);
|
||||
if (rel == null) {
|
||||
createLoginLog(userId, null, LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.TENANT_PERMISSION_DENIED);
|
||||
throw exception(USER_TENANT_REL_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSmsCode(AuthSmsSendReqVO reqVO) {
|
||||
// 如果是重置密码场景,需要校验图形验证码是否正确
|
||||
if (Objects.equals(SmsSceneEnum.ADMIN_MEMBER_RESET_PASSWORD.getScene(), reqVO.getScene())) {
|
||||
ResponseModel response = doValidateCaptcha(reqVO);
|
||||
if (!response.isSuccess()) {
|
||||
|
|
@ -145,7 +159,14 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||
throw exception(USER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 创建 Token 令牌,记录登录日志
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
if (tenantId == null) {
|
||||
createLoginLog(user.getId(), reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE, LoginResultEnum.BAD_CREDENTIALS);
|
||||
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
|
||||
}
|
||||
|
||||
validateUserTenantPermission(user.getId(), tenantId);
|
||||
|
||||
return createTokenAfterLoginSuccess(user.getId(), reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE);
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +204,11 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||
throw exception(USER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 创建 Token 令牌,记录登录日志
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
if (tenantId != null) {
|
||||
validateUserTenantPermission(user.getId(), tenantId);
|
||||
}
|
||||
|
||||
return createTokenAfterLoginSuccess(user.getId(), user.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL);
|
||||
}
|
||||
|
||||
|
|
@ -210,13 +235,25 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||
}
|
||||
|
||||
private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) {
|
||||
// 插入登陆日志
|
||||
createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS);
|
||||
// 创建访问令牌
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(),
|
||||
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
|
||||
OAuth2AccessTokenDO accessTokenDO;
|
||||
if (tenantId != null) {
|
||||
accessTokenDO = TenantUtils.execute(tenantId, () ->
|
||||
oauth2TokenService.createAccessToken(userId, getUserType().getValue(),
|
||||
OAuth2ClientConstants.CLIENT_ID_DEFAULT, null));
|
||||
} else {
|
||||
accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(),
|
||||
OAuth2ClientConstants.CLIENT_ID_DEFAULT, null);
|
||||
// 构建返回结果
|
||||
return BeanUtils.toBean(accessTokenDO, AuthLoginRespVO.class);
|
||||
}
|
||||
|
||||
List<TenantInfoVO> tenants = userTenantRelService.getUserTenants(userId);
|
||||
|
||||
AuthLoginRespVO respVO = BeanUtils.toBean(accessTokenDO, AuthLoginRespVO.class);
|
||||
respVO.setTenants(tenants);
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -227,12 +264,10 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||
|
||||
@Override
|
||||
public void logout(String token, Integer logType) {
|
||||
// 删除访问令牌
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(token);
|
||||
if (accessTokenDO == null) {
|
||||
return;
|
||||
}
|
||||
// 删除成功,则记录登出日志
|
||||
createLogoutLog(accessTokenDO.getUserId(), accessTokenDO.getUserType(), logType);
|
||||
}
|
||||
|
||||
|
|
@ -267,20 +302,16 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||
|
||||
@Override
|
||||
public AuthLoginRespVO register(AuthRegisterReqVO registerReqVO) {
|
||||
// 1. 校验验证码
|
||||
validateCaptcha(registerReqVO);
|
||||
|
||||
// 2. 校验用户名是否已存在
|
||||
Long userId = userService.registerUser(registerReqVO);
|
||||
|
||||
// 3. 创建 Token 令牌,记录登录日志
|
||||
return createTokenAfterLoginSuccess(userId, registerReqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateCaptcha(AuthRegisterReqVO reqVO) {
|
||||
ResponseModel response = doValidateCaptcha(reqVO);
|
||||
// 验证不通过
|
||||
if (!response.isSuccess()) {
|
||||
throw exception(AUTH_REGISTER_CAPTCHA_CODE_ERROR, response.getRepMsg());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.fjrcloud.community.framework.common.util.collection.CollectionUtils;
|
|||
import com.fjrcloud.community.framework.common.util.object.BeanUtils;
|
||||
import com.fjrcloud.community.framework.common.util.validation.ValidationUtils;
|
||||
import com.fjrcloud.community.framework.datapermission.core.util.DataPermissionUtils;
|
||||
import com.fjrcloud.community.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.fjrcloud.community.module.infra.api.config.ConfigApi;
|
||||
import com.fjrcloud.community.module.system.controller.admin.auth.vo.AuthRegisterReqVO;
|
||||
import com.fjrcloud.community.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
|
||||
|
|
@ -30,6 +31,7 @@ import com.fjrcloud.community.module.system.service.dept.PostService;
|
|||
import com.fjrcloud.community.module.system.service.oauth2.OAuth2TokenService;
|
||||
import com.fjrcloud.community.module.system.service.permission.PermissionService;
|
||||
import com.fjrcloud.community.module.system.service.tenant.TenantService;
|
||||
import com.fjrcloud.community.module.system.service.usertenant.UserTenantRelService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.mzt.logapi.context.LogRecordContext;
|
||||
import com.mzt.logapi.service.impl.DiffParseFunction;
|
||||
|
|
@ -78,10 +80,14 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
@Resource
|
||||
@Lazy // 延迟,避免循环依赖报错
|
||||
private TenantService tenantService;
|
||||
|
||||
@Resource
|
||||
@Lazy // 懒加载,避免循环依赖
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
|
||||
@Resource
|
||||
private UserTenantRelService userTenantRelService;
|
||||
|
||||
@Resource
|
||||
private UserPostMapper userPostMapper;
|
||||
|
||||
|
|
@ -93,52 +99,50 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
@LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_CREATE_SUB_TYPE, bizNo = "{{#user.id}}",
|
||||
success = SYSTEM_USER_CREATE_SUCCESS)
|
||||
public Long createUser(UserSaveReqVO createReqVO) {
|
||||
// 1.1 校验账户配合
|
||||
tenantService.handleTenantInfo(tenant -> {
|
||||
long count = userMapper.selectCount();
|
||||
if (count >= tenant.getAccountCount()) {
|
||||
throw exception(USER_COUNT_MAX, tenant.getAccountCount());
|
||||
}
|
||||
});
|
||||
// 1.2 校验正确性
|
||||
validateUserForCreateOrUpdate(null, createReqVO.getUsername(),
|
||||
createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds());
|
||||
// 2.1 插入用户
|
||||
|
||||
AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class);
|
||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
|
||||
user.setPassword(encodePassword(createReqVO.getPassword())); // 加密密码
|
||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
user.setPassword(encodePassword(createReqVO.getPassword()));
|
||||
userMapper.insert(user);
|
||||
// 2.2 插入关联岗位
|
||||
|
||||
if (CollectionUtil.isNotEmpty(user.getPostIds())) {
|
||||
userPostMapper.insertBatch(convertList(user.getPostIds(),
|
||||
postId -> new UserPostDO().setUserId(user.getId()).setPostId(postId)));
|
||||
}
|
||||
|
||||
// 3. 记录操作日志上下文
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
if (tenantId != null) {
|
||||
userTenantRelService.assignUserToTenant(user.getId(), tenantId, true);
|
||||
}
|
||||
|
||||
LogRecordContext.putVariable("user", user);
|
||||
return user.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long registerUser(AuthRegisterReqVO registerReqVO) {
|
||||
// 1.1 校验是否开启注册
|
||||
if (ObjUtil.notEqual(configApi.getConfigValueByKey(USER_REGISTER_ENABLED_KEY), "true")) {
|
||||
throw exception(USER_REGISTER_DISABLED);
|
||||
}
|
||||
// 1.2 校验账户配合
|
||||
tenantService.handleTenantInfo(tenant -> {
|
||||
long count = userMapper.selectCount();
|
||||
if (count >= tenant.getAccountCount()) {
|
||||
throw exception(USER_COUNT_MAX, tenant.getAccountCount());
|
||||
}
|
||||
});
|
||||
// 1.3 校验正确性
|
||||
validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null, null);
|
||||
|
||||
// 2. 插入用户
|
||||
AdminUserDO user = BeanUtils.toBean(registerReqVO, AdminUserDO.class);
|
||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
|
||||
user.setPassword(encodePassword(registerReqVO.getPassword())); // 加密密码
|
||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
user.setPassword(encodePassword(registerReqVO.getPassword()));
|
||||
userMapper.insert(user);
|
||||
return user.getId();
|
||||
}
|
||||
|
|
@ -148,18 +152,14 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
@LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
|
||||
success = SYSTEM_USER_UPDATE_SUCCESS)
|
||||
public void updateUser(UserSaveReqVO updateReqVO) {
|
||||
updateReqVO.setPassword(null); // 特殊:此处不更新密码
|
||||
// 1. 校验正确性
|
||||
updateReqVO.setPassword(null);
|
||||
AdminUserDO oldUser = validateUserForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getUsername(),
|
||||
updateReqVO.getMobile(), updateReqVO.getEmail(), updateReqVO.getDeptId(), updateReqVO.getPostIds());
|
||||
|
||||
// 2.1 更新用户
|
||||
AdminUserDO updateObj = BeanUtils.toBean(updateReqVO, AdminUserDO.class);
|
||||
userMapper.updateById(updateObj);
|
||||
// 2.2 更新岗位
|
||||
updateUserPost(updateReqVO, updateObj);
|
||||
|
||||
// 3. 记录操作日志上下文
|
||||
LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldUser, UserSaveReqVO.class));
|
||||
LogRecordContext.putVariable("user", oldUser);
|
||||
}
|
||||
|
|
@ -167,11 +167,9 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
private void updateUserPost(UserSaveReqVO reqVO, AdminUserDO updateObj) {
|
||||
Long userId = reqVO.getId();
|
||||
Set<Long> dbPostIds = convertSet(userPostMapper.selectListByUserId(userId), UserPostDO::getPostId);
|
||||
// 计算新增和删除的岗位编号
|
||||
Set<Long> postIds = CollUtil.emptyIfNull(updateObj.getPostIds());
|
||||
Collection<Long> createPostIds = CollUtil.subtract(postIds, dbPostIds);
|
||||
Collection<Long> deletePostIds = CollUtil.subtract(dbPostIds, postIds);
|
||||
// 执行新增和删除。对于已经授权的岗位,不用做任何处理
|
||||
if (!CollectionUtil.isEmpty(createPostIds)) {
|
||||
userPostMapper.insertBatch(convertList(createPostIds,
|
||||
postId -> new UserPostDO().setUserId(userId).setPostId(postId)));
|
||||
|
|
@ -188,21 +186,17 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
|
||||
@Override
|
||||
public void updateUserProfile(Long id, UserProfileUpdateReqVO reqVO) {
|
||||
// 校验正确性
|
||||
validateUserExists(id);
|
||||
validateEmailUnique(id, reqVO.getEmail());
|
||||
validateMobileUnique(id, reqVO.getMobile());
|
||||
// 执行更新
|
||||
userMapper.updateById(BeanUtils.toBean(reqVO, AdminUserDO.class).setId(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserPassword(Long id, UserProfileUpdatePasswordReqVO reqVO) {
|
||||
// 校验旧密码密码
|
||||
validateOldPassword(id, reqVO.getOldPassword());
|
||||
// 执行更新
|
||||
AdminUserDO updateObj = new AdminUserDO().setId(id);
|
||||
updateObj.setPassword(encodePassword(reqVO.getNewPassword())); // 加密密码
|
||||
updateObj.setPassword(encodePassword(reqVO.getNewPassword()));
|
||||
userMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
|
|
@ -210,31 +204,25 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
@LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_UPDATE_PASSWORD_SUB_TYPE, bizNo = "{{#id}}",
|
||||
success = SYSTEM_USER_UPDATE_PASSWORD_SUCCESS)
|
||||
public void updateUserPassword(Long id, String password) {
|
||||
// 1. 校验用户存在
|
||||
AdminUserDO user = validateUserExists(id);
|
||||
|
||||
// 2. 更新密码
|
||||
AdminUserDO updateObj = new AdminUserDO();
|
||||
updateObj.setId(id);
|
||||
updateObj.setPassword(encodePassword(password)); // 加密密码
|
||||
updateObj.setPassword(encodePassword(password));
|
||||
userMapper.updateById(updateObj);
|
||||
|
||||
// 3. 记录操作日志上下文
|
||||
LogRecordContext.putVariable("user", user);
|
||||
LogRecordContext.putVariable("newPassword", updateObj.getPassword());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserStatus(Long id, Integer status) {
|
||||
// 校验用户存在
|
||||
validateUserExists(id);
|
||||
// 更新状态
|
||||
AdminUserDO updateObj = new AdminUserDO();
|
||||
updateObj.setId(id);
|
||||
updateObj.setStatus(status);
|
||||
userMapper.updateById(updateObj);
|
||||
|
||||
// 如果是禁用用户,则删除其 Token 信息
|
||||
if (CommonStatusEnum.isDisable(status)) {
|
||||
oauth2TokenService.removeAccessToken(id, UserTypeEnum.ADMIN.getValue());
|
||||
}
|
||||
|
|
@ -245,27 +233,20 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
@LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_DELETE_SUB_TYPE, bizNo = "{{#id}}",
|
||||
success = SYSTEM_USER_DELETE_SUCCESS)
|
||||
public void deleteUser(Long id) {
|
||||
// 1. 校验用户存在
|
||||
AdminUserDO user = validateUserExists(id);
|
||||
|
||||
// 2.1 删除用户
|
||||
userMapper.deleteById(id);
|
||||
// 2.2 删除用户关联数据
|
||||
permissionService.processUserDeleted(id);
|
||||
// 2.2 删除用户岗位
|
||||
userPostMapper.deleteByUserId(id);
|
||||
|
||||
// 3. 记录操作日志上下文
|
||||
LogRecordContext.putVariable("user", user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteUserList(List<Long> ids) {
|
||||
// 1. 批量删除用户
|
||||
userMapper.deleteByIds(ids);
|
||||
|
||||
// 2. 批量删除用户关联数据
|
||||
ids.forEach(id -> {
|
||||
permissionService.processUserDeleted(id);
|
||||
userPostMapper.deleteByUserId(id);
|
||||
|
|
@ -284,7 +265,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
|
||||
@Override
|
||||
public PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO) {
|
||||
// 如果有角色编号,查询角色对应的用户编号
|
||||
Set<Long> userIds = null;
|
||||
if (reqVO.getRoleId() != null) {
|
||||
userIds = permissionService.getUserRoleIdListByRoleId(singleton(reqVO.getRoleId()));
|
||||
|
|
@ -293,7 +273,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
}
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
return userMapper.selectPage(reqVO, getDeptCondition(reqVO.getDeptId()), userIds);
|
||||
}
|
||||
|
||||
|
|
@ -335,10 +314,8 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 获得岗位信息
|
||||
List<AdminUserDO> users = userMapper.selectByIds(ids);
|
||||
Map<Long, AdminUserDO> userMap = CollectionUtils.convertMap(users, AdminUserDO::getId);
|
||||
// 校验
|
||||
ids.forEach(id -> {
|
||||
AdminUserDO user = userMap.get(id);
|
||||
if (user == null) {
|
||||
|
|
@ -355,36 +332,23 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
return userMapper.selectListByNickname(nickname);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得部门条件:查询指定部门的子部门编号们,包括自身
|
||||
*
|
||||
* @param deptId 部门编号
|
||||
* @return 部门编号集合
|
||||
*/
|
||||
private Set<Long> getDeptCondition(Long deptId) {
|
||||
if (deptId == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<Long> deptIds = convertSet(deptService.getChildDeptList(deptId), DeptDO::getId);
|
||||
deptIds.add(deptId); // 包括自身
|
||||
deptIds.add(deptId);
|
||||
return deptIds;
|
||||
}
|
||||
|
||||
private AdminUserDO validateUserForCreateOrUpdate(Long id, String username, String mobile, String email,
|
||||
Long deptId, Set<Long> postIds) {
|
||||
// 关闭数据权限,避免因为没有数据权限,查询不到数据,进而导致唯一校验不正确
|
||||
return DataPermissionUtils.executeIgnore(() -> {
|
||||
// 校验用户存在
|
||||
AdminUserDO user = validateUserExists(id);
|
||||
// 校验用户名唯一
|
||||
validateUsernameUnique(id, username);
|
||||
// 校验手机号唯一
|
||||
validateMobileUnique(id, mobile);
|
||||
// 校验邮箱唯一
|
||||
validateEmailUnique(id, email);
|
||||
// 校验部门处于开启状态
|
||||
deptService.validateDeptList(CollectionUtils.singleton(deptId));
|
||||
// 校验岗位处于开启状态
|
||||
postService.validatePostList(postIds);
|
||||
return user;
|
||||
});
|
||||
|
|
@ -411,7 +375,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的用户
|
||||
if (id == null) {
|
||||
throw exception(USER_USERNAME_EXISTS);
|
||||
}
|
||||
|
|
@ -429,7 +392,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的用户
|
||||
if (id == null) {
|
||||
throw exception(USER_EMAIL_EXISTS);
|
||||
}
|
||||
|
|
@ -447,7 +409,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的用户
|
||||
if (id == null) {
|
||||
throw exception(USER_MOBILE_EXISTS);
|
||||
}
|
||||
|
|
@ -456,11 +417,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验旧密码
|
||||
* @param id 用户 id
|
||||
* @param oldPassword 旧密码
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void validateOldPassword(Long id, String oldPassword) {
|
||||
AdminUserDO user = userMapper.selectById(id);
|
||||
|
|
@ -473,25 +429,21 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserImportRespVO importUserList(List<UserImportExcelVO> importUsers, boolean isUpdateSupport) {
|
||||
// 1.1 参数校验
|
||||
if (CollUtil.isEmpty(importUsers)) {
|
||||
throw exception(USER_IMPORT_LIST_IS_EMPTY);
|
||||
}
|
||||
// 1.2 初始化密码不能为空
|
||||
String initPassword = configApi.getConfigValueByKey(USER_INIT_PASSWORD_KEY);
|
||||
if (StrUtil.isEmpty(initPassword)) {
|
||||
throw exception(USER_IMPORT_INIT_PASSWORD);
|
||||
}
|
||||
|
||||
// 2. 遍历,逐个创建 or 更新
|
||||
UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
|
||||
.updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
|
||||
AtomicInteger index = new AtomicInteger(1);
|
||||
importUsers.forEach(importUser -> {
|
||||
int currentIndex = index.getAndIncrement();
|
||||
// 2.1.1 校验字段是否符合要求
|
||||
try {
|
||||
ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class).setPassword(initPassword));
|
||||
} catch (ConstraintViolationException ex) {
|
||||
|
|
@ -499,7 +451,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
respVO.getFailureUsernames().put(key, ex.getMessage());
|
||||
return;
|
||||
}
|
||||
// 2.1.2 校验,判断是否有不符合的原因
|
||||
try {
|
||||
validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
|
||||
importUser.getDeptId(), null);
|
||||
|
|
@ -508,7 +459,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
return;
|
||||
}
|
||||
|
||||
// 2.2.1 判断如果不存在,在进行插入
|
||||
AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
|
||||
if (existUser == null) {
|
||||
userMapper.insert(BeanUtils.toBean(importUser, AdminUserDO.class)
|
||||
|
|
@ -516,7 +466,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
respVO.getCreateUsernames().add(importUser.getUsername());
|
||||
return;
|
||||
}
|
||||
// 2.2.2 如果存在,判断是否允许更新
|
||||
if (!isUpdateSupport) {
|
||||
respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg());
|
||||
return;
|
||||
|
|
@ -539,12 +488,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||
return passwordEncoder.matches(rawPassword, encodedPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对密码进行加密
|
||||
*
|
||||
* @param password 密码
|
||||
* @return 加密后的密码
|
||||
*/
|
||||
private String encodePassword(String password) {
|
||||
return passwordEncoder.encode(password);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.fjrcloud.community.module.system.service.usertenant;
|
||||
|
||||
import com.fjrcloud.community.module.system.controller.admin.auth.vo.TenantInfoVO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.user.UserTenantRelDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserTenantRelService {
|
||||
|
||||
List<TenantInfoVO> getUserTenants(Long userId);
|
||||
|
||||
UserTenantRelDO getUserTenantRel(Long userId, Long tenantId);
|
||||
|
||||
UserTenantRelDO getDefaultTenant(Long userId);
|
||||
|
||||
void assignUserToTenant(Long userId, Long tenantId, Boolean isDefault);
|
||||
|
||||
void removeUserFromTenant(Long userId, Long tenantId);
|
||||
|
||||
void batchAssignUserToTenants(Long userId, List<Long> tenantIds);
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package com.fjrcloud.community.module.system.service.usertenant;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.fjrcloud.community.framework.common.exception.ServiceException;
|
||||
import com.fjrcloud.community.module.system.controller.admin.auth.vo.TenantInfoVO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.fjrcloud.community.module.system.dal.dataobject.user.UserTenantRelDO;
|
||||
import com.fjrcloud.community.module.system.dal.mysql.tenant.TenantMapper;
|
||||
import com.fjrcloud.community.module.system.dal.mysql.user.UserTenantRelMapper;
|
||||
import com.fjrcloud.community.module.system.enums.ErrorCodeConstants;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
@Service
|
||||
public class UserTenantRelServiceImpl implements UserTenantRelService {
|
||||
|
||||
@Resource
|
||||
private UserTenantRelMapper userTenantRelMapper;
|
||||
|
||||
@Resource
|
||||
private TenantMapper tenantMapper;
|
||||
|
||||
@Override
|
||||
public List<TenantInfoVO> getUserTenants(Long userId) {
|
||||
List<UserTenantRelDO> rels = userTenantRelMapper.selectListByUserId(userId);
|
||||
if (CollUtil.isEmpty(rels)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return rels.stream().map(rel -> {
|
||||
TenantDO tenant = tenantMapper.selectById(rel.getTenantId());
|
||||
return TenantInfoVO.builder()
|
||||
.tenantId(rel.getTenantId())
|
||||
.tenantName(tenant != null ? tenant.getName() : "")
|
||||
.isDefault(rel.getDefaultTenant())
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserTenantRelDO getUserTenantRel(Long userId, Long tenantId) {
|
||||
return userTenantRelMapper.selectByUserIdAndTenantId(userId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserTenantRelDO getDefaultTenant(Long userId) {
|
||||
return userTenantRelMapper.selectDefaultByUserId(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void assignUserToTenant(Long userId, Long tenantId, Boolean isDefault) {
|
||||
TenantDO tenant = tenantMapper.selectById(tenantId);
|
||||
if (tenant == null) {
|
||||
throw exception(ErrorCodeConstants.TENANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
UserTenantRelDO existRel = userTenantRelMapper.selectByUserIdAndTenantId(userId, tenantId);
|
||||
if (existRel != null) {
|
||||
throw exception(ErrorCodeConstants.USER_TENANT_REL_EXISTS);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(isDefault)) {
|
||||
clearDefaultTenant(userId);
|
||||
}
|
||||
|
||||
UserTenantRelDO rel = new UserTenantRelDO();
|
||||
rel.setUserId(userId);
|
||||
rel.setTenantId(tenantId);
|
||||
rel.setDefaultTenant(isDefault != null ? isDefault : false);
|
||||
userTenantRelMapper.insert(rel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void removeUserFromTenant(Long userId, Long tenantId) {
|
||||
UserTenantRelDO rel = userTenantRelMapper.selectByUserIdAndTenantId(userId, tenantId);
|
||||
if (rel == null) {
|
||||
return;
|
||||
}
|
||||
userTenantRelMapper.deleteById(rel.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchAssignUserToTenants(Long userId, List<Long> tenantIds) {
|
||||
if (CollUtil.isEmpty(tenantIds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Long tenantId : tenantIds) {
|
||||
try {
|
||||
assignUserToTenant(userId, tenantId, false);
|
||||
} catch (ServiceException e) {
|
||||
// 忽略已存在的关联
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDefaultTenant(Long userId) {
|
||||
UserTenantRelDO defaultRel = userTenantRelMapper.selectDefaultByUserId(userId);
|
||||
if (defaultRel != null) {
|
||||
defaultRel.setDefaultTenant(false);
|
||||
userTenantRelMapper.updateById(defaultRel);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue