Ver Fonte

前端用戶註冊功能附帶邀请码註冊

liyanbo há 3 meses atrás
pai
commit
e3f48b0a78

+ 1 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/enums/ErrorCodeConstants.java

@@ -51,6 +51,7 @@ public interface ErrorCodeConstants {
     ErrorCode USER_IMPORT_INIT_PASSWORD = new ErrorCode(1_002_003_009, "初始密码不能为空");
     ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_002_003_010, "该手机号尚未注册");
     ErrorCode USER_REGISTER_DISABLED = new ErrorCode(1_002_003_011, "注册功能已关闭");
+    ErrorCode USER_CODE_FAILURE = new ErrorCode(1_002_003_012, "邀请码校验失败");
 
     // ========== 部门模块 1-002-004-000 ==========
     ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门");

+ 8 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/service/invitecode/InviteCodeService.java

@@ -53,6 +53,14 @@ public interface InviteCodeService {
      */
     InviteCodeDO getInviteCode(Long id);
 
+    /**
+     * 获得指定邀请码(未使用)
+     *
+     * @param inviteCode 邀请码
+     * @return 邀请码
+     */
+    InviteCodeDO getUnusedInviteCode(String inviteCode);
+
     /**
      * 获得邀请码分页
      *

+ 9 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/service/invitecode/InviteCodeServiceImpl.java

@@ -15,10 +15,12 @@ import cn.iocoder.byzs.module.system.dal.mysql.invitecode.InviteCodeMapper;
 import cn.iocoder.byzs.module.system.dal.mysql.permission.RoleMapper;
 import cn.iocoder.byzs.module.system.dal.mysql.tenant.TenantMapper;
 import cn.iocoder.byzs.module.system.dal.mysql.user.AdminUserMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
+import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -147,6 +149,13 @@ public class InviteCodeServiceImpl implements InviteCodeService {
         return inviteCodeMapper.selectById(id);
     }
 
+    @Override
+    public InviteCodeDO getUnusedInviteCode(String inviteCode) {
+        return inviteCodeMapper.selectOne(new LambdaQueryWrapper<InviteCodeDO>()
+                .eq(InviteCodeDO::getCode, inviteCode)
+                .eq(InviteCodeDO::getStatus, "0"));
+    }
+
     @Override
     public PageResult<InviteCodeRespVO> getInviteCodePage(InviteCodePageReqVO pageReqVO) {
         PageResult<InviteCodeDO> inviteCodeDOPageResult = inviteCodeMapper.selectPage(pageReqVO);

+ 21 - 11
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/login/WebLoginController.java

@@ -3,7 +3,6 @@ package cn.iocoder.byzs.module.web.controller.admin.login;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.byzs.framework.common.pojo.CommonResult;
-import cn.iocoder.byzs.framework.common.util.json.JsonUtils;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
 import cn.iocoder.byzs.framework.security.config.SecurityProperties;
 import cn.iocoder.byzs.framework.security.core.util.SecurityFrameworkUtils;
@@ -22,7 +21,9 @@ import cn.iocoder.byzs.module.system.service.dict.DictDataService;
 import cn.iocoder.byzs.module.system.service.permission.PermissionService;
 import cn.iocoder.byzs.module.system.service.permission.RoleService;
 import cn.iocoder.byzs.module.system.service.tenant.TenantService;
-import cn.iocoder.byzs.module.web.controller.admin.login.vo.AuthLoginVO;
+import cn.iocoder.byzs.module.web.controller.admin.login.vo.WebLoginVO;
+import cn.iocoder.byzs.module.web.controller.admin.login.vo.WebRegisterVO;
+import cn.iocoder.byzs.module.web.service.login.WebLoginServiceImpl;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -34,7 +35,6 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -57,6 +57,8 @@ public class WebLoginController {
     private RoleService roleService;
     @Resource
     private DictDataService dictDataService;
+    @Resource
+    private WebLoginServiceImpl webLoginServiceImpl;
 
 
     @GetMapping("/getTenantIdByName")
@@ -69,17 +71,25 @@ public class WebLoginController {
         return success(tenant != null ? tenant.getId() : null);
     }
 
+    @PostMapping("/register")
+    @PermitAll
+    @Operation(summary = "注册租户")
+    public CommonResult<Boolean> register(@RequestBody @Valid WebRegisterVO reqVO) {
+        Long register = webLoginServiceImpl.register(reqVO);
+        return success(register != null);
+    }
+
     @PostMapping("/login")
     @PermitAll
     @Operation(summary = "使用账号密码登录")
-    public CommonResult<AuthLoginVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
+    public CommonResult<WebLoginVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
         return success(setAuthRoleVO(authService.login(reqVO)));
     }
 
     @PostMapping("/sms-login")
     @PermitAll
     @Operation(summary = "使用短信验证码登录")
-    public CommonResult<AuthLoginVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
+    public CommonResult<WebLoginVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
         return success(setAuthRoleVO(authService.smsLogin(reqVO)));
     }
 
@@ -131,12 +141,12 @@ public class WebLoginController {
      * @param login
      * @return
      */
-    private AuthLoginVO setAuthRoleVO(AuthLoginRespVO login) {
-        AuthLoginVO authLoginVO = BeanUtils.toBean(login, AuthLoginVO.class);
+    private WebLoginVO setAuthRoleVO(AuthLoginRespVO login) {
+        WebLoginVO webLoginVO = BeanUtils.toBean(login, WebLoginVO.class);
 
         // 已经在后台读取,这里无需重复读取
         if (true) {
-            return authLoginVO;
+            return webLoginVO;
         }
 
         // 获得角色列表
@@ -161,8 +171,8 @@ public class WebLoginController {
         }
 
         //填充课程数据权限
-        authLoginVO.setCourseDataScope(allDataScopeCourseIds);
-        authLoginVO.setBlocklyDataScope(allDataScopeBlocklyIds);
-        return authLoginVO;
+        webLoginVO.setCourseDataScope(allDataScopeCourseIds);
+        webLoginVO.setBlocklyDataScope(allDataScopeBlocklyIds);
+        return webLoginVO;
     }
 }

+ 1 - 1
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/login/vo/AuthLoginVO.java → byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/login/vo/WebLoginVO.java

@@ -8,7 +8,7 @@ import java.util.Set;
 
 @Schema(description = "管理强泰 - 账号密码登录 Request VO")
 @Data
-public class AuthLoginVO {
+public class WebLoginVO {
 
     @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long userId;

+ 37 - 0
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/login/vo/WebRegisterVO.java

@@ -0,0 +1,37 @@
+package cn.iocoder.byzs.module.web.controller.admin.login.vo;
+
+
+import cn.iocoder.byzs.module.system.controller.admin.auth.vo.CaptchaVerificationReqVO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.Pattern;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+@Schema(description = "管理后台 - Register Request VO")
+@Data
+public class WebRegisterVO extends CaptchaVerificationReqVO {
+
+    @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "byzs")
+    @NotBlank(message = "用户账号不能为空")
+    @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
+    @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
+    private String username;
+
+    @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "lyb")
+    @NotBlank(message = "用户昵称不能为空")
+    @Size(max = 30, message = "用户昵称长度不能超过 30 个字符")
+    private String nickname;
+
+    @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
+    @NotEmpty(message = "密码不能为空")
+    @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
+    private String password;
+
+    @Schema(description = "邀请码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
+    @NotEmpty(message = "邀请码不能为空")
+    @Length(min = 10, max = 20, message = "邀请码长度为 10-20 位")
+    private String inviteCode;
+}

+ 50 - 0
byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/login/WebLoginServiceImpl.java

@@ -0,0 +1,50 @@
+package cn.iocoder.byzs.module.web.service.login;
+
+import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthRegisterReqVO;
+import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodeSaveReqVO;
+import cn.iocoder.byzs.module.system.dal.dataobject.invitecode.InviteCodeDO;
+import cn.iocoder.byzs.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.byzs.module.system.service.invitecode.InviteCodeService;
+import cn.iocoder.byzs.module.system.service.user.AdminUserServiceImpl;
+import cn.iocoder.byzs.module.web.controller.admin.login.vo.WebRegisterVO;
+import jakarta.annotation.Resource;
+
+import java.time.LocalDateTime;
+
+import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.USER_CODE_FAILURE;
+
+public class WebLoginServiceImpl {
+    @Resource
+    private AdminUserServiceImpl userService;
+    @Resource
+    private InviteCodeService inviteCodeService;
+
+    public Long register(WebRegisterVO registerVO) {
+
+        //校验邀请码
+        InviteCodeDO inviteCode = inviteCodeService.getUnusedInviteCode(registerVO.getInviteCode());
+        if (inviteCode == null) {
+            throw exception(USER_CODE_FAILURE);
+        }
+
+        // 注册
+        AuthRegisterReqVO registerReqVo = new AuthRegisterReqVO();
+        BeanUtils.copyProperties(registerVO, registerReqVo);
+        Long userId = userService.registerUser(registerReqVo);
+        AdminUserDO user = userService.getUser(userId);
+
+        // 更新邀请码为已使用
+        inviteCodeService.updateInviteCode(new InviteCodeSaveReqVO()
+                        .setId(inviteCode.getId())
+                        .setUseUserId(userId)
+                        .setUseUserTenantId(user.getTenantId())
+                        .setUseTime(LocalDateTime.now())
+                        .setExpireTime(LocalDateTime.now().plusDays(inviteCode.getValidTime()))
+                        .setStatus("2"));
+
+        // 构建返回值
+        return userId;
+    }
+}