Skip to content

Commit

Permalink
fix: 뉴스레터 스크랩 로직 추가 & Member와 연관관계 매핑 (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
why-only-english committed Feb 14, 2024
1 parent 4fe61e6 commit a687c5f
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 48 deletions.
30 changes: 18 additions & 12 deletions src/main/java/com/api/ttoklip/domain/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.api.ttoklip.domain.honeytip.post.domain.HoneyTip;
import com.api.ttoklip.domain.member.editor.MemberEditor;
import com.api.ttoklip.domain.member.editor.MemberEditor.MemberEditorBuilder;
import com.api.ttoklip.domain.newsletter.scarp.entity.NewsletterScrap;
import com.api.ttoklip.domain.privacy.domain.Interest;
import com.api.ttoklip.domain.privacy.domain.Profile;
import com.api.ttoklip.domain.question.post.domain.Question;
Expand Down Expand Up @@ -75,6 +76,23 @@ public class Member extends BaseEntity {
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<HoneyTipLike> honeyTipLikes = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Community> communities = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CommunityLike> communityLikes = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CommunityScrap> communityScraps = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<NewsletterScrap> newsletterScraps = new ArrayList<>();


public MemberEditorBuilder toEditor() {
return MemberEditor.builder()
.independentYear(independentYear)
Expand All @@ -88,16 +106,4 @@ public void insertPrivacy(MemberEditor memberEditor) {
independentMonth = memberEditor.getIndependentMonth();
nickname = memberEditor.getNickname();
}

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Community> communities = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CommunityLike> communityLikes = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CommunityScrap> communityScraps = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package com.api.ttoklip.domain.newsletter.post.domain;

import static com.api.ttoklip.global.util.SecurityUtil.getCurrentMember;

import com.api.ttoklip.domain.common.Category;
import com.api.ttoklip.domain.common.base.BaseEntity;
import com.api.ttoklip.domain.member.domain.Member;
import com.api.ttoklip.domain.newsletter.comment.domain.NewsletterComment;
import com.api.ttoklip.domain.newsletter.image.domain.NewsletterImage;
import com.api.ttoklip.domain.newsletter.post.dto.request.NewsletterCreateReq;
import com.api.ttoklip.domain.newsletter.scarp.entity.NewsletterScrap;
import com.api.ttoklip.domain.newsletter.url.domain.NewsletterUrl;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
Expand Down Expand Up @@ -45,6 +41,10 @@ public class Newsletter extends BaseEntity {

private String mainImageUrl;

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

@Builder.Default
@OneToMany(mappedBy = "newsletter", cascade = CascadeType.ALL, orphanRemoval = true)
private List<NewsletterImage> newsletterImageList = new ArrayList<>();
Expand All @@ -57,12 +57,21 @@ public class Newsletter extends BaseEntity {
@OneToMany(mappedBy = "newsletter", cascade = CascadeType.ALL, orphanRemoval = true)
private List<NewsletterComment> newsletterComments = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "newsletter", cascade = CascadeType.ALL, orphanRemoval = true)
private List<NewsletterScrap> newsletterScraps = new ArrayList<>();

public static Newsletter from(final NewsletterCreateReq req, final String mainImageUrl) {
return Newsletter.builder()
.title(req.getTitle())
.content(req.getContent())
.category(req.getCategory())
.mainImageUrl(mainImageUrl)
.member(getCurrentMember())
.build();
}

public long getScrapsCount() {
return newsletterScraps.size();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.api.ttoklip.domain.newsletter.comment.domain.NewsletterComment;
import com.api.ttoklip.domain.newsletter.post.domain.Newsletter;
import com.api.ttoklip.domain.town.community.post.entity.Community;

import java.util.List;

public interface NewsletterQueryDslRepository {
Expand All @@ -11,4 +13,9 @@ public interface NewsletterQueryDslRepository {
List<NewsletterComment> findActiveCommentsByNewsletterId(final Long postId);

Long findNewsletterCount();

Newsletter findByIdActivated(final Long newsletterId);

Long countNewsletterScrapsByCommunityId(final Long newsletterId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.api.ttoklip.domain.newsletter.post.service;

import com.api.ttoklip.domain.newsletter.post.domain.Newsletter;
import com.api.ttoklip.domain.newsletter.post.repository.NewsletterRepository;
import com.api.ttoklip.global.exception.ApiException;
import com.api.ttoklip.global.exception.ErrorType;
import com.api.ttoklip.global.s3.S3FileUploader;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

import static com.api.ttoklip.global.util.SecurityUtil.getCurrentMember;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class NewsletterCommonService {

private final S3FileUploader s3FileUploader;
private final NewsletterRepository newsletterRepository;

/* -------------------------------------------- COMMON -------------------------------------------- */
public Newsletter getNewsletter(final Long postId) {
return newsletterRepository.findByIdActivated(postId);
}

public List<String> uploadImages(final List<MultipartFile> uploadImages) {
return s3FileUploader.uploadMultipartFiles(uploadImages);
}

public void checkEditPermission(final Newsletter newsletter) {
Long writerId = newsletter.getMember().getId();
Long currentMemberId = getCurrentMember().getId();

if (!writerId.equals(currentMemberId)) {
throw new ApiException(ErrorType.UNAUTHORIZED_EDIT_POST);
}
}

/* -------------------------------------------- COMMON 끝 -------------------------------------------- */
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.api.ttoklip.domain.newsletter.post.dto.request.NewsletterCreateReq;
import com.api.ttoklip.domain.newsletter.post.dto.response.NewsletterWithCommentRes;
import com.api.ttoklip.domain.newsletter.post.repository.NewsletterRepository;
import com.api.ttoklip.domain.newsletter.scarp.repository.NewsletterScrapRepository;
import com.api.ttoklip.domain.newsletter.url.service.NewsletterUrlService;
import com.api.ttoklip.global.exception.ApiException;
import com.api.ttoklip.global.exception.ErrorType;
Expand All @@ -30,14 +31,16 @@ public class NewsletterPostService {
private final NewsletterImageService imageService;
private final NewsletterUrlService urlService;
private final ReportService reportService;
private final NewsletterScrapRepository newsletterScrapRepository;
private final NewsletterCommonService newsletterCommonService;


/* -------------------------------------------- 존재 여부 확인 -------------------------------------------- */
public Newsletter findById(final Long postId) {
return newsletterRepository.findById(postId)
.orElseThrow(() -> new ApiException(ErrorType.NEWSLETTER_NOT_FOUND));
}
/* -------------------------------------------- 존재 여부 확인 -------------------------------------------- */
// /* -------------------------------------------- 존재 여부 확인 -------------------------------------------- */
// public Newsletter findById(final Long postId) {
// return newsletterRepository.findById(postId)
// .orElseThrow(() -> new ApiException(ErrorType.NEWSLETTER_NOT_FOUND));
// }
// /* -------------------------------------------- 존재 여부 확인 -------------------------------------------- */


/* -------------------------------------------- CREATE -------------------------------------------- */
Expand Down Expand Up @@ -101,8 +104,9 @@ public NewsletterWithCommentRes getSinglePost(final Long postId) {
/* -------------------------------------------- REPORT -------------------------------------------- */
@Transactional
public Message report(final Long postId, final ReportCreateRequest request) {
Newsletter newsletter = findById(postId);
Newsletter newsletter = newsletterCommonService.getNewsletter(postId);
reportService.reportNewsletter(request, newsletter);

return Message.reportPostSuccess(Newsletter.class, postId);
}
/* -------------------------------------------- REPORT 끝 -------------------------------------------- */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.api.ttoklip.domain.newsletter.scarp.repository;

import com.api.ttoklip.domain.newsletter.scarp.entity.NewsletterScrap;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface NewsletterScrapRepository extends JpaRepository<NewsletterScrap, Long>, NewsletterScrapRepositoryCustom {
Optional<NewsletterScrap> findByNewsletterIdAndMemberId(Long newsletterId, Long memberId);

boolean existsByNewsletterIdAndMemberId(Long postId, Long memberId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.api.ttoklip.domain.newsletter.scarp.repository;

public interface NewsletterScrapRepositoryCustom {

Long countNewsletterScrapsByNewsletterId(final Long newsletterId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.api.ttoklip.domain.newsletter.scarp.service;

import com.api.ttoklip.domain.newsletter.post.domain.Newsletter;
import com.api.ttoklip.domain.newsletter.post.service.NewsletterCommonService;
import com.api.ttoklip.domain.newsletter.scarp.entity.NewsletterScrap;
import com.api.ttoklip.domain.newsletter.scarp.repository.NewsletterScrapRepository;
import com.api.ttoklip.global.exception.ApiException;
import com.api.ttoklip.global.exception.ErrorType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.api.ttoklip.global.util.SecurityUtil.getCurrentMember;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class NewsletterScrapService {

private final NewsletterScrapRepository newsletterScrapRepository;
private final NewsletterCommonService newsletterCommonService;

// 스크랩 생성
public void registerScrap(final Long newsletterId) {
Long currentMemberId = getCurrentMember().getId();
boolean exists = newsletterScrapRepository.existsByNewsletterIdAndMemberId(newsletterId, currentMemberId);
if (exists) {
return; // 이미 스크랩이 존재하면 스크랩을 생성하지 않고 return
}
Newsletter findNewsletter = newsletterCommonService.getNewsletter(newsletterId);
NewsletterScrap newsletterScrap = NewsletterScrap.from(findNewsletter);
newsletterScrapRepository.save(newsletterScrap);
}

// 스크랩 취소
public void cancelScrap(final Long newsletterId) {
// HoneyTipId (게시글 ID)
Newsletter findNewsletter = newsletterCommonService.getNewsletter(newsletterId);
Long findNewsletterId = findNewsletter.getId();
Long currentMemberId = getCurrentMember().getId();
NewsletterScrap newsletterScrap = newsletterScrapRepository.findByNewsletterIdAndMemberId(findNewsletterId, currentMemberId)
.orElseThrow(() -> new ApiException(ErrorType.SCRAP_NOT_FOUND));
// 자격 검증: 이 단계에서는 findByHoneyTipIdAndMemberId 결과가 존재하므로, 현재 사용자가 좋아요를 누른 것입니다.
// 별도의 자격 검증 로직이 필요 없으며, 바로 삭제를 진행할 수 있습니다.
newsletterScrapRepository.deleteById(newsletterScrap.getId());
}
public Long countNewsletterScraps(final Long newsletterId) {
return newsletterScrapRepository.countNewsletterScrapsByNewsletterId(newsletterId);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package com.api.ttoklip.domain.town.community.post.service;

import com.api.ttoklip.domain.member.domain.Member;
import static com.api.ttoklip.global.util.SecurityUtil.getCurrentMember;

import com.api.ttoklip.domain.town.community.post.entity.Community;
import com.api.ttoklip.domain.town.community.post.repository.CommunityRepository;
import com.api.ttoklip.global.exception.ApiException;
import com.api.ttoklip.global.exception.ErrorType;
import com.api.ttoklip.global.s3.S3FileUploader;
import com.api.ttoklip.global.util.SecurityUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;


@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
Expand All @@ -37,15 +36,10 @@ public void checkEditPermission(final Community community) {
Long currentMemberId = getCurrentMember().getId();

if (!writerId.equals(currentMemberId)) {
// todo 게시글 별 커스텀 에러 수정
throw new ApiException(ErrorType.UNAUTHORIZED_EDIT_POST);
}
}

public static Member getCurrentMember() {
return SecurityUtil.getCurrentMember();
}

/* -------------------------------------------- COMMON 끝 -------------------------------------------- */

}
24 changes: 12 additions & 12 deletions src/main/java/com/api/ttoklip/global/success/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,6 @@ public static <T> Message likePostCancel(Class<T> itemType, Long itemId) {
return actionSuccess(itemType, itemId, LIKE, DELETE);
}

public static Message insertPrivacy() {
return Message.builder()
.message("회원가입 후 개인정보를 추가했습니다.")
.build();
}

public static Message validNickname() {
return Message.builder()
.message("닉네임 중복 확인에 통과하였습니다.")
.build();
}

public static <T> Message editStatusSuccess(Class<T> itemType, Long itemId) {
return actionSuccess(itemType, itemId, STATUS, EDIT);
}
Expand All @@ -98,4 +86,16 @@ public static <T> Message scrapPostSuccess(Class<T> itemType, Long itemId) {
public static <T> Message scrapPostCancel(Class<T> itemType, Long itemId) {
return actionSuccess(itemType, itemId, SCRAP, DELETE);
}

public static Message insertPrivacy() {
return Message.builder()
.message("회원가입 후 개인정보를 추가했습니다.")
.build();
}

public static Message validNickname() {
return Message.builder()
.message("닉네임 중복 확인에 통과하였습니다.")
.build();
}
}

0 comments on commit a687c5f

Please sign in to comment.