From 7333b5d755df86a230cfde6e06d23e790c3fd6e9 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 18:49:09 +0900 Subject: [PATCH 01/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20validate=EC=97=90=20isActive=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index d000fe4..fd9f0ae 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -97,7 +97,8 @@ class CreatorAdminContentSeriesService( request.genreId == null && request.isAdult == null && request.writer == null && - request.studio == null + request.studio == null && + request.isActive == null ) { throw SodaException("변경사항이 없습니다.") } -- 2.40.1 From 5f607e2b75624c214d35ba36608e34f5da920fc3 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 19:31:57 +0900 Subject: [PATCH 02/35] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EA=B4=80=EB=A6=AC=EC=9E=90=20-=20=EC=8B=9C?= =?UTF-8?q?=EB=A6=AC=EC=A6=88=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20-=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=EA=B0=92=EC=97=90=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EC=B6=94=EA=B0=80(=EC=86=8C=EA=B0=9C,=20?= =?UTF-8?q?=EC=97=B0=EC=9E=AC=EC=9A=94=EC=9D=BC,=20=EC=9E=A5=EB=A5=B4,=20?= =?UTF-8?q?=EC=97=B0=EB=A0=B9=EC=A0=9C=ED=95=9C=EC=97=AC=EB=B6=80,=20?= =?UTF-8?q?=EC=99=84=EA=B2=B0=EC=97=AC=EB=B6=80,=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20=EC=97=AC=EB=B6=80,=20=EC=9E=91=EA=B0=80,=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91=EC=82=AC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CreatorAdminContentSeriesRepository.kt | 19 +++++-------------- .../CreatorAdminContentSeriesService.kt | 18 ++++++++++++++++-- ...etCreatorAdminContentSeriesListResponse.kt | 14 ++++++++++---- .../content/series/ModifySeriesRequest.kt | 1 + 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt index 14fd766..22b8cf9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt @@ -14,9 +14,8 @@ interface CreatorAdminContentSeriesQueryRepository { fun getSeriesList( offset: Long, limit: Long, - creatorId: Long, - imageHost: String - ): List + creatorId: Long + ): List fun getSeriesContentCount(creatorId: Long): Int fun getSeriesContentList( @@ -55,18 +54,10 @@ class CreatorAdminContentSeriesQueryRepositoryImpl( override fun getSeriesList( offset: Long, limit: Long, - creatorId: Long, - imageHost: String - ): List { + creatorId: Long + ): List { return queryFactory - .select( - QGetCreatorAdminContentSeriesListItem( - series.id, - series.title, - series.coverImage.prepend("/").prepend(imageHost) - ) - ) - .from(series) + .selectFrom(series) .where( series.member.id.eq(creatorId) .and(series.isActive.isTrue) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index fd9f0ae..a9f0f10 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -170,9 +170,23 @@ class CreatorAdminContentSeriesService( val seriesList = repository.getSeriesList( offset = offset, limit = limit, - creatorId = creatorId, - imageHost = coverImageHost + creatorId = creatorId ) + .map { + GetCreatorAdminContentSeriesListItem( + seriesId = it.id!!, + title = it.title, + introduction = it.introduction, + coverImageUrl = "$coverImageHost/${it.coverImage!!}", + publishedDaysOfWeek = it.publishedDaysOfWeek.toList(), + genreId = it.genre!!.id!!, + isAdult = it.isAdult, + state = it.state, + isActive = it.isActive, + writer = it.writer, + studio = it.studio + ) + } return GetCreatorAdminContentSeriesListResponse(totalCount, seriesList) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesListResponse.kt index da32444..f7c6484 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesListResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesListResponse.kt @@ -1,14 +1,20 @@ package kr.co.vividnext.sodalive.creator.admin.content.series -import com.querydsl.core.annotations.QueryProjection - data class GetCreatorAdminContentSeriesListResponse( val totalCount: Int, val items: List ) -data class GetCreatorAdminContentSeriesListItem @QueryProjection constructor( +data class GetCreatorAdminContentSeriesListItem( val seriesId: Long, val title: String, - val coverImageUrl: String + val introduction: String, + val coverImageUrl: String, + val publishedDaysOfWeek: List, + val genreId: Long, + val isAdult: Boolean, + val state: SeriesState, + val isActive: Boolean, + val writer: String?, + val studio: String? ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/ModifySeriesRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/ModifySeriesRequest.kt index 4057c55..f51b4cb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/ModifySeriesRequest.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/ModifySeriesRequest.kt @@ -7,6 +7,7 @@ data class ModifySeriesRequest( val publishedDaysOfWeek: Set?, val genreId: Long?, val isAdult: Boolean?, + val state: SeriesState?, val isActive: Boolean?, val writer: String?, val studio: String? -- 2.40.1 From a438aae9bcff60534dcca42cbd7e63f2a2bfe107 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 19:49:43 +0900 Subject: [PATCH 03/35] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EA=B4=80=EB=A6=AC=EC=9E=90=20-=20=EC=8B=9C?= =?UTF-8?q?=EB=A6=AC=EC=A6=88=20=EB=93=B1=EB=A1=9D=20-=20=ED=82=A4?= =?UTF-8?q?=EC=9B=8C=EB=93=9C=20=EB=93=B1=EB=A1=9D=EC=8B=9C=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EB=93=B1=EB=A1=9D=EC=9D=B4=20=EB=90=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index a9f0f10..c8b4bb8 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -67,7 +67,7 @@ class CreatorAdminContentSeriesService( seriesKeyword } - series.keywordList.addAll(keywords) + series.keywordList.addAll(keywords.toSet()) val metadata = ObjectMetadata() metadata.contentLength = coverImage.size -- 2.40.1 From 2792caa387a41b7a5e2068928a817f47d281218d Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 19:57:41 +0900 Subject: [PATCH 04/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20-=20?= =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98=EC=A0=95=EC=8B=9C=20?= =?UTF-8?q?=EC=97=B0=EC=9E=AC=EC=9A=94=EC=9D=BC=EC=9D=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95(=EC=97=B0=EC=9E=AC=EC=9A=94?= =?UTF-8?q?=EC=9D=BC=EC=9D=84=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=EC=97=90=20Cascade=20=EC=A1=B0=EA=B1=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vividnext/sodalive/creator/admin/content/series/Series.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt index c801f13..496c4fc 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt @@ -4,6 +4,7 @@ import kr.co.vividnext.sodalive.admin.content.series.genre.SeriesGenre import kr.co.vividnext.sodalive.common.BaseEntity import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.SeriesKeyword import kr.co.vividnext.sodalive.member.Member +import org.hibernate.annotations.Cascade import javax.persistence.CascadeType import javax.persistence.CollectionTable import javax.persistence.Column @@ -37,6 +38,7 @@ data class Series( @ElementCollection(targetClass = SeriesPublishedDaysOfWeek::class, fetch = FetchType.EAGER) @Enumerated(value = EnumType.STRING) @CollectionTable(name = "series_published_days_of_week", joinColumns = [JoinColumn(name = "series_id")]) + @Cascade(value = [org.hibernate.annotations.CascadeType.ALL]) val publishedDaysOfWeek: Set = mutableSetOf(), var isAdult: Boolean = false, var isActive: Boolean = true -- 2.40.1 From 42e55c061702073b2f23df14baa118c661ec7dfe Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 20:35:25 +0900 Subject: [PATCH 05/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20=EC=99=84=EA=B2=B0=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index c8b4bb8..28fbdea 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -96,6 +96,7 @@ class CreatorAdminContentSeriesService( request.publishedDaysOfWeek == null && request.genreId == null && request.isAdult == null && + request.state == null && request.writer == null && request.studio == null && request.isActive == null @@ -152,6 +153,10 @@ class CreatorAdminContentSeriesService( series.isAdult = request.isAdult } + if (request.state != null) { + series.state = request.state + } + if (request.isActive != null) { series.isActive = request.isActive } -- 2.40.1 From 92c19092fe45c66a761b42d8218847bb54066918 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 21:00:36 +0900 Subject: [PATCH 06/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EC=8B=9C=20=EC=97=B0=EC=9E=AC=EC=9A=94=EC=9D=BC?= =?UTF-8?q?=EC=9D=B4=20=EC=88=98=EC=A0=95=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95(=EC=97=B0?= =?UTF-8?q?=EC=9E=AC=EC=9A=94=EC=9D=BC=EC=9D=84=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=95=84=EB=93=9C=EC=97=90=20Cascade=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 4 ++-- .../vividnext/sodalive/creator/admin/content/series/Series.kt | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index 28fbdea..b60a799 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -140,8 +140,8 @@ class CreatorAdminContentSeriesService( throw SodaException("랜덤과 연재요일 동시에 선택할 수 없습니다.") } - series.publishedDaysOfWeek.toMutableSet().clear() - series.publishedDaysOfWeek.toMutableSet().addAll(request.publishedDaysOfWeek) + series.publishedDaysOfWeek.clear() + series.publishedDaysOfWeek.addAll(request.publishedDaysOfWeek) } if (request.genreId != null) { diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt index 496c4fc..c8262a0 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt @@ -4,7 +4,6 @@ import kr.co.vividnext.sodalive.admin.content.series.genre.SeriesGenre import kr.co.vividnext.sodalive.common.BaseEntity import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.SeriesKeyword import kr.co.vividnext.sodalive.member.Member -import org.hibernate.annotations.Cascade import javax.persistence.CascadeType import javax.persistence.CollectionTable import javax.persistence.Column @@ -38,8 +37,7 @@ data class Series( @ElementCollection(targetClass = SeriesPublishedDaysOfWeek::class, fetch = FetchType.EAGER) @Enumerated(value = EnumType.STRING) @CollectionTable(name = "series_published_days_of_week", joinColumns = [JoinColumn(name = "series_id")]) - @Cascade(value = [org.hibernate.annotations.CascadeType.ALL]) - val publishedDaysOfWeek: Set = mutableSetOf(), + val publishedDaysOfWeek: MutableSet = mutableSetOf(), var isAdult: Boolean = false, var isActive: Boolean = true ) : BaseEntity() { -- 2.40.1 From 091ed270b026f3ac3b8afb832b87ffbc52990f26 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 21:04:13 +0900 Subject: [PATCH 07/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EC=8B=9C=20=EC=97=B0=EC=9E=AC=EC=9A=94=EC=9D=BC?= =?UTF-8?q?=EC=9D=B4=20=EC=88=98=EC=A0=95=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95(=EC=97=B0?= =?UTF-8?q?=EC=9E=AC=EC=9A=94=EC=9D=BC=EC=9D=84=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=95=84=EB=93=9C=EC=97=90=20Cascade=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../creator/admin/content/series/CreateSeriesRequest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreateSeriesRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreateSeriesRequest.kt index 658c1cc..c7e1a91 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreateSeriesRequest.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreateSeriesRequest.kt @@ -5,7 +5,7 @@ import kr.co.vividnext.sodalive.common.SodaException data class CreateSeriesRequest( val title: String, val introduction: String, - val publishedDaysOfWeek: Set, + val publishedDaysOfWeek: MutableSet, val keyword: String, val genreId: Long = 0, val isAdult: Boolean = false, -- 2.40.1 From 9a80979a422b221f1c31beeca850c84033a26502 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 22:55:14 +0900 Subject: [PATCH 08/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20-=20keyword=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index b60a799..73ff878 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -50,6 +50,7 @@ class CreatorAdminContentSeriesService( .split(" ") .map { it.trim() } .filter { it.isNotBlank() } + .toSet() .map { val tag = if (!it.startsWith("#")) { "#$it" @@ -67,7 +68,7 @@ class CreatorAdminContentSeriesService( seriesKeyword } - series.keywordList.addAll(keywords.toSet()) + series.keywordList.addAll(keywords) val metadata = ObjectMetadata() metadata.contentLength = coverImage.size -- 2.40.1 From 3f86862ae9b30e5e22565bceb3a293f18fa834d6 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 22 Apr 2024 23:29:06 +0900 Subject: [PATCH 09/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20-=20keyword=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../series/CreatorAdminContentSeriesService.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index 73ff878..49b6f63 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -48,18 +48,20 @@ class CreatorAdminContentSeriesService( val keywords = request.keyword .replace("#", " #") .split(" ") + .asSequence() .map { it.trim() } .filter { it.isNotBlank() } - .toSet() .map { - val tag = if (!it.startsWith("#")) { + if (!it.startsWith("#")) { "#$it" } else { it } - - val hashTag = hashTagRepository.findByTag(tag) - ?: hashTagRepository.save(HashTag(tag)) + } + .toSet() + .map { + val hashTag = hashTagRepository.findByTag(it) + ?: hashTagRepository.save(HashTag(it)) val seriesKeyword = SeriesKeyword() seriesKeyword.series = series @@ -67,6 +69,7 @@ class CreatorAdminContentSeriesService( seriesKeyword } + .toList() series.keywordList.addAll(keywords) -- 2.40.1 From 05c293ed6d984d1b42666fd7055c92d6fd720b11 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 23 Apr 2024 18:30:17 +0900 Subject: [PATCH 10/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20-=20=EC=BB=A4=EB=B2=84=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=20=EB=92=A4=EC=97=90=20!!=EA=B0=80=20=EC=9E=98=EB=AA=BB?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EA=B0=80=EB=8D=98=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../series/GetCreatorAdminContentSeriesDetailResponse.kt | 2 +- .../vividnext/sodalive/creator/admin/content/series/Series.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesDetailResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesDetailResponse.kt index 9cc2271..436b7fe 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesDetailResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/GetCreatorAdminContentSeriesDetailResponse.kt @@ -4,7 +4,7 @@ data class GetCreatorAdminContentSeriesDetailResponse( val seriesId: Long, val title: String, val introduction: String, - val coverImage: String, + val coverImageUrl: String, val publishedDaysOfWeek: String, val genre: String, val keywords: String, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt index c8262a0..ca2ef30 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt @@ -62,7 +62,7 @@ data class Series( seriesId = id!!, title = title, introduction = introduction, - coverImage = "$imageHost/$coverImage!!", + coverImageUrl = "$imageHost/${coverImage!!}", publishedDaysOfWeek = publishedDaysOfWeekText(), genre = genre!!.genre, keywords = keywordList.map { it.keyword!!.tag }.joinToString(" ") { it }, -- 2.40.1 From 2847cffa76cb26e1c66e69a7a0b855beb1e70a3b Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 24 Apr 2024 00:19:44 +0900 Subject: [PATCH 11/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=A0=9C=EA=B1=B0=20-=20removeIf=EB=A5=BC?= =?UTF-8?q?=20=EC=9D=B4=EC=9A=A9=ED=95=98=EC=97=AC=20=EC=BD=98=ED=85=90?= =?UTF-8?q?=EC=B8=A0=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=96=88=EC=A7=80?= =?UTF-8?q?=EB=A7=8C=20=EC=A0=9C=EA=B1=B0=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8D=98=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index 49b6f63..09504af 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -253,6 +253,7 @@ class CreatorAdminContentSeriesService( val series = repository.findByIdAndCreatorId(id = request.seriesId, creatorId = memberId) ?: throw SodaException("잘못된 접근입니다.") - series.contentList.removeIf { it.content!!.id == request.contentId } + val removeContentList = series.contentList.filter { it.content!!.id == request.contentId } + series.contentList.removeAll(removeContentList) } } -- 2.40.1 From 0acf98aef36bb09224cbb97ae6ec79617d3b78bd Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 24 Apr 2024 00:33:23 +0900 Subject: [PATCH 12/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=A0=9C=EA=B1=B0=20-=20removeIf=EB=A5=BC?= =?UTF-8?q?=20=EC=9D=B4=EC=9A=A9=ED=95=98=EC=97=AC=20=EC=BD=98=ED=85=90?= =?UTF-8?q?=EC=B8=A0=EB=A5=BC=20=EC=A0=9C=EA=B1=B0=ED=96=88=EC=A7=80?= =?UTF-8?q?=EB=A7=8C=20=EC=A0=9C=EA=B1=B0=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8D=98=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 3 +-- .../vividnext/sodalive/creator/admin/content/series/Series.kt | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index 09504af..49b6f63 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -253,7 +253,6 @@ class CreatorAdminContentSeriesService( val series = repository.findByIdAndCreatorId(id = request.seriesId, creatorId = memberId) ?: throw SodaException("잘못된 접근입니다.") - val removeContentList = series.contentList.filter { it.content!!.id == request.contentId } - series.contentList.removeAll(removeContentList) + series.contentList.removeIf { it.content!!.id == request.contentId } } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt index ca2ef30..00c9866 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt @@ -51,10 +51,10 @@ data class Series( var coverImage: String? = null - @OneToMany(mappedBy = "series", cascade = [CascadeType.ALL]) + @OneToMany(mappedBy = "series", cascade = [CascadeType.ALL], orphanRemoval = true) var contentList: MutableList = mutableListOf() - @OneToMany(mappedBy = "series", cascade = [CascadeType.ALL]) + @OneToMany(mappedBy = "series", cascade = [CascadeType.ALL], orphanRemoval = true) var keywordList: MutableList = mutableListOf() fun toDetailResponse(imageHost: String): GetCreatorAdminContentSeriesDetailResponse { -- 2.40.1 From 0c325185fb9596407fd0866cd1e5c487d7e067f3 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 24 Apr 2024 01:35:23 +0900 Subject: [PATCH 13/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=B6=94=EA=B0=80=20-=20=EC=8B=9C?= =?UTF-8?q?=EB=A6=AC=EC=A6=88=20=EC=BD=98=ED=85=90=EC=B8=A0=EB=A5=BC=20?= =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=EC=97=90=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=A0=20=EB=95=8C=20set=20=ED=83=80=EC=9E=85=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=ED=99=98=ED=95=98=EC=97=AC=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/series/CreatorAdminContentSeriesService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index 49b6f63..5a12f83 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -242,7 +242,7 @@ class CreatorAdminContentSeriesService( } if (seriesContentList.size > 0) { - series.contentList.addAll(seriesContentList) + series.contentList.addAll(seriesContentList.toSet()) } else { throw SodaException("추가된 콘텐츠가 없습니다.") } -- 2.40.1 From 613298bdeae23b5987d707b2fc25588dbc3440bb Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 24 Apr 2024 12:51:19 +0900 Subject: [PATCH 14/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=A1=B0=ED=9A=8C=20-=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20=EC=8B=9C=EB=A6=AC=EC=A6=88=EC=9D=98=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=EB=A7=8C=20=EC=A1=B0=ED=9A=8C=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/CreatorAdminContentSeriesRepository.kt | 3 +++ .../admin/content/series/CreatorAdminContentSeriesService.kt | 1 + 2 files changed, 4 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt index 22b8cf9..bb8d784 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt @@ -21,6 +21,7 @@ interface CreatorAdminContentSeriesQueryRepository { fun getSeriesContentList( offset: Long, limit: Long, + seriesId: Long, creatorId: Long, imageHost: String ): List @@ -86,6 +87,7 @@ class CreatorAdminContentSeriesQueryRepositoryImpl( override fun getSeriesContentList( offset: Long, limit: Long, + seriesId: Long, creatorId: Long, imageHost: String ): List { @@ -103,6 +105,7 @@ class CreatorAdminContentSeriesQueryRepositoryImpl( .innerJoin(seriesContent.content, audioContent) .where( series.member.id.eq(creatorId) + .and(series.id.eq(seriesId)) .and(audioContent.member.id.eq(creatorId)) .and(series.isActive.isTrue) ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index 5a12f83..08e5d0e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -217,6 +217,7 @@ class CreatorAdminContentSeriesService( val seriesContentList = repository.getSeriesContentList( offset = offset, limit = limit, + seriesId = seriesId, creatorId = creatorId, imageHost = coverImageHost ) -- 2.40.1 From 9bc1c610acf6e8941c2bf2b3eb92279feeb23335 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 24 Apr 2024 14:07:09 +0900 Subject: [PATCH 15/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=EC=97=90=20?= =?UTF-8?q?=EC=86=8D=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=B0=BE=EA=B8=B0=20API=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 --- .../CreatorAdminContentSeriesController.kt | 18 +++++++++ .../CreatorAdminContentSeriesRepository.kt | 40 +++++++++++++++++++ .../CreatorAdminContentSeriesService.kt | 14 +++++++ .../SearchContentNotInSeriesResponse.kt | 9 +++++ 4 files changed, 81 insertions(+) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/content/SearchContentNotInSeriesResponse.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesController.kt index ce1adfd..0785176 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesController.kt @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PutMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RequestPart import org.springframework.web.bind.annotation.RestController import org.springframework.web.multipart.MultipartFile @@ -116,4 +117,21 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte "콘텐츠를 삭제하였습니다." ) } + + @GetMapping("/content/search") + fun searchContentNotInSeries( + @RequestParam(value = "series_id") seriesId: Long, + @RequestParam(value = "search_word") searchWord: String, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok( + service.searchContentNotInSeries( + seriesId = seriesId, + searchWord = searchWord, + memberId = member.id!! + ) + ) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt index bb8d784..f391285 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesRepository.kt @@ -4,6 +4,8 @@ import com.querydsl.jpa.impl.JPAQueryFactory import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent +import kr.co.vividnext.sodalive.creator.admin.content.series.content.QSearchContentNotInSeriesResponse +import kr.co.vividnext.sodalive.creator.admin.content.series.content.SearchContentNotInSeriesResponse import org.springframework.data.jpa.repository.JpaRepository interface CreatorAdminContentSeriesRepository : JpaRepository, CreatorAdminContentSeriesQueryRepository @@ -25,6 +27,13 @@ interface CreatorAdminContentSeriesQueryRepository { creatorId: Long, imageHost: String ): List + + fun searchContentNotInSeries( + seriesId: Long, + searchWord: String, + memberId: Long, + imageHost: String + ): List } class CreatorAdminContentSeriesQueryRepositoryImpl( @@ -113,4 +122,35 @@ class CreatorAdminContentSeriesQueryRepositoryImpl( .limit(limit) .fetch() } + + override fun searchContentNotInSeries( + seriesId: Long, + searchWord: String, + memberId: Long, + imageHost: String + ): List { + return queryFactory + .select( + QSearchContentNotInSeriesResponse( + audioContent.id, + audioContent.title, + audioContent.coverImage.prepend("/").prepend(imageHost) + ) + ) + .from(audioContent) + .leftJoin(seriesContent) + .on( + audioContent.id.eq(seriesContent.content.id) + .and(seriesContent.series.id.eq(seriesId)) + ) + .where( + audioContent.duration.isNotNull + .and(audioContent.member.isNotNull) + .and(audioContent.member.id.eq(memberId)) + .and(audioContent.isActive.isTrue.or(audioContent.releaseDate.isNotNull)) + .and(audioContent.title.contains(searchWord)) + .and(seriesContent.id.isNull) + ) + .fetch() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt index 08e5d0e..b0317bc 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/CreatorAdminContentSeriesService.kt @@ -9,6 +9,7 @@ import kr.co.vividnext.sodalive.content.hashtag.HashTag import kr.co.vividnext.sodalive.content.hashtag.HashTagRepository import kr.co.vividnext.sodalive.creator.admin.content.series.content.AddingContentToTheSeriesRequest import kr.co.vividnext.sodalive.creator.admin.content.series.content.RemoveContentToTheSeriesRequest +import kr.co.vividnext.sodalive.creator.admin.content.series.content.SearchContentNotInSeriesResponse import kr.co.vividnext.sodalive.creator.admin.content.series.genre.CreatorAdminContentSeriesGenreRepository import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.SeriesKeyword import kr.co.vividnext.sodalive.member.Member @@ -256,4 +257,17 @@ class CreatorAdminContentSeriesService( series.contentList.removeIf { it.content!!.id == request.contentId } } + + fun searchContentNotInSeries( + seriesId: Long, + searchWord: String, + memberId: Long + ): List { + return repository.searchContentNotInSeries( + seriesId, + searchWord, + memberId, + imageHost = coverImageHost + ) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/content/SearchContentNotInSeriesResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/content/SearchContentNotInSeriesResponse.kt new file mode 100644 index 0000000..79c9f8e --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/content/SearchContentNotInSeriesResponse.kt @@ -0,0 +1,9 @@ +package kr.co.vividnext.sodalive.creator.admin.content.series.content + +import com.querydsl.core.annotations.QueryProjection + +data class SearchContentNotInSeriesResponse @QueryProjection constructor( + val contentId: Long, + val title: String, + val coverImage: String +) -- 2.40.1 From 84007e1b72a883179904e3b836adb9784cb150d0 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 24 Apr 2024 23:54:39 +0900 Subject: [PATCH 16/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/ContentSeriesController.kt | 36 +++++++++ .../content/series/ContentSeriesRepository.kt | 81 +++++++++++++++++++ .../content/series/ContentSeriesService.kt | 59 ++++++++++++++ .../content/series/GetSeriesListRawItem.kt | 57 +++++++++++++ .../content/series/GetSeriesListResponse.kt | 24 ++++++ .../content/ContentSeriesContentRepository.kt | 65 +++++++++++++++ .../creator/admin/content/series/Series.kt | 4 + 7 files changed, 326 insertions(+) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListResponse.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt new file mode 100644 index 0000000..f7a187b --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt @@ -0,0 +1,36 @@ +package kr.co.vividnext.sodalive.content.series + +import kr.co.vividnext.sodalive.common.ApiResponse +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType +import kr.co.vividnext.sodalive.member.Member +import org.springframework.data.domain.Pageable +import org.springframework.security.core.annotation.AuthenticationPrincipal +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 + +@RestController +@RequestMapping("/audio-content/series") +class ContentSeriesController(private val service: ContentSeriesService) { + @GetMapping + fun getSeriesList( + @RequestParam creatorId: Long, + @RequestParam("sortType", required = false) sortType: SeriesSortType = SeriesSortType.NEWEST, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, + pageable: Pageable + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok( + service.getSeriesList( + creatorId = creatorId, + sortType = sortType, + member = member, + offset = pageable.offset, + limit = pageable.pageSize.toLong() + ) + ) + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt new file mode 100644 index 0000000..6aaa22f --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -0,0 +1,81 @@ +package kr.co.vividnext.sodalive.content.series + +import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre +import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series +import kr.co.vividnext.sodalive.creator.admin.content.series.Series +import kr.co.vividnext.sodalive.member.QMember.member +import org.springframework.data.jpa.repository.JpaRepository + +interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository + +interface ContentSeriesQueryRepository { + fun getSeriesTotalCount(creatorId: Long, isAuth: Boolean): Int + fun getSeriesRawItemList( + imageHost: String, + creatorId: Long, + isAuth: Boolean, + offset: Long, + limit: Long + ): List +} + +class ContentSeriesQueryRepositoryImpl( + private val queryFactory: JPAQueryFactory +) : ContentSeriesQueryRepository { + override fun getSeriesTotalCount(creatorId: Long, isAuth: Boolean): Int { + var where = series.member.id.eq(creatorId) + .and(series.isActive.isTrue) + + if (!isAuth) { + where = where.and(series.isAdult.isFalse) + } + + return queryFactory + .select(series.id) + .from(series) + .where(where) + .fetch() + .size + } + + override fun getSeriesRawItemList( + imageHost: String, + creatorId: Long, + isAuth: Boolean, + offset: Long, + limit: Long + ): List { + var where = series.member.id.eq(creatorId) + .and(series.isActive.isTrue) + + if (!isAuth) { + where = where.and(series.isAdult.isFalse) + } + + return queryFactory + .select( + QGetSeriesListRawItem( + series.id, + series.title, + series.coverImage.coalesce("profile/default-profile.png") + .prepend("/") + .prepend(imageHost), + series.publishedDaysOfWeek, + series.state, + series.genre.genre, + series.isAdult, + series.member.id, + series.member.nickname, + series.member.profileImage.coalesce("profile/default-profile.png") + .prepend("/") + .prepend(imageHost) + ) + ) + .from(series) + .innerJoin(series.member, member) + .innerJoin(series.genre, seriesGenre) + .where(where) + .fetch() + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt new file mode 100644 index 0000000..f7ac607 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -0,0 +1,59 @@ +package kr.co.vividnext.sodalive.content.series + +import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType +import kr.co.vividnext.sodalive.member.Member +import org.springframework.beans.factory.annotation.Value +import org.springframework.stereotype.Service +import java.time.LocalDateTime + +@Service +class ContentSeriesService( + private val repository: ContentSeriesRepository, + private val seriesContentRepository: ContentSeriesContentRepository, + + @Value("\${cloud.aws.cloud-front.host}") + private val coverImageHost: String +) { + fun getSeriesList( + creatorId: Long, + member: Member, + sortType: SeriesSortType = SeriesSortType.NEWEST, + offset: Long = 0, + limit: Long = 10 + ): GetSeriesListResponse { + val totalCount = repository.getSeriesTotalCount(creatorId = creatorId, isAuth = member.auth != null) + val rawItems = repository.getSeriesRawItemList( + imageHost = coverImageHost, + creatorId = creatorId, + isAuth = member.auth != null, + offset = offset, + limit = limit + ) + + val items = rawItems + .map { it.toSeriesListItem() } + .map { + it.numberOfContent = seriesContentRepository.getContentCount( + seriesId = it.seriesId, + isAdult = member.auth == null + ) + + it + } + .map { + val nowDateTime = LocalDateTime.now() + + it.isNew = seriesContentRepository.isNewContent( + seriesId = it.seriesId, + isAdult = member.auth == null, + fromDate = nowDateTime.minusDays(7), + nowDate = nowDateTime + ) + + it + } + + return GetSeriesListResponse(totalCount, items) + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt new file mode 100644 index 0000000..8b65f7d --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt @@ -0,0 +1,57 @@ +package kr.co.vividnext.sodalive.content.series + +import com.querydsl.core.annotations.QueryProjection +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState + +data class GetSeriesListRawItem @QueryProjection constructor( + val seriesId: Long, + val title: String, + val coverImage: String, + val publishedDaysOfWeek: Set, + val state: SeriesState, + val genre: String, + val isAdult: Boolean, + val creatorId: Long, + val creatorNickname: String, + val creatorProfileImage: String + +) { + fun toSeriesListItem(): GetSeriesListResponse.SeriesListItem { + return GetSeriesListResponse.SeriesListItem( + seriesId = seriesId, + title = title, + coverImage = coverImage, + publishedDaysOfWeek = publishedDaysOfWeekText(), + isComplete = state == SeriesState.COMPLETE, + creator = GetSeriesListResponse.SeriesListItemCreator( + creatorId = creatorId, + nickname = creatorNickname, + profileImage = creatorProfileImage + ) + ) + } + + private fun publishedDaysOfWeekText(): String { + val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal } + .map { + when (it) { + SeriesPublishedDaysOfWeek.SUN -> "일" + SeriesPublishedDaysOfWeek.MON -> "월" + SeriesPublishedDaysOfWeek.TUE -> "화" + SeriesPublishedDaysOfWeek.WED -> "수" + SeriesPublishedDaysOfWeek.THU -> "목" + SeriesPublishedDaysOfWeek.FRI -> "금" + SeriesPublishedDaysOfWeek.SAT -> "토" + SeriesPublishedDaysOfWeek.RANDOM -> "랜덤" + } + } + .joinToString(", ") { it } + + return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) { + dayOfWeekText + } else { + "매주 ${dayOfWeekText}요일" + } + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListResponse.kt new file mode 100644 index 0000000..f83b40c --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListResponse.kt @@ -0,0 +1,24 @@ +package kr.co.vividnext.sodalive.content.series + +data class GetSeriesListResponse( + val totalCount: Int, + val items: List +) { + data class SeriesListItem( + val seriesId: Long, + val title: String, + val coverImage: String, + val publishedDaysOfWeek: String, + val isComplete: Boolean = false, + val creator: SeriesListItemCreator, + var numberOfContent: Int = 0, + var isNew: Boolean = false, + var isPopular: Boolean = false + ) + + data class SeriesListItemCreator( + val creatorId: Long, + val nickname: String, + val profileImage: String + ) +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt new file mode 100644 index 0000000..e8f955a --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt @@ -0,0 +1,65 @@ +package kr.co.vividnext.sodalive.content.series.content + +import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.content.QAudioContent.audioContent +import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series +import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesContent +import org.springframework.data.jpa.repository.JpaRepository +import java.time.LocalDateTime + +interface ContentSeriesContentRepository : JpaRepository, ContentSeriesContentQueryRepository + +interface ContentSeriesContentQueryRepository { + fun getContentCount(seriesId: Long, isAdult: Boolean): Int + fun isNewContent(seriesId: Long, isAdult: Boolean, fromDate: LocalDateTime, nowDate: LocalDateTime): Boolean +} + +class ContentSeriesContentQueryRepositoryImpl( + private val queryFactory: JPAQueryFactory +) : ContentSeriesContentQueryRepository { + override fun getContentCount(seriesId: Long, isAdult: Boolean): Int { + var where = seriesContent.series.id.eq(seriesId) + .and(seriesContent.content.isActive.isTrue) + + if (!isAdult) { + where = where.and(seriesContent.content.isAdult.isFalse) + } + + return queryFactory + .select(seriesContent.id) + .from(seriesContent) + .innerJoin(seriesContent.series, series) + .innerJoin(seriesContent.content, audioContent) + .where(where) + .fetch() + .size + } + + override fun isNewContent( + seriesId: Long, + isAdult: Boolean, + fromDate: LocalDateTime, + nowDate: LocalDateTime + ): Boolean { + var where = seriesContent.series.id.eq(seriesId) + .and(seriesContent.content.isActive.isTrue) + .and(seriesContent.content.releaseDate.after(fromDate)) + .and(seriesContent.content.releaseDate.before(nowDate)) + + if (!isAdult) { + where = where.and(seriesContent.content.isAdult.isFalse) + } + + val itemCount = queryFactory + .select(seriesContent.id) + .from(seriesContent) + .innerJoin(seriesContent.series, series) + .innerJoin(seriesContent.content, audioContent) + .where(where) + .fetch() + .size + + return itemCount > 0 + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt index 00c9866..82a63f4 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/series/Series.kt @@ -25,6 +25,10 @@ enum class SeriesState { PROCEEDING, SUSPEND, COMPLETE } +enum class SeriesSortType { + NEWEST, POPULAR +} + @Entity data class Series( var title: String, -- 2.40.1 From 290c4600fa18332e19b66fc078f69c2d9e5d89ae Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 00:20:09 +0900 Subject: [PATCH 17/35] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=B1=84=EB=84=90=20-=20=EC=8B=9C=EB=A6=AC?= =?UTF-8?q?=EC=A6=88=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/vividnext/sodalive/explorer/ExplorerService.kt | 7 +++++++ .../sodalive/explorer/GetCreatorProfileResponse.kt | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt index 6186c1b..2a1515d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt @@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.explorer import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.content.AudioContentService import kr.co.vividnext.sodalive.content.SortType +import kr.co.vividnext.sodalive.content.series.ContentSeriesService import kr.co.vividnext.sodalive.explorer.follower.GetFollowerListResponse import kr.co.vividnext.sodalive.explorer.follower.GetFollowerListResponseItem import kr.co.vividnext.sodalive.explorer.profile.ChannelNotice @@ -38,6 +39,7 @@ class ExplorerService( private val cheersRepository: CreatorCheersRepository, private val noticeRepository: ChannelNoticeRepository, private val communityService: CreatorCommunityService, + private val seriesService: ContentSeriesService, private val applicationEventPublisher: ApplicationEventPublisher, @@ -252,6 +254,10 @@ class ExplorerService( val liveContributorCount = queryRepository.getLiveContributorCount(creatorId) ?: 0 val contentCount = queryRepository.getContentCount(creatorId) ?: 0 + val seriesList = seriesService + .getSeriesList(creatorId = creatorId, member = member) + .items + return GetCreatorProfileResponse( creator = CreatorResponse( creatorId = creatorAccount.id!!, @@ -283,6 +289,7 @@ class ExplorerService( liveContributorCount = liveContributorCount, contentCount = contentCount ), + seriesList = seriesList, isBlock = isBlock ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/GetCreatorProfileResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/GetCreatorProfileResponse.kt index da86441..bfdd016 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/GetCreatorProfileResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/GetCreatorProfileResponse.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.explorer import kr.co.vividnext.sodalive.content.GetAudioContentListItem +import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.GetCommunityPostListResponse data class GetCreatorProfileResponse( @@ -13,6 +14,7 @@ data class GetCreatorProfileResponse( val communityPostList: List, val cheers: GetCheersResponse, val activitySummary: GetCreatorActivitySummary, + val seriesList: List, val isBlock: Boolean ) -- 2.40.1 From 44ffe20e8881cacfe79d37dab354225258eec8ae Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 02:14:56 +0900 Subject: [PATCH 18/35] . --- .../sodalive/content/series/ContentSeriesRepository.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 6aaa22f..1148c65 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -1,10 +1,8 @@ package kr.co.vividnext.sodalive.content.series import com.querydsl.jpa.impl.JPAQueryFactory -import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.Series -import kr.co.vividnext.sodalive.member.QMember.member import org.springframework.data.jpa.repository.JpaRepository interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository @@ -73,8 +71,6 @@ class ContentSeriesQueryRepositoryImpl( ) ) .from(series) - .innerJoin(series.member, member) - .innerJoin(series.genre, seriesGenre) .where(where) .fetch() } -- 2.40.1 From 246136b1ad7124c08c31dbe1b0d8ff9abbb26a58 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 02:25:16 +0900 Subject: [PATCH 19/35] . --- .../content/series/ContentSeriesRepository.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 1148c65..6194ec2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -1,8 +1,10 @@ package kr.co.vividnext.sodalive.content.series import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.Series +import kr.co.vividnext.sodalive.member.QMember.member import org.springframework.data.jpa.repository.JpaRepository interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository @@ -56,21 +58,19 @@ class ContentSeriesQueryRepositoryImpl( QGetSeriesListRawItem( series.id, series.title, - series.coverImage.coalesce("profile/default-profile.png") - .prepend("/") - .prepend(imageHost), + series.coverImage.prepend("/").prepend(imageHost), series.publishedDaysOfWeek, series.state, series.genre.genre, series.isAdult, series.member.id, series.member.nickname, - series.member.profileImage.coalesce("profile/default-profile.png") - .prepend("/") - .prepend(imageHost) + series.member.profileImage.prepend("/").prepend(imageHost) ) ) .from(series) + .innerJoin(series.member, member) + .innerJoin(series.genre, seriesGenre) .where(where) .fetch() } -- 2.40.1 From 0d709742ed6454bbc5f0e8569f334d2c0be8b94e Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 03:03:40 +0900 Subject: [PATCH 20/35] =?UTF-8?q?org.hibernate.QueryException:=20not=20an?= =?UTF-8?q?=20entity=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 6194ec2..fe1975d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -61,11 +61,11 @@ class ContentSeriesQueryRepositoryImpl( series.coverImage.prepend("/").prepend(imageHost), series.publishedDaysOfWeek, series.state, - series.genre.genre, + seriesGenre.genre, series.isAdult, - series.member.id, - series.member.nickname, - series.member.profileImage.prepend("/").prepend(imageHost) + member.id, + member.nickname, + member.profileImage.prepend("/").prepend(imageHost) ) ) .from(series) -- 2.40.1 From c95b3db6eb0d381433ac30a8e2ae59b7dc20d9cb Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 03:22:05 +0900 Subject: [PATCH 21/35] =?UTF-8?q?DTO=EB=A1=9C=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EB=A5=BC=20=ED=96=88=EC=9D=84=20=EB=95=8C=20org.hibernate.Quer?= =?UTF-8?q?yException:=20not=20an=20entity=20=EC=98=A4=EB=A5=98=EB=82=98?= =?UTF-8?q?=EB=8D=98=20=EB=B6=80=EB=B6=84=20series=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=A1=B0=ED=9A=8C=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/ContentSeriesRepository.kt | 24 ++--------- .../content/series/ContentSeriesService.kt | 40 ++++++++++++++++++- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index fe1975d..ce1678f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -1,10 +1,8 @@ package kr.co.vividnext.sodalive.content.series import com.querydsl.jpa.impl.JPAQueryFactory -import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.Series -import kr.co.vividnext.sodalive.member.QMember.member import org.springframework.data.jpa.repository.JpaRepository interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository @@ -17,7 +15,7 @@ interface ContentSeriesQueryRepository { isAuth: Boolean, offset: Long, limit: Long - ): List + ): List } class ContentSeriesQueryRepositoryImpl( @@ -45,7 +43,7 @@ class ContentSeriesQueryRepositoryImpl( isAuth: Boolean, offset: Long, limit: Long - ): List { + ): List { var where = series.member.id.eq(creatorId) .and(series.isActive.isTrue) @@ -54,23 +52,7 @@ class ContentSeriesQueryRepositoryImpl( } return queryFactory - .select( - QGetSeriesListRawItem( - series.id, - series.title, - series.coverImage.prepend("/").prepend(imageHost), - series.publishedDaysOfWeek, - series.state, - seriesGenre.genre, - series.isAdult, - member.id, - member.nickname, - member.profileImage.prepend("/").prepend(imageHost) - ) - ) - .from(series) - .innerJoin(series.member, member) - .innerJoin(series.genre, seriesGenre) + .selectFrom(series) .where(where) .fetch() } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt index f7ac607..ca4d840 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -1,7 +1,9 @@ package kr.co.vividnext.sodalive.content.series import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState import kr.co.vividnext.sodalive.member.Member import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service @@ -32,7 +34,20 @@ class ContentSeriesService( ) val items = rawItems - .map { it.toSeriesListItem() } + .map { + GetSeriesListResponse.SeriesListItem( + seriesId = it.id!!, + title = it.title, + coverImage = "$coverImageHost/${it.coverImage!!}", + publishedDaysOfWeek = publishedDaysOfWeekText(it.publishedDaysOfWeek), + isComplete = it.state == SeriesState.COMPLETE, + creator = GetSeriesListResponse.SeriesListItemCreator( + creatorId = it.member!!.id!!, + nickname = it.member!!.nickname, + profileImage = "$coverImageHost/${it.member!!.profileImage!!}" + ) + ) + } .map { it.numberOfContent = seriesContentRepository.getContentCount( seriesId = it.seriesId, @@ -56,4 +71,27 @@ class ContentSeriesService( return GetSeriesListResponse(totalCount, items) } + + private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set): String { + val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal } + .map { + when (it) { + SeriesPublishedDaysOfWeek.SUN -> "일" + SeriesPublishedDaysOfWeek.MON -> "월" + SeriesPublishedDaysOfWeek.TUE -> "화" + SeriesPublishedDaysOfWeek.WED -> "수" + SeriesPublishedDaysOfWeek.THU -> "목" + SeriesPublishedDaysOfWeek.FRI -> "금" + SeriesPublishedDaysOfWeek.SAT -> "토" + SeriesPublishedDaysOfWeek.RANDOM -> "랜덤" + } + } + .joinToString(", ") { it } + + return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) { + dayOfWeekText + } else { + "매주 ${dayOfWeekText}요일" + } + } } -- 2.40.1 From c077f7322d1ee718c55fc11b15fc391ebeceda33 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 03:47:29 +0900 Subject: [PATCH 22/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20API=20-=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=95=84=EB=93=9C=EB=A7=8C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/ContentSeriesRepository.kt | 27 ++++++++++-- .../content/series/ContentSeriesService.kt | 42 +------------------ 2 files changed, 26 insertions(+), 43 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index ce1678f..8014b8b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -1,8 +1,10 @@ package kr.co.vividnext.sodalive.content.series import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.Series +import kr.co.vividnext.sodalive.member.QMember import org.springframework.data.jpa.repository.JpaRepository interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository @@ -15,7 +17,7 @@ interface ContentSeriesQueryRepository { isAuth: Boolean, offset: Long, limit: Long - ): List + ): List } class ContentSeriesQueryRepositoryImpl( @@ -43,7 +45,10 @@ class ContentSeriesQueryRepositoryImpl( isAuth: Boolean, offset: Long, limit: Long - ): List { + ): List { + val qMember = QMember.member + val qSeriesGenre = QSeriesGenre.seriesGenre + var where = series.member.id.eq(creatorId) .and(series.isActive.isTrue) @@ -52,7 +57,23 @@ class ContentSeriesQueryRepositoryImpl( } return queryFactory - .selectFrom(series) + .select( + QGetSeriesListRawItem( + series.id, + series.title, + series.coverImage.prepend("/").prepend(imageHost), + series.publishedDaysOfWeek, + series.state, + qSeriesGenre.genre, + series.isAdult, + qMember.id, + qMember.nickname, + qMember.profileImage.prepend("/").prepend(imageHost) + ) + ) + .from(series) + .innerJoin(series.member, qMember) + .innerJoin(series.genre, qSeriesGenre) .where(where) .fetch() } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt index ca4d840..6f08877 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -1,9 +1,7 @@ package kr.co.vividnext.sodalive.content.series import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository -import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType -import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState import kr.co.vividnext.sodalive.member.Member import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service @@ -34,24 +32,11 @@ class ContentSeriesService( ) val items = rawItems - .map { - GetSeriesListResponse.SeriesListItem( - seriesId = it.id!!, - title = it.title, - coverImage = "$coverImageHost/${it.coverImage!!}", - publishedDaysOfWeek = publishedDaysOfWeekText(it.publishedDaysOfWeek), - isComplete = it.state == SeriesState.COMPLETE, - creator = GetSeriesListResponse.SeriesListItemCreator( - creatorId = it.member!!.id!!, - nickname = it.member!!.nickname, - profileImage = "$coverImageHost/${it.member!!.profileImage!!}" - ) - ) - } + .map { it.toSeriesListItem() } .map { it.numberOfContent = seriesContentRepository.getContentCount( seriesId = it.seriesId, - isAdult = member.auth == null + isAdult = member.auth != null ) it @@ -71,27 +56,4 @@ class ContentSeriesService( return GetSeriesListResponse(totalCount, items) } - - private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set): String { - val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal } - .map { - when (it) { - SeriesPublishedDaysOfWeek.SUN -> "일" - SeriesPublishedDaysOfWeek.MON -> "월" - SeriesPublishedDaysOfWeek.TUE -> "화" - SeriesPublishedDaysOfWeek.WED -> "수" - SeriesPublishedDaysOfWeek.THU -> "목" - SeriesPublishedDaysOfWeek.FRI -> "금" - SeriesPublishedDaysOfWeek.SAT -> "토" - SeriesPublishedDaysOfWeek.RANDOM -> "랜덤" - } - } - .joinToString(", ") { it } - - return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) { - dayOfWeekText - } else { - "매주 ${dayOfWeekText}요일" - } - } } -- 2.40.1 From d3b9fd7d78a06fe8b5cbed26e940b86d5dfdcfd9 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 03:55:12 +0900 Subject: [PATCH 23/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20API=20-=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=95=84=EB=93=9C=EB=A7=8C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 8014b8b..80898f2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -56,6 +56,13 @@ class ContentSeriesQueryRepositoryImpl( where = where.and(series.isAdult.isFalse) } + println( + queryFactory.select(series.publishedDaysOfWeek) + .from(series) + .where(where) + .fetch() + ) + return queryFactory .select( QGetSeriesListRawItem( -- 2.40.1 From 7b04803aa07d3fe5ebc08dac6cb49a4a1d7d2672 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 04:31:36 +0900 Subject: [PATCH 24/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20API=20-=20DTO=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20EnumCollection=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=EC=9D=98=20=EB=AC=B8=EC=A0=9C=EB=A1=9C=20series=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/ContentSeriesRepository.kt | 38 ++----------- .../content/series/ContentSeriesService.kt | 42 +++++++++++++- .../content/series/GetSeriesListRawItem.kt | 57 ------------------- 3 files changed, 45 insertions(+), 92 deletions(-) delete mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 80898f2..9ac91e2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -1,23 +1,21 @@ package kr.co.vividnext.sodalive.content.series import com.querydsl.jpa.impl.JPAQueryFactory -import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.Series -import kr.co.vividnext.sodalive.member.QMember import org.springframework.data.jpa.repository.JpaRepository interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository interface ContentSeriesQueryRepository { fun getSeriesTotalCount(creatorId: Long, isAuth: Boolean): Int - fun getSeriesRawItemList( + fun getSeriesList( imageHost: String, creatorId: Long, isAuth: Boolean, offset: Long, limit: Long - ): List + ): List } class ContentSeriesQueryRepositoryImpl( @@ -39,16 +37,13 @@ class ContentSeriesQueryRepositoryImpl( .size } - override fun getSeriesRawItemList( + override fun getSeriesList( imageHost: String, creatorId: Long, isAuth: Boolean, offset: Long, limit: Long - ): List { - val qMember = QMember.member - val qSeriesGenre = QSeriesGenre.seriesGenre - + ): List { var where = series.member.id.eq(creatorId) .and(series.isActive.isTrue) @@ -56,31 +51,8 @@ class ContentSeriesQueryRepositoryImpl( where = where.and(series.isAdult.isFalse) } - println( - queryFactory.select(series.publishedDaysOfWeek) - .from(series) - .where(where) - .fetch() - ) - return queryFactory - .select( - QGetSeriesListRawItem( - series.id, - series.title, - series.coverImage.prepend("/").prepend(imageHost), - series.publishedDaysOfWeek, - series.state, - qSeriesGenre.genre, - series.isAdult, - qMember.id, - qMember.nickname, - qMember.profileImage.prepend("/").prepend(imageHost) - ) - ) - .from(series) - .innerJoin(series.member, qMember) - .innerJoin(series.genre, qSeriesGenre) + .selectFrom(series) .where(where) .fetch() } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt index 6f08877..e3324ba 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -1,7 +1,9 @@ package kr.co.vividnext.sodalive.content.series import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState import kr.co.vividnext.sodalive.member.Member import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service @@ -23,7 +25,7 @@ class ContentSeriesService( limit: Long = 10 ): GetSeriesListResponse { val totalCount = repository.getSeriesTotalCount(creatorId = creatorId, isAuth = member.auth != null) - val rawItems = repository.getSeriesRawItemList( + val rawItems = repository.getSeriesList( imageHost = coverImageHost, creatorId = creatorId, isAuth = member.auth != null, @@ -32,7 +34,20 @@ class ContentSeriesService( ) val items = rawItems - .map { it.toSeriesListItem() } + .map { + GetSeriesListResponse.SeriesListItem( + seriesId = it.id!!, + title = it.title, + coverImage = "$coverImageHost/${it.coverImage!!}", + publishedDaysOfWeek = publishedDaysOfWeekText(it.publishedDaysOfWeek), + isComplete = it.state == SeriesState.COMPLETE, + creator = GetSeriesListResponse.SeriesListItemCreator( + creatorId = it.member!!.id!!, + nickname = it.member!!.nickname, + profileImage = "$coverImageHost/${it.member!!.profileImage!!}" + ) + ) + } .map { it.numberOfContent = seriesContentRepository.getContentCount( seriesId = it.seriesId, @@ -56,4 +71,27 @@ class ContentSeriesService( return GetSeriesListResponse(totalCount, items) } + + private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set): String { + val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal } + .map { + when (it) { + SeriesPublishedDaysOfWeek.SUN -> "일" + SeriesPublishedDaysOfWeek.MON -> "월" + SeriesPublishedDaysOfWeek.TUE -> "화" + SeriesPublishedDaysOfWeek.WED -> "수" + SeriesPublishedDaysOfWeek.THU -> "목" + SeriesPublishedDaysOfWeek.FRI -> "금" + SeriesPublishedDaysOfWeek.SAT -> "토" + SeriesPublishedDaysOfWeek.RANDOM -> "랜덤" + } + } + .joinToString(", ") { it } + + return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) { + dayOfWeekText + } else { + "매주 ${dayOfWeekText}요일" + } + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt deleted file mode 100644 index 8b65f7d..0000000 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesListRawItem.kt +++ /dev/null @@ -1,57 +0,0 @@ -package kr.co.vividnext.sodalive.content.series - -import com.querydsl.core.annotations.QueryProjection -import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek -import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState - -data class GetSeriesListRawItem @QueryProjection constructor( - val seriesId: Long, - val title: String, - val coverImage: String, - val publishedDaysOfWeek: Set, - val state: SeriesState, - val genre: String, - val isAdult: Boolean, - val creatorId: Long, - val creatorNickname: String, - val creatorProfileImage: String - -) { - fun toSeriesListItem(): GetSeriesListResponse.SeriesListItem { - return GetSeriesListResponse.SeriesListItem( - seriesId = seriesId, - title = title, - coverImage = coverImage, - publishedDaysOfWeek = publishedDaysOfWeekText(), - isComplete = state == SeriesState.COMPLETE, - creator = GetSeriesListResponse.SeriesListItemCreator( - creatorId = creatorId, - nickname = creatorNickname, - profileImage = creatorProfileImage - ) - ) - } - - private fun publishedDaysOfWeekText(): String { - val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal } - .map { - when (it) { - SeriesPublishedDaysOfWeek.SUN -> "일" - SeriesPublishedDaysOfWeek.MON -> "월" - SeriesPublishedDaysOfWeek.TUE -> "화" - SeriesPublishedDaysOfWeek.WED -> "수" - SeriesPublishedDaysOfWeek.THU -> "목" - SeriesPublishedDaysOfWeek.FRI -> "금" - SeriesPublishedDaysOfWeek.SAT -> "토" - SeriesPublishedDaysOfWeek.RANDOM -> "랜덤" - } - } - .joinToString(", ") { it } - - return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) { - dayOfWeekText - } else { - "매주 ${dayOfWeekText}요일" - } - } -} -- 2.40.1 From b10af9d9f122c3e4f3f19f94edf04a33fffef8a7 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 25 Apr 2024 21:55:47 +0900 Subject: [PATCH 25/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20API=20-=20offset,=20l?= =?UTF-8?q?imit=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 9ac91e2..5116afb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -54,6 +54,8 @@ class ContentSeriesQueryRepositoryImpl( return queryFactory .selectFrom(series) .where(where) + .offset(offset) + .limit(limit) .fetch() } } -- 2.40.1 From 6db8013e3402d39a2521036e043bad07dc3e79a0 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 00:39:37 +0900 Subject: [PATCH 26/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/ContentSeriesController.kt | 13 +++ .../content/series/ContentSeriesRepository.kt | 104 ++++++++++++++++++ .../content/series/ContentSeriesService.kt | 34 +++++- .../content/series/GetSeriesDetailResponse.kt | 34 ++++++ .../GetSeriesContentMinMaxPriceResponse.kt | 8 ++ 5 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentMinMaxPriceResponse.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt index f7a187b..946625e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt @@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.member.Member import org.springframework.data.domain.Pageable import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController @@ -33,4 +34,16 @@ class ContentSeriesController(private val service: ContentSeriesService) { ) ) } + + @GetMapping("/{id}") + fun getSeriesDetail( + @PathVariable id: Long, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok( + service.getSeriesDetail(seriesId = id, member = member) + ) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 5116afb..6d96e6d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -1,9 +1,20 @@ package kr.co.vividnext.sodalive.content.series +import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre +import kr.co.vividnext.sodalive.content.QAudioContent.audioContent +import kr.co.vividnext.sodalive.content.hashtag.QHashTag.hashTag +import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentMinMaxPriceResponse +import kr.co.vividnext.sodalive.content.series.content.QGetSeriesContentMinMaxPriceResponse import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series +import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent import kr.co.vividnext.sodalive.creator.admin.content.series.Series +import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek +import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.QSeriesKeyword.seriesKeyword +import kr.co.vividnext.sodalive.member.QMember import org.springframework.data.jpa.repository.JpaRepository +import java.time.LocalDateTime interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository @@ -16,6 +27,11 @@ interface ContentSeriesQueryRepository { offset: Long, limit: Long ): List + + fun getSeriesDetail(seriesId: Long, isAuth: Boolean, imageHost: String): GetSeriesDetailResponse? + fun getPublishedDaysOfWeek(seriesId: Long): Set + fun getKeywordList(seriesId: Long): List + fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse } class ContentSeriesQueryRepositoryImpl( @@ -58,4 +74,92 @@ class ContentSeriesQueryRepositoryImpl( .limit(limit) .fetch() } + + override fun getSeriesDetail(seriesId: Long, isAuth: Boolean, imageHost: String): GetSeriesDetailResponse? { + val qCreator = QMember.member + var where = series.id.eq(seriesId) + .and(series.isActive.isTrue) + + if (!isAuth) { + where = where.and(series.isAdult.isFalse) + } + + val formattedDate = Expressions.stringTemplate( + "DATE_FORMAT({0}, {1})", + Expressions.dateTimeTemplate( + LocalDateTime::class.java, + "CONVERT_TZ({0},{1},{2})", + series.createdAt, + "UTC", + "Asia/Seoul" + ), + "%Y-%m-%d" + ) + + return queryFactory + .select( + QGetSeriesDetailResponse( + series.id, + series.title, + series.coverImage.prepend("/").prepend(imageHost), + series.introduction, + seriesGenre.genre, + series.isAdult, + series.writer, + series.studio, + formattedDate, + QGetSeriesDetailResponse_GetSeriesDetailCreator( + qCreator.id, + qCreator.nickname, + qCreator.profileImage.prepend("/").prepend(imageHost), + Expressions.constant(false) + ), + Expressions.constant(0), + Expressions.constant(0), + Expressions.constant(15), + Expressions.constant(0), + Expressions.constant(0), + Expressions.constant>(emptyList()), + Expressions.constant(null) + ) + ) + .from(series) + .innerJoin(series.member, qCreator) + .innerJoin(series.genre, seriesGenre) + .where(where) + .fetchFirst() + } + + override fun getPublishedDaysOfWeek(seriesId: Long): Set { + return queryFactory + .select(series.publishedDaysOfWeek) + .from(series) + .where(series.id.eq(seriesId)) + .fetchFirst() + } + + override fun getKeywordList(seriesId: Long): List { + return queryFactory + .select(hashTag.tag) + .from(series) + .innerJoin(series.keywordList, seriesKeyword).fetchJoin() + .innerJoin(seriesKeyword.keyword, hashTag) + .where(series.id.eq(seriesId)) + .fetch() + } + + override fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse { + return queryFactory + .select( + QGetSeriesContentMinMaxPriceResponse( + audioContent.price.min(), + audioContent.price.max() + ) + ) + .from(series) + .innerJoin(series.contentList, seriesContent).fetchJoin() + .innerJoin(seriesContent.content, audioContent) + .where(series.id.eq(seriesId)) + .fetchFirst() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt index e3324ba..d6c9e27 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -1,9 +1,11 @@ package kr.co.vividnext.sodalive.content.series +import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState +import kr.co.vividnext.sodalive.explorer.ExplorerQueryRepository import kr.co.vividnext.sodalive.member.Member import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service @@ -12,6 +14,7 @@ import java.time.LocalDateTime @Service class ContentSeriesService( private val repository: ContentSeriesRepository, + private val explorerQueryRepository: ExplorerQueryRepository, private val seriesContentRepository: ContentSeriesContentRepository, @Value("\${cloud.aws.cloud-front.host}") @@ -72,6 +75,35 @@ class ContentSeriesService( return GetSeriesListResponse(totalCount, items) } + fun getSeriesDetail(seriesId: Long, member: Member): GetSeriesDetailResponse { + val seriesDetail = repository.getSeriesDetail( + seriesId = seriesId, + isAuth = member.auth != null, + imageHost = coverImageHost + ) ?: throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요") + + seriesDetail.creator.isFollow = explorerQueryRepository.isFollow( + creatorId = seriesDetail.creator.creatorId, + memberId = member.id!! + ) + + seriesDetail.publishedDaysOfWeek = publishedDaysOfWeekText( + repository.getPublishedDaysOfWeek(seriesId = seriesId) + ) + + seriesDetail.keywordList = repository.getKeywordList(seriesId = seriesId) + .filter { it.isNotBlank() } + + val minMaxPrice = repository.getSeriesContentMinMaxPrice(seriesId = seriesId) + seriesDetail.minPrice = minMaxPrice.minPrice + seriesDetail.maxPrice = minMaxPrice.maxPrice + seriesDetail.rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt() + seriesDetail.rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt() + + if (!seriesDetail.validate()) throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요") + return seriesDetail + } + private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set): String { val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal } .map { @@ -91,7 +123,7 @@ class ContentSeriesService( return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) { dayOfWeekText } else { - "매주 ${dayOfWeekText}요일" + "매주 $dayOfWeekText" } } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt new file mode 100644 index 0000000..ffbb94e --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt @@ -0,0 +1,34 @@ +package kr.co.vividnext.sodalive.content.series + +import com.querydsl.core.annotations.QueryProjection + +data class GetSeriesDetailResponse @QueryProjection constructor( + val seriesId: Long, + val title: String, + val coverImage: String, + val introduction: String, + val genre: String, + val isAdult: Boolean, + val writer: String?, + val studio: String?, + val publishedDate: String, + val creator: GetSeriesDetailCreator, + var rentalMinPrice: Int, + var rentalMaxPrice: Int, + val rentalPeriod: Int, + var minPrice: Int, + var maxPrice: Int, + var keywordList: List, + var publishedDaysOfWeek: String? +) { + data class GetSeriesDetailCreator @QueryProjection constructor( + val creatorId: Long, + val nickname: String, + val coverImage: String, + var isFollow: Boolean + ) + + fun validate(): Boolean { + return keywordList.isNotEmpty() && !publishedDaysOfWeek.isNullOrBlank() + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentMinMaxPriceResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentMinMaxPriceResponse.kt new file mode 100644 index 0000000..ff19274 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentMinMaxPriceResponse.kt @@ -0,0 +1,8 @@ +package kr.co.vividnext.sodalive.content.series.content + +import com.querydsl.core.annotations.QueryProjection + +data class GetSeriesContentMinMaxPriceResponse @QueryProjection constructor( + val minPrice: Int, + val maxPrice: Int +) -- 2.40.1 From 86e15d41555f3e240d3e4aa56cac9188718772cb Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 02:31:44 +0900 Subject: [PATCH 27/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 6d96e6d..5e4d286 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -120,7 +120,7 @@ class ContentSeriesQueryRepositoryImpl( Expressions.constant(0), Expressions.constant(0), Expressions.constant>(emptyList()), - Expressions.constant(null) + null ) ) .from(series) -- 2.40.1 From 1b49e3837c01e07f5d6264bf1157eef62fc3f450 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 03:05:30 +0900 Subject: [PATCH 28/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 5e4d286..ea9bb41 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -120,7 +120,7 @@ class ContentSeriesQueryRepositoryImpl( Expressions.constant(0), Expressions.constant(0), Expressions.constant>(emptyList()), - null + Expressions.nullExpression() ) ) .from(series) -- 2.40.1 From c599e2ee00360adf4df4216ff8d77a620e95717b Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 03:26:55 +0900 Subject: [PATCH 29/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index ea9bb41..bbffba9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -120,7 +120,7 @@ class ContentSeriesQueryRepositoryImpl( Expressions.constant(0), Expressions.constant(0), Expressions.constant>(emptyList()), - Expressions.nullExpression() + Expressions.constant(null) ) ) .from(series) -- 2.40.1 From bb8dda6da04380ab699f39abe518943fadb824ce Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 03:34:04 +0900 Subject: [PATCH 30/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 2 +- .../sodalive/content/series/GetSeriesDetailResponse.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index bbffba9..3421838 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -120,7 +120,7 @@ class ContentSeriesQueryRepositoryImpl( Expressions.constant(0), Expressions.constant(0), Expressions.constant>(emptyList()), - Expressions.constant(null) + Expressions.constant("") ) ) .from(series) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt index ffbb94e..e9bb8d3 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt @@ -19,7 +19,7 @@ data class GetSeriesDetailResponse @QueryProjection constructor( var minPrice: Int, var maxPrice: Int, var keywordList: List, - var publishedDaysOfWeek: String? + var publishedDaysOfWeek: String ) { data class GetSeriesDetailCreator @QueryProjection constructor( val creatorId: Long, @@ -29,6 +29,6 @@ data class GetSeriesDetailResponse @QueryProjection constructor( ) fun validate(): Boolean { - return keywordList.isNotEmpty() && !publishedDaysOfWeek.isNullOrBlank() + return keywordList.isNotEmpty() && publishedDaysOfWeek.isBlank() } } -- 2.40.1 From 3ec0cf4facda56c059db0e2e5f7b3c0906270eea Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 03:57:45 +0900 Subject: [PATCH 31/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/ContentSeriesRepository.kt | 51 +---------------- .../content/series/ContentSeriesService.kt | 55 ++++++++++++++----- .../content/series/GetSeriesDetailResponse.kt | 12 +--- 3 files changed, 48 insertions(+), 70 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 3421838..81b047c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -1,8 +1,6 @@ package kr.co.vividnext.sodalive.content.series -import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQueryFactory -import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.content.hashtag.QHashTag.hashTag import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentMinMaxPriceResponse @@ -12,9 +10,7 @@ import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seri import kr.co.vividnext.sodalive.creator.admin.content.series.Series import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.QSeriesKeyword.seriesKeyword -import kr.co.vividnext.sodalive.member.QMember import org.springframework.data.jpa.repository.JpaRepository -import java.time.LocalDateTime interface ContentSeriesRepository : JpaRepository, ContentSeriesQueryRepository @@ -28,7 +24,7 @@ interface ContentSeriesQueryRepository { limit: Long ): List - fun getSeriesDetail(seriesId: Long, isAuth: Boolean, imageHost: String): GetSeriesDetailResponse? + fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series? fun getPublishedDaysOfWeek(seriesId: Long): Set fun getKeywordList(seriesId: Long): List fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse @@ -75,8 +71,7 @@ class ContentSeriesQueryRepositoryImpl( .fetch() } - override fun getSeriesDetail(seriesId: Long, isAuth: Boolean, imageHost: String): GetSeriesDetailResponse? { - val qCreator = QMember.member + override fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series? { var where = series.id.eq(seriesId) .and(series.isActive.isTrue) @@ -84,48 +79,8 @@ class ContentSeriesQueryRepositoryImpl( where = where.and(series.isAdult.isFalse) } - val formattedDate = Expressions.stringTemplate( - "DATE_FORMAT({0}, {1})", - Expressions.dateTimeTemplate( - LocalDateTime::class.java, - "CONVERT_TZ({0},{1},{2})", - series.createdAt, - "UTC", - "Asia/Seoul" - ), - "%Y-%m-%d" - ) - return queryFactory - .select( - QGetSeriesDetailResponse( - series.id, - series.title, - series.coverImage.prepend("/").prepend(imageHost), - series.introduction, - seriesGenre.genre, - series.isAdult, - series.writer, - series.studio, - formattedDate, - QGetSeriesDetailResponse_GetSeriesDetailCreator( - qCreator.id, - qCreator.nickname, - qCreator.profileImage.prepend("/").prepend(imageHost), - Expressions.constant(false) - ), - Expressions.constant(0), - Expressions.constant(0), - Expressions.constant(15), - Expressions.constant(0), - Expressions.constant(0), - Expressions.constant>(emptyList()), - Expressions.constant("") - ) - ) - .from(series) - .innerJoin(series.member, qCreator) - .innerJoin(series.genre, seriesGenre) + .selectFrom(series) .where(where) .fetchFirst() } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt index d6c9e27..484a8bc 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -10,6 +10,8 @@ import kr.co.vividnext.sodalive.member.Member import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service import java.time.LocalDateTime +import java.time.ZoneId +import java.time.format.DateTimeFormatter @Service class ContentSeriesService( @@ -76,32 +78,59 @@ class ContentSeriesService( } fun getSeriesDetail(seriesId: Long, member: Member): GetSeriesDetailResponse { - val seriesDetail = repository.getSeriesDetail( + val series = repository.getSeriesDetail( seriesId = seriesId, - isAuth = member.auth != null, - imageHost = coverImageHost + isAuth = member.auth != null ) ?: throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요") - seriesDetail.creator.isFollow = explorerQueryRepository.isFollow( - creatorId = seriesDetail.creator.creatorId, + val isFollow = explorerQueryRepository.isFollow( + creatorId = series.member!!.id!!, memberId = member.id!! ) - seriesDetail.publishedDaysOfWeek = publishedDaysOfWeekText( + val publishedDaysOfWeek = publishedDaysOfWeekText( repository.getPublishedDaysOfWeek(seriesId = seriesId) ) - seriesDetail.keywordList = repository.getKeywordList(seriesId = seriesId) + val keywordList = repository.getKeywordList(seriesId = seriesId) .filter { it.isNotBlank() } val minMaxPrice = repository.getSeriesContentMinMaxPrice(seriesId = seriesId) - seriesDetail.minPrice = minMaxPrice.minPrice - seriesDetail.maxPrice = minMaxPrice.maxPrice - seriesDetail.rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt() - seriesDetail.rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt() + val minPrice = minMaxPrice.minPrice + val maxPrice = minMaxPrice.maxPrice + val rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt() + val rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt() - if (!seriesDetail.validate()) throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요") - return seriesDetail + val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + return GetSeriesDetailResponse( + seriesId = seriesId, + title = series.title, + coverImage = "$coverImageHost/${series.coverImage}", + introduction = series.introduction, + genre = series.genre!!.genre, + isAdult = series.isAdult, + writer = series.writer, + studio = series.studio, + publishedDate = series.createdAt!! + .atZone(ZoneId.of("UTC")) + .withZoneSameInstant(ZoneId.of("Asia/Seoul")) + .toLocalDateTime() + .format(dateTimeFormatter), + creator = GetSeriesDetailResponse.GetSeriesDetailCreator( + creatorId = series.member!!.id!!, + nickname = series.member!!.nickname, + profileImage = "$coverImageHost/${series.member!!.profileImage}", + isFollow = isFollow + ), + rentalMinPrice = rentalMinPrice, + rentalMaxPrice = rentalMaxPrice, + rentalPeriod = 15, + minPrice = minPrice, + maxPrice = maxPrice, + keywordList = keywordList, + publishedDaysOfWeek = publishedDaysOfWeek + + ) } private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set): String { diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt index e9bb8d3..be90080 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt @@ -1,8 +1,6 @@ package kr.co.vividnext.sodalive.content.series -import com.querydsl.core.annotations.QueryProjection - -data class GetSeriesDetailResponse @QueryProjection constructor( +data class GetSeriesDetailResponse( val seriesId: Long, val title: String, val coverImage: String, @@ -21,14 +19,10 @@ data class GetSeriesDetailResponse @QueryProjection constructor( var keywordList: List, var publishedDaysOfWeek: String ) { - data class GetSeriesDetailCreator @QueryProjection constructor( + data class GetSeriesDetailCreator( val creatorId: Long, val nickname: String, - val coverImage: String, + val profileImage: String, var isFollow: Boolean ) - - fun validate(): Boolean { - return keywordList.isNotEmpty() && publishedDaysOfWeek.isBlank() - } } -- 2.40.1 From 007be6b1ff4393fd1991a9f5fbd12e518f838ed2 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 04:19:21 +0900 Subject: [PATCH 32/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesService.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt index 484a8bc..6f96342 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -88,10 +88,6 @@ class ContentSeriesService( memberId = member.id!! ) - val publishedDaysOfWeek = publishedDaysOfWeekText( - repository.getPublishedDaysOfWeek(seriesId = seriesId) - ) - val keywordList = repository.getKeywordList(seriesId = seriesId) .filter { it.isNotBlank() } @@ -128,7 +124,7 @@ class ContentSeriesService( minPrice = minPrice, maxPrice = maxPrice, keywordList = keywordList, - publishedDaysOfWeek = publishedDaysOfWeek + publishedDaysOfWeek = publishedDaysOfWeekText(series.publishedDaysOfWeek) ) } -- 2.40.1 From 0350f863226a2af8188ac5068191d96999760e12 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 04:27:36 +0900 Subject: [PATCH 33/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/series/ContentSeriesRepository.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index 81b047c..e157180 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -97,7 +97,7 @@ class ContentSeriesQueryRepositoryImpl( return queryFactory .select(hashTag.tag) .from(series) - .innerJoin(series.keywordList, seriesKeyword).fetchJoin() + .innerJoin(series.keywordList, seriesKeyword) .innerJoin(seriesKeyword.keyword, hashTag) .where(series.id.eq(seriesId)) .fetch() @@ -112,7 +112,7 @@ class ContentSeriesQueryRepositoryImpl( ) ) .from(series) - .innerJoin(series.contentList, seriesContent).fetchJoin() + .innerJoin(series.contentList, seriesContent) .innerJoin(seriesContent.content, audioContent) .where(series.id.eq(seriesId)) .fetchFirst() -- 2.40.1 From 3b807543b72aa2b7ce1856a261a80d7566baa82f Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Apr 2024 21:18:13 +0900 Subject: [PATCH 34/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20API=20-=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=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 --- .../content/series/ContentSeriesController.kt | 18 ++++++ .../content/series/ContentSeriesRepository.kt | 10 ---- .../content/series/ContentSeriesService.kt | 44 ++++++++++++++- .../content/series/GetSeriesDetailResponse.kt | 14 +++-- .../content/ContentSeriesContentRepository.kt | 56 +++++++++++++++++++ .../content/GetSeriesContentListResponse.kt | 19 +++++++ 6 files changed, 143 insertions(+), 18 deletions(-) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentListResponse.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt index 946625e..13cdc3a 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt @@ -46,4 +46,22 @@ class ContentSeriesController(private val service: ContentSeriesService) { service.getSeriesDetail(seriesId = id, member = member) ) } + + @GetMapping("/{id}/content") + fun getSeriesContentList( + @PathVariable id: Long, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, + pageable: Pageable + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok( + service.getSeriesContentList( + seriesId = id, + member = member, + offset = pageable.offset, + limit = pageable.pageSize.toLong() + ) + ) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt index e157180..345e4fb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt @@ -8,7 +8,6 @@ import kr.co.vividnext.sodalive.content.series.content.QGetSeriesContentMinMaxPr import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent import kr.co.vividnext.sodalive.creator.admin.content.series.Series -import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.QSeriesKeyword.seriesKeyword import org.springframework.data.jpa.repository.JpaRepository @@ -25,7 +24,6 @@ interface ContentSeriesQueryRepository { ): List fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series? - fun getPublishedDaysOfWeek(seriesId: Long): Set fun getKeywordList(seriesId: Long): List fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse } @@ -85,14 +83,6 @@ class ContentSeriesQueryRepositoryImpl( .fetchFirst() } - override fun getPublishedDaysOfWeek(seriesId: Long): Set { - return queryFactory - .select(series.publishedDaysOfWeek) - .from(series) - .where(series.id.eq(seriesId)) - .fetchFirst() - } - override fun getKeywordList(seriesId: Long): List { return queryFactory .select(hashTag.tag) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt index 6f96342..3e05ff2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt @@ -1,7 +1,10 @@ package kr.co.vividnext.sodalive.content.series import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.content.order.OrderRepository +import kr.co.vividnext.sodalive.content.order.OrderType import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository +import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentListResponse import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState @@ -16,6 +19,7 @@ import java.time.format.DateTimeFormatter @Service class ContentSeriesService( private val repository: ContentSeriesRepository, + private val orderRepository: OrderRepository, private val explorerQueryRepository: ExplorerQueryRepository, private val seriesContentRepository: ContentSeriesContentRepository, @@ -97,7 +101,9 @@ class ContentSeriesService( val rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt() val rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt() - val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + val seriesContentList = getSeriesContentList(seriesId = seriesId, member = member, offset = 0, limit = 5) + + val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd") return GetSeriesDetailResponse( seriesId = seriesId, title = series.title, @@ -124,11 +130,43 @@ class ContentSeriesService( minPrice = minPrice, maxPrice = maxPrice, keywordList = keywordList, - publishedDaysOfWeek = publishedDaysOfWeekText(series.publishedDaysOfWeek) - + publishedDaysOfWeek = publishedDaysOfWeekText(series.publishedDaysOfWeek), + contentList = seriesContentList.items, + contentCount = seriesContentList.totalCount ) } + fun getSeriesContentList(seriesId: Long, member: Member, offset: Long, limit: Long): GetSeriesContentListResponse { + val isAdult = member.auth != null + + val totalCount = seriesContentRepository.getContentCount(seriesId, isAdult = isAdult) + val contentList = seriesContentRepository.getContentList( + seriesId = seriesId, + isAdult = isAdult, + imageHost = coverImageHost, + offset = offset, + limit = limit + ) + .map { + val (isExistsAudioContent, orderType) = orderRepository.isExistOrderedAndOrderType( + memberId = member.id!!, + contentId = it.contentId + ) + + if (isExistsAudioContent) { + if (orderType == OrderType.RENTAL) { + it.isRented = true + } else { + it.isOwned = true + } + } + + it + } + + return GetSeriesContentListResponse(totalCount, contentList) + } + private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set): String { val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal } .map { diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt index be90080..508c441 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/GetSeriesDetailResponse.kt @@ -1,5 +1,7 @@ package kr.co.vividnext.sodalive.content.series +import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentListItem + data class GetSeriesDetailResponse( val seriesId: Long, val title: String, @@ -14,15 +16,17 @@ data class GetSeriesDetailResponse( var rentalMinPrice: Int, var rentalMaxPrice: Int, val rentalPeriod: Int, - var minPrice: Int, - var maxPrice: Int, - var keywordList: List, - var publishedDaysOfWeek: String + val minPrice: Int, + val maxPrice: Int, + val keywordList: List, + val publishedDaysOfWeek: String, + val contentList: List, + val contentCount: Int ) { data class GetSeriesDetailCreator( val creatorId: Long, val nickname: String, val profileImage: String, - var isFollow: Boolean + val isFollow: Boolean ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt index e8f955a..b757acc 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt @@ -1,5 +1,6 @@ package kr.co.vividnext.sodalive.content.series.content +import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQueryFactory import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series @@ -12,6 +13,14 @@ interface ContentSeriesContentRepository : JpaRepository, C interface ContentSeriesContentQueryRepository { fun getContentCount(seriesId: Long, isAdult: Boolean): Int + fun getContentList( + seriesId: Long, + isAdult: Boolean, + imageHost: String, + offset: Long, + limit: Long + ): List + fun isNewContent(seriesId: Long, isAdult: Boolean, fromDate: LocalDateTime, nowDate: LocalDateTime): Boolean } @@ -36,6 +45,53 @@ class ContentSeriesContentQueryRepositoryImpl( .size } + override fun getContentList( + seriesId: Long, + isAdult: Boolean, + imageHost: String, + offset: Long, + limit: Long + ): List { + var where = series.id.eq(seriesId) + .and(audioContent.isActive.isTrue) + .and(audioContent.duration.isNotNull) + + if (!isAdult) { + where = where.and(audioContent.isAdult.isFalse) + } + + val formattedDate = Expressions.stringTemplate( + "DATE_FORMAT({0}, {1})", + Expressions.dateTimeTemplate( + LocalDateTime::class.java, + "CONVERT_TZ({0},{1},{2})", + audioContent.releaseDate, + "UTC", + "Asia/Seoul" + ), + "%y.%m.%d" + ) + + return queryFactory + .select( + QGetSeriesContentListItem( + audioContent.id, + audioContent.title, + audioContent.coverImage.prepend("/").prepend(imageHost), + formattedDate, + audioContent.duration, + audioContent.price, + Expressions.asBoolean(false), + Expressions.asBoolean(false) + ) + ) + .from(seriesContent) + .innerJoin(seriesContent.series, series) + .innerJoin(seriesContent.content, audioContent) + .where(where) + .fetch() + } + override fun isNewContent( seriesId: Long, isAdult: Boolean, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentListResponse.kt new file mode 100644 index 0000000..00f774c --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/GetSeriesContentListResponse.kt @@ -0,0 +1,19 @@ +package kr.co.vividnext.sodalive.content.series.content + +import com.querydsl.core.annotations.QueryProjection + +data class GetSeriesContentListResponse( + val totalCount: Int, + val items: List +) + +data class GetSeriesContentListItem @QueryProjection constructor( + val contentId: Long, + val title: String, + val coverImage: String, + val releaseDate: String, + val duration: String, + val price: Int, + var isRented: Boolean, + var isOwned: Boolean +) -- 2.40.1 From 976aeb0f7568c7176927ebe5871a2d8578896167 Mon Sep 17 00:00:00 2001 From: Klaus Date: Sat, 27 Apr 2024 00:17:55 +0900 Subject: [PATCH 35/35] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20-=20offset,?= =?UTF-8?q?=20limit=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/series/content/ContentSeriesContentRepository.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt index b757acc..469dbc2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/content/ContentSeriesContentRepository.kt @@ -89,6 +89,8 @@ class ContentSeriesContentQueryRepositoryImpl( .innerJoin(seriesContent.series, series) .innerJoin(seriesContent.content, audioContent) .where(where) + .offset(offset) + .limit(limit) .fetch() } -- 2.40.1