Skip to content

Commit

Permalink
Merge pull request #19 from Leets-Official/feat/#14/채팅-비지니스로직-개발
Browse files Browse the repository at this point in the history
[Feat] #19 채팅 비지니스 로직 구현
  • Loading branch information
koreaioi authored Nov 8, 2024
2 parents 1b334c6 + b3169d3 commit 44cb7db
Show file tree
Hide file tree
Showing 32 changed files with 588 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.leets.X.domain.chat.controller;

import com.leets.X.domain.chat.dto.request.ChatRoomCheckRequstDto;
import com.leets.X.domain.chat.dto.request.FindChatRoomRequestDto;
import com.leets.X.domain.chat.dto.response.ChatRoomResponseDto;
import com.leets.X.domain.chat.service.ChatRoomService;
import com.leets.X.global.common.response.ResponseDto;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import static com.leets.X.domain.chat.controller.ResponseMessage.*;

@Slf4j
@RestController
@RequestMapping("/api/v1/chatRoom")
@RequiredArgsConstructor
public class ChatRoomController {

private final ChatRoomService chatRoomService;

@PostMapping
public ResponseDto<ChatRoomResponseDto> createChatRoom(@RequestBody @Valid FindChatRoomRequestDto findChatRoomRequestDto){
ChatRoomResponseDto response = chatRoomService.saveChatRoom(findChatRoomRequestDto);
return ResponseDto.response(CHATROOM_CREATE_SUCCESS.getCode(), CHATROOM_CREATE_SUCCESS.getMessage(), response);
}



// user1Id와 user2Id의 채팅방이 있는 지 조회
@GetMapping("/{user1Id}/{user2Id}")
public ResponseDto<ChatRoomResponseDto> existChatRoom(@PathVariable Long user1Id, @PathVariable Long user2Id){
ChatRoomResponseDto response = chatRoomService.findUser1User2ChatRoom(user1Id , user2Id);

return ResponseDto.response(GET_ROOMID.getCode(), GET_ROOMID.getMessage(), response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.leets.X.domain.chat.controller;

import com.leets.X.domain.chat.dto.request.GetChatRoomRequestDto;
import com.leets.X.domain.chat.dto.response.ChattingDto;
import com.leets.X.domain.chat.dto.response.ChattingListResponseDto;
import com.leets.X.domain.chat.service.ChattingService;
import com.leets.X.global.common.response.ResponseDto;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static com.leets.X.domain.chat.controller.ResponseMessage.GET_CHATROOM;
import static com.leets.X.domain.chat.controller.ResponseMessage.GET_CHATTING_LIST;

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

private final ChattingService chattingService;

// 채팅방 하나를 조회해준다. (대화 내역을 돌려준다는 의미)
@GetMapping("/chatting/{roomId}/{page}/{size}")
public ResponseDto<ChattingDto> findChatting(@PathVariable Long roomId, @PathVariable Integer page, @PathVariable Integer size) {
ChattingDto response = chattingService.getChatRoom(roomId, page, size);
return ResponseDto.response(GET_CHATROOM.getCode(), GET_CHATROOM.getMessage(), response);
}


@GetMapping("/chattingList/{userId}")
public ResponseDto<List<ChattingListResponseDto>> findChattingList(@PathVariable Long userId){
List<ChattingListResponseDto> response = chattingService.getChattingList(userId);
return ResponseDto.response(GET_CHATTING_LIST.getCode(), GET_CHATTING_LIST.getMessage(), response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.leets.X.domain.chat.controller;


import com.leets.X.domain.chat.dto.request.MessageDto;
import com.leets.X.domain.chat.service.PublishMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
@RequiredArgsConstructor
public class PublishMessageController {

private final PublishMessageService publishMessageService;

// 클라이언트는 "/pub/chats/messages" 로 보낸다.
@MessageMapping("/chats/messages")
public void message(MessageDto messageDto) {
publishMessageService.publishMessage(messageDto);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.leets.X.domain.chat.controller;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum ResponseMessage {

CHATROOM_CREATE_SUCCESS(201,"채팅방 생성에 성공했습니다."),
GET_CHATROOM(200, "하나의 채팅방을 반환합니다."),
GET_ROOMID(200, "채팅방 번호를 반환합니다."),
GET_CHATTING_LIST(200, "모든 채팅방 목록을 반환합니다.");

private final int code;
private final String message;
}
2 changes: 2 additions & 0 deletions src/main/java/com/leets/X/domain/chat/dto/PublishMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class PublishMessage implements Serializable {

private Long senderId;

private String senderName;

private String content;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.leets.X.domain.chat.dto.request;

import jakarta.validation.constraints.NotNull;

public record ChatRoomCheckRequstDto(

@NotNull Long user1Id,
@NotNull Long user2Id

) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.leets.X.domain.chat.dto.request;

import jakarta.validation.constraints.NotNull;

public record FindChatRoomRequestDto(

@NotNull Long user1Id,
@NotNull Long user2Id
){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.leets.X.domain.chat.dto.request;

import jakarta.validation.constraints.NotNull;

public record GetChatRoomRequestDto(

@NotNull Long roomId,
@NotNull Integer size,
@NotNull Integer page

){
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class MessageDto implements Serializable {

private Long senderId;

private String senderName;

private String content;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.leets.X.domain.chat.dto.response;

import com.leets.X.domain.chat.entity.ChatMessage;

import java.time.LocalDateTime;

public record ChatMessageResponseDto(

Long senderId,
String senderName,
String content,
LocalDateTime createdAt

) {
public static ChatMessageResponseDto fromEntity(ChatMessage chatMessage){
return new ChatMessageResponseDto(
chatMessage.getSenderId(),
chatMessage.getSenderName(),
chatMessage.getContent(),
chatMessage.getCreatedAt()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.leets.X.domain.chat.dto.response;

public record ChatRoomResponseDto (

Long roomId

){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.leets.X.domain.chat.dto.response;

import java.util.List;

public record ChattingDto(
Long user1Id,
Long user2Id,
String user1Name,
String user2Name,
List<ChatMessageResponseDto> chatMessageList
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.leets.X.domain.chat.dto.response;

import com.leets.X.domain.chat.entity.ChatRoom;

public record ChattingListResponseDto(
Long roomId,
Long user1Id,
Long user2Id,
String user1Name,
String user2Name,
LatestMessageDto latestMessageDto
) {
public static ChattingListResponseDto of(ChatRoom chatRoom, LatestMessageDto latestMessageDto) {
return new ChattingListResponseDto(
chatRoom.getId(),
chatRoom.getUser1().getId(),
chatRoom.getUser2().getId(),
chatRoom.getUser1().getCustomId(),
chatRoom.getUser2().getCustomId(),
latestMessageDto
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.leets.X.domain.chat.dto.response;

import com.leets.X.domain.chat.entity.ChatMessage;

import java.time.LocalDateTime;


public record LatestMessageDto(

String content,
LocalDateTime createdAt

) {
public static LatestMessageDto of(ChatMessage message) {
return new LatestMessageDto(message.getContent(), message.getCreatedAt());
}
}
14 changes: 11 additions & 3 deletions src/main/java/com/leets/X/domain/chat/entity/ChatMessage.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.leets.X.domain.chat.entity;


import com.fasterxml.jackson.annotation.JsonFormat;
import com.leets.X.domain.chat.dto.PublishMessage;
import com.leets.X.global.common.domain.BaseTimeEntity;
import jakarta.persistence.Id;
Expand All @@ -10,25 +11,32 @@

import java.time.LocalDateTime;

@Document
@Document(collection = "chatMessage")
@Getter
@Builder
public class ChatMessage extends BaseTimeEntity {
public class ChatMessage {

@Id
private Long id; // MongoDb에서 사용하는 ObjectId
private String id; // MongoDb에서 사용하는 ObjectId

private Long roomId;

private Long senderId;

private String senderName;

private String content;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdAt;

public static ChatMessage of(PublishMessage publishMessage) {
return ChatMessage.builder()
.roomId(publishMessage.getRoomId())
.senderId(publishMessage.getSenderId())
.senderName(publishMessage.getSenderName())
.content(publishMessage.getContent())
.createdAt(LocalDateTime.now())
.build();
}

Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/leets/X/domain/chat/entity/ChatRoom.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDateTime;

@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본 생성자 접근 레벨 PROTECTED
@Entity
Expand All @@ -28,4 +28,13 @@ public class ChatRoom extends BaseTimeEntity {
private User user2;

private String lastMessage;

public static ChatRoom of(User user1, User user2) {

return ChatRoom.builder()
.user1(user1)
.user2(user2)
.lastMessage("")
.build();
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/leets/X/domain/chat/exception/ErrorMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.leets.X.domain.chat.exception;


import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum ErrorMessage {

NOT_FOUND_CHATROOM(400, "해당 채팅방을 찾을 수 없습니다.");

private final int code;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.leets.X.domain.chat.exception;

import com.leets.X.global.common.exception.BaseException;
import static com.leets.X.domain.chat.exception.ErrorMessage.NOT_FOUND_CHATROOM;

public class NotFoundChatRoomException extends BaseException {
public NotFoundChatRoomException() {
super(NOT_FOUND_CHATROOM.getCode(), NOT_FOUND_CHATROOM.getMessage());
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/leets/X/domain/chat/redis/RedisListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.leets.X.domain.chat.redis;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@Configuration
@RequiredArgsConstructor
public class RedisListener {

private final RedisMessageListenerContainer redisMessageListener;
private final RedisSubscriber redisSubscriber;

public void adaptMessageListener(Long roomId) {
ChannelTopic topic = new ChannelTopic("/sub/chats/" + roomId);
redisMessageListener.addMessageListener(redisSubscriber, topic);
}
}
Loading

0 comments on commit 44cb7db

Please sign in to comment.