Skip to content
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

[SAMBAD-327] 모임원 목록 조회 응답에 본인 여부, 손 흔들기 상태 필드 추가 #157

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading