Skip to content

Commit

Permalink
[SAMBAD-327] 모임원 조회 응답에 본인 여부, 손 흔들기 상태 필드 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
estkkj committed Sep 12, 2024
1 parent 025b089 commit a7d271d
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ public ResponseEntity<MeetingMemberResponse> getMyMeetingMember(
return ResponseEntity.ok(response);
}

@Operation(summary = "모임원 목록 조회", description = "- 특정 모임의 모임원 목록을 조회합니다.\n"
+ "- 자기 자신은 목록에서 제외합니다.")
@Operation(summary = "모임원 목록 조회", description = "- 특정 모임의 모임원 목록을 조회합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "모임원 목록 조회 성공"),
@ApiResponse(responseCode = "403", description = "USER_NOT_MEMBER_OF_MEETING")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.depromeet.sambad.moring.domain.common.utils;

import java.util.Optional;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class UserIdResolver {

public static Long resolveRequestedUserId() {
return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
.map(Authentication::getName)
.map(Long::valueOf)
.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import java.util.List;
import java.util.Optional;

import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavedMemberDto;
import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWaving;
import org.depromeet.sambad.moring.domain.meeting.member.domain.MeetingMember;

public interface HandWavingRepository {

Expand All @@ -14,7 +14,7 @@ public interface HandWavingRepository {

Optional<HandWaving> findFirstBySenderIdAndReceiverIdOrderByIdDesc(Long senderMemberId, Long receiverMemberId);

List<MeetingMember> findHandWavedMembersByMeetingMemberId(Long meetingMemberId);
List<HandWavedMemberDto> findHandWavedMembersByMeetingMemberId(Long meetingMemberId);

List<HandWaving> findAllByEventIdIn(List<Long> eventIds);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.depromeet.sambad.moring.domain.meeting.handwaving.domain;

import org.depromeet.sambad.moring.domain.meeting.member.domain.MeetingMember;

public record HandWavedMemberDto(
MeetingMember handWavedMember,
HandWaving handWaving
) {
public Long getMemberId() {
return handWavedMember.getId();
}

public HandWavingStatus getStatus() {
return handWaving.getStatus();
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package org.depromeet.sambad.moring.domain.meeting.handwaving.infrastructure;

import static org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavingStatus.*;
import static org.depromeet.sambad.moring.domain.meeting.handwaving.domain.QHandWaving.*;
import static org.depromeet.sambad.moring.domain.meeting.member.domain.QMeetingMember.*;

import java.util.List;
import java.util.Optional;

import org.depromeet.sambad.moring.domain.meeting.handwaving.application.HandWavingRepository;
import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavedMemberDto;
import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWaving;
import org.depromeet.sambad.moring.domain.meeting.member.domain.MeetingMember;
import org.springframework.stereotype.Repository;

import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -40,19 +40,25 @@ public Optional<HandWaving> findFirstBySenderIdAndReceiverIdOrderByIdDesc(Long s
}

@Override
public List<MeetingMember> findHandWavedMembersByMeetingMemberId(Long meetingMemberId) {
return query.select(meetingMember)
public List<HandWavedMemberDto> findHandWavedMembersByMeetingMemberId(Long meetingMemberId) {
List<Tuple> results = query.select(handWaving, meetingMember)
.from(handWaving)
.join(meetingMember)
.on(handWaving.receiver.id.eq(meetingMember.id)
.or(handWaving.sender.id.eq(meetingMember.id)))
.where(
handWaving.receiver.id.eq(meetingMemberId)
.or(handWaving.sender.id.eq(meetingMemberId)),
handWaving.status.eq(ACCEPTED),
meetingMember.id.ne(meetingMemberId)
)
.fetch();

return results.stream()
.map(tuple -> new HandWavedMemberDto(
tuple.get(meetingMember),
tuple.get(handWaving)
))
.toList();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public interface MeetingMemberRepository {

Optional<MeetingMember> findByUserIdAndMeetingId(Long userId, Long meetingId);

List<MeetingMember> findByMeetingIdAndMeetingMemberIdNotOrderByName(Long meetingId, Long loginMeetingMemberId);
List<MeetingMember> findByMeetingIdAndMeetingMemberIdNotInOrderByName(
Long meetingId, List<Long> excludeMemberIds);

List<MeetingMember> findNextTargetsByMeeting(Long meetingId, Long loginMeetingMemberId,
List<Long> excludeMemberIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import org.depromeet.sambad.moring.domain.event.application.EventService;
import org.depromeet.sambad.moring.domain.meeting.handwaving.application.HandWavingRepository;
import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavedMemberDto;
import org.depromeet.sambad.moring.domain.meeting.meeting.application.MeetingRepository;
import org.depromeet.sambad.moring.domain.meeting.meeting.domain.Meeting;
import org.depromeet.sambad.moring.domain.meeting.meeting.domain.MeetingCode;
Expand Down Expand Up @@ -92,11 +94,18 @@ public MeetingMemberListResponse getMeetingMembers(Long userId, Long meetingId)
meetingMemberValidator.validateUserIsMemberOfMeeting(userId, meetingId);
MeetingMember me = getByUserIdAndMeetingId(userId, meetingId);

List<MeetingMember> members = meetingMemberRepository.findByMeetingIdAndMeetingMemberIdNotOrderByName(meetingId,
me.getId());
List<MeetingMember> handWavedMembers = handWavingRepository.findHandWavedMembersByMeetingMemberId(me.getId());
List<HandWavedMemberDto> handWavedMembers = handWavingRepository.findHandWavedMembersByMeetingMemberId(me.getId());
List<Long> excludeMemberIds = handWavedMembers.stream()
.map(HandWavedMemberDto::getMemberId)
.collect(Collectors.toList());

return MeetingMemberListResponse.from(members, handWavedMembers);
// 본인은 항상 1순위이기 때문에, 목록 조회 대상에서 제외
excludeMemberIds.add(me.getId());

List<MeetingMember> notHandWavedMembers = meetingMemberRepository.findByMeetingIdAndMeetingMemberIdNotInOrderByName(
meetingId, excludeMemberIds);

return MeetingMemberListResponse.from(me, notHandWavedMembers, handWavedMembers);
}

public MeetingMember getByUserIdAndMeetingId(Long userId, Long meetingId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.depromeet.sambad.moring.domain.meeting.member.domain;

import static jakarta.persistence.EnumType.*;
import static org.depromeet.sambad.moring.domain.common.utils.UserIdResolver.*;

import java.time.LocalDate;
import java.util.ArrayList;
Expand Down Expand Up @@ -143,6 +144,10 @@ public boolean isOwner() {
return role.equals(MeetingMemberRole.OWNER);
}

public boolean isMe() {
return Objects.equals(this.user.getId(), resolveRequestedUserId());
}

@Override
public int compareTo(MeetingMember o) {
// 지연로딩 객체일 경우, getter를 통해 필드를 가져와야 프록시 객체가 초기화되어 정상적인 비교 수행 가능
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ public interface MeetingMemberJpaRepository extends JpaRepository<MeetingMember,

List<MeetingMember> findByUserId(Long userId);

List<MeetingMember> findByMeetingIdAndIdNotOrderByName(Long meetingId, Long meetingMemberId);
List<MeetingMember> findByMeetingIdAndIdNotInOrderByName(Long meetingId, List<Long> excludeMemberIds);

List<MeetingMember> findByMeetingIdOrderByName(Long meetingId);

Optional<MeetingMember> findByUserIdAndMeetingId(Long userId, Long meetingId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ public boolean isOwnerExceedingMaxMeetings(Long meetingId, int maxHostMeetings)
return meetingMemberQueryRepository.isOwnerExceedingMaxMeetings(meetingId, maxHostMeetings);
}

public List<MeetingMember> findByMeetingIdAndMeetingMemberIdNotOrderByName(Long meetingId,
Long loginMeetingMemberId) {
return meetingMemberJpaRepository.findByMeetingIdAndIdNotOrderByName(meetingId,
loginMeetingMemberId);
@Override
public List<MeetingMember> findByMeetingIdAndMeetingMemberIdNotInOrderByName(
Long meetingId, List<Long> excludeMemberIds
) {
if (excludeMemberIds.isEmpty()) {
return meetingMemberJpaRepository.findByMeetingIdOrderByName(meetingId);
}
return meetingMemberJpaRepository.findByMeetingIdAndIdNotInOrderByName(meetingId, excludeMemberIds);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public record MeetingMemberPersistRequest(
String location,

@Schema(description = "모임원 취미 ID 리스트", example = "[1, 2, 3]", requiredMode = NOT_REQUIRED)
@Size(max = 3)
List<Long> hobbyIds,

@Schema(description = "모임원 MBTI", example = "ISFP", requiredMode = NOT_REQUIRED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,53 @@

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.*;

import java.util.ArrayList;
import java.util.List;

import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavedMemberDto;
import org.depromeet.sambad.moring.domain.meeting.member.domain.MeetingMember;

import io.swagger.v3.oas.annotations.media.Schema;

public record MeetingMemberListResponse(
@Schema(
description = "모임원 목록",
example = "[{\"meetingMemberId\":1,\"name\":\"이한음\",\"profileImageFileUrl\":\"https://example.com\",\"role\":\"OWNER\"}]",
requiredMode = REQUIRED
)
List<MeetingMemberListResponseDetail> contents
) {

public static MeetingMemberListResponse from(List<MeetingMember> members, List<MeetingMember> handWavedMembers) {
List<MeetingMemberListResponseDetail> memberResponses = members.stream()
public static MeetingMemberListResponse from(
MeetingMember me, List<MeetingMember> notHandWavedMembers, List<HandWavedMemberDto> handWavedMembers
) {
List<MeetingMember> sortedHandWavedMembers = handWavedMembers.stream()
.map(HandWavedMemberDto::handWavedMember)
.sorted()
.toList();

List<MeetingMember> sortedNotHandWavedMembers = notHandWavedMembers.stream()
.sorted()
.toList();

List<MeetingMember> mergedMembers = mergeMeetingMembers(me, sortedHandWavedMembers, sortedNotHandWavedMembers);

List<MeetingMemberListResponseDetail> memberResponses = mergedMembers.stream()
.map(member -> MeetingMemberListResponseDetail.from(member, handWavedMembers))
.toList();

return new MeetingMemberListResponse(memberResponses);
}

private static List<MeetingMember> mergeMeetingMembers(
MeetingMember me, List<MeetingMember> sortedHandWavedMember, List<MeetingMember> sortedNotHandWavedMembers
) {
List<MeetingMember> mergedMembers = new ArrayList<>();

// 다음과 같은 순서대로 모임원 목록을 구성
mergedMembers.add(me);
mergedMembers.addAll(sortedHandWavedMember);
mergedMembers.addAll(sortedNotHandWavedMembers);

return mergedMembers;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.*;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.depromeet.sambad.moring.domain.file.presentation.annotation.FullFileUrl;
import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavedMemberDto;
import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavingStatus;
import org.depromeet.sambad.moring.domain.meeting.member.domain.MeetingMember;
import org.depromeet.sambad.moring.domain.meeting.member.domain.MeetingMemberRole;

Expand All @@ -25,15 +29,40 @@ public record MeetingMemberListResponseDetail(
MeetingMemberRole role,

@Schema(description = "서로 손 흔들어 인사하기를 수행했는지 여부", example = "true", requiredMode = REQUIRED)
boolean isHandWaved
boolean isHandWaved,

@Schema(description = "나인지 여부", example = "false", requiredMode = REQUIRED)
boolean isMe,

@Schema(description = "서로 손 흔들어 인사하기를 수행했는지 여부", example = "REQUESTED", requiredMode = REQUIRED)
HandWavingStatus handWavingStatus
) {
public static MeetingMemberListResponseDetail from(MeetingMember member, List<MeetingMember> handWavedMembers) {
public static MeetingMemberListResponseDetail from(
MeetingMember member, List<HandWavedMemberDto> handWavedMembers
) {

HandWavedMemberDto handWavedMember = getHandWavedMember(member, handWavedMembers);
HandWavingStatus handWavingStatus = Optional.ofNullable(handWavedMember)
.map(HandWavedMemberDto::getStatus)
.orElse(HandWavingStatus.NOT_REQUESTED);

return new MeetingMemberListResponseDetail(
member.getId(),
member.getName(),
member.getProfileImageUrl(),
member.getRole(),
handWavedMembers.contains(member)
Objects.nonNull(handWavedMember),
member.isMe(),
handWavingStatus
);
}

private static HandWavedMemberDto getHandWavedMember(
MeetingMember member, List<HandWavedMemberDto> handWavedMembers
) {
return handWavedMembers.stream()
.filter(handWavedMember -> Objects.equals(handWavedMember.getMemberId(), member.getId()))
.findFirst()
.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.depromeet.sambad.moring.domain.event.application.EventService;
import org.depromeet.sambad.moring.domain.event.domain.EventType;
import org.depromeet.sambad.moring.domain.meeting.handwaving.application.HandWavingRepository;
import org.depromeet.sambad.moring.domain.meeting.handwaving.domain.HandWavedMemberDto;
import org.depromeet.sambad.moring.domain.meeting.meeting.domain.Meeting;
import org.depromeet.sambad.moring.domain.meeting.member.application.MeetingMemberService;
import org.depromeet.sambad.moring.domain.meeting.member.domain.MeetingMember;
Expand Down Expand Up @@ -152,9 +153,10 @@ public MeetingMemberListResponse getMeetingMembersByMeetingQuestionId(
meetingQuestion.getId());
MeetingMember me = meetingMemberService.getByUserIdAndMeetingId(userId, meetingId);

List<MeetingMember> handWavedMembers = handWavingRepository.findHandWavedMembersByMeetingMemberId(me.getId());
List<HandWavedMemberDto> handWavedMembers = handWavingRepository.findHandWavedMembersByMeetingMemberId(
me.getId());

return MeetingMemberListResponse.from(members, handWavedMembers);
return MeetingMemberListResponse.from(me, members, handWavedMembers);
}

private CurrentMeetingQuestionResponse getCurrentMeetingQuestionResponse(
Expand Down

0 comments on commit a7d271d

Please sign in to comment.