Skip to content

Commit

Permalink
#9 feat : 채팅 추가기능 개발
Browse files Browse the repository at this point in the history
- 접속 종료 API
- 채팅 파일 업로드 API
- 채팅 파일 다운로드 API
- 채팅 이미지 업로드 API
  • Loading branch information
sim-mer committed May 10, 2024
1 parent 6809c7f commit 3eeff95
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 6 deletions.
60 changes: 55 additions & 5 deletions src/main/java/gdsc/comunity/controller/chat/ChatController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,87 @@

import gdsc.comunity.dto.chat.Chatting;
import gdsc.comunity.dto.chat.PagingChatting;
import gdsc.comunity.exception.CustomException;
import gdsc.comunity.exception.ErrorCode;
import gdsc.comunity.service.ChatService;
import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequiredArgsConstructor
public class ChatController {
private final SimpMessageSendingOperations messagingTemplate;
private final ChatService chatService;

@MessageMapping("/{channelId}/{userNickname}")
@MessageMapping("/{channelId}/{userNickname}/enter")
public void enter(@DestinationVariable Long channelId,
@DestinationVariable String userNickname){
messagingTemplate.convertAndSend("/api/sub/" + channelId
, userNickname);
}

@MessageMapping("/{channelId}/{userNickname}/exit")
public void exit(@DestinationVariable Long channelId,
@DestinationVariable String userNickname){
messagingTemplate.convertAndSend("/api/sub/" + channelId
, userNickname);
}

@MessageMapping("/{channelId}")
public void chat(Chatting chatting, @DestinationVariable Long channelId) {
chatService.saveChat(chatting, channelId);
messagingTemplate.convertAndSend("/api/sub/" + channelId
, chatting);
}

@PostMapping("/{channelId}/{userNickname}/file")
public void chatFileUpload(@PathVariable Long channelId, @PathVariable String userNickname, @RequestParam("file") MultipartFile file) {
Chatting chatting = chatService.saveChatFile(channelId, userNickname, file);
messagingTemplate.convertAndSend("/api/sub/" + channelId
, chatting);
}

@PostMapping("/{channelId}/{userNickname}/image")
public void chatImageUpload(@PathVariable Long channelId, @PathVariable String userNickname, @RequestParam("image") MultipartFile[] images) {
Chatting chatting = chatService.saveChatImage(channelId, userNickname, images);
messagingTemplate.convertAndSend("/api/sub/" + channelId
, chatting);
}

@GetMapping("/file/{fileCode}")
public ResponseEntity<ByteArrayResource> chatFileDownload(@PathVariable String fileCode) {
try {
File file = chatService.getChatFile(fileCode);
byte[] fileData = Files.readAllBytes(file.toPath());
String encodedFileName = URLEncoder.encode(file.getName(), StandardCharsets.UTF_8);

ByteArrayResource resource = new ByteArrayResource(fileData);

ResponseEntity<ByteArrayResource> responseEntity = ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"")
.body(resource);

file.delete();

return responseEntity;
} catch (Exception e) {
throw new CustomException(ErrorCode.FILE_DOWNLOAD_ERROR);
}
}

@GetMapping("/api/chatLog/{channelId}")
public ResponseEntity<PagingChatting> getChatLog(@PathVariable Long channelId,
@RequestParam int page){
Expand Down
39 changes: 38 additions & 1 deletion src/main/java/gdsc/comunity/service/ChatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import gdsc.comunity.dto.chat.PagingChatting;
import gdsc.comunity.dto.chat.Chatting;
import gdsc.comunity.entity.chat.ChatLog;
import gdsc.comunity.entity.chat.ChatType;
import gdsc.comunity.repository.channel.ChannelRepository;
import gdsc.comunity.repository.chat.ChatRepository;
import gdsc.comunity.repository.user.UserChannelRepository;
import java.io.File;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Map;

@Service
Expand All @@ -21,14 +25,15 @@ public class ChatService {
private final ChatRepository chatRepository;
private final ChannelRepository channelRepository;
private final UserChannelRepository userChannelRepository;
private final S3FileService s3FileService;

@Async
public void saveChat(Chatting chatting, Long channelId) {
var channel = channelRepository.getReferenceById(channelId);

Long userId = userChannelRepository.getUserIdByNicknameAndChannel(chatting.senderNickname, channelId);

chatRepository.save(chatting.toEntity(channel, userId));
chatRepository.save(chatting.toEntity(channel, userId, chatting.type));
}

public PagingChatting getChatLog(Long channelId, int page) {
Expand All @@ -38,4 +43,36 @@ public PagingChatting getChatLog(Long channelId, int page) {

return PagingChatting.of(chatLogPage, nicknameMap);
}

public Chatting saveChatFile(Long channelId, String userNickname, MultipartFile file) {
String s3filename = s3FileService.uploadFile(file);

String message = s3filename + "/" + file.getSize();

Chatting chatting = new Chatting(message, userNickname, ChatType.FILE, LocalDateTime.now());

saveChat(chatting, channelId);

return chatting;
}

public Chatting saveChatImage(Long channelId, String userNickname, MultipartFile[] images) {
StringBuilder message = new StringBuilder();
for (MultipartFile image : images) {
String url = s3FileService.uploadImage(image);
message.append(url).append("/")
.append(image.getOriginalFilename()).append("/")
.append(image.getSize()).append(";");
}

Chatting chatting = new Chatting(message.toString(), userNickname, ChatType.IMAGE, LocalDateTime.now());

saveChat(chatting, channelId);

return chatting;
}

public File getChatFile(String fileCode) {
return s3FileService.downloadFile(fileCode);
}
}

0 comments on commit 3eeff95

Please sign in to comment.