Skip to content

Commit

Permalink
[FEAT] 채팅방 상세 데이터 조회, 채팅 생성 로직 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
tidavid1 committed Feb 26, 2024
1 parent 0983710 commit 4248f4a
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package io.oeid.mogakgo.domain.chat.application;

import io.oeid.mogakgo.domain.chat.application.dto.req.ChatRoomCreateReq;
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomCreateRes;
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomDataRes;
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomPublicRes;
import io.oeid.mogakgo.domain.chat.entity.document.ChatRoom;
import io.oeid.mogakgo.domain.chat.infrastructure.ChatRepository;
import io.oeid.mogakgo.domain.chat.infrastructure.ChatRoomJpaRepository;
import io.oeid.mogakgo.domain.matching.exception.MatchingException;
import io.oeid.mogakgo.domain.project.domain.entity.Project;
import io.oeid.mogakgo.domain.project.exception.ProjectException;
import io.oeid.mogakgo.domain.project.infrastructure.ProjectJpaRepository;
import io.oeid.mogakgo.domain.user.application.UserCommonService;
import io.oeid.mogakgo.domain.user.domain.User;
import io.oeid.mogakgo.exception.code.ErrorCode404;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -19,21 +27,40 @@
public class ChatService {

private final UserCommonService userCommonService;
private final ChatRoomJpaRepository chatRoomJpaRepository;
private final ChatRoomJpaRepository chatRoomRepository;
private final ChatRepository chatRepository;
private final ProjectJpaRepository projectRepository;

public List<ChatRoom> findAllChatRoomByUserId(Long userId) {
// 채팅방 리스트 조회
// TODO 마지막 채팅 기록 가져오기 구현
public List<ChatRoomPublicRes> findAllChatRoomByUserId(Long userId) {
User user = userCommonService.getUserById(userId);
return chatRoomJpaRepository.findAllByUserId(user.getId());
return null;
//return chatRoomRepository.findAllByUserId(user.getId());
}

// 채팅방 생성
@Transactional
public ChatRoomCreateRes createChatRoom(Long creatorId, Long senderId, String name) {
public ChatRoomCreateRes createChatRoom(Long creatorId, ChatRoomCreateReq request) {
Project project = projectRepository.findById(request.getProjectId())
.orElseThrow(() -> new MatchingException(ErrorCode404.PROJECT_NOT_FOUND));
User creator = userCommonService.getUserById(creatorId);
User sender = userCommonService.getUserById(senderId);
ChatRoom chatRoom = chatRoomJpaRepository.save(
ChatRoom.builder().creator(creator).sender(sender).name(name).build());
User sender = userCommonService.getUserById(request.getSenderId());
ChatRoom chatRoom = chatRoomRepository.save(
ChatRoom.builder().project(project).creator(creator).sender(sender).build());
chatRepository.createCollection(chatRoom.getId());
return ChatRoomCreateRes.from(chatRoom);
}

// 채팅방 조회
public ChatRoomDataRes findAllChatInChatRoom(Long userId, String chatRoomId) {
var user = userCommonService.getUserById(userId);
var chatRoom = chatRoomRepository.findById(chatRoomId)
.orElseThrow(() -> new MatchingException(ErrorCode404.CHAT_ROOM_NOT_FOUND));
chatRoom.validateContainsUser(user);
var project = projectRepository.findById(chatRoom.getProject().getId())
.orElseThrow(() -> new ProjectException(ErrorCode404.PROJECT_NOT_FOUND));
var chatList = chatRepository.findAllByCollection(chatRoomId);
return ChatRoomDataRes.of(project.getMeetingInfo(), chatList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.oeid.mogakgo.domain.chat.application.dto.req;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class ChatRoomCreateReq {
private Long projectId;
private Long senderId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
public class ChatRoomCreateRes {

private String roomId;
private String name;
private Long projectId;
private Long creatorId;
private Long senderId;
private ChatStatus chatStatus;

private ChatRoomCreateRes(String roomId, String name, Long creatorId, Long senderId,
private ChatRoomCreateRes(String roomId, Long projectId, Long creatorId, Long senderId,
ChatStatus chatStatus) {
this.roomId = roomId;
this.name = name;
this.projectId = projectId;
this.creatorId = creatorId;
this.senderId = senderId;
this.chatStatus = chatStatus;
}

public static ChatRoomCreateRes from(ChatRoom chatRoom) {
return new ChatRoomCreateRes(chatRoom.getId(), chatRoom.getName(),
return new ChatRoomCreateRes(chatRoom.getId(), chatRoom.getProject().getId(),
chatRoom.getCreator().getId(), chatRoom.getSender().getId(), chatRoom.getStatus());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.oeid.mogakgo.domain.chat.application.dto.res;

import io.oeid.mogakgo.domain.chat.application.vo.ChatData;
import io.oeid.mogakgo.domain.chat.application.vo.ChatRoomProjectInfo;
import io.oeid.mogakgo.domain.chat.entity.document.ChatMessage;
import io.oeid.mogakgo.domain.project.domain.entity.vo.MeetingInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Schema(description = "채팅방 데이터 조회 응답")
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor
public class ChatRoomDataRes {

private ChatRoomProjectInfo project;
private List<ChatData> data;

public static ChatRoomDataRes of(MeetingInfo meetingInfo, List<ChatMessage> data) {
ChatRoomProjectInfo project = new ChatRoomProjectInfo(meetingInfo.getMeetDetail(),
meetingInfo.getMeetStartTime(), meetingInfo.getMeetEndTime());
return new ChatRoomDataRes(project, data.stream().map(ChatData::from).toList());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
package io.oeid.mogakgo.domain.chat.application.dto.res;

import io.oeid.mogakgo.domain.chat.application.vo.ChatUserInfo;
import io.oeid.mogakgo.domain.chat.entity.enums.ChatStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Schema(description = "채팅방 리스트 조회 응답")
@Getter
@AllArgsConstructor
public class ChatRoomPublicRes {
@Schema(description = "프로젝트 ID")
private Long projectId;
@Schema(description = "채팅방 ID")
private String chatRoomId;
@Schema(description = "마지막 메시지")
private String lastMessage;
@Schema(description = "마지막 메시지 생성 시간")
private LocalDateTime lastMessageCreatedAt;
@Schema(description = "채팅방 상태")
private ChatStatus status;

private List<ChatUserInfo> profiles;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.oeid.mogakgo.domain.chat.application.vo;

import io.oeid.mogakgo.domain.chat.entity.document.ChatMessage;
import io.oeid.mogakgo.domain.chat.entity.enums.ChatMessageType;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Schema(description = "채팅 데이터")
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ChatData {

@Schema(description = "메시지 타입")
private ChatMessageType messageType;
@Schema(description = "보낸 사람 ID")
private Long senderId;
@Schema(description = "메시지")
private String message;
@Schema(description = "생성 시간")
private LocalDateTime createdAt;

public static ChatData from(ChatMessage chatMessage) {
return new ChatData(chatMessage.getMessageType(), chatMessage.getSenderId(),
chatMessage.getMessage(), chatMessage.getCreatedAt());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.oeid.mogakgo.domain.chat.application.vo;

import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Schema(description = "채팅방 프로젝트 정보")
@Getter
@AllArgsConstructor
public class ChatRoomProjectInfo {

@Schema(description = "프로젝트 설명")
private String meetDetail;
@Schema(description = "프로젝트 시작 시간")
private LocalDateTime meetStartTime;
@Schema(description = "프로젝트 종료 시간")
private LocalDateTime meetEndTime;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.oeid.mogakgo.domain.chat.application.vo;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Schema(description = "채팅방 유저 정보")
@Getter
@AllArgsConstructor
public class ChatUserInfo {
@Schema(description = "유저 ID")
private Long userId;
@Schema(description = "유저 이름")
private String username;
@Schema(description = "유저 프로필 이미지 URL")
private String avatarUrl;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
public class ChatMessage {

private ChatMessageType messageType;
private String roomId;
private String senderId;
private String chatRoomId;
private Long senderId;
private String message;
private LocalDateTime createdAt;

public ChatMessage(ChatMessageType messageType, String roomId, String senderId, String message) {
public ChatMessage(ChatMessageType messageType, String chatRoomId, Long senderId, String message) {
this.messageType = messageType;
this.roomId = roomId;
this.chatRoomId = chatRoomId;
this.senderId = senderId;
this.message = message;
this.createdAt = LocalDateTime.now();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.oeid.mogakgo.domain.chat.entity.enums.ChatStatus;
import io.oeid.mogakgo.domain.chat.exception.ChatException;
import io.oeid.mogakgo.domain.project.domain.entity.Project;
import io.oeid.mogakgo.domain.user.domain.User;
import io.oeid.mogakgo.exception.code.ErrorCode400;
import jakarta.persistence.Column;
Expand Down Expand Up @@ -31,8 +32,9 @@ public class ChatRoom {
@GeneratedValue(strategy = GenerationType.UUID)
private String id;

@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "project_id")
private Project project;

@ManyToOne
@JoinColumn(name = "creator_id")
Expand All @@ -46,10 +48,11 @@ public class ChatRoom {
@Column(name = "status")
private ChatStatus status;


@Builder
private ChatRoom(String name, User creator, User sender) {
this.name = name;
private ChatRoom(Project project, User creator, User sender) {
validateUsers(creator, sender);
this.project = project;
this.creator = creator;
this.sender = sender;
this.status = ChatStatus.OPEN;
Expand All @@ -65,4 +68,10 @@ private void validateUsers(User creator, User sender) {
}
}

public void validateContainsUser(User user) {
if (!creator.equals(user) && !sender.equals(user)) {
throw new ChatException(ErrorCode400.CHAT_ROOM_USER_NOT_CONTAINS);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void handleMessage(WebSocketSession session, WebSocketMessage<?> message)
TextMessage textMessage = (TextMessage) message;
String payload = textMessage.getPayload();
ChatMessage chatMessage = objectMapper.readValue(payload, ChatMessage.class);
ChatRoom chatRoom = chatWebSocketService.findChatRoomById(chatMessage.getRoomId());
ChatRoom chatRoom = chatWebSocketService.findChatRoomById(chatMessage.getChatRoomId());
switch (chatMessage.getMessageType()) {
case ENTER -> chatWebSocketService.addSessionToRoom(chatRoom.getId(), session);
case QUIT -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.oeid.mogakgo.domain.chat.presentation;

import io.oeid.mogakgo.common.annotation.UserId;
import io.oeid.mogakgo.domain.chat.application.ChatService;
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomDataRes;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/chat")
public class ChatController {

private final ChatService chatService;

@GetMapping
public void getChatRoomList(@UserId Long userId) {
chatService.findAllChatRoomByUserId(userId);
}

@GetMapping("/{chatRoomId}")
public ResponseEntity<ChatRoomDataRes> getChatRoomDetailData(@UserId Long userId,
@PathVariable String chatRoomId) {
return ResponseEntity.ok(chatService.findAllChatInChatRoom(userId, chatRoomId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public enum ErrorCode400 implements ErrorCode {

CHAT_ROOM_CLOSED("E110101", "채팅방이 종료되어 채팅을 할 수 없습니다."),
CHAT_ROOM_USER_CANNOT_DUPLICATE("E110102", "채팅방에 중복된 유저가 있습니다."),
CHAT_ROOM_USER_NOT_CONTAINS("E110103", "채팅방에 해당 유저가 없습니다."),
;

private final HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
Expand Down

0 comments on commit 4248f4a

Please sign in to comment.