From 8344a67c42544b5472a542157a3afccf6809f652 Mon Sep 17 00:00:00 2001 From: Jaejun Lee <110995932+jooooonj@users.noreply.github.com> Date: Fri, 15 Sep 2023 19:13:37 +0900 Subject: [PATCH 01/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ef9d4082..4bea3329 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## ๐Ÿ‘– TrendPick, ์ทจํ–ฅ์— ๋งž๊ฒŒ ์ƒํ’ˆ์„ ์ถ”์ฒœ ํ•ด์ฃผ๋Š” ์„œ๋น„์Šค +## ๐Ÿ‘– TrendPick, ์ทจํ–ฅ์— ๋งž๊ฒŒ ์ƒํ’ˆ์„ ์ถ”์ฒœ ํ•ด์ฃผ๋Š” ์„œ๋น„์Šค

From 2d43ceb6afc3308f993657972d0fba044b557dcb Mon Sep 17 00:00:00 2001 From: Jaejun Lee <110995932+jooooonj@users.noreply.github.com> Date: Fri, 15 Sep 2023 19:14:26 +0900 Subject: [PATCH 02/14] Update work-2.yml --- .github/workflows/work-2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/work-2.yml b/.github/workflows/work-2.yml index 13e89225..edf5aa34 100644 --- a/.github/workflows/work-2.yml +++ b/.github/workflows/work-2.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: application-secret.yml ์ƒ์„ฑ + - name: application-secret.yml ์ƒ์„ฑํ•œ๋‹ค. env: ACTIONS_STEP_DEBUG: true APPLICATION_SECRET: ${{ secrets.APPLICATION_SECRET_YML }} From 131f1c8e872ec01f7ca60cffbf4adf7690b1f82f Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:29:36 +0900 Subject: [PATCH 03/14] =?UTF-8?q?refactor:=20=EC=A1=B0=ED=9A=8C=EC=88=98?= =?UTF-8?q?=20=EA=B0=B1=EC=8B=A0=20=EA=B8=B0=EB=8A=A5=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/basedata/BaseData.java | 6 --- .../global/kafka/view/entity/View.java | 23 ---------- .../kafka/view/repository/ViewRepository.java | 7 --- .../kafka/view/service/ViewService.java | 46 ------------------- 4 files changed, 82 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/global/kafka/view/entity/View.java delete mode 100644 src/main/java/project/trendpick_pro/global/kafka/view/repository/ViewRepository.java delete mode 100644 src/main/java/project/trendpick_pro/global/kafka/view/service/ViewService.java diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 99e63e21..93ea5dbd 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -24,7 +24,6 @@ import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.coupon.entity.expirationPeriod.ExpirationType; import project.trendpick_pro.domain.store.service.StoreService; -import project.trendpick_pro.global.kafka.view.service.ViewService; import project.trendpick_pro.domain.coupon.entity.Coupon; import project.trendpick_pro.domain.coupon.entity.dto.request.StoreCouponSaveRequest; import project.trendpick_pro.domain.coupon.repository.CouponRepository; @@ -99,7 +98,6 @@ CommandLineRunner initData( BrandService brandService, ProductService productService, StoreService storeService, - ViewService viewService, ProductRepository productRepository, ReviewRepository reviewRepository, CouponRepository couponRepository, @@ -138,10 +136,6 @@ public void run(String... args) { saveReviews(reviewCount, productCount, accessKeyMap, memberService, productService ,reviewRepository); saveStoreCoupon(couponCount, storeRepository, couponRepository, brandService); - if (viewService.findSize() == 0) { - viewService.registerView(); - } - log.info("BASE_DATA_SUCCESS"); } }; diff --git a/src/main/java/project/trendpick_pro/global/kafka/view/entity/View.java b/src/main/java/project/trendpick_pro/global/kafka/view/entity/View.java deleted file mode 100644 index 6366ce14..00000000 --- a/src/main/java/project/trendpick_pro/global/kafka/view/entity/View.java +++ /dev/null @@ -1,23 +0,0 @@ -package project.trendpick_pro.global.kafka.view.entity; - -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor -public class View { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private Long count = 0L; - - public void increment() { - this.count++; - } -} diff --git a/src/main/java/project/trendpick_pro/global/kafka/view/repository/ViewRepository.java b/src/main/java/project/trendpick_pro/global/kafka/view/repository/ViewRepository.java deleted file mode 100644 index d972c81c..00000000 --- a/src/main/java/project/trendpick_pro/global/kafka/view/repository/ViewRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package project.trendpick_pro.global.kafka.view.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.global.kafka.view.entity.View; - -public interface ViewRepository extends JpaRepository { -} diff --git a/src/main/java/project/trendpick_pro/global/kafka/view/service/ViewService.java b/src/main/java/project/trendpick_pro/global/kafka/view/service/ViewService.java deleted file mode 100644 index 37c417b2..00000000 --- a/src/main/java/project/trendpick_pro/global/kafka/view/service/ViewService.java +++ /dev/null @@ -1,46 +0,0 @@ -package project.trendpick_pro.global.kafka.view.service; - -import jakarta.servlet.http.HttpSession; -import lombok.RequiredArgsConstructor; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.global.kafka.view.entity.View; -import project.trendpick_pro.global.kafka.view.repository.ViewRepository; - -@Transactional(readOnly = true) -@Service -@RequiredArgsConstructor -public class ViewService { - - private final ViewRepository viewRepository; - - private final KafkaTemplate kafkaTemplate; - - @Transactional - public void registerView() { - viewRepository.save(new View()); - } - - public int findSize() { - return viewRepository.findAll().size(); - } - - @Async - public void requestIncrementViewCount(HttpSession session) { - if (session.getAttribute("visited") == null) { - kafkaTemplate.send("views", "increment", "1"); - session.setAttribute("visited", true); - } - } - - @Transactional - public void incrementViewCount(String viewId) { - viewRepository.findById(Long.valueOf(viewId)).get().increment(); - } - - public Long getCount() { - return viewRepository.findById(1L).get().getCount(); - } -} From 9a610faec74f23223c571052efce0f9590395bd8 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:39:26 +0900 Subject: [PATCH 04/14] =?UTF-8?q?refactor:=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EC=9D=98=20=EC=A3=BC=EB=AC=B8=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EC=83=9D=EC=84=B1=20=ED=95=A8=EC=88=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 --- .../common/controller/CommonController.java | 4 ---- .../domain/orders/entity/Order.java | 20 +++++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java b/src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java index 3aa7ec07..d759bb0f 100644 --- a/src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java +++ b/src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java @@ -6,18 +6,14 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.util.UriComponentsBuilder; -import project.trendpick_pro.global.kafka.view.service.ViewService; @Slf4j @Controller @RequiredArgsConstructor public class CommonController { - private final ViewService viewService; - @GetMapping("/") public String homePage(HttpSession session) { - viewService.requestIncrementViewCount(session); String mainCategory = "์ „์ฒด"; return "redirect:" + UriComponentsBuilder .fromPath("/trendpick/products/list") diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index b34dc0e5..8de538ac 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -39,7 +39,7 @@ public class Order extends BaseTimeEntity { @Enumerated(EnumType.STRING) private OrderStatus orderStatus; - @Column(name = "total_price", nullable = false) + @Column(name = "total_price") private int totalPrice = 0; public void connectUser(Member member) { @@ -49,7 +49,7 @@ public void connectUser(Member member) { public void connectPayment(String paymentMethod, String paymentKey) { this.paymentMethod = paymentMethod; this.paymentKey = paymentKey; - productDiscount(); + setDiscountAmount(); } public void connectDelivery(Delivery delivery) { @@ -66,6 +66,15 @@ public static Order createOrder(Member member, Delivery delivery, List orderItems) { + public void settingOrderItems(List orderItems) { for (OrderItem orderItem : orderItems) { this.addOrderItem(orderItem); this.totalPrice += orderItem.getTotalPrice(); From 60f3172d1efeea53dce220700fa894114df3fee2 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:40:16 +0900 Subject: [PATCH 05/14] =?UTF-8?q?refactor:=20orderItem=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=EC=97=90=EC=84=9C=20=EC=9E=AC=EA=B3=A0=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/entity/OrderItem.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index fd7bcfec..df3d1378 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -8,6 +8,7 @@ import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.coupon.entity.CouponCard; import project.trendpick_pro.domain.product.entity.product.Product; +import project.trendpick_pro.domain.product.exception.ProductStockOutException; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -69,21 +70,19 @@ public void connectOrder(Order order) { public void applyCouponCard(CouponCard couponCard) { this.couponCard = couponCard; int discountPercent = couponCard.getCoupon().getDiscountPercent(); - int price = getOrderPrice() * discountPercent / 100; //์ฟ ํฐ์€ ์ƒํ’ˆ ํ•œ ๊ฐœ ๊ฐ€๊ฒฉ์—์„œ ํ• ์ธ ์ ์šฉ - discount(price); + this.discountPrice = getOrderPrice() * discountPercent / 100; //์ฟ ํฐ์€ ์ƒํ’ˆ ํ•œ ๊ฐœ ๊ฐ€๊ฒฉ์—์„œ ํ• ์ธ ์ ์šฉ + this.totalPrice -= this.discountPrice; } public void cancelCouponCard(){ this.couponCard = null; + this.totalPrice += this.discountPrice; this.discountPrice = 0; } - private void discount(int price){ - this.discountPrice += price; - this.totalPrice -= this.discountPrice; - } - private OrderItem(Product product, int quantity, String size, String color) { + if(product.getProductOption().getStock() < quantity) + throw new ProductStockOutException("์ƒํ’ˆ์˜ ์žฌ๊ณ ๊ฐ€ ๋ถ€์กฑํ•˜์—ฌ ์ฃผ๋ฌธ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); this.product = product; this.orderPrice = (product.getDiscountedPrice() > 0) ? product.getDiscountedPrice() : product.getProductOption().getPrice(); this.quantity = quantity; From 7e8e03ae38c0fd6f6f2119021a5c457a7e6510f4 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:49:05 +0900 Subject: [PATCH 06/14] =?UTF-8?q?refactor:=20=EC=A3=BC=EB=AC=B8=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EC=9D=98=20=EC=83=81=ED=83=9C=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=B2=98=EB=A6=AC=20(=EC=9E=84=EC=8B=9C?= =?UTF-8?q?=20=EC=A3=BC=EB=AC=B8=20=EC=82=AD=EC=A0=9C,=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=B2=98=EB=A6=AC=20=EB=B0=A9=EC=A7=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/contoller/OrderController.java | 6 +++++- .../domain/orders/repository/OrderRepository.java | 10 ++++++++++ .../job/cancelOrderJobConfig/CancelOrderJobConfig.java | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index b2a6622c..cb380d30 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -7,6 +7,7 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.dto.request.CartToOrderRequest; import project.trendpick_pro.domain.orders.entity.dto.request.ProductOrderRequest; import project.trendpick_pro.domain.orders.entity.dto.response.OrderDetailResponse; @@ -28,7 +29,10 @@ public class OrderController { @PreAuthorize("hasAuthority({'MEMBER'})") @GetMapping("{orderId}/form") public String showOrderForm(@PathVariable("orderId") Long orderId, Model model){ - model.addAttribute("order", orderService.findById(orderId)); + Order order = orderService.findById(orderId); + if(order.getPaymentKey() != null || order.getOrderState().equals("์ฃผ๋ฌธ์ทจ์†Œ")) + return rq.redirectWithMsg("/", "์ด๋ฏธ ์ฒ˜๋ฆฌ๋œ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค."); + model.addAttribute("order", order); return "trendpick/orders/order-form"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index d72dbd7f..738a4923 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -1,7 +1,17 @@ package project.trendpick_pro.domain.orders.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import project.trendpick_pro.domain.orders.entity.Order; +import java.time.LocalDateTime; +import java.util.List; + public interface OrderRepository extends JpaRepository, OrderRepositoryCustom { + + @Query("SELECT o FROM Order o " + + "WHERE o.paymentKey IS NULL " + + "AND o.createdDate < :date") + List findAllByPaymentKeyIsNullAndCreatedDateIsBefore(@Param("date") LocalDateTime date); } diff --git a/src/main/java/project/trendpick_pro/global/job/cancelOrderJobConfig/CancelOrderJobConfig.java b/src/main/java/project/trendpick_pro/global/job/cancelOrderJobConfig/CancelOrderJobConfig.java index 21b834b8..db3d0df6 100644 --- a/src/main/java/project/trendpick_pro/global/job/cancelOrderJobConfig/CancelOrderJobConfig.java +++ b/src/main/java/project/trendpick_pro/global/job/cancelOrderJobConfig/CancelOrderJobConfig.java @@ -71,9 +71,9 @@ public RepositoryItemReader orderReader( return new RepositoryItemReaderBuilder() .name("orderReader") .repository(orderRepository) - .methodName("findAllByStatusAndCreatedDateIsBefore") + .methodName("findAllByPaymentKeyIsNullAndCreatedDateIsBefore") .pageSize(100) - .arguments(Arrays.asList(OrderStatus.TEMP, date)) + .arguments(Arrays.asList(date)) .sorts(Collections.singletonMap("id", Sort.Direction.ASC)) .build(); } From 0877564c639490f7955cd2909366a0dc8df9b900 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:50:39 +0900 Subject: [PATCH 07/14] =?UTF-8?q?refactor:=20OrderService=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=95=EB=A6=AC=20/=20OrderMaterial=20=EB=8F=84?= =?UTF-8?q?=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/service/OrderService.java | 3 +- .../orders/service/impl/OrderServiceImpl.java | 165 ++++++++---------- .../kafka/outbox/entity/OrderMaterial.java | 37 ++++ 3 files changed, 107 insertions(+), 98 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OrderMaterial.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 8b79a6c0..6f6ee020 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -8,6 +8,7 @@ import project.trendpick_pro.domain.orders.entity.dto.request.CartToOrderRequest; import project.trendpick_pro.domain.orders.entity.dto.response.OrderDetailResponse; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; +import project.trendpick_pro.global.kafka.outbox.entity.OrderMaterial; import project.trendpick_pro.global.util.rsData.RsData; import java.time.LocalDate; @@ -17,7 +18,7 @@ public interface OrderService { RsData cartToOrder(Member member, CartToOrderRequest request); RsData productToOrder(Member member, Long id, int quantity, String size, String color); - void tryOrder(String id) throws JsonProcessingException; + void tryOrder(String id, List orderMaterials) throws JsonProcessingException; RsData cancel(Long orderId); void delete(Long id); RsData findOrderItems(Member member, Long orderId); diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/impl/OrderServiceImpl.java b/src/main/java/project/trendpick_pro/domain/orders/service/impl/OrderServiceImpl.java index 76adb52b..eff83baf 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/impl/OrderServiceImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/impl/OrderServiceImpl.java @@ -1,13 +1,12 @@ package project.trendpick_pro.domain.orders.service.impl; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.Nullable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; -import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.CartItem; @@ -21,23 +20,17 @@ import project.trendpick_pro.domain.orders.entity.OrderStatus; import project.trendpick_pro.domain.orders.entity.dto.request.CartToOrderRequest; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; -import project.trendpick_pro.domain.orders.entity.dto.request.OrderStateResponse; import project.trendpick_pro.domain.orders.entity.dto.response.OrderDetailResponse; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.exception.OrderNotFoundException; import project.trendpick_pro.domain.orders.repository.OrderItemRepository; import project.trendpick_pro.domain.orders.repository.OrderRepository; import project.trendpick_pro.domain.orders.service.OrderService; -import project.trendpick_pro.domain.product.entity.product.Product; -import project.trendpick_pro.domain.product.entity.productOption.ProductOption; -import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.exception.ProductStockOutException; import project.trendpick_pro.domain.product.service.ProductService; -import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; -import project.trendpick_pro.domain.tags.tag.entity.TagType; import project.trendpick_pro.global.kafka.KafkaProducerService; -import project.trendpick_pro.global.kafka.kafkasave.entity.OutboxMessage; -import project.trendpick_pro.global.kafka.kafkasave.service.OutboxMessageService; +import project.trendpick_pro.global.kafka.outbox.entity.OrderMaterial; +import project.trendpick_pro.global.kafka.outbox.service.OutboxMessageService; import project.trendpick_pro.global.util.rsData.RsData; import java.time.LocalDate; @@ -59,76 +52,60 @@ public class OrderServiceImpl implements OrderService { private final CartService cartService; private final ProductService productService; - private final FavoriteTagService favoriteTagService; - private final OutboxMessageService outboxMessageService; - private final KafkaProducerService kafkaProducerService; @Transactional public RsData cartToOrder(Member member, CartToOrderRequest request) { - if(member.getAddress().trim().isEmpty()) { - return RsData.of("F-1", "์ฃผ์†Œ๋ฅผ ์•Œ ์ˆ˜ ์—†์–ด ์ฃผ๋ฌธ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); - } - if(request.getSelectedItems().isEmpty()){ - return RsData.of("F-1","์ƒํ’ˆ์„ ์„ ํƒํ•œ ํ›„ ์ฃผ๋ฌธํ•ด์ฃผ์„ธ์š”."); - } List cartItems = cartService.getSelectedCartItems(member, request); - if (!Objects.equals(cartItems.get(0).getCart().getMember().getId(), member.getId())) { - return RsData.of("F-1", "ํ˜„์žฌ ์ ‘์†์ค‘์ธ ์‚ฌ์šฉ์ž์™€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ฌ์šฉ์ž๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); - } - Order order = createOrder(member, cartItems); + RsData result = validateCartToOrder(member, request, cartItems); + if (result.isFail()) return result; - OutboxMessage message = createOutboxMessage(order); - kafkaProducerService.sendMessage(message.getId()); + Order order = orderRepository.save(Order.createTempOrder(member, new Delivery(member.getAddress()))); + String uuidCode = UUID.randomUUID().toString(); + + List orderMaterials = new ArrayList<>(); + for (CartItem cartItem : cartItems) + orderMaterials.add(new OrderMaterial(cartItem, uuidCode)); + outboxMessageService.publishOrderCreationMessage("orders", String.valueOf(order.getId()), orderMaterials, uuidCode); return RsData.of("S-1", "์ฃผ๋ฌธ์„ ์‹œ์ž‘ ํ•ฉ๋‹ˆ๋‹ค."); } @Transactional public RsData productToOrder(Member member, Long productId, int quantity, String size, String color) { - try { - Order saveOrder = orderRepository.save( - Order.createOrder(member, new Delivery(member.getAddress()), - List.of(OrderItem.of(productService.findById(productId), quantity, size, color)) - ) - ); - log.info("์žฌ๊ณ  : {}", saveOrder.getOrderItems().get(0).getProduct().getProductOption().getStock()); - OutboxMessage message = createOutboxMessage(saveOrder); - kafkaProducerService.sendMessage(message.getId()); - return RsData.of("S-1", "์ฃผ๋ฌธ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค."); - } catch (ProductNotFoundException e) { - return RsData.of("F-1", "์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ƒํ’ˆ์ž…๋‹ˆ๋‹ค."); - } + String uuidCode = UUID.randomUUID().toString(); + + Order order = orderRepository.save( + Order.createTempOrder(member, new Delivery(member.getAddress()))); + + List orderMaterials = List.of(new OrderMaterial(productId, quantity, size, color, uuidCode)); + outboxMessageService.publishOrderCreationMessage("orders", String.valueOf(order.getId()), orderMaterials, uuidCode); + return RsData.of("S-1", "์ฃผ๋ฌธ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค."); } - @Transactional - public void tryOrder(String id) throws JsonProcessingException { - Order order = orderRepository.findById(Long.parseLong(id)) - .orElseThrow(() -> new OrderNotFoundException("์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ฃผ๋ฌธ ์ž…๋‹ˆ๋‹ค.")); - String email = order.getMember().getEmail(); - try { + @Transactional //์‹ค์ œ ์ฃผ๋ฌธ ๋กœ์ง (์žฌ๊ณ  ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ์žฌ๊ณ  ๊ฐ์†Œ, ์ƒํƒœ ๋ณ€๊ฒฝ) + public void tryOrder(String id, List orderMaterials) throws JsonProcessingException { + Order order = findById(Long.valueOf(id)); + if(order.getOrderState().equals("๊ฒฐ์ œ์™„๋ฃŒ")) //๋ฉฑ๋“ฑ์„ฑ + throw new IllegalAccessError("์ด๋ฏธ ์ฒ˜๋ฆฌ๋œ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค."); + + try{ + List orderItems = OrderMaterialsToOrderItems(orderMaterials); + order.settingOrderItems(orderItems); order.updateStatus(OrderStatus.ORDERED); - sendMessage(order.getId(), "Success", email); - } catch (ProductStockOutException e) { - if (order.getOrderStatus() == OrderStatus.TEMP) { - order.cancelTemp(); - } - log.error("์ฃผ๋ฌธ ์‹คํŒจ : {}", e.getMessage()); - sendMessage(order.getId(), "Fail", email); + outboxMessageService.publishOrderProcessMessage("standByOrder", "Success", String.valueOf(order.getId()), order.getMember().getEmail()); + } catch(ProductStockOutException e){ + log.error("error message : {} ", e.getMessage()); + kafkaProducerService.sendOrderProcessFailMessage(order.getId(), "Fail", order.getMember().getEmail()); } } @Transactional public RsData cancel(Long orderId) { - Order order = orderRepository.findById(orderId).orElseThrow(() -> new OrderNotFoundException("์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค.")); - if(order.getOrderStatus() == OrderStatus.CANCELED) { - return RsData.of("F-1", "์ด๋ฏธ ์ทจ์†Œ๋œ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค."); - } else if (order.getDelivery().getState() == DeliveryState.COMPLETED) { - return RsData.of("F-2", "์ด๋ฏธ ๋ฐฐ์†ก์™„๋ฃŒ๋œ ์ƒํ’ˆ์€ ์ทจ์†Œ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); - } - if (order.getDelivery().getState() == DeliveryState.DELIVERY_ING) { - return RsData.of("F-3", "์ด๋ฏธ ๋ฐฐ์†ก์„ ์‹œ์ž‘ํ•˜์—ฌ ์ทจ์†Œ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); - } + Order order = findById(orderId); + RsData result = validateAvailableCancel(order); + if (result.isFail()) return result; + order.cancel(); return RsData.of("S-1", "ํ™˜๋ถˆ ์š”์ฒญ์ด ์ •์ƒ์ ์œผ๋กœ ์ง„ํ–‰ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ™˜๋ถˆ๊นŒ์ง€๋Š” ์ตœ์†Œ 2์ผ์—์„œ ์ตœ๋Œ€ 14์ผ๊นŒ์ง€ ์†Œ์š”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."); } @@ -143,7 +120,6 @@ public RsData findOrderItems(Member member, Long orderId) { try { Order order = orderRepository.findById(orderId).orElseThrow(() -> new OrderNotFoundException("์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ฃผ๋ฌธ ์ž…๋‹ˆ๋‹ค.")); if (order.getOrderStatus() == OrderStatus.TEMP) { - orderRepository.delete(order); return RsData.of("F-3", "์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค."); } if (!Objects.equals(order.getMember().getId(), member.getId())) { @@ -180,41 +156,6 @@ public List findAllByCreatedDateBetweenOrderByIdAsc(LocalDateTime fro return orderItemRepository.findAllByCreatedDateBetween(fromDate, toDate); } - private Order createOrder(Member member, List cartItems) { - List orderItems = createOrderItem(member, cartItems); - Order order = Order.createOrder(member, new Delivery(member.getAddress()), orderItems); - return orderRepository.save(order); - } - - private List createOrderItem(Member member, List cartItems) { - List orderItems = new ArrayList<>(); - for (CartItem cartItem : cartItems) { - Product product = checkingProductStock(cartItem); - favoriteTagService.updateTag(member, product, TagType.ORDER); - orderItems.add(OrderItem.of(product, cartItem)); - } - return orderItems; - } - - private Product checkingProductStock(CartItem cartItem) { - Product product = productService.findById(cartItem.getProduct().getId()); - if (product.getProductOption().getStock() < cartItem.getQuantity()) { - throw new ProductStockOutException("์žฌ๊ณ ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค."); - } - return product; - } - - private OutboxMessage createOutboxMessage(Order order) { - OutboxMessage message = new OutboxMessage("orders", - String.valueOf(order.getId()), String.valueOf(order.getId())); - outboxMessageService.save(message); - return message; - } - - private void sendMessage(Long orderId, String message, String email) throws JsonProcessingException { - kafkaProducerService.sendMessage(orderId, message, email); - } - private Page settingOrderByMemberStatus(Member member, int offset) { Page findOrders; PageRequest pageable = PageRequest.of(offset, 10); @@ -228,9 +169,39 @@ private Page settingOrderByMemberStatus(Member member, int offset return findOrders; } - private static List checkingTempStatus(Page findOrders) { + private List checkingTempStatus(Page findOrders) { return findOrders.stream() .filter(orderResponse -> !Objects.equals(orderResponse.getOrderStatus(), OrderStatus.TEMP.toString())) .collect(Collectors.toList()); } + + private RsData validateCartToOrder(Member member, CartToOrderRequest request, List cartItems) { + if(member.getAddress().trim().isEmpty()) + return RsData.of("F-1", "์ฃผ์†Œ๋ฅผ ์•Œ ์ˆ˜ ์—†์–ด ์ฃผ๋ฌธ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); + + if(request.getSelectedItems().isEmpty()) + return RsData.of("F-1", "์ƒํ’ˆ์„ ์„ ํƒํ•œ ํ›„ ์ฃผ๋ฌธํ•ด์ฃผ์„ธ์š”."); + + if (!Objects.equals(cartItems.get(0).getCart().getMember().getId(), member.getId())) + return RsData.of("F-1", "ํ˜„์žฌ ์ ‘์†์ค‘์ธ ์‚ฌ์šฉ์ž์™€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ฌ์šฉ์ž๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + return RsData.success(); + } + + private List OrderMaterialsToOrderItems(List orderMaterials) throws ProductStockOutException{ + List orderItems = new ArrayList<>(); + for (OrderMaterial orderMaterial : orderMaterials) { //์ด๋•Œ ์žฌ๊ณ  ๊ฐ์†Œ, ์žฌ๊ณ  ์ฒดํฌ + orderItems.add(OrderItem.of(productService.findById(orderMaterial.getProductId()), orderMaterial.getQuantity(), + orderMaterial.getSize(), orderMaterial.getColor())); + } + return orderItems; + } + + private RsData validateAvailableCancel(Order order) { + if(order.getOrderStatus() == OrderStatus.CANCELED) + return RsData.of("F-1", "์ด๋ฏธ ์ทจ์†Œ๋œ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค."); + + if (order.getDelivery().getState() == DeliveryState.DELIVERY_ING) + return RsData.of("F-3", "์ด๋ฏธ ๋ฐฐ์†ก์„ ์‹œ์ž‘ํ•˜์—ฌ ์ทจ์†Œ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); + return RsData.success(); + } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OrderMaterial.java b/src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OrderMaterial.java new file mode 100644 index 00000000..a20e7bc7 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OrderMaterial.java @@ -0,0 +1,37 @@ +package project.trendpick_pro.global.kafka.outbox.entity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.cart.entity.CartItem; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Entity +public class OrderMaterial { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private Long productId; + private Integer quantity; + private String size; + private String color; + private String code; + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "outbox_message_id") + private OutboxMessage outboxMessage; + + public OrderMaterial(Long productId, Integer quantity, String size, String color, String code) { + this.productId = productId; + this.quantity = quantity; + this.size = size; + this.color = color; + this.code = code; + } + + public OrderMaterial(CartItem cartItem, String code){ + new OrderMaterial(cartItem.getProduct().getId(), cartItem.getQuantity(), cartItem.getSize(), cartItem.getColor(), code); + } +} From 3cd2e80c5450bc1b186c562d0fca423a8f10813e Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:51:50 +0900 Subject: [PATCH 08/14] =?UTF-8?q?refactor:=20=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EB=B0=95=EC=8A=A4=20=ED=8C=A8=ED=84=B4=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EC=9A=A9=EB=8F=84=20=EB=B3=80=EA=B2=BD=20(=ED=8A=B8=EB=9E=9C?= =?UTF-8?q?=EC=9E=AD=EC=85=98=20=EB=AC=B6=EA=B8=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/kafka/KafkaProducerService.java | 66 +++++++++++++++---- .../kafka/kafkasave/entity/OutboxMessage.java | 29 -------- .../repository/OutboxMessageRepository.java | 7 -- .../service/OutboxMessageService.java | 31 --------- .../kafka/outbox/entity/OutboxMessage.java | 55 ++++++++++++++++ .../repository/OutboxMessageRepository.java | 16 +++++ .../outbox/service/OutboxMessageService.java | 56 ++++++++++++++++ 7 files changed, 180 insertions(+), 80 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/global/kafka/kafkasave/entity/OutboxMessage.java delete mode 100644 src/main/java/project/trendpick_pro/global/kafka/kafkasave/repository/OutboxMessageRepository.java delete mode 100644 src/main/java/project/trendpick_pro/global/kafka/kafkasave/service/OutboxMessageService.java create mode 100644 src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OutboxMessage.java create mode 100644 src/main/java/project/trendpick_pro/global/kafka/outbox/repository/OutboxMessageRepository.java create mode 100644 src/main/java/project/trendpick_pro/global/kafka/outbox/service/OutboxMessageService.java diff --git a/src/main/java/project/trendpick_pro/global/kafka/KafkaProducerService.java b/src/main/java/project/trendpick_pro/global/kafka/KafkaProducerService.java index b3708125..536c0725 100644 --- a/src/main/java/project/trendpick_pro/global/kafka/KafkaProducerService.java +++ b/src/main/java/project/trendpick_pro/global/kafka/KafkaProducerService.java @@ -6,13 +6,15 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.retry.support.RetryTemplate; -import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.orders.entity.dto.request.OrderStateResponse; -import project.trendpick_pro.global.kafka.kafkasave.entity.OutboxMessage; -import project.trendpick_pro.global.kafka.kafkasave.service.OutboxMessageService; +import project.trendpick_pro.global.kafka.outbox.entity.OutboxMessage; +import project.trendpick_pro.global.kafka.outbox.service.OutboxMessageService; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; @Slf4j @@ -28,12 +30,47 @@ public class KafkaProducerService { private final ObjectMapper objectMapper; @Transactional - public void sendMessage(Long id) { - OutboxMessage outboxMessage = outboxMessageService.findById(id); + @Scheduled(fixedRate = 3000) //3์ดˆ๋งˆ๋‹ค ์•„์›ƒ๋ฐ•์Šค๋ฅผ ์กฐํšŒํ•˜๋ฉฐ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค. + public void sendMessage() throws JsonProcessingException { + List outboxMessages = outboxMessageService.findAll(); + + List completedMessages = new ArrayList<>(); + for (OutboxMessage outboxMessage : outboxMessages) { + if(outboxMessage.getTopic().equals("standByOrder")) //์ฃผ๋ฌธ ์ฒ˜๋ฆฌ ์„ฑ๊ณต ๋ฉ”์‹œ์ง€ + sendOrderProcessSuccessMessage(completedMessages, outboxMessage); + + else if(outboxMessage.getTopic().equals("orders")) + sendCompleteOrderCreationMessage(completedMessages, outboxMessage); //์ฃผ๋ฌธ ๊ฐ์ฒด ์ƒ์„ฑ ์™„๋ฃŒ ๋ฉ”์‹œ์ง€ + } + + if(!completedMessages.isEmpty()) + outboxMessageService.deleteAllById(completedMessages); + } + + private void sendCompleteOrderCreationMessage(List completedMessages, OutboxMessage outboxMessage) { retryTemplate.execute(context -> { - kafkaTemplate.send(outboxMessage.getTopic(), outboxMessage.getPayload(), outboxMessage.getMessage()); - log.info("Message sent: {}", outboxMessage.getMessage()); - outboxMessageService.delete(outboxMessage); + kafkaTemplate.send(outboxMessage.getTopic(), outboxMessage.getPayload(), outboxMessage.getCode()); + outboxMessage.disconnectOrderMaterial(); + completedMessages.add(outboxMessage.getId()); + log.info("Message sent: {}", outboxMessage.getMessage()); + return null; + }, context -> { + log.error("Failed to send message: {}", context.getLastThrowable().getMessage()); + return null; + }); + } + + @Transactional + public void sendOrderProcessFailMessage(Long orderId, String message, String email) throws JsonProcessingException { + OrderStateResponse response = OrderStateResponse.builder() + .orderId(orderId) + .message(message) + .email(email) + .build(); + String json = objectMapper.writeValueAsString(response); + retryTemplate.execute(context -> { + kafkaTemplate.send("standByOrder", UUID.randomUUID().toString(), json); + log.info("Message sent: {}", message); return null; }, context -> { log.error("Failed to send message: {}", context.getLastThrowable().getMessage()); @@ -42,20 +79,23 @@ public void sendMessage(Long id) { } @Transactional - public void sendMessage(Long orderId, String message, String email) throws JsonProcessingException { + public void sendOrderProcessSuccessMessage(List completedMessages, OutboxMessage outboxMessage) throws JsonProcessingException { OrderStateResponse response = OrderStateResponse.builder() - .orderId(orderId) - .message(message) - .email(email) + .orderId(Long.valueOf(outboxMessage.getPayload())) + .message(outboxMessage.getMessage()) + .email( outboxMessage.getEmail()) .build(); String json = objectMapper.writeValueAsString(response); retryTemplate.execute(context -> { kafkaTemplate.send("standByOrder", UUID.randomUUID().toString(), json); - log.info("Message sent: {}", message); + completedMessages.add(outboxMessage.getId()); + log.info("Message sent: {}", outboxMessage.getMessage()); return null; }, context -> { log.error("Failed to send message: {}", context.getLastThrowable().getMessage()); return null; }); } + + } diff --git a/src/main/java/project/trendpick_pro/global/kafka/kafkasave/entity/OutboxMessage.java b/src/main/java/project/trendpick_pro/global/kafka/kafkasave/entity/OutboxMessage.java deleted file mode 100644 index 448da8fa..00000000 --- a/src/main/java/project/trendpick_pro/global/kafka/kafkasave/entity/OutboxMessage.java +++ /dev/null @@ -1,29 +0,0 @@ -package project.trendpick_pro.global.kafka.kafkasave.entity; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) -public class OutboxMessage { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "topic", nullable = false) - private String topic; - - @Column(name = "message", nullable = false) - private String message; - - @Column(name = "payload", nullable = false) - private String payload; - - public OutboxMessage(String topic, String message, String payload) { - this.topic = topic; - this.message = message; - this.payload = payload; - } -} diff --git a/src/main/java/project/trendpick_pro/global/kafka/kafkasave/repository/OutboxMessageRepository.java b/src/main/java/project/trendpick_pro/global/kafka/kafkasave/repository/OutboxMessageRepository.java deleted file mode 100644 index 5b97efb9..00000000 --- a/src/main/java/project/trendpick_pro/global/kafka/kafkasave/repository/OutboxMessageRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package project.trendpick_pro.global.kafka.kafkasave.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.global.kafka.kafkasave.entity.OutboxMessage; - -public interface OutboxMessageRepository extends JpaRepository { -} diff --git a/src/main/java/project/trendpick_pro/global/kafka/kafkasave/service/OutboxMessageService.java b/src/main/java/project/trendpick_pro/global/kafka/kafkasave/service/OutboxMessageService.java deleted file mode 100644 index 89bb9b1e..00000000 --- a/src/main/java/project/trendpick_pro/global/kafka/kafkasave/service/OutboxMessageService.java +++ /dev/null @@ -1,31 +0,0 @@ -package project.trendpick_pro.global.kafka.kafkasave.service; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.global.kafka.kafkasave.entity.OutboxMessage; -import project.trendpick_pro.global.kafka.kafkasave.repository.OutboxMessageRepository; - -import java.util.List; - -@Service -@RequiredArgsConstructor -public class OutboxMessageService { - - private final OutboxMessageRepository outboxMessageRepository; - - @Transactional - public void save(OutboxMessage outboxMessage) { - outboxMessageRepository.save(outboxMessage); - } - - @Transactional - public void delete(OutboxMessage outboxMessage) { - outboxMessageRepository.delete(outboxMessage); - } - - @Transactional(readOnly = true) - public OutboxMessage findById(Long id) { - return outboxMessageRepository.findById(id).get(); - } -} diff --git a/src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OutboxMessage.java b/src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OutboxMessage.java new file mode 100644 index 00000000..c739f7b1 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/kafka/outbox/entity/OutboxMessage.java @@ -0,0 +1,55 @@ +package project.trendpick_pro.global.kafka.outbox.entity; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; +import project.trendpick_pro.domain.product.entity.product.Product; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class OutboxMessage { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "topic", nullable = false) + private String topic; + + @Column(name = "message", nullable = false) + private String message; + + @Column(name = "payload", nullable = false) + private String payload; + + private String code; + + private String email; + + @OneToMany(mappedBy = "outboxMessage", cascade = CascadeType.PERSIST) + private List orderMaterials = new ArrayList<>(); + + public void disconnectOrderMaterial(){ + this.orderMaterials = null; + } + + public OutboxMessage (String topic, String message, String payload, + List orderMaterial, String code) { + this.topic = topic; + this.message = message; + this.payload = payload; + this.orderMaterials = orderMaterial; + this.code = code; + } + + public OutboxMessage (String topic, String message, String payload, String email) { + this.topic = topic; + this.message = message; + this.payload = payload; + this.email = email; + } +} diff --git a/src/main/java/project/trendpick_pro/global/kafka/outbox/repository/OutboxMessageRepository.java b/src/main/java/project/trendpick_pro/global/kafka/outbox/repository/OutboxMessageRepository.java new file mode 100644 index 00000000..14bb6975 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/kafka/outbox/repository/OutboxMessageRepository.java @@ -0,0 +1,16 @@ +package project.trendpick_pro.global.kafka.outbox.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import project.trendpick_pro.global.kafka.outbox.entity.OrderMaterial; +import project.trendpick_pro.global.kafka.outbox.entity.OutboxMessage; + +import java.util.List; +import java.util.Optional; + +public interface OutboxMessageRepository extends JpaRepository { + + @Query("select o from OrderMaterial o where o.code = :code") + List findAllOrderMaterialByCode(@Param("code") String code); +} diff --git a/src/main/java/project/trendpick_pro/global/kafka/outbox/service/OutboxMessageService.java b/src/main/java/project/trendpick_pro/global/kafka/outbox/service/OutboxMessageService.java new file mode 100644 index 00000000..cd9f802e --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/kafka/outbox/service/OutboxMessageService.java @@ -0,0 +1,56 @@ +package project.trendpick_pro.global.kafka.outbox.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.orders.entity.Order; +import project.trendpick_pro.global.kafka.outbox.entity.OrderMaterial; +import project.trendpick_pro.global.kafka.outbox.entity.OutboxMessage; +import project.trendpick_pro.global.kafka.outbox.repository.OutboxMessageRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class OutboxMessageService { + + private final OutboxMessageRepository outboxMessageRepository; + + public OutboxMessage findById(Long id) { + return outboxMessageRepository.findById(id).get(); + } + + public List findAll() { + return outboxMessageRepository.findAll(); + } + + @Transactional + public void save(OutboxMessage outboxMessage) { + outboxMessageRepository.save(outboxMessage); + } + + @Transactional + public void delete(OutboxMessage outboxMessage) { + outboxMessageRepository.delete(outboxMessage); + } + + @Transactional + public void deleteAllById(List completedMessages) { + outboxMessageRepository.deleteAllById(completedMessages); + } + + public List findOrderMaterial(String code){ + return outboxMessageRepository.findAllOrderMaterialByCode(code); + } + + //์ฃผ๋ฌธ ๊ฐ์ณ‰ ์ƒ์„ฑ ๋ฉ”์‹œ์ง€ ๋ฐœํ–‰ + public void publishOrderCreationMessage(String topic, String key, List orderMaterials, String code) { + outboxMessageRepository.save(new OutboxMessage(topic, key, key, orderMaterials, code)); + } + + //์ฃผ๋ฌธ ์ฒ˜๋ฆฌ ๋ฉ”์‹œ์ง€ ๋ฐœํ–‰ + public void publishOrderProcessMessage(String topic, String message, String payload, String email) { + outboxMessageRepository.save(new OutboxMessage(topic, message, payload, email)); + } +} From 3c5c4f938a6f5676d757a019d79a3d40bd99e3d7 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:54:21 +0900 Subject: [PATCH 09/14] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=B8=EC=A7=80?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20/=20=EB=B6=84=EC=82=B0=20=EB=9D=BD=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20(=EC=A3=BC=EB=AC=B8=20->=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EC=83=81=ED=92=88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 6 -- .../global/kafka/KafkaConsumerService.java | 18 ++---- .../redisson/service/RedissonService.java | 59 ++++++++++++++----- .../templates/trendpick/products/list.html | 5 -- 4 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 68067a0f..ef0301f8 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -20,7 +20,6 @@ import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.global.basedata.tagname.service.impl.TagNameServiceImpl; import project.trendpick_pro.global.util.rq.Rq; -import project.trendpick_pro.global.kafka.view.service.ViewService; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.product.entity.dto.ProductRequest; @@ -60,8 +59,6 @@ public class ProductController { private final ReviewService reviewService; private final AskService askService; - private final ViewService viewService; - private final Rq rq; @Value("${colors}") @@ -133,8 +130,6 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i @RequestParam(value = "main-category", defaultValue = "all") String mainCategory, @RequestParam(value = "sub-category", defaultValue = "์ „์ฒด") String subCategory, Pageable pageable, Model model, HttpSession session) { - viewService.requestIncrementViewCount(session); - model.addAttribute("totalView", viewService.getCount()); if (mainCategory.equals("recommend")) { mainCategory = "์ถ”์ฒœ"; } else if (mainCategory.equals("all")) { @@ -179,7 +174,6 @@ public String showAllProductBySeller(@RequestParam("page") int offset, Model mod @GetMapping("/keyword") public String searchQuery(@RequestParam String keyword, @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { Page products = productService.findAllByKeyword(keyword, offset); - model.addAttribute("totalView", viewService.getCount()); model.addAttribute("keyword", keyword); model.addAttribute("productResponses", products); return "trendpick/products/list"; diff --git a/src/main/java/project/trendpick_pro/global/kafka/KafkaConsumerService.java b/src/main/java/project/trendpick_pro/global/kafka/KafkaConsumerService.java index 12f9b3ec..14134d0d 100644 --- a/src/main/java/project/trendpick_pro/global/kafka/KafkaConsumerService.java +++ b/src/main/java/project/trendpick_pro/global/kafka/KafkaConsumerService.java @@ -10,8 +10,8 @@ import org.springframework.messaging.handler.annotation.Payload; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service; +import project.trendpick_pro.domain.orders.service.OrderService; import project.trendpick_pro.global.redis.redisson.service.RedissonService; -import project.trendpick_pro.global.kafka.view.service.ViewService; import project.trendpick_pro.domain.orders.entity.dto.request.OrderStateResponse; @Slf4j @@ -20,19 +20,18 @@ public class KafkaConsumerService { private final RedissonService redissonService; - private final ViewService viewService; - private final SimpMessagingTemplate messagingTemplate; private final ObjectMapper objectMapper; - + private final OrderService orderService; @KafkaListener(topics = "orders", groupId = "order") public void orderToOrder(ConsumerRecord message, Acknowledgment ack) { try { - redissonService.processOrderWithLock(message.key()); - ack.acknowledge(); + redissonService.processOrderWithLock(message.key(), message.value()); } catch (Exception e) { - log.error(e.getMessage()); + log.error("orderToOrder process error : {} ", e.getMessage()); + } finally { + ack.acknowledge(); } } @@ -41,9 +40,4 @@ public void message(@Payload String json) throws JsonProcessingException { OrderStateResponse response = objectMapper.readValue(json, OrderStateResponse.class); messagingTemplate.convertAndSendToUser(response.getEmail(), "/topic/standByOrder", json); } - - @KafkaListener(topicPattern = "views", groupId = "view") - public void handleIncrementViewCount(@Payload String viewId) { - viewService.incrementViewCount(viewId); - } } diff --git a/src/main/java/project/trendpick_pro/global/redis/redisson/service/RedissonService.java b/src/main/java/project/trendpick_pro/global/redis/redisson/service/RedissonService.java index 8d27d775..d0d265d5 100644 --- a/src/main/java/project/trendpick_pro/global/redis/redisson/service/RedissonService.java +++ b/src/main/java/project/trendpick_pro/global/redis/redisson/service/RedissonService.java @@ -1,46 +1,73 @@ package project.trendpick_pro.global.redis.redisson.service; -import com.fasterxml.jackson.core.JsonProcessingException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.stereotype.Service; +import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.service.OrderService; -import project.trendpick_pro.domain.product.exception.ProductStockOutException; +import project.trendpick_pro.global.kafka.outbox.entity.OrderMaterial; +import project.trendpick_pro.global.kafka.outbox.service.OutboxMessageService; import project.trendpick_pro.global.redis.exception.RedisLockException; - +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; @Slf4j @Service @RequiredArgsConstructor public class RedissonService { - private final RedissonClient redissonClient; private final OrderService orderService; + private final OutboxMessageService outboxMessageService; - public void processOrderWithLock(String orderKey) throws InterruptedException { - RLock lock = getDistributedLock(orderKey); - if (lock.tryLock(3, 3, TimeUnit.SECONDS)) { - try { - log.info(lock.getName()); - orderService.tryOrder(orderKey); - } catch (JsonProcessingException e) { + public void processOrderWithLock(String orderId, String orderMaterialCode) throws InterruptedException { + Order order = orderService.findById(Long.valueOf(orderId)); + List orderMaterials = outboxMessageService.findOrderMaterial(orderMaterialCode); + List locks = getLocks(orderMaterials); //์ฃผ๋ฌธ ์ƒํ’ˆ๋“ค์— ๋Œ€ํ•œ ๋ฝ + if (isCompleteLock(locks)) + try{ + orderService.tryOrder(orderId, orderMaterials); + } catch (Exception e){ log.error("Error processing order", e); - } finally {; + } finally { try { - lock.unlock(); + unlock(locks); } catch (IllegalMonitorStateException e) { log.info("Redisson Lock Already UnLocked"); } } - } else { - throw new RedisLockException("ํ•ด๋‹น ๋ฝ์ด ์‚ฌ์šฉ์ค‘์ž…๋‹ˆ๋‹ค"); + else throw new RedisLockException("ํ•ด๋‹น ๋ฝ์ด ์‚ฌ์šฉ์ค‘์ž…๋‹ˆ๋‹ค"); + } + + private List getLocks(List orderMaterials) { + List lockList = new ArrayList<>(); + for(OrderMaterial orderMaterial : orderMaterials) + lockList.add(getDistributedLock(String.valueOf(orderMaterial.getProductId()))); + return lockList; + } + + private boolean isCompleteLock(List lockList) throws InterruptedException { + for (RLock lock : lockList) { + if(!lock.tryLock(3, 1, TimeUnit.SECONDS)){ + return false; + } + } + return true; + } + + public void unlock(List lockList){ + for (RLock lock : lockList){ + try { + lock.unlock(); + } catch (IllegalMonitorStateException e) { + log.info("Redisson Lock Already UnLocked"); + } } } private RLock getDistributedLock(String key) { - return redissonClient.getLock("ORD_" + key); + return redissonClient.getLock("PRODUCT_" + key); } } diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index 039217dc..90886e59 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -163,11 +163,6 @@

-
-

๋ˆ„์  ์ ‘์†์ž:

-
- From d03f76e36d5bc803f982551372ee6d4d29485f18 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 19 Sep 2023 18:57:32 +0900 Subject: [PATCH 10/14] =?UTF-8?q?refactor:=20=EA=B2=B0=EC=A0=9C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20->=20=EC=84=9C=EB=B9=84=EC=8A=A4=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/dto/response/OrderItemDto.java | 12 +---- .../global/jmeter/JmeterController.java | 17 ------- .../controller/PaymentController.java | 40 ++++++++--------- .../tosspayment/service/PaymentService.java | 45 ++++++++++++++++++- .../trendpick/orders/order-form.html | 4 +- .../domain/orders/entity/OrderItemTest.java | 4 +- 6 files changed, 68 insertions(+), 54 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index e8ae0794..22ac1e36 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -8,6 +8,7 @@ import java.util.Locale; @Getter +@Builder public class OrderItemDto { private Long productId; private String productName; @@ -17,17 +18,6 @@ public class OrderItemDto { private int price; private Long cartItemId; - @Builder - private OrderItemDto(Long productId, String productName, int quantity, String size, String color, int price, Long cartItemId) { - this.productId = productId; - this.productName = productName; - this.quantity = quantity; - this.size = size; - this.color = color; - this.price = price; - this.cartItemId = cartItemId; - } - public static OrderItemDto of(Product product, int quantity, String size, String color) { return OrderItemDto.builder() .productId(product.getId()) diff --git a/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java b/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java index 28779068..1eb7256a 100644 --- a/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java +++ b/src/main/java/project/trendpick_pro/global/jmeter/JmeterController.java @@ -6,7 +6,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.member.entity.Member; @@ -20,7 +19,6 @@ import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.global.kafka.KafkaProducerService; import project.trendpick_pro.global.util.rq.Rq; -import project.trendpick_pro.global.util.rsData.RsData; import java.io.IOException; import java.util.List; @@ -48,21 +46,6 @@ public ResponseEntity getMemberInfo() { return new ResponseEntity<>(memberInfoResponse, headers, HttpStatus.OK); } - @PreAuthorize("hasAuthority({'MEMBER'})") - @GetMapping("/order") - @ResponseBody - public void processOrder() { - Member member = rq.getMember(); - - Long id = 3L; - int quantity = 1; - String size = "80"; - String color = "Sliver"; - - RsData data = orderService.productToOrder(member, id, quantity, size, color); - kafkaProducerService.sendMessage(data.getData()); - } - @PostMapping("/edit") public void modifyProduct(@RequestParam("productId") Long productId, @RequestParam("mainFile") MultipartFile mainFile, diff --git a/src/main/java/project/trendpick_pro/global/tosspayment/controller/PaymentController.java b/src/main/java/project/trendpick_pro/global/tosspayment/controller/PaymentController.java index 44e1dcae..606d136a 100644 --- a/src/main/java/project/trendpick_pro/global/tosspayment/controller/PaymentController.java +++ b/src/main/java/project/trendpick_pro/global/tosspayment/controller/PaymentController.java @@ -7,12 +7,9 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import project.trendpick_pro.domain.notification.service.NotificationService; -import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.service.OrderService; import project.trendpick_pro.global.util.rq.Rq; import project.trendpick_pro.global.util.rsData.RsData; -import project.trendpick_pro.global.tosspayment.dto.PaymentResultResponse; import project.trendpick_pro.global.tosspayment.service.PaymentService; @Controller @@ -22,11 +19,8 @@ public class PaymentController { private final PaymentService paymentService; private final OrderService orderService; - private final NotificationService notificationService; - private final Rq rq; - @Transactional @GetMapping(value = "/{id}/success") public String PaymentTry( @PathVariable("id") Long id, @@ -34,25 +28,31 @@ public String PaymentTry( @RequestParam(value = "amount") Integer amount, @RequestParam(value = "paymentKey") String paymentKey) { - PaymentResultResponse response = paymentService.requestPayment(paymentKey, orderId, amount); - Order order = orderService.findById(id); - - if (response.getStatus().equals("DONE")) { - order.connectPayment( - "TossPayments" + response.getMethod(), - response.getPaymentKey() - ); - notificationService.create(rq.getMember(), order.getId()); - return rq.redirectWithMsg("/trendpick/orders/%s".formatted(id), "์ฃผ๋ฌธ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."); - } else { - return rq.historyBack(RsData.of("F-1", "์ฃผ๋ฌธ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")); - } + RsData result = paymentService.processPayment(paymentKey, id, amount, orderId); + + if (result.isSuccess()) + return rq.redirectWithMsg("/trendpick/orders/%s".formatted(id), "๊ฒฐ์ œ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค."); + + orderService.cancel(id); + return rq.historyBack(RsData.of("F-1", "๊ฒฐ์ œ ๋„์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.")); + + } + + @Transactional + @GetMapping(value = "/{id}/fail") + public String PaymentFail( + @PathVariable("id") Long id, + @RequestParam(value = "orderId") String orderId, + @RequestParam(value = "amount", required = false) Integer amount, + @RequestParam(value = "paymentKey", required = false) String paymentKey) { + + orderService.cancel(id); + return rq.redirectWithMsg("/trendpick/products/list?main-category=์ „์ฒด", "๊ฒฐ์ œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."); } @GetMapping(value = "/{id}/cancel") public String paymentCancel(@PathVariable("id") Long id) { orderService.cancel(id); - notificationService.create(rq.getMember(),id); paymentService.cancelPayment(orderService.findById(id).getPaymentKey()); return rq.redirectWithMsg("/trendpick/orders/usr", "์ฃผ๋ฌธ์„ ์ทจ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค."); } diff --git a/src/main/java/project/trendpick_pro/global/tosspayment/service/PaymentService.java b/src/main/java/project/trendpick_pro/global/tosspayment/service/PaymentService.java index e8a0f19b..e40fe465 100644 --- a/src/main/java/project/trendpick_pro/global/tosspayment/service/PaymentService.java +++ b/src/main/java/project/trendpick_pro/global/tosspayment/service/PaymentService.java @@ -1,21 +1,30 @@ package project.trendpick_pro.global.tosspayment.service; +import lombok.RequiredArgsConstructor; import net.minidev.json.JSONObject; import org.springframework.beans.factory.annotation.Value; 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 project.trendpick_pro.domain.orders.entity.Order; +import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.orders.service.OrderService; +import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; +import project.trendpick_pro.domain.tags.tag.entity.TagType; import project.trendpick_pro.global.tosspayment.dto.PaymentResultResponse; +import project.trendpick_pro.global.util.rsData.RsData; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; import java.util.Base64; import java.util.Collections; -import java.util.Objects; @Service +@RequiredArgsConstructor public class PaymentService { @Value("${toss.secretKey}") @@ -24,7 +33,34 @@ public class PaymentService { @Value("${toss.url}") private String tossURL; - public PaymentResultResponse requestPayment(String paymentKey, String orderId, Integer amount) { + private final OrderService orderService; + private final FavoriteTagService favoriteTagService; + + @Transactional + public RsData processPayment(String paymentKey, Long orderId, Integer amount, String ORD_ID){ + PaymentResultResponse response = requestPayment(paymentKey, ORD_ID, amount); + + Order order = orderService.findById(orderId); + validatePayment(order); + + if (response.getStatus().equals("DONE")) { + successPaymentProcess(response.getMethod(), response.getPaymentKey(), order); + return RsData.of("S-1", "๊ฒฐ์ œ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค."); + } + + return RsData.of("F-1", "๊ฒฐ์ œ ๋„์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."); + } + + private void successPaymentProcess(String method, String paymentKey, Order order) { + order.connectPayment("TossPayments" + method, paymentKey); + + for (OrderItem orderItem : order.getOrderItems()) { + favoriteTagService.updateTag(order.getMember(), orderItem.getProduct(), TagType.ORDER); + orderItem.getCouponCard().use(LocalDateTime.now()); //์‹ค์ œ ์ฟ ํฐ ์‚ฌ์šฉ ์ฒ˜๋ฆฌ + } + } + + private PaymentResultResponse requestPayment(String paymentKey, String orderId, Integer amount) { RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); String secret = new String(Base64.getEncoder().encode((secretKey + ":").getBytes(StandardCharsets.UTF_8))); @@ -61,4 +97,9 @@ public void cancelPayment(String paymentKey) { PaymentResultResponse.class ); } + + private void validatePayment(Order order) { + if(order.getPaymentKey() != null)//๋ฉฑ๋“ฑ์„ฑ + throw new IllegalArgumentException("์ด๋ฏธ ๊ฒฐ์ œ ์™„๋ฃŒ๋œ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค."); + } } \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/orders/order-form.html b/src/main/resources/templates/trendpick/orders/order-form.html index 8bf45419..2bb3df72 100644 --- a/src/main/resources/templates/trendpick/orders/order-form.html +++ b/src/main/resources/templates/trendpick/orders/order-form.html @@ -171,8 +171,8 @@

๊ฒฐ์ œ ์ •๋ณด