Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class HistoryController {
private static final String DEFAULT_PAGE_SIZE = "30";
private final HistoryQueryService historyQueryService;

@GetMapping("/api/v1/history/{channelId}")
@GetMapping("/api/v1/history/forward/{channelId}")
public ChatMessagePageResponse getChatMessagesForward(
@PathVariable Long channelId,
//처음 요청시엔 서버 내에서 안읽은 메세지 값으로 설정하기 위해 false
Expand All @@ -28,4 +28,16 @@ public ChatMessagePageResponse getChatMessagesForward(
return historyQueryService.
getChatMessagesForward(channelId, cursorId, size, userInfo.userId());
}

@GetMapping("/api/v1/history/backward/{channelId}")
public ChatMessagePageResponse getChatMessagesBackward(
@PathVariable Long channelId,
//처음 요청시엔 서버 내에서 안읽은 메세지 값으로 설정하기 위해 false
// 이때 message의 objectId가 아닌 threadId가 기준
@RequestParam(required = false) Long cursorId,
@RequestParam(defaultValue = DEFAULT_PAGE_SIZE) int size,
@CurrentUser UserInfo userInfo) {
return historyQueryService.
getChatMessagesBackward(channelId, cursorId, size, userInfo.userId());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.jootalkpia.history_server.repository;

import com.jootalkpia.history_server.domain.ChatMessage;
import java.util.Optional;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
Expand All @@ -9,6 +10,13 @@

@Repository
public interface ChatMessageRepository extends MongoRepository<ChatMessage, String> {
// cursorId 이후의 메시지 조회 (페이징)

// cursorId 이후의 메시지 조회 (정방향)
List<ChatMessage> findByChannelIdAndThreadIdGreaterThanOrderByThreadIdAsc(Long channelId, Long threadId, Pageable pageable);
}

// 첫 요청 시 최신 메시지를 찾기 위한 쿼리
Optional<ChatMessage> findTopByChannelIdOrderByThreadIdDesc(Long channelId);

// 역방향 조회 (lastReadId 이하의 메시지)
List<ChatMessage> findByChannelIdAndThreadIdLessThanEqualOrderByThreadIdDesc(Long channelId, Long threadId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,29 @@ public ChatMessagePageResponse getChatMessagesForward(Long channelId, Long curso
return new ChatMessagePageResponse(hasNext, lastThreadId, responseMessages);
}

public ChatMessagePageResponse getChatMessagesBackward(Long channelId, Long cursorId, int size, Long userId) {
List<ChatMessage> chatMessageList = fetchMessagesBackward(channelId, cursorId, size, userId);

if (chatMessageList.isEmpty()) {
return new ChatMessagePageResponse(false, null, Collections.emptyList());
}

List<ThreadDto> responseMessages = convertToDtoList(chatMessageList);
boolean hasNext = determineHasNext(responseMessages, size);

// size + 1로 조회했으므로, 초과한 1개 데이터 제거
if (hasNext) {
responseMessages = responseMessages.subList(0, size);
}

Long lastThreadId = getLastThreadId(responseMessages);

return new ChatMessagePageResponse(hasNext, lastThreadId, responseMessages);
}


/**
* DB에서 채팅 메시지를 조회하는 메서드
* DB에서 채팅 메시지를 정방향으로 조회하는 메서드
*/
private List<ChatMessage> fetchMessagesForward(Long channelId, Long cursorId, int size, Long userId) {
if (cursorId == null) {
Expand All @@ -58,6 +78,34 @@ private List<ChatMessage> fetchMessagesForward(Long channelId, Long cursorId, in
channelId, cursorId, PageRequest.of(0, size + 1));
}

/**
* DB에서 채팅 메시지를 역방향으로 조회하는 메서드
*/
private List<ChatMessage> fetchMessagesBackward(Long channelId, Long cursorId, int size, Long userId) {
Long lastReadId = cursorId;

// 첫 요청 시 처리
if (cursorId == null) {
lastReadId = userChannelRepository.findLastReadIdByUserIdAndChannelId(userId, channelId);

// lastReadId가 null이면 (첫 입장 시) 가장 최신 메세지로 설정
if (lastReadId == null) {
lastReadId = chatMessageRepository.findTopByChannelIdOrderByThreadIdDesc(channelId)
.map(ChatMessage::getThreadId) // 가장 최신 메시지의 threadId 반환
.orElse(null); // 채널에 메시지가 없으면 null 반환
}

// 채널 내 메시지가 없는 경우 빈 리스트 반환
if (lastReadId == null) {
return Collections.emptyList();
}
}

// lastReadId 이하의 메시지를 최신순 (DESC)으로 조회
return chatMessageRepository.findByChannelIdAndThreadIdLessThanEqualOrderByThreadIdDesc(
channelId, lastReadId, PageRequest.of(0, size + 1));
}

/**
* ChatMessage 리스트를 ChatMessageDto 리스트로 변환하는 메서드
*/
Expand Down