From fd0dbaa1286dccc94549f5d59dd2e8cfe7c90146 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Tue, 21 Oct 2025 17:32:48 +0900 Subject: [PATCH 01/15] =?UTF-8?q?[refactor]=20=EC=A0=84=EA=B8=B0=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20=EC=97=AC=EB=B6=80=20=EA=B0=80=EB=8A=A5/?= =?UTF-8?q?=EB=B6=88=EA=B0=80=EB=8A=A5=EC=97=90=EC=84=9C=20=ED=95=84?= =?UTF-8?q?=EC=9A=94/=EB=B6=88=ED=95=84=EC=9A=94=EB=A1=9C=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=20=EC=88=98=EC=A0=95=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/foodtruck/domain/value/NeedElectricity.java | 4 ++-- .../presentation/dto/request/FoodTruckSearchRequest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java index f6a9e3df..7377616b 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java @@ -5,8 +5,8 @@ @Getter public enum NeedElectricity implements EnumValue { - REQUIRED("가능"), - NOT_REQUIRED("불가능"), + REQUIRED("필요"), + NOT_REQUIRED("불필요"), NEED_DISCUSSION("논의 필요"); private final String value; diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java index 484d58ba..5355769b 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java @@ -59,7 +59,7 @@ public record FoodTruckSearchRequest( schema = @Schema( type = "string", example = "논의 필요", - allowableValues = {"가능", "불가능", "논의 필요"} + allowableValues = {"필요", "불필요", "논의 필요"} ) ) NeedElectricity needElectricity, From 91afd60fa9c5b050940365472475c3dd3ca401ec Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Tue, 21 Oct 2025 18:07:52 +0900 Subject: [PATCH 02/15] =?UTF-8?q?[refactor]=20ddl-auto=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=20update=EB=A1=9C=20=EC=88=98=EC=A0=95=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-local.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 6ff2425e..8f008935 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -10,7 +10,7 @@ spring: jpa: hibernate: - ddl-auto: create + ddl-auto: update show-sql: true properties: hibernate: From e8fa91442a70656bc593ab83e3281c96f03d8974 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Tue, 21 Oct 2025 18:08:59 +0900 Subject: [PATCH 03/15] =?UTF-8?q?[refactor]=20FoodTruck=EC=97=90=EC=84=9C?= =?UTF-8?q?=20FoodTruckInfo=20=EA=B0=9D=EC=B2=B4=20=EC=B6=94=EC=B6=9C=20(#?= =?UTF-8?q?49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foodtruck/domain/model/FoodTruck.java | 54 +++--------------- .../repository/FoodTruckRepository.java | 3 +- .../infra/FoodTruckSearchRepositoryImpl.java | 9 +-- .../foodtruck/domain/value/FoodTruckInfo.java | 57 +++++++++++++++++++ .../dto/response/FoodTruckResponse.java | 10 ++-- .../MemberReservationDetailResponse.java | 6 +- .../MemberReservationHistoryResponse.java | 6 +- .../ReservationForRatingResponse.java | 6 +- .../dto/response/SavedFoodTruckResponse.java | 8 ++- .../dto/response/MyFoodTruckResponse.java | 10 ++-- .../OwnerReservationDetailResponse.java | 2 +- .../OwnerReservationHistoryResponse.java | 2 +- 12 files changed, 103 insertions(+), 70 deletions(-) create mode 100644 src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java index 1731931f..b563f013 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java @@ -26,39 +26,8 @@ public class FoodTruck extends BaseEntity { @Column(name = "food_truck_id", nullable = false) private Long foodTruckId; - @Column(nullable = false) - private String name; - - @Column(length = 300) - private String description; - - @Column(length = 15) - private String phoneNumber; - - private String activeTime; - - private Boolean timeDiscussRequired; - - @Convert(converter = PhotoUrlListConverter.class) - private PhotoUrlList foodTruckPhotoList; - - @Convert(converter = MenuCategoryListConverter.class) - private MenuCategoryList menuCategoryList; - - @Enumerated(EnumType.STRING) - private AvailableQuantity availableQuantity; - - @Enumerated(EnumType.STRING) - private NeedElectricity needElectricity; - - @Enumerated(EnumType.STRING) - private PaymentMethod paymentMethod; - - @Column(name = "operating_info", length = 800) - private String operatingInfo; - - @Column(name = "option", length = 800) - private String option; + @Embedded + private FoodTruckInfo foodTruckInfo; @Column(name = "rejection_reason", length = 30) private String rejectionReason; @@ -84,18 +53,7 @@ public class FoodTruck extends BaseEntity { public static FoodTruck createEmptyFoodTruck(User owner, String name) { return FoodTruck.builder() .owner(owner) - .name(name) - .description(null) - .phoneNumber(null) - .activeTime(null) - .timeDiscussRequired(null) - .foodTruckPhotoList(null) - .menuCategoryList(null) - .availableQuantity(null) - .needElectricity(null) - .paymentMethod(null) - .operatingInfo(null) - .option(null) + .foodTruckInfo(FoodTruckInfo.createEmptyFoodTruckInfo(name)) .rejectionReason(null) .foodTruckStatus(FoodTruckStatus.PENDING) .foodTruckViewedStatus(FoodTruckViewedStatus.OFF) @@ -113,6 +71,12 @@ public void validateOwner(Long ownerId) { } } + public void validateApprovedStatus() { + if (this.foodTruckStatus != FoodTruckStatus.APPROVED) { + throw new DomainRuleException(ErrorCode.FOOD_TRUCK_NOT_APPROVED); + } + } + public void updateAverageRating(double rating) { ratingInfo.updateAverageRating(rating); } 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 22738f95..740d120f 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 @@ -9,7 +9,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import java.util.Collection; import java.util.Optional; public interface FoodTruckRepository extends JpaRepository, FoodTruckSearchRepository { @@ -45,6 +44,6 @@ boolean existsByFoodTruckIdAndOwnerIdAndFoodTruckStatus( @Param("status") FoodTruckStatus status ); - boolean existsByName(String name); + boolean existsByFoodTruckInfo_Name(String name); } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java index 7043c8ed..fa2d53b2 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java @@ -34,6 +34,7 @@ public FoodTruckSearchRepositoryImpl(JPAQueryFactory query) { @Override public Slice getFoodTrucks(FoodTruckSearchRequest request) { BooleanBuilder where = new BooleanBuilder(); + QFoodTruckInfo foodTruckInfo = foodTruck.foodTruckInfo; // 지역 - prefix if (request.regionCodes() != null && !request.regionCodes().isEmpty()) { @@ -74,7 +75,7 @@ public Slice getFoodTrucks(FoodTruckSearchRequest request) { // 수량 if (request.availableQuantity() != null) { - where.and(foodTruck.availableQuantity.in( + where.and(foodTruckInfo.availableQuantity.in( AvailableQuantity.acceptableFor(request.availableQuantity()) )); } @@ -85,7 +86,7 @@ public Slice getFoodTrucks(FoodTruckSearchRequest request) { for (MenuCategory category : request.categories()) { any.or(Expressions.booleanTemplate( "concat(',', {0}, ',') like concat('%,', {1}, ',%')", - foodTruck.menuCategoryList, + foodTruckInfo.menuCategoryList, Expressions.constant(category.getValue()) )); } @@ -94,12 +95,12 @@ public Slice getFoodTrucks(FoodTruckSearchRequest request) { // 전기 if(request.needElectricity() != null) { - where.and(foodTruck.needElectricity.eq(request.needElectricity())); + where.and(foodTruckInfo.needElectricity.eq(request.needElectricity())); } // 결제방법 if (request.paymentMethod() != null && request.paymentMethod() != PaymentMethod.ANY) { - where.and(foodTruck.paymentMethod.eq(request.paymentMethod())); + where.and(foodTruckInfo.paymentMethod.eq(request.paymentMethod())); } // 푸드트럭 상태 diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java new file mode 100644 index 00000000..5793fb0e --- /dev/null +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java @@ -0,0 +1,57 @@ +package konkuk.chacall.domain.foodtruck.domain.value; + +import jakarta.persistence.*; +import konkuk.chacall.global.common.converter.MenuCategoryListConverter; +import konkuk.chacall.global.common.converter.PhotoUrlListConverter; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@Embeddable +public class FoodTruckInfo { + + @Column(nullable = false) + private String name; + + @Column(length = 300) + private String description; + + @Column(length = 15) + private String phoneNumber; + + private String activeTime; + + private Boolean timeDiscussRequired; + + @Convert(converter = PhotoUrlListConverter.class) + private PhotoUrlList foodTruckPhotoList; + + @Convert(converter = MenuCategoryListConverter.class) + private MenuCategoryList menuCategoryList; + + @Enumerated(EnumType.STRING) + private AvailableQuantity availableQuantity; + + @Enumerated(EnumType.STRING) + private NeedElectricity needElectricity; + + @Enumerated(EnumType.STRING) + private PaymentMethod paymentMethod; + + @Column(name = "operating_info", length = 800) + private String operatingInfo; + + @Column(name = "option", length = 800) + private String option; + + public static FoodTruckInfo createEmptyFoodTruckInfo(String name) { + return FoodTruckInfo.builder() + .name(name) + .build(); + } +} diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java index 2f869c0f..da112ed5 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; +import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckInfo; import java.util.List; @@ -25,12 +26,13 @@ public record FoodTruckResponse( ) { public static FoodTruckResponse of(FoodTruck foodTruck, boolean isSaved) { + FoodTruckInfo foodTruckInfo = foodTruck.getFoodTruckInfo(); return new FoodTruckResponse( foodTruck.getFoodTruckId(), - foodTruck.getName(), - foodTruck.getFoodTruckPhotoList().getMainPhotoUrl(), // 대표 사진 (첫 번째 사진) - foodTruck.getDescription(), - foodTruck.getMenuCategoryList().getMenuCategoryLabelList(), + foodTruckInfo.getName(), + foodTruckInfo.getFoodTruckPhotoList().getMainPhotoUrl(), // 대표 사진 (첫 번째 사진) + foodTruckInfo.getDescription(), + foodTruckInfo.getMenuCategoryList().getMenuCategoryLabelList(), foodTruck.getRatingInfo().getAverageRating(), foodTruck.getRatingInfo().getRatingCount(), isSaved diff --git a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java index b296eb2e..2a600518 100644 --- a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java +++ b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; +import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckInfo; import konkuk.chacall.domain.reservation.domain.model.Reservation; import konkuk.chacall.domain.reservation.domain.value.ReservationStatus; @@ -43,10 +44,11 @@ public record MemberReservationDetailResponse( public static MemberReservationDetailResponse of(Reservation reservation, FoodTruck foodTruck) { List dateTimeList = reservation.getReservationInfo().getFormattedDateTimeInfos(); + FoodTruckInfo foodTruckInfo = foodTruck.getFoodTruckInfo(); return new MemberReservationDetailResponse( - foodTruck.getFoodTruckPhotoList().getMainPhotoUrl(), - foodTruck.getName(), + foodTruckInfo.getFoodTruckPhotoList().getMainPhotoUrl(), + foodTruckInfo.getName(), reservation.getReservationInfo().getFullAddress(), dateTimeList, reservation.getReservationStatus() == ReservationStatus.CANCELLED ? // 예약 취소 상태이면 null 반환 diff --git a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationHistoryResponse.java b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationHistoryResponse.java index 2a2efa60..d88e08ab 100644 --- a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationHistoryResponse.java +++ b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationHistoryResponse.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; +import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckInfo; import konkuk.chacall.domain.reservation.domain.model.Reservation; import java.util.List; @@ -24,11 +25,12 @@ public record MemberReservationHistoryResponse( public static MemberReservationHistoryResponse of(Reservation reservation, FoodTruck foodTruck) { List dateTimeList = reservation.getReservationInfo().getFormattedDateTimeInfos(); + FoodTruckInfo foodTruckInfo = foodTruck.getFoodTruckInfo(); return new MemberReservationHistoryResponse( reservation.getReservationId(), - foodTruck.getFoodTruckPhotoList().getMainPhotoUrl(), - foodTruck.getName(), + foodTruckInfo.getFoodTruckPhotoList().getMainPhotoUrl(), + foodTruckInfo.getName(), reservation.getReservationInfo().getFullAddress(), dateTimeList, reservation.getReservationStatus().getValue() diff --git a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/ReservationForRatingResponse.java b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/ReservationForRatingResponse.java index 717c0f83..2ce2e04e 100644 --- a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/ReservationForRatingResponse.java +++ b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/ReservationForRatingResponse.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; +import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckInfo; import konkuk.chacall.domain.reservation.domain.model.Reservation; import java.util.List; @@ -32,12 +33,13 @@ public record ReservationForRating( ) { public static ReservationForRating of(FoodTruck foodTruck, Reservation reservation) { List dateTimeList = reservation.getReservationInfo().getFormattedDateTimeInfos(); + FoodTruckInfo foodTruckInfo = foodTruck.getFoodTruckInfo(); return new ReservationForRating( reservation.getReservationId(), foodTruck.getFoodTruckId(), - foodTruck.getName(), - foodTruck.getFoodTruckPhotoList().getMainPhotoUrl(), // 대표 사진 (첫 번째 사진) + foodTruckInfo.getName(), + foodTruckInfo.getFoodTruckPhotoList().getMainPhotoUrl(), // 대표 사진 (첫 번째 사진) reservation.getReservationInfo().getFullAddress(), dateTimeList ); diff --git a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/SavedFoodTruckResponse.java b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/SavedFoodTruckResponse.java index ca76ddfb..c3571214 100644 --- a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/SavedFoodTruckResponse.java +++ b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/SavedFoodTruckResponse.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; +import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckInfo; public record SavedFoodTruckResponse( @Schema(description = "푸드트럭 식별자", example = "1") @@ -18,11 +19,12 @@ public record SavedFoodTruckResponse( Integer ratingCount ) { public static SavedFoodTruckResponse of(FoodTruck foodTruck) { + FoodTruckInfo foodTruckInfo = foodTruck.getFoodTruckInfo(); return new SavedFoodTruckResponse( foodTruck.getFoodTruckId(), - foodTruck.getName(), - foodTruck.getFoodTruckPhotoList().getMainPhotoUrl(), // 대표 사진 (첫 번째 사진) - foodTruck.getDescription(), + foodTruckInfo.getName(), + foodTruckInfo.getFoodTruckPhotoList().getMainPhotoUrl(), // 대표 사진 (첫 번째 사진) + foodTruckInfo.getDescription(), foodTruck.getRatingInfo().getAverageRating(), foodTruck.getRatingInfo().getRatingCount() ); diff --git a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckResponse.java b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckResponse.java index 37515490..ae57baf0 100644 --- a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckResponse.java +++ b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckResponse.java @@ -3,6 +3,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; import konkuk.chacall.domain.foodtruck.domain.model.FoodTruckServiceArea; +import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckInfo; import java.util.List; @@ -29,15 +30,16 @@ public record MyFoodTruckResponse( * @return MyFoodTruckResponse DTO */ public static MyFoodTruckResponse of(FoodTruck foodTruck, List serviceAreas) { + FoodTruckInfo foodTruckInfo = foodTruck.getFoodTruckInfo(); // 대표 이미지 - String mainImageUrl = foodTruck.getFoodTruckPhotoList().getMainPhotoUrl(); + String mainImageUrl = foodTruckInfo.getFoodTruckPhotoList().getMainPhotoUrl(); return new MyFoodTruckResponse( foodTruck.getFoodTruckId(), mainImageUrl, - foodTruck.getName(), - foodTruck.getDescription(), - foodTruck.getActiveTime(), + foodTruckInfo.getName(), + foodTruckInfo.getDescription(), + foodTruckInfo.getActiveTime(), foodTruck.getServiceAreas(serviceAreas), foodTruck.getFoodTruckViewedStatus().name() ); diff --git a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationDetailResponse.java b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationDetailResponse.java index e40d6704..2e473f6c 100644 --- a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationDetailResponse.java +++ b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationDetailResponse.java @@ -48,7 +48,7 @@ public static OwnerReservationDetailResponse of(Reservation reservation, User me // boolean 값을 화면에 표시할 문자열로 변환 return new OwnerReservationDetailResponse( - reservation.getFoodTruck().getName(), + reservation.getFoodTruck().getFoodTruckInfo().getName(), member.getProfileImageUrl(), member.getName(), reservation.getReservationInfo().getFullAddress(), diff --git a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationHistoryResponse.java b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationHistoryResponse.java index 5258e894..9af29547 100644 --- a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationHistoryResponse.java +++ b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/OwnerReservationHistoryResponse.java @@ -33,7 +33,7 @@ public static OwnerReservationHistoryResponse of(Reservation reservation, User m member.getName(), reservation.getReservationInfo().getFullAddress(), dateTimeList, - reservation.getFoodTruck().getName(), + reservation.getFoodTruck().getFoodTruckInfo().getName(), reservation.getReservationStatus().getValue() ); } From b6e9dc7b41e6a697570e26e6b55dd89c47932b46 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Tue, 21 Oct 2025 18:09:22 +0900 Subject: [PATCH 04/15] =?UTF-8?q?[feat]=20=ED=91=B8=EB=93=9C=ED=8A=B8?= =?UTF-8?q?=EB=9F=AD=20=EC=A0=95=EB=B3=B4=EA=B8=B0=EC=9E=85/=EC=88=98?= =?UTF-8?q?=EC=A0=95=20api=20dto=20=EC=84=A0=EC=96=B8=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/UpdateFoodTruckInfoRequest.java | 83 +++++++++++++++++++ .../dto/response/FoodTruckIdResponse.java | 9 ++ 2 files changed, 92 insertions(+) create mode 100644 src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java create mode 100644 src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckIdResponse.java diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java new file mode 100644 index 00000000..e6b8dd4d --- /dev/null +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java @@ -0,0 +1,83 @@ +package konkuk.chacall.domain.foodtruck.presentation.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import konkuk.chacall.domain.foodtruck.domain.value.AvailableQuantity; +import konkuk.chacall.domain.foodtruck.domain.value.MenuCategory; +import konkuk.chacall.domain.foodtruck.domain.value.NeedElectricity; +import konkuk.chacall.domain.foodtruck.domain.value.PaymentMethod; + +import java.util.List; + +public record UpdateFoodTruckInfoRequest ( + @Schema(description = "푸드트럭 이름", example = "맛있는 푸드트럭") + @NotBlank(message = "푸드트럭 이름은 필수 입력 값입니다.") + String name, + + @Schema(description = "푸드트럭 설명", example = "저희 푸드트럭은 신선한 재료로 만든 음식을 제공합니다.") + @NotBlank(message = "푸드트럭 설명은 필수 입력 값입니다.") + String description, + + @Schema(description = "푸드트럭 전화번호", example = "010-1234-5678") + @NotBlank(message = "푸드트럭 전화번호는 필수 입력 값입니다.") + String phoneNumber, + + @Schema(description = "운영 시간대 (형식: HH:MM ~ HH:MM)", example = "10:00 ~ 18:00") + @NotBlank(message = "운영 시간대는 필수 입력 값입니다.") + String activeTime, + + @Schema(description = "시간 상의 필요 여부", example = "true") + @NotNull(message = "시간 상의 필요 여부는 필수 입력 값입니다.") + Boolean timeDiscussRequired, + + @Schema(description = "푸드트럭 서비스 가능 지역 ID 리스트", example = "[1, 2, 3]") + @Size(min = 1, max = 10, message = "서비스 가능 지역은 최소 1개 최대 10개 선택 가능합니다.") + List<@NotNull Long> foodTruckServiceAreas, + + @Schema(description = "메뉴 카테고리 리스트", example = "[\"한식\", \"분식\"]") + @Size(min = 1, max = 12, message = "메뉴 카테고리는 최소 1개 최대 12개 선택 가능합니다.") + List<@NotNull MenuCategory> menuCategories, + + @Schema(description = "제조 가능 수량", example = "100인분 미만", allowableValues = { + "50인분 미만", + "100인분 미만", + "150인분 미만", + "200인분 이상", + "논의 필요" + }) + @NotNull(message = "제조 가능 수량은 필수 입력 값입니다.") + AvailableQuantity availableQuantity, + + @Schema(description = "전기 필요 여부", example = "필요", allowableValues = { + "필요", + "불필요", + "논의 필요" + }) + @NotNull(message = "전기 사용 여부는 필수 입력 값입니다.") + NeedElectricity needElectricity, + + @Schema(description = "결제 수단", example = "계좌이체", allowableValues = { + "무관", + "계좌이체", + "카드" + }) + @NotNull(message = "결제 수단은 필수 입력 값입니다.") + PaymentMethod paymentMethod, + + @Schema(description = "운영 가능 날짜 리스트", example = "[{\"startDate\":\"2024.10.01\",\"endDate\":\"2024.10.10\"}]") + @Size(min = 1, max = 2, message = "운영 가능 날짜는 최소 1개, 최대 2개까지 등록 가능합니다.") + List availableDates, + + @Schema(description = "푸드트럭 사진 URL 리스트", example = "[\"http://image1.png\", \"http://image2.png\"]") + @Size(min = 1, max = 9, message = "푸드트럭 사진은 최소 1개 최대 9개까지 등록 가능합니다.") + List<@NotBlank String> photoUrl, + + @Schema(description = "운영 정보", example = "맛있는 음식을 신속하게 제공합니다.") + String operatingInfo, + + @Schema(description = "기타 옵션", example = "추가 요청 사항이 있으면 기재해주세요.") + String option +) { +} diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckIdResponse.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckIdResponse.java new file mode 100644 index 00000000..9805e034 --- /dev/null +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckIdResponse.java @@ -0,0 +1,9 @@ +package konkuk.chacall.domain.foodtruck.presentation.dto.response; + +public record FoodTruckIdResponse( + Long foodTruckId +) { + public static FoodTruckIdResponse of(Long foodTruckId) { + return new FoodTruckIdResponse(foodTruckId); + } +} From 03d0e56e082468617596214e3921798893efaf33 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Tue, 21 Oct 2025 18:09:27 +0900 Subject: [PATCH 05/15] =?UTF-8?q?[feat]=20=ED=91=B8=EB=93=9C=ED=8A=B8?= =?UTF-8?q?=EB=9F=AD=20=EC=A0=95=EB=B3=B4=EA=B8=B0=EC=9E=85/=EC=88=98?= =?UTF-8?q?=EC=A0=95=20api=20=ED=95=B8=EB=93=A4=EB=9F=AC=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/FoodTruckController.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) 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 72fcc10c..aea26693 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java @@ -5,16 +5,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import konkuk.chacall.domain.foodtruck.application.FoodTruckService; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.ImageRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckMenuRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckNameDuplicateCheckRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckSearchRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckMenuResponse; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckNameDuplicateCheckResponse; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckResponse; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.ImageResponse; -import konkuk.chacall.domain.owner.presentation.dto.request.MyFoodTruckMenuRequest; -import konkuk.chacall.domain.owner.presentation.dto.response.MyFoodTruckMenuResponse; +import konkuk.chacall.domain.foodtruck.presentation.dto.request.*; +import konkuk.chacall.domain.foodtruck.presentation.dto.response.*; import konkuk.chacall.global.common.annotation.ExceptionDescription; import konkuk.chacall.global.common.annotation.UserId; import konkuk.chacall.global.common.dto.BaseResponse; @@ -100,4 +92,19 @@ public BaseResponse> getFoodTruckMen @Parameter(hidden = true) @UserId final Long memberId) { return BaseResponse.ok(foodTruckService.getFoodTruckMenus(memberId, foodTruckId, request)); } + + @Operation( + summary = "나의 푸드트럭 정보 기입/수정", + description = "승인이 완료된 나의 푸드트럭 정보를 기입하거나 수정합니다." + ) + @PutMapping("{foodTruckId}") + public BaseResponse updateMyFoodTruckInfo( + @PathVariable final Long foodTruckId, + @Valid @RequestBody final UpdateFoodTruckInfoRequest request, + @Parameter(hidden = true) @UserId final Long ownerId + ) { + return BaseResponse.ok(foodTruckService.updateMyFoodTruckInfo(ownerId, foodTruckId, request)); + } + + } From 21cbb56e6dee5a09a61fd96896554302c41a4e4c Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Wed, 22 Oct 2025 00:42:22 +0900 Subject: [PATCH 06/15] =?UTF-8?q?[refactor]=20=ED=91=B8=EB=93=9C=ED=8A=B8?= =?UTF-8?q?=EB=9F=AD=20=EC=A0=95=EB=B3=B4=EA=B8=B0=EC=9E=85=EC=9D=B4=20?= =?UTF-8?q?=EB=90=98=EC=96=B4=EC=9E=88=EC=96=B4=EC=95=BC=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=20=EC=83=81=ED=83=9C=20=EB=B3=80=EA=B2=BD=EC=9D=B4=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(=EC=BB=AC=EB=9F=BC=EC=B6=94=EA=B0=80)=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foodtruck/domain/model/FoodTruck.java | 47 ++++++++++++++++++- .../swagger/SwaggerResponseDescription.java | 3 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java index b563f013..2ba5bbb9 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java @@ -3,8 +3,6 @@ import jakarta.persistence.*; import konkuk.chacall.domain.foodtruck.domain.value.*; import konkuk.chacall.domain.user.domain.model.User; -import konkuk.chacall.global.common.converter.MenuCategoryListConverter; -import konkuk.chacall.global.common.converter.PhotoUrlListConverter; import konkuk.chacall.global.common.domain.BaseEntity; import konkuk.chacall.global.common.exception.DomainRuleException; import konkuk.chacall.global.common.exception.code.ErrorCode; @@ -46,6 +44,11 @@ public class FoodTruck extends BaseEntity { @Column(nullable = false, length = 3) private FoodTruckViewedStatus foodTruckViewedStatus = FoodTruckViewedStatus.OFF; + //todo 컬럼 추가 후 기존 데이터 변경한 다음 다시 주석 해제할 예정 + @Builder.Default +// @Column(nullable = false) + private Boolean canChangeViewedStatus = false; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User owner; @@ -77,6 +80,41 @@ public void validateApprovedStatus() { } } + // 푸드트럭 노출 상태 변경 허용 (최소 1번의 정보 기입 후) + public void permitChangeViewStatus() { + this.canChangeViewedStatus = true; + } + + public void updateFoodTruckInfo( + String name, + String description, + String phoneNumber, + String activeTime, + Boolean timeDiscussRequired, + List photoUrls, + List menuCategories, + AvailableQuantity availableQuantity, + NeedElectricity needElectricity, + PaymentMethod paymentMethod, + String operatingInfo, + String option + ) { + this.foodTruckInfo.updateFoodTruckInfo( + name, + description, + phoneNumber, + activeTime, + timeDiscussRequired, + PhotoUrlList.of(photoUrls), + MenuCategoryList.of(menuCategories), + availableQuantity, + needElectricity, + paymentMethod, + operatingInfo, + option + ); + } + public void updateAverageRating(double rating) { ratingInfo.updateAverageRating(rating); } @@ -110,6 +148,11 @@ public void changeViewedStatus(FoodTruckViewedStatus targetViewedStatus) { throw new DomainRuleException(ErrorCode.INVALID_FOOD_TRUCK_STATUS_TRANSITION); } + if(!this.canChangeViewedStatus) { + throw new DomainRuleException(ErrorCode.FOOD_TRUCK_VIEWED_STATUS_CHANGE_NOT_PERMITTED, + new IllegalArgumentException("최소 1번의 정보 기입 후에만 푸드트럭 노출 상태를 변경할 수 있습니다.")); + } + this.foodTruckViewedStatus = targetViewedStatus; } } 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 e2069c5f..06dc304a 100644 --- a/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java +++ b/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java @@ -94,7 +94,8 @@ public enum SwaggerResponseDescription { USER_NOT_FOUND, USER_FORBIDDEN, FOOD_TRUCK_NOT_APPROVED, - INVALID_FOOD_TRUCK_STATUS_TRANSITION + INVALID_FOOD_TRUCK_STATUS_TRANSITION, + FOOD_TRUCK_VIEWED_STATUS_CHANGE_NOT_PERMITTED ))), OWNER_GET_FOOD_TRUCK_MENUS(new LinkedHashSet<>(Set.of( USER_NOT_FOUND, From 4cad11eff2f2062095aca4242ab054161db24c37 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Wed, 22 Oct 2025 02:05:05 +0900 Subject: [PATCH 07/15] =?UTF-8?q?[feat]=20json=20body=EC=97=90=EC=84=9C=20?= =?UTF-8?q?enum=20=EC=9E=90=EB=8F=99=20=EB=A7=A4=ED=95=91=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foodtruck/domain/value/AvailableQuantity.java | 13 +++++++++++++ .../domain/foodtruck/domain/value/MenuCategory.java | 6 +++++- .../foodtruck/domain/value/NeedElectricity.java | 13 +++++++++++++ .../foodtruck/domain/value/PaymentMethod.java | 13 +++++++++++++ .../dto/request/UpdateFoodTruckInfoRequest.java | 8 +++++--- .../global/common/exception/code/ErrorCode.java | 10 ++++++++++ 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java index 3a18c529..ebf2c889 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java @@ -1,6 +1,9 @@ package konkuk.chacall.domain.foodtruck.domain.value; +import com.fasterxml.jackson.annotation.JsonCreator; import konkuk.chacall.global.common.dto.EnumValue; +import konkuk.chacall.global.common.exception.DomainRuleException; +import konkuk.chacall.global.common.exception.code.ErrorCode; import lombok.Getter; import java.util.EnumSet; @@ -20,6 +23,16 @@ public enum AvailableQuantity implements EnumValue { this.value = value; } + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static AvailableQuantity from(String value) { + for (AvailableQuantity quantity : AvailableQuantity.values()) { + if (quantity.getValue().equals(value)) { + return quantity; + } + } + throw new DomainRuleException(ErrorCode.AVAILABLE_QUANTITY_MISMATCH); + } + // 요청된 수량 기준을 만족하는 트럭의 가능한 값 집합 public static EnumSet acceptableFor(AvailableQuantity req) { if (req == null) return EnumSet.noneOf(AvailableQuantity.class); diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/MenuCategory.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/MenuCategory.java index 2df7312b..994979f7 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/MenuCategory.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/MenuCategory.java @@ -1,6 +1,9 @@ package konkuk.chacall.domain.foodtruck.domain.value; +import com.fasterxml.jackson.annotation.JsonCreator; import konkuk.chacall.global.common.dto.EnumValue; +import konkuk.chacall.global.common.exception.DomainRuleException; +import konkuk.chacall.global.common.exception.code.ErrorCode; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -22,12 +25,13 @@ public enum MenuCategory implements EnumValue { private final String value; + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) public static MenuCategory from(String value) { for (MenuCategory category : MenuCategory.values()) { if (category.getValue().equals(value)) { return category; } } - throw new IllegalArgumentException("Unknown MenuCategory value: " + value); + throw new DomainRuleException(ErrorCode.MENU_CATEGORY_MISMATCH); } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java index 7377616b..96a84dc0 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/NeedElectricity.java @@ -1,6 +1,9 @@ package konkuk.chacall.domain.foodtruck.domain.value; +import com.fasterxml.jackson.annotation.JsonCreator; import konkuk.chacall.global.common.dto.EnumValue; +import konkuk.chacall.global.common.exception.DomainRuleException; +import konkuk.chacall.global.common.exception.code.ErrorCode; import lombok.Getter; @Getter @@ -14,4 +17,14 @@ public enum NeedElectricity implements EnumValue { NeedElectricity(String value) { this.value = value; } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static NeedElectricity from(String value) { + for (NeedElectricity needElectricity : NeedElectricity.values()) { + if (needElectricity.getValue().equals(value)) { + return needElectricity; + } + } + throw new DomainRuleException(ErrorCode.NEED_ELECTRICITY_MISMATCH); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/PaymentMethod.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/PaymentMethod.java index 2e8aaa4c..f487a9e7 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/PaymentMethod.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/PaymentMethod.java @@ -1,6 +1,9 @@ package konkuk.chacall.domain.foodtruck.domain.value; +import com.fasterxml.jackson.annotation.JsonCreator; import konkuk.chacall.global.common.dto.EnumValue; +import konkuk.chacall.global.common.exception.DomainRuleException; +import konkuk.chacall.global.common.exception.code.ErrorCode; import lombok.Getter; @Getter @@ -14,4 +17,14 @@ public enum PaymentMethod implements EnumValue { PaymentMethod(String value) { this.value = value; } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static PaymentMethod from(String value) { + for (PaymentMethod method : PaymentMethod.values()) { + if (method.getValue().equals(value)) { + return method; + } + } + throw new DomainRuleException(ErrorCode.PAYMENT_METHOD_MISMATCH); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java index e6b8dd4d..8b0cd34d 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java @@ -3,6 +3,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; import konkuk.chacall.domain.foodtruck.domain.value.AvailableQuantity; import konkuk.chacall.domain.foodtruck.domain.value.MenuCategory; @@ -24,7 +25,8 @@ public record UpdateFoodTruckInfoRequest ( @NotBlank(message = "푸드트럭 전화번호는 필수 입력 값입니다.") String phoneNumber, - @Schema(description = "운영 시간대 (형식: HH:MM ~ HH:MM)", example = "10:00 ~ 18:00") + @Schema(description = "운영 시간대 (형식: HH:MM-HH:MM)", example = "10:00-18:00") + @Pattern(regexp = "^(?:[01]\\d|2[0-3]):[0-5]\\d-(?:[01]\\d|2[0-3]):[0-5]\\d$", message = "운영 시간대는 'HH:MM-HH:MM' 형식이어야 합니다.") @NotBlank(message = "운영 시간대는 필수 입력 값입니다.") String activeTime, @@ -67,12 +69,12 @@ public record UpdateFoodTruckInfoRequest ( PaymentMethod paymentMethod, @Schema(description = "운영 가능 날짜 리스트", example = "[{\"startDate\":\"2024.10.01\",\"endDate\":\"2024.10.10\"}]") - @Size(min = 1, max = 2, message = "운영 가능 날짜는 최소 1개, 최대 2개까지 등록 가능합니다.") + @Size(min = 1, max = 4, message = "운영 가능 날짜는 최소 1개, 최대 4개까지 등록 가능합니다.") List availableDates, @Schema(description = "푸드트럭 사진 URL 리스트", example = "[\"http://image1.png\", \"http://image2.png\"]") @Size(min = 1, max = 9, message = "푸드트럭 사진은 최소 1개 최대 9개까지 등록 가능합니다.") - List<@NotBlank String> photoUrl, + List<@NotBlank String> photoUrls, @Schema(description = "운영 정보", example = "맛있는 음식을 신속하게 제공합니다.") String operatingInfo, diff --git a/src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java b/src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java index da0c349e..9d4285c1 100644 --- a/src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java +++ b/src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java @@ -78,6 +78,11 @@ public enum ErrorCode implements ResponseCode { FOOD_TRUCK_NOT_OWNED(HttpStatus.FORBIDDEN, 110002, "해당 푸드트럭의 소유자가 아닙니다."), FOOD_TRUCK_NOT_APPROVED(HttpStatus.FORBIDDEN, 110003, "승인된 푸드트럭이 아닙니다."), INVALID_FOOD_TRUCK_STATUS_TRANSITION(HttpStatus.BAD_REQUEST, 110004, "허용되지 않은 푸드트럭 상태 변경입니다."), + FOOD_TRUCK_VIEWED_STATUS_CHANGE_NOT_PERMITTED(HttpStatus.BAD_REQUEST, 110005, "푸드트럭 노출 상태 변경이 허용되지 않았습니다."), + MENU_CATEGORY_MISMATCH(HttpStatus.BAD_REQUEST, 110006, "메뉴 카테고리 값이 올바르지 않습니다."), + AVAILABLE_QUANTITY_MISMATCH(HttpStatus.BAD_REQUEST, 110007, "제조 가능 수량 값이 올바르지 않습니다."), + NEED_ELECTRICITY_MISMATCH(HttpStatus.BAD_REQUEST, 110008, "전기 사용 여부 값이 올바르지 않습니다."), + PAYMENT_METHOD_MISMATCH(HttpStatus.BAD_REQUEST, 110009, "결제 수단 값이 올바르지 않습니다."), INVALID_IMAGE_COUNT(HttpStatus.BAD_REQUEST, 115001, "이미지 개수가 유효하지 않습니다."), INVALID_FILE_EXTENSION(HttpStatus.BAD_REQUEST, 115002, "허용되지 않는 파일 확장자입니다."), @@ -99,6 +104,11 @@ public enum ErrorCode implements ResponseCode { */ MENU_NOT_FOUND(HttpStatus.NOT_FOUND, 140001, "메뉴를 찾을 수 없습니다."), INVALID_MENU_STATUS_TRANSITION(HttpStatus.BAD_REQUEST, 140002, "허용되지 않은 메뉴 상태 변경입니다."), + + /** + * FoodTruckServiceArea + */ + FOOD_TRUCK_SERVICE_AREA_NOT_FOUND(HttpStatus.NOT_FOUND, 150001, "푸드트럭 서비스 지역을 찾을 수 없습니다.") ; private final HttpStatus httpStatus; From f832e709a395d73cfb44fe2c097a05e5898206b3 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Wed, 22 Oct 2025 02:05:40 +0900 Subject: [PATCH 08/15] =?UTF-8?q?[feat]=20S3=EC=97=90=EC=84=9C=20=ED=91=B8?= =?UTF-8?q?=EB=93=9C=ED=8A=B8=EB=9F=AD=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EB=A5=BC=20=EC=82=AD=EC=A0=9C=ED=95=98?= =?UTF-8?q?=EB=8A=94=20api=20=EA=B5=AC=ED=98=84=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/FoodTruckImageService.java | 17 +++++++++++++++++ .../presentation/FoodTruckController.java | 18 ++++++++++++++++-- .../request/DeleteFoodTruckImagesRequest.java | 13 +++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/DeleteFoodTruckImagesRequest.java diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/application/image/FoodTruckImageService.java b/src/main/java/konkuk/chacall/domain/foodtruck/application/image/FoodTruckImageService.java index 21592650..5f94834a 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/application/image/FoodTruckImageService.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/application/image/FoodTruckImageService.java @@ -1,5 +1,8 @@ package konkuk.chacall.domain.foodtruck.application.image; +import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; +import konkuk.chacall.domain.foodtruck.domain.repository.FoodTruckRepository; +import konkuk.chacall.domain.foodtruck.presentation.dto.request.DeleteFoodTruckImagesRequest; import konkuk.chacall.domain.foodtruck.presentation.dto.request.ImageRequest; import konkuk.chacall.domain.foodtruck.presentation.dto.response.ImageResponse; import konkuk.chacall.domain.user.domain.model.User; @@ -7,6 +10,7 @@ import konkuk.chacall.global.common.exception.code.ErrorCode; import konkuk.chacall.global.common.storage.S3Service; import konkuk.chacall.global.common.storage.util.AllowedFileExtension; +import konkuk.chacall.global.common.storage.util.CdnUrlResolver; import konkuk.chacall.global.common.storage.util.KeyUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,7 +22,9 @@ public class FoodTruckImageService { private final S3Service s3Service; + private final CdnUrlResolver cdnUrlResolver; private static final int MAX_FOOD_TRUCK_IMAGE_COUNT = 9; + private final FoodTruckRepository foodTruckRepository; // private static final int MAX_MENU_IMAGE_COUNT = 5; public ImageResponse createFoodTruckImagePresignedUrl(ImageRequest request, User owner) { @@ -65,4 +71,15 @@ public ImageResponse createMenuImagePresignedUrl(ImageRequest request, User owne return ImageResponse.of(imageInfos); } + + public void deleteFoodTruckImagesFromS3(User owner, Long foodTruckId, DeleteFoodTruckImagesRequest request) { + FoodTruck foodTruck = foodTruckRepository.findById(foodTruckId) + .orElseThrow(() -> new BusinessException(ErrorCode.FOOD_TRUCK_NOT_FOUND)); + + foodTruck.validateOwner(owner.getUserId()); + + request.imageUrls().stream() + .map(cdnUrlResolver::extractKeyFromUrl) + .forEach(s3Service::delete); + } } \ No newline at end of file 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 aea26693..1a37a52f 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java @@ -94,17 +94,31 @@ public BaseResponse> getFoodTruckMen } @Operation( - summary = "나의 푸드트럭 정보 기입/수정", + summary = "나의 푸드트럭 정보 등록/수정", description = "승인이 완료된 나의 푸드트럭 정보를 기입하거나 수정합니다." ) @PutMapping("{foodTruckId}") public BaseResponse updateMyFoodTruckInfo( - @PathVariable final Long foodTruckId, + @Parameter(description = "푸드트럭 ID", example = "1") @PathVariable final Long foodTruckId, @Valid @RequestBody final UpdateFoodTruckInfoRequest request, @Parameter(hidden = true) @UserId final Long ownerId ) { return BaseResponse.ok(foodTruckService.updateMyFoodTruckInfo(ownerId, foodTruckId, request)); } + @Operation( + summary = "S3에서 푸드트럭 이미지 객체(메뉴 포함 x) 삭제", + description = "S3에서 푸드트럭 이미지 객체를 삭제합니다. 사용자가 기존 푸드트럭 이미지를 삭제했을 경우 나의 푸드트럭 정보 등록/수정 API 호출 이후 호출해주세요." + ) + @DeleteMapping("{foodTruckId}/images") + public BaseResponse deleteFoodTruckImagesFromS3( + @Parameter(description = "푸드트럭 ID", example = "1") @PathVariable final Long foodTruckId, + @Valid @RequestBody final DeleteFoodTruckImagesRequest request, + @Parameter(hidden = true) @UserId final Long ownerId + ) { + foodTruckService.deleteFoodTruckImagesFromS3(ownerId, foodTruckId, request); + return BaseResponse.ok(null); + } + } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/DeleteFoodTruckImagesRequest.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/DeleteFoodTruckImagesRequest.java new file mode 100644 index 00000000..7a522473 --- /dev/null +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/DeleteFoodTruckImagesRequest.java @@ -0,0 +1,13 @@ +package konkuk.chacall.domain.foodtruck.presentation.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Size; + +import java.util.List; + +public record DeleteFoodTruckImagesRequest( + @Schema(description = "삭제할 이미지 URL 목록", example = "[\"https://example.com/image1.jpg\", \"https://example.com/image2.jpg\"]") + @Size(min = 1, message = "최소 1개의 이미지 URL을 제공해야 합니다.") + List imageUrls +) { +} From 96f34457511e8f1b7f939db647cb21eee63ee29e Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Wed, 22 Oct 2025 02:58:26 +0900 Subject: [PATCH 09/15] =?UTF-8?q?[feat]=20=ED=91=B8=EB=93=9C=ED=8A=B8?= =?UTF-8?q?=EB=9F=AD=20=EC=A0=95=EB=B3=B4=20=EB=93=B1=EB=A1=9D/=EC=88=98?= =?UTF-8?q?=EC=A0=95=20api=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/FoodTruckService.java | 30 ++-- .../command/FoodTruckCommandService.java | 50 ------- .../info/FoodTruckInfoService.java | 136 ++++++++++++++++++ .../foodtruck/domain/model/AvailableDate.java | 13 +- .../domain/model/FoodTruckServiceArea.java | 13 +- .../FoodTruckServiceAreaRepository.java | 11 ++ .../foodtruck/domain/value/FoodTruckInfo.java | 28 ++++ .../request/UpdateFoodTruckInfoRequest.java | 3 +- 8 files changed, 214 insertions(+), 70 deletions(-) delete mode 100644 src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java create mode 100644 src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.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 dd6203f5..332c5dc4 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java @@ -1,16 +1,10 @@ package konkuk.chacall.domain.foodtruck.application; import konkuk.chacall.domain.foodtruck.application.image.FoodTruckImageService; -import konkuk.chacall.domain.foodtruck.application.command.FoodTruckCommandService; +import konkuk.chacall.domain.foodtruck.application.info.FoodTruckInfoService; import konkuk.chacall.domain.foodtruck.application.menu.FoodTruckMenuService; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckMenuRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckNameDuplicateCheckRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckSearchRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.ImageRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckMenuResponse; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckNameDuplicateCheckResponse; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckResponse; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.ImageResponse; +import konkuk.chacall.domain.foodtruck.presentation.dto.request.*; +import konkuk.chacall.domain.foodtruck.presentation.dto.response.*; import konkuk.chacall.domain.owner.application.validator.OwnerValidator; import konkuk.chacall.domain.user.domain.model.User; import konkuk.chacall.domain.member.application.validator.MemberValidator; @@ -24,25 +18,24 @@ @Transactional(readOnly = true) public class FoodTruckService { - private final FoodTruckCommandService foodTruckCommandService; + private final FoodTruckInfoService foodTruckInfoService; private final FoodTruckMenuService foodTruckMenuService; private final FoodTruckImageService foodTruckImageService; - private final MemberValidator memberValidator; private final OwnerValidator ownerValidator; public CursorPagingResponse getFoodTrucks(Long memberId, FoodTruckSearchRequest request) { memberValidator.validateAndGetMember(memberId); - return foodTruckCommandService.getFoodTrucks(memberId, request); + return foodTruckInfoService.getFoodTrucks(memberId, request); } public FoodTruckNameDuplicateCheckResponse isNameDuplicated(Long ownerId, FoodTruckNameDuplicateCheckRequest request) { ownerValidator.validateAndGetOwner(ownerId); return FoodTruckNameDuplicateCheckResponse.of( - foodTruckCommandService.isNameDuplicated(request.name())); + foodTruckInfoService.isNameDuplicated(request.name())); } public CursorPagingResponse getFoodTruckMenus(Long memberId, Long foodTruckId, FoodTruckMenuRequest request) { @@ -63,7 +56,18 @@ public ImageResponse createMenuImagePresignedUrl(ImageRequest request, Long owne return foodTruckImageService.createMenuImagePresignedUrl(request, owner); } + @Transactional + public FoodTruckIdResponse updateMyFoodTruckInfo(Long ownerId, Long foodTruckId, UpdateFoodTruckInfoRequest request) { + User owner = ownerValidator.validateAndGetOwner(ownerId); + return FoodTruckIdResponse.of( + foodTruckInfoService.updateMyFoodTruckInfo(owner, foodTruckId, request) + ); + } + public void deleteFoodTruckImagesFromS3(Long ownerId, Long foodTruckId, DeleteFoodTruckImagesRequest request) { + User owner = ownerValidator.validateAndGetOwner(ownerId); + foodTruckImageService.deleteFoodTruckImagesFromS3(owner, foodTruckId, request); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java b/src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java deleted file mode 100644 index 426397c1..00000000 --- a/src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java +++ /dev/null @@ -1,50 +0,0 @@ -package konkuk.chacall.domain.foodtruck.application.command; - -import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; -import konkuk.chacall.domain.foodtruck.domain.repository.FoodTruckRepository; -import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckSearchRequest; -import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckResponse; -import konkuk.chacall.domain.member.domain.repository.SavedFoodTruckRepository; -import konkuk.chacall.domain.user.domain.model.User; -import konkuk.chacall.global.common.dto.CursorPagingResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Slice; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Set; - -@Service -@RequiredArgsConstructor -public class FoodTruckCommandService { - - private final FoodTruckRepository foodTruckRepository; - private final SavedFoodTruckRepository savedFoodTruckRepository; - - public CursorPagingResponse getFoodTrucks(Long memberId, FoodTruckSearchRequest request) { - - Slice foodTruckSlice = foodTruckRepository.getFoodTrucks(request); - List content = foodTruckSlice.getContent(); - - // 이 페이지의 트럭 ID 목록 - List foodTruckIds = content.stream() - .map(FoodTruck::getFoodTruckId) - .toList(); - - Set savedFoodTruckIds = foodTruckIds.isEmpty() ? Set.of() : savedFoodTruckRepository.findSavedTruckIdsIn(memberId, foodTruckIds); - - List foodTrucks = content.stream() - .map(ft -> FoodTruckResponse.of(ft, savedFoodTruckIds.contains(ft.getFoodTruckId()))) - .toList(); - - return CursorPagingResponse.of( - foodTrucks, - FoodTruckResponse::foodTruckId, - foodTruckSlice.hasNext() - ); - } - - public boolean isNameDuplicated(String name) { - return foodTruckRepository.existsByName(name); - } -} 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 new file mode 100644 index 00000000..64c2fea1 --- /dev/null +++ b/src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java @@ -0,0 +1,136 @@ +package konkuk.chacall.domain.foodtruck.application.info; + +import konkuk.chacall.domain.foodtruck.domain.model.AvailableDate; +import konkuk.chacall.domain.foodtruck.domain.model.FoodTruck; +import konkuk.chacall.domain.foodtruck.domain.model.FoodTruckServiceArea; +import konkuk.chacall.domain.foodtruck.domain.repository.AvailableDateRepository; +import konkuk.chacall.domain.foodtruck.domain.repository.FoodTruckRepository; +import konkuk.chacall.domain.foodtruck.domain.repository.FoodTruckServiceAreaRepository; +import konkuk.chacall.domain.foodtruck.presentation.dto.request.DateRangeRequest; +import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckSearchRequest; +import konkuk.chacall.domain.foodtruck.presentation.dto.request.UpdateFoodTruckInfoRequest; +import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckResponse; +import konkuk.chacall.domain.member.domain.repository.SavedFoodTruckRepository; +import konkuk.chacall.domain.region.domain.model.Region; +import konkuk.chacall.domain.region.domain.repository.RegionRepository; +import konkuk.chacall.domain.user.domain.model.User; +import konkuk.chacall.global.common.dto.CursorPagingResponse; +import konkuk.chacall.global.common.exception.EntityNotFoundException; +import konkuk.chacall.global.common.exception.code.ErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class FoodTruckInfoService { + + private final FoodTruckRepository foodTruckRepository; + private final SavedFoodTruckRepository savedFoodTruckRepository; + private final FoodTruckServiceAreaRepository foodTruckServiceAreaRepository; + private final AvailableDateRepository availableDateRepository; + private final RegionRepository regionRepository; + + public CursorPagingResponse getFoodTrucks(Long memberId, FoodTruckSearchRequest request) { + + Slice foodTruckSlice = foodTruckRepository.getFoodTrucks(request); + List content = foodTruckSlice.getContent(); + + // 이 페이지의 트럭 ID 목록 + List foodTruckIds = content.stream() + .map(FoodTruck::getFoodTruckId) + .toList(); + + Set savedFoodTruckIds = foodTruckIds.isEmpty() ? Set.of() : savedFoodTruckRepository.findSavedTruckIdsIn(memberId, foodTruckIds); + + List foodTrucks = content.stream() + .map(ft -> FoodTruckResponse.of(ft, savedFoodTruckIds.contains(ft.getFoodTruckId()))) + .toList(); + + return CursorPagingResponse.of( + foodTrucks, + FoodTruckResponse::foodTruckId, + foodTruckSlice.hasNext() + ); + } + + public boolean isNameDuplicated(String name) { + return foodTruckRepository.existsByFoodTruckInfo_Name(name); + } + + public Long updateMyFoodTruckInfo(User owner, Long foodTruckId, UpdateFoodTruckInfoRequest request) { + FoodTruck foodTruck = foodTruckRepository.findById(foodTruckId) + .orElseThrow(() -> new EntityNotFoundException(ErrorCode.FOOD_TRUCK_NOT_FOUND)); + + // 푸드트럭 소유주/승인 상태 검증 + foodTruck.validateOwner(owner.getUserId()); + foodTruck.validateApprovedStatus(); + + // 푸드트럭 정보 업데이트 + foodTruck.updateFoodTruckInfo(request.name(), request.description(), request.phoneNumber(), request.activeTime(), request.timeDiscussRequired(), request.photoUrls(), + request.menuCategories(), request.availableQuantity(), request.needElectricity(), request.paymentMethod(), request.operatingInfo(), request.option()); + + // 푸드트럭 노출 상태 변경 허용 + foodTruck.permitChangeViewStatus(); + + // 서비스 가능 지역 동기화 + syncServiceAreas(foodTruck, request.foodTruckServiceAreas()); + + // 운영 가능 날짜 동기화 + syncAvailableDates(foodTruck, request.availableDates()); + + return foodTruck.getFoodTruckId(); + } + + private void syncAvailableDates(FoodTruck foodTruck, List dateRangeRequests) { + // 기존 운영 가능 날짜 삭제 + availableDateRepository.deleteAllByFoodTruckId(foodTruck.getFoodTruckId()); + + // 새로운 운영 가능 날짜 추가 + List newAvailableDates = dateRangeRequests.stream() + .map(request -> AvailableDate.createAvailableDate(request.startDate(), request.endDate(), foodTruck)) + .toList(); + + availableDateRepository.saveAll(newAvailableDates); + } + + private void syncServiceAreas(FoodTruck foodTruck, Set requestedRegionIds) { + Set currentRegionIds = foodTruckServiceAreaRepository.findAllByFoodTruckId(foodTruck.getFoodTruckId()).stream() + .map(FoodTruckServiceArea::getRegion) + .map(Region::getRegionId) + .collect(Collectors.toSet()); + + // 추가할 지역 + Set regionsToAdd = new HashSet<>(requestedRegionIds); + regionsToAdd.removeAll(currentRegionIds); // 현재 지역에서 없는 것들만 남김 + + // 제거할 지역 + Set regionsToRemove = new HashSet<>(currentRegionIds); + regionsToRemove.removeAll(requestedRegionIds); // 요청된 지역에서 없는 것들만 남김 + + // 추가 + if(!regionsToAdd.isEmpty()) { + List serviceAreasToAdd = regionsToAdd.stream() + .map(regionId -> FoodTruckServiceArea.createFoodTruckServiceArea(regionRepository.findById(regionId) + .orElseThrow(() -> new EntityNotFoundException(ErrorCode.REGION_NOT_FOUND)), foodTruck)) + .toList(); + + foodTruckServiceAreaRepository.saveAll(serviceAreasToAdd); + } + + // 제거 + if(!regionsToRemove.isEmpty()) { + List serviceAreasToRemove = regionsToRemove.stream() + .map(regionId -> foodTruckServiceAreaRepository.findByFoodTruckIdAndRegionId(foodTruck.getFoodTruckId(), regionId) + .orElseThrow(() -> new EntityNotFoundException(ErrorCode.FOOD_TRUCK_SERVICE_AREA_NOT_FOUND))) + .toList(); + + foodTruckServiceAreaRepository.deleteAll(serviceAreasToRemove); + } + } +} diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/AvailableDate.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/AvailableDate.java index ab3d7be0..aea4a7d8 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/AvailableDate.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/AvailableDate.java @@ -2,14 +2,14 @@ import jakarta.persistence.*; import konkuk.chacall.global.common.domain.BaseEntity; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import java.time.LocalDate; +@Builder @Entity @Table(name = "available_dates") +@AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class AvailableDate extends BaseEntity { @@ -29,4 +29,11 @@ public class AvailableDate extends BaseEntity { @JoinColumn(name = "food_truck_id", nullable = false) private FoodTruck foodTruck; + public static AvailableDate createAvailableDate(LocalDate startDate, LocalDate endDate, FoodTruck foodTruck) { + return AvailableDate.builder() + .startAt(startDate) + .endAt(endDate) + .foodTruck(foodTruck) + .build(); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruckServiceArea.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruckServiceArea.java index f520c58c..3887ba3d 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruckServiceArea.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruckServiceArea.java @@ -3,12 +3,12 @@ import jakarta.persistence.*; import konkuk.chacall.domain.region.domain.model.Region; import konkuk.chacall.global.common.domain.BaseEntity; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; +@Builder @Entity @Table(name = "food_truck_service_areas") +@AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class FoodTruckServiceArea extends BaseEntity { @@ -25,4 +25,11 @@ public class FoodTruckServiceArea extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "food_truck_id", nullable = false) private FoodTruck foodTruck; + + public static FoodTruckServiceArea createFoodTruckServiceArea(Region region, FoodTruck foodTruck) { + return FoodTruckServiceArea.builder() + .region(region) + .foodTruck(foodTruck) + .build(); + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckServiceAreaRepository.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckServiceAreaRepository.java index dedc4294..1870005f 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckServiceAreaRepository.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/FoodTruckServiceAreaRepository.java @@ -7,6 +7,7 @@ import org.springframework.data.repository.query.Param; import java.util.List; +import java.util.Optional; public interface FoodTruckServiceAreaRepository extends JpaRepository { @@ -18,4 +19,14 @@ public interface FoodTruckServiceAreaRepository extends JpaRepository findAllByFoodTruckId(Long foodTruckId); + + + @Query("SELECT ftsa FROM FoodTruckServiceArea ftsa " + + "WHERE ftsa.foodTruck.foodTruckId = :foodTruckId " + + "AND ftsa.region.regionId = :regionId") + Optional findByFoodTruckIdAndRegionId(Long foodTruckId, Long regionId); } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java index 5793fb0e..189d61dd 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/FoodTruckInfo.java @@ -54,4 +54,32 @@ public static FoodTruckInfo createEmptyFoodTruckInfo(String name) { .name(name) .build(); } + + public void updateFoodTruckInfo( + String name, + String description, + String phoneNumber, + String activeTime, + Boolean timeDiscussRequired, + PhotoUrlList foodTruckPhotoList, + MenuCategoryList menuCategoryList, + AvailableQuantity availableQuantity, + NeedElectricity needElectricity, + PaymentMethod paymentMethod, + String operatingInfo, + String option + ) { + this.name = name; + this.description = description; + this.phoneNumber = phoneNumber; + this.activeTime = activeTime; + this.timeDiscussRequired = timeDiscussRequired; + this.foodTruckPhotoList = foodTruckPhotoList; + this.menuCategoryList = menuCategoryList; + this.availableQuantity = availableQuantity; + this.needElectricity = needElectricity; + this.paymentMethod = paymentMethod; + this.operatingInfo = operatingInfo; + this.option = option; + } } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java index 8b0cd34d..537397f8 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java @@ -11,6 +11,7 @@ import konkuk.chacall.domain.foodtruck.domain.value.PaymentMethod; import java.util.List; +import java.util.Set; public record UpdateFoodTruckInfoRequest ( @Schema(description = "푸드트럭 이름", example = "맛있는 푸드트럭") @@ -36,7 +37,7 @@ public record UpdateFoodTruckInfoRequest ( @Schema(description = "푸드트럭 서비스 가능 지역 ID 리스트", example = "[1, 2, 3]") @Size(min = 1, max = 10, message = "서비스 가능 지역은 최소 1개 최대 10개 선택 가능합니다.") - List<@NotNull Long> foodTruckServiceAreas, + Set<@NotNull Long> foodTruckServiceAreas, @Schema(description = "메뉴 카테고리 리스트", example = "[\"한식\", \"분식\"]") @Size(min = 1, max = 12, message = "메뉴 카테고리는 최소 1개 최대 12개 선택 가능합니다.") From c8f2e4463da7e6b25ebe92508cf22abe3633a20e Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Wed, 22 Oct 2025 03:16:14 +0900 Subject: [PATCH 10/15] =?UTF-8?q?[docs]=20=EC=8A=A4=EC=9B=A8=EA=B1=B0=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=AA=85=EC=84=B8=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/FoodTruckController.java | 2 ++ .../common/swagger/SwaggerResponseDescription.java | 14 ++++++++++++++ 2 files changed, 16 insertions(+) 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 1a37a52f..4ab46107 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java @@ -97,6 +97,7 @@ public BaseResponse> getFoodTruckMen summary = "나의 푸드트럭 정보 등록/수정", description = "승인이 완료된 나의 푸드트럭 정보를 기입하거나 수정합니다." ) + @ExceptionDescription(SwaggerResponseDescription.UPDATE_FOOD_TRUCK_INFO) @PutMapping("{foodTruckId}") public BaseResponse updateMyFoodTruckInfo( @Parameter(description = "푸드트럭 ID", example = "1") @PathVariable final Long foodTruckId, @@ -110,6 +111,7 @@ public BaseResponse updateMyFoodTruckInfo( summary = "S3에서 푸드트럭 이미지 객체(메뉴 포함 x) 삭제", description = "S3에서 푸드트럭 이미지 객체를 삭제합니다. 사용자가 기존 푸드트럭 이미지를 삭제했을 경우 나의 푸드트럭 정보 등록/수정 API 호출 이후 호출해주세요." ) + @ExceptionDescription(SwaggerResponseDescription.DELETE_FOOD_TRUCK_IMAGES) @DeleteMapping("{foodTruckId}/images") public BaseResponse deleteFoodTruckImagesFromS3( @Parameter(description = "푸드트럭 ID", example = "1") @PathVariable final Long foodTruckId, 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 06dc304a..11ddede5 100644 --- a/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java +++ b/src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java @@ -221,6 +221,20 @@ public enum SwaggerResponseDescription { USER_FORBIDDEN, FOOD_TRUCK_NOT_FOUND ))), + UPDATE_FOOD_TRUCK_INFO(new LinkedHashSet<>(Set.of( + USER_NOT_FOUND, + USER_FORBIDDEN, + FOOD_TRUCK_NOT_FOUND, + FOOD_TRUCK_NOT_OWNED, + FOOD_TRUCK_NOT_APPROVED, + REGION_NOT_FOUND + ))), + DELETE_FOOD_TRUCK_IMAGES(new LinkedHashSet<>(Set.of( + USER_NOT_FOUND, + USER_FORBIDDEN, + FOOD_TRUCK_NOT_FOUND, + FOOD_TRUCK_NOT_OWNED + ))), // Default DEFAULT(new LinkedHashSet<>()) From 1431dcbf8d4a16421fed665035f9257b4240991c Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Fri, 24 Oct 2025 21:31:01 +0900 Subject: [PATCH 11/15] =?UTF-8?q?[refactor]=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=97=90=EC=84=9C=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=20=EC=A0=95=EC=88=98=ED=98=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../konkuk/chacall/domain/foodtruck/domain/model/Menu.java | 4 ---- .../presentation/dto/response/FoodTruckMenuResponse.java | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/Menu.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/Menu.java index 9aad31e4..a987f514 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/Menu.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/model/Menu.java @@ -60,10 +60,6 @@ public void updateMenu(String name, Integer price, String description, String im this.imageUrl = imageUrl; } - public String parsingMenuPrice() { - return price + "원"; - } - public void changeViewedStatus(MenuViewedStatus targetViewedStatus) { if(this.menuViewedStatus == targetViewedStatus) { throw new DomainRuleException(ErrorCode.INVALID_MENU_STATUS_TRANSITION); diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java index 2a0c9461..43975e50 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java @@ -9,8 +9,8 @@ public record FoodTruckMenuResponse ( Long menuId, @Schema(description = "메뉴명", example = "크림파스타") String name, - @Schema(description = "가격", example = "12000원") - String price, + @Schema(description = "가격", example = "12000") + int price, @Schema(description = "설명", example = "진한 크림소스와 베이컨") String description, @Schema(description = "이미지 URL", example = "https://cdn.example.com/menus/101.jpg") @@ -21,7 +21,7 @@ public static FoodTruckMenuResponse from(Menu menu) { return new FoodTruckMenuResponse( menu.getMenuId(), menu.getName(), - menu.parsingMenuPrice(), + menu.getPrice(), menu.getDescription(), menu.getImageUrl() ); From 6b1fb5a2909c5c48c8ce9be846e3968b27818e5a Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Sat, 25 Oct 2025 18:07:03 +0900 Subject: [PATCH 12/15] =?UTF-8?q?[refactor]=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=97=90=EC=84=9C=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=20=EC=A0=95=EC=88=98=ED=98=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/dto/response/MyFoodTruckMenuResponse.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckMenuResponse.java b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckMenuResponse.java index 4ef86554..fa32e8b0 100644 --- a/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckMenuResponse.java +++ b/src/main/java/konkuk/chacall/domain/owner/presentation/dto/response/MyFoodTruckMenuResponse.java @@ -9,8 +9,8 @@ public record MyFoodTruckMenuResponse( Long menuId, @Schema(description = "메뉴명", example = "크림파스타") String name, - @Schema(description = "가격", example = "12000원") - String price, + @Schema(description = "가격", example = "12000") + int price, @Schema(description = "설명", example = "진한 크림소스와 베이컨") String description, @Schema(description = "이미지 URL", example = "https://cdn.example.com/menus/101.jpg") @@ -23,7 +23,7 @@ public static MyFoodTruckMenuResponse from(Menu menu) { return new MyFoodTruckMenuResponse( menu.getMenuId(), menu.getName(), - menu.parsingMenuPrice(), + menu.getPrice(), menu.getDescription(), menu.getImageUrl(), menu.getMenuViewedStatus().name() From ade62c6143828fdf9cb6e5d1ffc9d28b443edc90 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Sat, 25 Oct 2025 18:18:13 +0900 Subject: [PATCH 13/15] =?UTF-8?q?[refactor]=20=EC=A0=9C=EC=A1=B0=20?= =?UTF-8?q?=EC=88=98=EB=9F=89=EC=97=90=EC=84=9C=20'200=EC=9D=B8=EB=B6=84?= =?UTF-8?q?=20=EB=AF=B8=EB=A7=8C'=20=EC=B6=94=EA=B0=80=ED=95=98=EA=B8=B0?= =?UTF-8?q?=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/foodtruck/domain/value/AvailableQuantity.java | 9 ++++++--- .../presentation/dto/request/FoodTruckSearchRequest.java | 1 + .../dto/request/UpdateFoodTruckInfoRequest.java | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java index ebf2c889..f2f45f52 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/domain/value/AvailableQuantity.java @@ -14,6 +14,7 @@ public enum AvailableQuantity implements EnumValue { LESS_THAN_50("50인분 미만"), LESS_THAN_100("100인분 미만"), LESS_THAN_150("150인분 미만"), + LESS_THAN_200("200인분 미만"), MORE_THAN_200("200인분 이상"), NEED_DISCUSSION("논의 필요"); @@ -39,11 +40,13 @@ public static EnumSet acceptableFor(AvailableQuantity req) { return switch (req) { case LESS_THAN_50 -> - EnumSet.of(LESS_THAN_50, LESS_THAN_100, LESS_THAN_150, MORE_THAN_200, NEED_DISCUSSION); + EnumSet.of(LESS_THAN_50, LESS_THAN_100, LESS_THAN_150, LESS_THAN_200, MORE_THAN_200, NEED_DISCUSSION); case LESS_THAN_100 -> - EnumSet.of(LESS_THAN_100, LESS_THAN_150, MORE_THAN_200, NEED_DISCUSSION); + EnumSet.of(LESS_THAN_100, LESS_THAN_150, LESS_THAN_200, MORE_THAN_200, NEED_DISCUSSION); case LESS_THAN_150 -> - EnumSet.of(LESS_THAN_150, MORE_THAN_200, NEED_DISCUSSION); + EnumSet.of(LESS_THAN_150, LESS_THAN_200, MORE_THAN_200, NEED_DISCUSSION); + case LESS_THAN_200 -> + EnumSet.of(LESS_THAN_200, MORE_THAN_200, NEED_DISCUSSION); case MORE_THAN_200 -> EnumSet.of(MORE_THAN_200, NEED_DISCUSSION); case NEED_DISCUSSION -> diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java index 5355769b..469985b0 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java @@ -39,6 +39,7 @@ public record FoodTruckSearchRequest( "50인분 미만", "100인분 미만", "150인분 미만", + "200인분 미만", "200인분 이상", "논의 필요" } diff --git a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java index 537397f8..bd503851 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/UpdateFoodTruckInfoRequest.java @@ -47,6 +47,7 @@ public record UpdateFoodTruckInfoRequest ( "50인분 미만", "100인분 미만", "150인분 미만", + "200인분 미만", "200인분 이상", "논의 필요" }) From d18efd31ef4ad0c0b53d574b1645fd604d9251ba Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Sat, 25 Oct 2025 18:43:15 +0900 Subject: [PATCH 14/15] =?UTF-8?q?[refactor]=20=EC=9D=BC=EB=B0=98=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=98=88=EC=95=BD=20=EC=83=81=EC=84=B8=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=97=90=EC=84=9C=20=EB=A6=AC=EB=B7=B0=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=97=AC=EB=B6=80=20=EB=B0=98=ED=99=98=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/MemberReservationService.java | 7 +++++-- .../member/domain/repository/RatingRepository.java | 2 ++ .../dto/response/MemberReservationDetailResponse.java | 9 ++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/konkuk/chacall/domain/member/application/reservation/MemberReservationService.java b/src/main/java/konkuk/chacall/domain/member/application/reservation/MemberReservationService.java index 3cbc1fd3..18b1e87b 100644 --- a/src/main/java/konkuk/chacall/domain/member/application/reservation/MemberReservationService.java +++ b/src/main/java/konkuk/chacall/domain/member/application/reservation/MemberReservationService.java @@ -1,6 +1,6 @@ package konkuk.chacall.domain.member.application.reservation; -import konkuk.chacall.domain.member.presentation.dto.request.GetReservationHistoryRequest; +import konkuk.chacall.domain.member.domain.repository.RatingRepository; import konkuk.chacall.domain.member.presentation.dto.response.MemberReservationDetailResponse; import konkuk.chacall.domain.member.presentation.dto.response.MemberReservationHistoryResponse; import konkuk.chacall.domain.reservation.domain.model.Reservation; @@ -22,6 +22,7 @@ public class MemberReservationService { private final ReservationRepository reservationRepository; + private final RatingRepository ratingRepository; public CursorPagingResponse getMemberReservations(User member, ReservationViewType viewType, Long lastCursor, int pageSize) { Slice memberReservationSlice = reservationRepository @@ -41,6 +42,8 @@ public MemberReservationDetailResponse getMemberReservationDetail(Long reservati reservation.validateReservedBy(member.getUserId()); - return MemberReservationDetailResponse.of(reservation, reservation.getFoodTruck()); + boolean reviewRequired = ratingRepository.existsByMemberAndReservation(member, reservation); + + return MemberReservationDetailResponse.of(reservation, reservation.getFoodTruck(), reviewRequired); } } diff --git a/src/main/java/konkuk/chacall/domain/member/domain/repository/RatingRepository.java b/src/main/java/konkuk/chacall/domain/member/domain/repository/RatingRepository.java index 5d80b4a7..dc259f4a 100644 --- a/src/main/java/konkuk/chacall/domain/member/domain/repository/RatingRepository.java +++ b/src/main/java/konkuk/chacall/domain/member/domain/repository/RatingRepository.java @@ -26,4 +26,6 @@ public interface RatingRepository extends JpaRepository { @Modifying @Query("DELETE FROM Rating r WHERE r.foodTruck.foodTruckId = :foodTruckId") void deleteAllByFoodTruckId(@Param("foodTruckId") Long foodTruckId); + + boolean existsByMemberAndReservation(User member, Reservation reservation); } diff --git a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java index 2a600518..72d3ffcd 100644 --- a/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java +++ b/src/main/java/konkuk/chacall/domain/member/presentation/dto/response/MemberReservationDetailResponse.java @@ -39,10 +39,12 @@ public record MemberReservationDetailResponse( example = "음식을 많이 주세요, 늦지말아주세요") String etcRequest, @Schema(description = "예약 상태", example = "예약 확정") - String reservationStatus + String reservationStatus, + @Schema(description = "리뷰 작성 필요 여부", example = "true") + boolean reviewRequired ) { - public static MemberReservationDetailResponse of(Reservation reservation, FoodTruck foodTruck) { + public static MemberReservationDetailResponse of(Reservation reservation, FoodTruck foodTruck, boolean reviewRequired) { List dateTimeList = reservation.getReservationInfo().getFormattedDateTimeInfos(); FoodTruckInfo foodTruckInfo = foodTruck.getFoodTruckInfo(); @@ -57,7 +59,8 @@ public static MemberReservationDetailResponse of(Reservation reservation, FoodTr reservation.getReservationInfo().getDeposit(), reservation.getReservationInfo().parsingIsUserElectricity(), reservation.getReservationInfo().getEtcRequest(), - reservation.getReservationStatus().getValue() + reservation.getReservationStatus().getValue(), + reviewRequired ); } } From 88348db1d1c7230e14acf91d81e090bcd96ee459 Mon Sep 17 00:00:00 2001 From: janghyunjun Date: Mon, 27 Oct 2025 13:48:52 +0900 Subject: [PATCH 15/15] =?UTF-8?q?[refactor]=20s3=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EC=82=AD=EC=A0=9C=EB=8F=84=20=EB=B3=84=EB=8F=84=20?= =?UTF-8?q?API=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foodtruck/presentation/FoodTruckController.java | 4 ++-- .../myfoodtruckmenu/MyFoodTruckMenuService.java | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) 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 4ab46107..5180f96b 100644 --- a/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java +++ b/src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java @@ -108,8 +108,8 @@ public BaseResponse updateMyFoodTruckInfo( } @Operation( - summary = "S3에서 푸드트럭 이미지 객체(메뉴 포함 x) 삭제", - description = "S3에서 푸드트럭 이미지 객체를 삭제합니다. 사용자가 기존 푸드트럭 이미지를 삭제했을 경우 나의 푸드트럭 정보 등록/수정 API 호출 이후 호출해주세요." + summary = "S3에서 푸드트럭 이미지 객체 삭제", + description = "S3에서 푸드트럭/메뉴 이미지 객체를 삭제합니다. 사용자가 기존 푸드트럭/메뉴 이미지를 삭제했을 경우 호출해주세요." ) @ExceptionDescription(SwaggerResponseDescription.DELETE_FOOD_TRUCK_IMAGES) @DeleteMapping("{foodTruckId}/images") diff --git a/src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java b/src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java index 064258cf..39b42491 100644 --- a/src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java +++ b/src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java @@ -114,12 +114,12 @@ public void deleteMenu(Long ownerId, Long foodTruckId, Long menuId) { Menu menu = menuRepository.findByMenuIdAndFoodTruckId(menuId, foodTruckId) .orElseThrow(() -> new BusinessException(ErrorCode.MENU_NOT_FOUND)); - String key = cdnUrlResolver.extractKeyFromUrl(menu.getImageUrl()); +// String key = cdnUrlResolver.extractKeyFromUrl(menu.getImageUrl()); - // 메뉴 이미지를 S3 에서 삭제 - if (key != null) { - s3Service.delete(key); - } +// // 메뉴 이미지를 S3 에서 삭제 +// if (key != null) { +// s3Service.delete(key); +// } menuRepository.delete(menu); }