Skip to content

Commit

Permalink
Merge pull request #191 from Codiary-UMC-6th/refactor/#173-myPage
Browse files Browse the repository at this point in the history
Feat: ํŒ€ ID ์ถ”๊ฐ€ ๋ฐ˜ํ™˜
  • Loading branch information
yumzen authored Aug 20, 2024
2 parents 6141d5f + a0665d0 commit 4e89a63
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import com.codiary.backend.global.domain.entity.Member;
import com.codiary.backend.global.domain.entity.Team;
import com.codiary.backend.global.domain.entity.mapping.MemberCategory;
import com.codiary.backend.global.domain.entity.mapping.TeamMember;
import com.codiary.backend.global.domain.entity.mapping.TechStacks;
import com.codiary.backend.global.web.dto.Member.FollowResponseDto;
import com.codiary.backend.global.web.dto.Member.MemberResponseDTO;
import com.codiary.backend.global.web.dto.Member.MemberSumResponseDto;
import com.codiary.backend.global.web.dto.Team.TeamResponseDTO;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -174,8 +174,13 @@ public static MemberResponseDTO.UserProfileDTO toProfileResponseDto(Member membe
.map(TechStacks::getName)
.collect(Collectors.toList()))
.teamList(user.getTeamMemberList().stream()
.map(TeamMember::getTeam)
.map(Team::getName)
.map(teamMember -> {
Team team = teamMember.getTeam();
return TeamResponseDTO.TeamPreviewDTO.builder()
.teamId(team.getTeamId())
.teamName(team.getName())
.build();
})
.collect(Collectors.toList()))
.myPage(user.getMemberId().equals(member.getMemberId()))
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,112 +1,14 @@
package com.codiary.backend.global.service.MemberService;

import com.codiary.backend.global.apiPayload.code.status.ErrorStatus;
import com.codiary.backend.global.apiPayload.exception.GeneralException;
import com.codiary.backend.global.domain.entity.Follow;
import com.codiary.backend.global.domain.entity.Member;
import com.codiary.backend.global.repository.FollowRepository;
import com.codiary.backend.global.repository.MemberRepository;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

@Service
@RequiredArgsConstructor
public class FollowService {
private final FollowRepository followRepository;
private final MemberRepository memberRepository;

@Transactional
public Follow follow(Long toId, Member fromMember) {
if (fromMember == null) {
throw new GeneralException(ErrorStatus.MEMBER_NOT_FOUND);
}
if (toId.equals(fromMember.getMemberId())) {
throw new GeneralException(ErrorStatus.MEMBER_SELF_FOLLOW);
}

fromMember = memberRepository.findByToIdWithFollowings(fromMember.getMemberId())
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));
Member toMember = memberRepository.findByToIdWithFollowers(toId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

Follow follow = followRepository.findByFromMemberAndToMember(fromMember, toMember)
.orElse(null);

if (follow == null) {
follow = Follow.builder()
.fromMember(fromMember)
.toMember(toMember)
.followStatus(true)
.build();
fromMember.getFollowings().add(follow);
toMember.getFollowers().add(follow);
} else {
if (follow.getFollowStatus()) {
follow.update(false);
fromMember.getFollowings().remove(follow);
toMember.getFollowers().remove(follow);
} else {
follow.update(true);
fromMember.getFollowings().add(follow);
toMember.getFollowers().add(follow);
}
}
followRepository.save(follow);

return follow;
}

