diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt index 4b4549a..f5a529a 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt @@ -131,11 +131,19 @@ class AudioContentController(private val service: AudioContentService) { fun getDetail( @PathVariable id: Long, @RequestParam timezone: String, + @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? ) = run { if (member == null) throw SodaException("로그인 정보를 확인해주세요.") - ApiResponse.ok(service.getDetail(id = id, member = member, timezone = timezone)) + ApiResponse.ok( + service.getDetail( + id = id, + member = member, + isAdultContentVisible = isAdultContentVisible ?: true, + timezone = timezone + ) + ) } @GetMapping("/{id}/generate-url") diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt index f904232..c46527f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -22,6 +22,7 @@ import kr.co.vividnext.sodalive.content.pin.QPinContent.pinContent import kr.co.vividnext.sodalive.content.playlist.AudioContentPlaylistContent import kr.co.vividnext.sodalive.content.playlist.QAudioContentPlaylistContent import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme +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.event.QEvent.event import kr.co.vividnext.sodalive.member.MemberRole @@ -164,8 +165,10 @@ interface AudioContentQueryRepository { fun fetchContentForPlaylist(contentIdList: List): List fun getCoverImageById(id: Long): String? - fun findPreviousContent(title: String): OtherContentResponse? - fun findNextContent(title: String): OtherContentResponse? + fun findPreviousContent(seriesId: Long, title: String, isAdult: Boolean): OtherContentResponse? + fun findNextContent(seriesId: Long, title: String, isAdult: Boolean): OtherContentResponse? + + fun findSeriesIdByContentId(contentId: Long, isAdult: Boolean): Long? } @Repository @@ -1156,7 +1159,18 @@ class AudioContentQueryRepositoryImpl( .fetchFirst() } - override fun findPreviousContent(title: String): OtherContentResponse? { + override fun findPreviousContent(seriesId: Long, title: String, isAdult: Boolean): OtherContentResponse? { + var where = series.isActive.isTrue + .and(series.id.eq(seriesId)) + .and(audioContent.isActive.isTrue) + .and(audioContent.title.lt(title)) + .and(audioContent.limited.isNull) + .and(audioContent.releaseDate.goe(LocalDateTime.now())) + + if (!isAdult) { + where = where.and(audioContent.isAdult.isFalse) + } + return queryFactory .select( QOtherContentResponse( @@ -1166,14 +1180,26 @@ class AudioContentQueryRepositoryImpl( ) ) .from(seriesContent) + .innerJoin(seriesContent.series, series) .innerJoin(seriesContent.content, audioContent) - .where(audioContent.title.lt(title)) + .where(where) .orderBy(audioContent.title.asc()) .limit(1) .fetchFirst() } - override fun findNextContent(title: String): OtherContentResponse? { + override fun findNextContent(seriesId: Long, title: String, isAdult: Boolean): OtherContentResponse? { + var where = series.isActive.isTrue + .and(series.id.eq(seriesId)) + .and(audioContent.isActive.isTrue) + .and(audioContent.title.gt(title)) + .and(audioContent.limited.isNull) + .and(audioContent.releaseDate.goe(LocalDateTime.now())) + + if (!isAdult) { + where = where.and(audioContent.isAdult.isFalse) + } + return queryFactory .select( QOtherContentResponse( @@ -1183,10 +1209,31 @@ class AudioContentQueryRepositoryImpl( ) ) .from(seriesContent) + .innerJoin(seriesContent.series, series) .innerJoin(seriesContent.content, audioContent) - .where(audioContent.title.gt(title)) + .where(where) .orderBy(audioContent.title.asc()) .limit(1) .fetchFirst() } + + override fun findSeriesIdByContentId(contentId: Long, isAdult: Boolean): Long? { + var where = series.isActive.isTrue + .and(audioContent.isActive.isTrue) + .and(audioContent.id.eq(contentId)) + + if (!isAdult) { + where = where.and(series.isAdult.isFalse) + } + + return queryFactory + .select(series.id) + .from(seriesContent) + .innerJoin(seriesContent.series, series) + .innerJoin(seriesContent.content, audioContent) + .where(where) + .orderBy(seriesContent.id.asc()) + .limit(1) + .fetchFirst() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index 6aaabb8..2082361 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -440,7 +440,14 @@ class AudioContentService( } } - fun getDetail(id: Long, member: Member, timezone: String): GetAudioContentDetailResponse { + fun getDetail( + id: Long, + member: Member, + isAdultContentVisible: Boolean, + timezone: String + ): GetAudioContentDetailResponse { + val isAdult = member.auth != null && isAdultContentVisible + // 오디오 콘텐츠 조회 (content_id, 제목, 내용, 테마, 태그, 19여부, 이미지, 콘텐츠 PATH) val audioContent = repository.findByIdOrNull(id) ?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.") @@ -473,8 +480,26 @@ class AudioContentService( null } - val previousContent = repository.findPreviousContent(title = audioContent.title) - val nextContent = repository.findNextContent(title = audioContent.title) + val seriesId = repository.findSeriesIdByContentId(audioContent.id!!, isAdult) + val previousContent = if (seriesId != null) { + repository.findPreviousContent( + seriesId = seriesId, + title = audioContent.title, + isAdult = isAdult + ) + } else { + null + } + + val nextContent = if (seriesId != null) { + repository.findNextContent( + seriesId = seriesId, + title = audioContent.title, + isAdult = isAdult + ) + } else { + null + } if ( !isExistsAudioContent &&