Skip to content

Commit

Permalink
Merge pull request #67 from NewsFit-jolp/fix/#53-recommend
Browse files Browse the repository at this point in the history
Fix/#53 recommend
  • Loading branch information
k000927 authored Oct 31, 2024
2 parents 53abd13 + 4d8036a commit c467506
Show file tree
Hide file tree
Showing 22 changed files with 219 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public SuccessResponse<List<GetArticles>> getArticle(@RequestParam(value = "cate
@Operation(summary = "뉴스 검색",
description = """
뉴스 검색 API입니다.
파라미터는 다음과 같습니다.
keyword: 검색하고자 하는 기사의 키워드를 지정합니다.
articleCursor: 조회하고자 하는 페이지의 직전 기사의 아이디입니다.
Expand Down Expand Up @@ -119,23 +119,34 @@ public SuccessResponse<Boolean> deleteArticleLikes(@PathVariable("articleId") St
return SuccessResponse.success(articleService.deleteArticleLikes(articleId));
}

@Operation(summary = "댓글 좋아요",
// @Operation(summary = "댓글 좋아요",
// description = """
// 댓글 좋아요 API입니다.
// """)
// @PostMapping("/{articleId}/comments/{commentId}/likes")
// public SuccessResponse<Boolean> postCommentLikes(@PathVariable("articleId") String articleId,
// @PathVariable("commentId") String commentId) {
// return SuccessResponse.createSuccess(articleService.postCommentLikes(articleId, commentId));
// }
//
// @Operation(summary = "댓글 좋아요 취소",
// description = """
// 댓글 좋아요 취소 API입니다.
// """)
// @DeleteMapping("/{articleId}/comments/{commentId}/likes")
// public SuccessResponse<Boolean> deleteCommentLikes(@PathVariable("articleId") String articleId,
// @PathVariable("commentId") String commentId) {
// return SuccessResponse.createSuccess(articleService.deleteCommentLikes(articleId, commentId));
// }

@Operation(summary = "기사 선호도 평가",
description = """
댓글 좋아요 API입니다.
기사 선호도 평가 API입니다.
""")
@PostMapping("/{articleId}/comments/{commentId}/likes")
public SuccessResponse<Boolean> postCommentLikes(@PathVariable("articleId") String articleId,
@PathVariable("commentId") String commentId) {
return SuccessResponse.createSuccess(articleService.postCommentLikes(articleId, commentId));
@PostMapping("/{articleId}/rate")
public SuccessResponse<String> rateArticle(@PathVariable("articleId") String articleId,
@RequestBody String requestBody) throws ParseException, JsonProcessingException {
return SuccessResponse.createSuccess(articleService.rateArticle(Long.valueOf(articleId), requestBody));
}

@Operation(summary = "댓글 좋아요 취소",
description = """
댓글 좋아요 취소 API입니다.
""")
@DeleteMapping("/{articleId}/comments/{commentId}/likes")
public SuccessResponse<Boolean> deleteCommentLikes(@PathVariable("articleId") String articleId,
@PathVariable("commentId") String commentId) {
return SuccessResponse.createSuccess(articleService.deleteCommentLikes(articleId, commentId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static GetComment of(Comment comment) {
comment.getMember().getNickname(),
comment.getLikeCount(),
comment.getCreatedDate(),
comment.getMember().getMemberId().equals(memberId)
comment.getMember().getOAuthId().equals(memberId)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ public class Article extends BaseEntity {

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "article_id")
private Long articleId;

private String title;

@Lob
@Column(columnDefinition = "TEXT")
private String content;

@ElementCollection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import net.minidev.json.annotate.JsonIgnore;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -18,6 +19,7 @@ public class ArticleLike {

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

@ManyToOne(fetch = FetchType.LAZY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Comment extends BaseEntity {
private Article article;

@ManyToOne
@JoinColumn(name = "member")
@JoinColumn(name = "member_id")
@JsonIgnore
private Member member;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jakarta.persistence.*;
import lombok.Builder;
import lombok.NoArgsConstructor;
import net.minidev.json.annotate.JsonIgnore;

@Entity
@NoArgsConstructor
Expand All @@ -14,6 +15,7 @@ public class CommentLike {

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

@ManyToOne(fetch = FetchType.LAZY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public interface ArticleLikesRepository extends JpaRepository<ArticleLike, Long> {
Optional<ArticleLike> findByMemberAndArticle(Member member, Article article);

Boolean existsByMember_MemberIdAndArticle(String memberId, Article article);
Boolean existsByMember_OAuthIdAndArticle(String OAuthId, Article article);

Optional<Integer> removeByMemberAndArticle(Member member, Article article);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ List<Article> findAllByTitleOrCategoryContaining(
Pageable pageable
);

@Transactional
@Modifying
@Query("DELETE FROM Article a " +
@Query("SELECT a FROM Article a " +
"WHERE a.createdDate < :yesterday")
void deleteOldArticle(@Param("yesterday") LocalDateTime yesterday);
List<Article> findOldArticle(@Param("yesterday") LocalDateTime yesterday);
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
package com.example.newsfit.domain.article.service;

import com.example.newsfit.domain.article.entity.Article;
import com.example.newsfit.domain.article.repository.ArticleRepository;
import com.example.newsfit.global.util.RecommenderUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

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

@Component
@RequiredArgsConstructor
public class ArticleCleanupScheduler {

@Autowired
private final ArticleRepository articleRepository;
private final RecommenderUtils recommenderUtils;

@Scheduled(cron = "0 0 4 * * ?")
public void cleanup() {
public void cleanup() throws JsonProcessingException {
LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
articleRepository.deleteOldArticle(yesterday);
List<Article> oldArticles = articleRepository.findOldArticle(yesterday);
for (Article oldArticle : oldArticles) {
recommenderUtils.removeOldArticles(oldArticle.getArticleId());
articleRepository.delete(oldArticle);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.example.newsfit.domain.member.repository.MemberRepository;
import com.example.newsfit.global.error.exception.CustomException;
import com.example.newsfit.global.error.exception.ErrorCode;
import com.example.newsfit.global.util.RecommenderUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -47,6 +48,7 @@ public class ArticleService {
private final ArticleSourceRepository articleSourceRepository;

private final RestTemplate restTemplate;
private final RecommenderUtils recommenderUtils;

@Value("${cloud.aws.lambda.langchain.endpoint}")
private String langChainEndpoint;
Expand Down Expand Up @@ -87,7 +89,7 @@ public GetArticles postArticle(String requestBody) throws ParseException {
}

public List<GetArticles> getArticles(String category, Long articleCursor, int size) {
Member member = memberRepository.findByMemberId(SecurityContextHolder.getContext().getAuthentication().getName())
Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

Category categoryEnum = null;
Expand Down Expand Up @@ -123,7 +125,7 @@ public Boolean removeArticle(Long articleId) {
public GetComment postComment(String articleId, String requestBody) throws ParseException {
JSONObject jsonObject = jsonObjectParser(requestBody);

Member member = memberRepository.findByMemberId(SecurityContextHolder.getContext().getAuthentication().getName())
Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

Article article = articleRepository.findById(Long.parseLong(articleId))
Expand All @@ -148,7 +150,7 @@ public GetArticle getArticle(String articleId) throws JsonProcessingException {
article.summaryArticle(summaryArticle(article));
}

Boolean isLikedArticle = articleLikesRepository.existsByMember_MemberIdAndArticle(SecurityContextHolder.getContext().getAuthentication().getName(), article);
Boolean isLikedArticle = articleLikesRepository.existsByMember_OAuthIdAndArticle(SecurityContextHolder.getContext().getAuthentication().getName(), article);
return GetArticle.of(article, isLikedArticle);
}

Expand Down Expand Up @@ -183,7 +185,7 @@ public Boolean deleteComment(String articleId, String commentId) {
Comment comment = commentRepository.findById(Long.parseLong(commentId))
.orElseThrow(() -> new CustomException(ErrorCode.COMMENT_NOT_FOUND));

Member member = memberRepository.findByMemberId(SecurityContextHolder.getContext().getAuthentication().getName())
Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

if (!comment.getMember().equals(member)) {
Expand All @@ -197,7 +199,7 @@ public Boolean postArticleLikes(String articleId) {
Article article = articleRepository.findById(Long.parseLong(articleId))
.orElseThrow(() -> new CustomException(ErrorCode.ARTICLE_NOT_FOUND));

Member member = memberRepository.findByMemberId(SecurityContextHolder.getContext().getAuthentication().getName())
Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));


Expand All @@ -220,7 +222,7 @@ public Boolean deleteArticleLikes(String articleId) {
Article article = articleRepository.findById(Long.parseLong(articleId))
.orElseThrow(() -> new CustomException(ErrorCode.ARTICLE_NOT_FOUND));

Member member = memberRepository.findByMemberId(SecurityContextHolder.getContext().getAuthentication().getName())
Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

Optional<Integer> removeLike = articleLikesRepository.removeByMemberAndArticle(member, article);
Expand All @@ -238,7 +240,7 @@ public Boolean postCommentLikes(String articleId, String commentId) {
Comment comment = commentRepository.findById(Long.parseLong(commentId))
.orElseThrow(() -> new CustomException(ErrorCode.COMMENT_NOT_FOUND));

Member member = memberRepository.findByMemberId(SecurityContextHolder.getContext().getAuthentication().getName())
Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

if (commentLikesRepository.findByMemberAndComment(member, comment).isPresent()) {
Expand All @@ -260,7 +262,7 @@ public Boolean deleteCommentLikes(String articleId, String commentId) {
Comment comment = commentRepository.findById(Long.parseLong(commentId))
.orElseThrow(() -> new CustomException(ErrorCode.COMMENT_NOT_FOUND));

Member member = memberRepository.findByMemberId(SecurityContextHolder.getContext().getAuthentication().getName())
Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

Optional<Integer> removeLike = commentLikesRepository.removeByMemberAndComment(member, comment);
Expand Down Expand Up @@ -304,5 +306,15 @@ private List<Article> searchArticlesByCursor(String keyword, Long articleId, int
articleRepository.findAllByTitleOrCategoryContaining(keyword, pageable) :
articleRepository.findByTitleOrCategoryContaining(keyword, articleId, pageable);
}

public String rateArticle(Long articleId, String requestBody) throws ParseException, JsonProcessingException {
JSONObject jsonObject = jsonObjectParser(requestBody);
Integer preference = (Integer) jsonObject.get("preference");

Member member = memberRepository.findByOAuthId(SecurityContextHolder.getContext().getAuthentication().getName())
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

return recommenderUtils.rateArticle(articleId, member.getId(), preference);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public SuccessResponse<GetMemberInfo> putMemberInfo(@RequestBody String requestB
유저 선호 주제를 수정합니다.
""")
@PutMapping("/categories")
public SuccessResponse<GetPreferredCategories> putPreferredCategories(@RequestBody String requestBody) throws ParseException {
public SuccessResponse<GetPreferredCategories> putPreferredCategories(@RequestBody String requestBody) throws ParseException, JsonProcessingException {
return SuccessResponse.success(memberService.putPreferredCategories(requestBody));
}

Expand All @@ -181,7 +181,7 @@ public SuccessResponse<GetPreferredCategories> putPreferredCategories(@RequestBo
유저 선호 언론사를 수정합니다.
""")
@PutMapping("/press")
public SuccessResponse<GetPreferredPress> purPreferredPress(@RequestBody String requestBody) throws ParseException {
public SuccessResponse<GetPreferredPress> purPreferredPress(@RequestBody String requestBody) throws ParseException, JsonProcessingException {
return SuccessResponse.success(memberService.putPreferredPress(requestBody));
}

Expand All @@ -190,7 +190,7 @@ public SuccessResponse<GetPreferredPress> purPreferredPress(@RequestBody String
회원 탈퇴를 진행합니다.
""")
@DeleteMapping("/withdraw")
public SuccessResponse<Boolean> deleteMember() {
public SuccessResponse<Boolean> deleteMember() throws JsonProcessingException {
return SuccessResponse.success(memberService.deleteMember());
}

Expand Down Expand Up @@ -225,7 +225,7 @@ public SuccessResponse<GetPreferredPress> getPreferredPress() {
""")
@DeleteMapping("/delete")
public SuccessResponse<Boolean> deleteUser() {
public SuccessResponse<Boolean> deleteUser() throws JsonProcessingException {
return SuccessResponse.success(memberService.deleteUser());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
package com.example.newsfit.domain.member.dto;

import com.amazonaws.services.dynamodbv2.xspec.S;
import com.example.newsfit.domain.article.entity.Category;
import com.example.newsfit.domain.member.entity.*;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.ArrayList;
import java.util.List;

public record GetPreferredCategories(
@Schema(description = "선호 카테고리", example = "IT, Technology, Sports") List<Category> preferredCategories

@Schema(description = "선호 카테고리", example = "IT, Technology, Sports") List<String> preferredCategories
) {
public static GetPreferredCategories of(Member member) {
return new GetPreferredCategories(member.getPreferredCategories());
List<Category> preferredCategories = member.getPreferredCategories();
List<String> displayName = new ArrayList<>();
for (Category category : preferredCategories) {
displayName.add(category.toString());
}
return new GetPreferredCategories(displayName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public MemberDto(String memberId, String email, String nickname, String profileI

public static MemberDto of(Member member) {
return MemberDto.builder()
.memberId(member.getMemberId())
.memberId(member.getOAuthId())
.email(member.getEmail())
.nickname(member.getNickname())
.profileImage(member.getProfileImage())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.example.newsfit.domain.member.entity;

public enum Gender {
Male, Female
MALE, FEMALE, UNKNOWN;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ public class Member extends BaseEntity {

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

private String memberId;
private String OAuthId;

private String nickname;

Expand All @@ -47,9 +48,9 @@ public class Member extends BaseEntity {
private Role role;

@Builder
public Member(String memberId, String email, String phone, String profileImage,
public Member(String OAuthId, String email, String phone, String profileImage,
String nickname, Date birth, Role role, Gender gender) {
this.memberId = memberId;
this.OAuthId = OAuthId;
this.email = email;
this.phone = phone;
this.nickname = nickname;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
public interface MemberRepository extends JpaRepository<Member, Long> {


Optional<Member> findByMemberId(String member);
Optional<Member> findByOAuthId(String member);

}
Loading

0 comments on commit c467506

Please sign in to comment.