Commit afd5a9c8590902af0365631a541c7e081806ea5f

Authored by 芋道源码
Committed by Gitee
2 parents 9c5c40fe 258250e3

!1074 增加用户注册功能

Merge pull request !1074 from scholarli/develop
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
... ... @@ -154,4 +154,10 @@ public class AuthController {
154 154 return success(authService.socialLogin(reqVO));
155 155 }
156 156  
  157 + @PostMapping("/register")
  158 + @PermitAll
  159 + @Operation(summary = "注册用户")
  160 + public CommonResult<AuthLoginRespVO> register(@RequestBody @Valid AuthRegisterReqVO registerReqVO) {
  161 + return success(authService.register(registerReqVO));
  162 + }
157 163 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthRegisterReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.auth.vo;
  2 +
  3 +
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import org.hibernate.validator.constraints.Length;
  7 +
  8 +import jakarta.validation.constraints.*;
  9 +
  10 +@Schema(description = "管理后台 - Register Request VO")
  11 +@Data
  12 +public class AuthRegisterReqVO {
  13 +
  14 + @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
  15 + @NotBlank(message = "用户账号不能为空")
  16 + @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
  17 + @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
  18 + private String username;
  19 +
  20 + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
  21 + @Size(max = 30, message = "用户昵称长度不能超过30个字符")
  22 + private String nickname;
  23 +
  24 + @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
  25 + @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
  26 + private String password;
  27 +
  28 + // ========== 图片验证码相关 ==========
  29 + @Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED,
  30 + example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==")
  31 + @NotEmpty(message = "验证码不能为空", groups = AuthLoginReqVO.CodeEnableGroup.class)
  32 + private String captchaVerification;
  33 +}
0 34 \ No newline at end of file
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java
... ... @@ -70,4 +70,11 @@ public interface AdminAuthService {
70 70 */
71 71 AuthLoginRespVO refreshToken(String refreshToken);
72 72  
  73 + /**
  74 + * 用户注册
  75 + *
  76 + * @param createReqVO 注册用户
  77 + * @return 注册结果
  78 + */
  79 + AuthLoginRespVO register(AuthRegisterReqVO createReqVO);
73 80 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
... ... @@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 6 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 8 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
8 9 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
9 10 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
... ... @@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*;
14 15 import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
15 16 import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
16 17 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  18 +import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
17 19 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
18 20 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
19 21 import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants;
... ... @@ -22,6 +24,7 @@ import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
22 24 import cn.iocoder.yudao.module.system.service.member.MemberService;
23 25 import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
24 26 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
  27 +import cn.iocoder.yudao.module.system.service.tenant.TenantService;
25 28 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
26 29 import com.google.common.annotations.VisibleForTesting;
27 30 import com.xingyuv.captcha.model.common.ResponseModel;
... ... @@ -29,6 +32,8 @@ import com.xingyuv.captcha.model.vo.CaptchaVO;
29 32 import com.xingyuv.captcha.service.CaptchaService;
30 33 import lombok.extern.slf4j.Slf4j;
31 34 import org.springframework.beans.factory.annotation.Value;
  35 +import org.springframework.context.annotation.Lazy;
  36 +import org.springframework.security.crypto.password.PasswordEncoder;
32 37 import org.springframework.stereotype.Service;
33 38  
34 39 import jakarta.annotation.Resource;
... ... @@ -64,7 +69,13 @@ public class AdminAuthServiceImpl implements AdminAuthService {
64 69 private CaptchaService captchaService;
65 70 @Resource
66 71 private SmsCodeApi smsCodeApi;
67   -
  72 + @Resource
  73 + @Lazy // 延迟,避免循环依赖报错
  74 + private TenantService tenantService;
  75 + @Resource
  76 + private AdminUserMapper userMapper;
  77 + @Resource
  78 + private PasswordEncoder passwordEncoder;
68 79 /**
69 80 * 验证码的开关,默认为 true
70 81 */
... ... @@ -247,4 +258,38 @@ public class AdminAuthServiceImpl implements AdminAuthService {
247 258 return UserTypeEnum.ADMIN;
248 259 }
249 260  
  261 +
  262 + public AuthLoginRespVO register(AuthRegisterReqVO registerReqVO) {
  263 + // 校验验证码
  264 + AuthLoginReqVO loginReqVO = BeanUtils.toBean(registerReqVO, AuthLoginReqVO.class);
  265 + validateCaptcha(loginReqVO);
  266 + // 校验账户配合
  267 + tenantService.handleTenantInfo(tenant -> {
  268 + long count = userMapper.selectCount();
  269 + if (count >= tenant.getAccountCount()) {
  270 + throw exception(USER_COUNT_MAX, tenant.getAccountCount());
  271 + }
  272 + });
  273 + // 校验用户名是否已存在
  274 + if (userMapper.selectByUsername(registerReqVO.getUsername()) != null) {
  275 + throw exception(USER_USERNAME_EXISTS);
  276 + }
  277 + // 插入用户
  278 + AdminUserDO user = BeanUtils.toBean(registerReqVO, AdminUserDO.class);
  279 + user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
  280 + user.setPassword(encodePassword(registerReqVO.getPassword())); // 加密密码
  281 + userMapper.insert(user);
  282 +
  283 + return createTokenAfterLoginSuccess(user.getId(), registerReqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
  284 + }
  285 +
  286 + /**
  287 + * 对密码进行加密
  288 + *
  289 + * @param password 密码
  290 + * @return 加密后的密码
  291 + */
  292 + private String encodePassword(String password) {
  293 + return passwordEncoder.encode(password);
  294 + }
250 295 }
... ...