From 232871fdfafb7b2e574701a5f7a008e5b5bcbb4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=84=EB=AA=A8?= Date: Tue, 6 Feb 2024 00:10:04 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=ED=8C=94=EB=A1=9C?= =?UTF-8?q?=EC=9E=89/=ED=8C=94=EB=A1=9C=EC=9B=8C=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20(#274)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 유저 팔로잉/팔로워 목록 조회 API * style: spotless * refactor: 메소드 추출 * style: spotless --- .../domain/follow/api/FollowController.java | 8 ++ .../follow/application/FollowService.java | 80 ++++++++++++++++++- .../dto/response/FollowListResponse.java | 16 ++++ 3 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/depromeet/domain/follow/dto/response/FollowListResponse.java diff --git a/src/main/java/com/depromeet/domain/follow/api/FollowController.java b/src/main/java/com/depromeet/domain/follow/api/FollowController.java index b974e58e6..3fcd80209 100644 --- a/src/main/java/com/depromeet/domain/follow/api/FollowController.java +++ b/src/main/java/com/depromeet/domain/follow/api/FollowController.java @@ -5,6 +5,7 @@ import com.depromeet.domain.follow.dto.request.FollowDeleteRequest; import com.depromeet.domain.follow.dto.response.FollowFindMeInfoResponse; import com.depromeet.domain.follow.dto.response.FollowFindTargetInfoResponse; +import com.depromeet.domain.follow.dto.response.FollowListResponse; import com.depromeet.domain.follow.dto.response.MemberFollowedResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -56,4 +57,11 @@ public FollowFindMeInfoResponse followFindMe() { public List followedUserFindAll() { return followService.findAllFollowedMember(); } + + // 팔로잉, 팔로워 리스트 응답 + @GetMapping("/{targetId}/list") + @Operation(summary = "팔로잉, 팔로워 유저 리스트를 반환합니다", description = "팔로잉, 팔로워 유저들을 반환합니다.") + public FollowListResponse followList(@PathVariable Long targetId) { + return followService.findFollowList(targetId); + } } diff --git a/src/main/java/com/depromeet/domain/follow/application/FollowService.java b/src/main/java/com/depromeet/domain/follow/application/FollowService.java index d7d6306c4..3cb37811b 100644 --- a/src/main/java/com/depromeet/domain/follow/application/FollowService.java +++ b/src/main/java/com/depromeet/domain/follow/application/FollowService.java @@ -4,12 +4,10 @@ import com.depromeet.domain.follow.domain.MemberRelation; import com.depromeet.domain.follow.dto.request.FollowCreateRequest; import com.depromeet.domain.follow.dto.request.FollowDeleteRequest; -import com.depromeet.domain.follow.dto.response.FollowFindMeInfoResponse; -import com.depromeet.domain.follow.dto.response.FollowFindTargetInfoResponse; -import com.depromeet.domain.follow.dto.response.FollowStatus; -import com.depromeet.domain.follow.dto.response.MemberFollowedResponse; +import com.depromeet.domain.follow.dto.response.*; import com.depromeet.domain.member.dao.MemberRepository; import com.depromeet.domain.member.domain.Member; +import com.depromeet.domain.member.dto.response.MemberSearchResponse; import com.depromeet.domain.mission.domain.Mission; import com.depromeet.domain.missionRecord.domain.ImageUploadStatus; import com.depromeet.domain.missionRecord.domain.MissionRecord; @@ -188,4 +186,78 @@ private Member getTargetMember(Long targetId) { ErrorCode.FOLLOW_TARGET_MEMBER_NOT_FOUND)); return targetMember; } + + public FollowListResponse findFollowList(Long targetId) { + final Member currentMember = memberUtil.getCurrentMember(); + Member targetMember = getTargetMember(targetId); + + List followingList = new ArrayList<>(); + List followerList = new ArrayList<>(); + + List targetMemberSources = + memberRelationRepository.findAllBySourceId(targetMember.getId()); + List targetMemberTargets = + memberRelationRepository.findAllByTargetId(targetMember.getId()); + + List currentMemberSources = + memberRelationRepository.findAllBySourceId(currentMember.getId()); + List currentMemberTargets = + memberRelationRepository.findAllByTargetId(currentMember.getId()); + + // target 유저의 팔로잉 + List followingMembers = + targetMemberSources.stream().map(MemberRelation::getTarget).toList(); + + // target 유저의 팔로워 + List followerMembers = + targetMemberTargets.stream().map(MemberRelation::getSource).toList(); + + // 팔로잉 리스트 구하기 + getFollowStatusIncludeList( + followingMembers, currentMemberSources, followingList, currentMemberTargets); + + // 팔로워 리스트 구하기 + getFollowStatusIncludeList( + followerMembers, currentMemberSources, followerList, currentMemberTargets); + + return FollowListResponse.of( + targetMember.getProfile().getNickname(), followingList, followerList); + } + + private static void getFollowStatusIncludeList( + List targetMembers, + List currentMemberSources, + List resultList, + List currentMemberTargets) { + for (Member member : targetMembers) { + boolean existRelation = false; + for (MemberRelation memberRelation : currentMemberSources) { + if (member.getId().equals(memberRelation.getTarget().getId())) { + existRelation = true; + break; + } + } + + if (existRelation) { // 조회 된 애들 중 내가 팔로우한 애라면 + resultList.add(MemberSearchResponse.toFollowingResponse(member)); + continue; + } + + // 내가 팔로우를 하지 않았을 때 + Optional optionalMemberRelation = + currentMemberTargets.stream() + .filter( + memberRelation -> + member.getId() + .equals(memberRelation.getSource().getId())) + .findFirst(); + if (optionalMemberRelation.isPresent()) { // 상대방만 나를 팔로우 하고 있을 때 + resultList.add(MemberSearchResponse.toFollowedByMeResponse(member)); + continue; + } + + // 아니라면 서로 팔로우가 아닌 상태 + resultList.add(MemberSearchResponse.toNotFollowingResponse(member)); + } + } } diff --git a/src/main/java/com/depromeet/domain/follow/dto/response/FollowListResponse.java b/src/main/java/com/depromeet/domain/follow/dto/response/FollowListResponse.java new file mode 100644 index 000000000..cd15b49a1 --- /dev/null +++ b/src/main/java/com/depromeet/domain/follow/dto/response/FollowListResponse.java @@ -0,0 +1,16 @@ +package com.depromeet.domain.follow.dto.response; + +import com.depromeet.domain.member.dto.response.MemberSearchResponse; +import java.util.List; + +public record FollowListResponse( + String targetNickname, + List followingList, + List followerList) { + public static FollowListResponse of( + String targetNickname, + List followingList, + List followerList) { + return new FollowListResponse(targetNickname, followingList, followerList); + } +}