diff --git a/build.gradle b/build.gradle index 83280837..55f40a01 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ dependencies { implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${swagger_version}" implementation 'org.mapstruct:mapstruct:1.5.5.Final' implementation 'ch.hsr:geohash:1.4.0' - + implementation 'net.nurigo:sdk:4.3.0' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0' diff --git a/src/main/java/com/ordertogether/team14_be/auth/presentation/AuthController.java b/src/main/java/com/ordertogether/team14_be/auth/presentation/AuthController.java index bc28548a..206cc8cd 100644 --- a/src/main/java/com/ordertogether/team14_be/auth/presentation/AuthController.java +++ b/src/main/java/com/ordertogether/team14_be/auth/presentation/AuthController.java @@ -84,7 +84,6 @@ public ResponseEntity> signUpMember( String serviceToken = kakaoAuthService.register( email, memberInfoRequest.deliveryName(), memberInfoRequest.phoneNumber()); - ResponseCookie cookie = ResponseCookie.from("serviceToken", serviceToken) .httpOnly(true) diff --git a/src/main/java/com/ordertogether/team14_be/order/details/controller/OrderDetailController.java b/src/main/java/com/ordertogether/team14_be/order/details/controller/OrderDetailController.java index 248f50d1..93886539 100644 --- a/src/main/java/com/ordertogether/team14_be/order/details/controller/OrderDetailController.java +++ b/src/main/java/com/ordertogether/team14_be/order/details/controller/OrderDetailController.java @@ -1,13 +1,25 @@ package com.ordertogether.team14_be.order.details.controller; -import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailRequestDto; -import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailResponseDto; +import com.ordertogether.team14_be.member.persistence.entity.Member; +import com.ordertogether.team14_be.member.presentation.LoginMember; +import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailReq; +import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailRes; +import com.ordertogether.team14_be.order.details.dto.get.GetCreatorOrderInfoRes; +import com.ordertogether.team14_be.order.details.dto.get.GetOrdersInfoReq; +import com.ordertogether.team14_be.order.details.dto.get.GetOrdersInfoRes; +import com.ordertogether.team14_be.order.details.dto.get.GetParticipantOrderInfoRes; +import com.ordertogether.team14_be.order.details.dto.update.UpdateOrderPriceReq; import com.ordertogether.team14_be.order.details.service.OrderDetailService; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -19,10 +31,36 @@ public class OrderDetailController { // 주문 생성 @PostMapping - public ResponseEntity createOrderDetail( - @RequestBody CreateOrderDetailRequestDto createOrderDetailRequestDto) { - CreateOrderDetailResponseDto createOrderDetailResponseDto = - orderDetailService.createOrderDetail(createOrderDetailRequestDto); - return ResponseEntity.ok(createOrderDetailResponseDto); + public ResponseEntity createOrderDetail( + @RequestBody CreateOrderDetailReq createOrderDetailReq) { + CreateOrderDetailRes createOrderDetailRes = + orderDetailService.createOrderDetail(createOrderDetailReq); + return ResponseEntity.ok(createOrderDetailRes); + } + + @GetMapping + public ResponseEntity getOrdersInfo( + @LoginMember Member member, @ModelAttribute @Valid GetOrdersInfoReq dto) { + return ResponseEntity.ok(orderDetailService.getOrdersInfo(member, dto)); + } + + @GetMapping("/participant") + public ResponseEntity getParticipantOrderInfo( + @LoginMember Member member, @RequestParam(name = "spot-id") Long spotId) { + return ResponseEntity.ok(orderDetailService.getParticipantOrderInfo(member, spotId)); + } + + @GetMapping("/creator") + public ResponseEntity getCreatorOrderInfo( + @LoginMember Member member, @RequestParam(name = "spot-id") Long spotId) { + return ResponseEntity.ok(orderDetailService.getCreatorOrderInfo(member, spotId)); + } + + // 가격 수정 + @PutMapping("/price") + public ResponseEntity updateOrderPrice( + @LoginMember Member member, @RequestBody @Valid UpdateOrderPriceReq dto) { + orderDetailService.updateOrderPrice(member, dto); + return ResponseEntity.ok().build(); } } diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailRequestDto.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailReq.java similarity index 89% rename from src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailRequestDto.java rename to src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailReq.java index 83a30603..c6e1cf39 100644 --- a/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailRequestDto.java +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailReq.java @@ -9,7 +9,7 @@ @NoArgsConstructor @AllArgsConstructor @Getter -public class CreateOrderDetailRequestDto { +public class CreateOrderDetailReq { private int price; private boolean isPayed; private Long participantId; // 참여자 아이디 diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailResponseDto.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailRes.java similarity index 90% rename from src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailResponseDto.java rename to src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailRes.java index 51d799d0..60a0149d 100644 --- a/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailResponseDto.java +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/create/CreateOrderDetailRes.java @@ -9,7 +9,7 @@ @NoArgsConstructor @AllArgsConstructor @Getter -public class CreateOrderDetailResponseDto { +public class CreateOrderDetailRes { private Long id; private int price; private boolean isPayed; diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetCreatorOrderInfoRes.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetCreatorOrderInfoRes.java new file mode 100644 index 00000000..d6af62cd --- /dev/null +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetCreatorOrderInfoRes.java @@ -0,0 +1,11 @@ +package com.ordertogether.team14_be.order.details.dto.get; + +import java.util.List; + +public record GetCreatorOrderInfoRes( + String category, + String storeName, + int minimumOrderAmount, + String pickUpLocation, + String deliveryStatus, + List memberInfo) {} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetOrdersInfoReq.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetOrdersInfoReq.java new file mode 100644 index 00000000..39fcdef2 --- /dev/null +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetOrdersInfoReq.java @@ -0,0 +1,7 @@ +package com.ordertogether.team14_be.order.details.dto.get; + +import java.util.List; + +public record GetOrdersInfoReq( + Integer page, Integer size, List sort // 첫 번째 - 정렬할 필드명(DB 기준), 두 번째 - 정렬 순서(desc, asc) + ) {} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetOrdersInfoRes.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetOrdersInfoRes.java new file mode 100644 index 00000000..4f8db70e --- /dev/null +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetOrdersInfoRes.java @@ -0,0 +1,5 @@ +package com.ordertogether.team14_be.order.details.dto.get; + +import java.util.List; + +public record GetOrdersInfoRes(int totalPages, long totalElements, List ordersInfo) {} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetParticipantOrderInfoRes.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetParticipantOrderInfoRes.java new file mode 100644 index 00000000..f29060d5 --- /dev/null +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/GetParticipantOrderInfoRes.java @@ -0,0 +1,9 @@ +package com.ordertogether.team14_be.order.details.dto.get; + +public record GetParticipantOrderInfoRes( + String category, + String storeName, + int minimumOrderAmount, + String pickUpLocation, + String deliveryStatus, + int price) {} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/get/MemberBriefInfo.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/MemberBriefInfo.java new file mode 100644 index 00000000..2e5d9b5b --- /dev/null +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/MemberBriefInfo.java @@ -0,0 +1,3 @@ +package com.ordertogether.team14_be.order.details.dto.get; + +public record MemberBriefInfo(long memberId, String deliveryName, int price, boolean isPayed) {} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/get/OrderInfo.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/OrderInfo.java new file mode 100644 index 00000000..fab28958 --- /dev/null +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/get/OrderInfo.java @@ -0,0 +1,27 @@ +package com.ordertogether.team14_be.order.details.dto.get; + +import com.ordertogether.team14_be.order.details.entity.OrderDetail; +import com.ordertogether.team14_be.spot.entity.Spot; + +public record OrderInfo( + Long id, + String category, + String storeName, + int minimumOrderAmount, + String pickUpLocation, + String deliveryStatus, + int price, + boolean isCreator) { + + public OrderInfo(Long memberId, OrderDetail order, Spot spot) { + this( + order.getId(), + spot.getCategory().toString(), + spot.getStoreName(), + spot.getMinimumOrderAmount(), + spot.getPickUpLocation(), + spot.getDeliveryStatus(), + order.getPrice(), + spot.getMember().getId().equals(memberId)); + } +} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/dto/update/UpdateOrderPriceReq.java b/src/main/java/com/ordertogether/team14_be/order/details/dto/update/UpdateOrderPriceReq.java new file mode 100644 index 00000000..be814390 --- /dev/null +++ b/src/main/java/com/ordertogether/team14_be/order/details/dto/update/UpdateOrderPriceReq.java @@ -0,0 +1,5 @@ +package com.ordertogether.team14_be.order.details.dto.update; + +public record UpdateOrderPriceReq(Long orderId, int price) { + +} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/entity/OrderDetail.java b/src/main/java/com/ordertogether/team14_be/order/details/entity/OrderDetail.java index 6e3f9255..587060cb 100644 --- a/src/main/java/com/ordertogether/team14_be/order/details/entity/OrderDetail.java +++ b/src/main/java/com/ordertogether/team14_be/order/details/entity/OrderDetail.java @@ -41,4 +41,8 @@ public class OrderDetail extends BaseTimeEntity { private int price; private boolean isPayed; + + public void updatePrice(int price) { + this.price = price; + } } diff --git a/src/main/java/com/ordertogether/team14_be/order/details/repository/OrderDetailRepository.java b/src/main/java/com/ordertogether/team14_be/order/details/repository/OrderDetailRepository.java index a04b42e6..8fbc5cac 100644 --- a/src/main/java/com/ordertogether/team14_be/order/details/repository/OrderDetailRepository.java +++ b/src/main/java/com/ordertogether/team14_be/order/details/repository/OrderDetailRepository.java @@ -1,8 +1,22 @@ package com.ordertogether.team14_be.order.details.repository; +import com.ordertogether.team14_be.member.persistence.entity.Member; import com.ordertogether.team14_be.order.details.entity.OrderDetail; +import com.ordertogether.team14_be.spot.entity.Spot; +import java.util.List; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository -public interface OrderDetailRepository extends JpaRepository {} +public interface OrderDetailRepository extends JpaRepository { + @EntityGraph(attributePaths = {"spot"}) + Page findAllByMember(Member member, Pageable pageable); + + Optional findBySpotAndMember(Spot spot, Member member); + + List findAllBySpot(Spot spot); +} diff --git a/src/main/java/com/ordertogether/team14_be/order/details/service/OrderDetailService.java b/src/main/java/com/ordertogether/team14_be/order/details/service/OrderDetailService.java index 481733d2..2fdce15b 100644 --- a/src/main/java/com/ordertogether/team14_be/order/details/service/OrderDetailService.java +++ b/src/main/java/com/ordertogether/team14_be/order/details/service/OrderDetailService.java @@ -2,48 +2,65 @@ import com.ordertogether.team14_be.member.persistence.MemberRepository; import com.ordertogether.team14_be.member.persistence.entity.Member; -import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailRequestDto; -import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailResponseDto; +import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailReq; +import com.ordertogether.team14_be.order.details.dto.create.CreateOrderDetailRes; +import com.ordertogether.team14_be.order.details.dto.get.GetCreatorOrderInfoRes; +import com.ordertogether.team14_be.order.details.dto.get.GetOrdersInfoReq; +import com.ordertogether.team14_be.order.details.dto.get.GetOrdersInfoRes; +import com.ordertogether.team14_be.order.details.dto.get.GetParticipantOrderInfoRes; +import com.ordertogether.team14_be.order.details.dto.get.MemberBriefInfo; +import com.ordertogether.team14_be.order.details.dto.get.OrderInfo; +import com.ordertogether.team14_be.order.details.dto.update.UpdateOrderPriceReq; import com.ordertogether.team14_be.order.details.entity.OrderDetail; import com.ordertogether.team14_be.order.details.repository.OrderDetailRepository; -import com.ordertogether.team14_be.spot.dto.servicedto.SpotDto; +import com.ordertogether.team14_be.spot.entity.Spot; +import com.ordertogether.team14_be.spot.repository.SimpleSpotRepository; import com.ordertogether.team14_be.spot.repository.SpotRepository; +import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class OrderDetailService { - + private final SimpleSpotRepository simpleSpotRepository; private final OrderDetailRepository orderDetailRepository; private final MemberRepository memberRepository; private final SpotRepository spotRepository; // 주문 상세 정보 생성 메서드 - public CreateOrderDetailResponseDto createOrderDetail( - CreateOrderDetailRequestDto createOrderDetailRequestDto) { + @Transactional + public CreateOrderDetailRes createOrderDetail(CreateOrderDetailReq createOrderDetailReq) { // 참여자 본인 정보 설정 Member member = memberRepository - .findById(createOrderDetailRequestDto.getParticipantId()) + .findById(createOrderDetailReq.getParticipantId()) .orElseThrow(() -> new IllegalArgumentException("참여자 정보가 없습니다.")); - // 스팟 정보 설정 - SpotDto spot = - spotRepository.findByIdAndIsDeletedFalse(createOrderDetailRequestDto.getSpotId()); + // 스팟 정보 설정 - spotMapper가 아직 구현되지 않아서 Simple사용 + // SpotDto spotDto = + // spotRepository.findByIdAndIsDeletedFalse(createOrderDetailRequestDto.getSpotId()); + Spot spot = + simpleSpotRepository + .findById(createOrderDetailReq.getSpotId()) + .orElseThrow(() -> new IllegalArgumentException("스팟 정보가 없습니다.")); OrderDetail orderDetail = OrderDetail.builder() .member(member) - // .spot(spot) - .price(createOrderDetailRequestDto.getPrice()) - .isPayed(createOrderDetailRequestDto.isPayed()) + .spot(spot) + .price(createOrderDetailReq.getPrice()) + .isPayed(createOrderDetailReq.isPayed()) .build(); OrderDetail savedOrderDetail = orderDetailRepository.save(orderDetail); - return CreateOrderDetailResponseDto.builder() + return CreateOrderDetailRes.builder() .id(savedOrderDetail.getId()) .price(savedOrderDetail.getPrice()) .isPayed(savedOrderDetail.isPayed()) @@ -51,4 +68,94 @@ public CreateOrderDetailResponseDto createOrderDetail( .spotName(spot.getStoreName()) .build(); } + + @Transactional(readOnly = true) + public GetOrdersInfoRes getOrdersInfo(Member member, GetOrdersInfoReq dto) { + Page orderDetails = + orderDetailRepository.findAllByMember( + member, + PageRequest.of( + dto.page(), + dto.size(), + dto.sort() == null ? Sort.unsorted() : Sort.by(dto.sort().get(1)))); + + return new GetOrdersInfoRes( + orderDetails.getTotalPages(), + orderDetails.getTotalElements(), + orderDetails.getContent().stream() + .map(order -> new OrderInfo(member.getId(), order, order.getSpot())) + .toList()); + } + + @Transactional(readOnly = true) + public GetParticipantOrderInfoRes getParticipantOrderInfo(Member member, Long spotId) { + Spot spot = + simpleSpotRepository + .findById(spotId) + .orElseThrow(() -> new IllegalArgumentException("스팟 정보가 없습니다.")); + Member creator = spot.getMember(); + + if (member.getId().equals(creator.getId())) + throw new IllegalArgumentException("방장입니다.(참여자만 사용 가능)"); + + OrderDetail orderDetail = + orderDetailRepository + .findBySpotAndMember(spot, member) + .orElseThrow(() -> new IllegalArgumentException("주문 정보가 없습니다.")); + + return new GetParticipantOrderInfoRes( + spot.getCategory().toString(), + spot.getStoreName(), + spot.getMinimumOrderAmount(), + spot.getPickUpLocation(), + spot.getDeliveryStatus(), + orderDetail.getPrice()); + } + + @Transactional(readOnly = true) + public GetCreatorOrderInfoRes getCreatorOrderInfo(Member member, Long spotId) { + Spot spot = + simpleSpotRepository + .findById(spotId) + .orElseThrow(() -> new IllegalArgumentException("스팟 정보가 없습니다.")); + Member creator = spot.getMember(); + + if (!member.getId().equals(creator.getId())) + throw new IllegalArgumentException("참여자입니다.(방장만 사용 가능)"); + + List orders = orderDetailRepository.findAllBySpot(spot); + + return new GetCreatorOrderInfoRes( + spot.getCategory().toString(), + spot.getStoreName(), + spot.getMinimumOrderAmount(), + spot.getPickUpLocation(), + spot.getDeliveryStatus(), + orders.stream() + .map( + order -> { + Member participant = order.getMember(); + return new MemberBriefInfo( + participant.getId(), + participant.getDeliveryName(), + order.getPrice(), + order.isPayed()); + }) + .toList()); // memberInfo + } + + @Transactional + public void updateOrderPrice(Member member, UpdateOrderPriceReq dto) { + OrderDetail orderDetail = + orderDetailRepository + .findById(dto.orderId()) + .orElseThrow(() -> new IllegalArgumentException("주문 정보를 찾을 수 없습니다.")); + + if (!orderDetail.getMember().getId().equals(member.getId())) { + throw new IllegalArgumentException("주문의 참여자가 아닙니다."); + } + + orderDetail.updatePrice(dto.price()); + orderDetailRepository.save(orderDetail); + } } diff --git a/src/main/java/com/ordertogether/team14_be/spot/enums/Category.java b/src/main/java/com/ordertogether/team14_be/spot/enums/Category.java index 58f70e9d..6696b4bf 100644 --- a/src/main/java/com/ordertogether/team14_be/spot/enums/Category.java +++ b/src/main/java/com/ordertogether/team14_be/spot/enums/Category.java @@ -28,7 +28,7 @@ public enum Category implements CodedEnum { private final String code; private final String stringCategory; - + // 한글 설명(String)을 ENUM으로 변환 public static Optional fromStringToEnum(String category) { return Arrays.stream(Category.values()) @@ -43,6 +43,20 @@ public static Optional fromEnumToString(Category category) { .describeConstable(); // 상수 풀에 저장되는 값을 안전하게 참조 } + // 한글 설명(String)을 ENUM으로 변환 + public static Optional fromStringToEnum(String category) { + return Arrays.stream(Category.values()) + .filter(c -> c.getCategory().equals(category)) + .findFirst(); + } + + // ENUM을 코드(String)으로 변환 + public static Optional fromEnumToString(Category category) { + return Optional.of(category.getCode()) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 카테고리입니다.")) + .describeConstable(); // 상수 풀에 저장되는 값을 안전하게 참조 + } + @jakarta.persistence.Converter(autoApply = true) static class Converter extends AbstractCodedEnumConverter { public Converter() {