From 838ab36889f5fda5f8eedd890ca84ee2de8a7fd8 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Fri, 9 Aug 2024 11:13:07 +0900 Subject: [PATCH 01/45] =?UTF-8?q?fix:=20GeneratedValue=20strategy=20Identi?= =?UTF-8?q?ty=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java b/Server/src/main/java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java index 0545a31d..ce4e9fb8 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java @@ -1,13 +1,15 @@ package JGS.CasperEvent.domain.url.entity; import JGS.CasperEvent.global.entity.BaseEntity; +import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +@Entity public class OriginalUrl extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.UUID) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String originalUrl; From 0396f2562c1a029e4ff1fa4ecefe03e5a7e65f0b Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Fri, 9 Aug 2024 11:13:21 +0900 Subject: [PATCH 02/45] =?UTF-8?q?chore:=20ShortenUrlResponseDto=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java new file mode 100644 index 00000000..df441221 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java @@ -0,0 +1,4 @@ +package JGS.CasperEvent.domain.url.dto; + +public record ShortenUrlResponseDto(String shortenUrl) { +} From 52cfd8c51bbabaeca0045a483151334a09475012 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Fri, 9 Aug 2024 11:13:34 +0900 Subject: [PATCH 03/45] =?UTF-8?q?chore:=20UrlRepository=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CasperEvent/domain/url/repository/UrlRepository.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java b/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java index 202cfb59..9052e753 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java @@ -1,4 +1,9 @@ package JGS.CasperEvent.domain.url.repository; -public interface UrlRepository { +import JGS.CasperEvent.domain.url.entity.OriginalUrl; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UrlRepository extends JpaRepository { } From 9a8cd33c6987e63b0a2379c4675cdf866435e47c Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Fri, 9 Aug 2024 11:14:18 +0900 Subject: [PATCH 04/45] =?UTF-8?q?chore:=20UrlController=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/url/controller/UrlController.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java b/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java index cc8a266c..b2999c0f 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java @@ -1,4 +1,31 @@ package JGS.CasperEvent.domain.url.controller; +import JGS.CasperEvent.domain.url.dto.ShortenUrlResponseDto; +import JGS.CasperEvent.domain.url.service.UrlService; +import JGS.CasperEvent.global.entity.BaseUser; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("link") public class UrlController { + + private final UrlService urlService; + + @Autowired + public UrlController(UrlService urlService) { + this.urlService = urlService; + } + + @PostMapping + public ResponseEntity generateShortUrl(HttpServletRequest request) { + BaseUser user = (BaseUser) request.getAttribute("user"); + return ResponseEntity.status(HttpStatus.CREATED) + .body(urlService.generateShortUrl(user)); + } } From b63919ee31dcdcf8c9e72c51bc9d748726526187 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Fri, 9 Aug 2024 11:14:34 +0900 Subject: [PATCH 05/45] =?UTF-8?q?chore:=20UrlService=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/url/service/UrlService.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java index df6b852f..15c1d272 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java @@ -1,4 +1,26 @@ package JGS.CasperEvent.domain.url.service; +import JGS.CasperEvent.domain.url.dto.ShortenUrlResponseDto; +import JGS.CasperEvent.domain.url.repository.UrlRepository; +import JGS.CasperEvent.global.entity.BaseUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service public class UrlService { + + private final UrlRepository urlRepository; + + @Autowired + public UrlService(UrlRepository urlRepository) { + this.urlRepository = urlRepository; + } + + public ShortenUrlResponseDto generateShortUrl(BaseUser user){ + String id = user.getId(); + + System.out.println("id = " + id); + + return new ShortenUrlResponseDto("shortenLink"); + } } From f81d267dac3c6644776312c7cee3884ab308da08 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Fri, 9 Aug 2024 11:15:56 +0900 Subject: [PATCH 06/45] =?UTF-8?q?chore:=20=EC=95=94=EB=B3=B5=ED=98=B8?= =?UTF-8?q?=ED=99=94=EC=9A=A9=20AESUtils=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/JGS/CasperEvent/global/util/AESUtils.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java diff --git a/Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java b/Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java new file mode 100644 index 00000000..19dbe358 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java @@ -0,0 +1,4 @@ +package JGS.CasperEvent.global.util; + +public class AESUtils { +} From d795e1cdcdb2533e31914b7fe05ae88aa9ce9ba4 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:06:36 +0900 Subject: [PATCH 07/45] =?UTF-8?q?chore:=20URL=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/url/entity/{OriginalUrl.java => Url.java} | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) rename Server/src/main/java/JGS/CasperEvent/domain/url/entity/{OriginalUrl.java => Url.java} (67%) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java b/Server/src/main/java/JGS/CasperEvent/domain/url/entity/Url.java similarity index 67% rename from Server/src/main/java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java rename to Server/src/main/java/JGS/CasperEvent/domain/url/entity/Url.java index ce4e9fb8..59b5514c 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/entity/OriginalUrl.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/entity/Url.java @@ -5,12 +5,22 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import lombok.Getter; @Entity -public class OriginalUrl extends BaseEntity { +@Getter +public class Url extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String originalUrl; + + public Url(String originalUrl){ + this.originalUrl = originalUrl; + } + + public Url() { + + } } From b47093e46b38d23a0784e390eb1816ed0cd00c4a Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:07:30 +0900 Subject: [PATCH 08/45] =?UTF-8?q?chore:=20=EC=95=94=EB=B3=B5=ED=98=B8?= =?UTF-8?q?=ED=99=94=20=ED=82=A4=20=EC=99=B8=EB=B6=80=20=EC=A3=BC=EC=9E=85?= =?UTF-8?q?=20=EC=9C=84=ED=95=9C=20SecurityConfig=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/SecurityConfig.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Server/src/main/java/JGS/CasperEvent/global/config/SecurityConfig.java diff --git a/Server/src/main/java/JGS/CasperEvent/global/config/SecurityConfig.java b/Server/src/main/java/JGS/CasperEvent/global/config/SecurityConfig.java new file mode 100644 index 00000000..90dbf9ad --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/global/config/SecurityConfig.java @@ -0,0 +1,20 @@ +package JGS.CasperEvent.global.config; + +import JGS.CasperEvent.global.util.AESUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.crypto.SecretKey; + +@Configuration +public class SecurityConfig { + + @Value("${spring.encryption.key}") + private String encryptionKey; + + @Bean + public SecretKey secretKey() { + return AESUtils.stringToKey(encryptionKey); + } +} From 545fedca08d26bae07e936e01f5b688a15a4e89f Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:08:04 +0900 Subject: [PATCH 09/45] =?UTF-8?q?feat:=20AES128=20=EC=95=94=EB=B3=B5?= =?UTF-8?q?=ED=98=B8=ED=99=94=20=EC=9C=84=ED=95=9C=20AESUtils=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JGS/CasperEvent/global/util/AESUtils.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java b/Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java index 19dbe358..1fc26b96 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java +++ b/Server/src/main/java/JGS/CasperEvent/global/util/AESUtils.java @@ -1,4 +1,31 @@ package JGS.CasperEvent.global.util; +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; + public class AESUtils { + + public static SecretKey stringToKey(String keyString) { + byte[] decodedKey = keyString.getBytes(); + return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES"); + } + + public static String encrypt(String plainText, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + byte[] encryptedBytes = cipher.doFinal(plainText.getBytes()); + return Base64.getEncoder().encodeToString(encryptedBytes); + } + + public static String decrypt(String encryptedText, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, key); + byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText)); + return new String(decryptedBytes); + } + + } From e319f3269a6cb704200e5ff32d891f3464964aff Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:08:27 +0900 Subject: [PATCH 10/45] =?UTF-8?q?chore:=20GlobalExceptionHandler=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=95=B8=EB=93=A4=EB=A7=81=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JGS/CasperEvent/global/error/GlobalExceptionHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/global/error/GlobalExceptionHandler.java b/Server/src/main/java/JGS/CasperEvent/global/error/GlobalExceptionHandler.java index 692154a2..de569e89 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/error/GlobalExceptionHandler.java +++ b/Server/src/main/java/JGS/CasperEvent/global/error/GlobalExceptionHandler.java @@ -19,8 +19,8 @@ public class GlobalExceptionHandler { @ExceptionHandler(CustomException.class) public ResponseEntity handler(CustomException e){ return ResponseEntity - .status(HttpStatus.BAD_REQUEST) - .body(ErrorResponse.of(CustomErrorCode.BAD_REQUEST, e.getMessage())); + .status(HttpStatus.valueOf(e.getErrorCode().getStatus())) + .body(ErrorResponse.of(e.getErrorCode(), e.getMessage())); } @ExceptionHandler(MissingRequestCookieException.class) From 3949cf5599735a8ee5c23289913840592fd660ed Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:08:57 +0900 Subject: [PATCH 11/45] =?UTF-8?q?test:=20=EB=8B=A8=EC=B6=95=20URL=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20API=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/entity/participants/LotteryParticipants.java | 2 +- .../CasperEvent/domain/url/controller/UrlController.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/LotteryParticipants.java b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/LotteryParticipants.java index 387084a1..39037862 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/LotteryParticipants.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/LotteryParticipants.java @@ -12,7 +12,7 @@ public class LotteryParticipants { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @OneToOne + @OneToOne // mappedBy 이용하면 둘 다 저장 안해도 됨 @JoinColumn(name = "base_user_id") //todo: 왜이런지 알아보기 @JsonBackReference diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java b/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java index b2999c0f..751e3895 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java @@ -11,6 +11,12 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + @RestController @RequestMapping("link") public class UrlController { @@ -23,7 +29,7 @@ public UrlController(UrlService urlService) { } @PostMapping - public ResponseEntity generateShortUrl(HttpServletRequest request) { + public ResponseEntity generateShortUrl(HttpServletRequest request) throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { BaseUser user = (BaseUser) request.getAttribute("user"); return ResponseEntity.status(HttpStatus.CREATED) .body(urlService.generateShortUrl(user)); From 4e224446bcb751e70f95d99308706806332a1416 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:09:21 +0900 Subject: [PATCH 12/45] =?UTF-8?q?test:=20BASE62=20=EC=9D=B8=EC=BD=94?= =?UTF-8?q?=EB=94=A9,=20=EB=94=94=EC=BD=94=EB=94=A9=20=EC=9C=84=ED=95=9C?= =?UTF-8?q?=20Base62Utils=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CasperEvent/global/util/Base62Utils.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Server/src/main/java/JGS/CasperEvent/global/util/Base62Utils.java diff --git a/Server/src/main/java/JGS/CasperEvent/global/util/Base62Utils.java b/Server/src/main/java/JGS/CasperEvent/global/util/Base62Utils.java new file mode 100644 index 00000000..bd63e1d3 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/global/util/Base62Utils.java @@ -0,0 +1,25 @@ +package JGS.CasperEvent.global.util; + +public class Base62Utils { + private static final String BASE62_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + public static String encode(long number) { + if (number == 0) return Character.toString(BASE62_CHARS.charAt(0)); + + StringBuilder sb = new StringBuilder(); + while (number > 0) { + int reminder = (int) (number % 62); + sb.append(BASE62_CHARS.charAt(reminder)); + number /= 62; + } + return sb.reverse().toString(); + } + + public static long decode(String str){ + long result = 0; + for (int i = 0; i < str.length(); i++) { + result = result * 62 + BASE62_CHARS.indexOf(str.charAt(i)); + } + return result; + } +} From 0bcdfb5a9551186b73707856e9c497d0e9ffe133 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:09:51 +0900 Subject: [PATCH 13/45] =?UTF-8?q?test:=20=EB=8B=A8=EC=B6=95=20URL=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/url/repository/UrlRepository.java | 7 ++-- .../domain/url/service/UrlService.java | 36 ++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java b/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java index 9052e753..f7d8649b 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/repository/UrlRepository.java @@ -1,9 +1,12 @@ package JGS.CasperEvent.domain.url.repository; -import JGS.CasperEvent.domain.url.entity.OriginalUrl; +import JGS.CasperEvent.domain.url.entity.Url; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository -public interface UrlRepository extends JpaRepository { +public interface UrlRepository extends JpaRepository { + Optional findByOriginalUrl(String originalUrl); } diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java index 15c1d272..4cb5ba2a 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java @@ -1,26 +1,52 @@ package JGS.CasperEvent.domain.url.service; import JGS.CasperEvent.domain.url.dto.ShortenUrlResponseDto; +import JGS.CasperEvent.domain.url.entity.Url; import JGS.CasperEvent.domain.url.repository.UrlRepository; import JGS.CasperEvent.global.entity.BaseUser; +import JGS.CasperEvent.global.util.AESUtils; +import JGS.CasperEvent.global.util.Base62Utils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + @Service public class UrlService { + @Value("${client.url}") + private String clientUrl; + + @Value("${shortenUrlService.url}") + private String shortenBaseUrl; + private final UrlRepository urlRepository; + private final SecretKey secretKey; @Autowired - public UrlService(UrlRepository urlRepository) { + public UrlService(UrlRepository urlRepository, SecretKey secretKey) { this.urlRepository = urlRepository; + this.secretKey = secretKey; } - public ShortenUrlResponseDto generateShortUrl(BaseUser user){ - String id = user.getId(); + public ShortenUrlResponseDto generateShortUrl(BaseUser user) throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + String encryptedUserId = AESUtils.encrypt(user.getId(), secretKey); + String originalUrl = clientUrl + "?" + "referralId=" + encryptedUserId; - System.out.println("id = " + id); + Url url = urlRepository.findByOriginalUrl(originalUrl).orElseGet( + () -> urlRepository.save(new Url(originalUrl)) + ); - return new ShortenUrlResponseDto("shortenLink"); + Long urlId = url.getId(); + String shortenUrl = shortenBaseUrl + "/link/" + Base62Utils.encode(urlId); + + return new ShortenUrlResponseDto(shortenUrl); } + } From 14ecc6c5dfe9d460920d3d3688230fef6d0de641 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:13:24 +0900 Subject: [PATCH 14/45] =?UTF-8?q?chore:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B0=8F=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JGS/CasperEvent/global/util/GsonUtil.java | 80 ------------------- .../JGS/CasperEvent/global/util/UserUtil.java | 11 --- 2 files changed, 91 deletions(-) delete mode 100644 Server/src/main/java/JGS/CasperEvent/global/util/GsonUtil.java diff --git a/Server/src/main/java/JGS/CasperEvent/global/util/GsonUtil.java b/Server/src/main/java/JGS/CasperEvent/global/util/GsonUtil.java deleted file mode 100644 index 7f6024f5..00000000 --- a/Server/src/main/java/JGS/CasperEvent/global/util/GsonUtil.java +++ /dev/null @@ -1,80 +0,0 @@ -package JGS.CasperEvent.global.util; - -import com.google.gson.*; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; - -import java.io.IOException; -import java.lang.reflect.Type; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; - -public class GsonUtil { - private static final String PATTERN_DATE = "yyyy-MM-dd"; - private static final String PATTERN_TIME = "HH:mm:ss"; - private static final String PATTERN_DATETIME = String.format("%s %s", PATTERN_DATE, PATTERN_TIME); - - static class LocalDataTimeAdapter extends TypeAdapter { - DateTimeFormatter format = DateTimeFormatter.ofPattern(PATTERN_DATETIME); - - @Override - public void write(JsonWriter out, LocalDateTime value) throws IOException { - if (value != null) out.value(value.format(format)); - } - - @Override - public LocalDateTime read(JsonReader in) throws IOException { - return LocalDateTime.parse(in.nextString(), format); - } - } - - static class LocalDateAdapter extends TypeAdapter { - DateTimeFormatter format = DateTimeFormatter.ofPattern(PATTERN_DATE); - - @Override - public void write(JsonWriter out, LocalDate value) throws IOException { - out.value(value.format(format)); - } - - @Override - public LocalDate read(JsonReader in) throws IOException { - return LocalDate.parse(in.nextString(), format); - } - } - - static class LocalTimeAdapter extends TypeAdapter { - DateTimeFormatter format = DateTimeFormatter.ofPattern(PATTERN_TIME); - - @Override - public void write(JsonWriter out, LocalTime value) throws IOException { - out.value(value.format(format)); - } - - @Override - public LocalTime read(JsonReader in) throws IOException { - return LocalTime.parse(in.nextString(), format); - } - } - - static class EnumSerializer implements JsonSerializer>{ - @Override - public JsonElement serialize(Enum src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(src.name()); - } - } - - private static final Gson gson = new GsonBuilder() - .disableHtmlEscaping() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .setDateFormat(PATTERN_DATETIME) - .registerTypeAdapter(LocalDateTime.class, new LocalDataTimeAdapter().nullSafe()) - .registerTypeAdapter(LocalDate.class, new LocalDateAdapter().nullSafe()) - .registerTypeAdapter(LocalTime.class, new LocalTimeAdapter().nullSafe()) - .create(); - - public static Gson getGson(){ - return gson; - } -} diff --git a/Server/src/main/java/JGS/CasperEvent/global/util/UserUtil.java b/Server/src/main/java/JGS/CasperEvent/global/util/UserUtil.java index 711708d1..a3ffb0cb 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/util/UserUtil.java +++ b/Server/src/main/java/JGS/CasperEvent/global/util/UserUtil.java @@ -5,17 +5,6 @@ public class UserUtil { //TODO: 스프링 서버 뻗으면 캐스퍼 아이디 0부터 다시 시작함 private static final AtomicLong counter = new AtomicLong(0); - - //TODO: 현재는 그냥 userData 즉시 반환, 키 이용한 복호화로 수정하기 - public static String getDecodedPhoneNumber(String userData) { - return userData; - } - - //TODO: 현재는 true 리턴, jwt로 변경 필요 - public static Boolean isValidAdminToken(String token){ - if (token.equals("adminToken")) return true; - return false; - } public static long generateId(){ return counter.incrementAndGet(); } From 58102198b645019e4dafa6e012ed84d2714592b6 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:28:49 +0900 Subject: [PATCH 15/45] =?UTF-8?q?chore:=20=EB=8B=A8=EC=B6=95=20url=20?= =?UTF-8?q?=EC=A3=BC=EC=86=8C=20=ED=99=94=EC=9D=B4=ED=8A=B8=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=97=90=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CasperEvent/global/jwt/filter/JwtAuthorizationFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/src/main/java/JGS/CasperEvent/global/jwt/filter/JwtAuthorizationFilter.java b/Server/src/main/java/JGS/CasperEvent/global/jwt/filter/JwtAuthorizationFilter.java index cb83d2d8..60c276ba 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/jwt/filter/JwtAuthorizationFilter.java +++ b/Server/src/main/java/JGS/CasperEvent/global/jwt/filter/JwtAuthorizationFilter.java @@ -32,7 +32,7 @@ public class JwtAuthorizationFilter implements Filter { "/event/rush", "/event/lottery/caspers", "/admin/join", "/admin/auth", "/h2", "/h2/*", "/swagger-ui/*", "/v3/api-docs", "/v3/api-docs/*", - "/event/lottery" + "/event/lottery", "/link/*" }; private final String[] blackListUris = new String[]{ "/event/rush/*", "/event/lottery/casperBot" From b3fc45b994cceed30a5e2c116b50be1ff7ff8af5 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:29:21 +0900 Subject: [PATCH 16/45] =?UTF-8?q?feat:=20=EB=8B=A8=EC=B6=95=20url=20?= =?UTF-8?q?=EC=A0=91=EC=86=8D=20api=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/url/controller/UrlController.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java b/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java index 751e3895..3503e936 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/controller/UrlController.java @@ -7,9 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; @@ -31,7 +29,16 @@ public UrlController(UrlService urlService) { @PostMapping public ResponseEntity generateShortUrl(HttpServletRequest request) throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { BaseUser user = (BaseUser) request.getAttribute("user"); - return ResponseEntity.status(HttpStatus.CREATED) + return ResponseEntity + .status(HttpStatus.CREATED) .body(urlService.generateShortUrl(user)); } + + @GetMapping("/{encodedId}") + public ResponseEntity redirectOriginalUrl(@PathVariable String encodedId){ + return ResponseEntity + .status(HttpStatus.FOUND) + .header("Location", urlService.getOriginalUrl(encodedId)) + .build(); + } } From c989ae3aed1d181912757fff718c75efa5e7ecc8 Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 02:29:32 +0900 Subject: [PATCH 17/45] =?UTF-8?q?feat:=20=EB=8B=A8=EC=B6=95=20url=20?= =?UTF-8?q?=EC=A0=91=EC=86=8D=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JGS/CasperEvent/domain/url/service/UrlService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java index 4cb5ba2a..3503fdef 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java @@ -16,6 +16,7 @@ import javax.crypto.SecretKey; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.util.NoSuchElementException; @Service public class UrlService { @@ -49,4 +50,10 @@ public ShortenUrlResponseDto generateShortUrl(BaseUser user) throws NoSuchPaddin return new ShortenUrlResponseDto(shortenUrl); } + public String getOriginalUrl(String encodedId){ + Long urlId = Base62Utils.decode(encodedId); + Url url = urlRepository.findById(urlId).orElseThrow(NoSuchElementException::new); + return url.getOriginalUrl(); + } + } From 2d5d4f0d159bac1b0547c46c735289ce43114eca Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 15:30:27 +0900 Subject: [PATCH 18/45] =?UTF-8?q?chore:=20=EB=B0=B0=ED=8F=AC=EC=9A=A9=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=B6=94=EA=B0=80=20-?= =?UTF-8?q?=20client.url=20->=20=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8?= =?UTF-8?q?=ED=8A=B8=20=EB=B0=B0=ED=8F=AC=20url=20-=20client.localUrl=20->?= =?UTF-8?q?=20=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=BB=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=9A=A9=20url=20-=20sh?= =?UTF-8?q?ortenUrlService.url=20->=20=EC=8A=A4=ED=94=84=EB=A7=81=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/src/main/resources/application-prod.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Server/src/main/resources/application-prod.yml b/Server/src/main/resources/application-prod.yml index 658d7e19..65bd582a 100644 --- a/Server/src/main/resources/application-prod.yml +++ b/Server/src/main/resources/application-prod.yml @@ -18,4 +18,12 @@ spring: data: redis: host: ${SPRING_REDIS_HOST} - port: ${SPRING_REDIS_PORT} \ No newline at end of file + port: ${SPRING_REDIS_PORT} + encryption: + key: ${AES_128_ENCRYPTION_KEY} + +client: + url: ${CLIENT_URL} + localUrl: ${LOCAL_CLIENT_URL} +shortenUrlService: + url: ${SPRING_SERVER_URL} \ No newline at end of file From 0457d85b726c399eae1dbeba50daeda141cf611d Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 15:30:52 +0900 Subject: [PATCH 19/45] =?UTF-8?q?chore:=20=ED=94=84=EB=A1=A0=ED=8A=B8?= =?UTF-8?q?=EC=97=94=EB=93=9C=20=EB=A1=9C=EC=BB=AC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=9A=A9=20shortenLocalUrl=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java index df441221..84f2ff92 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/dto/ShortenUrlResponseDto.java @@ -1,4 +1,4 @@ package JGS.CasperEvent.domain.url.dto; -public record ShortenUrlResponseDto(String shortenUrl) { +public record ShortenUrlResponseDto(String shortenUrl, String shortenLocalUrl) { } From 189fa19d30056acf3cffb56bdb64f6eaafde481f Mon Sep 17 00:00:00 2001 From: nnijgnus Date: Sat, 10 Aug 2024 15:41:05 +0900 Subject: [PATCH 20/45] =?UTF-8?q?chore:=20=ED=94=84=EB=A1=A0=ED=8A=B8?= =?UTF-8?q?=EC=97=94=EB=93=9C=20=EB=A1=9C=EC=BB=AC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=9A=A9=20shortenLocalUrl=EB=8F=84=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CasperEvent/domain/url/service/UrlService.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java index 3503fdef..dcb53cfa 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/url/service/UrlService.java @@ -23,10 +23,13 @@ public class UrlService { @Value("${client.url}") private String clientUrl; + @Value("${client.localUrl}") + private String localClientUrl; @Value("${shortenUrlService.url}") private String shortenBaseUrl; + private final UrlRepository urlRepository; private final SecretKey secretKey; @@ -36,18 +39,27 @@ public UrlService(UrlRepository urlRepository, SecretKey secretKey) { this.secretKey = secretKey; } + //todo: 테스트 끝나면 수정필요 public ShortenUrlResponseDto generateShortUrl(BaseUser user) throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { String encryptedUserId = AESUtils.encrypt(user.getId(), secretKey); + String originalUrl = clientUrl + "?" + "referralId=" + encryptedUserId; + String originalLocalUrl = localClientUrl + "?" + "referralId=" + encryptedUserId; Url url = urlRepository.findByOriginalUrl(originalUrl).orElseGet( () -> urlRepository.save(new Url(originalUrl)) ); + Url localUrl = urlRepository.findByOriginalUrl(originalLocalUrl).orElseGet( + () -> urlRepository.save(new Url(originalLocalUrl)) + ); Long urlId = url.getId(); + Long localUrlId = localUrl.getId(); + String shortenUrl = shortenBaseUrl + "/link/" + Base62Utils.encode(urlId); + String shortenLocalUrl = shortenBaseUrl + "/link/" + Base62Utils.encode(localUrlId); - return new ShortenUrlResponseDto(shortenUrl); + return new ShortenUrlResponseDto(shortenUrl, shortenLocalUrl); } public String getOriginalUrl(String encodedId){ From 9d94945c5bffd9737d1bc439f0f3af5753a1f26b Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:05:07 +0900 Subject: [PATCH 21/45] =?UTF-8?q?feat:=20LocalDateTime=20=EC=A7=81?= =?UTF-8?q?=EB=A0=AC=ED=99=94=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CasperEvent/global/entity/BaseEntity.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/global/entity/BaseEntity.java b/Server/src/main/java/JGS/CasperEvent/global/entity/BaseEntity.java index 1f65da20..6a41fb05 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/entity/BaseEntity.java +++ b/Server/src/main/java/JGS/CasperEvent/global/entity/BaseEntity.java @@ -1,8 +1,13 @@ package JGS.CasperEvent.global.entity; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import jakarta.persistence.Column; import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; +import lombok.Getter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -12,20 +17,16 @@ @EntityListeners(AuditingEntityListener.class) @MappedSuperclass +@Getter public class BaseEntity { - @CreatedDate + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) @Column(updatable = false) private LocalDateTime createdAt; @LastModifiedDate + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) private LocalDateTime updatedAt; - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } } From f89d14f52e3968c2f2a959f29c21940c9f6ad675 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:05:15 +0900 Subject: [PATCH 22/45] =?UTF-8?q?feat:=20LocalDateTime=20=EC=A7=81?= =?UTF-8?q?=EB=A0=AC=ED=99=94=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/entity/event/BaseEvent.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/BaseEvent.java b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/BaseEvent.java index c16fe270..491c8b9e 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/BaseEvent.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/BaseEvent.java @@ -1,23 +1,38 @@ package JGS.CasperEvent.domain.event.entity.event; import JGS.CasperEvent.global.entity.BaseEntity; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import jakarta.persistence.MappedSuperclass; +import lombok.Getter; -import java.time.LocalDate; +import java.time.LocalDateTime; +@Getter +@MappedSuperclass public class BaseEvent extends BaseEntity { - protected LocalDate eventStartDate; - protected LocalDate eventEndDate; - protected int winnerCount; + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + private LocalDateTime startDateTime; - public LocalDate getEventStartDate() { - return eventStartDate; - } + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + private LocalDateTime endDateTime; + private int winnerCount; - public LocalDate getEventEndDate() { - return eventEndDate; + // 기본 생성자에서 디폴트 값 설정 + public BaseEvent() { + this.startDateTime = LocalDateTime.now(); + this.endDateTime = LocalDateTime.now().plusMinutes(10); + this.winnerCount = 0; // 기본 우승자 수를 0으로 설정 } - public int getWinnerCount() { - return winnerCount; + // 특정 값을 설정할 수 있는 생성자 + public BaseEvent(LocalDateTime startDateTime, LocalDateTime endDateTime, int winnerCount) { + this.startDateTime = startDateTime; + this.endDateTime = endDateTime; + this.winnerCount = winnerCount; } } From 6b5f0f824b17622fb180e5019201cc273823ce88 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:05:48 +0900 Subject: [PATCH 23/45] =?UTF-8?q?feat:=20BaseUser=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EC=97=90=20RushParticipants=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/JGS/CasperEvent/global/entity/BaseUser.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Server/src/main/java/JGS/CasperEvent/global/entity/BaseUser.java b/Server/src/main/java/JGS/CasperEvent/global/entity/BaseUser.java index ee143b23..09f06708 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/entity/BaseUser.java +++ b/Server/src/main/java/JGS/CasperEvent/global/entity/BaseUser.java @@ -1,6 +1,7 @@ package JGS.CasperEvent.global.entity; import JGS.CasperEvent.domain.event.entity.participants.LotteryParticipants; +import JGS.CasperEvent.domain.event.entity.participants.RushParticipants; import JGS.CasperEvent.global.enums.Role; import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; @@ -18,6 +19,10 @@ public class BaseUser extends BaseEntity { @OneToOne(mappedBy = "baseUser", cascade = CascadeType.ALL) private LotteryParticipants lotteryParticipants; + @JsonManagedReference + @OneToOne(mappedBy = "baseUser", cascade = CascadeType.ALL) + private RushParticipants rushParticipants; + public void updateLotteryParticipants(LotteryParticipants lotteryParticipant) { this.lotteryParticipants = lotteryParticipant; } From 5b8f11067fb9338e9f60f4043494ec8de3187f25 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:06:05 +0900 Subject: [PATCH 24/45] =?UTF-8?q?feat:=20LocalDateTime=20=EC=A7=81?= =?UTF-8?q?=EB=A0=AC=ED=99=94=20=EC=84=A4=EC=A0=95=EC=9D=84=20=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/Server/build.gradle b/Server/build.gradle index 33e8c515..68f53cb8 100644 --- a/Server/build.gradle +++ b/Server/build.gradle @@ -46,6 +46,7 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5") annotationProcessor('org.projectlombok:lombok') + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3' } From 8eb923eb980f34b60854aa085f8a4873ff873f3a Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:06:19 +0900 Subject: [PATCH 25/45] =?UTF-8?q?feat:=20CursomErrorCode=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/JGS/CasperEvent/global/enums/CustomErrorCode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/global/enums/CustomErrorCode.java b/Server/src/main/java/JGS/CasperEvent/global/enums/CustomErrorCode.java index 035630f9..75378d38 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/enums/CustomErrorCode.java +++ b/Server/src/main/java/JGS/CasperEvent/global/enums/CustomErrorCode.java @@ -14,9 +14,9 @@ public enum CustomErrorCode { JWT_PARSE_EXCEPTION("Json 파싱 오류입니다.", 400), JWT_EXCEPTION("JWT 오류입니다.", 400), JWT_EXPIRED("만료된 토큰입니다.", 400), - JWT_MISSING("인증 토큰이 존재하지 않습니다.", 401); - - + JWT_MISSING("인증 토큰이 존재하지 않습니다.", 401), + MULTIPLE_RUSH_EVENTS_FOUND("해당 날짜에 여러 개의 이벤트가 존재합니다.", 409), + TODAY_RUSH_EVENT_NOT_FOUND("오늘의 이벤트를 찾을 수 없습니다.", 404); // 새로운 예외 추가 private final String message; private int status; From 463241c0ca1c5ce8761cc782f78a0fa0da75af73 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:07:07 +0900 Subject: [PATCH 26/45] =?UTF-8?q?fix:=20github=20action=20=ED=8A=B8?= =?UTF-8?q?=EB=A6=AC=EA=B1=B0=EB=A5=BC=20pull=5Frequest=20->=20push=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0aabad65..13b48476 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,7 +14,6 @@ env: jobs: build-and-deploy: runs-on: ubuntu-latest - steps: - name: Checkout code uses: actions/checkout@v2 From 7c3ba60d3116c9cae1095fb783774c21f46f115d Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:08:16 +0900 Subject: [PATCH 27/45] =?UTF-8?q?fix:=20LocalDate=20->=20LocalDateTime=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/dto/ResponseDto/LotteryEventResponseDto.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/LotteryEventResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/LotteryEventResponseDto.java index 6ca3df36..c15eed07 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/LotteryEventResponseDto.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/LotteryEventResponseDto.java @@ -6,14 +6,14 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; -public record LotteryEventResponseDto(LocalDateTime serverDateTime, LocalDate eventStartDate, LocalDate eventEndDate, +public record LotteryEventResponseDto(LocalDateTime serverDateTime, LocalDateTime eventStartDate, LocalDateTime eventEndDate, long activePeriod) { public static LotteryEventResponseDto of(LocalDateTime serverDateTime, LotteryEvent lotteryEvent) { return new LotteryEventResponseDto( serverDateTime, - lotteryEvent.getEventStartDate(), - lotteryEvent.getEventEndDate(), - ChronoUnit.DAYS.between(lotteryEvent.getEventStartDate(), lotteryEvent.getEventEndDate()) + lotteryEvent.getStartDateTime(), + lotteryEvent.getEndDateTime(), + ChronoUnit.DAYS.between(lotteryEvent.getStartDateTime(), lotteryEvent.getEndDateTime()) ); } From 2b3f4ef428ef374c8086b7427953ee7c498992f2 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:08:21 +0900 Subject: [PATCH 28/45] =?UTF-8?q?fix:=20LocalDate=20->=20LocalDateTime=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/service/eventService/LotteryEventService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/LotteryEventService.java b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/LotteryEventService.java index 5a94885e..3051249d 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/LotteryEventService.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/LotteryEventService.java @@ -90,8 +90,8 @@ public LotteryParticipants registerUserIfNeed(BaseUser user) { // TODO: 가짜 API, DB 접속되도록 수정 public LotteryEventResponseDto getLotteryEvent() { return new LotteryEventResponseDto(LocalDateTime.now(), - LocalDate.of(2000, 9, 27), - LocalDate.of(2100, 9, 27), + LocalDate.of(2000, 9, 27).atStartOfDay(), + LocalDate.of(2100, 9, 27).atStartOfDay(), ChronoUnit.DAYS.between(LocalDate.of(2000, 9, 27), LocalDate.of(2100, 9, 27))); } From 5c3c894a887093b90c350b0546415d3f12f8b22a Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:09:16 +0900 Subject: [PATCH 29/45] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=B3=B4=EC=97=AC=EC=A7=88=20Rus?= =?UTF-8?q?hEvent=EC=9D=98=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=8B=B4?= =?UTF-8?q?=EB=8A=94=20DTO=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResponseDto/MainRushEventResponseDto.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/MainRushEventResponseDto.java diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/MainRushEventResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/MainRushEventResponseDto.java new file mode 100644 index 00000000..cfd61949 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/MainRushEventResponseDto.java @@ -0,0 +1,27 @@ +package JGS.CasperEvent.domain.event.dto.ResponseDto; + +import JGS.CasperEvent.domain.event.entity.event.RushEvent; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +public class MainRushEventResponseDto { + private Long rushEventId; + private LocalDateTime startDateTime; + private LocalDateTime endDateTime; + + public MainRushEventResponseDto(Long rushEventId, LocalDateTime startDateTime, LocalDateTime endDateTime) { + this.rushEventId = rushEventId; + this.startDateTime = startDateTime; + this.endDateTime = endDateTime; + } + + public static MainRushEventResponseDto of (RushEvent rushEvent) { + return new MainRushEventResponseDto( + rushEvent.getRushEventId(), + rushEvent.getStartDateTime(), + rushEvent.getEndDateTime() + ); + } +} From 1dfaf0fe80d24162e55da9e8f29f9456116837fd Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:09:47 +0900 Subject: [PATCH 30/45] =?UTF-8?q?feat:=20Redis=EC=97=90=20RushEvent?= =?UTF-8?q?=EB=A5=BC=20=EB=8B=B4=EA=B8=B0=20=EC=9C=84=ED=95=9C=20RushEvent?= =?UTF-8?q?RedisTemplate=EC=9D=84=20Bean=EC=9C=BC=EB=A1=9C=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JGS/CasperEvent/global/config/RedisConfig.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java b/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java index 355ac87a..f397261c 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java +++ b/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java @@ -1,6 +1,7 @@ package JGS.CasperEvent.global.config; import JGS.CasperEvent.domain.event.dto.ResponseDto.CasperBotResponseDto; +import JGS.CasperEvent.domain.event.entity.event.RushEvent; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; @@ -29,7 +30,7 @@ public RedisConnectionFactory redisConnectionFactory(){ } @Bean - public RedisTemplate redisTemplate(){ + public RedisTemplate CasperBotRedisTemplate(){ RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); @@ -37,4 +38,12 @@ public RedisTemplate redisTemplate(){ return redisTemplate; } + @Bean + public RedisTemplate RushEventRedisTemplate(){ + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory()); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + return redisTemplate; + } } From 262ea60299210f2d1db179bf533a2fedf503677a Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:10:35 +0900 Subject: [PATCH 31/45] =?UTF-8?q?fix:=20=EC=9C=A0=EB=8B=88=ED=81=AC=20?= =?UTF-8?q?=EC=A0=9C=EC=95=BD=EC=A1=B0=EA=B1=B4=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EB=A5=BC=20=ED=95=B4=EA=B2=B0=ED=95=98=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20RushEvent=EA=B0=80=20=EA=B0=81=EA=B0=81=20?= =?UTF-8?q?=EB=91=90=EA=B0=9C=EC=9D=98=20=EC=98=B5=EC=85=98=EC=9D=84=20?= =?UTF-8?q?=EA=B0=96=EB=8A=94=20=EA=B2=83=EC=9D=B4=20=EC=95=84=EB=8B=8C,?= =?UTF-8?q?=20Set=20=ED=98=95=ED=83=9C=EB=A1=9C=20option?= =?UTF-8?q?=EC=9D=84=20=EA=B0=96=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/entity/event/RushEvent.java | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushEvent.java b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushEvent.java index 38767fbb..07ba336b 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushEvent.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushEvent.java @@ -2,10 +2,13 @@ import JGS.CasperEvent.domain.event.entity.participants.RushParticipants; import jakarta.persistence.*; +import lombok.Getter; +import java.time.LocalDateTime; import java.util.Set; @Entity +@Getter public class RushEvent extends BaseEvent { private String prizeImageUrl; private String prizeDescription; @@ -14,13 +17,9 @@ public class RushEvent extends BaseEvent { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long rushEventId; - @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "rush_event_id") - private RushOption leftOption; - - @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @JoinColumn(name = "rush_event_id") - private RushOption rightOption; + private Set options; @OneToMany(mappedBy = "rushEvent", cascade = CascadeType.ALL, orphanRemoval = true) private Set rushParticipants; @@ -28,29 +27,16 @@ public class RushEvent extends BaseEvent { public RushEvent() { } - // 파라미터가 있는 생성자 public RushEvent(String prizeImageUrl, String prizeDescription) { + super(); this.prizeImageUrl = prizeImageUrl; this.prizeDescription = prizeDescription; } - public String getPrizeImageUrl() { - return prizeImageUrl; - } - - public String getPrizeDescription() { - return prizeDescription; - } - public RushOption getLeftOption() { - return leftOption; - } - - public RushOption getRightOption() { - return rightOption; - } - - public Long getRushEventId() { - return rushEventId; + public RushEvent(LocalDateTime startDateTime, LocalDateTime endDateTime, int winnerCount, String prizeImageUrl, String prizeDescription) { + super(startDateTime, endDateTime, winnerCount); + this.prizeImageUrl = prizeImageUrl; + this.prizeDescription = prizeDescription; } } From e949dfbd12c5073ca4c4cf4ea6ee86ed65965643 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:10:55 +0900 Subject: [PATCH 32/45] =?UTF-8?q?feat:=20=EB=B0=B8=EB=9F=B0=EC=8A=A4=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EA=B2=B0=EA=B3=BC=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eventController/RushEventController.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java b/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java index 6b3fa926..a0b7790b 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java @@ -1,8 +1,9 @@ package JGS.CasperEvent.domain.event.controller.eventController; -import JGS.CasperEvent.domain.event.dto.ResponseDto.RushEventListAndServerTimeResponseDto; +import JGS.CasperEvent.domain.event.dto.ResponseDto.RushEventListResponseDto; import JGS.CasperEvent.domain.event.dto.ResponseDto.RushEventRateResponseDto; +import JGS.CasperEvent.domain.event.dto.ResponseDto.RushEventResultResponseDto; import JGS.CasperEvent.domain.event.service.eventService.RushEventService; import JGS.CasperEvent.global.entity.BaseUser; import jakarta.servlet.http.HttpServletRequest; @@ -20,7 +21,7 @@ public RushEventController(RushEventService rushEventService) { // 전체 선착순 이벤트 조회 @GetMapping - public ResponseEntity getRushEventListAndServerTime() { + public ResponseEntity getRushEventListAndServerTime() { return ResponseEntity.ok(rushEventService.getAllRushEvents()); } @@ -47,4 +48,19 @@ public ResponseEntity rushEventRate (@PathVariable("ev RushEventRateResponseDto rushEventRateResponseDto = rushEventService.getRushEventRate(eventId); return ResponseEntity.ok(rushEventRateResponseDto); } + + // 밸런스 게임 결과 조회 + @GetMapping("/{eventId}/result") + public ResponseEntity rushEventResult(HttpServletRequest httpServletRequest, @PathVariable("eventId") Long eventId) { + BaseUser user = (BaseUser) httpServletRequest.getAttribute("user"); + RushEventResultResponseDto result = rushEventService.getRushEventResult(user, eventId); + return ResponseEntity.ok(result); + } + + // 레디스에 오늘의 이벤트 등록 테스트 api + @GetMapping("/today/test") + public ResponseEntity setTodayEvent() { + rushEventService.setTodayEventToRedis(); + return ResponseEntity.noContent().build(); + } } From 75a90bc40d3a1ef59ce1a167d9ff538cfc6225d8 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:12:04 +0900 Subject: [PATCH 33/45] =?UTF-8?q?fix:=20RushEvent=20=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=A1=B0=ED=9A=8C=20API=EC=9D=98=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EA=B0=80=20=EC=B6=94=EA=B0=80=EB=90=98?= =?UTF-8?q?=EC=96=B4=EC=84=9C=20=ED=95=B4=EB=8B=B9=20=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...RushEventListAndServerTimeResponseDto.java | 31 ------------------- .../ResponseDto/RushEventListResponseDto.java | 26 ++++++++++++++++ 2 files changed, 26 insertions(+), 31 deletions(-) delete mode 100644 Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListAndServerTimeResponseDto.java create mode 100644 Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListResponseDto.java diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListAndServerTimeResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListAndServerTimeResponseDto.java deleted file mode 100644 index cc17a58b..00000000 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListAndServerTimeResponseDto.java +++ /dev/null @@ -1,31 +0,0 @@ -package JGS.CasperEvent.domain.event.dto.ResponseDto; - -import java.time.LocalDateTime; -import java.util.List; - -public class RushEventListAndServerTimeResponseDto { - private List events; - private LocalDateTime serverTime; - - public RushEventListAndServerTimeResponseDto(List events, LocalDateTime serverTime) { - this.events = events; - this.serverTime = serverTime; - } - - // Getters and setters - public List getEvents() { - return events; - } - public void setEvents(List events) { - this.events = events; - } - - public LocalDateTime getServerTime() { - return serverTime; - } - - public void setServerTime(LocalDateTime serverTime) { - this.serverTime = serverTime; - } - -} diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListResponseDto.java new file mode 100644 index 00000000..abcac614 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventListResponseDto.java @@ -0,0 +1,26 @@ +package JGS.CasperEvent.domain.event.dto.ResponseDto; + +import lombok.Getter; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +@Getter +public class RushEventListResponseDto { + private List events; + private LocalDateTime serverTime; + private Long todayEventId; + private LocalDate eventStartDate; + private LocalDate eventEndDate; + private Long activePeriod; + + public RushEventListResponseDto(List events, LocalDateTime serverTime, Long todayEventId, LocalDate eventStartDate, LocalDate eventEndDate, Long activePeriod) { + this.events = events; + this.serverTime = serverTime; + this.todayEventId = todayEventId; + this.eventStartDate = eventStartDate; + this.eventEndDate = eventEndDate; + this.activePeriod = activePeriod; + } +} From 97efb30922cc50c8eaa9538ae8d19881070df387 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:12:49 +0900 Subject: [PATCH 34/45] =?UTF-8?q?fix:=20=EA=B8=B0=EC=A1=B4=20Dto=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20->=20record=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/dto/ResponseDto/RushEventRateResponseDto.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventRateResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventRateResponseDto.java index 87700f1e..a4b81c45 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventRateResponseDto.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventRateResponseDto.java @@ -3,12 +3,5 @@ import lombok.Getter; @Getter -public class RushEventRateResponseDto { - long leftOption; - long rightOption; - - public RushEventRateResponseDto(long leftOption, long rightOption) { - this.leftOption = leftOption; - this.rightOption = rightOption; - } +public record RushEventRateResponseDto(long leftOption, long rightOption) { } From aa2b29b73fa1038e63f7993e4c0d80505d94a0f8 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:13:48 +0900 Subject: [PATCH 35/45] =?UTF-8?q?feat:=20=EC=98=A4=EB=8A=98=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EB=A5=BC=20=EA=BA=BC?= =?UTF-8?q?=EB=82=B4=EC=98=A4=EB=8A=94=20=EC=BF=BC=EB=A6=AC=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/eventRepository/RushEventRepository.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushEventRepository.java b/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushEventRepository.java index 3ff0c837..1913977f 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushEventRepository.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushEventRepository.java @@ -2,8 +2,17 @@ import JGS.CasperEvent.domain.event.entity.event.RushEvent; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.time.LocalDate; +import java.util.List; + @Repository public interface RushEventRepository extends JpaRepository { + @Query("SELECT e FROM RushEvent e WHERE DATE(e.startDateTime) = :eventDate") + List findByEventDate(@Param("eventDate") LocalDate eventDate); + + RushEvent findByRushEventId(Long rushEventId); } From 5dc3e445af60ef43dc7aaa1f2be1c30b1961107d Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:14:10 +0900 Subject: [PATCH 36/45] =?UTF-8?q?fix:=20LocalDate=20->=20LocalDateTime=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/dto/ResponseDto/RushEventResponseDto.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResponseDto.java index f6c9558d..923f30d6 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResponseDto.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResponseDto.java @@ -4,21 +4,22 @@ import JGS.CasperEvent.domain.event.entity.event.RushOption; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Set; -public record RushEventResponseDto(Long rushEventId, LocalDate startDate, LocalDate endDate, +public record RushEventResponseDto(Long rushEventId, LocalDateTime startDateTime, LocalDateTime endDateTime, int winnerCount, String prizeImageUrl, String prizeDescription, - RushOption leftOption, RushOption rightOption){ + Set options){ public static RushEventResponseDto of (RushEvent rushEvent){ return new RushEventResponseDto( rushEvent.getRushEventId(), - rushEvent.getEventStartDate(), - rushEvent.getEventEndDate(), + rushEvent.getStartDateTime(), + rushEvent.getEndDateTime(), rushEvent.getWinnerCount(), rushEvent.getPrizeImageUrl(), rushEvent.getPrizeDescription(), - rushEvent.getLeftOption(), - rushEvent.getRightOption() + rushEvent.getOptions() ); } From d72f1c13b83594281c71acf0dfc7b3b12bcff0e4 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:15:45 +0900 Subject: [PATCH 37/45] =?UTF-8?q?feat:=20RushEvent=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EC=9D=91=EB=8B=B5=20DTO=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/ResponseDto/RushEventResultResponseDto.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java new file mode 100644 index 00000000..f8171066 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java @@ -0,0 +1,10 @@ +package JGS.CasperEvent.domain.event.dto.ResponseDto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public record RushEventResultResponseDto(long leftOption, long rightOption, long rank, long totalParticipants, + long winnerCount) { +} From 6ce2fff33a2c53c7f6b6ea0651e48f5059642716 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:16:13 +0900 Subject: [PATCH 38/45] =?UTF-8?q?feat:=20=EC=98=A4=EB=8A=98=EC=9D=98=20Rus?= =?UTF-8?q?hEvent=EB=A5=BC=20=EB=A7=A4=EC=9D=BC=2012=EC=8B=9C=EC=97=90=20R?= =?UTF-8?q?edis=EC=97=90=20=EB=84=A3=EB=8A=94=20=EC=8A=A4=EC=BC=80?= =?UTF-8?q?=EC=A4=84=EB=9F=AC=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eventService/RushEventScheduler.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventScheduler.java diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventScheduler.java b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventScheduler.java new file mode 100644 index 00000000..9d91e79c --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventScheduler.java @@ -0,0 +1,33 @@ +package JGS.CasperEvent.domain.event.service.eventService; + +import JGS.CasperEvent.domain.event.entity.event.RushEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; + +@Service +@EnableScheduling +@RequiredArgsConstructor +public class RushEventScheduler { + + private final RushEventService rushEventService; + private final RedisTemplate rushEventRedisTemplate; + + // 매일 12시에 스케줄된 작업을 실행합니다. + @Scheduled(cron = "0 0 12 * * ?") + public void fetchDailyEvents() { + // 오늘의 날짜를 구합니다. + LocalDate today = LocalDate.now(); + + // EventService를 통해 오늘의 이벤트를 가져옵니다. + RushEvent todayEvent = rushEventService.getTodayRushEvent(today); + + // 가져온 이벤트에 대한 추가 작업을 수행합니다. + // 예: 캐싱, 로그 기록, 알림 발송 등 + rushEventRedisTemplate.opsForValue().set("todayEvent", todayEvent); + } +} From d68c9a5a116d56ad208eddafc6175235b8ed23a7 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:18:12 +0900 Subject: [PATCH 39/45] =?UTF-8?q?fix:=20=EC=83=9D=EC=84=B1=EC=9E=90?= =?UTF-8?q?=EC=97=90=EC=84=9C=20RushEventRateResponseDto=EB=A5=BC=20?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResponseDto/RushEventResultResponseDto.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java index f8171066..4fee8df8 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/dto/ResponseDto/RushEventResultResponseDto.java @@ -5,6 +5,18 @@ @Getter @AllArgsConstructor -public record RushEventResultResponseDto(long leftOption, long rightOption, long rank, long totalParticipants, - long winnerCount) { +public class RushEventResultResponseDto { + private final long leftOption; + private final long rightOption; + private final long rank; + private final long totalParticipants; + private final long winnerCount; + + public RushEventResultResponseDto(RushEventRateResponseDto rushEventRateResponseDto, long rank, long totalParticipants, long winnerCount) { + this.leftOption = rushEventRateResponseDto.leftOption(); + this.rightOption = rushEventRateResponseDto.rightOption(); + this.rank = rank; + this.totalParticipants = totalParticipants; + this.winnerCount = winnerCount; + } } From baca0a16152c88bc63cd0eca24108e303e0f1fa2 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:18:56 +0900 Subject: [PATCH 40/45] =?UTF-8?q?feat:=20rushEvent=EB=A5=BC=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=ED=95=98=EA=B3=A0,=20=EC=98=A4=EB=8A=98?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EB=A5=BC=20redis?= =?UTF-8?q?=EC=97=90=20=EB=84=A3=EB=8A=94=20API=20=EA=B5=AC=ED=98=84,=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EC=A0=81=EC=9D=B8=20API=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eventService/RushEventService.java | 161 ++++++++++++++++-- 1 file changed, 146 insertions(+), 15 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java index 35afbd36..26fb59b8 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java @@ -1,48 +1,82 @@ package JGS.CasperEvent.domain.event.service.eventService; -import JGS.CasperEvent.domain.event.dto.ResponseDto.RushEventResponseDto; -import JGS.CasperEvent.domain.event.dto.ResponseDto.RushEventListAndServerTimeResponseDto; -import JGS.CasperEvent.domain.event.dto.ResponseDto.RushEventRateResponseDto; +import JGS.CasperEvent.domain.event.dto.ResponseDto.*; import JGS.CasperEvent.domain.event.entity.event.RushEvent; +import JGS.CasperEvent.domain.event.entity.event.RushOption; import JGS.CasperEvent.domain.event.entity.participants.RushParticipants; import JGS.CasperEvent.domain.event.repository.eventRepository.RushEventRepository; +import JGS.CasperEvent.domain.event.repository.eventRepository.RushOptionRepository; import JGS.CasperEvent.domain.event.repository.participantsRepository.RushParticipantsRepository; import JGS.CasperEvent.global.entity.BaseUser; import JGS.CasperEvent.global.enums.CustomErrorCode; import JGS.CasperEvent.global.error.exception.CustomException; import JGS.CasperEvent.global.util.RepositoryErrorHandler; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Service +@RequiredArgsConstructor public class RushEventService { private final RushEventRepository rushEventRepository; private final RushParticipantsRepository rushParticipantsRepository; + private final RedisTemplate rushEventRedisTemplate; + private final RushOptionRepository rushOptionRepository; - public RushEventService(RushEventRepository rushEventRepository, RushParticipantsRepository rushParticipantsRepository) { - this.rushEventRepository = rushEventRepository; - this.rushParticipantsRepository = rushParticipantsRepository; - } + @Transactional + public RushEventListResponseDto getAllRushEvents() { + // 오늘의 선착순 이벤트 꺼내오기 + RushEvent todayEvent = rushEventRedisTemplate.opsForValue().get("todayEvent"); + + // 오늘의 선착순 이벤트가 redis에 등록되지 않은 경우 + if (todayEvent == null) { + throw new CustomException("오늘의 선착순 이벤트가 redis에 등록되지 않았습니다.", CustomErrorCode.TODAY_RUSH_EVENT_NOT_FOUND); + } - public RushEventListAndServerTimeResponseDto getAllRushEvents() { // DB에서 모든 RushEvent 가져오기 List rushEventList = rushEventRepository.findAll(); + + // 선착순 이벤트 전체 시작 날짜와 종료 날짜 구하기 + List dates = rushEventList.stream().map(rushEvent -> rushEvent.getStartDateTime().toLocalDate()).sorted().toList(); + + LocalDate totalStartDate = dates.get(0); + LocalDate totalEndDate = dates.get(dates.size() - 1); + + // 전체 이벤트 기간 구하기 + long activePeriod = totalStartDate.until(totalEndDate).getDays() + 1; + // RushEvent를 DTO로 전환 - List rushEventDtoList = rushEventList.stream() - .map(RushEventResponseDto::of) + List mainRushEventDtoList = rushEventList.stream() + .map(MainRushEventResponseDto::of) .toList(); + // DTO 리스트와 서버 시간을 담은 RushEventListAndServerTimeResponse 객체 생성 후 반환 - return new RushEventListAndServerTimeResponseDto(rushEventDtoList, LocalDateTime.now()); + return new RushEventListResponseDto( + mainRushEventDtoList, + LocalDateTime.now(), + todayEvent.getRushEventId(), + totalStartDate, + totalEndDate, + activePeriod + ); } + // 응모 여부 조회 public boolean isExists(Long eventId, String userId) { - return rushParticipantsRepository.existsByRushEventIdAndUserId(eventId, userId); + return rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(eventId, userId); } + @Transactional public void apply(BaseUser user, Long eventId, int optionId) { - if (isExists(eventId, user.getId())) { + // 이미 응모한 회원인지 검증 + if (rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(eventId, user.getId())) { throw new CustomException("이미 응모한 회원입니다.", CustomErrorCode.CONFLICT); } @@ -55,9 +89,106 @@ public void apply(BaseUser user, Long eventId, int optionId) { } public RushEventRateResponseDto getRushEventRate(Long eventId) { - long leftOptionCount = rushParticipantsRepository.countByRushEventIdAndOptionId(eventId, 1); - long rightOptionCount = rushParticipantsRepository.countByRushEventIdAndOptionId(eventId, 2); + long leftOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(eventId, 1); + long rightOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(eventId, 2); return new RushEventRateResponseDto(leftOptionCount, rightOptionCount); } + + // 이벤트 결과를 반환 + // 해당 요청은 무조건 응모한 유저일 때만 요청 가능하다고 가정 + @Transactional + public RushEventResultResponseDto getRushEventResult(BaseUser user, Long eventId) { + // 최종 선택 비율을 조회 + // TODO: 레디스에 캐시 + RushEventRateResponseDto rushEventRateResponseDto = getRushEventRate(eventId); + + // 해당 이벤트의 당첨자 수를 가져옴 + int winnerCount = rushEventRepository.findByRushEventId(eventId).getWinnerCount(); + + // 해당 유저가 응모한 optionId 가져옴 + Optional optionId = rushParticipantsRepository.getOptionIdByUserId(user.getId()); + + if (optionId.isEmpty()) { + throw new CustomException("해당 유저가 이벤트 응모를 하지 않았습니다.", CustomErrorCode.USER_NOT_FOUND); + } + + // eventId, userId, optionId 를 이용하여 해당 유저가 응모한 선택지에서 등수를 가져옴 + long rank = rushParticipantsRepository.findUserRankByEventIdAndUserIdAndOptionId(eventId, user.getId(), optionId.get()); + + // 해당 선택지를 선택한 모든 유저 수를 가져옴 + long totalParticipants = rushParticipantsRepository.countAllByOptionId(optionId.get()); + + return new RushEventResultResponseDto(rushEventRateResponseDto.getLeftOption(), rushEventRateResponseDto.rightOption(), rank, totalParticipants, winnerCount); + } + + @Transactional + // 오늘의 이벤트를 DB에 꺼내서 반환 + public RushEvent getTodayRushEvent(LocalDate today) { + // 오늘 날짜에 해당하는 모든 이벤트 꺼내옴 + List rushEventList = rushEventRepository.findByEventDate(today); + + if (rushEventList.isEmpty()) { + throw new CustomException("선착순 이벤트가 존재하지않습니다.", CustomErrorCode.NO_RUSH_EVENT); + } + + if (rushEventList.size() > 1) { + throw new CustomException("선착순 이벤트가 존재하지않습니다.", CustomErrorCode.MULTIPLE_RUSH_EVENTS_FOUND); + } + + return rushEventList.get(0); + } + + @Transactional + public void setTodayEventToRedis() { + // 테이블 초기화 + rushParticipantsRepository.deleteAllInBatch(); + rushOptionRepository.deleteAllInBatch(); + rushEventRepository.deleteAllInBatch(); + + LocalDateTime startDateTime = LocalDateTime.of(2024, 8, 11, 22, 0); + LocalDateTime endDateTime = startDateTime.plusMinutes(10); + + List rushEvents = new ArrayList<>(); + + for (int i = 0; i < 6; i++) { + // RushEvent 생성 및 초기화 + RushEvent rushEvent = new RushEvent( + startDateTime.plusDays(i), // 이벤트 시작 날짜 + endDateTime.plusDays(i), // 이벤트 종료 날짜 + 0, // 우승자 수 (winnerCount) + "http://example.com/prize" + (i + 1) + ".jpg", // 상 이미지 URL + "Prize Description " + (i + 1) // 상 설명 + ); + + // RushEvent 저장 + rushEvent = rushEventRepository.save(rushEvent); + rushEvents.add(rushEvent); + + // 첫 번째 RushOption 생성 및 저장 + RushOption option1 = new RushOption( + rushEvent, + "Option 1 Main Text for Event " + (i + 1), + "Option 1 Sub Text for Event " + (i + 1), + "Option 1 Result Main Text for Event " + (i + 1), + "Option 1 Result Sub Text for Event " + (i + 1), + "http://example.com/option1-image" + (i + 1) + ".jpg" + ); + rushOptionRepository.save(option1); + + // 두 번째 RushOption 생성 및 저장 + RushOption option2 = new RushOption( + rushEvent, + "Option 2 Main Text for Event " + (i + 1), + "Option 2 Sub Text for Event " + (i + 1), + "Option 2 Result Main Text for Event " + (i + 1), + "Option 2 Result Sub Text for Event " + (i + 1), + "http://example.com/option2-image" + (i + 1) + ".jpg" + ); + rushOptionRepository.save(option2); + } + + // 처음으로 생성된 RushEvent를 Redis에 저장 + rushEventRedisTemplate.opsForValue().set("todayEvent", rushEvents.get(0)); + } } From ac26b67420fb1e2603957f5618469c7894b9fb57 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:20:12 +0900 Subject: [PATCH 41/45] =?UTF-8?q?fix:=20=EB=A1=AC=EB=B3=B5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84?= =?UTF-8?q?=EB=A5=BC=20OneToOne=20->=20ManyToOne=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/entity/event/RushOption.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java index 4e771731..a66fd6d1 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java @@ -2,16 +2,20 @@ import JGS.CasperEvent.global.entity.BaseEntity; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; @Entity -public class RushOption extends BaseEntity{ +@AllArgsConstructor +@NoArgsConstructor +public class RushOption extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long optionId; - @OneToOne + @ManyToOne @JoinColumn(name = "rush_event_id") private RushEvent rushEvent; - - @Id - private int optionId; private String mainText; private String subText; private String resultMainText; From eeca21c736290826bab8efb8d0183d334bc1d614 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:20:34 +0900 Subject: [PATCH 42/45] =?UTF-8?q?fix:=20RushOptionRepository=20JPA?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/eventRepository/RushOptionRepository.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushOptionRepository.java b/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushOptionRepository.java index e4e65d12..96130c15 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushOptionRepository.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/repository/eventRepository/RushOptionRepository.java @@ -1,7 +1,9 @@ package JGS.CasperEvent.domain.event.repository.eventRepository; +import JGS.CasperEvent.domain.event.entity.event.RushOption; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository -public interface RushOptionRepository { +public interface RushOptionRepository extends JpaRepository { } From c93d8fbcdc60e7a99e2cebdd1e51423705385bf8 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:21:41 +0900 Subject: [PATCH 43/45] =?UTF-8?q?fix:=20=EC=B0=B8=EC=A1=B0=20=EC=88=9C?= =?UTF-8?q?=ED=99=98=20=EC=97=90=EB=9F=AC=EB=A5=BC=20=ED=95=B4=EA=B2=B0?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20@JsonBackReference=20?= =?UTF-8?q?=EC=95=A0=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/entity/participants/RushParticipants.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/RushParticipants.java b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/RushParticipants.java index f160d1ff..d3d5b213 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/RushParticipants.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/participants/RushParticipants.java @@ -2,6 +2,7 @@ import JGS.CasperEvent.domain.event.entity.event.RushEvent; import JGS.CasperEvent.global.entity.BaseUser; +import com.fasterxml.jackson.annotation.JsonBackReference; import jakarta.persistence.*; @Entity @@ -12,6 +13,7 @@ public class RushParticipants { private int optionId; @OneToOne @JoinColumn(name = "base_user_id") + @JsonBackReference private BaseUser baseUser; @ManyToOne From a511154a065c0716ecfd3a0773e6288057d4a987 Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:22:13 +0900 Subject: [PATCH 44/45] =?UTF-8?q?fix:=20=EC=B5=9C=EB=8C=80=ED=95=9C=20JPA?= =?UTF-8?q?=20=EA=B8=B0=EB=B3=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94?= =?UTF-8?q?=EA=B1=B4=20=EC=B2=98=EB=A6=AC=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD,=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EC=A0=81=EC=9D=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RushParticipantsRepository.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/repository/participantsRepository/RushParticipantsRepository.java b/Server/src/main/java/JGS/CasperEvent/domain/event/repository/participantsRepository/RushParticipantsRepository.java index d8b0daea..f53b74f7 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/repository/participantsRepository/RushParticipantsRepository.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/repository/participantsRepository/RushParticipantsRepository.java @@ -6,14 +6,23 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface RushParticipantsRepository extends JpaRepository { - @Query("SELECT CASE WHEN COUNT(rp) > 0 THEN TRUE ELSE FALSE END " + - "FROM RushParticipants rp " + - "WHERE rp.rushEvent.rushEventId = :eventId AND rp.baseUser.id = :userId") - boolean existsByRushEventIdAndUserId(@Param("eventId") Long eventId, @Param("userId") String userId); + boolean existsByRushEvent_RushEventIdAndBaseUser_Id(Long eventId, String userId); + long countByRushEvent_RushEventIdAndOptionId(Long eventId, int optionId); + @Query("SELECT COUNT(rp) + 1 FROM RushParticipants rp " + + "WHERE rp.rushEvent.rushEventId = :eventId " + + "AND rp.optionId = :optionId " + + "AND rp.id < (SELECT rp2.id FROM RushParticipants rp2 " + + "WHERE rp2.rushEvent.rushEventId = :eventId " + + "AND rp2.baseUser.id = :userId)") + long findUserRankByEventIdAndUserIdAndOptionId(@Param("eventId") Long eventId, + @Param("userId") String userId, + @Param("optionId") int optionId); + long countAllByOptionId(int optionId); + @Query("SELECT rp.optionId FROM RushParticipants rp WHERE rp.baseUser.id = :userId") + Optional getOptionIdByUserId(@Param("userId") String userId); - @Query("SELECT COUNT(rp) FROM RushParticipants rp " + - "WHERE rp.rushEvent.rushEventId = :eventId AND rp.optionId = :optionId") - long countByRushEventIdAndOptionId(@Param("eventId") Long eventId, @Param("optionId") int optionId); } From fdafb1384b6e857ecc208bba3ad86faa21c476de Mon Sep 17 00:00:00 2001 From: wjddn2165 Date: Sun, 11 Aug 2024 14:43:41 +0900 Subject: [PATCH 45/45] =?UTF-8?q?feat:=20AllArgsConstructor=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/entity/event/RushOption.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java index a66fd6d1..7d0726ba 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/entity/event/RushOption.java @@ -2,11 +2,9 @@ import JGS.CasperEvent.global.entity.BaseEntity; import jakarta.persistence.*; -import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @Entity -@AllArgsConstructor @NoArgsConstructor public class RushOption extends BaseEntity { @Id @@ -21,4 +19,13 @@ public class RushOption extends BaseEntity { private String resultMainText; private String resultSubText; private String imageUrl; + + public RushOption(RushEvent rushEvent, String mainText, String subText, String resultMainText, String resultSubText, String imageUrl) { + this.rushEvent = rushEvent; + this.mainText = mainText; + this.subText = subText; + this.resultMainText = resultMainText; + this.resultSubText = resultSubText; + this.imageUrl = imageUrl; + } }