Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.back.domain.chat.dm.controller;

public class PrivateChatWebSocketController {
}
51 changes: 0 additions & 51 deletions src/main/java/com/back/domain/chat/dto/ChatMessageDto.java

This file was deleted.

43 changes: 0 additions & 43 deletions src/main/java/com/back/domain/chat/dto/ChatPageResponse.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.back.domain.chat.controller;
package com.back.domain.chat.room.controller;

import com.back.domain.chat.dto.ChatPageResponse;
import com.back.domain.chat.service.ChatService;
import com.back.domain.chat.room.dto.RoomChatPageResponse;
import com.back.domain.chat.room.service.RoomChatService;
import com.back.global.common.dto.RsData;
import com.back.global.security.CustomUserDetails;
import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -18,22 +18,22 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
@Tag(name = "Chat API", description = "채팅 메시지 조회 관련 API")
public class ChatApiController {
@Tag(name = "RoomChat API", description = "스터디룸 채팅 메시지 조회 관련 API")
public class RoomChatApiController {

private final ChatService chatService;
private final RoomChatService roomChatService;

// 방 채팅 메시지 조회 (페이징, 특정 시간 이전 메시지)
@GetMapping("/rooms/{roomId}/messages")
@Operation(summary = "채팅방 메시지 목록 조회", description = "특정 채팅방의 이전 메시지 기록을 페이징하여 조회합니다.")
public ResponseEntity<RsData<ChatPageResponse>> getRoomChatMessages(
@Operation(summary = "스터디룸 채팅방 메시지 목록 조회", description = "특정 채팅방의 이전 메시지 기록을 페이징하여 조회합니다.")
public ResponseEntity<RsData<RoomChatPageResponse>> getRoomChatMessages(
@PathVariable Long roomId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime before,
@AuthenticationPrincipal CustomUserDetails userDetails) {

ChatPageResponse chatHistory = chatService.getRoomChatHistory(roomId, page, size, before);
RoomChatPageResponse chatHistory = roomChatService.getRoomChatHistory(roomId, page, size, before);

return ResponseEntity
.status(HttpStatus.OK)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.back.domain.chat.controller;
package com.back.domain.chat.room.controller;

import com.back.domain.studyroom.entity.RoomChatMessage;
import com.back.domain.chat.dto.ChatMessageDto;
import com.back.domain.chat.room.dto.RoomChatMessageDto;
import com.back.global.security.CustomUserDetails;
import com.back.global.websocket.dto.WebSocketErrorResponse;
import com.back.domain.chat.service.ChatService;
import com.back.domain.chat.room.service.RoomChatService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.handler.annotation.DestinationVariable;
Expand All @@ -18,10 +18,10 @@

@Controller
@RequiredArgsConstructor
@Tag(name = "Chat WebSocket", description = "STOMP를 이용한 실시간 채팅 WebSocket 컨트롤러 (Swagger에서 직접 테스트 불가)")
public class ChatWebSocketController {
@Tag(name = "RoomChat WebSocket", description = "STOMP를 이용한 실시간 채팅 WebSocket 컨트롤러 (Swagger에서 직접 테스트 불가)")
public class RoomChatWebSocketController {

private final ChatService chatService;
private final RoomChatService roomChatService;
private final SimpMessagingTemplate messagingTemplate;

/**
Expand All @@ -35,7 +35,7 @@ public class ChatWebSocketController {
*/
@MessageMapping("/chat/room/{roomId}")
public void handleRoomChat(@DestinationVariable Long roomId,
ChatMessageDto chatMessage,
RoomChatMessageDto chatMessage,
SimpMessageHeaderAccessor headerAccessor,
Principal principal) {

Expand All @@ -51,25 +51,26 @@ public void handleRoomChat(@DestinationVariable Long roomId,
String currentUserNickname = userDetails.getUsername();

// 메시지 정보 보완
chatMessage.setRoomId(roomId);
chatMessage.setUserId(currentUserId);
chatMessage.setNickname(currentUserNickname);
RoomChatMessageDto enrichedMessage = chatMessage
.withRoomId(roomId)
.withUserId(currentUserId)
.withNickname(currentUserNickname);

// DB에 메시지 저장
RoomChatMessage savedMessage = chatService.saveRoomChatMessage(chatMessage);
RoomChatMessage savedMessage = roomChatService.saveRoomChatMessage(enrichedMessage);

// 저장된 메시지 정보로 응답 DTO 생성
ChatMessageDto responseMessage = ChatMessageDto.builder()
.messageId(savedMessage.getId())
.roomId(roomId)
.userId(savedMessage.getUser().getId())
.nickname(savedMessage.getUser().getNickname())
.profileImageUrl(savedMessage.getUser().getProfileImageUrl())
.content(savedMessage.getContent())
.messageType(chatMessage.getMessageType())
.attachment(null) // 텍스트 채팅에서는 null
.createdAt(savedMessage.getCreatedAt())
.build();
RoomChatMessageDto responseMessage = RoomChatMessageDto.createResponse(
savedMessage.getId(),
roomId,
savedMessage.getUser().getId(),
savedMessage.getUser().getNickname(),
savedMessage.getUser().getProfileImageUrl(),
savedMessage.getContent(),
chatMessage.messageType(),
null, // 텍스트 채팅에서는 null
savedMessage.getCreatedAt()
);

// 해당 방의 모든 구독자에게 브로드캐스트
messagingTemplate.convertAndSend("/topic/room/" + roomId, responseMessage);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.back.domain.chat.room.dto;

import java.time.LocalDateTime;

public record RoomChatMessageDto(
// WebSocket Request
String content,
String messageType,
Long attachmentId,

// WebSocket Response
Long messageId,
Long roomId,
Long userId,
String nickname,
String profileImageUrl,
AttachmentDto attachment,
LocalDateTime createdAt
) {

// 첨부파일 DTO (나중에 파일 기능 구현 시 사용)
public record AttachmentDto(
Long id,
String originalName,
String url,
Long size,
String mimeType
) {}

// 텍스트 채팅 요청 생성 헬퍼
public static RoomChatMessageDto createRequest(String content, String messageType) {
return new RoomChatMessageDto(
content,
messageType,
null, // attachmentId - 텍스트 채팅에서는 null
null, // messageId
null, // roomId
null, // userId
null, // nickname
null, // profileImageUrl
null, // attachment
null // createdAt
);
}

// 필드 업데이트
public RoomChatMessageDto withRoomId(Long roomId) {
return new RoomChatMessageDto(content, messageType, attachmentId, messageId, roomId, userId, nickname, profileImageUrl, attachment, createdAt);
}

public RoomChatMessageDto withUserId(Long userId) {
return new RoomChatMessageDto(content, messageType, attachmentId, messageId, roomId, userId, nickname, profileImageUrl, attachment, createdAt);
}

public RoomChatMessageDto withNickname(String nickname) {
return new RoomChatMessageDto(content, messageType, attachmentId, messageId, roomId, userId, nickname, profileImageUrl, attachment, createdAt);
}

// Response용 생성자
public static RoomChatMessageDto createResponse(
Long messageId, Long roomId, Long userId, String nickname,
String profileImageUrl, String content, String messageType,
AttachmentDto attachment, LocalDateTime createdAt) {
return new RoomChatMessageDto(
content, messageType, null, // attachmentId는 request용이므로 null
messageId, roomId, userId, nickname, profileImageUrl, attachment, createdAt
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.back.domain.chat.room.dto;

import java.util.List;

public record RoomChatPageResponse(
List<RoomChatMessageDto> content,
PageableDto pageable,
long totalElements
) {

// 페이지 정보 DTO
public record PageableDto(
int page,
int size,
boolean hasNext
) {}

// 페이지 응답 생성
public static RoomChatPageResponse from(
org.springframework.data.domain.Page<?> page,
List<RoomChatMessageDto> convertedContent) {

return new RoomChatPageResponse(
convertedContent,
new PageableDto(
page.getNumber(),
page.getSize(),
page.hasNext()
),
page.getTotalElements()
);
}

// 빈 페이지 응답 생성
public static RoomChatPageResponse empty(int page, int size) {
return new RoomChatPageResponse(
List.of(),
new PageableDto(page, size, false),
0L
);
}

// 단일 페이지 응답 생성 (테스트용)
public static RoomChatPageResponse of(List<RoomChatMessageDto> content,
int page,
int size,
boolean hasNext,
long totalElements) {
return new RoomChatPageResponse(
content,
new PageableDto(page, size, hasNext),
totalElements
);
}
}
Loading