Skip to content

Commit

Permalink
Merge pull request #201 from PSR-Co/feat/#197-getChatRooms
Browse files Browse the repository at this point in the history
[feat] 채팅방 목록 조회 API
  • Loading branch information
sojungpp committed Nov 27, 2023
2 parents eafdade + 8f2dda4 commit 2316d31
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 10 deletions.
24 changes: 21 additions & 3 deletions src/main/kotlin/com/psr/psr/chat/controller/ChatController.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.psr.psr.chat.controller

import com.psr.psr.chat.dto.request.ChatMessageReq
import com.psr.psr.chat.dto.response.GetChatRoomsRes
import com.psr.psr.chat.service.ChatService
import com.psr.psr.global.dto.BaseResponse
import com.psr.psr.global.jwt.UserAccount
Expand Down Expand Up @@ -78,12 +79,29 @@ class ChatController(
)]
)
@PostMapping("/{chatRoomId}")
fun createChatMessage(@AuthenticationPrincipal userAccount: UserAccount,
@Parameter(description = "(Long) 채팅방 id", example = "1") @PathVariable chatRoomId: Long,
@RequestBody @Valid request: ChatMessageReq
fun createChatMessage(
@AuthenticationPrincipal userAccount: UserAccount,
@Parameter(description = "(Long) 채팅방 id", example = "1") @PathVariable chatRoomId: Long,
@RequestBody @Valid request: ChatMessageReq
): BaseResponse<Unit> {
return BaseResponse(chatService.createChatMessage(userAccount.getUser(), chatRoomId, request))
}


/**
* 채팅방 목록 조회
*/
@Operation(summary = "채팅방 목록 조회(박소정)", description = "채팅방 목록을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다.")]
)
@GetMapping("/rooms")
fun getChatRooms(
@AuthenticationPrincipal userAccount: UserAccount
): BaseResponse<GetChatRoomsRes?> {
return BaseResponse(chatService.getChatRooms(userAccount.getUser()));
}


}
53 changes: 53 additions & 0 deletions src/main/kotlin/com/psr/psr/chat/dto/response/ChatRoomRes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.psr.psr.chat.dto.response

import com.fasterxml.jackson.annotation.JsonFormat
import com.psr.psr.chat.entity.ChatMessage
import com.psr.psr.chat.entity.ChatRoom
import com.psr.psr.user.entity.User
import com.querydsl.core.annotations.QueryProjection
import io.swagger.v3.oas.annotations.media.Schema
import java.time.LocalDateTime

data class ChatRoomRes @QueryProjection constructor(
@Schema(description = "채팅방 id", example = "1")
val chatRoomId: Long,

@Schema(description = "프로필 이미지", example = "imgUrl")
val profileImgUrl: String? = null,

@Schema(description = "닉네임", example = "마리")
val nickname: String,

@Schema(description = "최근 메시지", example = "안녕하세요!")
val message: String? = null,

@Schema(description = "최근 메시지 날짜", example = "11.30")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM.dd")
val date: LocalDateTime? = null,

@Schema(description = "본인이 메시지 읽음 여부", example = "false")
val isRead: Boolean,

@Schema(description = "읽지 않은 메시지 수 (없으면 0)", example = "3")
val numOfUnread: Int? = null

) {
companion object {
fun toDto(chatRoom: ChatRoom, chatMessage: ChatMessage, partner: User, numOfUnread: Int): ChatRoomRes {
val isRead: Boolean =
if (chatMessage.senderUser == partner) chatMessage.isRead
else true

return ChatRoomRes(
chatRoom.id!!,
partner.imgUrl,
partner.nickname,
chatMessage.message,
chatMessage.createdAt,
isRead,
numOfUnread
)

}
}
}
15 changes: 15 additions & 0 deletions src/main/kotlin/com/psr/psr/chat/dto/response/GetChatRoomsRes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.psr.psr.chat.dto.response

import com.querydsl.core.annotations.QueryProjection
import io.swagger.v3.oas.annotations.media.Schema

