diff --git a/build.gradle b/build.gradle index 8765fd2..f76d3f0 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'com.selfstudy' -version = 'v0.0.1' +version = 'v0.0.2' configurations { compileOnly { diff --git a/src/main/java/picdiary/diary/controller/DiaryController.java b/src/main/java/picdiary/diary/controller/DiaryController.java index eb22caf..31404c9 100644 --- a/src/main/java/picdiary/diary/controller/DiaryController.java +++ b/src/main/java/picdiary/diary/controller/DiaryController.java @@ -5,24 +5,26 @@ import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import lombok.RequiredArgsConstructor; -import org.springframework.data.repository.query.Param; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; -import picdiary.diary.domain.Diary; import picdiary.diary.dto.request.DiaryCreateRequest; import picdiary.diary.dto.request.DiaryUpdateRequest; import picdiary.diary.dto.response.GetDiaryResponse; +import picdiary.diary.exception.DiaryErrorCode; import picdiary.diary.repository.DiaryEntity; import picdiary.diary.service.DiaryService; import picdiary.diary.service.S3Service; import picdiary.global.dto.response.ApplicationResponse; +import picdiary.global.exception.ApplicationException; import picdiary.user.repository.UserEntity; import java.io.IOException; import java.time.format.DateTimeFormatter; import java.util.stream.Stream; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; + @RestController @RequiredArgsConstructor @RequestMapping("/diaries") @@ -37,21 +39,33 @@ public class DiaryController { /** * 다이어리 작성 */ - @PostMapping - public ResponseEntity> createDiary(@Parameter(hidden = true) UserEntity user, @RequestParam(value = "imageFile", required = false) MultipartFile file, @RequestParam("content") String content, @RequestParam("date") String date, @RequestParam(value = "emotion", required = false) Diary.Emotion emotion) { - DiaryCreateRequest.DiaryCreateRequestBuilder builder = DiaryCreateRequest.builder().content(content).date(date) - .emotion(emotion); + @PostMapping(consumes = APPLICATION_JSON_VALUE) + public ResponseEntity> createDiary(@Parameter(hidden = true) UserEntity user, @RequestBody DiaryCreateRequest request) { + Long diaryId = diaryService.createDiary(user.getId(), request); + return ApplicationResponse.success(diaryId, "다이어리가 생성되었습니다.").entity(); + } - /* AWS S3 파일 저장 */ + /** + * AWS S3 파일 저장 + */ + private void createDiaryImageFile(UserEntity user, DiaryUpdateRequest request, String date) { + var file = request.getImageFile(); if (file != null) try { String prefix = String.format("%s/%s", user.getId(), date); - builder.imageFileName(s3Service.saveFile(prefix, file)); + request.setImageFileName(s3Service.saveFile(prefix, file)); } catch (IOException e) { // 파일 저장 중 오류 발생 시 처리 - return ApplicationResponse.error("파일 저장 중 오류가 발생했습니다.", null); + throw new ApplicationException(DiaryErrorCode.SAVE_ERROR); } + } - Long diaryId = diaryService.createDiary(user.getId(), builder.build()); + /** + * Multipart 다이어리 작성 + */ + @PostMapping(consumes = MULTIPART_FORM_DATA_VALUE) + public ResponseEntity> createForm(@Parameter(hidden = true) UserEntity user, @ModelAttribute DiaryCreateRequest request) { + createDiaryImageFile(user, request, request.getDate()); + Long diaryId = diaryService.createDiary(user.getId(), request); return ApplicationResponse.success(diaryId, "다이어리가 생성되었습니다.").entity(); } @@ -77,12 +91,23 @@ public GetDiaryResponse getDiaryInfo(@Parameter(hidden = true) UserEntity user, /** * 다이어리 수정 */ - @PatchMapping("/{diaryId}") + @PatchMapping(value = "/{diaryId}", consumes = APPLICATION_JSON_VALUE) public ApplicationResponse updateDiary(@Parameter(hidden = true) UserEntity user, @PathVariable("diaryId") Long diaryId, @RequestBody DiaryUpdateRequest request) { diaryService.updateDiary(user.getId(), diaryId, request); return ApplicationResponse.success(diaryId, "다이어리가 수정되었습니다."); } + /** + * 다이어리 수정 + */ + @PatchMapping(value = "/{diaryId}", consumes = MULTIPART_FORM_DATA_VALUE) + public ApplicationResponse updateForm(@Parameter(hidden = true) UserEntity user, @PathVariable("diaryId") Long diaryId, @ModelAttribute DiaryUpdateRequest request) { + var diary = diaryService.findDiaryById(diaryId); + createDiaryImageFile(user, request, diary.getDate().format(formatter)); + diaryService.updateDiary(user.getId(), diaryId, request); + return ApplicationResponse.success(diaryId, "다이어리가 수정되었습니다."); + } + /** * 다이어리 삭제 */ diff --git a/src/main/java/picdiary/diary/dto/request/DiaryCreateRequest.java b/src/main/java/picdiary/diary/dto/request/DiaryCreateRequest.java index b9817d8..8a6ee23 100644 --- a/src/main/java/picdiary/diary/dto/request/DiaryCreateRequest.java +++ b/src/main/java/picdiary/diary/dto/request/DiaryCreateRequest.java @@ -1,15 +1,17 @@ package picdiary.diary.dto.request; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import picdiary.diary.domain.Diary; @Data @Builder -public final class DiaryCreateRequest { +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public final class DiaryCreateRequest extends DiaryUpdateRequest { private String content; private String date; private Diary.Emotion emotion; - private String imageFileName; - } diff --git a/src/main/java/picdiary/diary/dto/request/DiaryUpdateRequest.java b/src/main/java/picdiary/diary/dto/request/DiaryUpdateRequest.java index 78ca1ef..3e8a7dc 100644 --- a/src/main/java/picdiary/diary/dto/request/DiaryUpdateRequest.java +++ b/src/main/java/picdiary/diary/dto/request/DiaryUpdateRequest.java @@ -1,6 +1,20 @@ package picdiary.diary.dto.request; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; import picdiary.diary.domain.Diary; -public record DiaryUpdateRequest(String content, Diary.Emotion emotion) { +@Data +@NoArgsConstructor +public class DiaryUpdateRequest { + private String content; + protected Diary.Emotion emotion; + private MultipartFile imageFile; + private String imageFileName; + + public DiaryUpdateRequest(String content, Diary.Emotion emotion) { + this.content = content; + this.emotion = emotion; + } } diff --git a/src/main/java/picdiary/diary/exception/DiaryErrorCode.java b/src/main/java/picdiary/diary/exception/DiaryErrorCode.java index 9a75947..f59b13b 100644 --- a/src/main/java/picdiary/diary/exception/DiaryErrorCode.java +++ b/src/main/java/picdiary/diary/exception/DiaryErrorCode.java @@ -8,7 +8,7 @@ public enum DiaryErrorCode implements ErrorCode { IS_NOT_WRITER(HttpStatus.FORBIDDEN, "권한이 없습니다."), NO_DIARY(HttpStatus.BAD_REQUEST, "일기 정보가 존재하지 않습니다."), - EMPTY_DIARY(HttpStatus.BAD_REQUEST, "내용이 비어있습니다."); + SAVE_ERROR(HttpStatus.BAD_REQUEST, "파일 저장 중 오류가 발생했습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/src/main/java/picdiary/diary/repository/DiaryEntity.java b/src/main/java/picdiary/diary/repository/DiaryEntity.java index f5b0f0e..aabe993 100644 --- a/src/main/java/picdiary/diary/repository/DiaryEntity.java +++ b/src/main/java/picdiary/diary/repository/DiaryEntity.java @@ -5,6 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import picdiary.diary.domain.Diary; +import picdiary.diary.dto.request.DiaryUpdateRequest; import picdiary.diary.exception.DiaryErrorCode; import picdiary.global.exception.ApplicationException; import picdiary.global.repository.BaseEntity; @@ -51,10 +52,17 @@ public DiaryEntity(String content, LocalDate date, Diary.Emotion emotion, String this.user = user; } - public void diaryUpdate(long userId, String content, Diary.Emotion emotion) { + public void diaryUpdate(long userId, DiaryUpdateRequest request) { validateUserIsWriter(userId); - this.content = content; - this.emotion = emotion; + if (request.getContent() != null) { + this.content = request.getContent(); + } + if (request.getEmotion() != null) { + this.emotion = request.getEmotion(); + } + if (request.getImageFileName() != null) { + this.imageFileName = request.getImageFileName(); + } } public void validateUserIsWriter(long userId) { diff --git a/src/main/java/picdiary/diary/service/DiaryService.java b/src/main/java/picdiary/diary/service/DiaryService.java index 1f46a62..2d83add 100644 --- a/src/main/java/picdiary/diary/service/DiaryService.java +++ b/src/main/java/picdiary/diary/service/DiaryService.java @@ -63,7 +63,7 @@ public Collection getDiaryByMonth(Long userId, String month) { public DiaryEntity updateDiary(Long userId, Long diaryId, DiaryUpdateRequest request) { DiaryEntity savedDiary = findDiaryById(diaryId); - savedDiary.diaryUpdate(userId, request.content(), request.emotion()); + savedDiary.diaryUpdate(userId, request); return diaryRepository.save(savedDiary); }