diff --git a/.gitignore b/.gitignore index 5275376..3a33dd1 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ bin/ ### IntelliJ IDEA ### .idea +.idea/ *.iws *.iml *.ipr diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 98cd9e7..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -backend \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 1bcd671..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index 19dd4a8..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - mysql.8 - true - com.mysql.cj.jdbc.Driver - jdbc:mysql://persi-public.czy08w68qx69.ap-northeast-2.rds.amazonaws.com:3306/wish_persi - - - - - - - $ProjectFileDir$ - - - mysql.8 - true - com.mysql.cj.jdbc.Driver - jdbc:mysql://persi-public.czy08w68qx69.ap-northeast-2.rds.amazonaws.com:3306/luckyvicky_dev - - - - - - - $ProjectFileDir$ - - - mysql.8 - true - com.mysql.cj.jdbc.Driver - jdbc:mysql://persi-public.czy08w68qx69.ap-northeast-2.rds.amazonaws.com:3306/luckyvicky_ldh - - - - - - - $ProjectFileDir$ - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index a0b2cd2..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index fdc392f..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 4dfdffa..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index c0788f1..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/build.gradle b/build.gradle index eb7a98d..5dad337 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,9 @@ dependencies { // coolsms sdk implementation 'net.nurigo:sdk:4.2.0' + // nano id + implementation 'com.aventrix.jnanoid:jnanoid:2.0.0' + // database runtimeOnly 'com.mysql:mysql-connector-j' diff --git a/src/main/java/LuckyVicky/backend/global/entity/Uuid.java b/src/main/java/LuckyVicky/backend/global/entity/Uuid.java deleted file mode 100644 index 076e2cd..0000000 --- a/src/main/java/LuckyVicky/backend/global/entity/Uuid.java +++ /dev/null @@ -1,28 +0,0 @@ -package LuckyVicky.backend.global.entity; - -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import java.util.UUID; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Uuid extends BaseEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(unique = true) - private String uuid; - - private Uuid(String uuid) { - this.uuid = uuid; - } - - public static Uuid generateUuid() { - return new Uuid(UUID.randomUUID().toString()); - } -} \ No newline at end of file diff --git a/src/main/java/LuckyVicky/backend/global/repository/UuidRepository.java b/src/main/java/LuckyVicky/backend/global/repository/UuidRepository.java deleted file mode 100644 index cd9bee6..0000000 --- a/src/main/java/LuckyVicky/backend/global/repository/UuidRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package LuckyVicky.backend.global.repository; - -import LuckyVicky.backend.global.entity.Uuid; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UuidRepository extends JpaRepository { - -} diff --git a/src/main/java/LuckyVicky/backend/global/util/UuidGenerator.java b/src/main/java/LuckyVicky/backend/global/util/UuidGenerator.java new file mode 100644 index 0000000..4a1c7f4 --- /dev/null +++ b/src/main/java/LuckyVicky/backend/global/util/UuidGenerator.java @@ -0,0 +1,15 @@ +package LuckyVicky.backend.global.util; + +import com.aventrix.jnanoid.jnanoid.NanoIdUtils; +import java.util.UUID; + +public class UuidGenerator { + + public static String generateNanoUuid() { + return NanoIdUtils.randomNanoId(NanoIdUtils.DEFAULT_NUMBER_GENERATOR, NanoIdUtils.DEFAULT_ALPHABET, 12); + } + + public static String generateUuid() { + return UUID.randomUUID().toString().replace("-", ""); + } +} \ No newline at end of file diff --git a/src/main/java/LuckyVicky/backend/pachinko/handler/PachinkoWebSocketHandler.java b/src/main/java/LuckyVicky/backend/pachinko/handler/PachinkoWebSocketHandler.java index 6443d24..35945d6 100644 --- a/src/main/java/LuckyVicky/backend/pachinko/handler/PachinkoWebSocketHandler.java +++ b/src/main/java/LuckyVicky/backend/pachinko/handler/PachinkoWebSocketHandler.java @@ -89,15 +89,14 @@ public void afterConnectionClosed(WebSocketSession session, CloseStatus status) sessions.remove(session); } - private void processSquareSelection(WebSocketSession session, User user, long currentRound, int selectedSquare) - throws IOException { + private void processSquareSelection(WebSocketSession session, User user, long currentRound, int selectedSquare) { System.out.println(pachinkoService.viewSelectedSquares() + "핸들러에서 processSquareSelection 시작지점"); String result = pachinkoService.selectSquare(user, currentRound, selectedSquare); System.out.println(pachinkoService.viewSelectedSquares() + "핸들러에서 processSquareSelection 시작지점"); if (Objects.equals(result, "정상적으로 선택 완료되었습니다.")) { - broadcastMessage(user.getUsername() + "가 " + selectedSquare + "을 선택했습니다."); + broadcastMessage(user.getNickname() + "가 " + selectedSquare + "을 선택했습니다."); checkGameStatusAndCloseSessionsIfNeeded(); } else if (Objects.equals(result, "다른 사용자가 이전에 선택한 칸입니다.")) { sendMessage(session, selectedSquare + "번째 칸은 이미 다른 사용자에 의해 선택되었습니다."); diff --git a/src/main/java/LuckyVicky/backend/user/converter/UserConverter.java b/src/main/java/LuckyVicky/backend/user/converter/UserConverter.java index 13f489d..f08574a 100644 --- a/src/main/java/LuckyVicky/backend/user/converter/UserConverter.java +++ b/src/main/java/LuckyVicky/backend/user/converter/UserConverter.java @@ -1,6 +1,5 @@ package LuckyVicky.backend.user.converter; -import LuckyVicky.backend.global.entity.Uuid; import LuckyVicky.backend.global.fcm.domain.UserDeviceToken; import LuckyVicky.backend.user.domain.User; import LuckyVicky.backend.user.dto.JwtDto; @@ -12,7 +11,7 @@ @NoArgsConstructor public class UserConverter { - public static User saveUser(UserRequestDto.UserReqDto userReqDto, String nick) { + public static User saveUser(UserRequestDto.UserReqDto userReqDto, String nick, String code) { LocalDateTime today = LocalDateTime.now(); DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd"); @@ -25,7 +24,7 @@ public static User saveUser(UserRequestDto.UserReqDto userReqDto, String nick) { .provider(userReqDto.getProvider()) .signInDate(todayDate) .lastAttendanceCheckedDay(0) - .inviteCode(Uuid.generateUuid().getUuid()) + .inviteCode(code) .previousPachinkoRound(-1L) .rouletteAvailableTime(today) .advertiseTodayLeftNum(10) diff --git a/src/main/java/LuckyVicky/backend/user/service/UserService.java b/src/main/java/LuckyVicky/backend/user/service/UserService.java index 0286097..89b0776 100644 --- a/src/main/java/LuckyVicky/backend/user/service/UserService.java +++ b/src/main/java/LuckyVicky/backend/user/service/UserService.java @@ -6,25 +6,24 @@ import LuckyVicky.backend.aes.service.AesEncryptService; import LuckyVicky.backend.enhance.domain.JewelType; import LuckyVicky.backend.global.api_payload.ErrorCode; -import LuckyVicky.backend.global.entity.Uuid; import LuckyVicky.backend.global.exception.GeneralException; import LuckyVicky.backend.global.fcm.domain.UserDeviceToken; import LuckyVicky.backend.global.fcm.repository.UserDeviceTokenRepository; -import LuckyVicky.backend.global.repository.UuidRepository; import LuckyVicky.backend.global.s3.AmazonS3Manager; +import LuckyVicky.backend.global.util.UuidGenerator; import LuckyVicky.backend.user.converter.UserConverter; import LuckyVicky.backend.user.domain.RefreshToken; import LuckyVicky.backend.user.domain.User; import LuckyVicky.backend.user.domain.UserJewel; import LuckyVicky.backend.user.dto.JwtDto; import LuckyVicky.backend.user.dto.UserRequestDto; -import LuckyVicky.backend.user.dto.UserRequestDto.UserReqDto; import LuckyVicky.backend.user.jwt.JwtTokenUtils; import LuckyVicky.backend.user.repository.RefreshTokenRepository; import LuckyVicky.backend.user.repository.UserJewelRepository; import LuckyVicky.backend.user.repository.UserRepository; import jakarta.servlet.http.HttpServletRequest; import jakarta.transaction.Transactional; +import jakarta.validation.ConstraintViolationException; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -54,7 +53,6 @@ public class UserService { private final JpaUserDetailsManager manager; private final JwtTokenUtils jwtTokenUtils; private final AmazonS3Manager amazonS3Manager; - private final UuidRepository uuidRepository; private final UserJewelRepository userJewelRepository; private final AesEncryptService aesEncryptService; @@ -86,13 +84,28 @@ public Boolean checkMemberByEmail(String email) { @Transactional public User createUser(UserRequestDto.UserReqDto userReqDto) { - Uuid uuid = Uuid.generateUuid(); - String nick = "user" + uuid.getUuid(); - uuidRepository.save(uuid); - User newUser = userRepository.save(UserConverter.saveUser(userReqDto, nick)); + int retryCount = 3; // 최대 재시도 횟수 + User newUser = null; + + for (int i = 0; i < retryCount; i++) { + try { + String nick = "user" + UuidGenerator.generateNanoUuid(); + String code = UuidGenerator.generateUuid(); + newUser = UserConverter.saveUser(userReqDto, nick, code); + + userRepository.save(newUser); // 저장 시도 + break; + } catch (ConstraintViolationException e) { + log.warn("UUID 충돌 발생, 재시도 ({}/{})", i + 1, retryCount); + } + } + if (newUser == null) { + log.error("최대 재시도 횟수를 초과하여 UUID를 생성하지 못했습니다."); + throw new RuntimeException("최대 재시도 횟수를 초과하여 UUID를 생성하지 못했습니다."); + } + + manager.loadUserByUsername(userReqDto.getUsername()); // 저장된 사용자 정보를 다시 로드하여 동기화 시도 - // 새로운 사용자 정보를 반환하기 전에 저장된 UserDetails를 다시 로드하여 동기화 시도 - manager.loadUserByUsername(userReqDto.getUsername()); return newUser; }