diff --git a/src/main/java/com/kusitms/jipbap/common/response/ErrorCode.java b/src/main/java/com/kusitms/jipbap/common/response/ErrorCode.java index 30ac8f1..813c9ea 100644 --- a/src/main/java/com/kusitms/jipbap/common/response/ErrorCode.java +++ b/src/main/java/com/kusitms/jipbap/common/response/ErrorCode.java @@ -29,7 +29,7 @@ public enum ErrorCode { //store STORE_NOT_FOUND_ERROR(false, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 가게입니다."), - STORE_ALREADY_EXISTS_ERROR(false, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 가게입니다."), + STORE_ALREADY_EXISTS_ERROR(false, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 가게이거나, 이미 가게를 생성한 유저입니다."), //food CATEGORY_NOT_FOUND_ERROR(false, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 카테고리입니다."), diff --git a/src/main/java/com/kusitms/jipbap/food/dto/CategoryDto.java b/src/main/java/com/kusitms/jipbap/food/dto/CategoryDto.java index 82ae499..31bf00c 100644 --- a/src/main/java/com/kusitms/jipbap/food/dto/CategoryDto.java +++ b/src/main/java/com/kusitms/jipbap/food/dto/CategoryDto.java @@ -3,10 +3,12 @@ import jakarta.persistence.Column; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter +@NoArgsConstructor @AllArgsConstructor public class CategoryDto { diff --git a/src/main/java/com/kusitms/jipbap/food/dto/FoodDto.java b/src/main/java/com/kusitms/jipbap/food/dto/FoodDto.java index 25a3d32..981bf49 100644 --- a/src/main/java/com/kusitms/jipbap/food/dto/FoodDto.java +++ b/src/main/java/com/kusitms/jipbap/food/dto/FoodDto.java @@ -2,10 +2,12 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter +@NoArgsConstructor @AllArgsConstructor public class FoodDto { diff --git a/src/main/java/com/kusitms/jipbap/food/dto/RegisterCategoryRequestDto.java b/src/main/java/com/kusitms/jipbap/food/dto/RegisterCategoryRequestDto.java index 1a8c906..ae26b45 100644 --- a/src/main/java/com/kusitms/jipbap/food/dto/RegisterCategoryRequestDto.java +++ b/src/main/java/com/kusitms/jipbap/food/dto/RegisterCategoryRequestDto.java @@ -1,10 +1,14 @@ package com.kusitms.jipbap.food.dto; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter +@NoArgsConstructor +@AllArgsConstructor public class RegisterCategoryRequestDto { private String name; private String image; diff --git a/src/main/java/com/kusitms/jipbap/food/dto/RegisterFoodRequestDto.java b/src/main/java/com/kusitms/jipbap/food/dto/RegisterFoodRequestDto.java index 5a0e412..deccfc6 100644 --- a/src/main/java/com/kusitms/jipbap/food/dto/RegisterFoodRequestDto.java +++ b/src/main/java/com/kusitms/jipbap/food/dto/RegisterFoodRequestDto.java @@ -2,11 +2,15 @@ import com.kusitms.jipbap.food.Category; import com.kusitms.jipbap.store.Store; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter +@NoArgsConstructor +@AllArgsConstructor public class RegisterFoodRequestDto { private Long storeId; diff --git a/src/main/java/com/kusitms/jipbap/order/OrderExceptionHandler.java b/src/main/java/com/kusitms/jipbap/order/OrderExceptionHandler.java new file mode 100644 index 0000000..ae880e8 --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/OrderExceptionHandler.java @@ -0,0 +1,24 @@ +package com.kusitms.jipbap.order; + +import com.kusitms.jipbap.common.response.CommonResponse; +import com.kusitms.jipbap.common.response.ErrorCode; +import com.kusitms.jipbap.order.exception.OrderNotExistsException; +import com.kusitms.jipbap.store.exception.StoreExistsException; +import com.kusitms.jipbap.store.exception.StoreNotExistsException; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class OrderExceptionHandler { + @ExceptionHandler(OrderNotExistsException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public CommonResponse handleOrderNotExistsException(OrderNotExistsException e, HttpServletRequest request) { + log.warn("ORDER-001> 요청 URI: " + request.getRequestURI() + ", 에러 메세지: " + e.getMessage()); + return new CommonResponse<>(ErrorCode.STORE_NOT_FOUND_ERROR); + } +} diff --git a/src/main/java/com/kusitms/jipbap/order/ReviewController.java b/src/main/java/com/kusitms/jipbap/order/ReviewController.java new file mode 100644 index 0000000..fc3706a --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/ReviewController.java @@ -0,0 +1,37 @@ +package com.kusitms.jipbap.order; + +import com.kusitms.jipbap.common.response.CommonResponse; +import com.kusitms.jipbap.order.dto.GetRegisteredReviewsResponseDto; +import com.kusitms.jipbap.order.dto.RegisterReviewRequestDto; +import com.kusitms.jipbap.order.dto.ReviewDto; +import com.kusitms.jipbap.security.Auth; +import com.kusitms.jipbap.security.AuthInfo; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/review") +@RequiredArgsConstructor +public class ReviewController { + + private final ReviewService reviewService; + + @Operation(summary = "주문 리뷰 작성") + @PostMapping + public CommonResponse registerReview(@Auth AuthInfo authInfo, @RequestBody RegisterReviewRequestDto dto) { + return new CommonResponse<>(reviewService.registerReview(authInfo.getEmail(), dto)); + } + + @Operation(summary = "유저가 작성한 리뷰 모아보기") + @GetMapping + public CommonResponse getUserRegisteredReviews(@Auth AuthInfo authInfo) { + return new CommonResponse<>(reviewService.getUserRegisteredReviews(authInfo.getEmail())); + } + + @Operation(summary = "가게 리뷰 모두보기") + @GetMapping("/{storeId}") + public CommonResponse getStoreRegisteredReviews(@PathVariable Long storeId) { + return new CommonResponse<>(reviewService.getStoreRegisteredReviews(storeId)); + } +} diff --git a/src/main/java/com/kusitms/jipbap/order/ReviewRepository.java b/src/main/java/com/kusitms/jipbap/order/ReviewRepository.java new file mode 100644 index 0000000..d968448 --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/ReviewRepository.java @@ -0,0 +1,6 @@ +package com.kusitms.jipbap.order; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReviewRepository extends JpaRepository , ReviewRepositoryExtension { +} diff --git a/src/main/java/com/kusitms/jipbap/order/ReviewRepositoryExtension.java b/src/main/java/com/kusitms/jipbap/order/ReviewRepositoryExtension.java new file mode 100644 index 0000000..fff0b9d --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/ReviewRepositoryExtension.java @@ -0,0 +1,11 @@ +package com.kusitms.jipbap.order; + +import com.kusitms.jipbap.store.Store; +import com.kusitms.jipbap.user.User; + +import java.util.List; + +public interface ReviewRepositoryExtension { + List findAllReviewsByUser(User user); + List findAllReviewsByStore(Store store); +} diff --git a/src/main/java/com/kusitms/jipbap/order/ReviewRepositoryExtensionImpl.java b/src/main/java/com/kusitms/jipbap/order/ReviewRepositoryExtensionImpl.java new file mode 100644 index 0000000..a57d276 --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/ReviewRepositoryExtensionImpl.java @@ -0,0 +1,36 @@ +package com.kusitms.jipbap.order; + +import com.kusitms.jipbap.store.Store; +import com.kusitms.jipbap.user.User; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +import static com.kusitms.jipbap.food.QFood.food; +import static com.kusitms.jipbap.order.QOrder.order; +import static com.kusitms.jipbap.order.QReview.review; + +@RequiredArgsConstructor +public class ReviewRepositoryExtensionImpl implements ReviewRepositoryExtension { + + private final JPAQueryFactory queryFactory; + + @Override + public List findAllReviewsByUser(User user) { + return queryFactory.selectFrom(review) + .join(review.order, order) + .where(order.user.eq(user)) + .fetch(); + } + + @Override + public List findAllReviewsByStore(Store store) { + return queryFactory.selectFrom(review) + .join(review.order, order) + .join(order.food, food) + .where(food.store.eq(store)) + .fetch(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/jipbap/order/ReviewService.java b/src/main/java/com/kusitms/jipbap/order/ReviewService.java new file mode 100644 index 0000000..5cdf7bd --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/ReviewService.java @@ -0,0 +1,66 @@ +package com.kusitms.jipbap.order; + +import com.kusitms.jipbap.order.dto.GetRegisteredReviewsResponseDto; +import com.kusitms.jipbap.order.dto.RegisterReviewRequestDto; +import com.kusitms.jipbap.order.dto.ReviewDto; +import com.kusitms.jipbap.order.exception.OrderNotExistsException; +import com.kusitms.jipbap.store.Store; +import com.kusitms.jipbap.store.StoreRepository; +import com.kusitms.jipbap.store.exception.StoreNotExistsException; +import com.kusitms.jipbap.user.User; +import com.kusitms.jipbap.user.UserRepository; +import com.kusitms.jipbap.user.exception.UserNotFoundException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ReviewService { + + private final ReviewRepository reviewRepository; + private final UserRepository userRepository; + private final OrderRepository orderRepository; + private final StoreRepository storeRepository; + + @Transactional + public ReviewDto registerReview(String email, RegisterReviewRequestDto dto) { + userRepository.findByEmail(email).orElseThrow(()-> new UserNotFoundException("유저 정보가 존재하지 않습니다.")); + Order order = orderRepository.findById(dto.getOrderId()).orElseThrow(()-> new OrderNotExistsException("orderId: "+dto.getOrderId()+"에 해당하는 주문이 존재하지 않습니다.")); + + Review review = reviewRepository.save(new Review(null, order, dto.getRating(), dto.getMessage())); + + return new ReviewDto(review.getId(), review.getOrder().getId(), review.getRating(), review.getMessage()); + } + + @Transactional + public GetRegisteredReviewsResponseDto getUserRegisteredReviews(String email) { + User user = userRepository.findByEmail(email).orElseThrow(() -> new UserNotFoundException("유저 정보가 존재하지 않습니다.")); + + List reviews = reviewRepository.findAllReviewsByUser(user); + + return new GetRegisteredReviewsResponseDto( + reviews.stream() + .map(r -> new ReviewDto(r.getId(), r.getOrder().getId(), r.getRating(), r.getMessage())) + .collect(Collectors.toList()) + ); + } + + @Transactional + public GetRegisteredReviewsResponseDto getStoreRegisteredReviews(Long storeId) { + Store store = storeRepository.findById(storeId).orElseThrow(()-> new StoreNotExistsException("storeId: "+storeId+"에 해당하는 가게가 존재하지 않습니다.")); + + List reviews = reviewRepository.findAllReviewsByStore(store); + + return new GetRegisteredReviewsResponseDto( + reviews.stream() + .map(r -> new ReviewDto(r.getId(), r.getOrder().getId(), r.getRating(), r.getMessage())) + .collect(Collectors.toList()) + ); + } +} diff --git a/src/main/java/com/kusitms/jipbap/order/dto/GetRegisteredReviewsResponseDto.java b/src/main/java/com/kusitms/jipbap/order/dto/GetRegisteredReviewsResponseDto.java new file mode 100644 index 0000000..511091d --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/dto/GetRegisteredReviewsResponseDto.java @@ -0,0 +1,16 @@ +package com.kusitms.jipbap.order.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class GetRegisteredReviewsResponseDto { + private List reviewList; +} diff --git a/src/main/java/com/kusitms/jipbap/order/dto/OrderDto.java b/src/main/java/com/kusitms/jipbap/order/dto/OrderDto.java index e5f190d..0f2aef9 100644 --- a/src/main/java/com/kusitms/jipbap/order/dto/OrderDto.java +++ b/src/main/java/com/kusitms/jipbap/order/dto/OrderDto.java @@ -2,11 +2,13 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @AllArgsConstructor +@NoArgsConstructor public class OrderDto { private Long id; diff --git a/src/main/java/com/kusitms/jipbap/order/dto/OrderFoodRequestDto.java b/src/main/java/com/kusitms/jipbap/order/dto/OrderFoodRequestDto.java index 3f3b928..44e5d49 100644 --- a/src/main/java/com/kusitms/jipbap/order/dto/OrderFoodRequestDto.java +++ b/src/main/java/com/kusitms/jipbap/order/dto/OrderFoodRequestDto.java @@ -2,10 +2,13 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter +@AllArgsConstructor +@NoArgsConstructor public class OrderFoodRequestDto { private Long user; diff --git a/src/main/java/com/kusitms/jipbap/order/dto/RegisterReviewRequestDto.java b/src/main/java/com/kusitms/jipbap/order/dto/RegisterReviewRequestDto.java new file mode 100644 index 0000000..affce86 --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/dto/RegisterReviewRequestDto.java @@ -0,0 +1,16 @@ +package com.kusitms.jipbap.order.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class RegisterReviewRequestDto { + private Long orderId; + private Long rating; + private String message; +} diff --git a/src/main/java/com/kusitms/jipbap/order/dto/ReviewDto.java b/src/main/java/com/kusitms/jipbap/order/dto/ReviewDto.java new file mode 100644 index 0000000..9f25009 --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/dto/ReviewDto.java @@ -0,0 +1,21 @@ +package com.kusitms.jipbap.order.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class ReviewDto { + + private Long id; + + private Long orderId; + + private Long rating; + + private String message; +} diff --git a/src/main/java/com/kusitms/jipbap/order/exception/OrderNotExistsException.java b/src/main/java/com/kusitms/jipbap/order/exception/OrderNotExistsException.java new file mode 100644 index 0000000..c8bebb9 --- /dev/null +++ b/src/main/java/com/kusitms/jipbap/order/exception/OrderNotExistsException.java @@ -0,0 +1,7 @@ +package com.kusitms.jipbap.order.exception; + +public class OrderNotExistsException extends RuntimeException{ + public OrderNotExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kusitms/jipbap/store/dto/BookmarkedStoreListResponseDto.java b/src/main/java/com/kusitms/jipbap/store/dto/BookmarkedStoreListResponseDto.java index a4e7227..9bd1ef5 100644 --- a/src/main/java/com/kusitms/jipbap/store/dto/BookmarkedStoreListResponseDto.java +++ b/src/main/java/com/kusitms/jipbap/store/dto/BookmarkedStoreListResponseDto.java @@ -2,6 +2,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import java.util.List; @@ -9,6 +10,7 @@ @Getter @Setter @AllArgsConstructor +@NoArgsConstructor public class BookmarkedStoreListResponseDto { private List stores; diff --git a/src/main/java/com/kusitms/jipbap/store/dto/RegisterStoreRequestDto.java b/src/main/java/com/kusitms/jipbap/store/dto/RegisterStoreRequestDto.java index ca6b1f7..8fbbe38 100644 --- a/src/main/java/com/kusitms/jipbap/store/dto/RegisterStoreRequestDto.java +++ b/src/main/java/com/kusitms/jipbap/store/dto/RegisterStoreRequestDto.java @@ -4,6 +4,7 @@ @Getter @Setter +@NoArgsConstructor @AllArgsConstructor public class RegisterStoreRequestDto { diff --git a/src/main/java/com/kusitms/jipbap/store/dto/StoreDetailResponseDto.java b/src/main/java/com/kusitms/jipbap/store/dto/StoreDetailResponseDto.java index 7e0c4f7..eb63b57 100644 --- a/src/main/java/com/kusitms/jipbap/store/dto/StoreDetailResponseDto.java +++ b/src/main/java/com/kusitms/jipbap/store/dto/StoreDetailResponseDto.java @@ -2,11 +2,13 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @AllArgsConstructor +@NoArgsConstructor public class StoreDetailResponseDto { private StoreDto storeDto; diff --git a/src/main/java/com/kusitms/jipbap/store/dto/StoreDto.java b/src/main/java/com/kusitms/jipbap/store/dto/StoreDto.java index f834b94..7fc9249 100644 --- a/src/main/java/com/kusitms/jipbap/store/dto/StoreDto.java +++ b/src/main/java/com/kusitms/jipbap/store/dto/StoreDto.java @@ -2,11 +2,13 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @AllArgsConstructor +@NoArgsConstructor public class StoreDto { private Long id; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7732259..238c179 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,7 +22,7 @@ spring: jpa: open-in-view: true hibernate: - ddl-auto: create-drop + ddl-auto: update show-sql: true properties: hibernate: