From 1c3f582a8ef19066967bd3b5a773c043879ff57e Mon Sep 17 00:00:00 2001 From: Cho jiwon <77895305+Jiwon-cho@users.noreply.github.com> Date: Wed, 21 Feb 2024 22:36:37 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=82=98=EB=88=94=20paging=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC,=20=EB=93=B1=EB=A1=9D=EC=88=9C,=20=EB=A7=88=EA=B0=90?= =?UTF-8?q?=20=EC=88=9C=20=EC=A0=95=EB=A0=AC,=20=EB=82=98=EB=88=94=20?= =?UTF-8?q?=EB=82=B4=EC=97=AD=20=EC=A1=B0=ED=9A=8C=20=EA=B0=9C=EB=B0=9C=20?= =?UTF-8?q?(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/share/ApplyShareRepository.kt | 3 - .../server/domain/share/ShareController.kt | 18 ++- .../mara/server/domain/share/ShareDto.kt | 3 +- .../server/domain/share/ShareRepository.kt | 112 +++++++++++++++++- .../mara/server/domain/share/ShareService.kt | 26 ++-- .../mara/server/domain/user/UserController.kt | 31 ++++- 6 files changed, 170 insertions(+), 23 deletions(-) diff --git a/src/main/kotlin/mara/server/domain/share/ApplyShareRepository.kt b/src/main/kotlin/mara/server/domain/share/ApplyShareRepository.kt index 3ce9bec..dcd11bc 100644 --- a/src/main/kotlin/mara/server/domain/share/ApplyShareRepository.kt +++ b/src/main/kotlin/mara/server/domain/share/ApplyShareRepository.kt @@ -4,8 +4,5 @@ import mara.server.domain.user.User import org.springframework.data.jpa.repository.JpaRepository interface ApplyShareRepository : JpaRepository { - - fun findAllByUser(user: User): List? - fun existsByUserAndShare(user: User, share: Share): Boolean } diff --git a/src/main/kotlin/mara/server/domain/share/ShareController.kt b/src/main/kotlin/mara/server/domain/share/ShareController.kt index 621c579..2d23928 100644 --- a/src/main/kotlin/mara/server/domain/share/ShareController.kt +++ b/src/main/kotlin/mara/server/domain/share/ShareController.kt @@ -1,7 +1,11 @@ package mara.server.domain.share +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag import mara.server.common.CommonResponse import mara.server.common.success +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable @@ -13,49 +17,59 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/shares") +@Tag(name = "나눔", description = "나눔 API") class ShareController(private val shareService: ShareService) { @PostMapping + @Operation(summary = "나눔 생성 API") fun createShare(@RequestBody shareRequest: ShareRequest): CommonResponse { return success(shareService.createShare(shareRequest)) } @PostMapping("/applies") + @Operation(summary = "나눔 신청 API") fun applyShare(@RequestBody applyShareRequest: ApplyShareRequest): CommonResponse { return success(shareService.applyShare(applyShareRequest)) } @GetMapping("/{id}") + @Operation(summary = "나눔 상세 조회 API") fun getShareInfo(@PathVariable(name = "id") id: Long): CommonResponse { return success(shareService.getShareInfo(id)) } @GetMapping - fun getAllShareList(): CommonResponse?> { - return success(shareService.getAllShareList()) + @Operation(summary = "모든 나눔 조회 API") + fun getAllShareList(pageable: Pageable, status: String): CommonResponse> { + return success(shareService.getAllShareList(pageable, status)) } @GetMapping("/{id}/applies") + @Operation(summary = "나눔 신청 사용자 이름 조회 API") fun getAllApplyUserList(@PathVariable(name = "id") shareId: Long): CommonResponse?> { return success(shareService.getAllApplyUserList(shareId)) } @PutMapping("/{id}") + @Operation(summary = "나눔 업데이트 API") fun updateShareInfo(@PathVariable(name = "id") shareId: Long, @RequestBody updateShareRequest: UpdateShareRequest): CommonResponse { return success(shareService.updateShareInfo(shareId, updateShareRequest)) } @PutMapping("/{id}/status") + @Operation(summary = "나눔 상태 변경 API") fun changeShareStatus(@PathVariable(name = "id") shareId: Long, updateShareStatusRequest: UpdateShareStatusRequest): CommonResponse { return success(shareService.changeShareStatus(shareId, updateShareStatusRequest)) } @DeleteMapping("/{id}") + @Operation(summary = "나눔 삭제 API") fun deleteShare(@PathVariable(name = "id") shareId: Long): CommonResponse { return success(shareService.deleteShare(shareId)) } @DeleteMapping("/applies/{id}") + @Operation(summary = "나눔 신청 취소 API") fun deleteApply(@PathVariable(name = "id") applyId: Long): CommonResponse { return success(shareService.deleteApplyShare(applyId)) } diff --git a/src/main/kotlin/mara/server/domain/share/ShareDto.kt b/src/main/kotlin/mara/server/domain/share/ShareDto.kt index acb4b8c..bcb9f42 100644 --- a/src/main/kotlin/mara/server/domain/share/ShareDto.kt +++ b/src/main/kotlin/mara/server/domain/share/ShareDto.kt @@ -1,5 +1,6 @@ package mara.server.domain.share +import org.springframework.data.domain.Page import java.time.LocalDate import java.time.LocalTime @@ -63,6 +64,6 @@ data class ShareResponse( ) } -fun List.toShareResponseList(): List { +fun Page.toShareResponseListPage(): Page { return this.map { ShareResponse(it) } } diff --git a/src/main/kotlin/mara/server/domain/share/ShareRepository.kt b/src/main/kotlin/mara/server/domain/share/ShareRepository.kt index b1ec782..62a17d7 100644 --- a/src/main/kotlin/mara/server/domain/share/ShareRepository.kt +++ b/src/main/kotlin/mara/server/domain/share/ShareRepository.kt @@ -1,8 +1,116 @@ package mara.server.domain.share +import com.querydsl.core.types.OrderSpecifier +import com.querydsl.jpa.impl.JPAQueryFactory +import mara.server.domain.friend.QFriendship.friendship +import mara.server.domain.share.QApplyShare.applyShare +import mara.server.domain.share.QShare.share import mara.server.domain.user.User +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.support.PageableExecutionUtils -interface ShareRepository : JpaRepository { - fun findAllByUser(user: User): List? +interface ShareRepository : JpaRepository, CustomShareRepository + +interface CustomShareRepository { + fun findAllMyFriendsShare(pageable: Pageable, status: ShareStatus, user: User): Page + + fun findAllMyCreatedShare(pageable: Pageable, status: ShareStatus, user: User): Page + + fun findAllMyAppliedShare(pageable: Pageable, status: ShareStatus, user: User): Page + + fun findAllMyShare(pageable: Pageable, status: ShareStatus, user: User): Page +} + +class CustomShareRepositoryImpl( + private val queryFactory: JPAQueryFactory, +) : CustomShareRepository { + + private val registeredDate: String = "registeredDate" + private val dueDate: String = "dueDate" + + override fun findAllMyFriendsShare(pageable: Pageable, status: ShareStatus, user: User): Page { + val friendsList = queryFactory.select(friendship.toUser.userId) + .from(friendship) + .where(friendship.fromUser.eq(user)) + + var sortBy = "" + pageable.sort.forEach { order -> + sortBy = order.property + } + + val query = queryFactory.selectFrom(share) + .where(share.user.userId.`in`(friendsList).and(share.status.eq(status))) + .offset(pageable.offset) + .limit(pageable.pageSize.toLong()) + .orderBy(getOrder(sortBy)).fetch() + + val count = queryFactory.select(share.count()).from(share).where(share.user.userId.`in`(friendsList).and(share.status.eq(status))).offset(pageable.offset) + .limit(pageable.pageSize.toLong()).fetchOne() + + return PageableExecutionUtils.getPage(query, pageable) { count!! } + } + + override fun findAllMyCreatedShare(pageable: Pageable, status: ShareStatus, user: User): Page { + val query = queryFactory.selectFrom(share) + .where(share.user.eq(user).and(share.status.eq(status))) + .offset(pageable.offset) + .limit(pageable.pageSize.toLong()) + .orderBy(share.createdAt.desc()).fetch() + + val count = queryFactory.select(share.count()).from(share).where(share.user.eq(user).and(share.status.eq(status))).offset(pageable.offset) + .limit(pageable.pageSize.toLong()).fetchOne() + + return PageableExecutionUtils.getPage(query, pageable) { count!! } + } + + override fun findAllMyAppliedShare( + pageable: Pageable, + + status: ShareStatus, + user: User + ): Page { + + val query = queryFactory.select(share).from(applyShare) + .join(applyShare.share, share) + .where(applyShare.user.eq(user).and(share.status.eq(status))) + .offset(pageable.offset) + .limit(pageable.pageSize.toLong()) + .orderBy(share.createdAt.desc()).fetch() + + val count = queryFactory.select(share.count()).from(applyShare) + .join(applyShare.share, share) + .where(applyShare.user.eq(user).and(share.status.eq(status))).offset(pageable.offset) + .limit(pageable.pageSize.toLong()) + .fetchOne() + + return PageableExecutionUtils.getPage(query, pageable) { count!! } + } + + override fun findAllMyShare(pageable: Pageable, status: ShareStatus, user: User): Page { + val appliedShareIdList = queryFactory.select(share.id).from(applyShare) + .join(applyShare.share, share) + .where(applyShare.user.eq(user).and(share.status.eq(status))) + .fetch() + + val query = queryFactory.selectFrom(share) + .where(share.id.`in`(appliedShareIdList).and(share.user.eq(user).and(share.status.eq(status)))).offset(pageable.offset) + .limit(pageable.pageSize.toLong()) + .orderBy(share.createdAt.desc()).fetch() + + val count = queryFactory.select(share.count()).from(share) + .where(share.id.`in`(appliedShareIdList).and(share.user.eq(user).and(share.status.eq(status)))).offset(pageable.offset) + .limit(pageable.pageSize.toLong()).fetchOne() + + return PageableExecutionUtils.getPage(query, pageable) { count!! } + } + private fun getOrder(sortBy: String): OrderSpecifier<*> { + val orderSpecifier = when (sortBy) { + registeredDate -> share.createdAt.desc() + dueDate -> share.shareDatetime.asc() + else -> throw IllegalArgumentException("Invalid sortBy value") + } + return orderSpecifier + } } diff --git a/src/main/kotlin/mara/server/domain/share/ShareService.kt b/src/main/kotlin/mara/server/domain/share/ShareService.kt index 65f60a3..cd58b15 100644 --- a/src/main/kotlin/mara/server/domain/share/ShareService.kt +++ b/src/main/kotlin/mara/server/domain/share/ShareService.kt @@ -2,6 +2,8 @@ package mara.server.domain.share import mara.server.domain.ingredient.IngredientDetailRepository import mara.server.domain.user.UserService +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.lang.RuntimeException @@ -70,13 +72,15 @@ class ShareService( return ShareResponse(getShare(shareId)) } - fun getAllShareList(): List? { - val shareList = shareRepository.findAll() - return shareList.toShareResponseList() + fun getAllShareList(pageable: Pageable, status: String): Page { + val me = userService.getCurrentLoginUser() + val shareList = shareRepository.findAllMyFriendsShare(pageable, ShareStatus.valueOf(status), me) + return shareList.toShareResponseListPage() } - fun getAllMyShareList(): List? { - return shareRepository.findAllByUser(userService.getCurrentLoginUser())?.toShareResponseList() + fun getAllMyCreatedShareList(pageable: Pageable, status: String): Page { + return shareRepository.findAllMyCreatedShare(pageable, ShareStatus.valueOf(status), userService.getCurrentLoginUser()) + .toShareResponseListPage() } fun getAllApplyUserList(shareId: Long): List? { @@ -85,10 +89,14 @@ class ShareService( return applyShareList.map { it.user.nickName }.toList() } - fun getAllMyApplyShareList(): List? { - return applyShareRepository.findAllByUser(userService.getCurrentLoginUser()) - ?.map { ShareResponse(it.share) } - ?.toList() + fun getAllMyAppliedShareList(pageable: Pageable, status: String): Page? { + return shareRepository.findAllMyAppliedShare(pageable, ShareStatus.valueOf(status), userService.getCurrentLoginUser()) + .toShareResponseListPage() + } + + fun getAllMyShareList(pageable: Pageable, status: String): Page? { + return shareRepository.findAllMyShare(pageable, ShareStatus.valueOf(status), userService.getCurrentLoginUser()) + .toShareResponseListPage() } @Transactional diff --git a/src/main/kotlin/mara/server/domain/user/UserController.kt b/src/main/kotlin/mara/server/domain/user/UserController.kt index 76856ff..0565a80 100644 --- a/src/main/kotlin/mara/server/domain/user/UserController.kt +++ b/src/main/kotlin/mara/server/domain/user/UserController.kt @@ -1,9 +1,13 @@ package mara.server.domain.user +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag import mara.server.common.CommonResponse import mara.server.common.success import mara.server.domain.share.ShareResponse import mara.server.domain.share.ShareService +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody @@ -13,46 +17,61 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/users") +@Tag(name = "유저", description = "유저 API") class UserController( private val userService: UserService, private val shareService: ShareService, ) { @PostMapping + @Operation(summary = "회원 가입 API") fun createUser(@RequestBody userRequest: UserRequest): CommonResponse { return success(userService.singUp(userRequest)) } @GetMapping("/nickname/check") + @Operation(summary = "닉네임 중복 체크 API") fun checkNickname(@RequestParam("nickname") nickname: String): CommonResponse = success(userService.checkNickName(nickname)) @GetMapping("/kakao-login") + @Operation(summary = "카카오 로그인 API") fun kakaoLogin(@RequestParam(value = "code") authorizedCode: String): CommonResponse { return success(userService.kakaoLogin(authorizedCode)) } @GetMapping("/google-login") + @Operation(summary = "구글 로그인 API") fun googleLogin(@RequestParam(value = "code") authorizedCode: String): CommonResponse { return success(userService.googleLogin(authorizedCode)) } @GetMapping("/me") + @Operation(summary = "로그인한 유저 조회 API") fun getCurrentLoginUser(): CommonResponse { return success(userService.getCurrentUserInfo()) } @GetMapping("/me/invite-code") + @Operation(summary = "유저 초대 코드 조회 API") fun getCurrentLoginUserInviteCode(): CommonResponse { return success(userService.getCurrentLoginUserInviteCode()) } - @GetMapping("/me/shares") - fun getAllMyShareList(): CommonResponse?> { - return success(shareService.getAllMyShareList()) + @GetMapping("/me/shares/created") + @Operation(summary = "유저가 올린 나눔 조회 API") + fun getAllMyCreatedShareList(pageable: Pageable, @RequestParam("status") status: String): CommonResponse> { + return success(shareService.getAllMyCreatedShareList(pageable, status)) } - @GetMapping("/me/shares/applies") - fun getAllMyApplyShareList(): CommonResponse?> { - return success(shareService.getAllMyApplyShareList()) + @GetMapping("/me/shares/applied") + @Operation(summary = "유저가 신청한 나눔 조회 API") + fun getAllMyAppliedShareList(pageable: Pageable, @RequestParam("status") status: String): CommonResponse> { + return success(shareService.getAllMyAppliedShareList(pageable, status)) + } + + @GetMapping("/me/shares/all") + @Operation(summary = "유저가 관련된 모든 나눔 조회 API") + fun getAllMyShareList(pageable: Pageable, @RequestParam("status") status: String): CommonResponse> { + return success(shareService.getAllMyShareList(pageable, status)) } }