diff --git a/src/main/java/kdt/web_ide/chat/controller/ChatController.java b/src/main/java/kdt/web_ide/chat/controller/ChatController.java index 837a097..4fe39bc 100644 --- a/src/main/java/kdt/web_ide/chat/controller/ChatController.java +++ b/src/main/java/kdt/web_ide/chat/controller/ChatController.java @@ -9,7 +9,9 @@ import org.springframework.messaging.handler.annotation.Payload; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import io.swagger.v3.oas.annotations.Operation; import kdt.web_ide.chat.dto.request.ChatMessageRequestDto; import kdt.web_ide.chat.dto.response.GetChatMessageResponseDto; import kdt.web_ide.chat.service.ChatService; @@ -40,4 +42,15 @@ public ResponseEntity> getChatMessage( Long memberId = memberService.getMember(userDetails.getMember()).getMemberId(); return ResponseEntity.status(HttpStatus.OK).body(chatService.getChatMessage(roomId, memberId)); } + + @PostMapping(value = "/{roomId}/images", consumes = "multipart/form-data") + @Operation(summary = "이미지 전송") + public ResponseEntity sendImages( + @PathVariable("roomId") Long roomId, + @RequestPart("imageFile") List imageFiles, + @AuthenticationPrincipal CustomUserDetails userDetails) { + Long memberId = userDetails.getMember().getMemberId(); + chatService.sendImage(memberId, roomId, imageFiles); + return ResponseEntity.status(HttpStatus.OK).body(null); + } } diff --git a/src/main/java/kdt/web_ide/chat/service/ChatService.java b/src/main/java/kdt/web_ide/chat/service/ChatService.java index 142c8a6..34f44f1 100644 --- a/src/main/java/kdt/web_ide/chat/service/ChatService.java +++ b/src/main/java/kdt/web_ide/chat/service/ChatService.java @@ -7,6 +7,7 @@ import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import kdt.web_ide.chat.dto.request.ChatMessageRequestDto; import kdt.web_ide.chat.dto.response.GetChatMessageResponseDto; @@ -19,6 +20,7 @@ import kdt.web_ide.chat.entity.repository.ChatRoomRepository; import kdt.web_ide.common.exception.CustomException; import kdt.web_ide.common.exception.ErrorCode; +import kdt.web_ide.file.service.S3Service; import kdt.web_ide.members.entity.Member; import kdt.web_ide.members.entity.repository.MemberRepository; import lombok.RequiredArgsConstructor; @@ -35,6 +37,8 @@ public class ChatService { private final MemberRepository memberRepository; + private final S3Service s3Service; + // 메세지 전송 @Transactional public void sendMessage(Long chatRoomId, ChatMessageRequestDto requestDto) { @@ -110,4 +114,25 @@ private void notifyUnreadMessageCount(Long roomId, Long senderId) { } } } + + @Transactional + public void sendImage(Long senderId, Long chatRoomId, List multipartFileList) { + + chatRoomRepository + .findById(chatRoomId) + .orElseThrow(() -> new CustomException(ErrorCode.CHATROOM_NOT_FOUND)); + + memberRepository + .findById(senderId) + .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); + + List imageUrlList = s3Service.uploadImages(multipartFileList); + + for (String imageUrl : imageUrlList) { + + ChatMessageRequestDto requestDto = new ChatMessageRequestDto(senderId, imageUrl); + + sendMessage(chatRoomId, requestDto); + } + } } diff --git a/src/main/java/kdt/web_ide/file/service/S3Service.java b/src/main/java/kdt/web_ide/file/service/S3Service.java index ea1fac2..be7c096 100644 --- a/src/main/java/kdt/web_ide/file/service/S3Service.java +++ b/src/main/java/kdt/web_ide/file/service/S3Service.java @@ -5,9 +5,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import kdt.web_ide.common.exception.CustomException; import kdt.web_ide.common.exception.ErrorCode; @@ -252,4 +256,38 @@ public void deleteFile(String filePath) { private String extractFileName(String filePath) { return filePath.substring(filePath.lastIndexOf("/") + 1); } + + public List uploadImages(List imageFiles) { + + List imageUrls = new ArrayList<>(); + + for (MultipartFile imageFile : imageFiles) { + try { + String fileName = generateChatImageFileName(); + + PutObjectRequest request = + PutObjectRequest.builder() + .bucket(bucketName) + .key(fileName) + .contentType(imageFile.getContentType()) + .build(); + + amazonS3.putObject( + request, RequestBody.fromInputStream(imageFile.getInputStream(), imageFile.getSize())); + + String imageUrl = getFileUrl(fileName); + + imageUrls.add(imageUrl); + + } catch (IOException e) { + log.error("Error uploading file to S3.", e); + throw new CustomException(ErrorCode.S3_UPLOAD_ERROR); + } + } + return imageUrls; + } + + private String generateChatImageFileName() { + return "chat" + '/' + UUID.randomUUID().toString(); + } } diff --git a/src/main/java/kdt/web_ide/post/service/PostService.java b/src/main/java/kdt/web_ide/post/service/PostService.java index 376314b..f4f4e66 100644 --- a/src/main/java/kdt/web_ide/post/service/PostService.java +++ b/src/main/java/kdt/web_ide/post/service/PostService.java @@ -56,15 +56,14 @@ public PostResponseDto createPost(PostRequestDto requestDto) { String fileName = generateFileName(requestDto.getName(), String.valueOf(requestDto.getLanguage())); - String filePath = "test"; - // uploadEmptyFileToS3(fileName, board.getId()); + uploadEmptyFileToS3(fileName, board.getId()); Post post = Post.builder() .board(board) .name(requestDto.getName()) .language(requestDto.getLanguage()) - .filePath(filePath) + .filePath(fileName) .createdAt(LocalDateTime.now()) .build();