Skip to content

Commit d73fd0c

Browse files
authored
fix : 요청사항 1차 완료 (#67)
1 parent 0ba8b8b commit d73fd0c

File tree

5 files changed

+128
-17
lines changed

5 files changed

+128
-17
lines changed

backend/src/main/java/com/back/domain/party/party/controller/ApiV1PartyController.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.back.domain.party.party.controller;
22

3+
import com.back.domain.mission.enums.MissionCategory;
34
import com.back.domain.party.party.dto.*;
45
import com.back.domain.party.party.entity.Party;
56
import com.back.domain.party.party.entity.PartyMember;
@@ -11,11 +12,16 @@
1112
import io.swagger.v3.oas.annotations.tags.Tag;
1213
import jakarta.validation.Valid;
1314
import lombok.RequiredArgsConstructor;
15+
import org.springdoc.core.annotations.ParameterObject;
16+
import org.springframework.data.domain.Page;
17+
import org.springframework.data.domain.Pageable;
18+
import org.springframework.format.annotation.DateTimeFormat;
1419
import org.springframework.http.HttpStatus;
1520
import org.springframework.http.ResponseEntity;
1621
import org.springframework.security.core.Authentication;
1722
import org.springframework.web.bind.annotation.*;
1823

24+
import java.time.LocalDate;
1925
import java.util.List;
2026
import java.util.stream.Collectors;
2127

@@ -112,16 +118,17 @@ public ResponseEntity<ApiResponse<Void>> deleteParty(
112118
}
113119

114120
@GetMapping
115-
@Operation(summary = "파티 목록 조회", description = "공개 파티 목록을 조회하는 API")
116-
public ResponseEntity<ApiResponse<List<PartyDto>>> getPartyList() {
117-
List<Party> parties = partyService.getPartyList();
118-
List<PartyDto> partyDtos = parties.stream()
119-
.map(PartyDto::new)
120-
.collect(Collectors.toList());
121+
@Operation(summary = "파티 목록 조회", description = "공개 파티 목록을 조회하고, 정렬(최신순/조회순) 및 필터링(카테고리/시작일)을 지원합니다.")
122+
public ResponseEntity<ApiResponse<Page<PartyDto>>> getPublicParties(
123+
@ParameterObject Pageable pageable,
124+
@RequestParam(required = false) MissionCategory category,
125+
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate
126+
) {
127+
Page<PartyDto> partyPage = partyService.getPublicPartyList(pageable, category, startDate);
121128

122129
return ResponseEntity
123130
.status(HttpStatus.OK)
124-
.body(ApiResponse.success("200", "파티 목록 조회 성공", partyDtos));
131+
.body(ApiResponse.success("200", "파티 목록 조회 성공", partyPage));
125132
}
126133

127134
@GetMapping("/{partyId}")

backend/src/main/java/com/back/domain/party/party/dto/PartyDto.java

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.back.domain.party.party.dto;
22

3+
import com.back.domain.mission.entity.Mission;
4+
import com.back.domain.mission.enums.MissionCategory;
35
import com.back.domain.party.party.entity.Party;
6+
import com.back.domain.party.party.entity.PartyMemberStatus;
47
import lombok.Getter;
58
import lombok.NoArgsConstructor;
69
import lombok.Setter;
710

11+
import java.time.LocalDate;
812
import java.util.List;
913
import java.util.stream.Collectors;
1014

@@ -19,21 +23,64 @@ public class PartyDto {
1923
private Integer maxMembers;
2024
private Boolean isPublic;
2125
private List<PartyMemberDto> members;
26+
private MissionCategory category;
27+
private LocalDate startDate;
28+
private LocalDate endDate;
29+
private LocalDate createDate;
30+
private Integer views;
2231

23-
// 미션 도메인 완성 시 사용
24-
// private Integer missionId;
32+
33+
public PartyDto(Party party, Mission mission) {
34+
this.id = party.getId();
35+
this.name = party.getName();
36+
this.leaderId = party.getLeader().getId();
37+
38+
this.currentMembers = (int) party.getPartyMembers().stream()
39+
.filter(pm -> pm.getStatus() == PartyMemberStatus.ACCEPTED)
40+
.count();
41+
42+
this.maxMembers = party.getMaxMembers();
43+
this.isPublic = party.isPublic();
44+
45+
this.createDate = party.getCreateDate().toLocalDate();
46+
47+
this.views = party.getViews();
48+
49+
if (mission != null) {
50+
this.category = mission.getCategory();
51+
this.startDate = mission.getStartDate();
52+
this.endDate = mission.getEndDate();
53+
}
54+
55+
this.members = party.getPartyMembers().stream()
56+
.filter(pm -> pm.getStatus() == PartyMemberStatus.ACCEPTED)
57+
.map(partyMember -> new PartyMemberDto(partyMember.getMember()))
58+
.collect(Collectors.toList());
59+
}
2560

2661
public PartyDto(Party party) {
2762
this.id = party.getId();
2863
this.name = party.getName();
2964
this.leaderId = party.getLeader().getId();
30-
this.currentMembers = party.getPartyMembers().size();
65+
66+
this.currentMembers = (int) party.getPartyMembers().stream()
67+
.filter(pm -> pm.getStatus() == PartyMemberStatus.ACCEPTED)
68+
.count();
69+
3170
this.maxMembers = party.getMaxMembers();
3271
this.isPublic = party.isPublic();
72+
73+
this.createDate = party.getCreateDate().toLocalDate();
74+
this.views = party.getViews();
75+
76+
this.category = null;
77+
this.startDate = null;
78+
this.endDate = null;
79+
3380
this.members = party.getPartyMembers().stream()
81+
.filter(pm -> pm.getStatus() == PartyMemberStatus.ACCEPTED)
3482
.map(partyMember -> new PartyMemberDto(partyMember.getMember()))
3583
.collect(Collectors.toList());
36-
// missionId는 미션 도메인 완성 후 추가
37-
// this.missionId = party.getMission().getId();
3884
}
85+
3986
}

backend/src/main/java/com/back/domain/party/party/entity/Party.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ public class Party extends BaseEntity {
2727
@JoinColumn(name = "leader_id")
2828
private Member leader;
2929

30-
// @ManyToOne(fetch = FetchType.LAZY)
31-
// @JoinColumn(name = "mission_id")
32-
// private Mission mission;
30+
@Column(nullable = false)
31+
private Integer views = 0;
32+
33+
public void incrementViews() {
34+
this.views++;
35+
}
3336

3437
@OneToMany(mappedBy = "party", cascade = CascadeType.ALL, orphanRemoval = true)
3538
private List<PartyMember> partyMembers = new ArrayList<>();

backend/src/main/java/com/back/domain/party/party/repository/PartyRepository.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.back.domain.party.party.repository;
22

33
import com.back.domain.party.party.entity.Party;
4+
import org.springframework.data.domain.Page;
5+
import org.springframework.data.domain.Pageable;
46
import org.springframework.data.jpa.repository.EntityGraph;
57
import org.springframework.data.jpa.repository.JpaRepository;
8+
import org.springframework.data.jpa.repository.Query;
69
import org.springframework.stereotype.Repository;
710

811
import java.util.List;
@@ -25,6 +28,11 @@ public interface PartyRepository extends JpaRepository<Party, Integer> {
2528
@EntityGraph(attributePaths = {"leader", "partyMembers.member"})
2629
Optional<Party> findById(Integer partyId);
2730

28-
// 특정 미션을 진행하는 파티를 찾는 메서드 (미션 도메인 완성 시 사용)
29-
// Optional<Party> findByMission_Id(Integer missionId);
31+
@Query(value = "SELECT DISTINCT p FROM Party p " +
32+
"LEFT JOIN FETCH p.leader l " +
33+
"LEFT JOIN p.partyMembers pm " +
34+
"LEFT JOIN Mission m ON m.party = p " +
35+
"WHERE p.isPublic = true",
36+
countQuery = "SELECT COUNT(p) FROM Party p WHERE p.isPublic = true")
37+
Page<Party> findPublicPartiesWithMissionAndMembers(Pageable pageable);
3038
}

backend/src/main/java/com/back/domain/party/party/service/PartyService.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import com.back.domain.member.entity.Member;
44
import com.back.domain.member.repository.MemberRepository;
5+
import com.back.domain.mission.entity.Mission;
6+
import com.back.domain.mission.enums.MissionCategory;
7+
import com.back.domain.mission.repository.MissionRepository;
8+
import com.back.domain.party.party.dto.PartyDto;
59
import com.back.domain.party.party.dto.PartyRequestDto;
610
import com.back.domain.party.party.dto.PartyUpdateRequestDto;
711
import com.back.domain.party.party.entity.Party;
@@ -14,13 +18,19 @@
1418
import lombok.RequiredArgsConstructor;
1519
import org.springframework.cache.annotation.CacheEvict;
1620
import org.springframework.cache.annotation.Cacheable;
21+
import org.springframework.data.domain.Page;
22+
import org.springframework.data.domain.PageImpl;
23+
import org.springframework.data.domain.Pageable;
1724
import org.springframework.stereotype.Service;
1825
import org.springframework.transaction.annotation.Transactional;
1926

27+
import java.time.LocalDate;
2028
import java.time.LocalDateTime;
2129
import java.util.Comparator;
2230
import java.util.List;
2331
import java.util.Objects;
32+
import java.util.Optional;
33+
import java.util.stream.Collectors;
2434

2535
@Service
2636
@RequiredArgsConstructor
@@ -30,6 +40,42 @@ public class PartyService {
3040
private final PartyRepository partyRepository;
3141
private final MemberRepository memberRepository;
3242
private final PartyMemberRepository partyMemberRepository;
43+
private final MissionRepository missionRepository;
44+
45+
public Page<PartyDto> getPublicPartyList(
46+
Pageable pageable,
47+
MissionCategory categoryFilter,
48+
LocalDate startDateFilter
49+
) {
50+
// 1. Repository를 사용하여 페이징 및 정렬된 Party 리스트 조회 (Mission, Leader, Members 포함)
51+
Page<Party> partyPage = partyRepository.findPublicPartiesWithMissionAndMembers(pageable);
52+
List<Party> parties = partyPage.getContent();
53+
54+
// 2. 파티 목록을 PartyDto로 변환하면서 Mission 정보를 매핑하고 필터링
55+
List<PartyDto> dtoList = parties.stream()
56+
.map(party -> {
57+
// MissionRepository를 사용하여 파티에 연결된 Mission을 조회 (파티당 하나의 미션만 있다고 가정)
58+
Optional<Mission> missionOptional = missionRepository.findByPartyId(party.getId()).stream().findFirst();
59+
60+
// Mission 정보를 포함하는 생성자로 DTO 생성
61+
PartyDto dto = new PartyDto(party, missionOptional.orElse(null));
62+
63+
// 3. Service에서 필터링 조건 확인 (DB 쿼리로 처리할 수 없는 동적 필터링을 여기서 처리)
64+
if (categoryFilter != null && (dto.getCategory() == null || !dto.getCategory().equals(categoryFilter))) {
65+
return null; // 카테고리 필터 불일치
66+
}
67+
if (startDateFilter != null && (dto.getStartDate() == null || !dto.getStartDate().isEqual(startDateFilter))) {
68+
return null; // 시작일 필터 불일치
69+
}
70+
return dto;
71+
})
72+
.filter(Objects::nonNull) // 필터링 조건에 맞지 않아 null이 된 항목 제거
73+
.collect(Collectors.toList());
74+
75+
76+
// 4. 필터링된 리스트를 Page 객체로 다시 변환하여 반환
77+
return new PageImpl<>(dtoList, pageable, partyPage.getTotalElements());
78+
}
3379

3480
// 파티 정원 확인 메서드
3581
private void checkPartyCapacity(Party party) {

0 commit comments

Comments
 (0)