Skip to content

Commit

Permalink
Merge pull request #24 from Domitory-CheckMate/feature/5-chat
Browse files Browse the repository at this point in the history
[feat] 채팅기능
  • Loading branch information
OJOJIN authored Jan 6, 2024
2 parents 448f767 + 1ed0ae0 commit a72b8d4
Show file tree
Hide file tree
Showing 40 changed files with 1,364 additions and 6 deletions.
12 changes: 10 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,24 @@ dependencies {
annotationProcessor "jakarta.annotation:jakarta.annotation-api" // java.lang.NoClassDefFoundError (javax.annotation.Generated) 대응 코드
annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError (javax.annotation.Entity) 대응 코드

// websocket
implementation 'org.springframework.boot:spring-boot-starter-websocket'

// Messaging
implementation 'org.springframework:spring-messaging:6.1.0'

// 이메일 SMTP
implementation 'org.springframework.boot:spring-boot-starter-mail'

// thymeleaf
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'

// mongoDB
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

}

tasks.named('test') {
Expand All @@ -85,4 +93,4 @@ sourceSets {
// gradle clean 시에 QClass 디렉토리 삭제
clean {
delete file(generated)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.gachon.checkmate.domain.chat.controller;

import lombok.RequiredArgsConstructor;
import org.gachon.checkmate.domain.chat.dto.MessageType;
import org.gachon.checkmate.domain.chat.dto.request.ChatListRequestDto;
import org.gachon.checkmate.domain.chat.dto.request.ChatRequestDto;
import org.gachon.checkmate.domain.chat.dto.response.*;
import org.gachon.checkmate.domain.chat.service.ChatService;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RequiredArgsConstructor
@RestController
public class ChatController {

private final ChatService chatService;

private final SimpMessageSendingOperations sendingOperations;

// 채팅 전송
@MessageMapping("/chat")
public void sendChat(@Header("simpSessionAttributes") Map<String, Object> simpSessionAttributes,
@Payload final ChatRequestDto request) {
ChatResponseDto response = chatService.sendChat(simpSessionAttributes, request);
sendingOperations.convertAndSend("/queue/chat/"+simpSessionAttributes.get("roomId"), SocketBaseResponse.of(MessageType.CHAT, response));
}

// 채팅방 정보 조회
@MessageMapping("/room-list")
public void getChatRoomList(@Header("simpSessionAttributes") Map<String, Object> simpSessionAttributes) {
ChatRoomListResponseDto response = chatService.getChatRoomList(simpSessionAttributes);
sendingOperations.convertAndSend("/queue/user/"+simpSessionAttributes.get("userId"), SocketBaseResponse.of(MessageType.ROOM_LIST, response));
}

// 이전 채팅 불러오기
@MessageMapping("/chat-list")
public void getChatList(@Header("simpSessionAttributes") Map<String, Object> simpSessionAttributes,
@Payload final ChatListRequestDto request) {
final ChatListResponseDto response = chatService.getChatList(simpSessionAttributes, request);
sendingOperations.convertAndSend("/queue/user/" + simpSessionAttributes.get("userId"), SocketBaseResponse.of(MessageType.CHAT_LIST, response));
}

// 채팅방 입장하기
@MessageMapping("/room-enter")
public void enterRoom(@Header("simpSessionAttributes") Map<String, Object> simpSessionAttributes,
@Payload final ChatListRequestDto request) {
ChatRoomEnterResponseDto response = chatService.enterChatRoom(simpSessionAttributes, request);
sendingOperations.convertAndSend("/queue/chat/" + response.chatRoomId(), SocketBaseResponse.of(MessageType.ROOM_ENTER, response));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.gachon.checkmate.domain.chat.dto;

import lombok.Builder;
import org.gachon.checkmate.domain.chat.entity.Chat;

import java.time.LocalDateTime;

@Builder
public record ChatLastMessageDto (
String content,
LocalDateTime sendTime
) {
public static ChatLastMessageDto of(Chat chat) {
return ChatLastMessageDto.builder()
.content(chat.getContent())
.sendTime(chat.getSendTime())
.build();
}
public static ChatLastMessageDto createEmptyChat() {
return ChatLastMessageDto.builder()
.content(null)
.sendTime(null)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.gachon.checkmate.domain.chat.dto;


import lombok.Builder;
import org.gachon.checkmate.domain.chat.entity.Chat;

import java.time.LocalDateTime;

@Builder
public record ChatMessageDto (
Long userId,
String content,
Boolean isRead,
LocalDateTime sendTime
) {
public static ChatMessageDto of(Chat chat) {
return ChatMessageDto.builder()
.userId(chat.getSenderId())
.content(chat.getContent())
.isRead(chat.getIsRead())
.sendTime(chat.getSendTime())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.gachon.checkmate.domain.chat.dto;

import lombok.Builder;


@Builder
public record ChatRoomListDto(
ChatLastMessageDto lastChatInfo,
Long notReadCount,
ChatRoomListUserInfoDto userInfo
) {
public static ChatRoomListDto of(ChatLastMessageDto lastChatInfo, Long notReadCount, ChatRoomListUserInfoDto chatRoomListUserInfoDto) {
return ChatRoomListDto.builder()
.lastChatInfo(lastChatInfo)
.notReadCount(notReadCount)
.userInfo(chatRoomListUserInfoDto)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.gachon.checkmate.domain.chat.dto;

import com.querydsl.core.annotations.QueryProjection;
import org.gachon.checkmate.domain.member.entity.GenderType;

import java.time.LocalDate;

public record ChatRoomListUserInfoDto(
Long userId,
String name,
String profile,
String major,
GenderType gender,
LocalDate endDate
) {
@QueryProjection
public ChatRoomListUserInfoDto(Long userId, String name, String profile, String major, GenderType gender, LocalDate endDate) {
this.userId = userId;
this.name = name;
this.profile = profile;
this.major = major;
this.gender = gender;
this.endDate = endDate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.gachon.checkmate.domain.chat.dto;

import com.querydsl.core.annotations.QueryProjection;

import java.time.LocalDate;

public record ChatUserInfoDto(
Long userId,
String name,
String profile,
Long postId,
String title,
LocalDate endDate
) {
@QueryProjection
public ChatUserInfoDto(Long userId, String name, String profile, Long postId, String title, LocalDate endDate) {
this.userId = userId;
this.name = name;
this.profile = profile;
this.postId = postId;
this.title = title;
this.endDate = endDate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.gachon.checkmate.domain.chat.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public enum MessageType {
CHAT("CHAT"),
NEW_CHAT_NOTIFICATION("NEW_CHAT_NOTIFICATION"),
ROOM_ENTER("ROOM_ENTER"),
ROOM_LIST("ROOM_LIST"),
CHAT_LIST("CHAT_LIST");

private final String desc;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.gachon.checkmate.domain.chat.dto.request;

public record ChatListRequestDto(
Long otherUserId,
Integer pageNumber,
Integer pageSize
) {
public ChatListRequestDto(Long otherUserId, Integer pageNumber, Integer pageSize) {
this.otherUserId = otherUserId;
this.pageNumber = (pageNumber != null) ? pageNumber : 0;
this.pageSize = pageSize != null ? pageSize : 20;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.gachon.checkmate.domain.chat.dto.request;

public record ChatRequestDto(
String content
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.gachon.checkmate.domain.chat.dto.response;

import lombok.Builder;
import lombok.Getter;
import org.gachon.checkmate.domain.chat.dto.ChatMessageDto;
import org.gachon.checkmate.domain.chat.dto.ChatUserInfoDto;
import org.gachon.checkmate.domain.chat.entity.Chat;

import java.util.ArrayList;
import java.util.List;

@Builder
@Getter
public class ChatListResponseDto{

private String chatRoomId;

private ChatUserInfoDto chatUserInfoDto;

@Builder.Default
private List<ChatMessageDto> chatMessageList = new ArrayList<>();

@Builder.Default
private Boolean hasNextPage = null;

@Builder.Default
private Integer pageNumber = null;

public static ChatListResponseDto of(String chatRoomId, ChatUserInfoDto chatUserInfoDto) {
return ChatListResponseDto.builder()
.chatRoomId(chatRoomId)
.chatUserInfoDto(chatUserInfoDto)
.build();
}

public void addChatMessage(Chat chat) {
this.chatMessageList.add(ChatMessageDto.of(chat));
}

public void updatePageInfo(Boolean hasNextPage, Integer pageNumber) {
this.hasNextPage = hasNextPage;
this.pageNumber = pageNumber;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.gachon.checkmate.domain.chat.dto.response;

import lombok.Builder;
import org.gachon.checkmate.domain.chat.entity.Chat;

import java.time.LocalDateTime;

@Builder
public record ChatResponseDto (
Long senderId,
String content,
Boolean isRead,
LocalDateTime sendTime
) {
public static ChatResponseDto of(Chat chat) {
return ChatResponseDto.builder()
.senderId(chat.getSenderId())
.content(chat.getContent())
.isRead(chat.getIsRead())
.sendTime(chat.getSendTime())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.gachon.checkmate.domain.chat.dto.response;

import lombok.Builder;

@Builder
public record ChatRoomEnterResponseDto (
Long userId,
String chatRoomId
) {
public static ChatRoomEnterResponseDto of(Long userId, String chatRoomId) {
return ChatRoomEnterResponseDto.builder()
.userId(userId)
.chatRoomId(chatRoomId)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.gachon.checkmate.domain.chat.dto.response;

import lombok.Builder;
import org.gachon.checkmate.domain.chat.dto.ChatRoomListDto;

import java.util.List;


@Builder
public record ChatRoomListResponseDto(
List<ChatRoomListDto> chatRoomList
) {
public static ChatRoomListResponseDto of(List<ChatRoomListDto> chatRoomListDto) {
return ChatRoomListResponseDto.builder()
.chatRoomList(chatRoomListDto)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.gachon.checkmate.domain.chat.dto.response;

import lombok.Builder;
import org.gachon.checkmate.domain.chat.entity.Chat;

import java.time.LocalDateTime;

@Builder
public record NewChatResponseDto(
String chatRoomId,
Long senderId,
String content,
LocalDateTime sendTime
) {
public static NewChatResponseDto of(Chat chat) {
return NewChatResponseDto.builder()
.chatRoomId(chat.getChatRoomId())
.senderId(chat.getSenderId())
.content(chat.getContent())
.sendTime(chat.getSendTime())
.build();
}
}
Loading

0 comments on commit a72b8d4

Please sign in to comment.