Skip to content
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

implementation 'org.flywaydb:flyway-core'
Expand Down Expand Up @@ -59,6 +60,8 @@ dependencies {

// 썸네일 라이브러리
implementation 'net.coobird:thumbnailator:0.4.20'

implementation 'software.amazon.awssdk:s3'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@

import jakarta.validation.Valid;
import java.util.List;
import kr.kro.photoliner.domain.photo.dto.request.CreatePhotosRequest;
import kr.kro.photoliner.domain.photo.dto.request.DeletePhotosRequest;
import kr.kro.photoliner.domain.photo.dto.request.PhotoCapturedDateUpdateRequest;
import kr.kro.photoliner.domain.photo.dto.request.PhotoLocationUpdateRequest;
import kr.kro.photoliner.domain.photo.dto.request.PhotoMarkersRequest;
import kr.kro.photoliner.domain.photo.dto.request.PresignedUrlRequest;
import kr.kro.photoliner.domain.photo.dto.response.PhotoMarkersResponse;
import kr.kro.photoliner.domain.photo.dto.response.PhotoUploadResponse;
import kr.kro.photoliner.domain.photo.dto.response.PhotosResponse;
import kr.kro.photoliner.domain.photo.dto.response.PresignedUrlResponse;
import kr.kro.photoliner.domain.photo.infra.S3CustomClient;
import kr.kro.photoliner.domain.photo.service.PhotoService;
import kr.kro.photoliner.domain.photo.service.PhotoUploadService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -26,22 +27,20 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/photos")
public class PhotoController {

private final PhotoService photoService;
private final PhotoUploadService photoUploadService;
private final S3CustomClient s3CustomClient;

@GetMapping
public ResponseEntity<PhotosResponse> getPhotos(
@RequestParam Long userId,
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable
@PageableDefault(sort = "capturedDt", direction = Sort.Direction.DESC) Pageable pageable
) {
return ResponseEntity.ok(photoService.getPhotosByIds(userId, pageable));
}
Expand All @@ -51,13 +50,20 @@ public ResponseEntity<PhotoMarkersResponse> getPhotoMarkers(@Valid PhotoMarkersR
return ResponseEntity.ok(photoService.getPhotoMarkers(request));
}

@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<PhotoUploadResponse> uploadPhotos(
@RequestParam("userId") Long userId,
@RequestPart("files") List<MultipartFile> files
@PostMapping("/presigned-urls")
public ResponseEntity<List<PresignedUrlResponse>> getPresignedUrls(
@Valid @RequestBody List<PresignedUrlRequest> requests
) {
PhotoUploadResponse response = photoUploadService.uploadPhotos(userId, files);
return ResponseEntity.status(HttpStatus.CREATED).body(response);
List<PresignedUrlResponse> responses = s3CustomClient.generatePresignedUrls(requests);
return ResponseEntity.ok(responses);
}

@PostMapping
public ResponseEntity<Void> createPhotos(
@Valid @RequestBody CreatePhotosRequest request
) {
photoService.createPhotos(request);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@PatchMapping("/{photoId}/captured-date")
Expand Down
11 changes: 0 additions & 11 deletions src/main/java/kr/kro/photoliner/domain/photo/dto/ExifData.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package kr.kro.photoliner.domain.photo.dto.request;

import jakarta.annotation.Nullable;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import org.locationtech.jts.geom.Coordinate;

public record CreatePhotosRequest(
@NotNull
Long userId,

@NotNull
@NotEmpty
List<InnerPhoto> photos
) {

public record InnerPhoto(
@NotNull
String fileName,

@NotNull
String uploadFileName,

@Nullable
LocalDateTime capturedDate,

@Nullable
@Min(0)
@Max(90)
Double latitude,

@Nullable
@Min(0)
@Max(180)
Double longitude
) {

public Coordinate convertToGeo() {
if (Objects.isNull(latitude) || Objects.isNull(longitude)) {
return null;
}
return new Coordinate(longitude, latitude);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kr.kro.photoliner.domain.photo.dto.request;

import jakarta.validation.constraints.NotBlank;

public record PresignedUrlRequest(
@NotBlank(message = "파일명은 필수입니다")
String originalFileName,

@NotBlank(message = "Content-Type은 필수입니다")
String contentType
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import kr.kro.photoliner.domain.photo.model.Photo;
import org.locationtech.jts.geom.Point;
import org.springframework.data.domain.Page;

public record PhotosResponse(
Expand Down Expand Up @@ -60,7 +58,7 @@ public static InnerPhotoResponse from(Photo photo) {
photo.getCapturedDt(),
photo.getLongitude(),
photo.getLatitude(),
photo.getUser().getId());
photo.getId());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package kr.kro.photoliner.domain.photo.dto.response;

public record PresignedUrlResponse(
String presignedUrl,
String uploadFileName
) {

public static PresignedUrlResponse of(String presignedUrl, String uploadFileName) {
return new PresignedUrlResponse(presignedUrl, uploadFileName);
}
}

This file was deleted.

Loading
Loading