Skip to content

Commit ec5cc12

Browse files
committed
[BOOK-198] feat: apis - 사용자 홈 화면에 최근 읽은 도서 조회 기능 추가
1 parent ce90a98 commit ec5cc12

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ import org.springframework.data.domain.Page
44
import org.springframework.data.domain.Pageable
55
import org.springframework.stereotype.Service
66
import org.yapp.apis.auth.dto.request.UserBooksByIsbnsRequest
7+
import org.yapp.apis.book.dto.request.UpsertUserBookRequest
78
import org.yapp.apis.book.dto.response.UserBookPageResponse
89
import org.yapp.apis.book.dto.response.UserBookResponse
9-
import org.yapp.apis.book.dto.request.UpsertUserBookRequest
1010
import org.yapp.apis.book.exception.UserBookErrorCode
1111
import org.yapp.apis.book.exception.UserBookNotFoundException
12+
import org.yapp.apis.home.dto.response.UserHomeResponse
1213
import org.yapp.domain.userbook.BookStatus
1314
import org.yapp.domain.userbook.UserBook
1415
import org.yapp.domain.userbook.UserBookDomainService
1516
import org.yapp.domain.userbook.UserBookSortType
16-
import java.util.UUID
17-
17+
import org.yapp.domain.userbook.vo.UserBookWithLastRecordVO
18+
import java.util.*
1819

1920
@Service
2021
class UserBookService(
@@ -42,7 +43,6 @@ class UserBookService(
4243
)
4344
}
4445

45-
4646
fun findAllByUserIdAndBookIsbnIn(userBooksByIsbnsRequest: UserBooksByIsbnsRequest): List<UserBookResponse> {
4747
val userBooks = userBookDomainService.findAllByUserIdAndBookIsbnIn(
4848
userBooksByIsbnsRequest.validUserId(),
@@ -51,6 +51,55 @@ class UserBookService(
5151
return userBooks.map { UserBookResponse.from(it) }
5252
}
5353

54+
fun findRecentReadingBooksForHome(userId: UUID, limit: Int): UserHomeResponse {
55+
val fetchLimit = maxOf(limit * 2, 10)
56+
val allUserBookVoInfos = userBookDomainService.findRecentReadingBooksWithLastRecord(userId, fetchLimit)
57+
val selectedBooks = selectBooksByPriority(allUserBookVoInfos, limit)
58+
59+
return UserHomeResponse.from(selectedBooks)
60+
}
61+
62+
private fun selectBooksByPriority(
63+
allBooks: List<UserBookWithLastRecordVO>,
64+
targetLimit: Int
65+
): List<UserBookWithLastRecordVO> {
66+
if (allBooks.isEmpty()) return emptyList()
67+
68+
val result = mutableListOf<UserBookWithLastRecordVO>()
69+
val usedBookIds = mutableSetOf<UUID>()
70+
71+
val readingBooks = allBooks
72+
.filter { it.status == BookStatus.READING }
73+
.sortedByDescending { it.lastRecordedAt }
74+
75+
val readingSelected = readingBooks.take(targetLimit)
76+
result.addAll(readingSelected)
77+
usedBookIds.addAll(readingSelected.map { it.id.value })
78+
79+
if (result.size < targetLimit) {
80+
val remainingSlots = targetLimit - result.size
81+
val completedBooks = allBooks
82+
.filter { it.status == BookStatus.COMPLETED && !usedBookIds.contains(it.id.value) }
83+
.sortedByDescending { it.lastRecordedAt }
84+
85+
val completedSelected = completedBooks.take(remainingSlots)
86+
result.addAll(completedSelected)
87+
usedBookIds.addAll(completedSelected.map { it.id.value })
88+
}
89+
90+
if (result.size < targetLimit) {
91+
val remainingSlots = targetLimit - result.size
92+
val remainingBooks = allBooks
93+
.filter { !usedBookIds.contains(it.id.value) }
94+
.sortedByDescending { it.lastRecordedAt }
95+
96+
val remainingSelected = remainingBooks.take(remainingSlots)
97+
result.addAll(remainingSelected)
98+
}
99+
100+
return result
101+
}
102+
54103
private fun findUserBooksByDynamicCondition(
55104
userId: UUID,
56105
status: BookStatus?,

0 commit comments

Comments
 (0)