Skip to content

Commit

Permalink
Merge pull request #103 from kakao-tech-campus-2nd-step3/develop
Browse files Browse the repository at this point in the history
Develop 병합
  • Loading branch information
yooonwodyd authored Nov 13, 2024
2 parents f0bd608 + ea13017 commit 69535a0
Show file tree
Hide file tree
Showing 31 changed files with 811 additions and 96 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ dependencies {
testImplementation 'org.testcontainers:junit-jupiter:1.20.2'
testImplementation 'org.testcontainers:mysql:1.20.2'

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

}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.helpmeCookies.chat.controller;


import com.helpmeCookies.chat.dto.ChatRoomInfo;
import com.helpmeCookies.chat.entity.ChatMessage;
import com.helpmeCookies.chat.entity.ChatRoom;
import com.helpmeCookies.chat.service.ChatMessageService;
import com.helpmeCookies.chat.service.ChatRoomService;
import com.helpmeCookies.chat.util.ImageStorageUtil;
import com.helpmeCookies.global.exception.chat.ChatRoomIdNotFoundException;
import com.helpmeCookies.global.exception.user.UserNotFoundException;
import com.helpmeCookies.user.entity.User;
import com.helpmeCookies.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/chat")
public class ChatMessageController {
private final ChatMessageService chatMessageService;
private final ChatRoomService chatRoomService;
private final UserService userService;
private final ImageStorageUtil imageStorageUtil;

@GetMapping("/rooms/{chatRoomId}/messages")
public List<ChatMessage> getMessagesByChatRoom(@PathVariable Long chatRoomId) {
ChatRoom chatRoom = chatRoomService.findById(chatRoomId)
.orElseThrow(() -> new ChatRoomIdNotFoundException(chatRoomId));

return chatMessageService.getMessagesByChatRoom(chatRoom);
}

@GetMapping("/rooms/user/{userId}")
public List<Long> getChatRoomIdsByUser(@PathVariable Long userId) throws UserNotFoundException {
User user = userService.findById(userId)
.orElseThrow(() -> new UserNotFoundException("User not found with ID: " + userId));

return chatMessageService.getChatRoomIdsByUser(user);
}

@GetMapping("/rooms/user/title/{userId}")
public List<ChatRoomInfo> getChatRoomInfosByUserTitle(@PathVariable Long userId) throws UserNotFoundException {
User user = userService.findById(userId)
.orElseThrow(() -> new UserNotFoundException("User not found with ID: " + userId));

return chatMessageService.getChatRoomInfosByUser(user);
}

@DeleteMapping("/messages/{id}")
public void deleteMessage(@PathVariable Long id) {
chatMessageService.deleteMessage(id);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.helpmeCookies.chat.controller;


import com.helpmeCookies.chat.entity.ChatRoom;
import com.helpmeCookies.chat.service.ChatMessageService;
import com.helpmeCookies.chat.service.ChatRoomService;
import com.helpmeCookies.chat.util.ImageStorageUtil;
import com.helpmeCookies.global.exception.user.UserNotFoundException;
import com.helpmeCookies.user.entity.User;
import com.helpmeCookies.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/chat/rooms")
public class ChatRoomController {
private final ChatRoomService chatRoomService;
private final UserService userService;
private final ImageStorageUtil imageStorageUtil;
private final ChatMessageService chatMessageService;

@PostMapping
public ChatRoom createChatRoom(
@RequestParam String userEmail1,
@RequestParam String userEmail2
) throws UserNotFoundException {
User user1 = userService.findByEmail(userEmail1)
.orElseThrow(() -> new UserNotFoundException("User not found: " + userEmail1));
User user2 = userService.findByEmail(userEmail2)
.orElseThrow(() -> new UserNotFoundException("User not found: " + userEmail2));


ChatRoom chatRoom = chatRoomService.createChatRoom(user1, user2);

String welcomeMessageContent = "Welcome, " + user2.getEmail() + "!";
chatMessageService.saveMessage(chatRoom, user1, welcomeMessageContent);

return chatRoom;
}

@GetMapping("/{chatRoomId}")
public ChatRoom getChatRoom(@PathVariable Long chatRoomId) {
return chatRoomService.getChatRoomById(chatRoomId);
}

@DeleteMapping("/{chatRoomId}")
public void deleteChatRoom(@PathVariable Long chatRoomId) {
chatRoomService.deleteChatRoom(chatRoomId);
imageStorageUtil.deleteChatFolder("chatRoom_" + chatRoomId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.helpmeCookies.chat.controller;


import com.helpmeCookies.chat.dto.ImageMessageDTO;
import com.helpmeCookies.chat.entity.ChatMessage;
import com.helpmeCookies.chat.entity.ChatRoom;
import com.helpmeCookies.chat.service.ChatMessageService;
import com.helpmeCookies.chat.service.ChatRoomService;
import com.helpmeCookies.chat.util.ImageStorageUtil;
import com.helpmeCookies.global.exception.user.UserNotFoundException;
import com.helpmeCookies.user.entity.User;
import com.helpmeCookies.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;


@RestController
@RequestMapping("/v1/websocket")
public class WebSocketChatController {

private final SimpMessageSendingOperations messagingTemplate;
private final ChatMessageService chatMessageService;
private final ChatRoomService chatRoomService;
private final UserService userService;
private final ImageStorageUtil imageStorageUtil;

public WebSocketChatController(SimpMessageSendingOperations messagingTemplate, ChatMessageService chatMessageService, ChatRoomService chatRoomService, UserService userService, ImageStorageUtil imageStorageUtil) {
this.messagingTemplate = messagingTemplate;
this.chatMessageService = chatMessageService;
this.chatRoomService = chatRoomService;
this.userService = userService;
this.imageStorageUtil = imageStorageUtil;
}

@MessageMapping("/chat/{chatRoomId}")
@Operation(summary = "채팅 메시지 전송", description = "WebSocket을 통해 특정 채팅방에 텍스트 메시지를 전송합니다.")
@Parameter(name = "chatRoomId", description = "채팅방 ID", required = true, schema = @Schema(type = "long"))
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 메시지를 전송했습니다."),
@ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없습니다.", content = @Content)
})
public void chat(@DestinationVariable Long chatRoomId,
@Parameter(description = "전송할 채팅 메시지", required = true) ChatMessage message) throws UserNotFoundException {
ChatRoom chatRoom = chatRoomService.getChatRoomById(chatRoomId);
User sender = userService.findByEmail(message.getSender().getEmail())
.orElseThrow(() -> new UserNotFoundException("발신자를 찾을 수 없습니다: " + message.getSender().getEmail()));

chatMessageService.saveMessage(chatRoom, sender, message.getContent());
messagingTemplate.convertAndSend("/api/sub/chat/rooms/" + chatRoomId, message);
}

@MessageMapping("/chat/{chatRoomId}/file")
@Operation(summary = "파일 전송", description = "WebSocket을 통해 특정 채팅방에 파일을 전송합니다.")
@Parameter(name = "chatRoomId", description = "채팅방 ID", required = true, schema = @Schema(type = "long"))
@Parameter(name = "file", description = "전송할 파일", required = true, schema = @Schema(type = "string", format = "binary"))
@Parameter(name = "userEmail", description = "발신자 이메일", required = true, schema = @Schema(type = "string"))
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 파일을 전송했습니다."),
@ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없습니다.", content = @Content)
})
public void sendFile(@DestinationVariable Long chatRoomId,
@RequestParam("file") MultipartFile file,
@RequestParam String userEmail)
throws UserNotFoundException, IOException {
ChatRoom chatRoom = chatRoomService.getChatRoomById(chatRoomId);
User sender = userService.findByEmail(userEmail)
.orElseThrow(() -> new UserNotFoundException("발신자를 찾을 수 없습니다: " + userEmail));

ChatMessage message = chatMessageService.saveFileMessage(chatRoom, sender, file);
String imagePath = message.getImageUrl();
byte[] imageBytes = java.nio.file.Files.readAllBytes(new File(imagePath).toPath());

ImageMessageDTO imageMessageDTO = new ImageMessageDTO(message, imageBytes);
messagingTemplate.convertAndSend("/api/sub/chat/rooms/" + chatRoomId, imageMessageDTO);
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/helpmeCookies/chat/dto/ChatRoomInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.helpmeCookies.chat.dto;

public class ChatRoomInfo {
private Long id;
private String title;

public ChatRoomInfo(Long id, String title) {
this.id = id;
this.title = title;
}

public Long getId() {
return id;
}

public String getTitle() {
return title;
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/helpmeCookies/chat/dto/ImageMessageDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.helpmeCookies.chat.dto;


import com.helpmeCookies.chat.entity.ChatMessage;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ImageMessageDTO {
private ChatMessage chatMessage;
private byte[] imageData;

public ImageMessageDTO(ChatMessage chatMessage, byte[] imageData) {
this.chatMessage = chatMessage;
this.imageData = imageData;
}
}

81 changes: 81 additions & 0 deletions src/main/java/com/helpmeCookies/chat/entity/ChatMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.helpmeCookies.chat.entity;


import com.helpmeCookies.user.entity.User;
import jakarta.persistence.*;

import java.time.LocalDateTime;

@Entity
@Table(name = "chat_messages")
public class ChatMessage {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "chat_room_id", nullable = false)
private ChatRoom chatRoom;

@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User sender;

//private MessageType type;

private String content; //내용

@Column(name = "image_url")
private String imageUrl; // 이미지 URL

private LocalDateTime timestamp;

protected ChatMessage() {}

public ChatMessage(ChatRoom chatRoom, User sender, String content) {
this.chatRoom = chatRoom;
this.sender = sender;
this.content = content;
this.timestamp = LocalDateTime.now();
}

public ChatMessage(ChatRoom chatRoom, User sender, String content, String imageUrl) {
this.chatRoom = chatRoom;
this.sender = sender;
this.content = content;
this.imageUrl = imageUrl;
this.timestamp = LocalDateTime.now();
}



// Getters and Setters
public Long getId() {
return id;
}

public ChatRoom getChatRoom() {
return chatRoom;
}

public User getSender() {
return sender;
}

public String getContent() {
return content;
}

public String getImageUrl() {
return imageUrl;
}

public LocalDateTime getTimestamp() {
return timestamp;
}

public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
35 changes: 35 additions & 0 deletions src/main/java/com/helpmeCookies/chat/entity/ChatRoom.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.helpmeCookies.chat.entity;


import com.helpmeCookies.user.entity.User;
import jakarta.persistence.*;
import lombok.Getter;

@Entity
@Getter
@Table(name = "chat_rooms")
public class ChatRoom {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
//@JsonIgnore
@JoinColumn(name = "user1_id", nullable = false)
private User user1;

@ManyToOne
//@JsonIgnore
@JoinColumn(name = "user2_id", nullable = false)
private User user2;

private String title;

protected ChatRoom() {}

public ChatRoom(User user1, User user2) {
this.user1 = user1;
this.user2 = user2;
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/helpmeCookies/chat/entity/MessageType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.helpmeCookies.chat.entity;

public enum MessageType {
ENTER, TALK, EXIT, MATCH, MATCH_REQUEST;
}
Loading

0 comments on commit 69535a0

Please sign in to comment.