From 278140b72e27a7fdd6b2685c5826051bb38d0ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=B0=ED=98=84=EC=84=9C?= Date: Sun, 13 Oct 2024 18:13:59 +0900 Subject: [PATCH] =?UTF-8?q?[hotfix]:=20=EC=9E=90=EB=A3=8C=EC=A7=91=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20api=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/controller/PostManageController.java | 21 +++++++++--- .../post/service/PostManageService.java | 33 +++++++++++++++++-- .../ussum/homepage/infra/utils/S3utils.java | 22 +++++++++++-- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/main/java/ussum/homepage/application/post/controller/PostManageController.java b/src/main/java/ussum/homepage/application/post/controller/PostManageController.java index 4125a11..d713116 100644 --- a/src/main/java/ussum/homepage/application/post/controller/PostManageController.java +++ b/src/main/java/ussum/homepage/application/post/controller/PostManageController.java @@ -102,24 +102,37 @@ public ResponseEntity> createDataPost(@Parameter(hidden = true) @ @RequestBody PostCreateRequest postCreateRequest) { return ApiResponse.success(postManageService.createDataPost(userId, fileCategory, postCreateRequest)); } - @Operation(summary = "게시물 생성 시 파일 및 이미지 저장 api", description = """ 게시물 생성 시 파일 및 이미지 저장하는 api입니다. 우선 이 api는 게시물 생성 api를 사용전 미리 호출하여야 합니다. 기본적으로 반환값이 저장된 파일 및 사진의 url이기 때문에 이 반환값을 가지고 게시물 생성 api에 있는 dto의 List에 url를 보내주어야 합니다. 기본적으로 액세스 토큰을 필요로 합니다. PathVariable로 노션에 있는 boardCode중 하나를 적습니다. - s3에 저장할 MultipartFile 형식을 fileType에 담아주시면 됩니다. + s3에 저장할 MultipartFile 형식의 파라미터를 2개 두었습니다. + 첫번째 파라미터는 files라는 key값으로 보내주면 됩니다. + 두번째 파라미터는 images라는 key값으로 보내주면 됩니다. 이미지와 파일을 경로를 구분하여 저장하기 위해 이러한 방식을 선택했습니다. 기본적인 api로직은 받은 파라미터를 통해 파일들을 먼저 s3에 저장하고 db에 순차적으로 생성된 id와 url을 하나의 dto로 이를 List로 반환합니다. """) - @PostMapping(value = "/{boardCode}/files/{fileType}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, + @PostMapping(value = "/{boardCode}/files", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> createBoardPostFile(@Parameter(hidden = true) @UserId Long userId, + @PathVariable(name = "boardCode") String boardCode, + @RequestPart(value = "files", required = false) MultipartFile[] files, + @RequestPart(value = "images", required = false) MultipartFile[] images) { + return ApiResponse.success(postManageService.createBoardPostFile(userId, boardCode, files, images)); + } + + @Operation(summary = "자료집 게시물 생성 시 파일 및 이미지 저장 api", description = """ + 자료집 게시물 생성 시 파일 및 이미지 저장하는 api입니다. + """) + @PostMapping(value = "/{boardCode}/files/{fileType}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> createBoardDataPostFile(@Parameter(hidden = true) @UserId Long userId, @PathVariable(name = "boardCode") String boardCode, @RequestPart(value = "files", required = false) MultipartFile[] files, @PathVariable(name = "fileType") String fileType) { - return ApiResponse.success(postManageService.createBoardPostFile(userId, boardCode, files, fileType)); + return ApiResponse.success(postManageService.createBoardDataPostFile(userId, boardCode, files, fileType)); } @Operation(summary = "게시물 단건 조회 후 파일 혹은 이미지 삭제 api", description = """ diff --git a/src/main/java/ussum/homepage/application/post/service/PostManageService.java b/src/main/java/ussum/homepage/application/post/service/PostManageService.java index d85041f..a730d4e 100644 --- a/src/main/java/ussum/homepage/application/post/service/PostManageService.java +++ b/src/main/java/ussum/homepage/application/post/service/PostManageService.java @@ -1,11 +1,14 @@ package ussum.homepage.application.post.service; +import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; import ussum.homepage.application.comment.service.dto.response.PostOfficialCommentResponse; import ussum.homepage.application.post.service.dto.request.PostCreateRequest; @@ -40,6 +43,7 @@ import ussum.homepage.domain.user.User; import ussum.homepage.domain.user.service.UserReader; import ussum.homepage.global.common.PageInfo; +import ussum.homepage.global.config.auth.UserId; import ussum.homepage.global.error.exception.GeneralException; import ussum.homepage.global.error.status.ErrorStatus; import ussum.homepage.infra.jpa.group.entity.GroupCode; @@ -120,7 +124,7 @@ public PostListRes getDataList(Long userId, int page, int take, String majorC ); PageInfo pageInfo = PageInfo.of(postList); - PostListResponseFactory factory = PostResponseFactoryProvider.getFactory("자료집게시판"); + PostListResponseFactory factory = PostResponseFactoryProvider.getFactory(BoardCode.DATA.getStringBoardCode()); List responseList = postList.getContent().stream() .map(post -> { @@ -184,9 +188,32 @@ public PostCreateResponse createDataPost(Long userId, String fileCategory, PostC return PostCreateResponse.of(post.getId(), BoardCode.DATA.getStringBoardCode()); } + //이거 두개 api 합쳐야댐!!!! + @Transactional + public PostFileListResponse createBoardPostFile(Long userId, String boardCode, MultipartFile[] files, MultipartFile[] images){ + PostFileMediatorResponse response = s3utils.uploadFileWithPath(userId, boardCode, files, images); + List postFiles = convertUrlsToPostFiles(response); + List afterSaveList = postFileAppender.saveAllPostFile(postFiles); + + String thumbnailUrl = afterSaveList.stream() + .filter(postFile -> postFile.getTypeName().equals("images")) + .min(Comparator.comparing(PostFile::getId)) + .map(PostFile::getUrl) + .orElse(null); + + AtomicInteger index = new AtomicInteger(0); + List postFileResponses = afterSaveList.stream() + .map(postFile -> { + int currentIndex = index.getAndIncrement(); + return PostFileResponse.of(postFile.getId(), postFile.getUrl(), response.originalFileNames().get(currentIndex)); + }) + .collect(Collectors.toList()); + + return PostFileListResponse.of(thumbnailUrl, postFileResponses); + } @Transactional - public PostFileListResponse createBoardPostFile(Long userId, String boardCode, MultipartFile[] files, String fileType){ - PostFileMediatorResponse response = s3utils.uploadFileWithPath(userId, boardCode, files, fileType); + public PostFileListResponse createBoardDataPostFile(Long userId, String boardCode, MultipartFile[] files, String fileType){ + PostFileMediatorResponse response = s3utils.uploadDataFileWithPath(userId, boardCode, files, fileType); List postFiles = convertUrlsToPostFiles(response); List afterSaveList = postFileAppender.saveAllPostFile(postFiles); diff --git a/src/main/java/ussum/homepage/infra/utils/S3utils.java b/src/main/java/ussum/homepage/infra/utils/S3utils.java index 676565a..9a8673e 100644 --- a/src/main/java/ussum/homepage/infra/utils/S3utils.java +++ b/src/main/java/ussum/homepage/infra/utils/S3utils.java @@ -51,8 +51,7 @@ public String uploadFile(MultipartFile file) { } return amazonS3.getUrl(bucket, originalFilename).toString(); } - - public PostFileMediatorResponse uploadFileWithPath(Long userId, String boardCode, MultipartFile[] files, String fileType) { + public PostFileMediatorResponse uploadDataFileWithPath(Long userId, String boardCode, MultipartFile[] files, String fileType) { List> uploadedFileUrls = new ArrayList<>(); List originalFileNames = new ArrayList<>(); @@ -70,6 +69,25 @@ public PostFileMediatorResponse uploadFileWithPath(Long userId, String boardCode return PostFileMediatorResponse.of(originalFileNames, uploadedFileUrls); } + + public PostFileMediatorResponse uploadFileWithPath(Long userId, String boardCode, MultipartFile[] files, MultipartFile[] images) { + List> uploadedFileUrls = new ArrayList<>(); + List originalFileNames = new ArrayList<>(); + + if (images != null && images.length > 0) { + PostFileMediatorResponse imageResponse = uploadFiles(userId, boardCode, files, "images"); + uploadedFileUrls.addAll(imageResponse.urlList()); + originalFileNames.addAll(formatOriginalFileNames(imageResponse.originalFileNames())); + } + + if (files != null && files.length > 0) { + PostFileMediatorResponse fileResponse = uploadFiles(userId, boardCode, files, "files"); + uploadedFileUrls.addAll(fileResponse.urlList()); + originalFileNames.addAll(formatOriginalFileNames(fileResponse.originalFileNames())); + } + + return PostFileMediatorResponse.of(originalFileNames, uploadedFileUrls); + } public List formatOriginalFileNames(List originalFileNames) { return originalFileNames.stream() .map(this::formatSingleFileName)