Skip to content

Commit

Permalink
[feat #78] 미분류 컨텐츠 조회 api (#79)
Browse files Browse the repository at this point in the history
* feat: 미분류 컨텐츠 조회 api

* fix: offset 추가
  • Loading branch information
jimin3263 authored Aug 8, 2024
1 parent 09907bc commit 0837e4f
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.pokit.auth.config.ErrorOperation
import com.pokit.auth.model.PrincipalUser
import com.pokit.auth.model.toDomain
import com.pokit.category.exception.CategoryErrorCode
import com.pokit.category.model.CategoryStatus
import com.pokit.common.dto.SliceResponseDto
import com.pokit.common.wrapper.ResponseWrapper.wrapOk
import com.pokit.common.wrapper.ResponseWrapper.wrapSlice
Expand Down Expand Up @@ -115,6 +116,27 @@ class ContentController(
.wrapOk()
}

@GetMapping("/uncategorized")
@Operation(summary = "미분류 카테고리 컨텐츠 조회")
fun getUncategorizedContents(
@AuthenticationPrincipal user: PrincipalUser,
@PageableDefault(
page = 0,
size = 10,
sort = ["createdAt"],
direction = Sort.Direction.DESC
) pageable: Pageable,
): ResponseEntity<SliceResponseDto<ContentsResponse>> {
return contentUseCase.getContentsByCategoryName(
user.id,
CategoryStatus.UNCATEGORIZED.name,
pageable
)
.map { it.toResponse() }
.wrapSlice()
.wrapOk()
}

@PostMapping("/{contentId}")
@Operation(summary = "컨텐츠 상세조회 API")
fun getContent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.pokit.content.dto.response

import com.pokit.category.model.RemindCategory
import java.time.format.DateTimeFormatter

data class ContentsResponse(
val contentId: Long,
val categoryId: Long,
val categoryName: String,
val category: RemindCategory,
val data: String,
val domain: String,
val title: String,
Expand All @@ -21,8 +21,7 @@ fun ContentsResult.toResponse(): ContentsResponse {

return ContentsResponse(
contentId = this.contentId,
categoryId = this.categoryId,
categoryName = this.categoryName,
category = this.category,
data = this.data,
domain = this.domain,
title = this.title,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.pokit.out.persistence.content.impl

import com.pokit.category.model.CategoryStatus
import com.pokit.content.dto.response.ContentsResult
import com.pokit.content.dto.request.ContentSearchCondition
import com.pokit.content.model.Content
Expand All @@ -13,6 +14,7 @@ import com.pokit.out.persistence.content.persist.QContentEntity.contentEntity
import com.pokit.out.persistence.content.persist.toDomain
import com.pokit.out.persistence.log.persist.QUserLogEntity.userLogEntity
import com.querydsl.core.Tuple
import com.querydsl.core.types.OrderSpecifier
import com.querydsl.core.types.Predicate
import com.querydsl.core.types.dsl.DateTimePath
import com.querydsl.jpa.impl.JPAQuery
Expand Down Expand Up @@ -57,7 +59,6 @@ class ContentAdapter(
condition: ContentSearchCondition,
pageable: Pageable,
): Slice<ContentsResult> {
var hasNext = false
val order = pageable.sort.getOrderFor("createdAt")

val query = queryFactory.select(contentEntity, categoryEntity.name, userLogEntity.count())
Expand All @@ -75,17 +76,14 @@ class ContentAdapter(
dateBetween(condition.startDate, condition.endDate),
categoryIn(condition.categoryIds)
)
.offset(pageable.offset)
.groupBy(contentEntity)
.orderBy(getSort(contentEntity.createdAt, order!!))
.limit(pageable.pageSize + 1L)


val contentEntityList = query.fetch()

if (contentEntityList.size > pageable.pageSize) {
hasNext = true
contentEntityList.removeAt(contentEntityList.size - 1)
}
val hasNext = getHasNext(contentEntityList, pageable)

val contents = contentEntityList.map {
ContentsResult.of(
Expand All @@ -98,17 +96,57 @@ class ContentAdapter(
return SliceImpl(contents, pageable, hasNext)
}

override fun loadByUserIdAndCategoryName(userId: Long, categoryName: String, pageable: Pageable): Slice<ContentsResult> {
val contents = queryFactory.select(contentEntity, categoryEntity.name, userLogEntity.count())
.from(contentEntity)
.leftJoin(userLogEntity).on(userLogEntity.contentId.eq(contentEntity.id))
.join(categoryEntity).on(categoryEntity.id.eq(contentEntity.categoryId))
.where(
categoryEntity.userId.eq(userId),
categoryEntity.name.eq(categoryName),
contentEntity.deleted.isFalse,
)
.offset(pageable.offset)
.groupBy(contentEntity)
.limit((pageable.pageSize + 1).toLong())
.orderBy(getSortOrder(contentEntity.createdAt, "createdAt", pageable))
.fetch()

val hasNext = getHasNext(contents, pageable)

val contentResults = contents.map {
ContentsResult.of(
it[contentEntity]!!.toDomain(),
CategoryStatus.resolveDisplayName(it[categoryEntity.name]!!),
it[userLogEntity.count()]!!
)
}

return SliceImpl(contentResults, pageable, hasNext)
}

override fun loadByContentIds(contentIds: List<Long>): List<Content> =
contentRepository.findByIdIn(contentIds)
.map { it.toDomain() }

private fun getHasNext(
contentEntityList: MutableList<Tuple>,
pageable: Pageable,
): Boolean {
var hasNext = false
if (contentEntityList.size > pageable.pageSize) {
hasNext = true
contentEntityList.removeAt(contentEntityList.size - 1)
}
return hasNext
}

private fun isUnread(read: Boolean?): Predicate? {
return read?.let {
userLogEntity.id.isNull.or(userLogEntity.type.ne(LogType.READ))
}
}


private fun categoryIn(categoryIds: List<Long>?): Predicate? {
if (categoryIds.isNullOrEmpty()) {
return null
Expand Down Expand Up @@ -154,4 +192,15 @@ class ContentAdapter(
if (order.isDescending) property.desc()
else property.asc()

private fun getSortOrder(property: DateTimePath<LocalDateTime>, sortField: String, pageable: Pageable): OrderSpecifier<*> {
val order = pageable.sort.getOrderFor(sortField)
?.direction
?: Sort.Direction.ASC

return if (order.isAscending) {
property.asc()
} else {
property.desc()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class ContentEntity(
@Column(name = "alert_yn")
val alertYn: String,

@Column(name = "domain")
val domain: String,

@Column(name = "is_deleted")
var deleted: Boolean = false
) : BaseEntity() {
Expand All @@ -47,7 +50,8 @@ class ContentEntity(
data = content.data,
title = content.title,
memo = content.memo,
alertYn = content.alertYn
alertYn = content.alertYn,
domain = content.domain
)
}
}
Expand All @@ -60,5 +64,6 @@ fun ContentEntity.toDomain() = Content(
title = this.title,
memo = this.memo,
alertYn = this.alertYn,
domain = this.domain,
createdAt = this.createdAt
)
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ interface ContentUseCase {
pageable: Pageable,
): Slice<ContentsResult>

fun getContentsByCategoryName(userId: Long, categoryName: String, pageable: Pageable): Slice<ContentsResult>

fun getContent(userId: Long, contentId: Long): GetContentResponse

fun getBookmarkContents(userId: Long, pageable: Pageable): Slice<RemindContentResult>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ interface ContentPort {
pageable: Pageable,
): Slice<ContentsResult>

fun loadByUserIdAndCategoryName(
userId: Long,
categoryName: String,
pageable: Pageable,
): Slice<ContentsResult>

fun deleteByUserId(userId: Long)

fun loadByContentIds(contentIds: List<Long>): List<Content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ class ContentService(
return contents
}

override fun getContentsByCategoryName(userId: Long, categoryName: String, pageable: Pageable): Slice<ContentsResult> =
contentPort.loadByUserIdAndCategoryName(userId, categoryName, pageable)


@Transactional
override fun getContent(userId: Long, contentId: Long): GetContentResponse {
val userLog = UserLog(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package com.pokit.category.model

enum class CategoryStatus(val displayName: String) {
enum class CategoryStatus(
val displayName: String
) {
UNCATEGORIZED("미분류")
;

companion object {
fun resolveDisplayName(status: String): String =
entries.find { it.name == status }
?.displayName
?: status

}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.pokit.content.dto.response

import com.pokit.category.model.RemindCategory
import com.pokit.content.model.Content
import java.time.LocalDateTime

data class ContentsResult(
val contentId: Long,
val categoryId: Long,
val categoryName: String,
val category: RemindCategory,
val data: String,
val domain: String,
val title: String,
Expand All @@ -20,8 +20,7 @@ data class ContentsResult(
fun of(content: Content, categoryName: String, isRead: Long): ContentsResult {
return ContentsResult(
contentId = content.id,
categoryId = content.categoryId,
categoryName = categoryName,
category = RemindCategory(content.categoryId, categoryName),
data = content.data,
domain = content.domain,
title = content.title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fun Content.toRemindContentResult(isRead: Boolean, category: RemindCategory): Re
fun ContentsResult.toRemindContentResult(): RemindContentResult {
return RemindContentResult(
contentId = this.contentId,
category = RemindCategory(this.categoryId, this.categoryName),
category = this.category,
data = this.data,
title = this.title,
createdAt = this.createdAt,
Expand Down

0 comments on commit 0837e4f

Please sign in to comment.