From fa668d99302c01cdf21dfe88f3598a0401b46f12 Mon Sep 17 00:00:00 2001 From: yoojinche Date: Tue, 19 Aug 2025 17:06:53 +0900 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefractor:=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EC=BD=94=EC=8A=A4=EB=B3=84=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C,=20searchCond=20=EB=82=98=EC=98=A4?= =?UTF-8?q?=EA=B2=8C=EB=81=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/query/DateQueryController.java | 20 +++++- .../domain/date/converter/DateConverter.java | 66 ++++++++++++++----- .../date/dto/request/DateRequestDTO.java | 5 +- .../date/dto/response/DateResponseDTO.java | 4 +- .../domain/date/entity/DateCourse.java | 12 +++- .../date/entity/DateCoursePlaceCategory.java | 1 + .../repository/PlaceCategoryRepository.java | 4 ++ .../command/DateCommandServiceImpl.java | 16 +++-- .../service/query/DateQueryServiceImpl.java | 2 +- 9 files changed, 100 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/controller/query/DateQueryController.java b/src/main/java/org/withtime/be/withtimebe/domain/date/controller/query/DateQueryController.java index 2af48e6..de8103b 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/controller/query/DateQueryController.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/controller/query/DateQueryController.java @@ -28,6 +28,8 @@ import org.withtime.be.withtimebe.global.annotation.SwaggerPageable; import org.withtime.be.withtimebe.global.security.annotation.AuthenticatedMember; +import java.util.List; + @RestController @RequiredArgsConstructor @RequestMapping("/api/v1/date-courses") @@ -63,9 +65,15 @@ public class DateQueryController { @GetMapping public DefaultResponse findDateCourses( @PageableDefault(page = 0, size = 10) Pageable pageable, - @ModelAttribute @ParameterObject DateRequestDTO.DateCourseSearchCond dateCourseSearchCond, + @RequestParam(required = false) DatePriceRange datePriceRange, + @RequestParam(required = false) List datePlaces, + @RequestParam(required = false) DateTime dateDurationTime, + @RequestParam(required = false) List mealTypes, + @RequestParam(required = false) Transportation transportation, + @RequestParam(required = false) List userPreferredKeywords, @AuthenticatedMember Member member ) { + DateRequestDTO.DateCourseSearchCond dateCourseSearchCond = DateConverter.createSearchCondFromParam(datePriceRange, datePlaces, dateDurationTime, mealTypes, transportation, userPreferredKeywords); DateResponseDTO.DateCourseList response = dateQueryService.findDateCourses(dateCourseSearchCond, pageable, member); return DefaultResponse.ok(response); } @@ -98,11 +106,17 @@ public DefaultResponse findDateCourses( @GetMapping("/bookmarks/search") public DefaultResponse findDateCourseBookmark( @PageableDefault(page = 0, size = 10) Pageable pageable, - @ModelAttribute @ParameterObject DateRequestDTO.DateCourseSearchCond dateCourseSearchCond, + @RequestParam(required = false) DatePriceRange datePriceRange, + @RequestParam(required = false) List datePlaces, + @RequestParam(required = false) DateTime dateDurationTime, + @RequestParam(required = false) List mealTypes, + @RequestParam(required = false) Transportation transportation, + @RequestParam(required = false) List userPreferredKeywords, @AuthenticatedMember Member member ){ + DateRequestDTO.DateCourseSearchCond dateCourseSearchCond = DateConverter.createSearchCondFromParam(datePriceRange, datePlaces, dateDurationTime, mealTypes, transportation, userPreferredKeywords); Page bookmarkedDateCourses = dateQueryService.findDateCourseBookmarks(dateCourseSearchCond, pageable, member); - DateResponseDTO.DateCourseList response = DateConverter.createDateCourseList(bookmarkedDateCourses, null, dateCourseSearchCond); + DateResponseDTO.DateCourseList response = DateConverter.createDateCourseList(bookmarkedDateCourses, null); return DefaultResponse.ok(response); } } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/converter/DateConverter.java b/src/main/java/org/withtime/be/withtimebe/domain/date/converter/DateConverter.java index c677cd8..53db7d7 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/converter/DateConverter.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/converter/DateConverter.java @@ -5,6 +5,10 @@ import org.withtime.be.withtimebe.domain.date.dto.request.DateRequestDTO; import org.withtime.be.withtimebe.domain.date.dto.response.DateResponseDTO; import org.withtime.be.withtimebe.domain.date.entity.*; +import org.withtime.be.withtimebe.domain.date.entity.enums.DatePriceRange; +import org.withtime.be.withtimebe.domain.date.entity.enums.DateTime; +import org.withtime.be.withtimebe.domain.date.entity.enums.MealType; +import org.withtime.be.withtimebe.domain.date.entity.enums.Transportation; import org.withtime.be.withtimebe.domain.member.entity.Member; import java.time.LocalDateTime; @@ -34,6 +38,11 @@ public static DateResponseDTO.DateCourseBookmark createDateCourseBookmarkRespons public static DateCourse createDateCourse(DateRequestDTO.SaveDateCourse dateCourse){ return DateCourse.builder() .name(dateCourse.name()) + .datePriceRange(dateCourse.dateCourseSearchCond().datePriceRange()) + .datePlaces(dateCourse.dateCourseSearchCond().datePlaces()) + .dateTime(dateCourse.dateCourseSearchCond().dateDurationTime()) + .mealTypes(dateCourse.dateCourseSearchCond().mealTypes()) + .transportation(dateCourse.dateCourseSearchCond().transportation()) .build(); } @@ -68,7 +77,7 @@ public static DateResponseDTO.DateCourseSearchCondInfo toDateCourseSearchCondInf .dateDurationTime(request.dateDurationTime()) // 데이트 소요 시간 .mealTypes(request.mealPlan()) // 식사 계획 .transportation(request.transportation()) // 교통 수단 - .userPreferredKeywords(request.userPreferredKeywords()) // 키워드 + .dateCoursePlaceCategories(request.userPreferredKeywords()) // 키워드 .build(); } @@ -132,10 +141,12 @@ public static DateResponseDTO.DatePlace createDatePlace(DatePlace datePlace, // DateResponseDTO.DateCourse -> DateResponseDTO.DateCourse public static DateResponseDTO.DateCourse createDateCourse(DateCourse dateCourse, - Set bookmarkedIds, - DateRequestDTO.DateCourseSearchCond cond){ - Boolean bookmarked = null; - if (bookmarkedIds != null && !bookmarkedIds.isEmpty()) bookmarked = bookmarkedIds.contains(dateCourse.getId()); + Set bookmarkedIds){ + Boolean bookmarked = (bookmarkedIds == null)? null + : (dateCourse.getId() != null && bookmarkedIds.contains(dateCourse.getId())); + if (dateCourse.getId() != null) System.out.println("test1"); + if (bookmarkedIds.contains(dateCourse.getId())) System.out.println("test2"); + List datePlaces = dateCourse.getDatePlaceDateCourses().stream() .map(dc -> DateConverter.createDatePlace(dc.getDatePlace(), dc.getStartTime(), dc.getEndTime())) .toList(); @@ -145,28 +156,31 @@ public static DateResponseDTO.DateCourse createDateCourse(DateCourse dateCourse, .name(dateCourse.getName()) .datePlaces(datePlaces) .isBookmarked(bookmarked) - .dateCourseSearchCondInfo(createSearchCond(cond)) + .dateCourseSearchCondInfo(createSearchCond(dateCourse)) .build(); } - public static DateResponseDTO.DateCourseSearchCondInfo createSearchCond(DateRequestDTO.DateCourseSearchCond cond){ + public static DateResponseDTO.DateCourseSearchCondInfo createSearchCond(DateCourse dateCourse){ + List dateCoursePlaceCategories = dateCourse.getDateCoursePlaceCategories().stream() + .map(dcpc -> dcpc.getPlaceCategory().getLabel()) + .toList(); + return DateResponseDTO.DateCourseSearchCondInfo.builder() - .budget(cond.datePriceRange()) - .datePlaces(cond.datePlaces()) - .mealTypes(cond.mealTypes()) - .transportation(cond.transportation()) - .dateDurationTime(cond.dateDurationTime()) - .userPreferredKeywords(cond.userPreferredKeywords()) + .budget(dateCourse.getDatePriceRange()) + .datePlaces(dateCourse.getDatePlaces()) + .mealTypes(dateCourse.getMealTypes()) + .transportation(dateCourse.getTransportation()) + .dateDurationTime(dateCourse.getDateTime()) + .dateCoursePlaceCategories(dateCoursePlaceCategories) .build(); } // Page -> DateRequestDTO.DateCourseList - public static DateResponseDTO.DateCourseList createDateCourseList(Page dateCourses, Set bookmarkedIds, - DateRequestDTO.DateCourseSearchCond cond){ + public static DateResponseDTO.DateCourseList createDateCourseList(Page dateCourses, Set bookmarkedIds){ List dateCourseList = dateCourses.stream() .map(dc ->{ - if (bookmarkedIds != null) return createDateCourse(dc, bookmarkedIds, cond); - return createDateCourse(dc, Collections.emptySet(), cond); + if (bookmarkedIds != null) return createDateCourse(dc, bookmarkedIds); + return createDateCourse(dc, Collections.emptySet()); }) .toList(); @@ -192,4 +206,22 @@ public static DateResponseDTO.SignatureDish toSignatureDish(Item item) { .build(); } + public static DateRequestDTO.DateCourseSearchCond createSearchCondFromParam( + DatePriceRange datePriceRange, + List datePlaces, + DateTime dateDurationTime, + List mealTypes, + Transportation transportation, + List userPreferredKeywords + ){ + return DateRequestDTO.DateCourseSearchCond.builder() + .datePriceRange(datePriceRange) + .datePlaces(datePlaces) + .dateDurationTime(dateDurationTime) + .mealTypes(mealTypes) + .transportation(transportation) + .userPreferredKeywords(userPreferredKeywords) + .build(); + } + } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/dto/request/DateRequestDTO.java b/src/main/java/org/withtime/be/withtimebe/domain/date/dto/request/DateRequestDTO.java index 40deadc..70c3741 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/dto/request/DateRequestDTO.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/dto/request/DateRequestDTO.java @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; +import lombok.Builder; import org.withtime.be.withtimebe.domain.date.entity.enums.DatePriceRange; import org.withtime.be.withtimebe.domain.date.entity.enums.DateTime; import org.withtime.be.withtimebe.domain.date.entity.enums.MealType; @@ -60,9 +61,11 @@ public record CreateDateCourse( public record SaveDateCourse( List datePlaceIds, - String name + String name, + DateCourseSearchCond dateCourseSearchCond ){} + @Builder public record DateCourseSearchCond( DatePriceRange datePriceRange, List datePlaces, diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/dto/response/DateResponseDTO.java b/src/main/java/org/withtime/be/withtimebe/domain/date/dto/response/DateResponseDTO.java index 05e3f7c..a146c9d 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/dto/response/DateResponseDTO.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/dto/response/DateResponseDTO.java @@ -3,8 +3,6 @@ import lombok.Builder; import org.withtime.be.withtimebe.domain.date.entity.enums.*; -import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.LocalTime; import java.util.List; @@ -69,7 +67,7 @@ public record DateCourseSearchCondInfo( DateTime dateDurationTime, List mealTypes, Transportation transportation, - List userPreferredKeywords + List dateCoursePlaceCategories ){} @Builder diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCourse.java b/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCourse.java index b5c2bee..3c2e76b 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCourse.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCourse.java @@ -59,7 +59,7 @@ public class DateCourse extends BaseEntity { @Builder.Default @OneToMany(mappedBy = "dateCourse", cascade = CascadeType.ALL, orphanRemoval = true) - private List DateCoursePlaceCategory = new ArrayList<>(); + private List dateCoursePlaceCategories = new ArrayList<>(); @Builder.Default @OneToMany(mappedBy = "dateCourse", cascade = CascadeType.ALL, orphanRemoval = true) @@ -73,4 +73,14 @@ public void addDatePlaceDateCourses(List datePlaceDateCours } datePlaceDateCourses.addAll(datePlaceDateCourseList); } + + public void addDateCoursePlaceCategory(List dateCoursePlaceCategoryList) { + if (dateCoursePlaceCategoryList == null || dateCoursePlaceCategoryList.isEmpty()) return; + for (DateCoursePlaceCategory dateCoursePlaceCategory : dateCoursePlaceCategoryList) { + dateCoursePlaceCategory.setDateCourse(this); + } + dateCoursePlaceCategories.addAll(dateCoursePlaceCategoryList); + } + + } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCoursePlaceCategory.java b/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCoursePlaceCategory.java index 262f436..16330dc 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCoursePlaceCategory.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/entity/DateCoursePlaceCategory.java @@ -18,6 +18,7 @@ public class DateCoursePlaceCategory { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "date_course_id", nullable = false) + @Setter private DateCourse dateCourse; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/repository/PlaceCategoryRepository.java b/src/main/java/org/withtime/be/withtimebe/domain/date/repository/PlaceCategoryRepository.java index 135ae95..ed84618 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/repository/PlaceCategoryRepository.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/repository/PlaceCategoryRepository.java @@ -3,5 +3,9 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.withtime.be.withtimebe.domain.date.entity.PlaceCategory; +import java.util.Collection; +import java.util.List; + public interface PlaceCategoryRepository extends JpaRepository { + List findAllByLabelIn(List labels); } diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/service/command/DateCommandServiceImpl.java b/src/main/java/org/withtime/be/withtimebe/domain/date/service/command/DateCommandServiceImpl.java index fc2812b..26a597d 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/service/command/DateCommandServiceImpl.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/service/command/DateCommandServiceImpl.java @@ -5,10 +5,7 @@ import org.springframework.transaction.annotation.Transactional; import org.withtime.be.withtimebe.domain.date.converter.DateConverter; import org.withtime.be.withtimebe.domain.date.dto.request.DateRequestDTO; -import org.withtime.be.withtimebe.domain.date.entity.DateCourse; -import org.withtime.be.withtimebe.domain.date.entity.DateCourseBookmark; -import org.withtime.be.withtimebe.domain.date.entity.DatePlace; -import org.withtime.be.withtimebe.domain.date.entity.DatePlaceDateCourse; +import org.withtime.be.withtimebe.domain.date.entity.*; import org.withtime.be.withtimebe.domain.date.entity.enums.BudgetLevel; import org.withtime.be.withtimebe.domain.date.entity.enums.KeywordForBudget; import org.withtime.be.withtimebe.domain.date.entity.enums.MealType; @@ -18,6 +15,7 @@ import org.withtime.be.withtimebe.domain.date.repository.DateCourseBookmarkRepository; import org.withtime.be.withtimebe.domain.date.repository.DateCourseRepository; import org.withtime.be.withtimebe.domain.date.repository.DatePlaceRepository; +import org.withtime.be.withtimebe.domain.date.repository.PlaceCategoryRepository; import org.withtime.be.withtimebe.domain.date.service.command.dto.RecommendedCourseResult; import org.withtime.be.withtimebe.domain.member.annotation.GetPoint; import org.withtime.be.withtimebe.domain.member.annotation.enums.PointAction; @@ -38,6 +36,7 @@ public class DateCommandServiceImpl implements DateCommandService{ private final DateCourseBookmarkRepository dateCourseBookmarkRepository; private final DateCourseRepository dateCourseRepository; private final DatePlaceRepository datePlaceRepository; + private final PlaceCategoryRepository placeCategoryRepository; /** 단일 코스 생성 (저장/북마크/attemptCount 없음, excludedCourseSignatures로 중복 제외) */ @Transactional(readOnly = true) @@ -296,10 +295,19 @@ public DateCourseBookmark createDateCourseBookmarkWithGeneratedCourse( ){ DateCourse dateCourse = DateConverter.createDateCourse(request); List datePlaces = datePlaceRepository.findAllById(request.datePlaceIds()); + List placeCategories = placeCategoryRepository.findAllByLabelIn(request.dateCourseSearchCond().userPreferredKeywords()); + List datePlaceDateCourses = datePlaces.stream() .map(datePlace -> DatePlaceDateCourse.builder().datePlace(datePlace).build()) .toList(); dateCourse.addDatePlaceDateCourses(datePlaceDateCourses); + + List dateCoursePlaceCategories = placeCategories.stream() + .map(dcpc -> DateCoursePlaceCategory.builder() + .placeCategory(dcpc) + .build()) + .toList(); + dateCourse.addDateCoursePlaceCategory(dateCoursePlaceCategories); dateCourseRepository.save(dateCourse); DateCourseBookmark dateCourseBookmark = DateConverter.createDateCourseBookmark(dateCourse, member); diff --git a/src/main/java/org/withtime/be/withtimebe/domain/date/service/query/DateQueryServiceImpl.java b/src/main/java/org/withtime/be/withtimebe/domain/date/service/query/DateQueryServiceImpl.java index f49b919..ad8b55b 100644 --- a/src/main/java/org/withtime/be/withtimebe/domain/date/service/query/DateQueryServiceImpl.java +++ b/src/main/java/org/withtime/be/withtimebe/domain/date/service/query/DateQueryServiceImpl.java @@ -37,7 +37,7 @@ public DateResponseDTO.DateCourseList findDateCourses(DateRequestDTO.DateCourseS ? new HashSet<>(dateCourseBookmarkRepository.findBookmarkedCourseIds(member.getId(), ids)) : java.util.Collections.emptySet(); - return DateConverter.createDateCourseList(dateCourses, bookmarkedIds, dateCourseSearchCond); + return DateConverter.createDateCourseList(dateCourses, bookmarkedIds); } @LogPlaceCategory