Skip to content

Commit

Permalink
feat: Add Suggest API (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
Berygna committed Aug 7, 2024
1 parent 8074c66 commit b16bd38
Show file tree
Hide file tree
Showing 15 changed files with 561 additions and 1,231 deletions.
1,230 changes: 0 additions & 1,230 deletions app.log

This file was deleted.

2 changes: 2 additions & 0 deletions src/main/java/jjhhyb/deepvalley/image/ImageService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class ImageService {
private final S3Service s3Service;
private static final String REVIEW_IMAGE_FOLDER = "review-images";
private static final String PROFILE_IMAGE_FOLDER = "profile-images";
private static final String SUGGEST_IMAGE_FOLDER = "suggest-images";

// 이미지 파일을 S3에 업로드하고 URL 리스트를 반환
public List<String> uploadImagesAndGetUrls(List<MultipartFile> imageFiles, ImageType imageType) {
Expand All @@ -32,6 +33,7 @@ private String getFolderByImageType(ImageType imageType) {
return switch (imageType) {
case REVIEW -> REVIEW_IMAGE_FOLDER;
case PROFILE -> PROFILE_IMAGE_FOLDER;
case SUGGEST -> SUGGEST_IMAGE_FOLDER;
};
}
}
2 changes: 1 addition & 1 deletion src/main/java/jjhhyb/deepvalley/image/ImageType.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package jjhhyb.deepvalley.image;

public enum ImageType {
REVIEW, PROFILE
REVIEW, PROFILE, SUGGEST
}
47 changes: 47 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/Suggest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package jjhhyb.deepvalley.suggest;

import jakarta.persistence.*;
import jjhhyb.deepvalley.place.Place;
import jjhhyb.deepvalley.user.entity.Member;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
@Builder
public class Suggest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long suggestId;
private String uuid;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "place_id")
private Place place;

@OneToMany(mappedBy = "suggest", cascade = CascadeType.ALL, orphanRemoval = true)
private List<SuggestImage> suggestImages = new ArrayList<>();

private String title;
private String content;

@CreatedDate
private LocalDateTime createdDate;

@LastModifiedDate
private LocalDateTime updatedDate;

private LocalDateTime visitedDate;
}
51 changes: 51 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/SuggestController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package jjhhyb.deepvalley.suggest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@RestController
@RequestMapping("/api/suggest")
public class SuggestController {
@Autowired
private SuggestService suggestService;

@PostMapping
public SuggestDetailResponse createSuggest(
@RequestPart("suggestPostRequest") SuggestPostRequest suggestPostRequest,
@RequestPart(value = "imageUrls", required = false) List<MultipartFile> imageFiles,
Authentication auth) {

return suggestService.createSuggest(suggestPostRequest, imageFiles, auth.getName());
}

// 정보변경제안 특성상 수정, 삭제 기능이 필요하지 않음
// @GetMapping
// public SuggestsResponse getAllSuggests() {
// return suggestService.getSuggests();
// }
//
// @GetMapping("/{suggest-id}")
// public SuggestDetailResponse getSuggestDetail(@PathVariable("suggest-id") String suggestId) {
// return suggestService.getSuggestDetail(suggestId);
// }
//
// @PutMapping("/{suggest-id}")
// public SuggestDetailResponse updateSuggest(
// @PathVariable("suggest-id") String suggestId,
// @RequestPart("suggestPostRequest") SuggestPostRequest suggestPostRequest,
// @RequestPart(value = "imageUrls", required = false) List<MultipartFile> imageFiles,
// Authentication auth) {
//
// return suggestService.updateSuggest(suggestId, suggestPostRequest, imageFiles, auth.getName());
// }
//
// @DeleteMapping("/{suggest-id}")
// public ResponseEntity<Void> deleteSuggest(@PathVariable("suggest-id") String suggestId, Authentication auth) {
// suggestService.deleteSuggest(suggestId, auth.getName());
// return ResponseEntity.noContent().build();
// }
}
45 changes: 45 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/SuggestDetailResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package jjhhyb.deepvalley.suggest;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class SuggestDetailResponse {
private String suggestId;
private String title;
private String content;
private String memberId;
private String placeId;
private String valleyName;
private String createdDate;
private String updatedDate;
private List<String> imageUrls;

public static SuggestDetailResponse from(Suggest suggest) {
return SuggestDetailResponse.builder()
.suggestId(String.valueOf(suggest.getUuid()))
.title(suggest.getTitle())
.content(suggest.getContent())
.memberId(String.valueOf(suggest.getMember().getLoginEmail()))
.placeId(String.valueOf(suggest.getPlace().getUuid()))
.valleyName(suggest.getPlace().getName())
.createdDate(String.valueOf(suggest.getCreatedDate()))
.updatedDate(String.valueOf(suggest.getUpdatedDate()))
.imageUrls((suggest.getSuggestImages() != null ? suggest.getSuggestImages().stream()
.map(reviewImage -> reviewImage.getImage().getImageUrl())
.collect(Collectors.toList()) : Collections.emptyList()))
.build();
}
}
29 changes: 29 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/SuggestImage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package jjhhyb.deepvalley.suggest;

