diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock index 2b1859b..b7ef009 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.lock and b/.gradle/8.8/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock index f96e492..61f9f9a 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.lock and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index ed80e72..87e9da0 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/src/main/java/likelion/MZConnent/api/club/ClubController.java b/src/main/java/likelion/MZConnent/api/club/ClubController.java index 685232b..6157065 100644 --- a/src/main/java/likelion/MZConnent/api/club/ClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/ClubController.java @@ -2,10 +2,9 @@ import jakarta.validation.Valid; import likelion.MZConnent.domain.member.Member; +import likelion.MZConnent.dto.club.request.ClubSimpleRequest; import likelion.MZConnent.dto.club.request.CreateClubRequest; -import likelion.MZConnent.dto.club.response.ClubDetailResponse; -import likelion.MZConnent.dto.club.response.CreateClubResponse; -import likelion.MZConnent.dto.club.response.RegionCategoryResponse; +import likelion.MZConnent.dto.club.response.*; import likelion.MZConnent.jwt.principle.UserPrinciple; import likelion.MZConnent.repository.member.MemberRepository; import likelion.MZConnent.service.club.ClubInfoService; @@ -13,12 +12,18 @@ import likelion.MZConnent.service.club.RegionCategoryService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; +import java.util.List; import java.util.Map; @Slf4j @@ -73,4 +78,22 @@ public ResponseEntity getClubDetail(@PathVariable Long clubI return ResponseEntity.ok(clubDetail); } + + @GetMapping("/api/clubs/list") + public ResponseEntity> getClubList( + @RequestParam(value = "page", defaultValue = "0") int pageNumber, + @RequestParam(value = "sort", defaultValue = "createdDate") String sortWay, + @RequestBody ClubSimpleRequest request) { + + Pageable pageable; + if(sortWay.equals("meetingDate")){ + pageable = PageRequest.of(pageNumber, 6, Sort.by(sortWay).ascending()); + } + else { + pageable = PageRequest.of(pageNumber, 6, Sort.by(sortWay).descending()); + } + + PageContentResponse clubList = clubInfoService.getClubList(request, pageable); + return ResponseEntity.ok(clubList); + } } diff --git a/src/main/java/likelion/MZConnent/config/SecurityConfig.java b/src/main/java/likelion/MZConnent/config/SecurityConfig.java index 905050f..7bb03f8 100644 --- a/src/main/java/likelion/MZConnent/config/SecurityConfig.java +++ b/src/main/java/likelion/MZConnent/config/SecurityConfig.java @@ -34,7 +34,7 @@ public class SecurityConfig { "/swagger", "/swagger-ui.html", "/swagger-ui/**", "/api-docs", "/api-docs/**", "/v3/api-docs/**", //swagger }; private final String[] anonymousUrl = { - "/api/auth/signup", "/api/categories/region", "/api/clubs/*" + "/api/auth/signup", "/api/categories/region", "/api/clubs/*", "/api/clubs/list" }; diff --git a/src/main/java/likelion/MZConnent/dto/club/request/ClubSimpleRequest.java b/src/main/java/likelion/MZConnent/dto/club/request/ClubSimpleRequest.java new file mode 100644 index 0000000..aba263a --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/request/ClubSimpleRequest.java @@ -0,0 +1,19 @@ +package likelion.MZConnent.dto.club.request; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ClubSimpleRequest { + private Long cultureId; + private Long regionId; + + @Builder + public ClubSimpleRequest(Long cultureId, Long regionId) { + this.cultureId = cultureId; + this.regionId = regionId; + } +} diff --git a/src/main/java/likelion/MZConnent/dto/club/response/ClubSimpleResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/ClubSimpleResponse.java new file mode 100644 index 0000000..451a7d1 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/ClubSimpleResponse.java @@ -0,0 +1,46 @@ +package likelion.MZConnent.dto.club.response; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor +public class ClubSimpleResponse { + private Long clubId; + private String title; + private Long regionId; + private String regionName; + private Long cultureCategoryId; + private String cultureName; + private String leaderProfileImage; + private LocalDate meetingDate; + private LocalDateTime createdDate; + private String genderRestriction; + private String ageRestriction; + private int currentParticipant; + private int maxParticipant; + + @Builder + public ClubSimpleResponse(Long clubId, String title, Long regionId, String regionName, Long cultureCategoryId, + String cultureName, String leaderProfileImage, LocalDate meetingDate, + LocalDateTime createdDate, String genderRestriction, String ageRestriction, + int currentParticipant, int maxParticipant) { + this.clubId = clubId; + this.title = title; + this.regionId = regionId; + this.regionName = regionName; + this.cultureCategoryId = cultureCategoryId; + this.cultureName = cultureName; + this.leaderProfileImage = leaderProfileImage; + this.meetingDate = meetingDate; + this.createdDate = createdDate; + this.genderRestriction = genderRestriction; + this.ageRestriction = ageRestriction; + this.currentParticipant = currentParticipant; + this.maxParticipant = maxParticipant; + } +} diff --git a/src/main/java/likelion/MZConnent/dto/club/response/PageContentResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/PageContentResponse.java new file mode 100644 index 0000000..77720e6 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/PageContentResponse.java @@ -0,0 +1,22 @@ +package likelion.MZConnent.dto.club.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@NoArgsConstructor +public class PageContentResponse { + private List content; + private int totalPages; + private long totalElements; + private int size; + + public PageContentResponse(List content, int totalPages, long totalElements, int size) { + this.content = content; + this.totalPages = totalPages; + this.totalElements = totalElements; + this.size = size; + } +} diff --git a/src/main/java/likelion/MZConnent/repository/club/ClubRepository.java b/src/main/java/likelion/MZConnent/repository/club/ClubRepository.java index 4f05998..d03da70 100644 --- a/src/main/java/likelion/MZConnent/repository/club/ClubRepository.java +++ b/src/main/java/likelion/MZConnent/repository/club/ClubRepository.java @@ -1,10 +1,24 @@ package likelion.MZConnent.repository.club; import likelion.MZConnent.domain.club.Club; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface ClubRepository extends JpaRepository { + + // status가 OPEN인 클럽만 조회 + // cultureId와 regionId가 0이면 무시 + // cultureId와 regionId가 0이 아니면 해당 cultureId와 regionId에 맞는 클럽만 조회 + @Query("SELECT c FROM Club c WHERE c.status = 'OPEN' " + + "AND (:cultureId = 0 OR c.culture.cultureId = :cultureId) " + + "AND (:regionId = 0 OR c.region.regionId = :regionId)") + Page findAllByFilters(@Param("cultureId") Long cultureId, + @Param("regionId") Long regionId, + Pageable pageable); } diff --git a/src/main/java/likelion/MZConnent/service/club/ClubInfoService.java b/src/main/java/likelion/MZConnent/service/club/ClubInfoService.java index cdbba40..83b10c7 100644 --- a/src/main/java/likelion/MZConnent/service/club/ClubInfoService.java +++ b/src/main/java/likelion/MZConnent/service/club/ClubInfoService.java @@ -4,10 +4,15 @@ import likelion.MZConnent.domain.member.Member; import likelion.MZConnent.dto.club.LeaderDto; import likelion.MZConnent.dto.club.SelfIntroductionDto; +import likelion.MZConnent.dto.club.request.ClubSimpleRequest; import likelion.MZConnent.dto.club.response.ClubDetailResponse; +import likelion.MZConnent.dto.club.response.ClubSimpleResponse; +import likelion.MZConnent.dto.club.response.PageContentResponse; import likelion.MZConnent.repository.club.ClubRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import likelion.MZConnent.domain.club.Club; @@ -77,4 +82,42 @@ private ClubDetailResponse buildClubDetailResponse(Long clubId, Member member) { .leader(leaderResponses) .build(); } + + public PageContentResponse getClubList(ClubSimpleRequest request, Pageable pageable) { + Page clubs = clubRepository.findAllByFilters( + request.getCultureId(), + request.getRegionId(), + pageable); + + return new PageContentResponse<>( + clubs.stream() + .map(club -> ClubSimpleResponse.builder() + .clubId(club.getClubId()) + .title(club.getTitle()) + .regionId(club.getRegion().getRegionId()) + .regionName(club.getRegion().getName()) + .cultureCategoryId(club.getCulture().getCultureCategory().getId()) + .cultureName(club.getCulture().getName()) + .leaderProfileImage(getLeaderProfileImage(club)) + .meetingDate(club.getMeetingDate()) + .createdDate(club.getCreatedDate()) + .genderRestriction(club.getGenderRestriction().name()) + .ageRestriction(club.getAgeRestriction().name()) + .currentParticipant(club.getCurrentParticipant()) + .maxParticipant(club.getMaxParticipant()) + .build()) + .collect(Collectors.toList()), + clubs.getTotalPages(), + clubs.getTotalElements(), + pageable.getPageSize() + ); + } + + private String getLeaderProfileImage(Club club) { + return club.getClubMembers().stream() + .filter(cm -> cm.getClubRole() == ClubRole.LEADER) + .findFirst() + .map(cm -> cm.getMember().getProfileImageUrl()) + .orElse(null); + } }