diff --git a/src/main/kotlin/mara/server/domain/HealthController.kt b/src/main/kotlin/mara/server/domain/HealthController.kt index 93a359a..8f97ef6 100644 --- a/src/main/kotlin/mara/server/domain/HealthController.kt +++ b/src/main/kotlin/mara/server/domain/HealthController.kt @@ -1,13 +1,17 @@ package mara.server.domain +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RestController @RestController +@Tag(name = "서버 상태", description = "서버 상태 API") class HealthController { @GetMapping("/health-check") + @Operation(summary = "서버 상태 조회 API") fun healthCheck(): HttpStatus { return HttpStatus.OK } diff --git a/src/main/kotlin/mara/server/domain/friend/FriendRefrigeratorDto.kt b/src/main/kotlin/mara/server/domain/friend/FriendRefrigeratorDto.kt index 0a867ec..b05f02e 100644 --- a/src/main/kotlin/mara/server/domain/friend/FriendRefrigeratorDto.kt +++ b/src/main/kotlin/mara/server/domain/friend/FriendRefrigeratorDto.kt @@ -10,7 +10,7 @@ data class FriendRefrigeratorResponse( val friendRefrigeratorIngredientGroupList: List ) { constructor(user: User, refrigerator: Refrigerator, ingredientList: List) : this( - nickname = user.nickName, + nickname = user.nickname, refrigeratorId = refrigerator.refrigeratorId, friendRefrigeratorIngredientGroupList = ingredientList.map { FriendRefrigeratorIngredient(it) } ) diff --git a/src/main/kotlin/mara/server/domain/friend/FriendshipController.kt b/src/main/kotlin/mara/server/domain/friend/FriendshipController.kt index cdcdc3f..28821af 100644 --- a/src/main/kotlin/mara/server/domain/friend/FriendshipController.kt +++ b/src/main/kotlin/mara/server/domain/friend/FriendshipController.kt @@ -31,7 +31,8 @@ class FriendshipController( @Operation(summary = "친구 조회 API") fun getFriendshipList( @PageableDefault( - size = 10 + size = 10, + sort = ["createdAt"] ) pageable: Pageable ): CommonResponse> { diff --git a/src/main/kotlin/mara/server/domain/friend/FriendshipRepository.kt b/src/main/kotlin/mara/server/domain/friend/FriendshipRepository.kt index 36a1874..7536d3a 100644 --- a/src/main/kotlin/mara/server/domain/friend/FriendshipRepository.kt +++ b/src/main/kotlin/mara/server/domain/friend/FriendshipRepository.kt @@ -2,11 +2,12 @@ package mara.server.domain.friend import com.querydsl.jpa.impl.JPAQueryFactory import mara.server.domain.friend.QFriendship.friendship +import mara.server.domain.user.QUser import mara.server.domain.user.User import org.springframework.data.domain.Page -import org.springframework.data.domain.PageImpl import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.support.PageableExecutionUtils import java.util.Optional interface FriendshipRepository : JpaRepository, CustomFriendshipRepository { @@ -30,15 +31,33 @@ class CustomFriendshipRepositoryImpl( private val queryFactory: JPAQueryFactory ) : CustomFriendshipRepository { + private val createdAt: String = "createdAt" + private val nickname: String = "nickname" + override fun findByFromUserPage(user: User, pageable: Pageable): Page { - val results = queryFactory.select(friendship).from(friendship).where(friendship.fromUser.eq(user)) - .offset(pageable.offset).limit(pageable.pageSize.toLong()).fetch() + val appUser = QUser.user + val query = queryFactory.select(friendship).from(friendship).innerJoin(friendship.toUser, appUser).on( + friendship.toUser.userId.eq(appUser.userId) + ).where(friendship.fromUser.eq(user)) + .offset(pageable.offset).limit(pageable.pageSize.toLong()) + + pageable.sort.forEach { order -> + val path = when (order.property) { + createdAt -> friendship.createdAt.asc() + nickname -> appUser.nickname.asc() + else -> throw IllegalArgumentException("Unsupported sorting property: ${order.property}") + } + query.orderBy(path) + } + + val results = query.fetch() - val count = queryFactory.select(friendship.count()).from(friendship) - .where(friendship.fromUser.eq(user)) - .offset(pageable.offset).limit(pageable.pageSize.toLong()).orderBy(friendship.createdAt.asc()).fetchOne() ?: 0 + val count = queryFactory.select(friendship.count()).from(friendship).innerJoin(friendship.toUser, appUser).on( + friendship.toUser.userId.eq(appUser.userId) + ).where(friendship.fromUser.eq(user)) + .offset(pageable.offset).limit(pageable.pageSize.toLong()).fetchOne() - return PageImpl(results, pageable, count) + return PageableExecutionUtils.getPage(results, pageable) { count!! } } override fun findByFromUserAndToUser(fromUser: User, toUser: User): List { diff --git a/src/main/kotlin/mara/server/domain/friend/FriendshipService.kt b/src/main/kotlin/mara/server/domain/friend/FriendshipService.kt index fb5a8e5..2e68e12 100644 --- a/src/main/kotlin/mara/server/domain/friend/FriendshipService.kt +++ b/src/main/kotlin/mara/server/domain/friend/FriendshipService.kt @@ -1,5 +1,7 @@ package mara.server.domain.friend +import mara.server.domain.ingredient.IngredientDetailRepository +import mara.server.domain.refrigerator.RefrigeratorRepository import mara.server.domain.user.User import mara.server.domain.user.UserFriendResponse import mara.server.domain.user.UserRepository @@ -13,7 +15,9 @@ import org.springframework.transaction.annotation.Transactional class FriendshipService( private val friendshipRepository: FriendshipRepository, private val userRepository: UserRepository, - private val userService: UserService + private val userService: UserService, + private val refrigeratorRepository: RefrigeratorRepository, + private val ingredientDetailRepository: IngredientDetailRepository ) { private val ok = "ok" @@ -37,10 +41,10 @@ class FriendshipService( val currentLoginUser = userService.getCurrentLoginUser() val friendshipList = friendshipRepository.findByFromUserPage(currentLoginUser, pageable) val userFriendResponseList = friendshipList.map { friendship -> - val userId = friendship.toUser.userId - val user = - userRepository.findById(userId).orElseThrow { NoSuchElementException("해당 유저가 존재하지 않습니다. ID: $userId") } - UserFriendResponse(user) + val user = friendship.toUser + val refrigeratorList = refrigeratorRepository.findByUser(user) + val ingredientCount = ingredientDetailRepository.countByRefrigeratorList(refrigeratorList) + UserFriendResponse(user, ingredientCount) } return userFriendResponseList diff --git a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt index 4b1ca49..7fd9fea 100644 --- a/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt +++ b/src/main/kotlin/mara/server/domain/ingredient/IngredientDetailRepository.kt @@ -4,9 +4,9 @@ import com.querydsl.jpa.impl.JPAQueryFactory import mara.server.domain.ingredient.QIngredientDetail.ingredientDetail import mara.server.domain.refrigerator.Refrigerator import org.springframework.data.domain.Page -import org.springframework.data.domain.PageImpl import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.support.PageableExecutionUtils import java.time.LocalDateTime interface IngredientDetailRepository : JpaRepository, CustomIngredientDetailRepository @@ -28,6 +28,10 @@ interface CustomIngredientDetailRepository { limit: Long ): List + fun countByRefrigeratorList( + refrigeratorList: List, + ): Long + fun countByRefrigeratorListAndExpirationDay( refrigeratorList: List, expirationDay: LocalDateTime @@ -53,9 +57,9 @@ class CustomIngredientDetailRepositoryImpl( val count = queryFactory.select(ingredientDetail.count()).from(ingredientDetail) .where(ingredientDetail.refrigerator.eq(refrigerator).and(ingredientDetail.isDeleted.isFalse)) - .offset(pageable.offset).limit(pageable.pageSize.toLong()).fetchOne() ?: 0 + .offset(pageable.offset).limit(pageable.pageSize.toLong()).fetchOne() - return PageImpl(results, pageable, count) + return PageableExecutionUtils.getPage(results, pageable) { count!! } } override fun findByRefrigeratorList(refrigeratorList: List, limit: Long): List { @@ -64,6 +68,15 @@ class CustomIngredientDetailRepositoryImpl( .orderBy(ingredientDetail.expirationDate.desc()).limit(limit).fetch() } + override fun countByRefrigeratorList(refrigeratorList: List): Long { + val count = queryFactory.select(ingredientDetail.count()).from(ingredientDetail).where( + ingredientDetail.refrigerator.`in`(refrigeratorList) + .and(ingredientDetail.isDeleted.isFalse) + ).fetchOne() + + return count!! + } + override fun countByRefrigeratorListAndExpirationDay( refrigeratorList: List, expirationDay: LocalDateTime @@ -75,6 +88,6 @@ class CustomIngredientDetailRepositoryImpl( .and(ingredientDetail.isDeleted.isFalse) ).fetchOne() - return count ?: 0 + return count!! } } diff --git a/src/main/kotlin/mara/server/domain/share/ShareService.kt b/src/main/kotlin/mara/server/domain/share/ShareService.kt index cd58b15..8325f2d 100644 --- a/src/main/kotlin/mara/server/domain/share/ShareService.kt +++ b/src/main/kotlin/mara/server/domain/share/ShareService.kt @@ -86,7 +86,7 @@ class ShareService( fun getAllApplyUserList(shareId: Long): List? { val share = getShare(shareId) val applyShareList = share.applyShareList - return applyShareList.map { it.user.nickName }.toList() + return applyShareList.map { it.user.nickname }.toList() } fun getAllMyAppliedShareList(pageable: Pageable, status: String): Page? { diff --git a/src/main/kotlin/mara/server/domain/user/User.kt b/src/main/kotlin/mara/server/domain/user/User.kt index 7b7a145..4b4afc6 100644 --- a/src/main/kotlin/mara/server/domain/user/User.kt +++ b/src/main/kotlin/mara/server/domain/user/User.kt @@ -13,7 +13,7 @@ enum class Role { USER } @Entity @Table(name = "app_user") class User( - val nickName: String, + val nickname: String, val password: String, val kakaoId: Long?, val kakaoEmail: String?, diff --git a/src/main/kotlin/mara/server/domain/user/UserController.kt b/src/main/kotlin/mara/server/domain/user/UserController.kt index 0565a80..a8a3945 100644 --- a/src/main/kotlin/mara/server/domain/user/UserController.kt +++ b/src/main/kotlin/mara/server/domain/user/UserController.kt @@ -31,7 +31,7 @@ class UserController( @GetMapping("/nickname/check") @Operation(summary = "닉네임 중복 체크 API") - fun checkNickname(@RequestParam("nickname") nickname: String): CommonResponse = success(userService.checkNickName(nickname)) + fun checkNickname(@RequestParam("nickname") nickname: String): CommonResponse = success(userService.checkNickname(nickname)) @GetMapping("/kakao-login") @Operation(summary = "카카오 로그인 API") diff --git a/src/main/kotlin/mara/server/domain/user/UserDto.kt b/src/main/kotlin/mara/server/domain/user/UserDto.kt index c7fda6e..cf558ff 100644 --- a/src/main/kotlin/mara/server/domain/user/UserDto.kt +++ b/src/main/kotlin/mara/server/domain/user/UserDto.kt @@ -1,7 +1,7 @@ package mara.server.domain.user data class UserRequest( - val nickName: String, + val nickname: String, val kakaoId: Long?, val kakaoEmail: String?, val googleEmail: String?, @@ -12,14 +12,14 @@ data class CheckDuplicateResponse(val isDuplicated: Boolean) data class RefreshAccessTokenRequest(val refreshToken: String) class UserResponse( - val nickName: String?, + val nickname: String?, val kakaoId: Long?, val kakaoEmail: String?, val googleEmail: String?, val profileImage: String?, ) { constructor(user: User) : this( - nickName = user.nickName, + nickname = user.nickname, kakaoId = user.kakaoId, googleEmail = user.googleEmail, kakaoEmail = user.kakaoEmail, @@ -37,10 +37,12 @@ class UserInviteCodeResponse( class UserFriendResponse( val userId: Long, - val nickName: String + val nickname: String, + val ingredientCount: Long ) { - constructor(user: User) : this( + constructor(user: User, ingredientCount: Long) : this( userId = user.userId, - nickName = user.nickName + nickname = user.nickname, + ingredientCount = ingredientCount ) } diff --git a/src/main/kotlin/mara/server/domain/user/UserRepository.kt b/src/main/kotlin/mara/server/domain/user/UserRepository.kt index e7f412d..09a9d6b 100644 --- a/src/main/kotlin/mara/server/domain/user/UserRepository.kt +++ b/src/main/kotlin/mara/server/domain/user/UserRepository.kt @@ -10,7 +10,7 @@ interface UserRepository : JpaRepository, CustomUserRepository { fun findByKakaoId(id: Long): User? fun findByGoogleEmail(email: String): User? fun findByInviteCode(inviteCode: String): Optional - fun existsByNickName(nickName: String): Boolean + fun existsByNickname(nickname: String): Boolean } interface CustomUserRepository { diff --git a/src/main/kotlin/mara/server/domain/user/UserService.kt b/src/main/kotlin/mara/server/domain/user/UserService.kt index ccf62b1..b9a25f4 100644 --- a/src/main/kotlin/mara/server/domain/user/UserService.kt +++ b/src/main/kotlin/mara/server/domain/user/UserService.kt @@ -51,9 +51,9 @@ class UserService( } private fun createUser(userRequest: UserRequest): User { val user = User( - nickName = userRequest.nickName, + nickname = userRequest.nickname, kakaoId = userRequest.kakaoId, - password = passwordEncoder.encode(userRequest.nickName), + password = passwordEncoder.encode(userRequest.nickname), googleEmail = userRequest.googleEmail, kakaoEmail = userRequest.kakaoEmail, profileImage = ProfileImage.valueOf(userRequest.profileImage), @@ -62,7 +62,7 @@ class UserService( return userRepository.save(user) } - fun checkNickName(nickName: String): CheckDuplicateResponse = CheckDuplicateResponse(userRepository.existsByNickName(nickName)) + fun checkNickname(nickname: String): CheckDuplicateResponse = CheckDuplicateResponse(userRepository.existsByNickname(nickname)) fun kakaoLogin(authorizedCode: String): AuthDto { // 리다이랙트 url 환경 따라 다르게 전달하기 위한 구분 값