diff --git a/src/main/java/GDGoC/team_24/domain/diary/controller/DiaryController.java b/src/main/java/GDGoC/team_24/domain/diary/controller/DiaryController.java new file mode 100644 index 0000000..91c050d --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/diary/controller/DiaryController.java @@ -0,0 +1,56 @@ +package GDGoC.team_24.domain.diary.controller; + +import GDGoC.team_24.domain.diary.dto.DiaryRequestDto; +import GDGoC.team_24.domain.diary.dto.DiaryResponseDto; +import GDGoC.team_24.domain.diary.service.DiaryService; +import GDGoC.team_24.global.ApiResponse; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/diary") +public class DiaryController { + + private final DiaryService diaryService; + + @PostMapping + @Operation(summary = "일기 작성 API", description = "일기 생성하는 API입니다.") + public ApiResponse createDiary(@RequestPart(name = "diary") DiaryRequestDto userRequestDto, + @RequestPart(name = "ImageFile", required = false) List imgs + ) { + return ApiResponse.onSuccess(diaryService.createDiary(userRequestDto, imgs)); + + } + + @PostMapping("/{diaryId}") + @Operation(summary = "일기조회 API", description = "일기 조회하는 API입니다.") + public ApiResponse getDiary(@PathVariable Long diaryId) { + + return ApiResponse.onSuccess( diaryService.getDiary(diaryId)); + + } + + @PatchMapping("{diaryId}") + @Operation(summary = "일기 수정 API", description = "일기 수정하는 API입니다.") + public ApiResponse updateDiary(@PathVariable Long diaryId, + @RequestPart(name = "diary") DiaryRequestDto userRequestDto, + @RequestPart(name = "ImageFile", required = false) List imgs) { + + return ApiResponse.onSuccess( diaryService.updateDiary(diaryId, userRequestDto, imgs)); + + } + + @DeleteMapping("{diaryId}") + @Operation(summary = "일기삭제 API", description = "일기 삭제하는 API입니다.") + public ApiResponse deleteDiary(@PathVariable Long diaryId) { + + diaryService.deleteDiary(diaryId); + + return ApiResponse.onSuccess("일기가 성공적으로 삭제되었습니다."); + } + +} diff --git a/src/main/java/GDGoC/team_24/domain/diary/domain/Diary.java b/src/main/java/GDGoC/team_24/domain/diary/domain/Diary.java index 1baf510..9249b03 100644 --- a/src/main/java/GDGoC/team_24/domain/diary/domain/Diary.java +++ b/src/main/java/GDGoC/team_24/domain/diary/domain/Diary.java @@ -1,7 +1,9 @@ package GDGoC.team_24.domain.diary.domain; +import GDGoC.team_24.domain.diary.dto.DiaryRequestDto; import GDGoC.team_24.domain.user.domain.User; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -26,4 +28,19 @@ public class Diary { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; + + @Builder + public Diary(String content, LocalDateTime date, TODAYEMTION todayEmtion, User user) { + this.content = content; + this.date = date; + this.todayEmtion = todayEmtion; + this.user = user; + } + + public void update(DiaryRequestDto userRequestDto) { + this.content = content; + this.date = date; + this.todayEmtion = todayEmtion; + this.user = user; + } } diff --git a/src/main/java/GDGoC/team_24/domain/diary/dto/DiaryRequestDto.java b/src/main/java/GDGoC/team_24/domain/diary/dto/DiaryRequestDto.java new file mode 100644 index 0000000..52cf467 --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/diary/dto/DiaryRequestDto.java @@ -0,0 +1,11 @@ +package GDGoC.team_24.domain.diary.dto; + +import java.time.LocalDateTime; +import java.util.List; + +public record DiaryRequestDto( + LocalDateTime date, + String content, + Long userId, + String todayEmotion) { +} diff --git a/src/main/java/GDGoC/team_24/domain/diary/dto/DiaryResponseDto.java b/src/main/java/GDGoC/team_24/domain/diary/dto/DiaryResponseDto.java new file mode 100644 index 0000000..2664145 --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/diary/dto/DiaryResponseDto.java @@ -0,0 +1,34 @@ +package GDGoC.team_24.domain.diary.dto; + +import GDGoC.team_24.domain.diary.domain.Diary; + +import GDGoC.team_24.domain.diaryPhoto.domain.DiaryPhoto; +import GDGoC.team_24.domain.user.domain.User; + + + +import java.util.List; +import java.util.stream.Collectors; + +public record DiaryResponseDto( + Long id, + Long userId, + String content, + String date, + String todayEmotion, + List photoUrls +) { + + public DiaryResponseDto(Diary diary, List diaryPhotos) { + this( + diary.getId(), + diary.getUser().getId(), + diary.getContent(), + diary.getDate().toString(), + diary.getTodayEmtion().toString(), + diaryPhotos.stream().map(DiaryPhoto::getPhotoUrl).collect(Collectors.toList()) + ); + } + + +} diff --git a/src/main/java/GDGoC/team_24/domain/diary/repository/DiaryRepository.java b/src/main/java/GDGoC/team_24/domain/diary/repository/DiaryRepository.java new file mode 100644 index 0000000..96e6376 --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/diary/repository/DiaryRepository.java @@ -0,0 +1,8 @@ +package GDGoC.team_24.domain.diary.repository; + + +import GDGoC.team_24.domain.diary.domain.Diary; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DiaryRepository extends JpaRepository { +} diff --git a/src/main/java/GDGoC/team_24/domain/diary/service/DiaryService.java b/src/main/java/GDGoC/team_24/domain/diary/service/DiaryService.java new file mode 100644 index 0000000..63aaad1 --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/diary/service/DiaryService.java @@ -0,0 +1,122 @@ +package GDGoC.team_24.domain.diary.service; + +import GDGoC.team_24.domain.diary.domain.Diary; +import GDGoC.team_24.domain.diary.dto.DiaryResponseDto; +import GDGoC.team_24.domain.diaryPhoto.domain.DiaryPhoto; +import GDGoC.team_24.domain.diary.domain.TODAYEMTION; +import GDGoC.team_24.domain.diary.dto.DiaryRequestDto; +import GDGoC.team_24.domain.diary.repository.DiaryRepository; +import GDGoC.team_24.domain.diaryPhoto.repository.DiaryPhotoRepository; +import GDGoC.team_24.domain.user.domain.User; +import GDGoC.team_24.domain.user.repository.UserRepository; +import GDGoC.team_24.global.code.status.ErrorStatus; +import GDGoC.team_24.global.exception.GeneralException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import GDGoC.team_24.global.aws.AwsS3Service; + +import java.util.ArrayList; +import java.util.List; + + +@Service +@RequiredArgsConstructor +public class DiaryService { + + private final DiaryRepository diaryRepository; + private final DiaryPhotoRepository diaryPhotoRepository; + private final UserRepository userRepository; + private final AwsS3Service awsS3Service; + + public DiaryResponseDto createDiary(DiaryRequestDto userRequestDto, List imgs) { + + User user = userRepository.findById(userRequestDto.userId()) + .orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND)); + + TODAYEMTION todayemtion = TODAYEMTION.valueOf(userRequestDto.todayEmotion().toUpperCase()); + + // Diary 객체 생성 + Diary diary = Diary.builder() + .content(userRequestDto.content()) + .date(userRequestDto.date()) + .todayEmtion(todayemtion) + .user(user) + .build(); + + diaryRepository.save(diary); + + // Diary에 포함될 사진들 저장 + List diaryPhotos = new ArrayList<>(); + for (MultipartFile img : imgs) { + String imgUrl = awsS3Service.uploadFile(img); + + DiaryPhoto photo = DiaryPhoto.builder() + .diary(diary) + .photoUrl(imgUrl) + .build(); + + diaryPhotoRepository.save(photo); + diaryPhotos.add(photo); + } + + // Diary와 관련된 사진들을 포함하는 DTO 반환 + return new DiaryResponseDto(diary, diaryPhotos); + } + + + public DiaryResponseDto getDiary(Long diaryId) { + + Diary diary = diaryRepository.findById(diaryId) + .orElseThrow(() -> new GeneralException(ErrorStatus._BAD_REQUEST)); + + List diaryPhotos = diaryPhotoRepository.findByDiary(diary); + + return new DiaryResponseDto(diary, diaryPhotos); + } + + public DiaryResponseDto updateDiary(Long diaryId, DiaryRequestDto userRequestDto, List imgs) { + + Diary diary = diaryRepository.findById(diaryId) + .orElseThrow(() -> new GeneralException(ErrorStatus._BAD_REQUEST)); + + + Diary updateDiary = Diary.builder() + .date(userRequestDto.date()) + .content(userRequestDto.content()) + .todayEmtion(diary.getTodayEmtion()) + .todayEmtion(diary.getTodayEmtion()) + .user(diary.getUser()) + .build(); + + diaryRepository.save(updateDiary); + + + List existingPhotos = diaryPhotoRepository.findByDiary(diary); + for (DiaryPhoto photo : existingPhotos) { + awsS3Service.deleteFile(photo.getPhotoUrl()); + diaryPhotoRepository.delete(photo); + } + + List diaryPhotos = new ArrayList<>(); + + for (MultipartFile img : imgs) { + String imgUrl = awsS3Service.uploadFile(img); + DiaryPhoto newPhoto = DiaryPhoto.builder() + .diary(updateDiary) + .photoUrl(imgUrl) + .build(); + diaryPhotoRepository.save(newPhoto); + diaryPhotos.add(newPhoto); + } + + return new DiaryResponseDto(updateDiary, diaryPhotos); + + } + + public void deleteDiary(Long diaryId) { + + diaryRepository.deleteById(diaryId); + } + } + diff --git a/src/main/java/GDGoC/team_24/domain/diaryPhoto/domain/DiaryPhoto.java b/src/main/java/GDGoC/team_24/domain/diaryPhoto/domain/DiaryPhoto.java new file mode 100644 index 0000000..1a7d7bd --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/diaryPhoto/domain/DiaryPhoto.java @@ -0,0 +1,30 @@ +package GDGoC.team_24.domain.diaryPhoto.domain; + +import GDGoC.team_24.domain.diary.domain.Diary; +import jakarta.persistence.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor +@Getter +public class DiaryPhoto { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String photoUrl; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "diaryId") + private Diary diary; + + @Builder + public DiaryPhoto(String photoUrl, Diary diary) { + this.photoUrl = photoUrl; + this.diary = diary; + } + +} diff --git a/src/main/java/GDGoC/team_24/domain/diaryPhoto/repository/DiaryPhotoRepository.java b/src/main/java/GDGoC/team_24/domain/diaryPhoto/repository/DiaryPhotoRepository.java new file mode 100644 index 0000000..b402a33 --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/diaryPhoto/repository/DiaryPhotoRepository.java @@ -0,0 +1,12 @@ +package GDGoC.team_24.domain.diaryPhoto.repository; + +import GDGoC.team_24.domain.diary.domain.Diary; +import GDGoC.team_24.domain.diaryPhoto.domain.DiaryPhoto; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface DiaryPhotoRepository extends JpaRepository { + + List findByDiary(Diary diary); +} diff --git a/src/main/java/GDGoC/team_24/domain/s3/controller/AwsS3Controller.java b/src/main/java/GDGoC/team_24/domain/s3/controller/AwsS3Controller.java new file mode 100644 index 0000000..79f8dea --- /dev/null +++ b/src/main/java/GDGoC/team_24/domain/s3/controller/AwsS3Controller.java @@ -0,0 +1,33 @@ +//package GDGoC.team_24.domain.s3.controller; +// +//import GDGoC.team_24.domain.s3.service.AwsS3Service; +//import GDGoC.team_24.global.ApiResponse; +//import GDGoC.team_24.global.code.status.SuccessStatus; +//import lombok.RequiredArgsConstructor; +//import org.springframework.web.bind.annotation.PostMapping; +//import org.springframework.web.bind.annotation.RequestMapping; +//import org.springframework.web.bind.annotation.RequestPart; +//import org.springframework.web.bind.annotation.RestController; +//import org.springframework.web.multipart.MultipartFile; +// +//import java.util.ArrayList; +//import java.util.List; +// +//@RestController +//@RequiredArgsConstructor +//@RequestMapping("api/s3") +//public class AwsS3Controller { +// +// private final AwsS3Service awsS3Service; +// @PostMapping(consumes = "multipart/form-data") +// public ApiResponse> s3upload(@RequestPart(required = false) List imgs) { +// List img_urls = new ArrayList<>(); +// for(MultipartFile img : imgs){ +// img_urls.add(awsS3Service.uploadFile(img)); +// } +// return ApiResponse.of(SuccessStatus._OK,img_urls); +// } +//} +// +// +// diff --git a/src/main/java/GDGoC/team_24/domain/user/dto/UserResponseDto.java b/src/main/java/GDGoC/team_24/domain/user/dto/UserResponseDto.java index edd289a..ca1150b 100644 --- a/src/main/java/GDGoC/team_24/domain/user/dto/UserResponseDto.java +++ b/src/main/java/GDGoC/team_24/domain/user/dto/UserResponseDto.java @@ -10,7 +10,8 @@ public record UserResponseDto( String name, String emoji, String phoneNumber, - Family family + Long familyId + ) { public UserResponseDto(User user) { this( @@ -20,7 +21,7 @@ public UserResponseDto(User user) { user.getName(), user.getEmoji().toString(), user.getPhoneNumber(), - user.getFamily() + user.getFamily().getId() ); } } diff --git a/src/main/java/GDGoC/team_24/global/aws/AwsS3Service.java b/src/main/java/GDGoC/team_24/global/aws/AwsS3Service.java index 2124fe5..99e1e1c 100644 --- a/src/main/java/GDGoC/team_24/global/aws/AwsS3Service.java +++ b/src/main/java/GDGoC/team_24/global/aws/AwsS3Service.java @@ -1,6 +1,7 @@ package GDGoC.team_24.global.aws; import GDGoC.team_24.global.code.status.ErrorStatus; + import GDGoC.team_24.global.exception.Handler.S3Handler; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.DeleteObjectRequest; @@ -10,7 +11,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; - import java.io.IOException; import java.io.InputStream; import java.util.UUID; @@ -19,6 +19,8 @@ @Service @RequiredArgsConstructor public class AwsS3Service { + + @Value("${cloud.aws.s3.bucket}") private String bucket;