From 28d113f30aadc0201f587848fba46f0b4a6bddcd Mon Sep 17 00:00:00 2001 From: Namgyu11 <103015031+Namgyu11@users.noreply.github.com> Date: Fri, 27 Dec 2024 19:50:40 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A1=9C=EC=A7=81=EC=97=90=20=ED=8F=89=EC=A0=90=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EB=B0=8F=20=ED=8F=89=EA=B7=A0=20=ED=8F=89?= =?UTF-8?q?=EC=A0=90=20=EA=B0=B1=EC=8B=A0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wooco/woocobe/place/domain/model/Place.kt | 29 ++++++++++++------- .../domain/usecase/AddPlaceReviewUseCase.kt | 2 +- .../usecase/DeletePlaceReviewUseCase.kt | 6 ++-- .../usecase/UpdatePlaceReviewUseCase.kt | 6 ++++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/kr/wooco/woocobe/place/domain/model/Place.kt b/src/main/kotlin/kr/wooco/woocobe/place/domain/model/Place.kt index 1c0cb9f..8e25823 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/domain/model/Place.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/domain/model/Place.kt @@ -11,20 +11,29 @@ class Place( var reviewCount: Long, // 한줄평 통계 로직 고려 중 ) { - fun increaseReviewCount() = - apply { - reviewCount++ - } + fun addReview(newRating: Double) { + averageRating = ((averageRating * reviewCount) + newRating) / (reviewCount + 1) + reviewCount++ + } - fun decreaseReviewCount() = - apply { - reviewCount-- + fun updateReview( + oldRating: Double, + newRating: Double, + ) { + if (reviewCount > 0) { + averageRating += (newRating - oldRating) / reviewCount } + } - fun updateAverageRating(rating: Double) = - apply { - averageRating = (averageRating * reviewCount + rating) / (reviewCount) + fun deleteReview(oldRating: Double) { + if (reviewCount > 1) { + averageRating = ((averageRating * reviewCount) - oldRating) / (reviewCount - 1) + reviewCount-- + } else { + averageRating = 0.0 + reviewCount = 0 } + } companion object { fun register( diff --git a/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/AddPlaceReviewUseCase.kt b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/AddPlaceReviewUseCase.kt index fefd200..ba391af 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/AddPlaceReviewUseCase.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/AddPlaceReviewUseCase.kt @@ -37,8 +37,8 @@ class AddPlaceReviewUseCase( oneLineReview = input.oneLineReviews, imageUrls = input.imageUrls, ).also(placeReviewStorageGateway::save) - place.increaseReviewCount() + place.addReview(input.rating) placeStorageGateway.save(place) } } diff --git a/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/DeletePlaceReviewUseCase.kt b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/DeletePlaceReviewUseCase.kt index da091ee..100051a 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/DeletePlaceReviewUseCase.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/DeletePlaceReviewUseCase.kt @@ -27,8 +27,10 @@ class DeletePlaceReviewUseCase( placeReviewStorageGateway.deleteByPlaceReviewId(placeReviewId = placeReview.id) - placeReview.place.decreaseReviewCount() + val place = placeReview.place - placeStorageGateway.save(placeReview.place) + place.deleteReview(oldRating = placeReview.rating) + + placeStorageGateway.save(place) } } diff --git a/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/UpdatePlaceReviewUseCase.kt b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/UpdatePlaceReviewUseCase.kt index d41165f..029969e 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/UpdatePlaceReviewUseCase.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/UpdatePlaceReviewUseCase.kt @@ -2,6 +2,7 @@ package kr.wooco.woocobe.place.domain.usecase import kr.wooco.woocobe.common.domain.usecase.UseCase import kr.wooco.woocobe.place.domain.gateway.PlaceReviewStorageGateway +import kr.wooco.woocobe.place.domain.gateway.PlaceStorageGateway import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -17,6 +18,7 @@ data class UpdatePlaceReviewInput( @Service class UpdatePlaceReviewUseCase( private val placeReviewStorageGateway: PlaceReviewStorageGateway, + private val placeStorageGateway: PlaceStorageGateway, ) : UseCase { @Transactional override fun execute(input: UpdatePlaceReviewInput) { @@ -34,5 +36,9 @@ class UpdatePlaceReviewUseCase( oneLineReviews = input.oneLineReviews, imageUrls = input.imageUrls, ).also(placeReviewStorageGateway::save) + + val place = placeReview.place + place.updateReview(oldRating = placeReview.rating, newRating = input.rating) + placeStorageGateway.save(place) } } From f47cfbec45eee447c283eedc7794f6f691904c53 Mon Sep 17 00:00:00 2001 From: Namgyu11 <103015031+Namgyu11@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:49:16 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infrastructure/storage/PlaceOneLineReviewEntity.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewEntity.kt b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewEntity.kt index 88284d5..8e15bbb 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewEntity.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewEntity.kt @@ -13,8 +13,10 @@ import kr.wooco.woocobe.place.domain.model.PlaceOneLineReview class PlaceOneLineReviewEntity( @Column(name = "content") val content: String, - @Column(name = "place_id") + @Column(name = "place_Review_id") val placeReviewId: Long, + @Column(name = "place_id") + val placeId: Long, @Id @Tsid @Column(name = "place_one_line_review_id") val id: Long? = 0L, @@ -23,10 +25,12 @@ class PlaceOneLineReviewEntity( companion object { fun of( + placeId: Long, placeReviewId: Long, content: String, ): PlaceOneLineReviewEntity = PlaceOneLineReviewEntity( + placeId = placeId, placeReviewId = placeReviewId, content = content, ) From cf5579ffa201fa9372507aa03c318dc0be962c57 Mon Sep 17 00:00:00 2001 From: Namgyu11 <103015031+Namgyu11@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:50:05 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=ED=95=9C=EC=A4=84=ED=8F=89=20?= =?UTF-8?q?=ED=86=B5=EA=B3=84=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlaceOneLineReviewStorageGateway.kt | 7 +++++ .../domain/model/PlaceOneLineReviewStat.kt | 6 +++++ .../usecase/GetOneLineReviewStatsUseCase.kt | 26 +++++++++++++++++++ .../JpaPlaceOneLineReviewStorageGateway.kt | 24 +++++++++++++++++ .../gateway/JpaPlaceReviewStorageGateway.kt | 13 +++++++--- .../PlaceOneLineReviewJpaRepository.kt | 15 +++++++++++ 6 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/kr/wooco/woocobe/place/domain/gateway/PlaceOneLineReviewStorageGateway.kt create mode 100644 src/main/kotlin/kr/wooco/woocobe/place/domain/model/PlaceOneLineReviewStat.kt create mode 100644 src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/GetOneLineReviewStatsUseCase.kt create mode 100644 src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceOneLineReviewStorageGateway.kt diff --git a/src/main/kotlin/kr/wooco/woocobe/place/domain/gateway/PlaceOneLineReviewStorageGateway.kt b/src/main/kotlin/kr/wooco/woocobe/place/domain/gateway/PlaceOneLineReviewStorageGateway.kt new file mode 100644 index 0000000..d31947f --- /dev/null +++ b/src/main/kotlin/kr/wooco/woocobe/place/domain/gateway/PlaceOneLineReviewStorageGateway.kt @@ -0,0 +1,7 @@ +package kr.wooco.woocobe.place.domain.gateway + +import kr.wooco.woocobe.place.domain.model.PlaceOneLineReviewStat + +interface PlaceOneLineReviewStorageGateway { + fun getOneLineReviewStats(placeId: Long): List +} diff --git a/src/main/kotlin/kr/wooco/woocobe/place/domain/model/PlaceOneLineReviewStat.kt b/src/main/kotlin/kr/wooco/woocobe/place/domain/model/PlaceOneLineReviewStat.kt new file mode 100644 index 0000000..58da45b --- /dev/null +++ b/src/main/kotlin/kr/wooco/woocobe/place/domain/model/PlaceOneLineReviewStat.kt @@ -0,0 +1,6 @@ +package kr.wooco.woocobe.place.domain.model + +class PlaceOneLineReviewStat( + val content: String, + val count: Long, +) diff --git a/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/GetOneLineReviewStatsUseCase.kt b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/GetOneLineReviewStatsUseCase.kt new file mode 100644 index 0000000..4490b32 --- /dev/null +++ b/src/main/kotlin/kr/wooco/woocobe/place/domain/usecase/GetOneLineReviewStatsUseCase.kt @@ -0,0 +1,26 @@ +package kr.wooco.woocobe.place.domain.usecase + +import kr.wooco.woocobe.common.domain.usecase.UseCase +import kr.wooco.woocobe.place.domain.gateway.PlaceOneLineReviewStorageGateway +import kr.wooco.woocobe.place.domain.model.PlaceOneLineReviewStat + +data class GetOneLineReviewStatsInput( + val placeId: Long, +) + +data class GetOneLineReviewStatsOutput( + val placeOneLineReviewRank: List, +) + +class GetOneLineReviewStatsUseCase( + private val placeOneLineReviewStorageGateway: PlaceOneLineReviewStorageGateway, +) : UseCase { + override fun execute(input: GetOneLineReviewStatsInput): GetOneLineReviewStatsOutput { + val placeOneLineReviewRank = + placeOneLineReviewStorageGateway.getOneLineReviewStats(input.placeId) + + return GetOneLineReviewStatsOutput( + placeOneLineReviewRank = placeOneLineReviewRank, + ) + } +} diff --git a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceOneLineReviewStorageGateway.kt b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceOneLineReviewStorageGateway.kt new file mode 100644 index 0000000..52477cd --- /dev/null +++ b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceOneLineReviewStorageGateway.kt @@ -0,0 +1,24 @@ +package kr.wooco.woocobe.place.infrastructure.gateway + +import kr.wooco.woocobe.place.domain.gateway.PlaceOneLineReviewStorageGateway +import kr.wooco.woocobe.place.domain.model.PlaceOneLineReviewStat +import kr.wooco.woocobe.place.infrastructure.storage.PlaceOneLineReviewJpaRepository +import org.springframework.stereotype.Component + +@Component +class JpaPlaceOneLineReviewStorageGateway( + private val placeOneLineReviewRepository: PlaceOneLineReviewJpaRepository, +) : PlaceOneLineReviewStorageGateway { + override fun getOneLineReviewStats(placeId: Long): List { + val stats = placeOneLineReviewRepository.findPlaceOneLineReviewStatsByPlaceId(placeId) + return stats.map { row -> + val content = row["content"] ?: throw RuntimeException() + val count = row["count"] ?: throw RuntimeException() + + PlaceOneLineReviewStat( + content = content.toString(), + count = count, + ) + } + } +} diff --git a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceReviewStorageGateway.kt b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceReviewStorageGateway.kt index 91a8ea2..87a2c92 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceReviewStorageGateway.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/gateway/JpaPlaceReviewStorageGateway.kt @@ -24,6 +24,7 @@ class JpaPlaceReviewStorageGateway( placeReview.oneLineReviews .map { PlaceOneLineReviewEntity.of( + placeId = placeReviewEntity.placeId, placeReviewId = placeReviewEntity.id!!, content = it.content, ) @@ -55,7 +56,9 @@ class JpaPlaceReviewStorageGateway( map { placeReviewEntity -> placeReviewEntity.toDomain( user = userEntities.find { placeReviewEntity.userId == it.id }!!.toDomain(), - place = placeEntities.find { placeReviewEntity.placeId == it.id }!!.toDomain(), + place = placeEntities + .find { placeReviewEntity.placeId == it.id }!! + .toDomain(), placeOneLineReview = placeOneLineReviewEntities .filter { placeReviewEntity.id == it.placeReviewId } .map { it.toDomain() }, @@ -74,7 +77,9 @@ class JpaPlaceReviewStorageGateway( map { placeReviewEntity -> placeReviewEntity.toDomain( user = userEntity.find { placeReviewEntity.userId == it.id }!!.toDomain(), - place = placeJpaRepository.findByIdOrNull(placeReviewEntity.placeId)!!.toDomain(), + place = placeJpaRepository + .findByIdOrNull(placeReviewEntity.placeId)!! + .toDomain(), placeOneLineReview = placeOneLineReviewEntity .filter { placeReviewEntity.id == it.placeReviewId } .map { it.toDomain() }, @@ -93,7 +98,9 @@ class JpaPlaceReviewStorageGateway( map { placeReviewEntity -> placeReviewEntity.toDomain( user = userEntity.toDomain(), - place = placeJpaRepository.findByIdOrNull(placeReviewEntity.placeId)!!.toDomain(), + place = placeJpaRepository + .findByIdOrNull(placeReviewEntity.placeId)!! + .toDomain(), placeOneLineReview = placeOneLineReviewEntity .filter { placeReviewEntity.id == it.placeReviewId } .map { it.toDomain() }, diff --git a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt index 7bec58c..07c4287 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt @@ -1,9 +1,24 @@ package kr.wooco.woocobe.place.infrastructure.storage import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.query.Param interface PlaceOneLineReviewJpaRepository : JpaRepository { fun findAllByPlaceReviewIdOrderByCreatedAt(placeReviewId: Long): List fun findAllByPlaceReviewIdInOrderByCreatedAt(placeReviewId: List): List + + @Query( + """ + select r.content as content, count(r.content) as count + from PlaceOneLineReviewEntity r + where r.placeId = :placeId + group by r.content + order by count desc + """, + ) + fun findPlaceOneLineReviewStatsByPlaceId( + @Param("placeId") placeId: Long, + ): List> } From e2878d45c946c14ce6f22c6258a3b9bdef959113 Mon Sep 17 00:00:00 2001 From: Namgyu11 <103015031+Namgyu11@users.noreply.github.com> Date: Sun, 29 Dec 2024 00:26:27 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20@Param=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=A0=9C=EA=B1=B0=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storage/PlaceOneLineReviewJpaRepository.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt index 07c4287..0af639a 100644 --- a/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt +++ b/src/main/kotlin/kr/wooco/woocobe/place/infrastructure/storage/PlaceOneLineReviewJpaRepository.kt @@ -2,7 +2,6 @@ package kr.wooco.woocobe.place.infrastructure.storage import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query -import org.springframework.data.repository.query.Param interface PlaceOneLineReviewJpaRepository : JpaRepository { fun findAllByPlaceReviewIdOrderByCreatedAt(placeReviewId: Long): List @@ -18,7 +17,5 @@ interface PlaceOneLineReviewJpaRepository : JpaRepository> + fun findPlaceOneLineReviewStatsByPlaceId(placeId: Long): List> }