Skip to content

Commit 6246b51

Browse files
authored
Merge pull request #90 from Dugout-Developers/feat/#89
[FEAT] 채팅 내역 조회 기능 구현
2 parents aa80b6d + 9de1934 commit 6246b51

File tree

8 files changed

+108
-26
lines changed

8 files changed

+108
-26
lines changed
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
package com.back.catchmate.domain.chat.controller;
22

33
import com.back.catchmate.domain.chat.dto.ChatRequest.ChatMessageRequest;
4-
import com.back.catchmate.domain.chat.dto.ChatResponse.MessageInfo;
4+
import com.back.catchmate.domain.chat.dto.ChatResponse.PagedChatMessageInfo;
55
import com.back.catchmate.domain.chat.service.ChatService;
6+
import com.back.catchmate.global.jwt.JwtValidation;
7+
import io.swagger.v3.oas.annotations.Operation;
68
import io.swagger.v3.oas.annotations.tags.Tag;
79
import lombok.RequiredArgsConstructor;
10+
import org.springframework.data.domain.PageRequest;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.data.domain.Sort;
813
import org.springframework.messaging.handler.annotation.DestinationVariable;
914
import org.springframework.messaging.handler.annotation.MessageMapping;
1015
import org.springframework.messaging.handler.annotation.SendTo;
1116
import org.springframework.web.bind.annotation.GetMapping;
1217
import org.springframework.web.bind.annotation.PathVariable;
1318
import org.springframework.web.bind.annotation.RequestMapping;
19+
import org.springframework.web.bind.annotation.RequestParam;
1420
import org.springframework.web.bind.annotation.RestController;
1521
import reactor.core.publisher.Mono;
1622

17-
import java.util.List;
18-
1923
@Tag(name = "채팅 관련 API")
2024
@RestController
2125
@RequestMapping("/chats")
@@ -29,9 +33,13 @@ public void sendMessage(@DestinationVariable Long chatRoomId, ChatMessageRequest
2933
chatService.sendMessage(chatRoomId, request);
3034
}
3135

32-
@Deprecated
33-
@GetMapping(value = "/{roomId}")
34-
public Mono<List<MessageInfo>> findChatMessageList(@PathVariable("roomId") Long roomId) {
35-
return chatService.findChatMessageList(roomId).collectList();
36+
@GetMapping("/{chatRoomId}")
37+
@Operation(summary = "특정 채팅방의 채팅 내역 조회 API", description = "특정 채팅방의 채팅 내역 조회 API 입니다.")
38+
public Mono<PagedChatMessageInfo> findChatMessageList(@JwtValidation Long userId,
39+
@PathVariable Long chatRoomId,
40+
@RequestParam(defaultValue = "0") int page,
41+
@RequestParam(defaultValue = "20") int size) {
42+
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Order.desc("id.timestamp")));
43+
return chatService.getChatMessageList(userId, chatRoomId, pageable);
3644
}
3745
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.back.catchmate.domain.chat.converter;
2+
3+
import com.back.catchmate.domain.chat.dto.ChatResponse;
4+
import com.back.catchmate.domain.chat.dto.ChatResponse.ChatMessageInfo;
5+
import com.back.catchmate.domain.chat.entity.ChatMessage;
6+
import org.springframework.data.domain.Pageable;
7+
import org.springframework.stereotype.Component;
8+
import reactor.core.publisher.Flux;
9+
import reactor.core.publisher.Mono;
10+
11+
import java.util.List;
12+
import java.util.stream.Collectors;
13+
14+
@Component
15+
public class ChatMessageConverter {
16+
public Mono<ChatResponse.PagedChatMessageInfo> toPagedMessageInfo(Flux<ChatMessage> chatMessageFlux, Pageable pageable) {
17+
return chatMessageFlux.collectList()
18+
.flatMap(chatMessages -> {
19+
// 전체 메시지 수를 구하고 페이지 계산
20+
int totalElements = chatMessages.size();
21+
int totalPages = (int) Math.ceil((double) totalElements / pageable.getPageSize());
22+
boolean isFirst = pageable.getPageNumber() == 0;
23+
boolean isLast = pageable.getPageNumber() == totalPages - 1;
24+
25+
// ChatMessageInfo 리스트로 변환
26+
List<ChatResponse.ChatMessageInfo> chatMessageInfoList = chatMessages.stream()
27+
.map(this::toChatMessageInfo)
28+
.collect(Collectors.toList());
29+
30+
// PagedChatMessageInfo 반환
31+
return Mono.just(ChatResponse.PagedChatMessageInfo.builder()
32+
.chatMessageInfoList(chatMessageInfoList)
33+
.totalPages(totalPages)
34+
.totalElements((long) totalElements)
35+
.isFirst(isFirst)
36+
.isLast(isLast)
37+
.build());
38+
});
39+
}
40+
41+
42+
private ChatMessageInfo toChatMessageInfo(ChatMessage chatMessage) {
43+
return ChatMessageInfo.builder()
44+
.id(chatMessage.getId())
45+
.roomId(chatMessage.getRoomId())
46+
.content(chatMessage.getContent())
47+
.senderId(chatMessage.getSenderId())
48+
.build();
49+
}
50+
}

