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

✨ feat: 팔로우 기능 api 추가(#168) #169

Merged
merged 2 commits into from
Mar 25, 2024
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 @@ -67,6 +67,13 @@ public enum ErrorStatus implements BaseErrorCode {
JWT_UNSUPPORTED_TOKEN(HttpStatus.UNAUTHORIZED, "JWT4004","지원하지 않는 JWT 토큰입니다."),
JWT_TOKEN_NOT_FOUND(HttpStatus.UNAUTHORIZED, "JWT4005","유효한 JWT 토큰이 없습니다."),

//POST

POST_SELF_FOLLOW(HttpStatus.BAD_REQUEST, "POST4001", "자신을 팔로우 했습니다."),
POST_ALREADY_FOLLOW(HttpStatus.BAD_REQUEST, "POST4002", "이미 팔로우 했습니다."),
POST_FOLLOW_NOT_FOUND(HttpStatus.BAD_REQUEST, "POST4003", "해당 팔로우를 찾을수 없습니다."),


//Category
CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "CATEGORY4001", "해당 카테고리가 존재하지 않습니다"),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ public enum SuccessStatus implements BaseCode {
MEMBER_CUSTOM_INFO_UPDATE(HttpStatus.OK, "MEMBER2006", "회원 맞춤 정보 변경 성공입니다."),
MEMBER_DECLARE_SUCCESS(HttpStatus.OK, "MEMBER2007", "신고 등록 성공했습니다."),
MEMBER_DECLARE_DELETE(HttpStatus.OK, "MEMBER2008", "신고 삭제 성공했습니다."),
MEMBER_CONTACT_SUCCESS(HttpStatus.OK, "MEMBER2009", "연락가능 시간 변경 성공입니다.")
MEMBER_CONTACT_SUCCESS(HttpStatus.OK, "MEMBER2009", "연락가능 시간 변경 성공입니다."),

//POST
POST_FOLLOW_SUCCESS(HttpStatus.OK, "POST2001", "팔로우 성공입니다."),
POST_DELETE_FOLLOW_SUCCESS(HttpStatus.OK, "POST2002", "팔로우 취소 성공입니다.")
;

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.umc.TheGoods.apiPayload.exception.handler;

import com.umc.TheGoods.apiPayload.code.status.ErrorStatus;
import com.umc.TheGoods.apiPayload.exception.GeneralException;

public class PostHandler extends GeneralException {

public PostHandler(ErrorStatus errorCode){ super(errorCode);}
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ public static ProfileImg toProfileImg(String url, Member member) {
.build();
}

public static MemberResponseDTO.ProfileResultDTO toProfile(Member member, String url, List<Account> account, List<Address> address) {
public static MemberResponseDTO.ProfileResultDTO toProfile(Member member, String url, List<Account> account,
List<Address> address, Long following, Long dibs) {

List<MemberResponseDTO.AccountDTO> accountList = account.stream().map(a -> MemberResponseDTO.AccountDTO.builder()
.id(a.getId())
Expand All @@ -261,6 +262,8 @@ public static MemberResponseDTO.ProfileResultDTO toProfile(Member member, String
.url(url)
.accountList(null)
.addressList(null)
.following(following)
.dibs(dibs)
.build();
}
if (account.isEmpty()){
Expand All @@ -270,6 +273,8 @@ public static MemberResponseDTO.ProfileResultDTO toProfile(Member member, String
.url(url)
.addressList(addressList)
.accountList(accountList)
.following(following)
.dibs(dibs)
.build();
}
if(address.isEmpty()){
Expand All @@ -279,6 +284,8 @@ public static MemberResponseDTO.ProfileResultDTO toProfile(Member member, String
.url(url)
.addressList(null)
.accountList(accountList)
.following(following)
.dibs(dibs)
.build();
}

Expand All @@ -288,6 +295,8 @@ public static MemberResponseDTO.ProfileResultDTO toProfile(Member member, String
.url(url)
.addressList(addressList)
.accountList(accountList)
.following(following)
.dibs(dibs)
.build();
}

Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/umc/TheGoods/converter/post/PostConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.umc.TheGoods.converter.post;

import com.umc.TheGoods.domain.member.Follow;
import com.umc.TheGoods.domain.member.Member;

public class PostConverter {
public static Follow toFollow(Member follower, Member following){

return Follow.builder()
.follower(follower)
.following(following)
.build();
}
}
13 changes: 7 additions & 6 deletions src/main/java/com/umc/TheGoods/domain/member/Follow.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.umc.TheGoods.domain.member;

import com.umc.TheGoods.domain.common.BaseDateTimeEntity;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

import javax.persistence.*;

@Entity
@Table(name = "follow")
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 생성 로직 규정
public class Follow extends BaseDateTimeEntity {

Expand All @@ -18,11 +18,12 @@ public class Follow extends BaseDateTimeEntity {
@Column(name = "follow_id")
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "follower_id")
private Member follower;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "following_id")
private Member following;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "follower_id")
private Member follower;
}
4 changes: 2 additions & 2 deletions src/main/java/com/umc/TheGoods/domain/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ public class Member extends BaseDateTimeEntity {
private List<PostLike> postLikeList = new ArrayList<>();

// Follow 양방향 매핑(mappedBy = "member"로 변경 할 수도 있음)
@OneToMany(mappedBy = "following", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "follower", cascade = CascadeType.ALL)
private List<Follow> followingList = new ArrayList<>();

@OneToMany(mappedBy = "follower", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "following", cascade = CascadeType.ALL)
private List<Follow> followerList = new ArrayList<>();

// Notice 양방향 매핑
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.umc.TheGoods.repository.post;

import com.umc.TheGoods.domain.member.Follow;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface FollowRepository extends JpaRepository<Follow, Long> {

Optional<Follow> findByFollowingIdAndFollowerId(Long followingId, Long followerId);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package com.umc.TheGoods.service.PostService;

import com.umc.TheGoods.domain.member.Member;

public interface PostCommandService {

void follow(Long followingId, Member follower);

void deleteFollow(Long followingId, Long followerId);

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
package com.umc.TheGoods.service.PostService;

import com.umc.TheGoods.apiPayload.code.status.ErrorStatus;
import com.umc.TheGoods.apiPayload.exception.handler.MemberHandler;
import com.umc.TheGoods.apiPayload.exception.handler.PostHandler;
import com.umc.TheGoods.converter.post.PostConverter;
import com.umc.TheGoods.domain.member.Follow;
import com.umc.TheGoods.domain.member.Member;
import com.umc.TheGoods.repository.member.MemberRepository;
import com.umc.TheGoods.repository.post.FollowRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class PostCommandServiceImpl implements PostCommandService {

private final FollowRepository followRepository;
private final MemberRepository memberRepository;

@Override
public void follow(Long followingId, Member follower) {

if(followingId.equals(follower.getId())){
throw new PostHandler(ErrorStatus.POST_SELF_FOLLOW);
}
Optional<Follow> check = followRepository.findByFollowingIdAndFollowerId(followingId,follower.getId());
if(!check.isEmpty()){
throw new PostHandler(ErrorStatus.POST_ALREADY_FOLLOW);
}

Member following = memberRepository.findById(followingId).orElseThrow(()->new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
Follow follow = PostConverter.toFollow(follower,following);
followRepository.save(follow);
}

@Override
public void deleteFollow(Long followingId, Long followerId) {

Follow follow = followRepository.findByFollowingIdAndFollowerId(followingId,followerId).orElseThrow(() -> new PostHandler(ErrorStatus.POST_FOLLOW_NOT_FOUND));

followRepository.delete(follow);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,28 +233,6 @@ public ApiResponse<?> naverCallback(@RequestParam String code, String state) {
}


@GetMapping(value = "/profile")
@Operation(summary = "프로필 조회 api", description = "프로필이미지, 닉네임을 조회할 수 있습니다.")
public ApiResponse<MemberResponseDTO.ProfileResultDTO> getProfile(Authentication authentication) {



Member member = memberQueryService.findMemberById(Long.valueOf(authentication.getName().toString())).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
Optional<ProfileImg> profileImg = memberQueryService.findProfileImgByMember(member.getId());
List<Address> address = memberQueryService.findAllAddressById(member.getId());
List<Account> account = memberQueryService.findAllAccountById(member.getId());



if(profileImg.isEmpty()){
return ApiResponse.onSuccess(MemberConverter.toProfile(member, null, account, address));
}
else {
return ApiResponse.onSuccess(MemberConverter.toProfile(member, profileImg.get().getUrl(),account, address));
}


}



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.umc.TheGoods.apiPayload.exception.handler.MemberHandler;
import com.umc.TheGoods.converter.member.MemberConverter;
import com.umc.TheGoods.domain.enums.OrderStatus;
import com.umc.TheGoods.domain.images.ProfileImg;
import com.umc.TheGoods.domain.item.Category;
import com.umc.TheGoods.domain.item.Tag;
import com.umc.TheGoods.domain.member.Auth;
Expand Down Expand Up @@ -292,6 +293,30 @@ public ApiResponse<?> postContact(Authentication authentication,
return ApiResponse.of(SuccessStatus.MEMBER_CONTACT_SUCCESS,null);
}

@GetMapping(value = "/profile")
@Operation(summary = "프로필 조회 api", description = "프로필이미지, 닉네임, 주소, 계좌, 팔로잉 수, 찜 수를 조회할 수 있습니다.")
public ApiResponse<MemberResponseDTO.ProfileResultDTO> getProfile(Authentication authentication) {



Member member = memberQueryService.findMemberById(Long.valueOf(authentication.getName().toString())).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
Optional<ProfileImg> profileImg = memberQueryService.findProfileImgByMember(member.getId());
List<Address> address = memberQueryService.findAllAddressById(member.getId());
List<Account> account = memberQueryService.findAllAccountById(member.getId());
Long following = Long.valueOf(member.getFollowingList().size());
Long dibs = Long.valueOf(member.getDibsList().size());



if(profileImg.isEmpty()){
return ApiResponse.onSuccess(MemberConverter.toProfile(member, null, account, address,following,dibs));
}
else {
return ApiResponse.onSuccess(MemberConverter.toProfile(member, profileImg.get().getUrl(),account, address,following,dibs));
}


}
/**
* 주문 상세 내역
* 입금처, 입금 은행, 상품 사진, 상품 이름, 상품 옵션, 주문 상태(결제 전, 결제 완료), 주문자명, 주문자 연락처, 주문 번호, 상품 주문 개수, 상품가격
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/com/umc/TheGoods/web/controller/PostController.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package com.umc.TheGoods.web.controller;

import com.umc.TheGoods.apiPayload.ApiResponse;
import com.umc.TheGoods.apiPayload.code.status.ErrorStatus;
import com.umc.TheGoods.apiPayload.code.status.SuccessStatus;
import com.umc.TheGoods.apiPayload.exception.handler.MemberHandler;
import com.umc.TheGoods.domain.member.Auth;
import com.umc.TheGoods.domain.member.Member;
import com.umc.TheGoods.service.MemberService.MemberQueryService;
import com.umc.TheGoods.service.PostService.PostCommandService;
import com.umc.TheGoods.service.PostService.PostQueryService;
import com.umc.TheGoods.web.dto.post.PostResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

@RestController
Expand All @@ -16,6 +24,8 @@
public class PostController {

final PostQueryService queryService;
private final MemberQueryService memberQueryService;
final PostCommandService postCommandService;

@GetMapping("/")
@Operation(summary = "인기 사장님 피드 전체 조회 API", description = "포스트의 기본 디폴트 정렬로, 좋아요 순으로 내림차순 정렬합니다. \n\n")
Expand All @@ -28,10 +38,34 @@ public ApiResponse<PostResponseDto.PostListViewDto> posts(@RequestParam("like")
}

@GetMapping("/follow")
@Operation(summary = "팔로잉 중인 피드 전체 조회 API")
public ApiResponse<PostResponseDto.PostListViewDto> following(@RequestParam("like") boolean like) {
return null;
}

@PostMapping("/follow/{followingId}")
@Operation(summary = "팔로우 API", description = "팔로우 하려는 사람의 id를 request로 주시면 됩니다.")
public ApiResponse<?> follow(Authentication authentication,
@RequestParam(name = "followingId") Long followingId){

Member member = memberQueryService.findMemberById(Long.valueOf(authentication.getName().toString())).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
//팔로우 기능
postCommandService.follow(followingId, member);

return ApiResponse.of(SuccessStatus.POST_FOLLOW_SUCCESS, null);
}

@PostMapping("/follow/delete/{followingId}")
@Operation(summary = "팔로우 취소 API", description = "팔로우 취소하려는 사람의 id를 request로 주시면 됩니다.")
public ApiResponse<?> deleteFollow(Authentication authentication,
@RequestParam(name = "followingId") Long followingId){

Long memberId = Long.valueOf(authentication.getName().toString());
//팔로우 취소 기능
postCommandService.deleteFollow(followingId,memberId);
return ApiResponse.of(SuccessStatus.POST_DELETE_FOLLOW_SUCCESS,null);
}

@GetMapping("/{postId}")
public ApiResponse<PostResponseDto.PostViewDto> post(@PathVariable Long postId) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ public static class ProfileResultDTO {
String phone;
List<MemberResponseDTO.AddressDTO> addressList;
List<MemberResponseDTO.AccountDTO> accountList;
Long following;
Long dibs;

}

Expand Down
Loading