diff --git a/src/main/java/umc/cockple/demo/domain/party/controller/PartyController.java b/src/main/java/umc/cockple/demo/domain/party/controller/PartyController.java index f8fc6bef..2fe33348 100644 --- a/src/main/java/umc/cockple/demo/domain/party/controller/PartyController.java +++ b/src/main/java/umc/cockple/demo/domain/party/controller/PartyController.java @@ -77,11 +77,12 @@ public BaseResponse> getMyParties( } @GetMapping("/my/parties/suggestions") - @Operation(summary = "추천 모임 조회", + @Operation(summary = "모임 추천 조회", description = "사용자에게 추천되는 모임 목록을 조회합니다.") @ApiResponse(responseCode = "200", description = "모임 조회 성공") @ApiResponse(responseCode = "404", description = "존재하지 않는 사용자") public BaseResponse> getRecommendedParties( + @RequestParam(required = false) String search, @RequestParam(defaultValue = "true") boolean isCockpleRecommend, @RequestParam(required = false) String addr1, @RequestParam(required = false) String addr2, @@ -96,6 +97,7 @@ public BaseResponse> getRecommendedParties( Long memberId = SecurityUtil.getCurrentMemberId(); PartyFilterDTO.Request filter = PartyFilterDTO.Request.builder() + .search(search) .addr1(addr1) .addr2(addr2) .level(level) diff --git a/src/main/java/umc/cockple/demo/domain/party/dto/PartyFilterDTO.java b/src/main/java/umc/cockple/demo/domain/party/dto/PartyFilterDTO.java index d6a71e62..2d483939 100644 --- a/src/main/java/umc/cockple/demo/domain/party/dto/PartyFilterDTO.java +++ b/src/main/java/umc/cockple/demo/domain/party/dto/PartyFilterDTO.java @@ -10,6 +10,7 @@ public class PartyFilterDTO { @Builder @Schema(name = "PartyFilterRequestDTO", description = "모임 추천 조회 요청") public record Request( + String search, String addr1, String addr2, List level, diff --git a/src/main/java/umc/cockple/demo/domain/party/repository/PartyRepositoryCustomImpl.java b/src/main/java/umc/cockple/demo/domain/party/repository/PartyRepositoryCustomImpl.java index c3fe99cc..5fe030aa 100644 --- a/src/main/java/umc/cockple/demo/domain/party/repository/PartyRepositoryCustomImpl.java +++ b/src/main/java/umc/cockple/demo/domain/party/repository/PartyRepositoryCustomImpl.java @@ -51,6 +51,7 @@ public Slice searchParties(Long memberId, PartyFilterDTO.Request filter, .where(memberParty.member.id.eq(memberId)) ), //동적 필터 조건 + partyNameContains(filter.search()), addr1Eq(filter.addr1()), addr2Eq(filter.addr2()), levelIn(filter.level()), @@ -73,6 +74,10 @@ public Slice searchParties(Long memberId, PartyFilterDTO.Request filter, return new SliceImpl<>(content, pageable, hasNext); } + private BooleanExpression partyNameContains(String search) { + return StringUtils.hasText(search) ? party.partyName.contains(search) : null; + } + private BooleanExpression addr1Eq(String addr1) { return StringUtils.hasText(addr1) ? party.partyAddr.addr1.eq(addr1) : null; } diff --git a/src/main/java/umc/cockple/demo/domain/party/service/PartyQueryServiceImpl.java b/src/main/java/umc/cockple/demo/domain/party/service/PartyQueryServiceImpl.java index 81424b9a..82894ac5 100644 --- a/src/main/java/umc/cockple/demo/domain/party/service/PartyQueryServiceImpl.java +++ b/src/main/java/umc/cockple/demo/domain/party/service/PartyQueryServiceImpl.java @@ -5,6 +5,7 @@ import org.springframework.data.domain.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import umc.cockple.demo.domain.bookmark.repository.PartyBookmarkRepository; import umc.cockple.demo.domain.exercise.domain.Exercise; import umc.cockple.demo.domain.exercise.repository.ExerciseRepository; @@ -102,7 +103,7 @@ public Slice getRecommendedParties(Long memberId, Boolean isC if (isCockpleRecommend) { //--- 콕플 추천 로직 실행 --- - partySlice = getCockpleRecommendedParties(memberId, pageable); + partySlice = getCockpleRecommendedParties(memberId, filter.search(), pageable); } else { //--- 필터 조회 로직 실행 --- Pageable sortedPageable = createSortedPageable(pageable, sort); //정렬 기준 문자 검증, Pageable 객체 생성 @@ -297,12 +298,14 @@ private void validatePartyIsActive(Party party) { // ========== 비즈니스 로직 메서드 ========== //콕플 추천 로직을 처리 - private Slice getCockpleRecommendedParties(Long memberId, Pageable pageable) { + private Slice getCockpleRecommendedParties(Long memberId, String search, Pageable pageable) { //추천의 기준이 되는 정보 조회 RecommendedPartiesInfo partiesInfo = getRecommendedPartiesInfo(memberId); //지역, 나이대, 급수로 필터링 된 모임 목록 조회 List filteredParties = findFilteredParties(partiesInfo); + //이름 검색 필터 적용 + List searchedParties = filterByName(filteredParties, search); //키워드 일치 개수로 정렬 List sortedParties = sortPartiesByKeywordMatch(filteredParties, partiesInfo.keywords()); //수동으로 페이징 @@ -311,6 +314,15 @@ private Slice getCockpleRecommendedParties(Long memberId, Pageable pageab return partySlice; } + // 이름으로 모임 필터링 + private List filterByName(List parties, String search) { + if (!StringUtils.hasText(search)) + return parties; + return parties.stream() + .filter(p -> p.getPartyName().contains(search)) + .toList(); + } + //정렬 로직 처리 private Pageable createSortedPageable(Pageable pageable, String sort) { PartyOrderType sortType = PartyOrderType.fromKorean(sort);