-
Notifications
You must be signed in to change notification settings - Fork 1
[feat] 모집중인 방 상세보기 api 개발 #67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
234176b
183faac
9b0e687
0ae4a61
a52949d
68a1ad0
f7c8ca4
f8eed8f
7562ea3
f39cdf5
0baeb59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package konkuk.thip.room.adapter.in.web.response; | ||
|
|
||
| import lombok.Builder; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record RoomRecruitingDetailViewResponse( | ||
| boolean isHost, | ||
| boolean isJoining, | ||
| Long roomId, | ||
| String roomName, | ||
| String roomImageUrl, | ||
| boolean isPublic, | ||
| String progressStartDate, | ||
| String progressEndDate, | ||
| String recruitEndDate, | ||
| String category, | ||
| String roomDescription, | ||
| int memberCount, | ||
| int recruitCount, | ||
| String isbn, | ||
| String bookImageUrl, | ||
| String bookTitle, | ||
| String authorName, | ||
| String bookDescription, | ||
| List<RecommendRoom> recommendRooms | ||
| ) { | ||
| @Builder | ||
| public record RecommendRoom( | ||
| String roomImageUrl, | ||
| String roomName, | ||
| int memberCount, | ||
| int recruitCount, | ||
| String recruitEndDate | ||
| ) {} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,19 @@ | ||
| package konkuk.thip.room.adapter.out.persistence; | ||
|
|
||
| import konkuk.thip.room.adapter.in.web.response.RoomRecruitingDetailViewResponse; | ||
| import konkuk.thip.room.adapter.in.web.response.RoomGetHomeJoinedListResponse; | ||
| import konkuk.thip.room.adapter.in.web.response.RoomSearchResponse; | ||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.Pageable; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import java.time.LocalDate; | ||
|
|
||
| public interface RoomQueryRepository { | ||
|
|
||
| Page<RoomSearchResponse.RoomSearchResult> searchRoom(String keyword, String category, Pageable pageable); | ||
|
|
||
| List<RoomRecruitingDetailViewResponse.RecommendRoom> findOtherRecruitingRoomsByCategoryOrderByStartDateAsc(Long roomId, String category, int count); | ||
| Page<RoomGetHomeJoinedListResponse.RoomSearchResult> searchHomeJoinedRooms(Long userId, LocalDate today, Pageable pageable); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package konkuk.thip.room.application.port.in; | ||
|
|
||
| import konkuk.thip.room.adapter.in.web.response.RoomRecruitingDetailViewResponse; | ||
|
|
||
| public interface RoomShowRecruitingDetailViewUseCase { | ||
|
|
||
| RoomRecruitingDetailViewResponse getRecruitingRoomDetailView(Long userId, Long roomId); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,19 @@ | ||
| package konkuk.thip.room.application.port.out; | ||
|
|
||
| import konkuk.thip.room.adapter.in.web.response.RoomRecruitingDetailViewResponse; | ||
| import konkuk.thip.room.adapter.in.web.response.RoomGetHomeJoinedListResponse; | ||
| import konkuk.thip.room.adapter.in.web.response.RoomSearchResponse; | ||
| import konkuk.thip.room.domain.Room; | ||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.Pageable; | ||
|
|
||
| import java.time.LocalDate; | ||
| import java.util.List; | ||
|
|
||
| public interface RoomQueryPort { | ||
| int countRecruitingRoomsByBookAndStartDateAfter(Long bookId, LocalDate currentDate); | ||
| Page<RoomSearchResponse.RoomSearchResult> searchRoom(String keyword, String category, Pageable pageable); | ||
|
|
||
| List<RoomRecruitingDetailViewResponse.RecommendRoom> findOtherRecruitingRoomsByCategoryOrderByStartDateAsc(Room currentRoom, int count); | ||
| Page<RoomGetHomeJoinedListResponse.RoomSearchResult> searchHomeJoinedRooms(Long userId, LocalDate today, Pageable pageable); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| package konkuk.thip.room.application.service; | ||
|
|
||
| import konkuk.thip.book.application.port.out.BookCommandPort; | ||
| import konkuk.thip.book.domain.Book; | ||
| import konkuk.thip.common.util.DateUtil; | ||
| import konkuk.thip.room.adapter.in.web.response.RoomRecruitingDetailViewResponse; | ||
| import konkuk.thip.room.application.port.in.RoomShowRecruitingDetailViewUseCase; | ||
| import konkuk.thip.room.application.port.out.RoomCommandPort; | ||
| import konkuk.thip.room.application.port.out.RoomQueryPort; | ||
| import konkuk.thip.room.domain.Room; | ||
| import konkuk.thip.user.application.port.out.UserRoomCommandPort; | ||
| import konkuk.thip.user.domain.UserRoom; | ||
| import konkuk.thip.user.domain.RoomParticipants; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class RoomShowRecruitingDetailViewService implements RoomShowRecruitingDetailViewUseCase { | ||
|
|
||
| private final static int RECOMMEND_ROOM_COUNT = 5; | ||
|
|
||
| private final RoomCommandPort roomCommandPort; | ||
| private final RoomQueryPort roomQueryPort; | ||
| private final BookCommandPort bookCommandPort; | ||
| private final UserRoomCommandPort userRoomCommandPort; | ||
|
|
||
| @Override | ||
| @Transactional(readOnly = true) | ||
| public RoomRecruitingDetailViewResponse getRecruitingRoomDetailView(Long userId, Long roomId) { | ||
| // 1. Room 조회, Book 조회 | ||
| Room room = roomCommandPort.findById(roomId); | ||
| Book book = bookCommandPort.findById(room.getBookId()); | ||
|
|
||
| // 2. Room과 연관된 UserRoom 조회, RoomParticipants 일급 컬렉션 생성 | ||
| List<UserRoom> findByRoomId = userRoomCommandPort.findAllByRoomId(roomId); | ||
| RoomParticipants roomParticipants = RoomParticipants.from(findByRoomId); | ||
|
|
||
| // 3. 다른 모임방 추천 | ||
| List<RoomRecruitingDetailViewResponse.RecommendRoom> recommendRooms = roomQueryPort.findOtherRecruitingRoomsByCategoryOrderByStartDateAsc(room, RECOMMEND_ROOM_COUNT); | ||
|
|
||
| // 4. response 구성 | ||
| return buildResponse(userId, room, book, roomParticipants, recommendRooms); | ||
| } | ||
|
|
||
| private RoomRecruitingDetailViewResponse buildResponse( | ||
| Long userId, | ||
| Room room, | ||
| Book book, | ||
| RoomParticipants participants, | ||
| List<RoomRecruitingDetailViewResponse.RecommendRoom> recommendRooms | ||
| ) { | ||
| return new RoomRecruitingDetailViewResponse( | ||
| participants.isHostOfRoom(userId), | ||
| participants.isJoiningToRoom(userId), | ||
| room.getId(), | ||
| room.getTitle(), | ||
| room.getCategory().getImageUrl(), | ||
| room.isPublic(), | ||
| DateUtil.formatDate(room.getStartDate()), | ||
| DateUtil.formatDate(room.getEndDate()), | ||
| DateUtil.formatAfterTime(room.getStartDate()), | ||
| room.getCategory().getValue(), | ||
| room.getDescription(), | ||
| participants.calculateMemberCount(), | ||
| room.getRecruitCount(), | ||
| book.getIsbn(), | ||
| book.getImageUrl(), | ||
| book.getTitle(), | ||
| book.getAuthorName(), | ||
| book.getDescription(), | ||
| recommendRooms | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package konkuk.thip.user.domain; | ||
|
|
||
| import konkuk.thip.user.adapter.out.jpa.UserRoomRole; | ||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public class RoomParticipants { | ||
| /** | ||
| * 특정 Room 과 연관된 UserRoom 들을 모은 일급 컬렉션 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LGTM |
||
| */ | ||
|
|
||
| private final List<UserRoom> participants; | ||
|
|
||
| public static RoomParticipants from(List<UserRoom> participants) { | ||
| return new RoomParticipants(participants); | ||
| } | ||
|
|
||
| public int calculateMemberCount() { | ||
| return participants.size(); | ||
| } | ||
|
|
||
| public boolean isJoiningToRoom(Long userId) { | ||
| return participants.stream() | ||
| .anyMatch(userRoom -> userRoom.getUserId().equals(userId)); | ||
| } | ||
|
|
||
| public boolean isHostOfRoom(Long userId) { | ||
| return participants.stream() | ||
| .filter(userRoom -> userRoom.getUserId().equals(userId)) | ||
| .anyMatch(userRoom -> userRoom.getUserRoomRole().equals(UserRoomRole.HOST.getType())); | ||
| } | ||
| } | ||
|
Comment on lines
+8
to
+36
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p3: 특정 Room과 연관된 UserRoom들이니까 Room 도메인에 속하지 않을까 싶은데 User 패키지 아래 두신 이유가 따로있나욥
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 딱히 이유 없습니다! 그냥 UserRoom 의 List를 포함하는 일급컬렉션이어서 UserRoom 과 같은 패키지에 위치시켰습니다! |
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p3: 두 메서드의 조건이 중복되는 것 같은데
isJoiningToRoom(user)를 먼저 호출하여 true일 경우에만isHostOfRoom(userId)을 호출하는거 어떨까요?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
response를 구성할때 if 분기처리를 통해서 isJoining 이 true인 경우에만 isHost 메서드를 호출하는 흐름을 말하시는거 같은데, response를 구성할때 분기처리 로직을 추가하는거 보다, 단순히 메서드를 호출하는게 더 가독성이 있지않나 싶어서 이렇게 구현했긴합니다!