From 8437a3b2dfe183ba2f211b01e3d457cd0ab60203 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 18 May 2024 00:22:36 +0900 Subject: [PATCH 01/16] =?UTF-8?q?[Feat]=20UserGifticon=20BaseTimeEntity=20?= =?UTF-8?q?=EC=83=81=EC=86=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haedal/gifticionfunding/entity/gifticon/UserGifticon.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/team/haedal/gifticionfunding/entity/gifticon/UserGifticon.java b/src/main/java/team/haedal/gifticionfunding/entity/gifticon/UserGifticon.java index 39384b9..392741d 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/gifticon/UserGifticon.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/gifticon/UserGifticon.java @@ -13,13 +13,14 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import team.haedal.gifticionfunding.entity.common.BaseTimeEntity; import team.haedal.gifticionfunding.entity.gifticon.Gifticon; import team.haedal.gifticionfunding.entity.user.User; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity -public class UserGifticon { +public class UserGifticon extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; From 3dc1b239a18fe611c5fd6fde9792c509f3574cd3 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 18 May 2024 00:22:50 +0900 Subject: [PATCH 02/16] =?UTF-8?q?[Feat]=20StoreBrand=20Enum=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haedal/gifticionfunding/entity/gifticon/StoreBrand.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/team/haedal/gifticionfunding/entity/gifticon/StoreBrand.java b/src/main/java/team/haedal/gifticionfunding/entity/gifticon/StoreBrand.java index fd4f302..237617e 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/gifticon/StoreBrand.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/gifticon/StoreBrand.java @@ -11,5 +11,8 @@ public enum StoreBrand { STARBUCKS, TWO_SOME_PLACE, EDIYA, HOLLYS, TOM_N_TOMS, COFFEE_BEAN, PARIS_BAGUETTE, BASKIN_ROBBINS, DUNKIN, //Chicken - BBQ, BHC, GOOBNE, KYOCHON, NENE, PELicana, MOMS_TOUCH + BBQ, BHC, GOOBNE, KYOCHON, NENE, + + //Clothes + ZARA, UNIQLO } From bf4ab5d238a70e234a4d1bb44251c60059f24b75 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 18 May 2024 00:25:29 +0900 Subject: [PATCH 03/16] =?UTF-8?q?[Refactor]=20Entity=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0=20(Friendship)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/user/Friendship.java | 14 ++++---- .../entity/user/FriendshipProposal.java | 36 ------------------- .../user/FriendshipProposalRepository.java | 7 ---- 3 files changed, 7 insertions(+), 50 deletions(-) delete mode 100644 src/main/java/team/haedal/gifticionfunding/entity/user/FriendshipProposal.java delete mode 100644 src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipProposalRepository.java diff --git a/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java b/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java index 7015445..19ce4b9 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java @@ -20,16 +20,16 @@ public class Friendship { private Long id; @ManyToOne - @JoinColumn(name = "user1_id") - private User user1; + @JoinColumn(name = "from_user_id") + private User fromUser; @ManyToOne - @JoinColumn(name = "user2_id") - private User user2; + @JoinColumn(name = "to_user_id") + private User toUser; @Builder - private Friendship(User user1, User user2) { - this.user1 = user1; - this.user2 = user2; + private Friendship(User fromUser, User toUser) { + this.fromUser = fromUser; + this.toUser = toUser; } } diff --git a/src/main/java/team/haedal/gifticionfunding/entity/user/FriendshipProposal.java b/src/main/java/team/haedal/gifticionfunding/entity/user/FriendshipProposal.java deleted file mode 100644 index 603b948..0000000 --- a/src/main/java/team/haedal/gifticionfunding/entity/user/FriendshipProposal.java +++ /dev/null @@ -1,36 +0,0 @@ -package team.haedal.gifticionfunding.entity.user; - -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import team.haedal.gifticionfunding.entity.common.BaseTimeEntity; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -public class FriendshipProposal extends BaseTimeEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - @JoinColumn(name = "from_user_id") - private User fromUser; - - @ManyToOne - @JoinColumn(name = "to_user_id") - private User toUser; - - @Builder - private FriendshipProposal(User fromUser, User toUser) { - this.fromUser = fromUser; - this.toUser = toUser; - } -} diff --git a/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipProposalRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipProposalRepository.java deleted file mode 100644 index c4f36e3..0000000 --- a/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipProposalRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package team.haedal.gifticionfunding.repository.user; - -import org.springframework.data.jpa.repository.JpaRepository; -import team.haedal.gifticionfunding.entity.user.FriendshipProposal; - -public interface FriendshipProposalRepository extends JpaRepository { -} From b7ca735300886a1b76a7a426dc47cde2a0cb75d2 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 18 May 2024 09:39:59 +0900 Subject: [PATCH 04/16] =?UTF-8?q?[Feat]=20=EC=B9=9C=EA=B5=AC=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20(=EC=B9=9C=EA=B5=AC=EC=9D=98?= =?UTF-8?q?=20=EC=B9=9C=EA=B5=AC=EA=B9=8C=EC=A7=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FriendshipController.java | 36 +++++++++++++ .../haedal/gifticionfunding/dto/UserDto.java | 24 +++++++++ .../entity/user/Friendship.java | 3 +- .../repository/user/FriendshipRepository.java | 19 +++++++ .../service/FriendshipService.java | 51 +++++++++++++++++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/main/java/team/haedal/gifticionfunding/controller/FriendshipController.java create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/UserDto.java create mode 100644 src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FriendshipController.java b/src/main/java/team/haedal/gifticionfunding/controller/FriendshipController.java new file mode 100644 index 0000000..1ca3579 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/controller/FriendshipController.java @@ -0,0 +1,36 @@ +package team.haedal.gifticionfunding.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import team.haedal.gifticionfunding.annotation.UserId; +import team.haedal.gifticionfunding.dto.UserDto; +import team.haedal.gifticionfunding.dto.common.PagingResponse; +import team.haedal.gifticionfunding.dto.common.ResponseDto; +import team.haedal.gifticionfunding.service.FriendshipService; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class FriendshipController { + private final FriendshipService friendshipService; + + @GetMapping("/v1/profile/friends") + public ResponseEntity getFriends( + @UserId Long userId, + @RequestParam(value = "depth", defaultValue = "1") Integer depth, + @RequestParam(value = "page", defaultValue = "0") Integer page, + @RequestParam(value = "size", defaultValue = "10") Integer size + ) { + PagingResponse userDtoPage = friendshipService.getFriends(userId, depth, page, size); + return new ResponseEntity<>( + new ResponseDto<>(1, "친구 목록 조회 성공", userDtoPage), + HttpStatus.OK + ); + } + +} diff --git a/src/main/java/team/haedal/gifticionfunding/dto/UserDto.java b/src/main/java/team/haedal/gifticionfunding/dto/UserDto.java new file mode 100644 index 0000000..f7a9451 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/UserDto.java @@ -0,0 +1,24 @@ +package team.haedal.gifticionfunding.dto; + +import java.time.format.DateTimeFormatter; +import lombok.Builder; +import team.haedal.gifticionfunding.entity.user.User; + +@Builder +public record UserDto ( + Long id, + String name, + String birthdate, + String profileImageUrl +){ + public static UserDto fromEntity(User user) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + return UserDto.builder() + .id(user.getId()) + .birthdate(user.getBirthdate().format(formatter)) + .profileImageUrl(user.getProfileImageUrl()) + .name(user.getNickname()) + .build(); + } +} diff --git a/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java b/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java index 19ce4b9..326342b 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/user/Friendship.java @@ -10,11 +10,12 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import team.haedal.gifticionfunding.entity.common.BaseTimeEntity; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity -public class Friendship { +public class Friendship extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java index d600a4b..67a1395 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java @@ -1,7 +1,26 @@ package team.haedal.gifticionfunding.repository.user; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import team.haedal.gifticionfunding.entity.user.Friendship; +import team.haedal.gifticionfunding.entity.user.User; public interface FriendshipRepository extends JpaRepository { + @Query("SELECT f.toUser FROM Friendship f WHERE f.fromUser.id = :userId") + Page findFriendsByUserId(@Param("userId") Long userId, Pageable pageable); + + @Query("SELECT DISTINCT u FROM User u " + + "WHERE u.id IN (" + + " SELECT f.toUser.id FROM Friendship f WHERE f.fromUser.id = :userId " + // cl + " OR f.toUser.id IN (" + + " SELECT f2.toUser.id FROM Friendship f1 JOIN Friendship f2 ON f1.toUser.id = f2.fromUser.id WHERE f1.fromUser.id = :userId" + + " )" + + ")") + Page findFriendsAndFriendsOfFriends( + @Param("userId") Long userId, + Pageable pageable + ); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java b/src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java new file mode 100644 index 0000000..2cf38a0 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java @@ -0,0 +1,51 @@ +package team.haedal.gifticionfunding.service; + + +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import team.haedal.gifticionfunding.dto.UserDto; +import team.haedal.gifticionfunding.dto.common.PagingResponse; +import team.haedal.gifticionfunding.entity.user.User; +import team.haedal.gifticionfunding.handler.ex.CustomApiException; +import team.haedal.gifticionfunding.repository.user.FriendshipRepository; + +@Service +@RequiredArgsConstructor +public class FriendshipService { + private final FriendshipRepository friendshipRepository; + + public PagingResponse getFriends(Long userId, Integer depth, Integer page, Integer size) { + if (page < 0 || size <= 0) { + throw new CustomApiException("page는 0이상, size는 1이상이어야 합니다."); + } + + Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending()); + + // 친구 목록 조회 + if (depth == 1) { + Page frinedPage = friendshipRepository.findFriendsByUserId(userId, pageable); + return PagingResponse.builder() + .hasNext(frinedPage.hasNext()) + .data(frinedPage.getContent().stream() + .map(UserDto::fromEntity) + .toList()) + .build(); + } + + // 친구의 친구까지 목록 조회 + if (depth == 2) { + Page friendPage = friendshipRepository.findFriendsAndFriendsOfFriends(userId, pageable); + return PagingResponse.builder() + .hasNext(friendPage.hasNext()) + .data(friendPage.getContent().stream() + .map(UserDto::fromEntity) + .toList()) + .build(); + } + throw new CustomApiException("depth는 1또는 2만 가능합니다."); + } +} From dd155fb27802304be985fd504a83e5c3a03ae0d9 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 18 May 2024 18:28:39 +0900 Subject: [PATCH 05/16] =?UTF-8?q?[Fix]=20=EC=B9=9C=EA=B5=AC=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=EA=B8=B0=EC=A4=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team/haedal/gifticionfunding/service/FriendshipService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java b/src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java index 2cf38a0..9877462 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FriendshipService.java @@ -23,7 +23,7 @@ public PagingResponse getFriends(Long userId, Integer depth, Integer pa throw new CustomApiException("page는 0이상, size는 1이상이어야 합니다."); } - Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending()); + Pageable pageable = PageRequest.of(page, size, Sort.by("nickname").ascending()); // 친구 목록 조회 if (depth == 1) { From c438b3f5bea8de18b05fcb5b4dc109bdc92903f9 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Fri, 24 May 2024 00:36:58 +0900 Subject: [PATCH 06/16] =?UTF-8?q?[Feat]=2010-5.=20=ED=8E=80=EB=94=A9=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FundingArticleController.java | 35 +++++++++++++++ .../dto/FundingArticleDto.java | 29 ++++++++++++ .../entity/funding/FundingArticle.java | 3 +- .../funding/FundingArticleRepository.java | 19 ++++++++ .../service/FundingArticleService.java | 44 +++++++++++++++++++ 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDto.java create mode 100644 src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java new file mode 100644 index 0000000..d880286 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java @@ -0,0 +1,35 @@ +package team.haedal.gifticionfunding.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import team.haedal.gifticionfunding.annotation.UserId; +import team.haedal.gifticionfunding.dto.FundingArticleDto; +import team.haedal.gifticionfunding.dto.common.PagingResponse; +import team.haedal.gifticionfunding.dto.common.ResponseDto; +import team.haedal.gifticionfunding.service.FundingArticleService; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class FundingArticleController { + private final FundingArticleService fundingArticleService; + + @GetMapping("/v1/fundings/articles") + public ResponseEntity getFundingArticles( + @UserId Long userId, + @RequestParam(value = "page", defaultValue = "0") Integer page, + @RequestParam(value = "size", defaultValue = "10") Integer size + ) { + PagingResponse fundingArticleDtoPage = fundingArticleService.getFundingArticles(userId, page, size); + return new ResponseEntity<>( + new ResponseDto<>(1, "펀딩 게시글 목록 조회 성공", fundingArticleDtoPage), + HttpStatus.OK + ); + } + +} diff --git a/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDto.java b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDto.java new file mode 100644 index 0000000..f1bc3af --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDto.java @@ -0,0 +1,29 @@ +package team.haedal.gifticionfunding.dto; + +import java.time.format.DateTimeFormatter; +import java.util.List; +import team.haedal.gifticionfunding.entity.funding.FundingArticle; + +public record FundingArticleDto( + String author, + String birthdate, + String title, + String content, + String endAt, + List gificonImageUrls +) { + public static FundingArticleDto fromEntity(FundingArticle fundingArticle) { + return new FundingArticleDto( + fundingArticle.getAuthor().getNickname(), + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(fundingArticle.getAuthor().getBirthdate()), + fundingArticle.getTitle(), + fundingArticle.getContent(), + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(fundingArticle.getEndAt()), + fundingArticle.getGifticons().stream() + .map(g -> g.getGifticon().getImageUrl()) + .toList() + ); + + + } +} diff --git a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java index f5f4834..7a90713 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java @@ -1,5 +1,6 @@ package team.haedal.gifticionfunding.entity.funding; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -40,7 +41,7 @@ public class FundingArticle extends BaseTimeEntity { @Column(nullable = false) private LocalDateTime endAt; - @OneToMany(mappedBy = "fundingArticle", fetch = FetchType.LAZY) + @OneToMany(mappedBy = "fundingArticle", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List gifticons = new ArrayList<>(); @Builder private FundingArticle(User author, String title, String content, LocalDateTime endAt) { diff --git a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java index 7d89113..403dccd 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java @@ -1,7 +1,26 @@ package team.haedal.gifticionfunding.repository.funding; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import team.haedal.gifticionfunding.entity.funding.FundingArticle; public interface FundingArticleRepository extends JpaRepository { + @Query( + "SELECT fa FROM FundingArticle fa " + + "JOIN FETCH fa.author " + + "JOIN FETCH fa.gifticons " + + "WHERE fa.author.id IN (" + + " SELECT f.toUser.id FROM Friendship f " + + "WHERE f.fromUser.id = :userId " + // cl + " OR f.toUser.id IN (" + + " SELECT f2.toUser.id FROM Friendship f1 JOIN Friendship f2 ON f1.toUser.id = f2.fromUser.id WHERE f1.fromUser.id = :userId" + + " )" + + ")" + ) + Page findAllByFriendOfFriend( + @Param("userId") Long userId, + Pageable pageable); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java new file mode 100644 index 0000000..3ba9e7d --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java @@ -0,0 +1,44 @@ +package team.haedal.gifticionfunding.service; + +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import team.haedal.gifticionfunding.dto.FundingArticleDto; +import team.haedal.gifticionfunding.dto.common.PagingResponse; +import team.haedal.gifticionfunding.entity.funding.FundingArticle; +import team.haedal.gifticionfunding.repository.funding.FundingArticleRepository; + +@Service +@RequiredArgsConstructor +public class FundingArticleService { + private final FundingArticleRepository fundingArticleRepository; + + /** + * 친구 depth2 범위의 펀딩 게시글을 목록 조회한다. + * @param page + * @param size + * @return + */ + @Transactional(readOnly = true) + public PagingResponse getFundingArticles(Long userId, Integer page, Integer size) { + Pageable pageable = PageRequest.of(page, size, Sort.by("endAt").ascending()); + + // 친구 depth2 범위의 게시글 조회 + Page fundingArticlePage = fundingArticleRepository.findAllByFriendOfFriend(userId, pageable); + + // FundingArticleDto로 변환 + List fundingArticleDtoList = fundingArticlePage.getContent().stream() + .map(FundingArticleDto::fromEntity) + .toList(); + + return PagingResponse.builder() + .hasNext(fundingArticlePage.hasNext()) + .data(fundingArticleDtoList) + .build(); + } +} From 378656cd9b72489101f4234edc1c0b1a5e1905c7 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Fri, 24 May 2024 00:42:28 +0900 Subject: [PATCH 07/16] =?UTF-8?q?[Fix]=20=ED=8E=80=EB=94=A9=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EB=AC=BC=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/funding/FundingArticleRepository.java | 2 +- .../haedal/gifticionfunding/service/FundingArticleService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java index 403dccd..9425966 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java @@ -20,7 +20,7 @@ public interface FundingArticleRepository extends JpaRepository findAllByFriendOfFriend( + Page findAllWithAuthorAndGifticonsByFriendOfFriend( @Param("userId") Long userId, Pageable pageable); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java index 3ba9e7d..e05966c 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java @@ -29,7 +29,7 @@ public PagingResponse getFundingArticles(Long userId, Integer Pageable pageable = PageRequest.of(page, size, Sort.by("endAt").ascending()); // 친구 depth2 범위의 게시글 조회 - Page fundingArticlePage = fundingArticleRepository.findAllByFriendOfFriend(userId, pageable); + Page fundingArticlePage = fundingArticleRepository.findAllWithAuthorAndGifticonsByFriendOfFriend(userId, pageable); // FundingArticleDto로 변환 List fundingArticleDtoList = fundingArticlePage.getContent().stream() From 9cf625f74341700ed4fbc5628eb52386e4c478ef Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Fri, 24 May 2024 00:56:46 +0900 Subject: [PATCH 08/16] =?UTF-8?q?[Fix]=20Entity=20=EC=97=B0=EA=B4=80?= =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/funding/FundingContribute.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingContribute.java b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingContribute.java index 485991c..547a42d 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingContribute.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingContribute.java @@ -1,6 +1,7 @@ package team.haedal.gifticionfunding.entity.funding; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -11,8 +12,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; import team.haedal.gifticionfunding.entity.common.BaseTimeEntity; -import team.haedal.gifticionfunding.entity.user.User; import team.haedal.gifticionfunding.entity.gifticon.UserGifticon; +import team.haedal.gifticionfunding.entity.user.User; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -24,23 +25,23 @@ public class FundingContribute extends BaseTimeEntity { private Long point; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User contributor; - @ManyToOne - @JoinColumn(name = "funding_article_id") - private FundingArticle fundingArticle; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "funding_article_giftcion_id") + private FundingArticleGifticon fundingArticleGifticon; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_gifticon_id") private UserGifticon userGifticon; @Builder - private FundingContribute(Long point, User contributor, FundingArticle fundingArticle, UserGifticon userGifticon) { + private FundingContribute(Long point, User contributor, FundingArticleGifticon fundingArticleGifticon, UserGifticon userGifticon) { this.point = point; this.contributor = contributor; - this.fundingArticle = fundingArticle; + this.fundingArticleGifticon = fundingArticleGifticon; this.userGifticon = userGifticon; } } From 1d21d54303a8dba2c3e67dd31ff990a2ac7276a2 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Fri, 24 May 2024 01:43:35 +0900 Subject: [PATCH 09/16] =?UTF-8?q?[Feat]=2010-6.=20=ED=8E=80=EB=94=A9=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=84=B8=EB=B6=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FundingArticleController.java | 13 ++++- .../dto/FundingArticleDetailDto.java | 37 +++++++++++++ .../dto/FundingArticleGifticonDto.java | 33 ++++++++++++ .../funding/FundingArticleRepository.java | 5 ++ .../funding/FundingContributeRepository.java | 38 +++++++++++++ .../service/FundingArticleService.java | 53 ++++++++++++++++++- 6 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDetailDto.java create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java index d880286..64971c4 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import team.haedal.gifticionfunding.annotation.UserId; +import team.haedal.gifticionfunding.dto.FundingArticleDetailDto; import team.haedal.gifticionfunding.dto.FundingArticleDto; import team.haedal.gifticionfunding.dto.common.PagingResponse; import team.haedal.gifticionfunding.dto.common.ResponseDto; @@ -31,5 +32,15 @@ public ResponseEntity getFundingArticles( HttpStatus.OK ); } - + + @GetMapping("/v1/fundings/articles/{articleId}") + public ResponseEntity getFundingArticle( + @RequestParam(value = "articleId") Long articleId + ) { + FundingArticleDetailDto fundingArticleDto = fundingArticleService.getFundingArticle(articleId); + return new ResponseEntity<>( + new ResponseDto<>(1, "펀딩 게시글 조회 성공", fundingArticleDto), + HttpStatus.OK + ); + } } diff --git a/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDetailDto.java b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDetailDto.java new file mode 100644 index 0000000..e59dcb3 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleDetailDto.java @@ -0,0 +1,37 @@ +package team.haedal.gifticionfunding.dto; + +import java.util.List; +import java.util.Map; +import team.haedal.gifticionfunding.entity.funding.FundingArticle; + +public record FundingArticleDetailDto( + String author, + String birthdate, + String title, + String content, + String endAt, + List goalGifticons +) { + + public static FundingArticleDetailDto of( + FundingArticle fundingArticle, + Map fundAmountMap, + Map numberOfSupportersMap + ) { + return new FundingArticleDetailDto( + fundingArticle.getAuthor().getNickname(), + fundingArticle.getAuthor().getBirthdate().toString(), + fundingArticle.getTitle(), + fundingArticle.getContent(), + fundingArticle.getEndAt().toString(), + fundingArticle.getGifticons().stream() + .map(fundingArticleGifticon -> FundingArticleGifticonDto.of( + fundingArticleGifticon, + fundAmountMap.getOrDefault(fundingArticleGifticon.getId(), 0), + numberOfSupportersMap.getOrDefault(fundingArticleGifticon.getId(), 0) + ) + ) + .toList() + ); + } +} diff --git a/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java new file mode 100644 index 0000000..65b483f --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java @@ -0,0 +1,33 @@ +package team.haedal.gifticionfunding.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import team.haedal.gifticionfunding.entity.funding.FundingArticleGifticon; + +@Getter +public record FundingArticleGifticonDto( + String gifticonName, + Integer price, + String category, + String imageUrl, + Integer achievementRate, + Integer currentFundAmount, + Integer numberOfSupporters +) { + + public static FundingArticleGifticonDto of(FundingArticleGifticon fundingArticleGifticon, Integer currentFundAmount, Integer numberOfSupporters) { + int achievementRate = (int) ((double) currentFundAmount / fundingArticleGifticon.getGifticon().getPrice() * 100); + int price = fundingArticleGifticon.getGifticon().getPrice().intValue(); + + return new FundingArticleGifticonDto( + fundingArticleGifticon.getGifticon().getName(), + price, + fundingArticleGifticon.getGifticon().getCategory().toString(), + fundingArticleGifticon.getGifticon().getImageUrl(), + achievementRate, + currentFundAmount, + numberOfSupporters + ); + } +} diff --git a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java index 9425966..6e9f2ef 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java @@ -1,7 +1,9 @@ package team.haedal.gifticionfunding.repository.funding; +import java.util.Optional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -23,4 +25,7 @@ public interface FundingArticleRepository extends JpaRepository findAllWithAuthorAndGifticonsByFriendOfFriend( @Param("userId") Long userId, Pageable pageable); + + @EntityGraph(attributePaths = {"author", "gifticons"}) + Optional findAllWithAuthorAndGifticonsById(Long articleId); } diff --git a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java index 3cda247..692214b 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java @@ -1,7 +1,45 @@ package team.haedal.gifticionfunding.repository.funding; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import team.haedal.gifticionfunding.entity.funding.FundingContribute; public interface FundingContributeRepository extends JpaRepository { + + @Query( + "SELECT fc.fundingArticleGifticon.id as fundingArticleGifticonId, " + + "COUNT(fc) as contributerNumber " + + "FROM FundingContribute fc " + + "WHERE fc.fundingArticleGifticon.id IN :fundingArticleGifticonIds " + + "GROUP BY fc.fundingArticleGifticon.id" + ) + List countByFundingArticleGifticonIdIn( + @Param("fundingArticleIds") List fundingArticleGifticonIds + ); + + @Query( + "SELECT fc.fundingArticleGifticon.id as fundingArticleGifticonId, " + + "SUM(" + + "CASE WHEN fc.point IS NULL THEN fc.userGifticon.gifticon.price " + + "WHEN fc.userGifticon IS NULL THEN fc.point END" + + ") as contributeAmount " + + "FROM FundingContribute fc " + + "WHERE fc.fundingArticleGifticon.id IN :fundingArticleGifticonIds " + + "GROUP BY fc.fundingArticleGifticon.id" + ) + List sumByFundingArticleGifticonIdIn( + @Param("fundingArticleIds") List fundingArticleGifticonIds + ); + + interface FundingContributerNumber { + Long getFundingArticleGifticonId(); + Integer getContributerNumber(); + } + + interface FundingContributeAmount { + Long getFundingArticleGifticonId(); + Integer getContributeAmount(); + } } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java index e05966c..a69d41e 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java @@ -1,6 +1,8 @@ package team.haedal.gifticionfunding.service; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -8,18 +10,24 @@ import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import team.haedal.gifticionfunding.dto.FundingArticleDetailDto; import team.haedal.gifticionfunding.dto.FundingArticleDto; import team.haedal.gifticionfunding.dto.common.PagingResponse; import team.haedal.gifticionfunding.entity.funding.FundingArticle; import team.haedal.gifticionfunding.repository.funding.FundingArticleRepository; +import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository; +import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository.FundingContributeAmount; +import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository.FundingContributerNumber; @Service @RequiredArgsConstructor public class FundingArticleService { private final FundingArticleRepository fundingArticleRepository; + private final FundingContributeRepository fundingContributeRepository; /** * 친구 depth2 범위의 펀딩 게시글을 목록 조회한다. + * * @param page * @param size * @return @@ -29,7 +37,8 @@ public PagingResponse getFundingArticles(Long userId, Integer Pageable pageable = PageRequest.of(page, size, Sort.by("endAt").ascending()); // 친구 depth2 범위의 게시글 조회 - Page fundingArticlePage = fundingArticleRepository.findAllWithAuthorAndGifticonsByFriendOfFriend(userId, pageable); + Page fundingArticlePage = fundingArticleRepository.findAllWithAuthorAndGifticonsByFriendOfFriend( + userId, pageable); // FundingArticleDto로 변환 List fundingArticleDtoList = fundingArticlePage.getContent().stream() @@ -41,4 +50,46 @@ public PagingResponse getFundingArticles(Long userId, Integer .data(fundingArticleDtoList) .build(); } + + /** + * 펀딩 게시글 상세 조회. 해당 게시글의 후원 금액과 후원자 수를 함께 조회한다. + * @param articleId + * @return + */ + @Transactional(readOnly = true) + public FundingArticleDetailDto getFundingArticle(Long articleId) { + // 펀딩 게시글 조회 + FundingArticle fundingArticle = fundingArticleRepository.findAllWithAuthorAndGifticonsById(articleId) + .orElseThrow(() -> new IllegalArgumentException("해당 펀딩 게시글이 존재하지 않습니다.")); + + List fundingArticleGifticonIds = fundingArticle.getGifticons().stream() + .map(fundingArticleGifticon -> fundingArticleGifticon.getId()) + .toList(); + + // 해당 게시글 기프티콘당 성취 금액 조회 + List fundingContributerAmounts = fundingContributeRepository + .sumByFundingArticleGifticonIdIn(fundingArticleGifticonIds); + + Map fundAmountMap = fundingContributerAmounts.stream() + .collect( + Collectors.toMap( + FundingContributeAmount::getFundingArticleGifticonId, + FundingContributeAmount::getContributeAmount + ) + ); + + // 해당 게시글 기프티콘당 후원자 수 조회 + List fundingContributerNumbers = fundingContributeRepository + .countByFundingArticleGifticonIdIn(fundingArticleGifticonIds); + + Map numberOfSupportersMap = fundingContributerNumbers.stream() + .collect( + Collectors.toMap( + FundingContributerNumber::getFundingArticleGifticonId, + FundingContributerNumber::getContributerNumber + ) + ); + + return FundingArticleDetailDto.of(fundingArticle, fundAmountMap, numberOfSupportersMap); + } } From e45333936eea1dc5a36d0331b100b3410a74a1a3 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Fri, 24 May 2024 01:58:11 +0900 Subject: [PATCH 10/16] =?UTF-8?q?[Feat]=2010-2.=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=ED=8E=80=EB=94=A9=20=EC=97=B0=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FundingArticleController.java | 16 ++++++++++++++++ .../entity/funding/FundingArticle.java | 6 ++++++ .../funding/FundingArticleRepository.java | 3 +++ .../service/FundingArticleService.java | 14 ++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java index 64971c4..a6ba1b0 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java @@ -4,6 +4,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -43,4 +45,18 @@ public ResponseEntity getFundingArticle( HttpStatus.OK ); } + + @PatchMapping("/v1/fundings/articles/{articleId}/expiration") + public ResponseEntity updateFundingArticleExpiration( + @UserId Long userId, + @RequestParam(value = "articleId") Long articleId + ) { + fundingArticleService.updateFundingArticleExpiration(userId, articleId); + return new ResponseEntity<>( + new ResponseDto<>(1, "펀딩 게시글 연장 성공", null), + HttpStatus.OK + ); + } + + } diff --git a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java index 7a90713..e016a00 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java @@ -17,12 +17,14 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.hibernate.annotations.DynamicUpdate; import team.haedal.gifticionfunding.entity.common.BaseTimeEntity; import team.haedal.gifticionfunding.entity.user.User; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity +@DynamicUpdate public class FundingArticle extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -50,4 +52,8 @@ private FundingArticle(User author, String title, String content, LocalDateTime this.content = content; this.endAt = endAt; } + + public void updateExpiration(int maxExtensionDate) { + this.endAt = this.endAt.plusDays(maxExtensionDate); + } } diff --git a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java index 6e9f2ef..0e825b7 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleRepository.java @@ -28,4 +28,7 @@ Page findAllWithAuthorAndGifticonsByFriendOfFriend( @EntityGraph(attributePaths = {"author", "gifticons"}) Optional findAllWithAuthorAndGifticonsById(Long articleId); + + @EntityGraph(attributePaths = {"author"}) + Optional findWithAuthorById(Long articleId); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java index a69d41e..48723d5 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java @@ -22,6 +22,8 @@ @Service @RequiredArgsConstructor public class FundingArticleService { + private static final int MAX_EXTENSION_DATE = 3; + private final FundingArticleRepository fundingArticleRepository; private final FundingContributeRepository fundingContributeRepository; @@ -92,4 +94,16 @@ public FundingArticleDetailDto getFundingArticle(Long articleId) { return FundingArticleDetailDto.of(fundingArticle, fundAmountMap, numberOfSupportersMap); } + + @Transactional + public void updateFundingArticleExpiration(Long userId, Long articleId) { + FundingArticle fundingArticle = fundingArticleRepository.findWithAuthorById(articleId) + .orElseThrow(() -> new IllegalArgumentException("해당 펀딩 게시글이 존재하지 않습니다.")); + + if (!fundingArticle.getAuthor().getId().equals(userId)) { + throw new IllegalArgumentException("해당 펀딩 게시글의 작성자가 아닙니다."); + } + + fundingArticle.updateExpiration(MAX_EXTENSION_DATE); + } } From 625a176ab7e1ab319755a5551db0eaf7da1658cb Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Fri, 24 May 2024 02:27:21 +0900 Subject: [PATCH 11/16] =?UTF-8?q?[Refactor]=20FundingArticle,=20FundingArt?= =?UTF-8?q?icleGifticon=20status=20Enum=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/funding/FundingArticle.java | 9 +++++++++ .../entity/funding/FundingArticleGifticon.java | 8 ++++++++ .../type/EFundingArticleGifticonStatus.java | 15 +++++++++++++++ .../entity/type/EFundingArticleStatus.java | 14 ++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleGifticonStatus.java create mode 100644 src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleStatus.java diff --git a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java index e016a00..25ea71d 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java @@ -3,6 +3,8 @@ import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -19,6 +21,7 @@ import lombok.NoArgsConstructor; import org.hibernate.annotations.DynamicUpdate; import team.haedal.gifticionfunding.entity.common.BaseTimeEntity; +import team.haedal.gifticionfunding.entity.type.EFundingArticleStatus; import team.haedal.gifticionfunding.entity.user.User; @Getter @@ -43,6 +46,10 @@ public class FundingArticle extends BaseTimeEntity { @Column(nullable = false) private LocalDateTime endAt; + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private EFundingArticleStatus status; + @OneToMany(mappedBy = "fundingArticle", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List gifticons = new ArrayList<>(); @Builder @@ -51,6 +58,8 @@ private FundingArticle(User author, String title, String content, LocalDateTime this.title = title; this.content = content; this.endAt = endAt; + + this.status = EFundingArticleStatus.PROCESSING; } public void updateExpiration(int maxExtensionDate) { diff --git a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java index 6f1d94c..314e921 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java @@ -1,6 +1,9 @@ package team.haedal.gifticionfunding.entity.funding; +import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -12,6 +15,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import team.haedal.gifticionfunding.entity.gifticon.Gifticon; +import team.haedal.gifticionfunding.entity.type.EFundingArticleGifticonStatus; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -29,6 +33,10 @@ public class FundingArticleGifticon { @JoinColumn(name = "funding_article_id") private FundingArticle fundingArticle; + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private EFundingArticleGifticonStatus status; + @Builder private FundingArticleGifticon(Gifticon gifticon, FundingArticle fundingArticle) { this.gifticon = gifticon; diff --git a/src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleGifticonStatus.java b/src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleGifticonStatus.java new file mode 100644 index 0000000..848f0b4 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleGifticonStatus.java @@ -0,0 +1,15 @@ +package team.haedal.gifticionfunding.entity.type; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum EFundingArticleGifticonStatus { + PROCESSING("PROCESSING"), + FINISH_SUCCESS("FINISH_SUCCESS"), + FINISH_FAIL("FINISH_FAIL"), + ; + + private final String value; +} diff --git a/src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleStatus.java b/src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleStatus.java new file mode 100644 index 0000000..c4cf55f --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/entity/type/EFundingArticleStatus.java @@ -0,0 +1,14 @@ +package team.haedal.gifticionfunding.entity.type; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum EFundingArticleStatus { + PROCESSING("PROCESSING"), + FINISH("FINISH"), + ; + + private final String value; +} From 242893131ee77f1c52a89679494360ada6cb77a2 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Fri, 24 May 2024 02:44:11 +0900 Subject: [PATCH 12/16] =?UTF-8?q?[Feat]=2010-3.=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=ED=8E=80=EB=94=A9=20=EB=A7=88=EA=B0=90=20(?= =?UTF-8?q?=EC=84=B1=EA=B3=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FundingArticleController.java | 12 +++++- .../entity/funding/FundingArticle.java | 4 ++ .../funding/FundingArticleGifticon.java | 4 ++ .../FundingArticleGifticonRepository.java | 10 +++++ .../service/FundingArticleService.java | 39 ++++++++++++++++++- 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java index a6ba1b0..9d0bb39 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java @@ -58,5 +58,15 @@ public ResponseEntity updateFundingArticleExpiration( ); } - + @PostMapping("/v1/fundings/articles/gifticons/{fundingArticleGifticonId}/success") + public ResponseEntity receiveFunding( + @UserId Long userId, + @RequestParam(value = "fundingArticleGifticonId") Long fundingArticleGifticonId + ) { + fundingArticleService.receiveFunding(userId, fundingArticleGifticonId); + return new ResponseEntity<>( + new ResponseDto<>(1, "펀딩 게시글 성공 처리 성공", null), + HttpStatus.OK + ); + } } diff --git a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java index 25ea71d..b97676c 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticle.java @@ -65,4 +65,8 @@ private FundingArticle(User author, String title, String content, LocalDateTime public void updateExpiration(int maxExtensionDate) { this.endAt = this.endAt.plusDays(maxExtensionDate); } + + public void updateStatus(EFundingArticleStatus status) { + this.status = status; + } } diff --git a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java index 314e921..d40c0d6 100644 --- a/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java +++ b/src/main/java/team/haedal/gifticionfunding/entity/funding/FundingArticleGifticon.java @@ -42,4 +42,8 @@ private FundingArticleGifticon(Gifticon gifticon, FundingArticle fundingArticle) this.gifticon = gifticon; this.fundingArticle = fundingArticle; } + + public void updateStatus(EFundingArticleGifticonStatus eFundingArticleGifticonStatus) { + this.status = eFundingArticleGifticonStatus; + } } diff --git a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleGifticonRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleGifticonRepository.java index dfb1d81..b7d222f 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleGifticonRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingArticleGifticonRepository.java @@ -1,7 +1,17 @@ package team.haedal.gifticionfunding.repository.funding; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import team.haedal.gifticionfunding.entity.funding.FundingArticleGifticon; public interface FundingArticleGifticonRepository extends JpaRepository { + @Query("SELECT fag FROM FundingArticleGifticon fag " + + "JOIN FETCH fag.fundingArticle " + + "JOIN FETCH fag.fundingArticle.author " + + "WHERE fag.id = :fundingArticleGifticonId") + Optional findWithArticleAndAuthorById( + @Param("fundingArticleGifticonId") Long fundingArticleGifticonId + ); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java index 48723d5..1f68ef4 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java @@ -14,10 +14,16 @@ import team.haedal.gifticionfunding.dto.FundingArticleDto; import team.haedal.gifticionfunding.dto.common.PagingResponse; import team.haedal.gifticionfunding.entity.funding.FundingArticle; +import team.haedal.gifticionfunding.entity.funding.FundingArticleGifticon; +import team.haedal.gifticionfunding.entity.gifticon.UserGifticon; +import team.haedal.gifticionfunding.entity.type.EFundingArticleGifticonStatus; +import team.haedal.gifticionfunding.entity.type.EFundingArticleStatus; +import team.haedal.gifticionfunding.repository.funding.FundingArticleGifticonRepository; import team.haedal.gifticionfunding.repository.funding.FundingArticleRepository; import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository; import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository.FundingContributeAmount; import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository.FundingContributerNumber; +import team.haedal.gifticionfunding.repository.user.UserGifticonRepository; @Service @RequiredArgsConstructor @@ -26,7 +32,8 @@ public class FundingArticleService { private final FundingArticleRepository fundingArticleRepository; private final FundingContributeRepository fundingContributeRepository; - + private final FundingArticleGifticonRepository fundingArticleGifticonRepository; + private final UserGifticonRepository userGifticonRepository; /** * 친구 depth2 범위의 펀딩 게시글을 목록 조회한다. * @@ -106,4 +113,34 @@ public void updateFundingArticleExpiration(Long userId, Long articleId) { fundingArticle.updateExpiration(MAX_EXTENSION_DATE); } + + @Transactional + public void receiveFunding(Long userId, Long fundingArticleGifticonId) { + FundingArticleGifticon fundingArticleGifticon = fundingArticleGifticonRepository.findWithArticleAndAuthorById(fundingArticleGifticonId) + .orElseThrow(() -> new IllegalArgumentException("해당 펀딩 게시글 기프티콘이 존재하지 않습니다.")); + + if (!fundingArticleGifticon.getFundingArticle().getAuthor().getId().equals(userId)) { + throw new IllegalArgumentException("해당 펀딩 게시글의 작성자가 아닙니다."); + } + + // userGifticon 생성 + UserGifticon receivedGifticon = UserGifticon.builder() + .buyer(fundingArticleGifticon.getFundingArticle().getAuthor()) + .owner(fundingArticleGifticon.getFundingArticle().getAuthor()) + .gifticon(fundingArticleGifticon.getGifticon()) + .build(); + + // fundingArticleGifticon 상태 변경 + fundingArticleGifticon.updateStatus(EFundingArticleGifticonStatus.FINISH_SUCCESS); + + // 마지막 후원까지 종료되었을 경우, 펀딩 게시글 상태 변경 + int numberOfReceivedGifticons = (int) fundingArticleGifticon.getFundingArticle().getGifticons().stream() + .filter(fundingArticleGifticon1 -> fundingArticleGifticon1.getStatus().equals(EFundingArticleGifticonStatus.FINISH_SUCCESS)) + .count(); + if (numberOfReceivedGifticons == fundingArticleGifticon.getFundingArticle().getGifticons().size()) { + fundingArticleGifticon.getFundingArticle().updateStatus(EFundingArticleStatus.FINISH); + } + // userGifticon 저장 및 flush + userGifticonRepository.saveAndFlush(receivedGifticon); + } } From a187182bff60eb793fe20119ce6b2e06eb4ace76 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 25 May 2024 00:10:27 +0900 Subject: [PATCH 13/16] =?UTF-8?q?[Fix]=20=EA=B8=B0=EC=A1=B4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=20=EC=9E=AC?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/FundingArticleGifticonDto.java | 4 ---- .../funding/FundingContributeRepository.java | 4 ++-- .../core/jwt/JwtAuthorizationFilterTest.java | 10 +++++++--- .../haedal/gifticionfunding/dummy/DummyFactory.java | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java index 65b483f..ea4e2a7 100644 --- a/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java +++ b/src/main/java/team/haedal/gifticionfunding/dto/FundingArticleGifticonDto.java @@ -1,11 +1,7 @@ package team.haedal.gifticionfunding.dto; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; import team.haedal.gifticionfunding.entity.funding.FundingArticleGifticon; -@Getter public record FundingArticleGifticonDto( String gifticonName, Integer price, diff --git a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java index 692214b..e059864 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/funding/FundingContributeRepository.java @@ -16,7 +16,7 @@ public interface FundingContributeRepository extends JpaRepository countByFundingArticleGifticonIdIn( - @Param("fundingArticleIds") List fundingArticleGifticonIds + @Param("fundingArticleGifticonIds") List fundingArticleGifticonIds ); @Query( @@ -30,7 +30,7 @@ List countByFundingArticleGifticonIdIn( "GROUP BY fc.fundingArticleGifticon.id" ) List sumByFundingArticleGifticonIdIn( - @Param("fundingArticleIds") List fundingArticleGifticonIds + @Param("fundingArticleGifticonIds") List fundingArticleGifticonIds ); interface FundingContributerNumber { diff --git a/src/test/java/team/haedal/gifticionfunding/core/jwt/JwtAuthorizationFilterTest.java b/src/test/java/team/haedal/gifticionfunding/core/jwt/JwtAuthorizationFilterTest.java index 26c5b96..f8e8cd0 100644 --- a/src/test/java/team/haedal/gifticionfunding/core/jwt/JwtAuthorizationFilterTest.java +++ b/src/test/java/team/haedal/gifticionfunding/core/jwt/JwtAuthorizationFilterTest.java @@ -30,6 +30,8 @@ class JwtAuthorizationFilterTest extends DummyFactory { private MockMvc mvc; @Autowired private UserRepository userRepository; + @Autowired + private JwtProvider jwtProvider; @Test @DisplayName("관리자가 아닌 사용자가 접근하면 403을 반환한다.") @@ -38,7 +40,8 @@ void authorization_admin_fail_test() throws Exception { User user = newUser("jae@naver.com", "jaehyeon1114", "1234"); User savedUser = userRepository.save(user); - String jwtToken = JwtProvider.create(savedUser); + String jwtToken = jwtProvider.generateAccessToken(savedUser.getId(), savedUser.getRole()) + .accessToken(); System.out.println("테스트 : " + jwtToken); //when @@ -53,8 +56,9 @@ void authorization_admin_fail_test() throws Exception { void authorization_admin_success_test() throws Exception { //given User admin = newUser("jae@naver.com", "jaehyeon1114", "1234"); - PrincipalDetails loginAdmin = new PrincipalDetails(admin); - String jwtToken = JwtProvider.create(admin); + PrincipalDetails loginAdmin = new PrincipalDetails(1L, admin.getRole()); + String jwtToken = jwtProvider.generateAccessToken(1L, loginAdmin.getRole()) + .accessToken();; System.out.println("테스트 : " + jwtToken); //when diff --git a/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java b/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java index 0cb4655..af8884d 100644 --- a/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java +++ b/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java @@ -14,7 +14,7 @@ protected static User newUser(String email, String nickname, String password) { .email(email) .password(passwordEncoder.encode(password)) .point(0L) - .userRole(UserRole.ROLE_USER) + .role(UserRole.ROLE_USER) .nickname(nickname) .birthdate(LocalDate.of(1999, 1, 1)) .build(); @@ -26,7 +26,7 @@ protected static User newAdmin(String email, String nickname, String password) { .email(email) .password(passwordEncoder.encode(password)) .point(0L) - .userRole(UserRole.ROLE_ADMIN) + .role(UserRole.ROLE_ADMIN) .nickname(nickname) .birthdate(LocalDate.of(1999, 1, 1)) .build(); From 674ca32f6d1386bf1409b7cb22fda79ac9a995eb Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 25 May 2024 00:40:10 +0900 Subject: [PATCH 14/16] =?UTF-8?q?[Refactor]=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=EC=A1=B0=EA=B1=B4=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FundingArticleController.java | 3 ++- .../repository/user/FriendshipRepository.java | 10 ++++++++++ .../service/FundingArticleService.java | 11 ++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java index 9d0bb39..3acd262 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingArticleController.java @@ -37,9 +37,10 @@ public ResponseEntity getFundingArticles( @GetMapping("/v1/fundings/articles/{articleId}") public ResponseEntity getFundingArticle( + @UserId Long userId, @RequestParam(value = "articleId") Long articleId ) { - FundingArticleDetailDto fundingArticleDto = fundingArticleService.getFundingArticle(articleId); + FundingArticleDetailDto fundingArticleDto = fundingArticleService.getFundingArticle(userId, articleId); return new ResponseEntity<>( new ResponseDto<>(1, "펀딩 게시글 조회 성공", fundingArticleDto), HttpStatus.OK diff --git a/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java index 67a1395..f80db21 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/user/FriendshipRepository.java @@ -23,4 +23,14 @@ Page findFriendsAndFriendsOfFriends( @Param("userId") Long userId, Pageable pageable ); + + @Query("SELECT CASE WHEN COUNT(u) > 0 THEN TRUE ELSE FALSE END FROM User u " + + "WHERE u.id = :targetUserId AND u.id IN (" + + " SELECT f2.toUser.id FROM Friendship f1 " + + " JOIN Friendship f2 ON f1.toUser.id = f2.fromUser.id " + + " WHERE f1.fromUser.id = :userId)") + Boolean existsUserInFriendsOfFriends( + @Param("userId") Long userId, + @Param("targetUserId") Long targetUserId + ); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java index 1f68ef4..c3d8eeb 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingArticleService.java @@ -23,6 +23,7 @@ import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository; import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository.FundingContributeAmount; import team.haedal.gifticionfunding.repository.funding.FundingContributeRepository.FundingContributerNumber; +import team.haedal.gifticionfunding.repository.user.FriendshipRepository; import team.haedal.gifticionfunding.repository.user.UserGifticonRepository; @Service @@ -34,6 +35,7 @@ public class FundingArticleService { private final FundingContributeRepository fundingContributeRepository; private final FundingArticleGifticonRepository fundingArticleGifticonRepository; private final UserGifticonRepository userGifticonRepository; + private final FriendshipRepository friendshipRepository; /** * 친구 depth2 범위의 펀딩 게시글을 목록 조회한다. * @@ -62,15 +64,22 @@ public PagingResponse getFundingArticles(Long userId, Integer /** * 펀딩 게시글 상세 조회. 해당 게시글의 후원 금액과 후원자 수를 함께 조회한다. + * + * @param userId * @param articleId * @return */ @Transactional(readOnly = true) - public FundingArticleDetailDto getFundingArticle(Long articleId) { + public FundingArticleDetailDto getFundingArticle(Long userId, Long articleId) { // 펀딩 게시글 조회 FundingArticle fundingArticle = fundingArticleRepository.findAllWithAuthorAndGifticonsById(articleId) .orElseThrow(() -> new IllegalArgumentException("해당 펀딩 게시글이 존재하지 않습니다.")); + Long authorId = fundingArticle.getAuthor().getId(); + if (!friendshipRepository.existsUserInFriendsOfFriends(userId, authorId)) { + throw new IllegalArgumentException("친구 depth 2 범위의 펀딩 게시글이 아닙니다."); + } + List fundingArticleGifticonIds = fundingArticle.getGifticons().stream() .map(fundingArticleGifticon -> fundingArticleGifticon.getId()) .toList(); From 0285e8036a4a564cde68445ac467e383550f749f Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 25 May 2024 00:40:36 +0900 Subject: [PATCH 15/16] [Test] getFundingArticle Test --- .../gifticionfunding/dummy/DummyFactory.java | 2 + .../service/FundingArticleServiceTest.java | 124 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java diff --git a/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java b/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java index af8884d..dbb4906 100644 --- a/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java +++ b/src/test/java/team/haedal/gifticionfunding/dummy/DummyFactory.java @@ -31,4 +31,6 @@ protected static User newAdmin(String email, String nickname, String password) { .birthdate(LocalDate.of(1999, 1, 1)) .build(); } + + } diff --git a/src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java b/src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java new file mode 100644 index 0000000..0772f10 --- /dev/null +++ b/src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java @@ -0,0 +1,124 @@ +package team.haedal.gifticionfunding.service; + + +import static java.time.LocalDate.now; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import team.haedal.gifticionfunding.dto.FundingArticleDetailDto; +import team.haedal.gifticionfunding.dummy.DummyFactory; +import team.haedal.gifticionfunding.entity.funding.FundingArticle; +import team.haedal.gifticionfunding.entity.user.Friendship; +import team.haedal.gifticionfunding.entity.user.User; +import team.haedal.gifticionfunding.repository.funding.FundingArticleRepository; +import team.haedal.gifticionfunding.repository.user.FriendshipRepository; +import team.haedal.gifticionfunding.repository.user.UserRepository; + +@SpringBootTest +class FundingArticleServiceTest extends DummyFactory { + @Autowired private FundingArticleService fundingArticleService; + @Autowired private UserRepository userRepository; + @Autowired private FriendshipRepository friendshipRepository; + @Autowired private FundingArticleRepository fundingArticleRepository; + + @AfterEach + void tearDown() { + fundingArticleRepository.deleteAllInBatch(); + friendshipRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); + } + + @Test + @DisplayName("존재하지 않는 펀딩 게시글을 조회하면, IllegalArgumentException 예외가 발생한다.") + void throw_when_read_non_existed_article() { + //given + Long nonExistentId = 1L; + + //when & then + assertThrows(IllegalArgumentException.class, () -> fundingArticleService.getFundingArticle(1L, nonExistentId)); + } + + @Test + @DisplayName("친구 depth 2 범위가 아닌 펀딩 게시글을 조회하면, IllegalArgumentException 예외가 발생한다.") + void throw_when_read_out_of_depth2() { + //given + //유저 생성 + User user = newUser("jae@naver.com", "jaehyeon1114", "1234"); + User depth1Friend = newUser("jae2@naver.com", "jaehyeon1115", "1234"); + User depth2Friend = newUser("jae3@naver.com", "jaehyeon1116", "1234"); + User depth3Friend = newUser("jae4@naver.com", "jaehyeon1117", "1234"); + + userRepository.saveAll(List.of(user, depth1Friend, depth2Friend, depth3Friend)); + + //친구관계 생성 + Friendship friendship1 = Friendship.builder().fromUser(user).toUser(depth1Friend).build(); + Friendship friendship2 = Friendship.builder().fromUser(depth1Friend).toUser(depth2Friend).build(); + Friendship friendship3 = Friendship.builder().fromUser(depth2Friend).toUser(depth3Friend).build(); + + friendshipRepository.saveAll(List.of(friendship1, friendship2, friendship3)); + + // depth3 친구 게시글 생성 + FundingArticle fundingArticle = FundingArticle.builder() + .author(depth3Friend) + .title("title") + .content("content") + .endAt(now().plusDays(1).atStartOfDay()) + .build(); + + fundingArticleRepository.save(fundingArticle); + + //when & then + assertThrows(IllegalArgumentException.class, () -> fundingArticleService.getFundingArticle(user.getId(), fundingArticle.getId())); + } + + @Test + @DisplayName("친구 depth 2 범위의 펀딩 게시글을 정상적으로 조회한다.") + void success_when_read_in_depth2() { + //given + //유저 생성 + User user = newUser("jae@naver.com", "jaehyeon1114", "1234"); + User depth1Friend = newUser("jae2@naver.com", "jaehyeon1115", "1234"); + User depth2Friend = newUser("jae3@naver.com", "jaehyeon1116", "1234"); + + userRepository.saveAll(List.of(user, depth1Friend, depth2Friend)); + + //친구관계 생성 + Friendship friendship1 = Friendship.builder().fromUser(user).toUser(depth1Friend).build(); + Friendship friendship2 = Friendship.builder().fromUser(depth1Friend).toUser(depth2Friend).build(); + + friendshipRepository.saveAll(List.of(friendship1, friendship2)); + + // depth3 친구 게시글 생성 + FundingArticle fundingArticle = FundingArticle.builder() + .author(depth2Friend) + .title("title") + .content("content") + .endAt(now().plusDays(1).atStartOfDay()) + .build(); + + fundingArticleRepository.save(fundingArticle); + + //when + FundingArticleDetailDto fundingArticleDetailDto = fundingArticleService.getFundingArticle(user.getId(), fundingArticle.getId()); + + //then + assertEquals(fundingArticle.getAuthor().getNickname(), fundingArticleDetailDto.author()); + } + @Test + void getFundingArticle() { + } + + @Test + void updateFundingArticleExpiration() { + } + + @Test + void receiveFunding() { + } +} \ No newline at end of file From 6bd4fa803418605487cbd8552613b8fa77eac357 Mon Sep 17 00:00:00 2001 From: jaehyeon Date: Sat, 25 May 2024 19:46:39 +0900 Subject: [PATCH 16/16] [Test] getFundingArticles Test --- .../service/FundingArticleServiceTest.java | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java b/src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java index 0772f10..fa20c32 100644 --- a/src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java +++ b/src/test/java/team/haedal/gifticionfunding/service/FundingArticleServiceTest.java @@ -12,6 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import team.haedal.gifticionfunding.dto.FundingArticleDetailDto; +import team.haedal.gifticionfunding.dto.FundingArticleDto; +import team.haedal.gifticionfunding.dto.common.PagingResponse; import team.haedal.gifticionfunding.dummy.DummyFactory; import team.haedal.gifticionfunding.entity.funding.FundingArticle; import team.haedal.gifticionfunding.entity.user.Friendship; @@ -79,7 +81,7 @@ void throw_when_read_out_of_depth2() { @Test @DisplayName("친구 depth 2 범위의 펀딩 게시글을 정상적으로 조회한다.") - void success_when_read_in_depth2() { + void success_when_read_article_in_depth2() { //given //유저 생성 User user = newUser("jae@naver.com", "jaehyeon1114", "1234"); @@ -111,7 +113,54 @@ void success_when_read_in_depth2() { assertEquals(fundingArticle.getAuthor().getNickname(), fundingArticleDetailDto.author()); } @Test - void getFundingArticle() { + @DisplayName("친구 depth 2 범위의 펀딩 게시글 목록을 정상적으로 조회한다.") + void success_when_read_articles_in_depth2() { + //유저 생성 + User user = newUser("jae@naver.com", "jaehyeon1114", "1234"); + User depth1Friend = newUser("jae2@naver.com", "jaehyeon1115", "1234"); + User depth2Friend = newUser("jae3@naver.com", "jaehyeon1116", "1234"); + User depth3Friend = newUser("jae4@naver.com", "jaehyeon1117", "1234"); + + userRepository.saveAll(List.of(user, depth1Friend, depth2Friend, depth3Friend)); + + //친구관계 생성 + Friendship friendship1 = Friendship.builder().fromUser(user).toUser(depth1Friend).build(); + Friendship friendship2 = Friendship.builder().fromUser(depth1Friend).toUser(depth2Friend).build(); + Friendship friendship3 = Friendship.builder().fromUser(depth2Friend).toUser(depth3Friend).build(); + + friendshipRepository.saveAll(List.of(friendship1, friendship2, friendship3)); + + // depth1 친구 게시글 생성 + FundingArticle fundingArticle1 = FundingArticle.builder() + .author(depth1Friend) + .title("title") + .content("content") + .endAt(now().plusDays(1).atStartOfDay()) + .build(); + + // depth2 친구 게시글 생성 + FundingArticle fundingArticle2 = FundingArticle.builder() + .author(depth2Friend) + .title("title") + .content("content") + .endAt(now().plusDays(1).atStartOfDay()) + .build(); + + // depth3 친구 게시글 생성 + FundingArticle fundingArticle3 = FundingArticle.builder() + .author(depth3Friend) + .title("title") + .content("content") + .endAt(now().plusDays(1).atStartOfDay()) + .build(); + + fundingArticleRepository.saveAll(List.of(fundingArticle1, fundingArticle2, fundingArticle3)); + + //when + PagingResponse fundingArticleDtos = fundingArticleService.getFundingArticles(user.getId(), 0, 10); + + //then + assertEquals(2, fundingArticleDtos.getData().size()); } @Test