From a3546b625fa759478d3326ec4399f83c9a264199 Mon Sep 17 00:00:00 2001 From: toychip Date: Fri, 16 Aug 2024 15:59:32 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20Pick,=20DetailPick=20=EA=B5=AC?= =?UTF-8?q?=EB=B6=84=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=B0=8F=20DTO=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20(rebase)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/mashup/dojo/PickController.kt | 22 +++++++++---------- .../mashup/dojo/service/DefaultPickService.kt | 18 +++++++-------- .../com/mashup/dojo/usecase/PickUseCase.kt | 12 +++++----- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/api/src/main/kotlin/com/mashup/dojo/PickController.kt b/api/src/main/kotlin/com/mashup/dojo/PickController.kt index 520c347d..25cea76d 100644 --- a/api/src/main/kotlin/com/mashup/dojo/PickController.kt +++ b/api/src/main/kotlin/com/mashup/dojo/PickController.kt @@ -84,11 +84,11 @@ class PickController( @RequestParam(required = false, defaultValue = "10") pageSize: Int, ): DojoApiResponse { val currentMemberId = MemberPrincipalContextHolder.current().id - val pickPaging: PickUseCase.GetPagingPick = + val pickDetailPaging: PickUseCase.GetPickDetailPaging = pickUseCase.getReceivedPickDetailPaging(PickUseCase.GetPagingPickCommand(currentMemberId, QuestionId(questionId), pageNumber, pageSize)) val pickDetails = - pickPaging.picks.map { + pickDetailPaging.picks.map { ReceivedPickDetail( pickId = it.pickId, pickerOrdinal = it.pickerOrdinal, @@ -107,16 +107,16 @@ class PickController( } val pickPagingResponse = PickPaging( - questionId = pickPaging.questionId, - questionContent = pickPaging.questionContent, - questionEmojiImageUrl = pickPaging.questionEmojiImageUrl, - totalReceivedPickCount = pickPaging.totalReceivedPickCount, - anyOpenPickerCount = pickPaging.anyOpenPickerCount, + questionId = pickDetailPaging.questionId, + questionContent = pickDetailPaging.questionContent, + questionEmojiImageUrl = pickDetailPaging.questionEmojiImageUrl, + totalReceivedPickCount = pickDetailPaging.totalReceivedPickCount, + anyOpenPickerCount = pickDetailPaging.anyOpenPickerCount, picks = pickDetails, - totalPage = pickPaging.totalPage, - totalElements = pickPaging.totalElements, - isFirst = pickPaging.isFirst, - isLast = pickPaging.isLast + totalPage = pickDetailPaging.totalPage, + totalElements = pickDetailPaging.totalElements, + isFirst = pickDetailPaging.isFirst, + isLast = pickDetailPaging.isLast ) return DojoApiResponse.success(pickPagingResponse) diff --git a/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt b/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt index cf36b650..f3ad6150 100644 --- a/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt +++ b/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt @@ -24,7 +24,7 @@ import java.time.LocalDateTime import java.time.ZoneId interface PickService { - fun getReceivedPickList( + fun getReceivedPickPaging( pickedMemberId: MemberId, sort: PickSort, ): List @@ -48,12 +48,12 @@ interface PickService { pickOpenItem: PickOpenItem, ): String - fun getPickPaging( + fun getPickDetailPaging( questionId: QuestionId, memberId: MemberId, pageNumber: Int, pageSize: Int, - ): GetPagingPick + ): GetPickDetailPaging fun getPickCount( questionId: QuestionId, @@ -70,8 +70,8 @@ interface PickService { ): Int fun getReceivedMySpacePicks(memberId: MemberId): List - - data class GetPagingPick( + + data class GetPickDetailPaging( val picks: List, val totalPage: Int, val totalElements: Long, @@ -113,7 +113,7 @@ class DefaultPickService( @Value("\${dojo.rank.size}") private val defaultRankSize: Long, ) : PickService { - override fun getReceivedPickList( + override fun getReceivedPickPaging( pickedMemberId: MemberId, sort: PickSort, ): List { @@ -178,12 +178,12 @@ class DefaultPickService( return pickRepository.findByIdOrNull(pickId.value)?.toPick() } - override fun getPickPaging( + override fun getPickDetailPaging( questionId: QuestionId, memberId: MemberId, pageNumber: Int, pageSize: Int, - ): PickService.GetPagingPick { + ): PickService.GetPickDetailPaging { val pageable = PageRequest.of(pageNumber, pageSize) val pagingPick = pickRepository.findPickDetailPaging(memberId = memberId.value, questionId = questionId.value, pageable = pageable) @@ -219,7 +219,7 @@ class DefaultPickService( ) } - return PickService.GetPagingPick( + return PickService.GetPickDetailPaging( picks = receivedPickDetails, totalPage = pagingPick.totalPages, totalElements = pagingPick.totalElements, diff --git a/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt b/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt index 38f0c6e7..85cc6499 100644 --- a/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt +++ b/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt @@ -44,7 +44,7 @@ interface PickUseCase { val pageSize: Int, ) - data class GetPagingPick( + data class GetPickDetailPaging( val questionId: QuestionId, val questionContent: String, val questionEmojiImageUrl: String, @@ -85,7 +85,7 @@ interface PickUseCase { fun openPick(openPickCommand: OpenPickCommand): PickOpenInfo - fun getReceivedPickDetailPaging(command: GetPagingPickCommand): GetPagingPick + fun getReceivedPickDetailPaging(command: GetPagingPickCommand): GetPickDetailPaging } @Component @@ -97,7 +97,7 @@ class DefaultPickUseCase( private val notificationService: NotificationService, ) : PickUseCase { override fun getReceivedPickList(command: GetReceivedPickListCommand): List { - val receivedPickList: List = pickService.getReceivedPickList(command.memberId, command.sort) + val receivedPickList: List = pickService.getReceivedPickPaging(command.memberId, command.sort) if (receivedPickList.isEmpty()) return EMPTY_RECEIVED_PICK @@ -166,7 +166,7 @@ class DefaultPickUseCase( ).let { PickOpenInfo(openPickCommand.pickId, openPickCommand.pickOpenItem, it) } } - override fun getReceivedPickDetailPaging(command: PickUseCase.GetPagingPickCommand): PickUseCase.GetPagingPick { + override fun getReceivedPickDetailPaging(command: PickUseCase.GetPagingPickCommand): PickUseCase.GetPickDetailPaging { val question = questionService.getQuestionById(command.questionId) ?: throw DojoException.of(DojoExceptionType.NOT_EXIST, "등록되지 않은 QuestionId 입니다. QuestionId: [${command.questionId}]") @@ -177,11 +177,11 @@ class DefaultPickUseCase( val pickCount: Int = pickService.getPickCount(question.id, command.memberId) - val receivedPickPaging = pickService.getPickPaging(question.id, command.memberId, command.pageNumber, command.pageSize) + val receivedPickPaging = pickService.getPickDetailPaging(question.id, command.memberId, command.pageNumber, command.pageSize) val anyOpenPickerCount = pickService.getAnyOpenPickerCount(question.id, command.memberId) - return PickUseCase.GetPagingPick( + return PickUseCase.GetPickDetailPaging( questionId = question.id, questionContent = question.content, questionEmojiImageUrl = imageUrl, From 3a035c40ef04c11f57ea5595a8400423ddf41800 Mon Sep 17 00:00:00 2001 From: toychip Date: Fri, 16 Aug 2024 22:31:08 +0900 Subject: [PATCH 2/4] feat: findGroupByPickPaging query --- .../com/mashup/dojo/DojoExceptionType.kt | 3 + .../kotlin/com/mashup/dojo/PickRepository.kt | 97 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt b/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt index 7d1d6a9e..fe545c68 100644 --- a/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt +++ b/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt @@ -47,4 +47,7 @@ enum class DojoExceptionType( // MemberRelation RELATION_NOT_FOUND("Relation not found", "MR001_RELATION_NOT_FOUND", 500), + + // Pick Paging Sort + SORT_NOT_FOUND("Relation not found", "SORT_NOT_FOUND", 500), } diff --git a/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt b/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt index 41bde932..7f5cab22 100644 --- a/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt +++ b/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt @@ -4,6 +4,7 @@ import com.mashup.dojo.base.BaseTimeEntity import com.querydsl.core.annotations.QueryProjection import com.querydsl.core.types.dsl.BooleanExpression import com.querydsl.core.types.dsl.Wildcard +import com.querydsl.jpa.impl.JPAQuery import com.querydsl.jpa.impl.JPAQueryFactory import jakarta.persistence.Column import jakarta.persistence.Entity @@ -72,6 +73,12 @@ interface PickRepositoryCustom { memberId: String, rank: Long, ): List + + fun findGroupByPickPaging( + pickedId: String, + sort: String, + pageable: Pageable, + ): Page } class PickRepositoryImpl( @@ -221,6 +228,80 @@ class PickRepositoryImpl( .limit(rank) .fetch() } + + override fun findGroupByPickPaging( + pickedId: String, + sort: String, + pageable: Pageable, + ): Page { + val content = getGroupByPickContent(pickedId, sort, pageable) + val totalCount = getGroupByPickTotalCount(pickedId) + + return PageImpl(content, pageable, totalCount) + } + + private fun getGroupByPickContent( + pickedId: String, + sort: String, + pageable: Pageable, + ): List { + val pickEntity = QPickEntity.pickEntity + val questionEntity = QQuestionEntity.questionEntity + val imageEntity = QImageEntity.imageEntity + + val query = + jpaQueryFactory + .select( + QPickQuestionDetailMapper( + pickEntity.id, + questionEntity.id, + questionEntity.content, + imageEntity.url, + // 가장 최근의 Pick 시간 가져오기 + pickEntity.createdAt.max().`as`("latestPickedAt"), + pickEntity.id.count().`as`("totalReceivedPickCount") + ) + ) + .from(pickEntity) + .join(questionEntity).on(pickEntity.questionId.eq(questionEntity.id)) + .join(imageEntity).on(questionEntity.emojiImageId.eq(imageEntity.id)) + .where(pickEntity.pickedId.eq(pickedId)) + // Question, Image URL 기준으로 그룹화 + .groupBy(pickEntity.questionId, imageEntity.url) + + val sortedQuery = getSorted(sort, query) + + return sortedQuery + .limit(pageable.pageSize.toLong()) + .offset(pageable.offset) + .fetch() + } + + private fun getSorted( + sort: String, + query: JPAQuery, + ): JPAQuery { + val pickEntity = QPickEntity.pickEntity + if (sort == PickSort.MOST_PICKED.name) { + return query.orderBy(Wildcard.count.desc(), pickEntity.createdAt.desc()) + } + + if (sort == PickSort.LATEST.name) { + return query.orderBy(pickEntity.createdAt.desc()) + } + + throw DojoException.of(DojoExceptionType.SORT_NOT_FOUND) + } + + private fun getGroupByPickTotalCount(pickedId: String): Long { + val pickEntity = QPickEntity.pickEntity + + return jpaQueryFactory + .select(pickEntity.questionId.countDistinct()) + .from(pickEntity) + .where(pickEntity.pickedId.eq(pickedId)) + .fetchOne() ?: 0L + } } data class PickEntityMapper @@ -253,3 +334,19 @@ data class PickQuestionMapper val questionContent: String, val createdAt: LocalDateTime, ) + +enum class PickSort { + LATEST, + MOST_PICKED, +} + +data class PickQuestionDetailMapper + @QueryProjection + constructor( + val pickId: String, + val questionId: String, + val questionContent: String, + val questionEmojiImageUrl: String, + val latestPickedAt: LocalDateTime, + val totalReceivedPickCount: Long, + ) From 6a007701d97092d576f88024d91d6cc648e20901 Mon Sep 17 00:00:00 2001 From: toychip Date: Fri, 16 Aug 2024 22:44:39 +0900 Subject: [PATCH 3/4] feat: Pick Paging API --- _endpoint_test/pick.http | 3 +- .../kotlin/com/mashup/dojo/PickController.kt | 65 ++++++++++++++----- .../kotlin/com/mashup/dojo/dto/PickDto.kt | 10 ++- .../com/mashup/dojo/DojoExceptionType.kt | 3 +- .../kotlin/com/mashup/dojo/domain/Pick.kt | 8 +++ .../mashup/dojo/service/DefaultPickService.kt | 57 ++++++++++++++-- .../com/mashup/dojo/usecase/PickUseCase.kt | 51 ++++----------- 7 files changed, 131 insertions(+), 66 deletions(-) diff --git a/_endpoint_test/pick.http b/_endpoint_test/pick.http index 2d24fb01..780a57ae 100644 --- a/_endpoint_test/pick.http +++ b/_endpoint_test/pick.http @@ -1,6 +1,5 @@ ### 내가 받은 픽 리스트 조회하기 - -GET {{host}}/pick/picked-list?sort=MOST_PICKED +GET {{host}}/pick/picked-list?pageSize=10&pageNumber=0&sort=MOST_PICKED ### 내가 받은 픽 중 특정 질문의 페이징 조회하기 GET {{host}}/pick/picked-detail?questionId=abc diff --git a/api/src/main/kotlin/com/mashup/dojo/PickController.kt b/api/src/main/kotlin/com/mashup/dojo/PickController.kt index 25cea76d..bfe403a2 100644 --- a/api/src/main/kotlin/com/mashup/dojo/PickController.kt +++ b/api/src/main/kotlin/com/mashup/dojo/PickController.kt @@ -8,15 +8,17 @@ import com.mashup.dojo.domain.PickOpenItem import com.mashup.dojo.domain.PickSort import com.mashup.dojo.domain.QuestionId import com.mashup.dojo.dto.CreatePickRequest +import com.mashup.dojo.dto.PickDetailPaging import com.mashup.dojo.dto.PickOpenItemDto import com.mashup.dojo.dto.PickOpenRequest import com.mashup.dojo.dto.PickOpenResponse -import com.mashup.dojo.dto.PickPaging import com.mashup.dojo.dto.PickResponse import com.mashup.dojo.dto.ReceivedPickDetail -import com.mashup.dojo.dto.ReceivedPickListGetResponse +import com.mashup.dojo.dto.ReceivedPickPagingGetResponse import com.mashup.dojo.usecase.PickUseCase import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Schema import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.tags.Tag import jakarta.validation.Valid @@ -37,27 +39,44 @@ class PickController( ) { @GetMapping("/picked-list") @Operation( - summary = "내가 받은 픽 List API", - description = "내가 받은 픽들을 정렬하여 보여주는 API. default sort : 최신 순", + summary = "내가 받은 픽 페이징 API", + description = "내가 받은 픽들을 페이징 처리 후 정렬하여 보여주는 API. default sort : 최신 순", responses = [ - ApiResponse(responseCode = "200", description = "내가 받은 픽 리스트") + ApiResponse(responseCode = "200", description = "내가 받은 픽 리스트 페이징") ] ) fun getReceivedPickList( - // todo : add userinfo - @RequestParam(required = false, defaultValue = "LATEST") sort: PickSort, - ): DojoApiResponse { + @Parameter( + description = "정렬 기준. LATEST는 최근에 Pick된 항목을 기준으로 정렬하고, MOST_PICKED는 가장 많이 Pick된 항목을 기준으로 정렬합니다.", + schema = Schema(defaultValue = "LATEST") + ) + @RequestParam(required = false, defaultValue = "LATEST") sort: String, + @Parameter( + description = "페이지 번호. 0부터 시작합니다.", + schema = Schema(defaultValue = "0") + ) + @RequestParam(required = false, defaultValue = "0") pageNumber: Int, + @Parameter( + description = "페이지 크기. 한 페이지에 포함될 항목의 개수를 설정합니다.", + schema = Schema(defaultValue = "10") + ) + @RequestParam(required = false, defaultValue = "10") pageSize: Int, + ): DojoApiResponse { val currentMemberId = MemberPrincipalContextHolder.current().id - val receivedPickList: List = + val validSort = PickSort.findByValue(sort) + + val receivedPickList = pickUseCase.getReceivedPickList( - PickUseCase.GetReceivedPickListCommand( + PickUseCase.GetReceivedPickPagingCommand( memberId = currentMemberId, - sort = sort + sort = validSort, + pageNumber = pageNumber, + pageSize = pageSize ) ) val pickResponseList = - receivedPickList.map { + receivedPickList.picks.map { PickResponse( pickId = it.pickId, questionId = it.questionId, @@ -67,7 +86,19 @@ class PickController( latestPickedAt = it.latestPickedAt ) } - return DojoApiResponse.success(ReceivedPickListGetResponse(pickResponseList, sort)) + + return DojoApiResponse.success( + ReceivedPickPagingGetResponse( + pickList = pickResponseList, + totalPage = receivedPickList.totalPage, + totalElements = receivedPickList.totalElements, + isFirst = receivedPickList.isFirst, + isLast = receivedPickList.isLast, + sort = validSort, + pageNumber = pageNumber, + pageSize = pageSize + ) + ) } @GetMapping("/picked-detail") @@ -82,7 +113,7 @@ class PickController( @RequestParam questionId: String, @RequestParam(required = false, defaultValue = "0") pageNumber: Int, @RequestParam(required = false, defaultValue = "10") pageSize: Int, - ): DojoApiResponse { + ): DojoApiResponse { val currentMemberId = MemberPrincipalContextHolder.current().id val pickDetailPaging: PickUseCase.GetPickDetailPaging = pickUseCase.getReceivedPickDetailPaging(PickUseCase.GetPagingPickCommand(currentMemberId, QuestionId(questionId), pageNumber, pageSize)) @@ -105,8 +136,8 @@ class PickController( latestPickedAt = it.latestPickedAt ) } - val pickPagingResponse = - PickPaging( + val pickDetailPagingResponse = + PickDetailPaging( questionId = pickDetailPaging.questionId, questionContent = pickDetailPaging.questionContent, questionEmojiImageUrl = pickDetailPaging.questionEmojiImageUrl, @@ -119,7 +150,7 @@ class PickController( isLast = pickDetailPaging.isLast ) - return DojoApiResponse.success(pickPagingResponse) + return DojoApiResponse.success(pickDetailPagingResponse) } @PostMapping diff --git a/api/src/main/kotlin/com/mashup/dojo/dto/PickDto.kt b/api/src/main/kotlin/com/mashup/dojo/dto/PickDto.kt index 94446810..cf8ee747 100644 --- a/api/src/main/kotlin/com/mashup/dojo/dto/PickDto.kt +++ b/api/src/main/kotlin/com/mashup/dojo/dto/PickDto.kt @@ -26,9 +26,15 @@ data class CreatePickRequest( val pickedId: MemberId, ) -data class ReceivedPickListGetResponse( +data class ReceivedPickPagingGetResponse( val pickList: List, + val totalPage: Int, + val totalElements: Long, + val isFirst: Boolean, + val isLast: Boolean, val sort: PickSort, + val pageNumber: Int, + val pageSize: Int, ) // todo : 질문의 유형(카테고리)도 전달해줘야 하는가 @@ -41,7 +47,7 @@ data class PickResponse( val latestPickedAt: LocalDateTime, ) -data class PickPaging( +data class PickDetailPaging( val questionId: QuestionId, val questionContent: String, val questionEmojiImageUrl: String, diff --git a/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt b/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt index fe545c68..160f9804 100644 --- a/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt +++ b/common/src/main/kotlin/com/mashup/dojo/DojoExceptionType.kt @@ -49,5 +49,6 @@ enum class DojoExceptionType( RELATION_NOT_FOUND("Relation not found", "MR001_RELATION_NOT_FOUND", 500), // Pick Paging Sort - SORT_NOT_FOUND("Relation not found", "SORT_NOT_FOUND", 500), + SORT_CLIENT_NOT_FOUND("Bad SortType", "SORT_NOT_FOUND", 400), + SORT_NOT_FOUND("Sort Type not found", "SORT_NOT_FOUND", 500), } diff --git a/service/src/main/kotlin/com/mashup/dojo/domain/Pick.kt b/service/src/main/kotlin/com/mashup/dojo/domain/Pick.kt index 4eee6a5f..b6452e55 100644 --- a/service/src/main/kotlin/com/mashup/dojo/domain/Pick.kt +++ b/service/src/main/kotlin/com/mashup/dojo/domain/Pick.kt @@ -100,4 +100,12 @@ enum class PickOpenItem(val value: String, val cost: Int) { enum class PickSort { LATEST, MOST_PICKED, + ; + + companion object { + fun findByValue(value: String): PickSort { + return PickSort.entries.find { it.name.equals(value, ignoreCase = true) } + ?: throw DojoException.of(DojoExceptionType.SORT_CLIENT_NOT_FOUND) + } + } } diff --git a/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt b/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt index f3ad6150..b1aada79 100644 --- a/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt +++ b/service/src/main/kotlin/com/mashup/dojo/service/DefaultPickService.kt @@ -27,7 +27,9 @@ interface PickService { fun getReceivedPickPaging( pickedMemberId: MemberId, sort: PickSort, - ): List + pageNumber: Int, + pageSize: Int, + ): GetPickPaging fun getSolvedPickList( pickerMemberId: MemberId, @@ -70,7 +72,24 @@ interface PickService { ): Int fun getReceivedMySpacePicks(memberId: MemberId): List - + + data class GetPickPaging( + val picks: List, + val totalPage: Int, + val totalElements: Long, + val isFirst: Boolean, + val isLast: Boolean, + ) + + data class GetReceivedPick( + val pickId: PickId, + val questionId: QuestionId, + val questionContent: String, + val questionEmojiImageUrl: String, + val latestPickedAt: LocalDateTime, + val totalReceivedPickCount: Int, + ) + data class GetPickDetailPaging( val picks: List, val totalPage: Int, @@ -116,9 +135,37 @@ class DefaultPickService( override fun getReceivedPickPaging( pickedMemberId: MemberId, sort: PickSort, - ): List { - return pickRepository.findAllByPickedId(pickedMemberId.value) - .map { it.toPick() } + pageNumber: Int, + pageSize: Int, + ): PickService.GetPickPaging { + val pageable = PageRequest.of(pageNumber, pageSize) + + val pickPaging = + pickRepository.findGroupByPickPaging( + pickedId = pickedMemberId.value, + sort = sort.name, + pageable = pageable + ) + + val receivedPicks = + pickPaging.content.map { + PickService.GetReceivedPick( + pickId = PickId(it.pickId), + questionId = QuestionId(it.questionId), + questionContent = it.questionContent, + questionEmojiImageUrl = it.questionEmojiImageUrl, + latestPickedAt = it.latestPickedAt, + totalReceivedPickCount = it.totalReceivedPickCount.toInt() + ) + } + + return PickService.GetPickPaging( + picks = receivedPicks, + totalPage = pickPaging.totalPages, + totalElements = pickPaging.totalElements, + isFirst = pickPaging.isFirst, + isLast = pickPaging.isLast + ) } override fun getSolvedPickList( diff --git a/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt b/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt index 85cc6499..61bcca69 100644 --- a/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt +++ b/service/src/main/kotlin/com/mashup/dojo/usecase/PickUseCase.kt @@ -3,7 +3,6 @@ package com.mashup.dojo.usecase import com.mashup.dojo.DojoException import com.mashup.dojo.DojoExceptionType import com.mashup.dojo.domain.MemberId -import com.mashup.dojo.domain.Pick import com.mashup.dojo.domain.PickId import com.mashup.dojo.domain.PickOpenItem import com.mashup.dojo.domain.PickSort @@ -16,16 +15,18 @@ import com.mashup.dojo.service.NotificationService import com.mashup.dojo.service.PickService import com.mashup.dojo.service.QuestionService import com.mashup.dojo.usecase.PickUseCase.GetReceivedPick -import com.mashup.dojo.usecase.PickUseCase.GetReceivedPickListCommand +import com.mashup.dojo.usecase.PickUseCase.GetReceivedPickPagingCommand import com.mashup.dojo.usecase.PickUseCase.OpenPickCommand import com.mashup.dojo.usecase.PickUseCase.PickOpenInfo import org.springframework.stereotype.Component import java.time.LocalDateTime interface PickUseCase { - data class GetReceivedPickListCommand( + data class GetReceivedPickPagingCommand( val memberId: MemberId, val sort: PickSort, + val pageNumber: Int, + val pageSize: Int, ) data class GetReceivedPick( @@ -77,7 +78,7 @@ interface PickUseCase { val value: String, ) - fun getReceivedPickList(command: GetReceivedPickListCommand): List + fun getReceivedPickList(command: GetReceivedPickPagingCommand): PickService.GetPickPaging fun createPick(command: CreatePickCommand): PickId @@ -96,41 +97,13 @@ class DefaultPickUseCase( private val memberService: MemberService, private val notificationService: NotificationService, ) : PickUseCase { - override fun getReceivedPickList(command: GetReceivedPickListCommand): List { - val receivedPickList: List = pickService.getReceivedPickPaging(command.memberId, command.sort) - - if (receivedPickList.isEmpty()) return EMPTY_RECEIVED_PICK - - val result = - receivedPickList.groupBy { it.questionId } - .flatMap { (questionId, pickList) -> - val question = - questionService.getQuestionById(questionId) - ?: throw DojoException.of(DojoExceptionType.NOT_EXIST, "등록되지 않은 QuestionId 입니다. QuestionId: [$questionId]") - - val url = - imageService.load(question.emojiImageId)?.url - ?: throw DojoException.of(DojoExceptionType.NOT_EXIST, "해당하는 이미지를 찾을 수 없습니다. EmojiImageId: [${question.emojiImageId}]") - - val pickedTotalCount = pickList.size - val latestPickedAt = pickList.maxBy { it.createdAt }.createdAt - - pickList.map { pick -> - GetReceivedPick( - pickId = pick.id, - questionId = question.id, - questionContent = question.content, - questionEmojiImageUrl = url, - totalReceivedPickCount = pickedTotalCount, - latestPickedAt = latestPickedAt - ) - } - } - - return when (command.sort) { - PickSort.LATEST -> result.sortedByDescending { it.latestPickedAt } - PickSort.MOST_PICKED -> result.sortedByDescending { it.totalReceivedPickCount } - } + override fun getReceivedPickList(command: GetReceivedPickPagingCommand): PickService.GetPickPaging { + return pickService.getReceivedPickPaging( + pickedMemberId = command.memberId, + sort = command.sort, + pageNumber = command.pageNumber, + pageSize = command.pageSize + ) } override fun createPick(command: PickUseCase.CreatePickCommand): PickId { From 9c9bdba5f9b73a9268081a70d01a46460f39767e Mon Sep 17 00:00:00 2001 From: toychip Date: Sat, 17 Aug 2024 19:14:01 +0900 Subject: [PATCH 4/4] refactor: sort query if -> when --- .../kotlin/com/mashup/dojo/PickRepository.kt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt b/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt index 7f5cab22..7241e46f 100644 --- a/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt +++ b/entity/src/main/kotlin/com/mashup/dojo/PickRepository.kt @@ -282,15 +282,10 @@ class PickRepositoryImpl( query: JPAQuery, ): JPAQuery { val pickEntity = QPickEntity.pickEntity - if (sort == PickSort.MOST_PICKED.name) { - return query.orderBy(Wildcard.count.desc(), pickEntity.createdAt.desc()) + return when (PickSort.findByValue(sort)) { + PickSort.MOST_PICKED -> query.orderBy(Wildcard.count.desc(), pickEntity.createdAt.desc()) + PickSort.LATEST -> query.orderBy(pickEntity.createdAt.desc()) } - - if (sort == PickSort.LATEST.name) { - return query.orderBy(pickEntity.createdAt.desc()) - } - - throw DojoException.of(DojoExceptionType.SORT_NOT_FOUND) } private fun getGroupByPickTotalCount(pickedId: String): Long { @@ -338,6 +333,14 @@ data class PickQuestionMapper enum class PickSort { LATEST, MOST_PICKED, + ; + + companion object { + fun findByValue(value: String): PickSort { + return PickSort.entries.find { it.name.equals(value, ignoreCase = true) } + ?: throw DojoException.of(DojoExceptionType.SORT_CLIENT_NOT_FOUND) + } + } } data class PickQuestionDetailMapper