From 92401f98a2e73c03d8ba042ecebcfd7584aecb83 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Mon, 3 Nov 2025 15:30:36 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat]=20=ED=99=88=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=9A=A9=20=ED=8F=89=EC=A0=90=20=EB=86=92=EC=9D=80=20=ED=91=B8?= =?UTF-8?q?=EB=93=9C=ED=8A=B8=EB=9F=AD=20=EC=A1=B0=ED=9A=8C=20api=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#24)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/FoodTruckService.java | 6 +++++ .../info/FoodTruckInfoService.java | 9 +++++++ .../repository/FoodTruckRepository.java | 11 +++++++++ .../presentation/FoodTruckController.java | 12 ++++++++++ .../response/FoodTruckTopRateResponse.java | 24 +++++++++++++++++++ 5 files changed, 62 insertions(+) create mode 100644 src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckTopRateResponse.java diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java b/src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java index 22285d1..0ae4e26 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java @@ -92,4 +92,10 @@ public List searchFoodTruckMenus(Long foodTruckId, String return foodTruckMenuService.searchFoodTruckMenus(foodTruckId, keyword, member); } + + public List getTopRatedFoodTrucks(Long memberId) { + memberValidator.validateAndGetMember(memberId); + + return foodTruckInfoService.getTopRatedFoodTrucks(); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java b/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java index 60f6d79..7eb9aca 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java @@ -11,6 +11,7 @@ import konkuk.chacall.domain.foodtruck.presentation.dto.request.UpdateFoodTruckInfoRequest; import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckDetailResponse; import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckResponse; +import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckTopRateResponse; import konkuk.chacall.domain.member.domain.repository.SavedFoodTruckRepository; import konkuk.chacall.domain.region.domain.model.Region; import konkuk.chacall.domain.region.domain.repository.RegionRepository; @@ -37,6 +38,8 @@ public class FoodTruckInfoService { private final AvailableDateRepository availableDateRepository; private final RegionRepository regionRepository; + private static final int TOP_RATED_FOOD_TRUCK_LIMIT = 7; + public CursorPagingResponse getFoodTrucks(Long memberId, FoodTruckSearchRequest request) { Slice foodTruckSlice = foodTruckRepository.getFoodTrucks(request); @@ -154,4 +157,10 @@ public FoodTruckDetailResponse getFoodTruckDetails(User member, Long foodTruckId return FoodTruckDetailResponse.from(foodTruck, foodTruckServiceAreas, availableDates, isSaved); } + + public List getTopRatedFoodTrucks() { + return foodTruckRepository.findTopRatedFoodTrucks(TOP_RATED_FOOD_TRUCK_LIMIT).stream() + .map(FoodTruckTopRateResponse::from) + .toList(); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java index a197eb7..01586a4 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java @@ -10,6 +10,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.util.Collection; import java.util.List; import java.util.Optional; @@ -53,4 +54,14 @@ boolean existsByFoodTruckIdAndOwnerIdAndFoodTruckStatus( @EntityGraph(attributePaths = {"owner"}) List findAll(); + + @Query(""" + select f + from FoodTruck f + where f.foodTruckStatus = 'APPROVED' + and f.foodTruckViewedStatus = 'ON' + order by f.ratingInfo.averageRating desc, f.ratingInfo.ratingCount desc + limit :limit + """) + List findTopRatedFoodTrucks(@Param("limit") int limit); } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java index c84df2e..2f35a70 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java @@ -158,4 +158,16 @@ public BaseResponse> searchFoodTruckMenus( ) { return BaseResponse.ok(foodTruckService.searchFoodTruckMenus(foodTruckId, keyword, memberId)); } + + @Operation( + summary = "[홈화면용] 평점 높은 푸드트럭 조회", + description = "평점이 높은 푸드트럭을 조회합니다." + ) + @ExceptionDescription(SwaggerResponseDescription.GET_TOP_RATED_FOOD_TRUCKS) + @GetMapping("/top-rated") + public BaseResponse> getTopRatedFoodTrucks( + @Parameter(hidden = true) @UserId final Long memberId + ) { + return BaseResponse.ok(foodTruckService.getTopRatedFoodTrucks(memberId)); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckTopRateResponse.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckTopRateResponse.java new file mode 100644 index 0000000..6b2db54 --- /dev/null +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckTopRateResponse.java @@ -0,0 +1,24 @@ +package konkuk.chacall.domain.foodtruck.presentation.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; + +public record FoodTruckTopRateResponse( + @Schema(description = "푸드트럭 식별자", example = "1") + Long foodTruckId, + @Schema(description = "푸드트럭 이름", example = "푸드트럭") + String name, + @Schema(description = "푸드트럭 대표 사진 URL", example = "http://image.png") + String photoUrl, + @Schema(description = "푸드트럭 평균 평점", example = "4.5") + Double averageRating +) { + public static FoodTruckTopRateResponse from(FoodTruck foodTruck) { + return new FoodTruckTopRateResponse( + foodTruck.getFoodTruckId(), + foodTruck.getFoodTruckInfo().getName(), + foodTruck.getFoodTruckInfo().getFoodTruckPhotoList().getMainPhotoUrl(), + foodTruck.getRatingInfo().getAverageRating() + ); + } +} From 3a39b30ac92477b9b959e0833437aacea0c96889 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Mon, 3 Nov 2025 15:34:02 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[docs]=20=EC=8A=A4=EC=9B=A8=EA=B1=B0=20?= =?UTF-8?q?=EB=AA=85=EC=84=B8=20(#24)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/common/swagger/SwaggerResponseDescription.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java b/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java index 437f441..28ef84a 100644 --- a/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java +++ b/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java @@ -264,6 +264,10 @@ public enum SwaggerResponseDescription { USER_FORBIDDEN, FOOD_TRUCK_STATUS_MISMATCH ))), + GET_TOP_RATED_FOOD_TRUCKS(new LinkedHashSet<>(Set.of( + USER_NOT_FOUND, + USER_FORBIDDEN + ))), // Default DEFAULT(new LinkedHashSet<>()) From 42dfeadd14da3b66933bcb457850d6f77e9407f9 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Thu, 6 Nov 2025 00:22:17 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[refactor]=20limit=20=EB=8C=80=EC=8B=A0=20p?= =?UTF-8?q?agerequest=EB=A1=9C=20=EC=BF=BC=EB=A6=AC=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20(#24)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foodtruck/application/info/FoodTruckInfoService.java | 5 ++++- .../foodtruck/domain/repository/FoodTruckRepository.java | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java b/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java index 7eb9aca..48b010c 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java @@ -20,6 +20,9 @@ import konkuk.chacall.global.common.exception.EntityNotFoundException; import konkuk.chacall.global.common.exception.code.ErrorCode; import lombok.RequiredArgsConstructor; +import org.springdoc.core.converters.models.Pageable; +import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; @@ -159,7 +162,7 @@ public FoodTruckDetailResponse getFoodTruckDetails(User member, Long foodTruckId } public List getTopRatedFoodTrucks() { - return foodTruckRepository.findTopRatedFoodTrucks(TOP_RATED_FOOD_TRUCK_LIMIT).stream() + return foodTruckRepository.findTopRatedFoodTrucks(PageRequest.of(0, TOP_RATED_FOOD_TRUCK_LIMIT)).stream() .map(FoodTruckTopRateResponse::from) .toList(); } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java index 01586a4..ac5be51 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckRepository.java @@ -10,7 +10,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import java.util.Collection; import java.util.List; import java.util.Optional; @@ -61,7 +60,6 @@ boolean existsByFoodTruckIdAndOwnerIdAndFoodTruckStatus( where f.foodTruckStatus = 'APPROVED' and f.foodTruckViewedStatus = 'ON' order by f.ratingInfo.averageRating desc, f.ratingInfo.ratingCount desc - limit :limit """) - List findTopRatedFoodTrucks(@Param("limit") int limit); + List findTopRatedFoodTrucks(Pageable pageable); } From 209461b398f6a6837625f4228f5447c55400c672 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Tue, 11 Nov 2025 17:44:13 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[chore]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20import=20=EC=A0=9C=EA=B1=B0=20(#24)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/foodtruck/application/info/FoodTruckInfoService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java b/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java index 48b010c..6c208d8 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java @@ -20,8 +20,6 @@ import konkuk.chacall.global.common.exception.EntityNotFoundException; import konkuk.chacall.global.common.exception.code.ErrorCode; import lombok.RequiredArgsConstructor; -import org.springdoc.core.converters.models.Pageable; -import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service;