From 07e8656cf3f473ff1ddb300a64a1b543f4594800 Mon Sep 17 00:00:00 2001 From: sunseo18 Date: Thu, 13 Jul 2023 00:20:48 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[ADD]=20=EC=95=84=ED=8B=B0=ED=81=B4=20?= =?UTF-8?q?=EB=B6=81=EB=A7=88=ED=81=AC=20=EC=A1=B0=ED=9A=8C=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=EC=A1=B0=ED=9A=8C=20=EB=A6=AC=EC=8A=A4=ED=8F=B0?= =?UTF-8?q?=EC=8A=A4=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/indipage/org/indipage/exception/Success.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/indipage/org/indipage/exception/Success.java b/src/main/java/indipage/org/indipage/exception/Success.java index a92ac8f..79e43aa 100644 --- a/src/main/java/indipage/org/indipage/exception/Success.java +++ b/src/main/java/indipage/org/indipage/exception/Success.java @@ -21,6 +21,7 @@ public enum Success { UPDATE_VISIT_SUCCESS(HttpStatus.OK, "공간 방문에 성공했습니다."), READ_IF_USER_HAS_RECEIVED_TICKET_SUCCESS(HttpStatus.OK, "티켓 수령 여부 조회를 성공했습니다."), READ_ARTICLE_SUMMARY_LIST_SUCCESS(HttpStatus.OK, "아티클 전체 목록 조회에 성공했습니다."), + READ_IS_ARTICLE_BOOKMARKED_SUCCESS(HttpStatus.OK, "아티클 북마크 여부 조회 성공"), /** * 201 CREATED */ From ceb017baf58c1280b892b670d3088f61014b8691 Mon Sep 17 00:00:00 2001 From: sunseo18 Date: Thu, 13 Jul 2023 00:24:58 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[ADD]=20embeddedId=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/Relation/ArticleBookmarkRelationId.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelationId.java b/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelationId.java index 30e89f9..b519b7b 100644 --- a/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelationId.java +++ b/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelationId.java @@ -1,13 +1,18 @@ package indipage.org.indipage.domain.Relation; +import indipage.org.indipage.domain.Article; +import indipage.org.indipage.domain.Space; +import indipage.org.indipage.domain.User; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Embeddable; +import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @Embeddable @NoArgsConstructor +@AllArgsConstructor @EqualsAndHashCode public class ArticleBookmarkRelationId implements Serializable { @@ -16,4 +21,8 @@ public class ArticleBookmarkRelationId implements Serializable { @Column(name = "user_id", nullable = false) private Long userId; + + public static ArticleBookmarkRelationId newInstance(Article article, User user) { + return new ArticleBookmarkRelationId(article.getId(), user.getId()); + } } From 5e5a2459fc553fedbe3b4e59574efaf7f07fed0b Mon Sep 17 00:00:00 2001 From: sunseo18 Date: Thu, 13 Jul 2023 00:25:30 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[ADD]=20=EB=B6=81=EB=A7=88=ED=81=AC=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EC=A1=B0=ED=9A=8C=20api=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20dto=20=EA=B5=AC=ED=98=84=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/IsBookmarkedResponseDto.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/indipage/org/indipage/api/user/controller/dto/response/IsBookmarkedResponseDto.java diff --git a/src/main/java/indipage/org/indipage/api/user/controller/dto/response/IsBookmarkedResponseDto.java b/src/main/java/indipage/org/indipage/api/user/controller/dto/response/IsBookmarkedResponseDto.java new file mode 100644 index 0000000..1f2b489 --- /dev/null +++ b/src/main/java/indipage/org/indipage/api/user/controller/dto/response/IsBookmarkedResponseDto.java @@ -0,0 +1,17 @@ +package indipage.org.indipage.api.user.controller.dto.response; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class IsBookmarkedResponseDto { + private boolean isBookMarked; + + public static IsBookmarkedResponseDto of(boolean isBookMarked) { + return new IsBookmarkedResponseDto(isBookMarked); + } +} From c8068768bceeaabe7acfe9285cdfbcc4d6fd2b8b Mon Sep 17 00:00:00 2001 From: sunseo18 Date: Thu, 13 Jul 2023 00:25:49 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[FEAT]=20=EC=95=84=ED=8B=B0=ED=81=B4=20?= =?UTF-8?q?=EB=B6=81=EB=A7=88=ED=81=AC=20=EC=97=AC=EB=B6=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20=EA=B5=AC=ED=98=84=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/controller/UserController.java | 8 ++++++ .../api/user/service/UserService.java | 28 +++++++++++++++++++ .../ArticleBookmarkRelationRepository.java | 14 ++++++++++ 3 files changed, 50 insertions(+) create mode 100644 src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java diff --git a/src/main/java/indipage/org/indipage/api/user/controller/UserController.java b/src/main/java/indipage/org/indipage/api/user/controller/UserController.java index 5708178..e5cd70d 100644 --- a/src/main/java/indipage/org/indipage/api/user/controller/UserController.java +++ b/src/main/java/indipage/org/indipage/api/user/controller/UserController.java @@ -1,6 +1,7 @@ package indipage.org.indipage.api.user.controller; import indipage.org.indipage.api.user.controller.dto.response.HasReceivedTicketResponseDto; +import indipage.org.indipage.api.user.controller.dto.response.IsBookmarkedResponseDto; import indipage.org.indipage.api.user.controller.dto.response.UserDto; import indipage.org.indipage.api.user.service.UserService; import indipage.org.indipage.common.dto.ApiResponse; @@ -47,4 +48,11 @@ public ApiResponse updateVisit(@PathVariable final Long spaceId) { userService.visit(1L, spaceId); return ApiResponse.success(Success.UPDATE_VISIT_SUCCESS); } + + @GetMapping("/bookmark/article/{articleId}") + @ResponseStatus(HttpStatus.OK) + public ApiResponse readIsArticleBookMarked(@PathVariable Long articleId) { + return ApiResponse.success(Success.READ_IS_ARTICLE_BOOKMARKED_SUCCESS, + userService.readIsArticleBookMarked(1L, articleId)); + } } diff --git a/src/main/java/indipage/org/indipage/api/user/service/UserService.java b/src/main/java/indipage/org/indipage/api/user/service/UserService.java index cb01594..55039eb 100644 --- a/src/main/java/indipage/org/indipage/api/user/service/UserService.java +++ b/src/main/java/indipage/org/indipage/api/user/service/UserService.java @@ -2,8 +2,14 @@ import indipage.org.indipage.api.ticket.service.TicketService; import indipage.org.indipage.api.user.controller.dto.response.HasReceivedTicketResponseDto; +import indipage.org.indipage.api.user.controller.dto.response.IsBookmarkedResponseDto; import indipage.org.indipage.api.user.controller.dto.response.UserDto; +import indipage.org.indipage.domain.Article; +import indipage.org.indipage.domain.ArticleBookmarkRelationRepository; +import indipage.org.indipage.domain.ArticleRepository; import indipage.org.indipage.domain.InviteSpaceRelationRepository; +import indipage.org.indipage.domain.Relation.ArticleBookmarkRelation; +import indipage.org.indipage.domain.Relation.ArticleBookmarkRelationId; import indipage.org.indipage.domain.Relation.InviteSpaceRelation; import indipage.org.indipage.domain.Relation.InviteSpaceRelationId; import indipage.org.indipage.domain.Space; @@ -14,6 +20,7 @@ import indipage.org.indipage.exception.Error; import indipage.org.indipage.exception.model.ConflictException; import indipage.org.indipage.exception.model.NotFoundException; +import java.util.Optional; import javax.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -23,8 +30,10 @@ public class UserService { private final UserRepository userRepository; private final TicketService ticketService; + private final ArticleRepository articleRepository; private final SpaceRepository spaceRepository; private final InviteSpaceRelationRepository inviteSpaceRelationRepository; + private final ArticleBookmarkRelationRepository articleBookmarkRelationRepository; public UserDto readUser(final Long userId) { return UserDto.of(findUser(userId)); @@ -79,10 +88,29 @@ public void visit(final Long userId, final Long spaceId) { inviteSpaceRelationRepository.save(relation); } + public IsBookmarkedResponseDto readIsArticleBookMarked(final Long userId, final Long articleId) { + + User user = findUser(userId); + Article article = findArticle(articleId); + + Optional relation = articleBookmarkRelationRepository.findArticleBookmarkRelationByArticleBookmarkRelationId( + ArticleBookmarkRelationId.newInstance(article, user)); + + if (relation.isEmpty()) { + return IsBookmarkedResponseDto.of(false); + } + return IsBookmarkedResponseDto.of(true); + } + private Space findSpace(Long spaceId) { return spaceRepository.findById(spaceId).orElseThrow( () -> new NotFoundException(Error.NOT_FOUND_SPACE_EXCEPTION, Error.NOT_FOUND_SPACE_EXCEPTION.getMessage())); } + private Article findArticle(Long articleId) { + return articleRepository.findById(articleId).orElseThrow( + () -> new NotFoundException(Error.NOT_FOUND_ARTICLE_EXCEPTION, + Error.NOT_FOUND_ARTICLE_EXCEPTION.getMessage())); + } } diff --git a/src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java b/src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java new file mode 100644 index 0000000..2c138c1 --- /dev/null +++ b/src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java @@ -0,0 +1,14 @@ +package indipage.org.indipage.domain; + +import indipage.org.indipage.domain.Relation.ArticleBookmarkRelation; +import indipage.org.indipage.domain.Relation.ArticleBookmarkRelationId; +import indipage.org.indipage.domain.Relation.FollowSpaceRelation; +import java.util.Optional; +import org.springframework.data.repository.Repository; + +public interface ArticleBookmarkRelationRepository extends + Repository { + Optional findArticleBookmarkRelationByArticleBookmarkRelationId( + ArticleBookmarkRelationId articleBookmarkRelationId); + +} \ No newline at end of file From f8197af63e6ff0a318c4f110166408de1a9a0392 Mon Sep 17 00:00:00 2001 From: sunseo18 Date: Thu, 13 Jul 2023 00:59:32 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[ADD]=20=EC=95=84=ED=8B=B0=ED=81=B4=20?= =?UTF-8?q?=EB=B6=81=EB=A7=88=ED=81=AC=20=EB=93=B1=EB=A1=9D=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EB=A6=AC=EC=8A=A4=ED=8F=B0=EC=8A=A4=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/indipage/org/indipage/exception/Error.java | 1 + src/main/java/indipage/org/indipage/exception/Success.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/indipage/org/indipage/exception/Error.java b/src/main/java/indipage/org/indipage/exception/Error.java index 98ef234..3a9d938 100644 --- a/src/main/java/indipage/org/indipage/exception/Error.java +++ b/src/main/java/indipage/org/indipage/exception/Error.java @@ -30,6 +30,7 @@ public enum Error { * 409 CONFLICT */ ALREADY_INVITED_EXCEPTION(HttpStatus.CONFLICT, "이미 티켓을 수령한 상태입니다."), + ALREADY_BOOKMARKED_ARTICLE_EXCEPTION(HttpStatus.CONFLICT, "이미 북마크한 아티클입니다."), /** * 413 PAYLOAD_TOO_LARGE diff --git a/src/main/java/indipage/org/indipage/exception/Success.java b/src/main/java/indipage/org/indipage/exception/Success.java index 79e43aa..7f6064d 100644 --- a/src/main/java/indipage/org/indipage/exception/Success.java +++ b/src/main/java/indipage/org/indipage/exception/Success.java @@ -30,8 +30,8 @@ public enum Success { CREATE_IMAGE_SUCCESS(HttpStatus.CREATED, "이미지 업로드를 완료했습니다."), CREATE_FOLLOW_SPACE_SUCCESS(HttpStatus.CREATED, "조르기 등록에 성공했습니다."), - - CREATE_RECEIVE_TICKET_SUCCESS(HttpStatus.CREATED, "티켓 수령에 성공했습니다.") + CREATE_RECEIVE_TICKET_SUCCESS(HttpStatus.CREATED, "티켓 수령에 성공했습니다."), + CREATE_ARTICLE_BOOKMARK_SUCCESS(HttpStatus.CREATED, "아티클 북마크 등록에 성공했습니다.") ; private final HttpStatus httpStatus; From 6743a5636147b8d41c2751dac5b74908a26ab378 Mon Sep 17 00:00:00 2001 From: sunseo18 Date: Thu, 13 Jul 2023 01:00:34 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[ADD]=20=EC=95=84=ED=8B=B0=ED=81=B4=20?= =?UTF-8?q?=EB=B6=81=EB=A7=88=ED=81=AC=20=EC=83=9D=EC=84=B1=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../indipage/domain/Relation/ArticleBookmarkRelation.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelation.java b/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelation.java index 09df2fc..4ad012d 100644 --- a/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelation.java +++ b/src/main/java/indipage/org/indipage/domain/Relation/ArticleBookmarkRelation.java @@ -9,11 +9,13 @@ import javax.persistence.ManyToOne; import javax.persistence.MapsId; import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @Entity @Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ArticleBookmarkRelation extends CreatedTimeBaseEntity { @@ -29,4 +31,9 @@ public class ArticleBookmarkRelation extends CreatedTimeBaseEntity { @ManyToOne @JoinColumn(name = "user_id") private User user; + + public static ArticleBookmarkRelation newInstance(Article article, User user) { + return new ArticleBookmarkRelation( + ArticleBookmarkRelationId.newInstance(article, user), article, user); + } } \ No newline at end of file From 6395bb659332522e31309515e29fec88f7f60bc5 Mon Sep 17 00:00:00 2001 From: sunseo18 Date: Thu, 13 Jul 2023 01:00:56 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[FEAT]=20=EC=95=84=ED=8B=B0=ED=81=B4=20?= =?UTF-8?q?=EB=B6=81=EB=A7=88=ED=81=AC=20api=20=EA=B5=AC=ED=98=84=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/controller/UserController.java | 7 +++++ .../api/user/service/UserService.java | 27 +++++++++++++++++++ .../ArticleBookmarkRelationRepository.java | 2 ++ 3 files changed, 36 insertions(+) diff --git a/src/main/java/indipage/org/indipage/api/user/controller/UserController.java b/src/main/java/indipage/org/indipage/api/user/controller/UserController.java index e5cd70d..257bb50 100644 --- a/src/main/java/indipage/org/indipage/api/user/controller/UserController.java +++ b/src/main/java/indipage/org/indipage/api/user/controller/UserController.java @@ -55,4 +55,11 @@ public ApiResponse readIsArticleBookMarked(@PathVariabl return ApiResponse.success(Success.READ_IS_ARTICLE_BOOKMARKED_SUCCESS, userService.readIsArticleBookMarked(1L, articleId)); } + + @PostMapping("/bookmark/article/{articleId}") + @ResponseStatus(HttpStatus.CREATED) + public ApiResponse createArticleBookmark(@PathVariable Long articleId) { + userService.createArticleBookmark(1L, articleId); + return ApiResponse.success(Success.CREATE_ARTICLE_BOOKMARK_SUCCESS); + } } diff --git a/src/main/java/indipage/org/indipage/api/user/service/UserService.java b/src/main/java/indipage/org/indipage/api/user/service/UserService.java index 55039eb..c56e024 100644 --- a/src/main/java/indipage/org/indipage/api/user/service/UserService.java +++ b/src/main/java/indipage/org/indipage/api/user/service/UserService.java @@ -102,6 +102,22 @@ public IsBookmarkedResponseDto readIsArticleBookMarked(final Long userId, final return IsBookmarkedResponseDto.of(true); } + @Transactional(rollbackOn = Exception.class) + public void createArticleBookmark(final Long userId, final Long articleId) { + User user = findUser(userId); + Article article = findArticle(articleId); + + // 북마크 검사 + if (isBookMarked(user, article)) { + throw new ConflictException(Error.ALREADY_BOOKMARKED_ARTICLE_EXCEPTION, + Error.ALREADY_BOOKMARKED_ARTICLE_EXCEPTION.getMessage()); + } + ; + + ArticleBookmarkRelation relation = ArticleBookmarkRelation.newInstance(article, user); + articleBookmarkRelationRepository.save(relation); + } + private Space findSpace(Long spaceId) { return spaceRepository.findById(spaceId).orElseThrow( () -> new NotFoundException(Error.NOT_FOUND_SPACE_EXCEPTION, @@ -113,4 +129,15 @@ private Article findArticle(Long articleId) { () -> new NotFoundException(Error.NOT_FOUND_ARTICLE_EXCEPTION, Error.NOT_FOUND_ARTICLE_EXCEPTION.getMessage())); } + + private boolean isBookMarked(User user, Article article) { + Optional relation = articleBookmarkRelationRepository.findArticleBookmarkRelationByArticleBookmarkRelationId( + ArticleBookmarkRelationId.newInstance(article, user)); + + if (relation.isEmpty()) { + return false; + } + + return true; + } } diff --git a/src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java b/src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java index 2c138c1..7c6fd4b 100644 --- a/src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java +++ b/src/main/java/indipage/org/indipage/domain/ArticleBookmarkRelationRepository.java @@ -11,4 +11,6 @@ public interface ArticleBookmarkRelationRepository extends Optional findArticleBookmarkRelationByArticleBookmarkRelationId( ArticleBookmarkRelationId articleBookmarkRelationId); + void save(ArticleBookmarkRelation relation); + } \ No newline at end of file