src/main/java/com/back/catchmate/domain/chat/dto/ChatResponse.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.back.catchmate.domain.chat.dto;
22

33
import com.back.catchmate.domain.board.dto.BoardResponse.BoardInfo;
4+
import com.back.catchmate.domain.notification.dto.NotificationResponse;
45
import lombok.AllArgsConstructor;
56
import lombok.Builder;
67
import lombok.Getter;
@@ -15,13 +16,25 @@ public abstract class ChatResponse {
1516
@Builder
1617
@NoArgsConstructor
1718
@AllArgsConstructor
18-
public static class MessageInfo {
19+
public static class ChatMessageInfo {
1920
ObjectId id;
2021
private Long roomId;
2122
private String content;
2223
private Long senderId;
2324
}
2425

26+
@Getter
27+
@Builder
28+
@AllArgsConstructor
29+
@NoArgsConstructor
30+
public static class PagedChatMessageInfo {
31+
private List<ChatMessageInfo> chatMessageInfoList;
32+
private Integer totalPages;
33+
private Long totalElements;
34+
private Boolean isFirst;
35+
private Boolean isLast;
36+
}
37+
2538
@Getter
2639
@Builder
2740
@AllArgsConstructor
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.back.catchmate.domain.chat.repository;
22

33
import com.back.catchmate.domain.chat.entity.ChatMessage;
4+
import org.springframework.data.domain.Page;
5+
import org.springframework.data.domain.Pageable;
6+
import org.springframework.data.mongodb.repository.Query;
47
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
5-
import org.springframework.data.mongodb.repository.Tailable;
68
import reactor.core.publisher.Flux;
79

810
public interface ChatMessageRepository extends ReactiveMongoRepository<ChatMessage, String> {
9-
Flux<ChatMessage> findAllByRoomId(Long roomId);
11+
Flux<ChatMessage> findByRoomIdOrderByIdDesc(Long roomId, Pageable pageable);
12+
1013
}

src/main/java/com/back/catchmate/domain/chat/repository/ChatRoomRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88

99
public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {
1010
Optional<ChatRoom> findByBoardId(Long boardId);
11+
1112
boolean existsByBoardId(Long boardId);
1213
}

src/main/java/com/back/catchmate/domain/chat/repository/UserChatRoomRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
public interface UserChatRoomRepository extends JpaRepository<UserChatRoom, Long> {
1212
Optional<UserChatRoom> findByUserIdAndChatRoomId(Long userId, Long chatRoomId);
1313

14+
boolean existsByUserIdAndChatRoomId(Long userId, Long chatRoomId);
15+
1416
@Query("SELECT ucr FROM UserChatRoom ucr " +
1517
"JOIN FETCH ucr.chatRoom cr " +
1618
"WHERE ucr.user.id = :userId " +
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package com.back.catchmate.domain.chat.service;
22

33
import com.back.catchmate.domain.chat.dto.ChatRequest.ChatMessageRequest;
4-
import com.back.catchmate.domain.chat.dto.ChatResponse.MessageInfo;
5-
import reactor.core.publisher.Flux;
4+
import com.back.catchmate.domain.chat.dto.ChatResponse;
5+
import org.springframework.data.domain.Pageable;
6+
import reactor.core.publisher.Mono;
67

78
public interface ChatService {
89
void sendMessage(Long chatRoomId, ChatMessageRequest request);
910

10-
Flux<MessageInfo> findChatMessageList(Long roomId);
11+
Mono<ChatResponse.PagedChatMessageInfo> getChatMessageList(Long userId, Long roomId, Pageable pageable);
1112
}

src/main/java/com/back/catchmate/domain/chat/service/ChatServiceImpl.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package com.back.catchmate.domain.chat.service;
22

3+
import com.back.catchmate.domain.chat.converter.ChatMessageConverter;
34
import com.back.catchmate.domain.chat.dto.ChatRequest.ChatMessageRequest;
4-
import com.back.catchmate.domain.chat.dto.ChatResponse;
5-
import com.back.catchmate.domain.chat.dto.ChatResponse.MessageInfo;
5+
import com.back.catchmate.domain.chat.dto.ChatResponse.PagedChatMessageInfo;
66
import com.back.catchmate.domain.chat.entity.ChatMessage;
77
import com.back.catchmate.domain.chat.repository.ChatMessageRepository;
8+
import com.back.catchmate.domain.chat.repository.UserChatRoomRepository;
9+
import com.back.catchmate.global.error.ErrorCode;
10+
import com.back.catchmate.global.error.exception.BaseException;
811
import lombok.RequiredArgsConstructor;
912
import lombok.extern.slf4j.Slf4j;
13+
import org.springframework.data.domain.Pageable;
1014
import org.springframework.messaging.simp.SimpMessagingTemplate;
1115
import org.springframework.stereotype.Service;
1216
import org.springframework.transaction.annotation.Transactional;
1317
import reactor.core.publisher.Flux;
18+
import reactor.core.publisher.Mono;
1419

1520
import static com.back.catchmate.domain.chat.dto.ChatRequest.ChatMessageRequest.MessageType;
1621

@@ -20,6 +25,8 @@
2025
public class ChatServiceImpl implements ChatService {
2126
private final SimpMessagingTemplate messagingTemplate;
2227
private final ChatMessageRepository chatMessageRepository;
28+
private final ChatMessageConverter chatMessageConverter;
29+
private final UserChatRoomRepository userChatRoomRepository;
2330

2431
// 메시지를 특정 채팅방으로 전송
2532
@Override
@@ -42,16 +49,13 @@ public void sendMessage(Long chatRoomId, ChatMessageRequest request) {
4249
messagingTemplate.convertAndSend(destination, request);
4350
}
4451

45-
@Override
46-
@Transactional(readOnly = true)
47-
public Flux<MessageInfo> findChatMessageList(Long roomId) {
48-
return chatMessageRepository.findAllByRoomId(roomId)
49-
.map(chatMessage -> ChatResponse.MessageInfo.builder()
50-
.id(chatMessage.getId())
51-
.roomId(chatMessage.getRoomId())
52-
.content(chatMessage.getContent())
53-
.senderId(chatMessage.getSenderId())
54-
.build()
55-
);
52+
public Mono<PagedChatMessageInfo> getChatMessageList(Long userId, Long chatRoomId, Pageable pageable) {
53+
// 동기 방식으로 수정된 메서드 호출
54+
if (!userChatRoomRepository.existsByUserIdAndChatRoomId(userId, chatRoomId)) {
55+
throw new BaseException(ErrorCode.USER_CHATROOM_NOT_FOUND);
56+
}
57+
58+
Flux<ChatMessage> chatMessageList = chatMessageRepository.findByRoomIdOrderByIdDesc(chatRoomId, pageable);
59+
return chatMessageConverter.toPagedMessageInfo(chatMessageList, pageable);
5660
}
5761
}

0 commit comments

Comments
 (0)