Просмотр исходного кода

邀请码加入指定手机号绑定,过期邀请码
web注册增加手机号校验和邀请码过期校验
增加定时器每日凌晨清理过期邀请码

liyanbo 3 недель назад
Родитель
Сommit
e2444ef93f

+ 3 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/controller/admin/invitecode/vo/InviteCodePageReqVO.java

@@ -46,4 +46,7 @@ public class InviteCodePageReqVO extends PageParam {
     @Schema(description = "租户编号", example = "24563")
     private Long tenantId;
 
+    @Schema(description = "指定手机号")
+    private String onlyPhone;
+
 }

+ 4 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/controller/admin/invitecode/vo/InviteCodeRespVO.java

@@ -72,4 +72,8 @@ public class InviteCodeRespVO {
     @ExcelProperty("租户编号")
     private Long tenantId;
 
+    @Schema(description = "指定手机号")
+    @ExcelProperty("指定手机号")
+    private String onlyPhone;
+
 }

+ 3 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/controller/admin/invitecode/vo/InviteCodeSaveReqVO.java

@@ -26,6 +26,9 @@ public class InviteCodeSaveReqVO {
     @Schema(description = "有效期(天)")
     private Integer validTime;
 
+    @Schema(description = "指定手机号")
+    private String onlyPhone;
+
     @Schema(description = "使用时间")
     private LocalDateTime useTime;
 

+ 5 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/dal/dataobject/invitecode/InviteCodeDO.java

@@ -63,6 +63,11 @@ public class InviteCodeDO extends BaseDO {
      */
     private String status;
 
+    /**
+     * 指定手机号
+     */
+    private String onlyPhone;
+
     private Long tenantId;
 
 

+ 1 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/dal/mysql/invitecode/InviteCodeMapper.java

@@ -24,6 +24,7 @@ public interface InviteCodeMapper extends BaseMapperX<InviteCodeDO> {
 //                .eqIfPresent(InviteCodeDO::getUseUserId, reqVO.getUseUserName())
 //                .eqIfPresent(InviteCodeDO::getUseUserTenantId, reqVO.getUseUserTenantName())
                 .eqIfPresent(InviteCodeDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(InviteCodeDO::getOnlyPhone, reqVO.getOnlyPhone())
                 .betweenIfPresent(InviteCodeDO::getCreateTime, reqVO.getCreateTime())
                 .eqIfPresent(InviteCodeDO::getTenantId, reqVO.getTenantId())
                 .orderByDesc(InviteCodeDO::getId));

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

@@ -56,6 +56,8 @@ public interface ErrorCodeConstants {
     ErrorCode USER_REGISTER_DISABLED = new ErrorCode(1_002_003_011, "注册功能已关闭");
     ErrorCode USER_CODE_FAILURE = new ErrorCode(1_002_003_012, "邀请码校验失败");
     ErrorCode USER_CODE_USED = new ErrorCode(1_002_003_013, "邀请码已被使用");
+    ErrorCode USER_CODE_EXPIRED = new ErrorCode(1_002_003_014, "邀请码已过期");
+    ErrorCode USER_CODE_ONLY_PHONE_ERROR = new ErrorCode(1_002_003_015, "邀请码指定手机号与注册手机号不一致");
 
     // ========== 部门模块 1-002-004-000 ==========
     ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门");

+ 59 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/job/InviteCodeExpireJob.java

@@ -0,0 +1,59 @@
+package cn.iocoder.byzs.module.system.job;
+
+import cn.iocoder.byzs.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.byzs.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.byzs.module.system.dal.dataobject.invitecode.InviteCodeDO;
+import cn.iocoder.byzs.module.system.dal.mysql.invitecode.InviteCodeMapper;
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 邀请码过期检查定时任务
+ *
+ * @author lyb
+ */
+@Slf4j
+@Component
+public class InviteCodeExpireJob implements JobHandler {
+
+    @Resource
+    private InviteCodeMapper inviteCodeMapper;
+
+    @Override
+    @TenantIgnore
+    public String execute(String param) {
+        log.info("开始执行邀请码过期检查任务");
+
+        try {
+            // 1. 查询所有未使用且已过期的邀请码
+            LocalDateTime now = LocalDateTime.now();
+            List<InviteCodeDO> expiredInviteCodes = inviteCodeMapper.selectList(new LambdaQueryWrapperX<InviteCodeDO>()
+                    .eq(InviteCodeDO::getStatus, "0") // 状态未使用
+                    .le(InviteCodeDO::getExpireTime, now) // 过期时间小与于等于当前时间
+            );
+
+            log.info("发现 {} 个过期的邀请码", expiredInviteCodes.size());
+
+            // 2. 更新过期邀请码的状态
+            int updateCount = 0;
+            for (InviteCodeDO inviteCode : expiredInviteCodes) {
+                // 将状态设置为过期("3"表示过期状态)
+                inviteCode.setStatus("3");
+                inviteCodeMapper.updateById(inviteCode);
+                updateCount++;
+                log.info("邀请码 {} 已设置为过期状态", inviteCode.getCode());
+            }
+
+            log.info("邀请码过期检查任务执行完成,共处理 {} 个过期邀请码", updateCount);
+            return String.format("成功处理 %d 个过期邀请码", updateCount);
+        } catch (Exception e) {
+            log.error("执行邀请码过期检查任务时发生错误", e);
+            return "执行任务时发生错误: " + e.getMessage();
+        }
+    }
+}

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

@@ -270,6 +270,18 @@ public class InviteCodeServiceImpl implements InviteCodeService {
                     .collect(Collectors.toList());
         }
 
+        // 按指定手机号筛选
+        if (pageReqVO.getOnlyPhone() != null && !pageReqVO.getOnlyPhone().isEmpty()) {
+            filteredRespVOList = filteredRespVOList.stream()
+                    .filter(respVO -> {
+                        if (respVO.getOnlyPhone() == null) {
+                            return false;
+                        }
+                        return respVO.getOnlyPhone().contains(pageReqVO.getOnlyPhone());
+                    })
+                    .collect(Collectors.toList());
+        }
+
         // 4. 对筛选后的结果进行分页
         int pageNo = pageReqVO.getPageNo();
         int pageSize = pageReqVO.getPageSize();

+ 15 - 4
byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/login/WebLoginServiceImpl.java

@@ -32,8 +32,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.USER_CODE_FAILURE;
-import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.USER_CODE_USED;
+import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.*;
 
 @Service
 public class WebLoginServiceImpl {
@@ -59,9 +58,22 @@ public class WebLoginServiceImpl {
         if (inviteCode == null) {
             throw exception(USER_CODE_FAILURE);
         }
-        if(!"0".equals(inviteCode.getStatus())){
+        if("1".equals(inviteCode.getStatus())){
             throw exception(USER_CODE_USED);
         }
+        // 校验邀请码是否指定手机号
+        if (inviteCode.getOnlyPhone() != null && !inviteCode.getOnlyPhone().isEmpty()) {
+            if (!inviteCode.getOnlyPhone().equals(registerVO.getUsername())) {
+                throw exception(USER_CODE_ONLY_PHONE_ERROR);
+            }
+        }
+        // 校验邀请码是否过期
+        if (inviteCode.getExpireTime() != null && inviteCode.getExpireTime().isBefore(LocalDateTime.now())) {
+            if (!"3".equals(inviteCode.getStatus())){
+                inviteCodeService.updateInviteCode(new InviteCodeSaveReqVO().setId(inviteCode.getId()).setStatus("3"));
+            }
+            throw exception(USER_CODE_EXPIRED);
+        }
 
         // 注册
         AuthRegisterReqVO registerReqVo = new AuthRegisterReqVO();
@@ -82,7 +94,6 @@ public class WebLoginServiceImpl {
                         .setUseUserId(userId)
                         .setUseUserTenantId(user.getTenantId())
                         .setUseTime(LocalDateTime.now())
-                        .setExpireTime(LocalDateTime.now().plusDays(inviteCode.getValidTime()))
                         .setStatus("1"));