Skip to content

Commit

Permalink
[Backend : Feat] 여행 후 사용자가 사진을 저장하는 기능 구현
Browse files Browse the repository at this point in the history
[Backend : Feat] 여행 후 사용자가 사진을 저장하는 기능 구현
  • Loading branch information
yo0oni authored Aug 8, 2024
2 parents 9534ab4 + e66823e commit 32b625d
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 59 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.isp.backend.domain.scheduleImage.controller;

import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageResponse;
import com.isp.backend.domain.scheduleImage.service.SaveImageService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequiredArgsConstructor
@RequestMapping("/scheduleImages")
public class ScheduleImageController {

private final SaveImageService saveImageService;

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public SaveScheduleImageResponse create(@RequestPart(value = "image", required = false) MultipartFile image,
@RequestPart(value = "saveScheduleImageRequest") SaveScheduleImageRequest request) {
return saveImageService.save(request, image);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.isp.backend.domain.scheduleImage.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Getter
@NoArgsConstructor
public class SaveScheduleImageRequest {
private Long scheduleId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime saveDate;

public Long scheduleId() {
return scheduleId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.isp.backend.domain.scheduleImage.dto;

import com.isp.backend.domain.scheduleImage.entity.ScheduleImage;
import lombok.Getter;

@Getter
public final class SaveScheduleImageResponse {
private final ScheduleImage scheduleImage;

public SaveScheduleImageResponse(ScheduleImage scheduleImage) {
this.scheduleImage = scheduleImage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.isp.backend.domain.scheduleImage.entity;

import com.isp.backend.domain.schedule.entity.Schedule;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
@Table(name = "schedule_image")
public class ScheduleImage {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "schedule_id")
private Schedule schedule;
private String path;

public ScheduleImage(Schedule schedule, String path) {
this.schedule = schedule;
this.path = path;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.isp.backend.domain.scheduleImage.repository;

import com.isp.backend.domain.scheduleImage.entity.ScheduleImage;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ScheduleImageRepository extends JpaRepository<ScheduleImage, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.isp.backend.domain.scheduleImage.repository;

import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
import io.awspring.cloud.s3.S3Resource;
import io.awspring.cloud.s3.S3Template;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

@Repository
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class ScheduleImageS3Repository {
private static final String IMAGE = "HowAboutTrip-Backend-ScheduleImage/";
private static final String SLASH = "/";

private final S3Template s3template;
private final String bucketName;

public ScheduleImageS3Repository(S3Template s3template,
@Value("${spring.cloud.aws.s3.bucket}") String bucketName) {
this.s3template = s3template;
this.bucketName = bucketName;
}

public String save(SaveScheduleImageRequest request, MultipartFile image) {
String path = IMAGE + request.scheduleId() + SLASH + image.getOriginalFilename();
S3Resource result = s3template.upload(bucketName, path, getInputStream(image));
return getUrl(result);
}

private InputStream getInputStream(MultipartFile image) {
try {
return image.getInputStream();
} catch (IOException e) {
throw new RuntimeException("Error getting input stream from MultipartFile", e);
}
}

private String getUrl(S3Resource s3Resource) {
try {
return s3Resource.getURL().toString();
} catch (IOException e) {
throw new RuntimeException("Error getting URL from S3Resource", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.isp.backend.domain.scheduleImage.service;

import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageResponse;
import org.springframework.web.multipart.MultipartFile;

public interface SaveImageService {

SaveScheduleImageResponse save(SaveScheduleImageRequest request, MultipartFile image);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.isp.backend.domain.scheduleImage.service;

import com.isp.backend.domain.schedule.entity.Schedule;
import com.isp.backend.domain.schedule.repository.ScheduleRepository;
import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageRequest;
import com.isp.backend.domain.scheduleImage.dto.SaveScheduleImageResponse;
import com.isp.backend.domain.scheduleImage.entity.ScheduleImage;
import com.isp.backend.domain.scheduleImage.repository.ScheduleImageRepository;
import com.isp.backend.domain.scheduleImage.repository.ScheduleImageS3Repository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Service
@RequiredArgsConstructor
public class ScheduleImageService implements SaveImageService {

private final ScheduleImageS3Repository scheduleImageS3Repository;
private final ScheduleRepository scheduleRepository;
private final ScheduleImageRepository scheduleImageRepository;

@Override
public SaveScheduleImageResponse save(SaveScheduleImageRequest request, MultipartFile image) {
String imagePath = scheduleImageS3Repository.save(request, image);
Schedule schedule = scheduleRepository.findById(request.scheduleId()).orElseThrow(IllegalArgumentException::new);
ScheduleImage scheduleImage = new ScheduleImage(schedule, imagePath);

scheduleImageRepository.save(scheduleImage);
return new SaveScheduleImageResponse(scheduleImage);
}
}

0 comments on commit 32b625d

Please sign in to comment.