diff --git a/src/main/java/com/e2i1/linkeepserver/common/error/ErrorCode.java b/src/main/java/com/e2i1/linkeepserver/common/error/ErrorCode.java index 36bb121..4014fef 100644 --- a/src/main/java/com/e2i1/linkeepserver/common/error/ErrorCode.java +++ b/src/main/java/com/e2i1/linkeepserver/common/error/ErrorCode.java @@ -49,9 +49,11 @@ public enum ErrorCode{ //좋아요 관련 에러 코드 - LIKE_NOT_FOUND(94040,HttpStatus.NOT_FOUND,"사용자가 모음집을 좋아요한 기록이 없습니다.") + LIKE_NOT_FOUND(94040,HttpStatus.NOT_FOUND,"사용자가 모음집을 좋아요한 기록이 없습니다."), + + //친구 관련 에러 코드 + FRINEDS_NOT_FOUND(104040, HttpStatus.NOT_FOUND, "해당 사용자와 친구가 아닙니다."); - ; private final int errorCode; private final HttpStatus httpStatusCode; private final String description; diff --git a/src/main/java/com/e2i1/linkeepserver/domain/collaborators/repository/CollaboratorsRepository.java b/src/main/java/com/e2i1/linkeepserver/domain/collaborators/repository/CollaboratorsRepository.java index 4eddfc3..0c39add 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/collaborators/repository/CollaboratorsRepository.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/collaborators/repository/CollaboratorsRepository.java @@ -20,4 +20,9 @@ public interface CollaboratorsRepository extends JpaRepository> findCollaboratorsByCollection(@Param("collection") CollectionsEntity collection); Optional> findByCollection(CollectionsEntity collection); + + @Query("select count(*) from CollaboratorsEntity where user=:user") + long countCollectionByUser(@Param("user") UsersEntity user); + + long countCollaboratorsEntitiesByUser(UsersEntity user); } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/collaborators/service/CollaboratorsService.java b/src/main/java/com/e2i1/linkeepserver/domain/collaborators/service/CollaboratorsService.java index 58b2d7e..5be899f 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/collaborators/service/CollaboratorsService.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/collaborators/service/CollaboratorsService.java @@ -8,9 +8,11 @@ import com.e2i1.linkeepserver.domain.users.entity.UsersEntity; import java.util.List; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @Service +@Slf4j @RequiredArgsConstructor public class CollaboratorsService { private final CollaboratorsRepository collaboratorsRepository; @@ -32,4 +34,8 @@ public void insert(CollaboratorsEntity collaborator) { public List findByCollection(CollectionsEntity collection) { return collaboratorsRepository.findByCollection(collection).orElseThrow(()->new ApiException(ErrorCode.COLLABORATOR_NOT_FOUND)); } + + public long countCollection(UsersEntity user) { + return collaboratorsRepository.countCollaboratorsEntitiesByUser(user); + } } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/collections/business/CollectionsBusiness.java b/src/main/java/com/e2i1/linkeepserver/domain/collections/business/CollectionsBusiness.java index 3eafc40..07d1141 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/collections/business/CollectionsBusiness.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/collections/business/CollectionsBusiness.java @@ -58,9 +58,8 @@ public CollectionUserResDTO getCollection(Long id, UsersEntity user) { List tagList = tagsService.findByCollection(collection); List tagDTOList = tagList.stream().map(TagsEntity::getTagName) .collect(Collectors.toList()); - CollectionUserResDTO result = collectionsConverter.toCollectionUserResDTO(collection, + return collectionsConverter.toCollectionUserResDTO(collection, linkDTOList, tagDTOList,isLike); - return result; } public List getUserCollection(UsersEntity user){ List collectionList = collaboratorsService.findCollectionByUser(user); diff --git a/src/main/java/com/e2i1/linkeepserver/domain/collections/converter/CollectionsConverter.java b/src/main/java/com/e2i1/linkeepserver/domain/collections/converter/CollectionsConverter.java index d767f13..a136d75 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/collections/converter/CollectionsConverter.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/collections/converter/CollectionsConverter.java @@ -21,7 +21,7 @@ public class CollectionsConverter { public CollectionUserResDTO toCollectionUserResDTO(CollectionsEntity collection, List linkList, List tagsList, boolean isLike){ - CollectionUserResDTO userResDTO = CollectionUserResDTO.builder() + return CollectionUserResDTO.builder() .title(collection.getTitle()) .imgUrl(collection.getImgURL()) .description(collection.getDescription()) @@ -29,7 +29,6 @@ public CollectionUserResDTO toCollectionUserResDTO(CollectionsEntity collection, .tagList(tagsList) .isLike(isLike) .build(); - return userResDTO; } public CollectionTitleResDTO toCollectionTitleResDTO(CollectionsEntity collection){ diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/business/FriendsBusiness.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/business/FriendsBusiness.java index 5ac10f8..b7afb48 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/friends/business/FriendsBusiness.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/business/FriendsBusiness.java @@ -1,13 +1,65 @@ package com.e2i1.linkeepserver.domain.friends.business; import com.e2i1.linkeepserver.common.annotation.Business; +import com.e2i1.linkeepserver.domain.collaborators.service.CollaboratorsService; import com.e2i1.linkeepserver.domain.friends.converter.FriendsConverter; +import com.e2i1.linkeepserver.domain.friends.dto.FriendStatusResDTO; +import com.e2i1.linkeepserver.domain.friends.dto.FriendsResDTO; +import com.e2i1.linkeepserver.domain.friends.entity.FriendsEntity; import com.e2i1.linkeepserver.domain.friends.service.FriendsService; +import com.e2i1.linkeepserver.domain.users.entity.UsersEntity; +import com.e2i1.linkeepserver.domain.users.service.UsersService; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +import io.jsonwebtoken.lang.Collections; import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; @Business @RequiredArgsConstructor public class FriendsBusiness { private final FriendsService friendsService; + private final UsersService usersService; + private final CollaboratorsService collaboratorsService; private final FriendsConverter friendsConverter; + + + public List getFollowers(UsersEntity user) { + List FriendsList = friendsService.getFollowers(user); + return FriendsList.stream().map(friend -> { + long cnt = collaboratorsService.countCollection(friend.getFollowingUser()); + return friendsConverter.toFriendsResDTO(friend.getFollowingUser(), cnt); + }).toList(); + + } + + public List getFollowings(UsersEntity user) { + List FriendsList = friendsService.getFollowings(user); + for(FriendsEntity f : FriendsList) + System.out.println(f.getId()); + return FriendsList.stream().map(friend -> { + long cnt = collaboratorsService.countCollection(friend.getFollowedUser()); + System.out.println(friend.getFollowedUser()+" : "+cnt); + + return friendsConverter.toFriendsResDTO(friend.getFollowedUser(), cnt); + }).toList(); + + } + + public void insertFollow(String nickName, UsersEntity followingUser) { + UsersEntity followedUser = usersService.findByNickName(nickName); + FriendsEntity friend = friendsConverter.toFriendsEntity(followedUser,followingUser); + friendsService.insertFriend(friend); + } + + @Transactional + public FriendStatusResDTO changeStatus(long userId, UsersEntity follower ) { + UsersEntity followee = usersService.findById(userId); + FriendsEntity friend = friendsService.findByFollowedUserAndFollowingUser(followee,follower); + friend.updateStatus(); + return friendsConverter.toFriendStatusResDTO(friend.getIsFollowing()); + } } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/controller/FriendsController.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/controller/FriendsController.java index c8691d7..0bb22c7 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/friends/controller/FriendsController.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/controller/FriendsController.java @@ -1,7 +1,13 @@ package com.e2i1.linkeepserver.domain.friends.controller; +import com.e2i1.linkeepserver.common.annotation.UserSession; import com.e2i1.linkeepserver.domain.friends.business.FriendsBusiness; +import com.e2i1.linkeepserver.domain.friends.dto.FriendReqDTO; +import com.e2i1.linkeepserver.domain.friends.dto.FriendStatusReqDTO; +import com.e2i1.linkeepserver.domain.friends.dto.FriendStatusResDTO; import com.e2i1.linkeepserver.domain.friends.dto.FriendsResDTO; +import com.e2i1.linkeepserver.domain.users.entity.UsersEntity; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -14,21 +20,26 @@ public class FriendsController { private final FriendsBusiness friendsBusiness; - @GetMapping() - public ResponseEntity getFriends(){ - return ResponseEntity.ok(null); + @GetMapping("/follower") + public ResponseEntity> getFollowers(@UserSession UsersEntity user){ + return ResponseEntity.ok(friendsBusiness.getFollowers(user)); + } + + @GetMapping("/following") + public ResponseEntity> getFollowings(@UserSession UsersEntity user){ + return ResponseEntity.ok(friendsBusiness.getFollowings(user)); } @PostMapping() - public ResponseEntity insertFriend(@RequestBody String nickName){ + public ResponseEntity insertFriend(@RequestBody FriendReqDTO friendReqDTO, @UserSession UsersEntity user){ + friendsBusiness.insertFollow(friendReqDTO.getNickname(), user); return ResponseEntity.ok("success"); } @PostMapping("/follow") - public ResponseEntity> isFollow(@RequestBody Long userId){ - HashMap result = new HashMap<>(); - result.put("isFollowing","Y"); - return ResponseEntity.ok(result); + public ResponseEntity isFollow(@RequestBody FriendStatusReqDTO reqDTO, @UserSession UsersEntity user){ + + return ResponseEntity.ok(friendsBusiness.changeStatus(reqDTO.getUserId(),user)); } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/converter/FriendsConverter.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/converter/FriendsConverter.java index 0d0fa62..0a3457b 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/friends/converter/FriendsConverter.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/converter/FriendsConverter.java @@ -1,9 +1,27 @@ package com.e2i1.linkeepserver.domain.friends.converter; import com.e2i1.linkeepserver.common.annotation.Converter; +import com.e2i1.linkeepserver.domain.friends.dto.FriendStatusResDTO; +import com.e2i1.linkeepserver.domain.friends.dto.FriendsResDTO; +import com.e2i1.linkeepserver.domain.friends.entity.FriendsEntity; +import com.e2i1.linkeepserver.domain.users.entity.UsersEntity; import lombok.RequiredArgsConstructor; @Converter @RequiredArgsConstructor public class FriendsConverter { + + public FriendsEntity toFriendsEntity(UsersEntity followedUser, UsersEntity followingUser) { + return FriendsEntity.builder() + .followedUser(followedUser) + .followingUser(followingUser) + .isFollowing(true).build(); + } + + public FriendsResDTO toFriendsResDTO(UsersEntity user, long cnt) { + return FriendsResDTO.builder().nickName(user.getNickname()).userId(user.getId()).numOfCollections(cnt).build(); + } + public FriendStatusResDTO toFriendStatusResDTO(boolean followStatus){ + return FriendStatusResDTO.builder().followStatus(followStatus).build(); + } } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendReqDTO.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendReqDTO.java new file mode 100644 index 0000000..018f4aa --- /dev/null +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendReqDTO.java @@ -0,0 +1,14 @@ +package com.e2i1.linkeepserver.domain.friends.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FriendReqDTO { + private String nickname; +} diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendStatusReqDTO.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendStatusReqDTO.java new file mode 100644 index 0000000..77dcc7b --- /dev/null +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendStatusReqDTO.java @@ -0,0 +1,14 @@ +package com.e2i1.linkeepserver.domain.friends.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FriendStatusReqDTO { + private long userId; +} diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendStatusResDTO.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendStatusResDTO.java new file mode 100644 index 0000000..8dcccc9 --- /dev/null +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendStatusResDTO.java @@ -0,0 +1,14 @@ +package com.e2i1.linkeepserver.domain.friends.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FriendStatusResDTO { + private boolean followStatus; +} diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendsResDTO.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendsResDTO.java index d59030f..44518f4 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendsResDTO.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/dto/FriendsResDTO.java @@ -11,5 +11,6 @@ @AllArgsConstructor public class FriendsResDTO { private String nickName; + private Long userId; private Long numOfCollections; } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/entity/FriendsEntity.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/entity/FriendsEntity.java index df8f5bf..1b3de9f 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/friends/entity/FriendsEntity.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/entity/FriendsEntity.java @@ -39,4 +39,7 @@ public void setFollowingUser(UsersEntity usersEntity) { public void setFollowedUser(UsersEntity usersEntity) { followedUser = usersEntity; } + public void updateStatus(){ + this.isFollowing = !this.isFollowing; + } } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/repository/FriendsRepository.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/repository/FriendsRepository.java index be02ab1..096f941 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/friends/repository/FriendsRepository.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/repository/FriendsRepository.java @@ -1,7 +1,15 @@ package com.e2i1.linkeepserver.domain.friends.repository; import com.e2i1.linkeepserver.domain.friends.entity.FriendsEntity; +import com.e2i1.linkeepserver.domain.users.entity.UsersEntity; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.Repository; -public interface FriendsRepository extends Repository { +public interface FriendsRepository extends JpaRepository { + public List findByFollowedUserAndIsFollowing(UsersEntity user,boolean isFollow); + public List findByFollowingUserAndIsFollowing(UsersEntity user,boolean isFollow); + Optional findByFollowedUserAndFollowingUser(UsersEntity followee, UsersEntity follower); + } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/friends/service/FriendsService.java b/src/main/java/com/e2i1/linkeepserver/domain/friends/service/FriendsService.java index c6d5929..8ef0f79 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/friends/service/FriendsService.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/friends/service/FriendsService.java @@ -1,11 +1,33 @@ package com.e2i1.linkeepserver.domain.friends.service; +import com.e2i1.linkeepserver.common.error.ErrorCode; +import com.e2i1.linkeepserver.common.exception.ApiException; +import com.e2i1.linkeepserver.domain.friends.entity.FriendsEntity; import com.e2i1.linkeepserver.domain.friends.repository.FriendsRepository; +import com.e2i1.linkeepserver.domain.users.entity.UsersEntity; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class FriendsService { - private FriendsRepository friendsRepository; + private final FriendsRepository friendsRepository; + + public List getFollowers(UsersEntity user) { + return friendsRepository.findByFollowedUserAndIsFollowing(user,true); + } + + public List getFollowings(UsersEntity user) { + return friendsRepository.findByFollowingUserAndIsFollowing(user,true); + } + public FriendsEntity insertFriend(FriendsEntity friend) { + return friendsRepository.save(friend); + } + + public FriendsEntity findByFollowedUserAndFollowingUser(UsersEntity followee, UsersEntity follower) { + return friendsRepository.findByFollowedUserAndFollowingUser(followee,follower).orElseThrow(() -> new ApiException(ErrorCode.FRINEDS_NOT_FOUND)); + } + + } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/users/entity/UsersEntity.java b/src/main/java/com/e2i1/linkeepserver/domain/users/entity/UsersEntity.java index 41eeb19..9b78974 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/users/entity/UsersEntity.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/users/entity/UsersEntity.java @@ -33,10 +33,10 @@ public class UsersEntity extends DateEntity { private List likeOthersList; @OneToMany(mappedBy = "followingUser", cascade = ALL) - private Set followingList; // 내가 팔로우한 유저 리스트 + private List followingList; // 내가 팔로우한 유저 리스트 @OneToMany(mappedBy = "followedUser", cascade = ALL) - private Set followerList; // 나를 팔로우한 유저 리스트 + private List followerList; // 나를 팔로우한 유저 리스트 @OneToMany(mappedBy = "user", cascade = ALL) private List linkList; diff --git a/src/main/java/com/e2i1/linkeepserver/domain/users/repository/UsersRepository.java b/src/main/java/com/e2i1/linkeepserver/domain/users/repository/UsersRepository.java index 351cc4f..52756db 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/users/repository/UsersRepository.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/users/repository/UsersRepository.java @@ -17,5 +17,5 @@ public interface UsersRepository extends JpaRepository { Optional findByNicknameAndStatus(String nickname, UserStatus status); List findByNicknameContainingAndStatus(String search, UserStatus status); - + UsersEntity findByNickname(String nickName); } diff --git a/src/main/java/com/e2i1/linkeepserver/domain/users/service/UsersService.java b/src/main/java/com/e2i1/linkeepserver/domain/users/service/UsersService.java index 1617229..131ab84 100644 --- a/src/main/java/com/e2i1/linkeepserver/domain/users/service/UsersService.java +++ b/src/main/java/com/e2i1/linkeepserver/domain/users/service/UsersService.java @@ -62,4 +62,7 @@ public void editProfile(String imgUrl, EditProfileReqDTO editProfile, UsersEntit // user는 UserSessionResolver에서 getUserWithThrow로 가져온 user 객체임 -> 즉, 영속성 컨텍스트 안에 있음 -> dirty checking 가능 } + public UsersEntity findByNickName(String nickName) { + return usersRepository.findByNickname(nickName); + } } diff --git a/src/test/java/com/e2i1/linkeepserver/CollectionTests.java b/src/test/java/com/e2i1/linkeepserver/CollectionTests.java index 21adc8d..2b78320 100644 --- a/src/test/java/com/e2i1/linkeepserver/CollectionTests.java +++ b/src/test/java/com/e2i1/linkeepserver/CollectionTests.java @@ -3,6 +3,10 @@ import com.e2i1.linkeepserver.domain.collections.business.CollectionsBusiness; import com.e2i1.linkeepserver.domain.collections.dto.CollectionResDTO; import com.e2i1.linkeepserver.domain.collections.dto.CollectionUserResDTO; +import com.e2i1.linkeepserver.domain.friends.entity.FriendsEntity; +import com.e2i1.linkeepserver.domain.users.business.UsersBusiness; +import com.e2i1.linkeepserver.domain.users.entity.UsersEntity; +import com.e2i1.linkeepserver.domain.users.service.UsersService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -15,9 +19,17 @@ public class CollectionTests { @Autowired - private CollectionsBusiness collectionsBusiness; - + private UsersBusiness usersBusiness; + @Autowired + private UsersService usersService; + + @Test + public void 팔로잉_목록(){ + UsersEntity user= usersService.findById(2L); + for(FriendsEntity f : user.getFollowerList()) + System.out.println("id : "+f.getId()); + }