From e228963ad8032ce2c7f24ed205dba2e58fd7557b Mon Sep 17 00:00:00 2001 From: soohyeon Date: Mon, 30 Sep 2024 23:38:22 +0900 Subject: [PATCH 1/3] refactor :: bookmark --- .../domain/{good => bookmark}/Bookmark.kt | 18 +++----- .../domain/bookmark/BookmarkRepository.kt | 13 ++++++ .../meogo/domain/bookmark/BookmarkService.kt | 42 +++++++++++++++++++ 3 files changed, 61 insertions(+), 12 deletions(-) rename src/main/kotlin/org/meogo/domain/{good => bookmark}/Bookmark.kt (62%) create mode 100644 src/main/kotlin/org/meogo/domain/bookmark/BookmarkRepository.kt create mode 100644 src/main/kotlin/org/meogo/domain/bookmark/BookmarkService.kt diff --git a/src/main/kotlin/org/meogo/domain/good/Bookmark.kt b/src/main/kotlin/org/meogo/domain/bookmark/Bookmark.kt similarity index 62% rename from src/main/kotlin/org/meogo/domain/good/Bookmark.kt rename to src/main/kotlin/org/meogo/domain/bookmark/Bookmark.kt index ead5012..5bfe945 100644 --- a/src/main/kotlin/org/meogo/domain/good/Bookmark.kt +++ b/src/main/kotlin/org/meogo/domain/bookmark/Bookmark.kt @@ -1,26 +1,20 @@ -package org.meogo.domain.good +package org.meogo.domain.bookmark +import org.meogo.domain.user.domain.User +import org.meogo.global.base.BaseUUIDEntity import java.util.UUID import javax.persistence.Entity import javax.persistence.FetchType import javax.persistence.JoinColumn import javax.persistence.ManyToOne -import org.meogo.domain.post.domain.Post -import org.meogo.domain.user.domain.User -import org.meogo.global.base.BaseUUIDEntity @Entity -class Bookmark ( +class Bookmark( id: UUID? = null, - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id", nullable = true) - val post: Post? = null, - + val schoolId: Int? = 0, @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) val user: User - -) : BaseUUIDEntity(id) \ No newline at end of file +) : BaseUUIDEntity(id) diff --git a/src/main/kotlin/org/meogo/domain/bookmark/BookmarkRepository.kt b/src/main/kotlin/org/meogo/domain/bookmark/BookmarkRepository.kt new file mode 100644 index 0000000..e5ba47b --- /dev/null +++ b/src/main/kotlin/org/meogo/domain/bookmark/BookmarkRepository.kt @@ -0,0 +1,13 @@ +package org.meogo.domain.bookmark + +import org.meogo.domain.user.domain.User +import org.springframework.data.jpa.repository.JpaRepository +import java.util.UUID + +interface BookmarkRepository : JpaRepository { + fun findAllBySchoolId(schoolId: Int): List? + + fun existsBySchoolIdAndUser(schoolId: Int, user: User): Boolean + + fun deleteBySchoolIdAndUser(schoolId: Int, user: User) +} diff --git a/src/main/kotlin/org/meogo/domain/bookmark/BookmarkService.kt b/src/main/kotlin/org/meogo/domain/bookmark/BookmarkService.kt new file mode 100644 index 0000000..2455b95 --- /dev/null +++ b/src/main/kotlin/org/meogo/domain/bookmark/BookmarkService.kt @@ -0,0 +1,42 @@ +package org.meogo.domain.bookmark + +import org.meogo.domain.post.domain.PostRepository +import org.meogo.domain.user.exception.UserNotFoundException +import org.meogo.domain.user.facade.UserFacade +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class BookmarkService( + private val bookmarkRepository: BookmarkRepository, + private val userFacade: UserFacade, + private val postRepository: PostRepository +) { + + @Transactional + fun execute(schoolId: Int) { + val user = userFacade.currentUser() ?: throw UserNotFoundException + + bookmarkRepository.save( + Bookmark( + schoolId = schoolId, + user = user + ) + ) + } + + fun queryBookmarkedPost(schoolId: Int): Int { + val posts = bookmarkRepository.findAllBySchoolId(schoolId) + return posts?.size ?: 0 + } + + fun queryIsBookmarked(schoolId: Int): Boolean { + val user = userFacade.currentUser() ?: throw UserNotFoundException + return bookmarkRepository.existsBySchoolIdAndUser(schoolId, user) + } + + fun deleteBookmark(schoolId: Int) { + val user = userFacade.currentUser() ?: throw UserNotFoundException + bookmarkRepository.deleteBySchoolIdAndUser(schoolId, user) + } +} From 6fde9748e596bb2987e96dc3d11881fe6dfe581c Mon Sep 17 00:00:00 2001 From: soohyeon Date: Mon, 30 Sep 2024 23:38:35 +0900 Subject: [PATCH 2/3] add :: good --- .../org/meogo/domain/good/domain/Good.kt | 24 +++++++++++++++++++ .../domain/good/domain/GoodRepository.kt | 10 ++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/main/kotlin/org/meogo/domain/good/domain/Good.kt create mode 100644 src/main/kotlin/org/meogo/domain/good/domain/GoodRepository.kt diff --git a/src/main/kotlin/org/meogo/domain/good/domain/Good.kt b/src/main/kotlin/org/meogo/domain/good/domain/Good.kt new file mode 100644 index 0000000..b2e9406 --- /dev/null +++ b/src/main/kotlin/org/meogo/domain/good/domain/Good.kt @@ -0,0 +1,24 @@ +package org.meogo.domain.good.domain + +import org.meogo.domain.post.domain.Post +import org.meogo.domain.user.domain.User +import org.meogo.global.base.BaseUUIDEntity +import java.util.UUID +import javax.persistence.Entity +import javax.persistence.FetchType +import javax.persistence.JoinColumn +import javax.persistence.ManyToOne + +@Entity +class Good( + id: UUID? = null, + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", nullable = true) + val post: Post? = null, + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + val user: User + +) : BaseUUIDEntity(id) diff --git a/src/main/kotlin/org/meogo/domain/good/domain/GoodRepository.kt b/src/main/kotlin/org/meogo/domain/good/domain/GoodRepository.kt new file mode 100644 index 0000000..d5e08dc --- /dev/null +++ b/src/main/kotlin/org/meogo/domain/good/domain/GoodRepository.kt @@ -0,0 +1,10 @@ +package org.meogo.domain.good.domain + +import org.meogo.domain.post.domain.Post +import org.meogo.domain.user.domain.User +import org.springframework.data.jpa.repository.JpaRepository +import java.util.UUID + +interface GoodRepository : JpaRepository { + fun findByUserAndPost(user: User, post: Post): Good +} From 8d7635e69cf5ea8b8f67dd37e90069fca263e80a Mon Sep 17 00:00:00 2001 From: soohyeon Date: Mon, 30 Sep 2024 23:38:45 +0900 Subject: [PATCH 3/3] add :: add delete good api --- .../good/presentation/GoodController.kt | 28 +++++++++++++ .../meogo/domain/good/service/GoodService.kt | 41 +++++++++++++++++++ .../org/meogo/domain/post/domain/Post.kt | 4 ++ 3 files changed, 73 insertions(+) create mode 100644 src/main/kotlin/org/meogo/domain/good/presentation/GoodController.kt create mode 100644 src/main/kotlin/org/meogo/domain/good/service/GoodService.kt diff --git a/src/main/kotlin/org/meogo/domain/good/presentation/GoodController.kt b/src/main/kotlin/org/meogo/domain/good/presentation/GoodController.kt new file mode 100644 index 0000000..a608086 --- /dev/null +++ b/src/main/kotlin/org/meogo/domain/good/presentation/GoodController.kt @@ -0,0 +1,28 @@ +package org.meogo.domain.good.presentation + +import lombok.RequiredArgsConstructor +import org.meogo.domain.good.service.GoodService +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.DeleteMapping +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.ResponseStatus +import org.springframework.web.bind.annotation.RestController + +@RequiredArgsConstructor +@RestController +@RequestMapping("/good") +class GoodController( + private val goodService: GoodService +) { + @ResponseStatus(HttpStatus.CREATED) + @PostMapping + fun addGood(@RequestParam(name = "post_id")postId: Long) = + goodService.addGood(postId) + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping + fun deleteGood(@RequestParam(name = "post_id")postId: Long) = + goodService.deleteGood(postId) +} diff --git a/src/main/kotlin/org/meogo/domain/good/service/GoodService.kt b/src/main/kotlin/org/meogo/domain/good/service/GoodService.kt new file mode 100644 index 0000000..d1c0399 --- /dev/null +++ b/src/main/kotlin/org/meogo/domain/good/service/GoodService.kt @@ -0,0 +1,41 @@ +package org.meogo.domain.good.service + +import org.meogo.domain.good.domain.Good +import org.meogo.domain.good.domain.GoodRepository +import org.meogo.domain.post.domain.PostRepository +import org.meogo.domain.user.exception.UserNotFoundException +import org.meogo.domain.user.facade.UserFacade +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class GoodService( + private val goodRepository: GoodRepository, + private val userFacade: UserFacade, + private val postRepository: PostRepository +) { + + @Transactional + fun addGood(postId: Long) { + val user = userFacade.currentUser() ?: throw UserNotFoundException + val post = postRepository.findById(postId) + + post.addGood() + goodRepository.save( + Good( + post = post, + user = user + ) + ) + } + + @Transactional + fun deleteGood(postId: Long) { + val user = userFacade.currentUser() ?: throw UserNotFoundException + val post = postRepository.findById(postId) + val good = goodRepository.findByUserAndPost(user, post) + + post.deleteGood() + goodRepository.delete(good) + } +} diff --git a/src/main/kotlin/org/meogo/domain/post/domain/Post.kt b/src/main/kotlin/org/meogo/domain/post/domain/Post.kt index 9f2ac60..7ee3071 100644 --- a/src/main/kotlin/org/meogo/domain/post/domain/Post.kt +++ b/src/main/kotlin/org/meogo/domain/post/domain/Post.kt @@ -62,5 +62,9 @@ class Post( this.good += 1 } + fun deleteGood() { + this.good -= 1 + } + fun format(date: LocalDateTime) = date.format(DateTimeFormatter.ofPattern("yy.MM.dd HH:mm"))!! }