data class GetChatRoomsRes @QueryProjection constructor(
@Schema(description = "채팅방 리스트")
val noticeLists: List<ChatRoomRes>?
) {
companion object {
fun toDto(response: MutableList<ChatRoomRes>): GetChatRoomsRes? {
return GetChatRoomsRes(response)
}
}
}
7 changes: 5 additions & 2 deletions src/main/kotlin/com/psr/psr/chat/entity/ChatMessage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ data class ChatMessage(
var chatRoom: ChatRoom,

@NotNull
var message: String
var message: String,

) : BaseEntity() {
@NotNull
var isRead: Boolean = false,

) : BaseEntity() {
companion object {
fun toEntity(user: User, chatRoom: ChatRoom, message: String): ChatMessage {
return ChatMessage(
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/com/psr/psr/chat/entity/ChatRoom.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ data class ChatRoom(

@OneToOne
@JoinColumn(nullable = false, name = "order_id")
var order: Order?
var order: Order

) : BaseEntity() {
fun leave(user: User) {
Expand Down
11 changes: 11 additions & 0 deletions src/main/kotlin/com/psr/psr/chat/repository/ChatMessageCustom.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.psr.psr.chat.repository

import com.psr.psr.chat.dto.response.GetChatRoomsRes
import com.psr.psr.chat.entity.ChatRoom
import com.psr.psr.user.entity.User


interface ChatMessageCustom {
fun getRecentChat(user: User, chatRooms: List<ChatRoom>): GetChatRoomsRes?

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface ChatMessageRepository : JpaRepository<ChatMessage, Long> {
interface ChatMessageRepository : JpaRepository<ChatMessage, Long>, ChatMessageCustom {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.psr.psr.chat.repository

import com.psr.psr.chat.dto.response.ChatRoomRes
import com.psr.psr.chat.dto.response.GetChatRoomsRes
import com.psr.psr.chat.entity.ChatMessage
import com.psr.psr.chat.entity.ChatRoom
import com.psr.psr.chat.entity.QChatMessage.chatMessage
import com.psr.psr.global.Constant.UserStatus.UserStatus.ACTIVE_STATUS
import com.psr.psr.user.entity.User
import com.querydsl.jpa.impl.JPAQueryFactory
import org.springframework.stereotype.Component

@Component
class ChatMessageRepositoryImpl(
private val queryFactory: JPAQueryFactory
) : ChatMessageCustom {
override fun getRecentChat(user: User, chatRooms: List<ChatRoom>): GetChatRoomsRes? {

val response: MutableList<ChatRoomRes> = mutableListOf()

for (chatRoom in chatRooms) {
val chat: ChatMessage = queryFactory
.selectFrom(chatMessage)
.where(
chatMessage.chatRoom.eq(chatRoom),
chatMessage.status.eq(ACTIVE_STATUS),
)
.orderBy(chatMessage.updatedAt.desc())
.fetchFirst()

val numOfUnread: Int = queryFactory
.select(chatMessage)
.from(chatMessage)
.where(
chatMessage.chatRoom.eq(chatRoom),
chatMessage.status.eq(ACTIVE_STATUS),
chatMessage.isRead.eq(false),
!chatMessage.senderUser.eq(user)
)
.fetch()
.size

val partner: User =
if (user == chatRoom.order.user) chatRoom.order.product.user
else chatRoom.order.user

val chatRoomRes: ChatRoomRes = ChatRoomRes.toDto(chatRoom, chat, partner, numOfUnread)
response.add(chatRoomRes)
}

return GetChatRoomsRes.toDto(response)
}

}
10 changes: 10 additions & 0 deletions src/main/kotlin/com/psr/psr/chat/repository/ChatRoomCustom.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.psr.psr.chat.repository

import com.psr.psr.chat.entity.ChatRoom
import com.psr.psr.user.entity.User


interface ChatRoomCustom {
fun getChatRooms(user: User): List<ChatRoom>?

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.psr.psr.chat.repository

import com.psr.psr.chat.entity.ChatRoom
import com.psr.psr.order.entity.Order
import com.psr.psr.user.entity.User
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface ChatRoomRepository: JpaRepository<ChatRoom, Long> {
interface ChatRoomRepository : JpaRepository<ChatRoom, Long>, ChatRoomCustom {
fun deleteBySenderUser(user: User)
fun deleteByReceiverUser(user: User)
fun findByIdAndStatus(chatRoomId: Long, activeStatus: String): ChatRoom?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.psr.psr.chat.repository

import com.psr.psr.chat.entity.ChatRoom
import com.psr.psr.chat.entity.QChatRoom.chatRoom
import com.psr.psr.global.Constant.UserStatus.UserStatus.ACTIVE_STATUS
import com.psr.psr.user.entity.User
import com.querydsl.jpa.impl.JPAQueryFactory
import org.springframework.stereotype.Component

@Component
class ChatRoomRepositoryImpl(
private val queryFactory: JPAQueryFactory
) : ChatRoomCustom {
override fun getChatRooms(user: User): List<ChatRoom> {
return queryFactory
.selectFrom(chatRoom)
.where(
chatRoom.status.eq(ACTIVE_STATUS),
(chatRoom.senderUser.eq(user)).or(chatRoom.receiverUser.eq(user))
)
.orderBy(chatRoom.updatedAt.desc())
.fetch()
}

}
9 changes: 8 additions & 1 deletion src/main/kotlin/com/psr/psr/chat/service/ChatService.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.psr.psr.chat.service

import com.psr.psr.chat.dto.request.ChatMessageReq
import com.psr.psr.chat.dto.response.GetChatRoomsRes
import com.psr.psr.chat.entity.ChatMessage
import com.psr.psr.chat.entity.ChatRoom
import com.psr.psr.chat.repository.ChatMessageRepository
Expand Down Expand Up @@ -36,7 +37,7 @@ class ChatService(
}

private fun checkChatRoom(chatRoom: ChatRoom) {
if(chatRoom.senderUser==null && chatRoom.receiverUser==null)
if (chatRoom.senderUser == null && chatRoom.receiverUser == null)
chatRoomRepository.delete(chatRoom)
}

Expand All @@ -46,4 +47,10 @@ class ChatService(
?: throw BaseException(BaseResponseCode.NOT_FOUND_CHATROOM)
chatMessageRepository.save(ChatMessage.toEntity(user, chatRoom, request.message))
}

fun getChatRooms(user: User): GetChatRoomsRes? {
val chatRooms: List<ChatRoom>? = chatRoomRepository.getChatRooms(user)
if (chatRooms?.isEmpty() == true) return null;
return chatMessageRepository.getRecentChat(user, chatRooms!!)
}
}

0 comments on commit 2316d31

Please sign in to comment.