Skip to content

Commit

Permalink
Merge branch 'develop' into feat/issue-763
Browse files Browse the repository at this point in the history
  • Loading branch information
wugawuga authored Oct 18, 2023
2 parents ac45159 + ef2ee73 commit 9f2c53d
Show file tree
Hide file tree
Showing 151 changed files with 3,823 additions and 830 deletions.
3 changes: 2 additions & 1 deletion backend/src/main/java/com/funeat/FuneatApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import com.funeat.common.repository.BaseRepositoryImpl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableAsync
@SpringBootApplication
@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class)
public class FuneatApplication {

public static void main(String[] args) {
SpringApplication.run(FuneatApplication.class, args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public class AdminProductSpecification {

private static final List<Class<Long>> COUNT_RESULT_TYPES = List.of(Long.class, long.class);

private AdminProductSpecification() {
}

public static Specification<Product> searchBy(final ProductSearchCondition condition) {
return (root, query, criteriaBuilder) -> {
if (!COUNT_RESULT_TYPES.contains(query.getResultType())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

public class AdminReviewSpecification {

private AdminReviewSpecification() {
}

public static Specification<Review> searchBy(final ReviewSearchCondition condition) {
return (root, query, criteriaBuilder) -> {
if (query.getResultType() != Long.class && query.getResultType() != long.class) {
Expand Down
59 changes: 59 additions & 0 deletions backend/src/main/java/com/funeat/comment/domain/Comment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.funeat.comment.domain;

import com.funeat.member.domain.Member;
import com.funeat.recipe.domain.Recipe;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Comment {

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

private String comment;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "recipe_id")
private Recipe recipe;

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

@Column(nullable = false)
private LocalDateTime createdAt = LocalDateTime.now();

protected Comment() {
}

public Comment(final Recipe recipe, final Member member, final String comment) {
this.recipe = recipe;
this.member = member;
this.comment = comment;
}

public Long getId() {
return id;
}

public String getComment() {
return comment;
}

public Member getMember() {
return member;
}

public LocalDateTime getCreatedAt() {
return createdAt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.funeat.comment.persistence;

import com.funeat.comment.domain.Comment;
import com.funeat.common.repository.BaseRepository;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CommentRepository extends JpaRepository<Comment, Long>, BaseRepository<Comment, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.funeat.comment.specification;

import com.funeat.comment.domain.Comment;
import com.funeat.recipe.domain.Recipe;
import java.util.List;
import java.util.Objects;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Path;
import org.springframework.data.jpa.domain.Specification;

public class CommentSpecification {

private CommentSpecification() {
}

private static final List<Class<Long>> COUNT_RESULT_TYPES = List.of(Long.class, long.class);

public static Specification<Comment> findAllByRecipe(final Recipe recipe, final Long lastCommentId) {
return (root, query, criteriaBuilder) -> {
if (!COUNT_RESULT_TYPES.contains(query.getResultType())) {
root.fetch("member", JoinType.LEFT);
}

criteriaBuilder.desc(root.get("id"));

return Specification
.where(lessThan(lastCommentId))
.and(equalToRecipe(recipe))
.toPredicate(root, query, criteriaBuilder);
};
}

private static Specification<Comment> lessThan(final Long commentId) {
return (root, query, criteriaBuilder) -> {
if (Objects.isNull(commentId)) {
return null;
}

final Path<Long> commentIdPath = root.get("id");

return criteriaBuilder.lessThan(commentIdPath, commentId);
};
}

private static Specification<Comment> equalToRecipe(final Recipe recipe) {
return (root, query, criteriaBuilder) -> {
if (Objects.isNull(recipe)) {
return null;
}

final Path<Recipe> recipePath = root.get("recipe");

return criteriaBuilder.equal(recipePath, recipe);
};
}
}
2 changes: 2 additions & 0 deletions backend/src/main/java/com/funeat/common/ImageUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
public interface ImageUploader {

String upload(final MultipartFile image);

void delete(final String fileName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ public S3UploadFailException(final CommonErrorCode errorCode) {
super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage()));
}
}

public static class S3DeleteFailException extends CommonException {
public S3DeleteFailException(final CommonErrorCode errorCode) {
super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage()));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.funeat.common.repository;

import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
Expand All @@ -11,4 +12,6 @@
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {

Page<T> findAllForPagination(final Specification<T> spec, final Pageable pageable, final Long totalElements);

List<T> findAllWithSpecification(final Specification<T> spec, final int pageSize);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.funeat.common.repository;

import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
Expand Down Expand Up @@ -37,4 +40,12 @@ public Page<T> findAllForPagination(final Specification<T> spec, final Pageable

return new PageImpl<>(query.getResultList(), PageRequest.of(0, pageSize), totalElements);
}

@Override
public List<T> findAllWithSpecification(final Specification<T> spec, final int pageSize) {
final TypedQuery<T> query = getQuery(spec, Sort.unsorted());
query.setMaxResults(pageSize);

return query.getResultList();
}
}
19 changes: 19 additions & 0 deletions backend/src/main/java/com/funeat/common/s3/S3Uploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import static com.funeat.exception.CommonErrorCode.IMAGE_EXTENSION_ERROR_CODE;
import static com.funeat.exception.CommonErrorCode.UNKNOWN_SERVER_ERROR_CODE;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.funeat.common.ImageUploader;
import com.funeat.common.exception.CommonException.NotAllowedFileExtensionException;
import com.funeat.common.exception.CommonException.S3DeleteFailException;
import com.funeat.common.exception.CommonException.S3UploadFailException;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
Expand All @@ -21,8 +25,11 @@
@Profile("!test")
public class S3Uploader implements ImageUploader {

private static final int BEGIN_FILE_NAME_INDEX_WITHOUT_CLOUDFRONT_PATH = 31;
private static final List<String> INCLUDE_EXTENSIONS = List.of("image/jpeg", "image/png", "image/webp");

private final Logger log = LoggerFactory.getLogger(this.getClass());

@Value("${cloud.aws.s3.bucket}")
private String bucket;

Expand Down Expand Up @@ -53,6 +60,18 @@ public String upload(final MultipartFile image) {
}
}

@Override
public void delete(final String image) {
final String imageName = image.substring(BEGIN_FILE_NAME_INDEX_WITHOUT_CLOUDFRONT_PATH);
try {
final String key = folder + imageName;
amazonS3.deleteObject(bucket, key);
} catch (final AmazonServiceException e) {
log.error("S3 이미지 삭제에 실패했습니다. 이미지 경로 : {}", image);
throw new S3DeleteFailException(UNKNOWN_SERVER_ERROR_CODE);
}
}

private void validateExtension(final MultipartFile image) {
final String contentType = image.getContentType();
if (!INCLUDE_EXTENSIONS.contains(contentType)) {
Expand Down

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
Expand Up @@ -3,10 +3,15 @@
import com.funeat.member.domain.Member;
import com.funeat.member.domain.favorite.ReviewFavorite;
import com.funeat.review.domain.Review;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ReviewFavoriteRepository extends JpaRepository<ReviewFavorite, Long> {

Optional<ReviewFavorite> findByMemberAndReview(final Member member, final Review review);

void deleteByReview(final Review review);

List<ReviewFavorite> findByReview(final Review review);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import org.springframework.data.web.PageableDefault;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
Expand Down Expand Up @@ -69,4 +71,13 @@ public ResponseEntity<MemberRecipesResponse> getMemberRecipe(@AuthenticationPrin

return ResponseEntity.ok().body(response);
}

@Logging
@DeleteMapping("/reviews/{reviewId}")
public ResponseEntity<Void> deleteReview(@PathVariable final Long reviewId,
@AuthenticationPrincipal final LoginInfo loginInfo) {
reviewService.deleteReview(reviewId, loginInfo.getId());

return ResponseEntity.noContent().build();
}
}
Loading

0 comments on commit 9f2c53d

Please sign in to comment.