@Transactional
public Boolean isFollowing(Long toId, Member fromMember) {
if(fromMember == null){
throw new GeneralException(ErrorStatus.MEMBER_NOT_FOUND);
}
if (toId.equals(fromMember.getMemberId())) {
throw new GeneralException(ErrorStatus.MEMBER_SELF_FOLLOW);
}
Member toMember = memberRepository.findById(toId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

return followRepository.findByFromMemberAndToMember(fromMember, toMember)
.map(Follow::getFollowStatus)
.orElse(false);
}


@Transactional
public List<Member> getFollowings(Member member) {
if (member == null) {
throw new GeneralException(ErrorStatus.MEMBER_NOT_FOUND);
}

member = memberRepository.findByToIdWithFollowings(member.getMemberId())
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

List<Follow> followings = followRepository.findByFromMemberAndFollowStatusTrueOrderByUpdatedAt(member);

return followings.stream()
.map(Follow::getToMember)
.collect(Collectors.toList());
}

@Transactional
public List<Member> getFollowers(Member member) {
if (member == null) {
throw new GeneralException(ErrorStatus.MEMBER_NOT_FOUND);
}

member = memberRepository.findByToIdWithFollowers(member.getMemberId())
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

List<Follow> followers = followRepository.findByToMemberAndFollowStatusTrueOrderByUpdatedAt(member);
public interface FollowService {

return followers.stream()
.map(Follow::getFromMember)
.collect(Collectors.toList());
}
Follow follow(Long toId, Member fromMember);
Boolean isFollowing(Long toId, Member fromMember);
List<Member> getFollowings(Member member);
List<Member> getFollowers(Member member);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.codiary.backend.global.service.MemberService;


import com.codiary.backend.global.apiPayload.code.status.ErrorStatus;
import com.codiary.backend.global.apiPayload.exception.GeneralException;
import com.codiary.backend.global.domain.entity.Follow;
import com.codiary.backend.global.domain.entity.Member;
import com.codiary.backend.global.repository.FollowRepository;
import com.codiary.backend.global.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

@Service
@RequiredArgsConstructor
public class FollowServiceImpl implements FollowService {
private final FollowRepository followRepository;
private final MemberRepository memberRepository;

@Override
public Follow follow(Long toId, Member fromMember) {
//Validation: fromMember ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ/ toMember ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ/ ์ž๊ธฐ ์ž์‹  ํŒ”๋กœ์šฐ ๋ถˆ๊ฐ€/ ์ด๋ฏธ ํŒ”๋กœ์šฐ ์ค‘์ธ์ง€ ํ™•์ธ
if (fromMember == null) {
throw new GeneralException(ErrorStatus.MEMBER_NOT_FOUND);
}

Member toMember = memberRepository.findByToIdWithFollowers(toId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

if (toId.equals(fromMember.getMemberId())) {
throw new GeneralException(ErrorStatus.MEMBER_SELF_FOLLOW);
}

Follow follow = followRepository.findByFromMemberAndToMember(fromMember, toMember)
.orElse(null);

// Business Logic: ํŒ”๋กœ์ž‰ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ํŒ”๋กœ์ž‰ ์ถ”๊ฐ€/์‚ญ์ œ
if (follow == null) {
follow = Follow.builder()
.fromMember(fromMember)
.toMember(toMember)
.followStatus(true)
.build();
fromMember.getFollowings().add(follow);
toMember.getFollowers().add(follow);
} else {
if (follow.getFollowStatus()) {
follow.update(false);
fromMember.getFollowings().remove(follow);
toMember.getFollowers().remove(follow);
} else {
follow.update(true);
fromMember.getFollowings().add(follow);
toMember.getFollowers().add(follow);
}
}
followRepository.save(follow);

// Response: ํŒ”๋กœ์šฐ ์ •๋ณด ๋ฐ˜ํ™˜
return follow;
}

@Override
public Boolean isFollowing(Long toId, Member fromMember) {
//Validation: fromMember ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ/ toMember ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ/ ์ž๊ธฐ ์ž์‹  ํŒ”๋กœ์šฐ ๋ถˆ๊ฐ€
if(fromMember == null){
throw new GeneralException(ErrorStatus.MEMBER_NOT_FOUND);
}
if (toId.equals(fromMember.getMemberId())) {
throw new GeneralException(ErrorStatus.MEMBER_SELF_FOLLOW);
}
Member toMember = memberRepository.findById(toId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

// Response: ํŒ”๋กœ์ž‰ ์—ฌ๋ถ€ ๋ฐ˜ํ™˜
return followRepository.findByFromMemberAndToMember(fromMember, toMember)
.map(Follow::getFollowStatus)
.orElse(false);
}


@Override
public List<Member> getFollowings(Member member) {
//Validation: member ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
member = memberRepository.findByToIdWithFollowings(member.getMemberId())
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

//Business Logic: ํŒ”๋กœ์ž‰ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ
List<Follow> followings = followRepository.findByFromMemberAndFollowStatusTrueOrderByUpdatedAt(member);

//Response: ํŒ”๋กœ์ž‰ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜
return followings.stream()
.map(Follow::getToMember)
.collect(Collectors.toList());
}

@Override
public List<Member> getFollowers(Member member) {
//Validation: member ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
member = memberRepository.findByToIdWithFollowers(member.getMemberId())
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

//Business Logic: ํŒ”๋กœ์›Œ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ
List<Follow> followers = followRepository.findByToMemberAndFollowStatusTrueOrderByUpdatedAt(member);

//Response: ํŒ”๋กœ์›Œ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜
return followers.stream()
.map(Follow::getFromMember)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
package com.codiary.backend.global.web.controller;

import com.codiary.backend.global.apiPayload.ApiResponse;
import com.codiary.backend.global.apiPayload.code.ErrorReasonDTO;
import com.codiary.backend.global.converter.MemberConverter;
import com.codiary.backend.global.converter.PostConverter;
import com.codiary.backend.global.domain.entity.*;
import com.codiary.backend.global.domain.entity.mapping.MemberCategory;
import com.codiary.backend.global.domain.enums.TechStack;
import com.codiary.backend.global.service.MemberService.MemberCommandService;
import com.codiary.backend.global.service.MemberService.MemberQueryService;
import com.codiary.backend.global.web.dto.Member.MemberRequestDTO;
import com.codiary.backend.global.web.dto.Member.MemberResponseDTO;
import com.codiary.backend.global.web.dto.Post.PostResponseDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.codiary.backend.global.apiPayload.code.status.SuccessStatus;
import com.codiary.backend.global.service.MemberService.FollowService;
import com.codiary.backend.global.web.dto.Member.FollowResponseDto;
import com.codiary.backend.global.web.dto.Member.MemberSumResponseDto;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -87,12 +85,27 @@ public ApiResponse<String> logout(@RequestHeader("Authorization") String token)
description = "id๋ฅผ ๊ฐ€์ง„ ์œ ์ €์— ๋Œ€ํ•ด ํŒ”๋กœ์šฐํ•˜๊ฑฐ๋‚˜ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."
)
@PostMapping("/follow/{memberId}")
public ApiResponse<FollowResponseDto> follow(@PathVariable("memberId") Long toId) {
Member fromMember = memberCommandService.getRequester();
Follow follow = followService.follow(toId, fromMember);
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "MEMBER_1000", description = "์„ฑ๊ณต์ž…๋‹ˆ๋‹ค.",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "MEMBER_1001", description = "์‚ฌ์šฉ์ž๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorReasonDTO.class ))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "MEMBER_1100", description = "์…€ํ”„ ํŒ”๋กœ์šฐ ๊ธฐ๋Šฅ์€ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorReasonDTO.class ))),
})
public ApiResponse<?> follow(@PathVariable("memberId") Long toId) {
Member member = memberCommandService.getRequester();

// ํŒ”๋กœ์šฐ ์š”์ฒญ ์ฒ˜๋ฆฌ
Follow follow = followService.follow(toId, member);

return ApiResponse.onSuccess(SuccessStatus.MEMBER_OK, MemberConverter.toManageFollowDto(follow));
}


@Operation(
summary = "ํŒ”๋กœ์šฐ ์—ฌ๋ถ€ ์กฐํšŒ ๊ธฐ๋Šฅ",
description = "id๋ฅผ ๊ฐ€์ง„ ์œ ์ €์— ๋Œ€ํ•ด ํŒ”๋กœ์šฐ ํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. true-ํŒ”๋กœ์šฐO / false-ํŒ”๋กœ์šฐX"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.codiary.backend.global.web.dto.Member;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Builder;

@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public record FollowResponseDto(
Long followId,
Long followerId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.codiary.backend.global.domain.enums.TechStack;
import com.codiary.backend.global.jwt.TokenInfo;
import com.codiary.backend.global.web.dto.Team.TeamResponseDTO;
import lombok.*;

import java.time.LocalDateTime;
Expand Down Expand Up @@ -97,7 +98,7 @@ public static class UserProfileDTO {
String discordUrl;
String introduction;
List<TechStack> techStacksList;
List<String> teamList;
List<TeamResponseDTO.TeamPreviewDTO> teamList;
Boolean myPage;
}

Expand Down

0 comments on commit 4e89a63

Please sign in to comment.