From 20f8d9c152b65417bcecd8f5d70dd2c0f7d5efb1 Mon Sep 17 00:00:00 2001 From: ziin Date: Thu, 9 Apr 2026 15:23:18 +0800 Subject: [PATCH] =?UTF-8?q?refactor(service):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=B3=A8=E5=86=8C=E9=80=BB=E8=BE=91=E5=B9=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B3=A8=E9=94=80=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yolo/keyborad/common/ErrorCode.java | 1 + .../service/impl/UserServiceImpl.java | 20 ++++++++++++++++++ .../impl/user/UserRegistrationHandler.java | 21 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/main/java/com/yolo/keyborad/common/ErrorCode.java b/src/main/java/com/yolo/keyborad/common/ErrorCode.java index d7edd52..f5812f8 100644 --- a/src/main/java/com/yolo/keyborad/common/ErrorCode.java +++ b/src/main/java/com/yolo/keyborad/common/ErrorCode.java @@ -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, "未找到可用的版本配置"); /** diff --git a/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java index 0d161cb..0d921db 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java @@ -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() + .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()); diff --git a/src/main/java/com/yolo/keyborad/service/impl/user/UserRegistrationHandler.java b/src/main/java/com/yolo/keyborad/service/impl/user/UserRegistrationHandler.java index 7b07efb..21c146e 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/user/UserRegistrationHandler.java +++ b/src/main/java/com/yolo/keyborad/service/impl/user/UserRegistrationHandler.java @@ -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() + .eq(KeyboardUser::getEmail, mailAddress) + ); + } + + private void ensureNotRecentlyCancelled(LambdaQueryWrapper 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) {