import jakarta.persistence.*;
import jjhhyb.deepvalley.image.Image;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Builder
public class SuggestImage {

@EmbeddedId
private SuggestImageId id;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("suggestId")
@JoinColumn(name = "suggest_id")
private Suggest suggest;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("imageId")
@JoinColumn(name = "image_id")
private Image image;
}
26 changes: 26 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/SuggestImageId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package jjhhyb.deepvalley.suggest;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@NoArgsConstructor
@EqualsAndHashCode
@Embeddable
@Getter
public class SuggestImageId implements Serializable {
@Column(name = "SUGGEST_ID")
private Long suggestId;

@Column(name = "IMAGE_ID")
private Long imageId;

public SuggestImageId(Long suggestId, Long imageId) {
this.suggestId = suggestId;
this.imageId = imageId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package jjhhyb.deepvalley.suggest;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface SuggestImageRepository extends JpaRepository<SuggestImage, SuggestImageId> {
List<SuggestImage> findBySuggest_SuggestId(Long suggestId);
}
77 changes: 77 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/SuggestImageService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package jjhhyb.deepvalley.suggest;

import jjhhyb.deepvalley.community.repository.ImageRepository;
import jjhhyb.deepvalley.image.Image;
import jjhhyb.deepvalley.image.ImageService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SuggestImageService{
private final ImageRepository imageRepository;
private final SuggestImageRepository suggestImageRepository;
private final ImageService imageService;

// 이미지 URL 리스트로 SuggestImage 객체 리스트 생성
public List<SuggestImage> processImages(List<String> imageUrls, Suggest suggest) {
return imageUrls.stream()
.map(imageUrl -> createOrUpdateImage(imageUrl, suggest))
.collect(Collectors.toList());
}

// 이미지 URL로 Image 객체 생성 or 업데이트
private SuggestImage createOrUpdateImage(String imageUrl, Suggest suggest) {
// 데이터베이스에서 이미지 조회, 없으면 새로 생성
Image image = imageRepository.findByImageUrl(imageUrl);
if (image == null) {
image = imageRepository.save(new Image(imageUrl));
}
// SuggestImage 객체 생성
return SuggestImage.builder()
.id(new SuggestImageId(suggest.getSuggestId(), image.getImageId()))
.suggest(suggest)
.image(image)
.build();
}

// 제안과 연결된 이미지 업데이트
public void updateSuggestImages(Suggest suggest, List<SuggestImage> updatedImages) {
Set<Long> updatedImageIds = updatedImages.stream()
.map(suggestImage -> suggestImage.getId().getImageId())
.collect(Collectors.toSet());

// 기존 이미지 리스트와 업데이트된 이미지 IDs를 비교하여 삭제할 이미지들을 결정
List<SuggestImage> existingImages = new ArrayList<>(suggest.getSuggestImages()); // 모든 기존 이미지
List<SuggestImage> imagesToDelete = existingImages.stream() // 더 이상 사용되지 않는 이미지를 필터링해 포함
.filter(existingImage -> !updatedImageIds.contains(existingImage.getId().getImageId()))
.toList();

// 기존 이미지를 제안과의 연관관계에서 제거
suggest.getSuggestImages().removeAll(existingImages);
suggestImageRepository.flush();

suggest.getSuggestImages().clear();
suggest.getSuggestImages().addAll(updatedImages);

// S3에서 이미지 삭제
imageService.deleteImages(imagesToDelete.stream()
.map(image -> image.getImage().getImageUrl())
.collect(Collectors.toList()));
// 데이터 베이스에서 삭제
suggestImageRepository.deleteAll(existingImages);
}

// 주어진 SuggestImage 리스트의 모든 이미지 삭제
public void deleteAll(List<SuggestImage> suggestImages) {
imageService.deleteImages(suggestImages.stream()
.map(image -> image.getImage().getImageUrl())
.collect(Collectors.toList()));
suggestImageRepository.deleteAll(suggestImages);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package jjhhyb.deepvalley.suggest;

public class SuggestNotFoundException extends RuntimeException{
public SuggestNotFoundException(String message) {
super(message);
}
}
22 changes: 22 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/SuggestPostRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package jjhhyb.deepvalley.suggest;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class SuggestPostRequest {
private String title;
private String content;
private String placeId;
private List<String> imageUrls;
}
16 changes: 16 additions & 0 deletions src/main/java/jjhhyb/deepvalley/suggest/SuggestRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package jjhhyb.deepvalley.suggest;

import jjhhyb.deepvalley.user.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

public interface SuggestRepository extends JpaRepository<Suggest, Long> {
List<Suggest> findAllByPlace_Uuid(String uuid);
List<Suggest> findAllByMember_loginEmail(String uuid);
Optional<Suggest> findByUuid(String uuid);
List<Suggest> findByVisitedDateAfter(LocalDate date);
void deleteByMember(Member member);
}
Loading

0 comments on commit b16bd38

Please sign in to comment.