From 280aa8c31b5983a6a2af7a83019e39ce6829212f Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 28 Dec 2023 14:25:32 +0900 Subject: [PATCH 01/23] =?UTF-8?q?Feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A6=AC=EC=82=AC=EC=9D=B4=EC=A7=95=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 1007515..931f9ee 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,8 @@ dependencies { testImplementation 'org.mockito:mockito-core:5.2.0' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + + implementation 'net.coobird:thumbnailator:0.4.19' } tasks.named('bootBuildImage') { From 024f6a61007b590fcb44c991bbbf6e871935d6bf Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 28 Dec 2023 14:27:04 +0900 Subject: [PATCH 02/23] =?UTF-8?q?Feat:=20=EB=A6=AC=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EC=A7=95=ED=95=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=B4=EA=B8=B0=20=EC=9C=84=ED=95=9C=20S3=20=EB=B2=84?= =?UTF-8?q?=ED=82=B7=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6f2dbce..cc4c2c3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -28,8 +28,8 @@ spring: multipart: enabled: true location: '${custom.image.url}' - max-request-size: 500MB - max-file-size: 500MB + max-request-size: '${custom.image.request-size}' + max-file-size: '${custom.image.file-size}' security: oauth2: client: @@ -44,6 +44,7 @@ spring: cloud: aws: s3: + resized-bucket: '${cloud.aws.s3.resized-bucket}' bucket: '${cloud.aws.s3.bucket}' url: '${cloud.aws.s3.url}' stack.auto: false From fd6412d861004c9d90d0ef2213fac5f9d94ead48 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 28 Dec 2023 14:30:15 +0900 Subject: [PATCH 03/23] =?UTF-8?q?Feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A6=AC=EC=82=AC=EC=9D=B4=EC=A7=95=20=EA=B8=B0=EB=8A=A5=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 --- .../image/service/ImageServiceImpl.java | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/ll/netmong/domain/image/service/ImageServiceImpl.java b/src/main/java/com/ll/netmong/domain/image/service/ImageServiceImpl.java index 20afd55..ce9876b 100644 --- a/src/main/java/com/ll/netmong/domain/image/service/ImageServiceImpl.java +++ b/src/main/java/com/ll/netmong/domain/image/service/ImageServiceImpl.java @@ -7,11 +7,14 @@ import com.ll.netmong.domain.post.entity.Post; import com.ll.netmong.domain.product.entity.Product; import lombok.RequiredArgsConstructor; +import net.coobird.thumbnailator.Thumbnails; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Optional; @@ -21,15 +24,18 @@ public class ImageServiceImpl implements ImageService { private final AmazonS3Client amazonS3Client; private final ImageRepository imageRepository; + @Value("${cloud.aws.s3.resized-bucket}") + private String resizedBucket; + @Value("${cloud.aws.s3.bucket}") - private String bucket; + private String originalBucket; @Value("${cloud.aws.s3.url}") - private String bucketUrl; + private String originalBucketUrl; @Transactional public Optional uploadImage(T requestType, MultipartFile file) throws IOException { - String imageLocation = bucketUrl; + String imageLocation = originalBucketUrl; String imageName = file.getOriginalFilename(); String requestTypeSimpleName = requestType.getClass().getSimpleName() + "/"; @@ -51,16 +57,35 @@ public Optional uploadImage(T requestType, MultipartFile file) throws if (image.isPresent()) { imageRepository.save(image.get()); - createS3Bucket(fileName, file); + uploadOriginalImage(originalBucket, fileName, file); + uploadResizedImage(resizedBucket, fileName, file); } return image; } - private void createS3Bucket(String fileName, MultipartFile image) throws IOException { + private void uploadOriginalImage(String bucketName, String fileName, MultipartFile image) throws IOException { + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(image.getContentType()); + metadata.setContentLength(image.getSize()); + amazonS3Client.putObject(bucketName, fileName, image.getInputStream(), metadata); + } + + private void uploadResizedImage(String bucketName, String fileName, MultipartFile image) throws IOException { ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType(image.getContentType()); metadata.setContentLength(image.getSize()); - amazonS3Client.putObject(bucket, fileName, image.getInputStream(), metadata); + + byte[] buffer = getResizedImageStream(image); + metadata.setContentLength(buffer.length); + ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer); + + amazonS3Client.putObject(bucketName, fileName, inputStream, metadata); + } + + private byte[] getResizedImageStream(MultipartFile image) throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Thumbnails.of(image.getInputStream()).size(400, 400).toOutputStream(outputStream); + return outputStream.toByteArray(); } } From 562377fb0ca1e012554cac651fb0647ac38fe613 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Sat, 30 Dec 2023 15:20:31 +0900 Subject: [PATCH 04/23] =?UTF-8?q?Feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=EC=97=90=20=EB=8B=B4=EA=B8=B4=20=EC=82=AD=ED=92=88=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ll/netmong/domain/cart/controller/CartController.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java b/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java index 9cbe32b..3d12311 100644 --- a/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java +++ b/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java @@ -30,4 +30,11 @@ public RsData addMyCart(@AuthenticationPrincipal UserDetails currentUser, cartService.addProductByCart(currentUser, productId, productCountRequest); return RsData.of("S-1", CART_SUCCESS_PRODUCT, "create"); } + + @DeleteMapping("{productId}") + public RsData deleteByProduct(@AuthenticationPrincipal UserDetails currentUser, + @PathVariable(name = "productId") Long productId) { + cartService.deleteByProduct(currentUser, productId); + return RsData.successOf("delete"); + } } From e15b6e00246e35f3553f8bc4b8bea75368acc011 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Sat, 30 Dec 2023 15:20:55 +0900 Subject: [PATCH 05/23] =?UTF-8?q?Feat:=20=EC=83=81=ED=92=88=20=EC=9E=AC?= =?UTF-8?q?=EA=B3=A0=20=EA=B0=90=EC=86=8C=20=EA=B8=B0=EB=8A=A5=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 --- src/main/java/com/ll/netmong/domain/cart/entity/Cart.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java b/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java index 1b19ba0..979c65c 100644 --- a/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java +++ b/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java @@ -34,4 +34,8 @@ public static Cart createCart(Member member) { public void addCount(Integer count) { this.totalCount += count; } + + public void minusCount(Integer count){ + this.totalCount -= count; + } } From 616f50a73dfa903068da767e055e338830d5aa24 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Sat, 30 Dec 2023 15:21:30 +0900 Subject: [PATCH 06/23] =?UTF-8?q?Feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=EC=97=90=20=EB=93=B1=EB=A1=9D=EB=90=9C=20=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=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 --- .../com/ll/netmong/domain/cart/service/CartService.java | 2 ++ .../ll/netmong/domain/cart/service/CartServiceImpl.java | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/main/java/com/ll/netmong/domain/cart/service/CartService.java b/src/main/java/com/ll/netmong/domain/cart/service/CartService.java index 75495a9..5922bf7 100644 --- a/src/main/java/com/ll/netmong/domain/cart/service/CartService.java +++ b/src/main/java/com/ll/netmong/domain/cart/service/CartService.java @@ -8,4 +8,6 @@ public interface CartService { void createCart(Member member); void addProductByCart(UserDetails currentUser, Long productId, ProductCountRequest productCountRequest); + + void deleteByProduct(UserDetails currentUser, Long productId); } diff --git a/src/main/java/com/ll/netmong/domain/cart/service/CartServiceImpl.java b/src/main/java/com/ll/netmong/domain/cart/service/CartServiceImpl.java index acce7fc..ad933f4 100644 --- a/src/main/java/com/ll/netmong/domain/cart/service/CartServiceImpl.java +++ b/src/main/java/com/ll/netmong/domain/cart/service/CartServiceImpl.java @@ -44,6 +44,13 @@ public void addProductByCart(UserDetails currentUser, Long productId, ProductCou itemCartService.addToCartForExistingProduct(findItemCart.get(), cart, productCountRequest); } + @Override + @Transactional + public void deleteByProduct(UserDetails currentUser, Long productId) { + Cart cart = validateExistMember(currentUser); + itemCartService.deleteByProduct(cart, productId); + } + private Cart validateExistMember(UserDetails currentUser) { return cartRepository.findByMemberEmail(currentUser.getUsername()) .orElseThrow(() -> new ProductException("회원이 존재하지 않습니다.", ProductErrorCode.NOT_EXIST_PRODUCT)); From a9d38d8bfc8a469b35a27ce372de67389078dd42 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Sun, 31 Dec 2023 13:53:18 +0900 Subject: [PATCH 07/23] =?UTF-8?q?Feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=EC=97=90=20=EB=93=B1=EB=A1=9D=EB=90=9C=20=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=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 --- .../cart/itemCart/service/ItemCartService.java | 2 ++ .../itemCart/service/ItemCartServiceImpl.java | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartService.java b/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartService.java index fb9f11d..403c540 100644 --- a/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartService.java +++ b/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartService.java @@ -14,6 +14,8 @@ public interface ItemCartService { void addToCartForExistingProduct(ItemCart findItemCart, Cart cart, ProductCountRequest productCountRequest); + void deleteByProduct(Cart cart, Long productId); + ItemCart getItemCart(Cart cart, Long productId); String findMemberEmailByProductId(Long productId); diff --git a/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java b/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java index 43bf487..69b995d 100644 --- a/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java +++ b/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java @@ -73,13 +73,27 @@ public void addToCartForExistingProduct(ItemCart findItemCart, Cart cart, Produc findItemCart.addCount(productCountRequest.getCount()); } + @Override + public void deleteByProduct(Cart cart, Long productId) { + ItemCart itemCart = getItemCart(cart, productId); + int stackCount = itemCart.getStackCount(); + + Product product = productRepository.findById(itemCart.getProduct().getId()) + .orElseThrow(() -> new ProductException("존재하지 않는 상품입니다.", ProductErrorCode.NOT_EXIST_PRODUCT)); + product.setCount(product.getCount() + stackCount); + + cart.minusCount(stackCount); + itemCartRepository.deleteById(itemCart.getId()); + productRepository.save(product); + } + @Transactional public void removeStock(Long productId, Integer count) { try { transactionTemplate.execute(status -> { // Pessimistic Lock을 걸고 상품을 조회합니다. Product findByProduct = productRepository.findByIdWithPessimisticLock(productId) - .orElseThrow(() -> new ProductException("존재하지 않는 상품입니다.", ProductErrorCode.NOT_EXIST_PRODUCT_NAME)); + .orElseThrow(() -> new ProductException("존재하지 않는 상품입니다.", ProductErrorCode.NOT_EXIST_PRODUCT)); int restStock = findByProduct.getCount() - count; From ee2f96eb00a188d7336f1584fff99d76e8aae182 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Wed, 3 Jan 2024 12:32:57 +0900 Subject: [PATCH 08/23] =?UTF-8?q?Feat:=20=ED=86=A0=EC=8A=A4=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EB=A8=BC=EC=B8=A0=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/config/TossPaymentConfig.java | 31 +++++++++++++++++++ src/main/resources/application.yml | 7 +++++ 2 files changed, 38 insertions(+) create mode 100644 src/main/java/com/ll/netmong/base/config/TossPaymentConfig.java diff --git a/src/main/java/com/ll/netmong/base/config/TossPaymentConfig.java b/src/main/java/com/ll/netmong/base/config/TossPaymentConfig.java new file mode 100644 index 0000000..9fcfdc4 --- /dev/null +++ b/src/main/java/com/ll/netmong/base/config/TossPaymentConfig.java @@ -0,0 +1,31 @@ +package com.ll.netmong.base.config; + +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Getter +public class TossPaymentConfig { + public static final String TOSS_COMMON_URL = "https://api.tosspayments.com/v1/payments/"; + + @Value("${payment.toss.test-client-api-key}") + private String testClientApiKey; + + @Value("${payment.toss.test-secrete-api-key}") + private String testSecretKey; + + /** + * 실제 전자 결제 신청 후 사용할 API 키 + * @Value("${payment.toss.live_client_api_key}") + * private String liveClientApiKey; + * @Value("${payment.toss.live_secrete_api_key}") + * private String liveSecretKey; + */ + + @Value("${payment.success-url}") + private String successUrl; + + @Value("${payment.fail-url}") + private String failUrl; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index cc4c2c3..2354639 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -58,4 +58,11 @@ logging: root: INFO org.hibernate.orm.jdbc.bind: trace +payment: + toss: + test-client-api-key: '${payment.toss.test-client-api-key}' + test-secrete-api-key: '${payment.toss.test-secrete-api-key}' + success-url: '${payment.success-url}' + fail-url: '${payment.fail-url}' + domain: '${custom.image.domain}' From e61a90c6475d17762f370b037c3cc6bb3597b7b4 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 00:18:04 +0900 Subject: [PATCH 09/23] =?UTF-8?q?Feat:=20X=20To=20One=20=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20Lazy=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ll/netmong/domain/product/entity/Product.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/ll/netmong/domain/product/entity/Product.java b/src/main/java/com/ll/netmong/domain/product/entity/Product.java index 8a29dff..bf108af 100644 --- a/src/main/java/com/ll/netmong/domain/product/entity/Product.java +++ b/src/main/java/com/ll/netmong/domain/product/entity/Product.java @@ -47,7 +47,7 @@ public class Product extends BaseEntity { @JoinColumn(name = "member_id") private Member member; - @OneToOne(orphanRemoval = true) + @OneToOne(orphanRemoval = true, fetch = FetchType.LAZY) @JoinColumn(name = "image_id") private Image image; From fccc71c266a1032e4d9e1925ef32e8ae44308afa Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 19:12:11 +0900 Subject: [PATCH 10/23] =?UTF-8?q?Feat:=20=EA=B2=B0=EC=A0=9C=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=EC=97=90=20=EB=8C=80=ED=95=9C=20enum=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 --- .../ll/netmong/domain/order/util/PayType.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/com/ll/netmong/domain/order/util/PayType.java diff --git a/src/main/java/com/ll/netmong/domain/order/util/PayType.java b/src/main/java/com/ll/netmong/domain/order/util/PayType.java new file mode 100644 index 0000000..149ecdc --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/util/PayType.java @@ -0,0 +1,20 @@ +package com.ll.netmong.domain.order.util; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum PayType { + CARD("카드"), + CASH("현금"), + POINT("포인트"); + + PayType(String paymentType) { + this.paymentType = paymentType; + } + + private final String paymentType; + + @JsonValue + public String getPaymentType() { + return paymentType; + } +} From 06706aea88742df18db70152f99ecd81a1fa0d9d Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 19:18:16 +0900 Subject: [PATCH 11/23] =?UTF-8?q?Feat:=20=EC=A3=BC=EB=AC=B8=20Entity=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ll/netmong/domain/order/entity/Order.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/main/java/com/ll/netmong/domain/order/entity/Order.java diff --git a/src/main/java/com/ll/netmong/domain/order/entity/Order.java b/src/main/java/com/ll/netmong/domain/order/entity/Order.java new file mode 100644 index 0000000..db6085e --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/entity/Order.java @@ -0,0 +1,84 @@ +package com.ll.netmong.domain.order.entity; + +import com.ll.netmong.common.BaseEntity; +import com.ll.netmong.domain.member.entity.Member; +import com.ll.netmong.domain.order.dto.response.PaymentResponse; +import com.ll.netmong.domain.order.util.PayType; +import com.ll.netmong.domain.product.entity.Product; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@Entity +@Getter +@Table(name = "payment") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@SuperBuilder(toBuilder = true) +public class Order extends BaseEntity { + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; + + @Column(name = "pay_type") + @Enumerated(EnumType.STRING) + private PayType payType; + + @Column(name = "pay_amount") + private Long amount; + + @Column(name = "pay_name") + private String orderName; + + @Column(name = "order_id") + private String orderId; + + @Column(name = "payment_key") + private String paymentKey; + + @Column(name = "pay_success_status") + private boolean paySuccessYN; + + @Column(name = "cancel_status") + private boolean cancelYN; + + @Column(name = "fail_reason") + private String failReason; + + + public void setMember(Member member) { + this.member = member; + } + + + public void paymentSuccess(String paymentKey) { + this.paymentKey = paymentKey; + this.paySuccessYN = true; + } + + public void paymentFail(String message) { + this.failReason = message; + this.paySuccessYN = false; + } + + public PaymentResponse toPaymentResponse() { + return PaymentResponse + .builder() + .payType(payType.getPaymentType()) + .amount(amount) + .orderName(orderName) + .orderId(orderId) + .customerEmail(member.getEmail()) + .customerName(member.getRealName()) + .createdAt(String.valueOf(getCreateDate())) + .cancelYN(cancelYN) + .failReason(failReason) + .build(); + } +} From 89c4650ccf70d3ea23be13098c3fcc040955762f Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 19:18:58 +0900 Subject: [PATCH 12/23] =?UTF-8?q?Feat:=20=EA=B2=B0=EC=A0=9C=EC=9A=94?= =?UTF-8?q?=EC=B2=AD,=20=EC=84=B1=EA=B3=B5=EC=8B=9C=20=EB=A1=A4=EB=B0=B1?= =?UTF-8?q?=20URL,=20=EC=8B=A4=ED=8C=A8=EC=8B=9C=20=EB=A1=A4=EB=B0=B1=20UR?= =?UTF-8?q?L=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/controller/OrderController.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/main/java/com/ll/netmong/domain/order/controller/OrderController.java diff --git a/src/main/java/com/ll/netmong/domain/order/controller/OrderController.java b/src/main/java/com/ll/netmong/domain/order/controller/OrderController.java new file mode 100644 index 0000000..1aea222 --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/controller/OrderController.java @@ -0,0 +1,51 @@ +package com.ll.netmong.domain.order.controller; + +import com.ll.netmong.base.config.TossPaymentConfig; +import com.ll.netmong.common.RsData; +import com.ll.netmong.domain.order.dto.request.PaymentRequest; +import com.ll.netmong.domain.order.dto.response.PaymentFailResponse; +import com.ll.netmong.domain.order.dto.response.PaymentResponse; +import com.ll.netmong.domain.order.dto.response.PaymentSuccessResponse; +import com.ll.netmong.domain.order.service.OrderService; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; + +@RestController +@RequiredArgsConstructor +@RequestMapping("api/v1/order") +public class OrderController { + private final OrderService orderService; + private final TossPaymentConfig tossPaymentConfig; + + @PostMapping + public RsData requestPaymentByToss(@AuthenticationPrincipal UserDetails currentUser, + @RequestBody PaymentRequest paymentRequest) throws Exception { + PaymentResponse paymentResponse = orderService.requestPayment(paymentRequest.createOrder(), currentUser.getUsername()); + paymentResponse.setSuccessUrl(Optional.ofNullable(paymentRequest.getSuccessUrl()).orElse(tossPaymentConfig.getSuccessUrl())); + paymentResponse.setFailUrl(Optional.ofNullable(paymentRequest.getFailUrl()).orElse(tossPaymentConfig.getFailUrl())); + + return RsData.successOf(paymentResponse); + } + + @GetMapping("/success") + public RsData successPaymentByToss(@RequestParam String paymentKey, + @RequestParam String orderId, + @RequestParam Long amount) { + PaymentSuccessResponse paymentSuccessResponse = orderService.paymentSuccess(paymentKey, orderId, amount); + + return RsData.successOf(paymentSuccessResponse); + } + + @GetMapping("/fail") + public RsData failPaymentByToss(@RequestParam String code, + @RequestParam String orderId, + @RequestParam String message) { + PaymentFailResponse paymentFailResponse = orderService.failPayment(code, orderId, message); + + return RsData.successOf(paymentFailResponse); + } +} From 77ea67832f99189139f927411c90888850e2ee69 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 19:21:43 +0900 Subject: [PATCH 13/23] =?UTF-8?q?Feat:=20=EA=B2=B0=EC=A0=9C=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EA=B8=B0=EB=8A=A5,=20=EC=84=B1=EA=B3=B5=EC=8B=9C?= =?UTF-8?q?=20=EB=A1=A4=EB=B0=B1=20=EA=B8=B0=EB=8A=A5,=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=EC=8B=9C=20=EB=A1=A4=EB=B0=B1=20=EA=B8=B0=EB=8A=A5=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 --- .../domain/order/service/OrderService.java | 15 +++ .../order/service/OrderServiceImpl.java | 127 ++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 src/main/java/com/ll/netmong/domain/order/service/OrderService.java create mode 100644 src/main/java/com/ll/netmong/domain/order/service/OrderServiceImpl.java diff --git a/src/main/java/com/ll/netmong/domain/order/service/OrderService.java b/src/main/java/com/ll/netmong/domain/order/service/OrderService.java new file mode 100644 index 0000000..55e2f46 --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/service/OrderService.java @@ -0,0 +1,15 @@ +package com.ll.netmong.domain.order.service; + +import com.ll.netmong.domain.order.dto.response.PaymentFailResponse; +import com.ll.netmong.domain.order.dto.response.PaymentResponse; +import com.ll.netmong.domain.order.dto.response.PaymentSuccessResponse; +import com.ll.netmong.domain.order.entity.Order; + +public interface OrderService { + + PaymentResponse requestPayment(Order order, String userEmail) throws Exception; + + PaymentSuccessResponse paymentSuccess(String paymentKey, String orderId, Long amount); + + PaymentFailResponse failPayment(String code, String orderId, String message); +} diff --git a/src/main/java/com/ll/netmong/domain/order/service/OrderServiceImpl.java b/src/main/java/com/ll/netmong/domain/order/service/OrderServiceImpl.java new file mode 100644 index 0000000..ec3b337 --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/service/OrderServiceImpl.java @@ -0,0 +1,127 @@ +package com.ll.netmong.domain.order.service; + +import com.ll.netmong.base.config.TossPaymentConfig; +import com.ll.netmong.domain.member.entity.Member; +import com.ll.netmong.domain.member.service.MemberService; +import com.ll.netmong.domain.order.dto.response.PaymentFailResponse; +import com.ll.netmong.domain.order.dto.response.PaymentResponse; +import com.ll.netmong.domain.order.dto.response.PaymentSuccessResponse; +import com.ll.netmong.domain.order.entity.Order; +import com.ll.netmong.domain.order.repository.OrderRepository; +import lombok.RequiredArgsConstructor; +import net.minidev.json.JSONObject; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Collections; + + +@Service +@RequiredArgsConstructor +public class OrderServiceImpl implements OrderService { + private final MemberService memberService; + private final OrderRepository orderRepository; + private final TossPaymentConfig tossPaymentConfig; + + @Override + @Transactional + public PaymentResponse requestPayment(Order order, String userEmail) throws Exception { + Member findMemberByEmail = memberService.findByEmail(userEmail); + order.setMember(findMemberByEmail); + + return orderRepository.save(order).toPaymentResponse(); + } + + @Override + @Transactional + public PaymentSuccessResponse paymentSuccess(String paymentKey, String orderId, Long amount) { + Order order = verifyPayment(orderId, amount); // 요청가격 == 결제된 금액 + PaymentSuccessResponse result = requestPaymentAccept(paymentKey, orderId, amount); + order.paymentSuccess(paymentKey); + + // todo : 회원의 포인트 갱신으로 인해 Member 테이블에 Point 컬럼 추가 +// order.getMember(). + + return result; + } + + @Override + @Transactional + public PaymentFailResponse failPayment(String code, String orderId, String message) { + Order order = findByOrder(orderId); + order.paymentFail(message); + + return requestPaymentFail(code, message, orderId); + } + + private PaymentFailResponse requestPaymentFail(String code, String message, String orderId) { + return PaymentFailResponse + .builder() + .errorCode(code) + .errorMessage(message) + .orderId(orderId) + .build(); + } + + private Order verifyPayment(String orderId, Long amount) { + Order order = findByOrder(orderId); + + if (!order.getAmount().equals(amount)) { + throw new IllegalArgumentException(); + } + return order; + } + + private Order findByOrder(String orderId) { + return orderRepository.findByOrderId(orderId).orElseThrow(() -> { + throw new IllegalArgumentException(); + }); + } + + private PaymentSuccessResponse requestPaymentAccept(String paymentKey, String orderId, Long amount) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = getHeaders(); + JSONObject params = createParmas(orderId, amount); + + PaymentSuccessResponse result; + + try { + result = restTemplate.postForObject(TossPaymentConfig.TOSS_COMMON_URL + paymentKey, + new HttpEntity<>(params, headers), + PaymentSuccessResponse.class); + } catch (Exception exception) { + throw new IllegalArgumentException(); + } + + return result; + } + + private HttpHeaders getHeaders() { + HttpHeaders headers = new HttpHeaders(); + + // 토스에서 받은 시크릿 키를 Base64를 이용하여 인코딩 한다. + // 이때, {시크릿 키 + ":"} 조합으로 인코딩 해야함 + String encodeAuthKey = new String( + Base64.getEncoder().encode((tossPaymentConfig.getTestSecretKey() + ":").getBytes(StandardCharsets.UTF_8)) + ); + + headers.setBasicAuth(encodeAuthKey); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + + return headers; + } + + private JSONObject createParmas(String orderId, Long amount) { + JSONObject params = new JSONObject(); + params.put("orderId", orderId); + params.put("amount", amount); + return params; + } +} From 24f5699e8fb0b4812428f33f0350f74f0dbae3eb Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 19:22:27 +0900 Subject: [PATCH 14/23] =?UTF-8?q?Feat:=20=EA=B2=B0=EC=A0=9C=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=9D=91=EB=8B=B5=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/PaymentFailResponse.java | 16 +++++++++++ .../order/dto/response/PaymentResponse.java | 25 +++++++++++++++++ .../dto/response/PaymentSuccessResponse.java | 27 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 src/main/java/com/ll/netmong/domain/order/dto/response/PaymentFailResponse.java create mode 100644 src/main/java/com/ll/netmong/domain/order/dto/response/PaymentResponse.java create mode 100644 src/main/java/com/ll/netmong/domain/order/dto/response/PaymentSuccessResponse.java diff --git a/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentFailResponse.java b/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentFailResponse.java new file mode 100644 index 0000000..9b6ecd9 --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentFailResponse.java @@ -0,0 +1,16 @@ +package com.ll.netmong.domain.order.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@Builder +public class PaymentFailResponse { + private String errorCode; + private String errorMessage; + private String orderId; +} diff --git a/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentResponse.java b/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentResponse.java new file mode 100644 index 0000000..36a18f8 --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentResponse.java @@ -0,0 +1,25 @@ +package com.ll.netmong.domain.order.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@Builder +public class PaymentResponse { + private String payType; + private Long amount; + private String orderName; + private String orderId; + private String customerEmail; + private String customerName; + private String successUrl; + private String failUrl; + private String failReason; + private boolean cancelYN; + private String cancelReason; + private String createdAt; +} diff --git a/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentSuccessResponse.java b/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentSuccessResponse.java new file mode 100644 index 0000000..6ef1c9d --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/dto/response/PaymentSuccessResponse.java @@ -0,0 +1,27 @@ +package com.ll.netmong.domain.order.dto.response; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PaymentSuccessResponse { + private String mid; // 가맹점 Id -> tosspayments + private String version; // Payment 객체 응답 버전 + private String paymentKey; + private String orderId; + private String orderName; + private String currency; // "KRW" + private String method; // 결제 수단 + private String totalAmount; + private String balanceAmount; + private String suppliedAmount; + private String vat; // 부가가치세 + private String status; // 결제 처리 상태 + private String requestedAt; + private String approvedAt; + private String useEscrow; // false + private String cultureExpense; // false +// private PaymentSuccessCardDto card; // 결제 카드 정보 (아래 자세한 정보 있음) + private String type; // 결제 타입 정보 (NOMAL / BILLING / CONNECTPAY) +} From a55665b200dc48754d9acac5f8162ff5e37b8496 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 19:22:43 +0900 Subject: [PATCH 15/23] =?UTF-8?q?Feat:=20=EA=B2=B0=EC=A0=9C=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/dto/request/PaymentRequest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/java/com/ll/netmong/domain/order/dto/request/PaymentRequest.java diff --git a/src/main/java/com/ll/netmong/domain/order/dto/request/PaymentRequest.java b/src/main/java/com/ll/netmong/domain/order/dto/request/PaymentRequest.java new file mode 100644 index 0000000..bcc2700 --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/dto/request/PaymentRequest.java @@ -0,0 +1,29 @@ +package com.ll.netmong.domain.order.dto.request; + +import com.ll.netmong.domain.order.entity.Order; +import com.ll.netmong.domain.order.util.PayType; +import lombok.Getter; +import lombok.Setter; + +import java.util.UUID; + +@Getter +@Setter +public class PaymentRequest { + private PayType payType; + private String orderName; // 주문명, ex : 포인트 충전 + private Long amount; + private String successUrl; // 성공 시 리다이렉트 될 URL + private String failUrl; // 실패 시 리다이렉트 될 URL + + public Order createOrder() { + return Order + .builder() + .payType(payType) + .amount(amount) + .orderName(orderName) + .orderId(UUID.randomUUID().toString()) + .paySuccessYN(false) + .build(); + } +} From 40cc396feae26c5b41f8ced35d1e4169bcd0fde7 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 4 Jan 2024 19:22:57 +0900 Subject: [PATCH 16/23] =?UTF-8?q?Feat:=20=EA=B2=B0=EC=A0=9C=20Repository?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/order/repository/OrderRepository.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/ll/netmong/domain/order/repository/OrderRepository.java diff --git a/src/main/java/com/ll/netmong/domain/order/repository/OrderRepository.java b/src/main/java/com/ll/netmong/domain/order/repository/OrderRepository.java new file mode 100644 index 0000000..06e6110 --- /dev/null +++ b/src/main/java/com/ll/netmong/domain/order/repository/OrderRepository.java @@ -0,0 +1,11 @@ +package com.ll.netmong.domain.order.repository; + +import com.ll.netmong.domain.order.entity.Order; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface OrderRepository extends JpaRepository { + + Optional findByOrderId(String orderId); +} From d07b41afbc4e6271cc64661b4ccd0a5d07eda3cf Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 11 Jan 2024 11:38:31 +0900 Subject: [PATCH 17/23] =?UTF-8?q?Refactor=20:=20isImageExists=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=EB=A5=BC=20=ED=95=9C=EB=B2=88=EB=A7=8C=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=ED=95=98=EA=B2=8C=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../netmong/domain/product/service/ProductServiceImpl.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java b/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java index aac7f63..f284268 100644 --- a/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java +++ b/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java @@ -38,11 +38,8 @@ public class ProductServiceImpl implements ProductService { @Transactional public void createProductWithImage(UserDetails currentUser, CreateRequest createRequest, MultipartFile images) throws IOException { - if (!isImageExists(images)) { - initProduct(currentUser, createRequest); - } + Product product = initProduct(currentUser, createRequest); if (isImageExists(images)) { - Product product = initProduct(currentUser, createRequest); product.addProductImage(imageService.uploadImage(product, images).orElseThrow()); } } From 7f65cf3f4d7d37229d53a1a88edcb94b54aa49b9 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 11 Jan 2024 12:39:11 +0900 Subject: [PATCH 18/23] =?UTF-8?q?Refactor=20:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ll/netmong/domain/product/service/ProductServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java b/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java index f284268..a4eb040 100644 --- a/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java +++ b/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java @@ -89,7 +89,8 @@ public void updateProduct(UserDetails currentUser, @Transactional public void softDeleteProduct(UserDetails currentUser, Long productId) { - validateCurrentUser(currentUser, validateExistProduct(productId)); + Product findProduct = validateExistProduct(productId); + validateCurrentUser(currentUser, findProduct); productRepository.deleteById(productId); } From 57d6bcbf21c637b75283474e8d72bbd6e261e9ae Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Thu, 11 Jan 2024 12:40:48 +0900 Subject: [PATCH 19/23] =?UTF-8?q?Refactor=20:=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ll/netmong/domain/product/controller/ProductController.java | 2 +- .../com/ll/netmong/domain/product/service/ProductService.java | 2 +- .../ll/netmong/domain/product/service/ProductServiceImpl.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/ll/netmong/domain/product/controller/ProductController.java b/src/main/java/com/ll/netmong/domain/product/controller/ProductController.java index 479d126..9dd48e1 100644 --- a/src/main/java/com/ll/netmong/domain/product/controller/ProductController.java +++ b/src/main/java/com/ll/netmong/domain/product/controller/ProductController.java @@ -64,7 +64,7 @@ public RsData findByProductCategory(@PathVariable(name = "category") String cate @GetMapping("/name/{name}") public RsData findByProductName(@PathVariable(name = "name") String name) { - return RsData.successOf(productService.findByProductName(name)); + return RsData.successOf(productService.findProductsByProductName(name)); } @GetMapping("/all") diff --git a/src/main/java/com/ll/netmong/domain/product/service/ProductService.java b/src/main/java/com/ll/netmong/domain/product/service/ProductService.java index 4bf05d4..dd45cd6 100644 --- a/src/main/java/com/ll/netmong/domain/product/service/ProductService.java +++ b/src/main/java/com/ll/netmong/domain/product/service/ProductService.java @@ -22,7 +22,7 @@ public interface ProductService { List findByProductCategory(Category category); - List findByProductName(String productName); + List findProductsByProductName(String productName); Page readPageByProduct(Pageable pageable); diff --git a/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java b/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java index a4eb040..686ecd6 100644 --- a/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java +++ b/src/main/java/com/ll/netmong/domain/product/service/ProductServiceImpl.java @@ -60,7 +60,7 @@ public List findByProductCategory(Category category) { } @Override - public List findByProductName(String productName) { + public List findProductsByProductName(String productName) { List products = productRepository.findByProductName(productName); if (products.isEmpty()) { throw new ProductException("존재 하지 않는 상품 이름 입니다.", ProductErrorCode.NOT_EXIST_PRODUCT_NAME); From 46654c35b3556ac61693b51ffcc75622938dd47d Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Sun, 14 Jan 2024 23:29:09 +0900 Subject: [PATCH 20/23] =?UTF-8?q?Feat=20:=20=EC=9C=A0=EC=A0=80=EC=9D=98=20?= =?UTF-8?q?=EC=9E=A5=EB=B0=94=EA=B5=AC=EB=8B=88=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EC=8B=9C=20N=20+=201=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/itemCart/repository/ItemCartRepository.java | 7 +++++++ .../domain/cart/itemCart/service/ItemCartServiceImpl.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ll/netmong/domain/cart/itemCart/repository/ItemCartRepository.java b/src/main/java/com/ll/netmong/domain/cart/itemCart/repository/ItemCartRepository.java index e11ff50..1600765 100644 --- a/src/main/java/com/ll/netmong/domain/cart/itemCart/repository/ItemCartRepository.java +++ b/src/main/java/com/ll/netmong/domain/cart/itemCart/repository/ItemCartRepository.java @@ -2,7 +2,14 @@ import com.ll.netmong.domain.cart.itemCart.entity.ItemCart; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; public interface ItemCartRepository extends JpaRepository { ItemCart findByCartIdAndProductId(Long cartId, Long productId); + + @Query("select ic from ItemCart ic join fetch ic.cart c join fetch c.member m join fetch ic.product where m.email = :email") + List findByMemberEmail(@Param("email")String findMemberEmail); } diff --git a/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java b/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java index 69b995d..623591b 100644 --- a/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java +++ b/src/main/java/com/ll/netmong/domain/cart/itemCart/service/ItemCartServiceImpl.java @@ -31,7 +31,7 @@ public class ItemCartServiceImpl implements ItemCartService { @Override public List readMemberCartByUser(String findMemberEmail) { - List findItemCart = itemCartRepository.findAll(); + List findItemCart = itemCartRepository.findByMemberEmail(findMemberEmail); List memberProducts = new ArrayList<>(); for (ItemCart itemCart : findItemCart) { From ec902469da9eb19e4601be03ebaf8236e530e265 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Mon, 15 Jan 2024 11:27:29 +0900 Subject: [PATCH 21/23] =?UTF-8?q?Refactor=20:=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20Index=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ll/netmong/domain/cart/entity/Cart.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java b/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java index 979c65c..ab2b631 100644 --- a/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java +++ b/src/main/java/com/ll/netmong/domain/cart/entity/Cart.java @@ -10,9 +10,7 @@ @Entity @Getter -@Table(name = "product_cart", indexes = { - @Index(name = "idx_member_id", columnList = "member_id") -}) +@Table(name = "product_cart") @NoArgsConstructor(access = AccessLevel.PROTECTED) @SuperBuilder(toBuilder = true) public class Cart extends BaseEntity { From 9796a0909e380ad4cc409b38497a24f819a0d134 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Mon, 15 Jan 2024 13:38:48 +0900 Subject: [PATCH 22/23] =?UTF-8?q?Refactor=20:=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EC=84=B1=20=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../netmong/domain/cart/dto/request/ProductCountRequest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/ll/netmong/domain/cart/dto/request/ProductCountRequest.java b/src/main/java/com/ll/netmong/domain/cart/dto/request/ProductCountRequest.java index 7f43ab1..520acf5 100644 --- a/src/main/java/com/ll/netmong/domain/cart/dto/request/ProductCountRequest.java +++ b/src/main/java/com/ll/netmong/domain/cart/dto/request/ProductCountRequest.java @@ -1,10 +1,14 @@ package com.ll.netmong.domain.cart.dto.request; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import lombok.Getter; import lombok.Setter; @Getter @Setter public class ProductCountRequest { + @Min(value = 1, message = "상품의 수량은 최소 1개 이상이어야 합니다.") + @Max(value = 30, message = "상품의 수량은 최대 30개까지 가능합니다.") private Integer count; } From e5124ab5dfc9a9d6fcfe6578952793806f42a2a1 Mon Sep 17 00:00:00 2001 From: shinjaewon99 Date: Mon, 15 Jan 2024 13:39:42 +0900 Subject: [PATCH 23/23] =?UTF-8?q?Refactor=20:=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=EC=8B=9C=20ResponseEntity=EB=A5=BC=20=EA=B0=90=EC=8B=BC?= =?UTF-8?q?=ED=9B=84=20return?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java b/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java index 3d12311..4eb9ffe 100644 --- a/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java +++ b/src/main/java/com/ll/netmong/domain/cart/controller/CartController.java @@ -2,13 +2,18 @@ import com.ll.netmong.common.RsData; import com.ll.netmong.domain.cart.dto.request.ProductCountRequest; +import com.ll.netmong.domain.cart.dto.response.ViewCartResponse; import com.ll.netmong.domain.cart.itemCart.service.ItemCartService; import com.ll.netmong.domain.cart.service.CartService; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequiredArgsConstructor @RequestMapping("api/v1/products/cart") @@ -18,23 +23,27 @@ public class CartController { private final ItemCartService itemCartService; @GetMapping - public RsData readProductCartByUser(@AuthenticationPrincipal UserDetails userDetails) { + public ResponseEntity readCartByUser(@AuthenticationPrincipal UserDetails userDetails) { String findMemberEmail = userDetails.getUsername(); - return RsData.successOf(itemCartService.readMemberCartByUser(findMemberEmail)); + RsData> responseBody = RsData.successOf(itemCartService.readMemberCartByUser(findMemberEmail)); + return ResponseEntity.ok(responseBody); } @PostMapping("{productId}") - public RsData addMyCart(@AuthenticationPrincipal UserDetails currentUser, + public ResponseEntity addProductToCart(@AuthenticationPrincipal UserDetails currentUser, @PathVariable(name = "productId") Long productId, @RequestBody ProductCountRequest productCountRequest) { cartService.addProductByCart(currentUser, productId, productCountRequest); - return RsData.of("S-1", CART_SUCCESS_PRODUCT, "create"); + RsData responseBody = RsData.of("S-1", CART_SUCCESS_PRODUCT, "create"); + return new ResponseEntity<>(responseBody, HttpStatus.CREATED); + } @DeleteMapping("{productId}") - public RsData deleteByProduct(@AuthenticationPrincipal UserDetails currentUser, + public ResponseEntity removeProductFromCart(@AuthenticationPrincipal UserDetails currentUser, @PathVariable(name = "productId") Long productId) { cartService.deleteByProduct(currentUser, productId); - return RsData.successOf("delete"); + RsData responseBody = RsData.successOf("delete"); + return ResponseEntity.ok(responseBody); } }