refactor(service): 重构用户注册逻辑并新增注销校验

This commit is contained in:
2026-04-09 15:23:18 +08:00
parent 52727dfd7c
commit 20f8d9c152
3 changed files with 42 additions and 0 deletions

View File

@@ -85,6 +85,7 @@ public enum ErrorCode {
REPORT_TYPE_INVALID(40020, "举报类型无效"),
REPORT_COMPANION_ID_EMPTY(40021, "被举报的AI角色ID不能为空"),
REPORT_TYPE_EMPTY(40022, "举报类型不能为空"),
ACCOUNT_RECENTLY_CANCELLED(50038, "账号注销未满7天暂不允许注册"),
VERSION_NOT_FOUND(40022, "未找到可用的版本配置");
/**

View File

@@ -27,6 +27,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import com.yolo.keyborad.service.impl.user.UserInviteCodeBinder;
import com.yolo.keyborad.service.impl.user.UserMailVerificationHandler;
@@ -90,8 +92,26 @@ public class UserServiceImpl extends ServiceImpl<KeyboardUserMapper, KeyboardUse
.eq(KeyboardUser::getStatus, false));
}
private static final int ACCOUNT_REUSE_COOLDOWN_DAYS = 7;
private void ensureSubjectIdNotRecentlyCancelled(String sub) {
Date cooldownStart = Date.from(Instant.now().minus(ACCOUNT_REUSE_COOLDOWN_DAYS, ChronoUnit.DAYS));
KeyboardUser recentlyDeleted = keyboardUserMapper.selectOne(
new LambdaQueryWrapper<KeyboardUser>()
.eq(KeyboardUser::getSubjectId, sub)
.eq(KeyboardUser::getDeleted, true)
.gt(KeyboardUser::getDeletedAt, cooldownStart)
.last("LIMIT 1")
);
if (recentlyDeleted != null) {
throw new BusinessException(ErrorCode.ACCOUNT_RECENTLY_CANCELLED);
}
}
@Override
public KeyboardUser createUserWithSubjectId(String sub) {
ensureSubjectIdNotRecentlyCancelled(sub);
KeyboardUser keyboardUser = buildNewUserWithSubjectId(sub);
keyboardUserMapper.insert(keyboardUser);
keyboardCharacterService.addDefaultUserCharacter(keyboardUser.getId());

View File

@@ -18,6 +18,8 @@ import com.yolo.keyborad.service.KeyboardUserQuotaTotalService;
import com.yolo.keyborad.service.KeyboardUserWalletService;
import com.yolo.keyborad.utils.RedisUtil;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -33,6 +35,7 @@ import org.springframework.transaction.annotation.Transactional;
public class UserRegistrationHandler {
private static final String USER_CODE_PREFIX = "user:";
private static final int ACCOUNT_REUSE_COOLDOWN_DAYS = 7;
private final KeyboardUserMapper keyboardUserMapper;
private final PasswordEncoder passwordEncoder;
@@ -91,6 +94,24 @@ public class UserRegistrationHandler {
if (userMail != null) {
throw new BusinessException(ErrorCode.USER_HAS_EXISTED);
}
ensureNotRecentlyCancelled(
new LambdaQueryWrapper<KeyboardUser>()
.eq(KeyboardUser::getEmail, mailAddress)
);
}
private void ensureNotRecentlyCancelled(LambdaQueryWrapper<KeyboardUser> baseQuery) {
Date cooldownStart = Date.from(Instant.now().minus(ACCOUNT_REUSE_COOLDOWN_DAYS, ChronoUnit.DAYS));
KeyboardUser recentlyDeleted = keyboardUserMapper.selectOne(
baseQuery
.eq(KeyboardUser::getDeleted, true)
.gt(KeyboardUser::getDeletedAt, cooldownStart)
.last("LIMIT 1")
);
if (recentlyDeleted != null) {
throw new BusinessException(ErrorCode.ACCOUNT_RECENTLY_CANCELLED);
}
}
private void validatePasswords(UserRegisterDTO userRegisterDTO) {