From dc57e1d2c63552058b7bb5a41bdbbbfdb24d2e6b Mon Sep 17 00:00:00 2001 From: orlzlL Date: Thu, 11 Apr 2024 19:30:22 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[feat]=20=EB=82=B4=20=EA=B2=8C=EC=8B=9C?= =?UTF-8?q?=EA=B8=80=EC=97=90=20=EC=83=88=EB=A1=9C=EC=9A=B4=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=EC=9D=B4=20=EC=9E=91=EC=84=B1=EB=90=98=EC=97=88?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EC=95=8C=EB=9E=8C=EC=9D=B4=20=EC=98=A4?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @Setter 없이 ModelMapper 사용하도록 main 수정해야함 MyPostListDTO 및 Post 엔티티 컬럼명 변경(location -> locationId) 해야함 --- .../comment/command/dto/CommentDTO.java | 1 - .../command/service/CommentServiceImpl.java | 26 ++++++++++++++++--- .../controller/NotificationController.java | 2 +- .../command/service/NotificationService.java | 14 +++++++--- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/dto/CommentDTO.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/dto/CommentDTO.java index f947248..3595770 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/dto/CommentDTO.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/dto/CommentDTO.java @@ -24,6 +24,5 @@ public class CommentDTO { private String memberId; - private String nickname; // 필요없으면 지움 } diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java index c39be6f..a2a9984 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java @@ -11,9 +11,12 @@ import org.omoknoone.onionhotsayyo.comment.command.dto.CommentDTO; import org.omoknoone.onionhotsayyo.comment.command.dto.CommentReplyDTO; import org.omoknoone.onionhotsayyo.comment.command.repository.CommentRepository; -import org.omoknoone.onionhotsayyo.member.aggregate.Member; import org.omoknoone.onionhotsayyo.member.dto.MemberDTO; import org.omoknoone.onionhotsayyo.member.service.MemberService; +import org.omoknoone.onionhotsayyo.notification.command.service.NotificationService; +import org.omoknoone.onionhotsayyo.post.command.repository.PostRepository; +import org.omoknoone.onionhotsayyo.post.command.service.PostService; +import org.omoknoone.onionhotsayyo.post.command.vo.PostDetailVO; import org.omoknoone.onionhotsayyo.reply.command.dto.ReplyDTO; import org.omoknoone.onionhotsayyo.reply.command.service.ReplyService; import org.springframework.beans.factory.annotation.Autowired; @@ -26,14 +29,22 @@ public class CommentServiceImpl implements CommentService { private final CommentRepository commentRepository; private final ReplyService replyService; private final MemberService memberService; + private final NotificationService notificationService; + private final PostService postService; + private final PostRepository postRepository; + @Autowired - public CommentServiceImpl(ModelMapper modelMapper, CommentRepository commentRepository, ReplyService replyService, MemberService memberService) { + public CommentServiceImpl(ModelMapper modelMapper, CommentRepository commentRepository, ReplyService replyService, MemberService memberService, + NotificationService notificationService, PostService postService, PostRepository postRepository) { this.modelMapper = modelMapper; this.commentRepository = commentRepository; this.replyService = replyService; this.memberService = memberService; - } + this.notificationService = notificationService; + this.postService = postService; + this.postRepository = postRepository; + } @Transactional @Override @@ -42,7 +53,14 @@ public void createComment(CommentDTO commentDTO) { Comment comment = modelMapper.map(commentDTO, Comment.class); commentRepository.save(comment); - + System.out.println("[comment] = " + comment); + + // 새 댓글 등록 시 알림 + // PostDetailVO post = postService.viewPostById(commentDTO.getPostId()); + PostDetailVO post = postService.viewPostById(comment.getPostId()); + MemberDTO postAuthor = memberService.getMemberDetailsByMemberId(post.getMemberId()); + MemberDTO commentAuthor = memberService.getMemberDetailsByMemberId(comment.getMemberId()); + notificationService.send(postAuthor.getMemberId(), commentAuthor.getNickname() + "님이 내 글에 댓글을 달았습니다: " + comment.getContent()); } @Transactional diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/controller/NotificationController.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/controller/NotificationController.java index 4d3078e..f3fd2de 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/controller/NotificationController.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/controller/NotificationController.java @@ -18,7 +18,7 @@ @RequestMapping("/notifications") public class NotificationController { private final NotificationService notificationService; - + public static Map sseEmitters = new ConcurrentHashMap<>(); @Autowired public NotificationController(NotificationService notificationService) { this.notificationService = notificationService; diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationService.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationService.java index e40c14d..72ecba0 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationService.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationService.java @@ -2,16 +2,22 @@ import java.io.IOException; import java.time.LocalDateTime; +import java.util.HashMap; import java.util.Map; import org.modelmapper.ModelMapper; +import org.omoknoone.onionhotsayyo.comment.command.aggregate.Comment; +import org.omoknoone.onionhotsayyo.comment.command.repository.CommentRepository; import org.omoknoone.onionhotsayyo.member.aggregate.Member; import org.omoknoone.onionhotsayyo.member.repository.MemberRepository; import org.omoknoone.onionhotsayyo.member.service.MemberService; import org.omoknoone.onionhotsayyo.notification.command.aggregate.Notification; +import org.omoknoone.onionhotsayyo.notification.command.controller.NotificationController; import org.omoknoone.onionhotsayyo.notification.command.dto.NotificationDTO; import org.omoknoone.onionhotsayyo.notification.command.repository.EmitterRepository; import org.omoknoone.onionhotsayyo.notification.command.repository.NotificationRepository; +import org.omoknoone.onionhotsayyo.post.command.aggregate.Post; +import org.omoknoone.onionhotsayyo.post.command.repository.PostRepository; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @@ -24,6 +30,8 @@ public class NotificationService { private final EmitterRepository emitterRepository; private final ModelMapper modelMapper; + + public NotificationService(MemberRepository memberRepository, NotificationRepository notificationRepository, EmitterRepository emitterRepository, ModelMapper modelMapper) { this.memberRepository = memberRepository; @@ -78,6 +86,8 @@ public void send(String receiverName, String content) { System.out.println("[send] receiverName = " + receiverName); Member receiver = memberRepository.findByMemberId(receiverName); System.out.println("receiver = " + receiver); + + // DB에 notification 추가 Notification notification = notificationRepository.save(createNotification(receiver, content)); System.out.println("notification = " + notification); @@ -121,8 +131,4 @@ public void checkNotification (Notification notification) { notification.setChecked(true); notificationRepository.save(notification); } - - - - } From 0f0208d2cfbb5e15d7b42ec39aac7bb6203049b6 Mon Sep 17 00:00:00 2001 From: orlzlL Date: Thu, 11 Apr 2024 19:31:43 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[refactor]=20=ED=8C=94=EB=A1=9C=EC=9A=B0=20?= =?UTF-8?q?=EC=8B=9C=20=EC=95=8C=EB=A6=BC=20=EB=B0=9C=EC=86=A1=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EC=BD=94=EB=93=9C=20=EA=B0=84?= =?UTF-8?q?=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 불필요한 코드 줄임 --- .../follow/command/service/FollowServiceImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java index 6fe62c3..6a31899 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java @@ -42,9 +42,7 @@ public void followMember(FollowDTO followDTO) { // 팔로우 당한 사람에게 팔로우 알림 전송 Member fromMember = memberRepository.findByMemberId(follow.getFromMemberId()); - String fromMemberNickName = fromMember.getNickname(); - String notifyMessage = fromMemberNickName + "님이 나를 팔로우 했습니다."; - notificationService.send(follow.getToMemberId(), notifyMessage); + notificationService.send(follow.getToMemberId(), fromMember.getNickname() + "님이 나를 팔로우 했습니다."); // } } From 8d130ff28ece8527b314f11aa0f62d61e2a71212 Mon Sep 17 00:00:00 2001 From: orlzlL Date: Fri, 12 Apr 2024 10:54:13 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[feat]=20=EB=8C=80=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EC=8B=9C=20=EC=95=8C=EB=A6=BC=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + 내가 작성한 댓글 및 대댓글 조회 시 commentService와 replyService 순환참조 발생하여 Repository로 수정함 --- .../command/service/CommentService.java | 2 + .../command/service/CommentServiceImpl.java | 32 +++++++++++++-- .../command/service/ReplyServiceImpl.java | 40 ++++++++++++++++++- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentService.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentService.java index 35c39d5..f92fa45 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentService.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentService.java @@ -10,4 +10,6 @@ public interface CommentService { void modifyComment(CommentDTO commentDetailDTO); void removeComment(int commentid); List viewCommentListByMe(String memberId); + + CommentDTO getCommentById(Integer commentId); } diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java index a2a9984..47064d6 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java @@ -3,6 +3,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.modelmapper.ModelMapper; import org.modelmapper.TypeToken; @@ -17,7 +18,9 @@ import org.omoknoone.onionhotsayyo.post.command.repository.PostRepository; import org.omoknoone.onionhotsayyo.post.command.service.PostService; import org.omoknoone.onionhotsayyo.post.command.vo.PostDetailVO; +import org.omoknoone.onionhotsayyo.reply.command.aggregate.Reply; import org.omoknoone.onionhotsayyo.reply.command.dto.ReplyDTO; +import org.omoknoone.onionhotsayyo.reply.command.repository.ReplyRepository; import org.omoknoone.onionhotsayyo.reply.command.service.ReplyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -27,7 +30,8 @@ public class CommentServiceImpl implements CommentService { private final ModelMapper modelMapper; private final CommentRepository commentRepository; - private final ReplyService replyService; + // private final ReplyService replyService; + private final ReplyRepository replyRepository; private final MemberService memberService; private final NotificationService notificationService; private final PostService postService; @@ -35,11 +39,16 @@ public class CommentServiceImpl implements CommentService { @Autowired - public CommentServiceImpl(ModelMapper modelMapper, CommentRepository commentRepository, ReplyService replyService, MemberService memberService, + public CommentServiceImpl(ModelMapper modelMapper, CommentRepository commentRepository, + ReplyRepository replyRepository, MemberService memberService, NotificationService notificationService, PostService postService, PostRepository postRepository) { this.modelMapper = modelMapper; this.commentRepository = commentRepository; - this.replyService = replyService; + this.replyRepository = replyRepository; + + /* 순환 참조 일어남 */ + // this.replyService = replyService; + this.memberService = memberService; this.notificationService = notificationService; this.postService = postService; @@ -85,6 +94,12 @@ public void removeComment(int commentId) { findcomment.setDeleted(true); } + public CommentDTO getCommentById(int commentId) { + Comment findcomment = commentRepository.findById(commentId) + .orElseThrow(() -> new RuntimeException("댓글을 찾을 수 없습니다.")); + return modelMapper.map(findcomment, CommentDTO.class); + } + @Override public List viewCommentListByMe(String memberId) { @@ -93,7 +108,10 @@ public List viewCommentListByMe(String memberId) { List commentList = commentRepository.findAllByMemberId(memberId); List commentDTOList = modelMapper.map(commentList, new TypeToken>() {}.getType()); - List replyDTOList = replyService.viewReplyListByMemberId(memberId); + // List replyDTOList = replyService.viewReplyListByMemberId(memberId); + List replyList = replyRepository.findAllByMemberId(memberId); + List replyDTOList = modelMapper.map(replyList, new TypeToken>() {}.getType()); + List commentReplyDTOList = new ArrayList<>(); for (CommentDTO commentDTO : commentDTOList) { @@ -120,4 +138,10 @@ public List viewCommentListByMe(String memberId) { return commentReplyDTOList; } + + @Override + public CommentDTO getCommentById(Integer commentId) { + Comment comment = commentRepository.findById(commentId).orElseThrow(IllegalArgumentException::new); + return modelMapper.map(comment, CommentDTO.class); + } } diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java index 74e2dbd..ab9e64b 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java @@ -7,6 +7,14 @@ import org.modelmapper.TypeToken; import org.modelmapper.convention.MatchingStrategies; import org.omoknoone.onionhotsayyo.comment.command.aggregate.Comment; +import org.omoknoone.onionhotsayyo.comment.command.dto.CommentDTO; +import org.omoknoone.onionhotsayyo.comment.command.service.CommentService; +import org.omoknoone.onionhotsayyo.comment.command.service.CommentServiceImpl; +import org.omoknoone.onionhotsayyo.member.dto.MemberDTO; +import org.omoknoone.onionhotsayyo.member.service.MemberService; +import org.omoknoone.onionhotsayyo.notification.command.service.NotificationService; +import org.omoknoone.onionhotsayyo.post.command.service.PostService; +import org.omoknoone.onionhotsayyo.post.command.vo.PostDetailVO; import org.omoknoone.onionhotsayyo.reply.command.aggregate.Reply; import org.omoknoone.onionhotsayyo.reply.command.dto.ReplyDTO; import org.omoknoone.onionhotsayyo.reply.command.repository.ReplyRepository; @@ -18,11 +26,22 @@ public class ReplyServiceImpl implements ReplyService{ private final ModelMapper modelMapper; private final ReplyRepository replyRepository; + private final NotificationService notificationService; + private final CommentService commentService; + private final MemberService memberService; + private final PostService postService; @Autowired - public ReplyServiceImpl(ModelMapper modelMapper, ReplyRepository replyRepository) { + public ReplyServiceImpl(ModelMapper modelMapper, ReplyRepository replyRepository, + NotificationService notificationService, CommentService commentService, MemberService memberService, + PostService postService) { this.modelMapper = modelMapper; this.replyRepository = replyRepository; + // this.commentService = commentService; + this.notificationService = notificationService; + this.commentService = commentService; + this.memberService = memberService; + this.postService = postService; } @Transactional @@ -31,6 +50,25 @@ public void createReply(ReplyDTO replyDTO) { modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); Reply reply = modelMapper.map(replyDTO, Reply.class); replyRepository.save(reply); + + /* 대댓글 작성 시 알림 (부모 댓글 작성자와 글쓰니에게) */ + + // 대댓글 작성자 닉네임 가져오기 위함 + MemberDTO replyAuthor = memberService.getMemberDetailsByMemberId(reply.getMemberId()); + + // 부모 댓글 작성자에게 알림 전송 + CommentDTO comment = commentService.getCommentById(reply.getCommentId()); + notificationService.send(comment.getMemberId(), + replyAuthor.getNickname() + "님이 대댓글을 남겼습니다: " + reply.getContent()); + + // 게시글 작성자에게 알림 전송 + PostDetailVO post = postService.viewPostById(comment.getPostId()); + + /* 댓글 작성자랑 글쓴이가 똑같은 경우 중복 발생 예외 처리 -> 댓쓴이와 글쓴이가 다를 경우에만 글쓴이에게 알림 발송*/ + if(!(comment.getMemberId().equals(post.getMemberId()))) { + notificationService.send(post.getMemberId(), + replyAuthor.getNickname() + "님이 대댓글을 남겼습니다: " + reply.getContent()); + } } @Transactional From fb7c1ac6ad21f8ca6ab5c445375961114d89dd08 Mon Sep 17 00:00:00 2001 From: orlzlL Date: Fri, 12 Apr 2024 15:00:26 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[feat]=20AOP=EB=A1=9C=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=20=EC=A0=84=EC=86=A1-=EB=8C=93=EA=B8=80=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존에 CommentService에서 전송하던 알림을 AOP로 분리함 추가사항: gradle에 aop 추가해야함 main문에 @EnableAspectJAutoProxy 추가해야함 --- .../command/service/CommentServiceImpl.java | 32 ++-------- .../command/service/NotificationAspect.java | 64 +++++++++++++++++++ 2 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java index 47064d6..d55ee7d 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/comment/command/service/CommentServiceImpl.java @@ -14,14 +14,9 @@ import org.omoknoone.onionhotsayyo.comment.command.repository.CommentRepository; import org.omoknoone.onionhotsayyo.member.dto.MemberDTO; import org.omoknoone.onionhotsayyo.member.service.MemberService; -import org.omoknoone.onionhotsayyo.notification.command.service.NotificationService; -import org.omoknoone.onionhotsayyo.post.command.repository.PostRepository; -import org.omoknoone.onionhotsayyo.post.command.service.PostService; -import org.omoknoone.onionhotsayyo.post.command.vo.PostDetailVO; import org.omoknoone.onionhotsayyo.reply.command.aggregate.Reply; import org.omoknoone.onionhotsayyo.reply.command.dto.ReplyDTO; import org.omoknoone.onionhotsayyo.reply.command.repository.ReplyRepository; -import org.omoknoone.onionhotsayyo.reply.command.service.ReplyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,31 +25,20 @@ public class CommentServiceImpl implements CommentService { private final ModelMapper modelMapper; private final CommentRepository commentRepository; - // private final ReplyService replyService; private final ReplyRepository replyRepository; private final MemberService memberService; - private final NotificationService notificationService; - private final PostService postService; - private final PostRepository postRepository; - @Autowired public CommentServiceImpl(ModelMapper modelMapper, CommentRepository commentRepository, - ReplyRepository replyRepository, MemberService memberService, - NotificationService notificationService, PostService postService, PostRepository postRepository) { + ReplyRepository replyRepository, + MemberService memberService) { this.modelMapper = modelMapper; this.commentRepository = commentRepository; this.replyRepository = replyRepository; - - /* 순환 참조 일어남 */ - // this.replyService = replyService; - - this.memberService = memberService; - this.notificationService = notificationService; - this.postService = postService; - this.postRepository = postRepository; + this.memberService = memberService; } + @Transactional @Override public void createComment(CommentDTO commentDTO) { @@ -62,14 +46,6 @@ public void createComment(CommentDTO commentDTO) { Comment comment = modelMapper.map(commentDTO, Comment.class); commentRepository.save(comment); - System.out.println("[comment] = " + comment); - - // 새 댓글 등록 시 알림 - // PostDetailVO post = postService.viewPostById(commentDTO.getPostId()); - PostDetailVO post = postService.viewPostById(comment.getPostId()); - MemberDTO postAuthor = memberService.getMemberDetailsByMemberId(post.getMemberId()); - MemberDTO commentAuthor = memberService.getMemberDetailsByMemberId(comment.getMemberId()); - notificationService.send(postAuthor.getMemberId(), commentAuthor.getNickname() + "님이 내 글에 댓글을 달았습니다: " + comment.getContent()); } @Transactional diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java new file mode 100644 index 0000000..eb7c9eb --- /dev/null +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java @@ -0,0 +1,64 @@ +package org.omoknoone.onionhotsayyo.notification.command.service; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.omoknoone.onionhotsayyo.comment.command.dto.CommentDTO; +import org.omoknoone.onionhotsayyo.member.dto.MemberDTO; +import org.omoknoone.onionhotsayyo.member.service.MemberService; +import org.omoknoone.onionhotsayyo.post.command.service.PostService; +import org.omoknoone.onionhotsayyo.post.command.vo.PostDetailVO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +@Aspect +@Component +public class NotificationAspect { + + Logger log = LoggerFactory.getLogger(this.getClass()); + + private final NotificationService notificationService; + private final PostService postService; + private final MemberService memberService; + + @Autowired + public NotificationAspect(NotificationService notificationService, PostService postService, + MemberService memberService) { + this.notificationService = notificationService; + this.postService = postService; + this.memberService = memberService; + } + + // 특정 서비스의 특정 메소드에만 적용되도록 설정 + @Pointcut("execution(* org.omoknoone.onionhotsayyo.comment.command.service.CommentService.createComment(..)) && args(commentDTO)") + private void commentServiceCreateComment(CommentDTO commentDTO) {} + + // 이 곳에 원하는 어드바이스 로직 작성 + @After("commentServiceCreateComment(commentDTO)") + public void afterCreateComment(JoinPoint joinPoint, CommentDTO commentDTO) { + + PostDetailVO post = postService.viewPostById(commentDTO.getPostId()); + MemberDTO postAuthor = memberService.getMemberDetailsByMemberId(post.getMemberId()); + MemberDTO commentAuthor = memberService.getMemberDetailsByMemberId(commentDTO.getMemberId()); + notificationService.send(postAuthor.getMemberId(), + commentAuthor.getNickname() + "님이 내 글에 댓글을 달았습니다: " + commentDTO.getContent()); + + System.out.println("[After CreateComment]: " + joinPoint.getSignature()); + System.out.println("새 댓글 알림 전송 됨"); + + } + + + + + + + + +} From cb5f39c5b7cf3ebccc970f2fccb5acf167ba718a Mon Sep 17 00:00:00 2001 From: orlzlL Date: Fri, 12 Apr 2024 15:22:08 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[feat]=20AOP=20=EB=8C=80=EB=8C=93=EA=B8=80?= =?UTF-8?q?=20=EC=95=8C=EB=A6=BC,=20=ED=8C=94=EB=A1=9C=EC=9A=B0=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/service/FollowServiceImpl.java | 4 -- .../command/service/NotificationAspect.java | 60 ++++++++++++++++++- .../command/service/ReplyServiceImpl.java | 32 +--------- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java index 6a31899..ca39cec 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/follow/command/service/FollowServiceImpl.java @@ -39,10 +39,6 @@ public void followMember(FollowDTO followDTO) { modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); Follow follow = modelMapper.map(followDTO, Follow.class); followRepository.save(follow); - - // 팔로우 당한 사람에게 팔로우 알림 전송 - Member fromMember = memberRepository.findByMemberId(follow.getFromMemberId()); - notificationService.send(follow.getToMemberId(), fromMember.getNickname() + "님이 나를 팔로우 했습니다."); // } } diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java index eb7c9eb..32641a2 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java @@ -2,15 +2,17 @@ import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; -import org.aspectj.lang.annotation.AfterReturning; -import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.omoknoone.onionhotsayyo.comment.command.dto.CommentDTO; +import org.omoknoone.onionhotsayyo.comment.command.service.CommentService; +import org.omoknoone.onionhotsayyo.follow.command.dto.FollowDTO; +import org.omoknoone.onionhotsayyo.member.aggregate.Member; import org.omoknoone.onionhotsayyo.member.dto.MemberDTO; import org.omoknoone.onionhotsayyo.member.service.MemberService; import org.omoknoone.onionhotsayyo.post.command.service.PostService; import org.omoknoone.onionhotsayyo.post.command.vo.PostDetailVO; +import org.omoknoone.onionhotsayyo.reply.command.dto.ReplyDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -25,35 +27,89 @@ public class NotificationAspect { private final NotificationService notificationService; private final PostService postService; + private final CommentService commentService; private final MemberService memberService; @Autowired public NotificationAspect(NotificationService notificationService, PostService postService, + CommentService commentService, MemberService memberService) { this.notificationService = notificationService; this.postService = postService; + this.commentService = commentService; this.memberService = memberService; } // 특정 서비스의 특정 메소드에만 적용되도록 설정 + // 댓글 알림 @Pointcut("execution(* org.omoknoone.onionhotsayyo.comment.command.service.CommentService.createComment(..)) && args(commentDTO)") private void commentServiceCreateComment(CommentDTO commentDTO) {} + // 대댓글 알림 + @Pointcut("execution(* org.omoknoone.onionhotsayyo.reply.command.service.ReplyService.createReply(..)) && args(replyDTO)") + private void replyServiceCreateReply(ReplyDTO replyDTO) {} + + // 팔로우 알림 + @Pointcut("execution(* org.omoknoone.onionhotsayyo.follow.command.service.FollowService.followMember(..)) && args(followDTO)") + private void followServiceFollowMember(FollowDTO followDTO) {} + + + + + // 이 곳에 원하는 어드바이스 로직 작성 + // 댓글 알림 @After("commentServiceCreateComment(commentDTO)") public void afterCreateComment(JoinPoint joinPoint, CommentDTO commentDTO) { PostDetailVO post = postService.viewPostById(commentDTO.getPostId()); MemberDTO postAuthor = memberService.getMemberDetailsByMemberId(post.getMemberId()); MemberDTO commentAuthor = memberService.getMemberDetailsByMemberId(commentDTO.getMemberId()); + notificationService.send(postAuthor.getMemberId(), commentAuthor.getNickname() + "님이 내 글에 댓글을 달았습니다: " + commentDTO.getContent()); System.out.println("[After CreateComment]: " + joinPoint.getSignature()); System.out.println("새 댓글 알림 전송 됨"); + } + + // 대댓글 알림 (부모 댓쓰니랑 글쓰니에게) + @After("replyServiceCreateReply(replyDTO)") + public void afterCreateReply(JoinPoint joinPoint, ReplyDTO replyDTO) { + // 대댓글 작성자 닉네임 가져오기 + MemberDTO replyAuthor = memberService.getMemberDetailsByMemberId(replyDTO.getMemberId()); + + // 부모 댓글 작성자에게 알림 전송 + CommentDTO comment = commentService.getCommentById(replyDTO.getCommentId()); + notificationService.send(comment.getMemberId(), + replyAuthor.getNickname() + "님이 대댓글을 남겼습니다: " + replyDTO.getContent()); + + // 게시글 작성자에게 알림 전송 + PostDetailVO post = postService.viewPostById(comment.getPostId()); + + /* 댓글 작성자랑 글쓴이가 똑같은 경우 중복 발생 예외 처리 -> 댓쓴이와 글쓴이가 다를 경우에만 글쓴이에게 알림 발송*/ + if(!(comment.getMemberId().equals(post.getMemberId()))) { + notificationService.send(post.getMemberId(), + replyAuthor.getNickname() + "님이 대댓글을 남겼습니다: " + replyDTO.getContent()); + } + + System.out.println("[After CreateReply]: " + joinPoint.getSignature()); + System.out.println("새 대댓글 알림 전송 됨"); } + // 팔로우 알림 + @After("followServiceFollowMember(followDTO)") + public void afterFollowMember(FollowDTO followDTO) { + + MemberDTO fromMember = memberService.getMemberDetailsByMemberId(followDTO.getFromMemberId()); + notificationService.send(followDTO.getToMemberId(), fromMember.getNickname() + "님이 나를 팔로우 했습니다."); + + System.out.println("새 팔로우 알림 전송 됨"); + + } + + diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java index ab9e64b..908f3a7 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/reply/command/service/ReplyServiceImpl.java @@ -26,22 +26,11 @@ public class ReplyServiceImpl implements ReplyService{ private final ModelMapper modelMapper; private final ReplyRepository replyRepository; - private final NotificationService notificationService; - private final CommentService commentService; - private final MemberService memberService; - private final PostService postService; @Autowired - public ReplyServiceImpl(ModelMapper modelMapper, ReplyRepository replyRepository, - NotificationService notificationService, CommentService commentService, MemberService memberService, - PostService postService) { + public ReplyServiceImpl(ModelMapper modelMapper, ReplyRepository replyRepository) { this.modelMapper = modelMapper; this.replyRepository = replyRepository; - // this.commentService = commentService; - this.notificationService = notificationService; - this.commentService = commentService; - this.memberService = memberService; - this.postService = postService; } @Transactional @@ -50,25 +39,6 @@ public void createReply(ReplyDTO replyDTO) { modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); Reply reply = modelMapper.map(replyDTO, Reply.class); replyRepository.save(reply); - - /* 대댓글 작성 시 알림 (부모 댓글 작성자와 글쓰니에게) */ - - // 대댓글 작성자 닉네임 가져오기 위함 - MemberDTO replyAuthor = memberService.getMemberDetailsByMemberId(reply.getMemberId()); - - // 부모 댓글 작성자에게 알림 전송 - CommentDTO comment = commentService.getCommentById(reply.getCommentId()); - notificationService.send(comment.getMemberId(), - replyAuthor.getNickname() + "님이 대댓글을 남겼습니다: " + reply.getContent()); - - // 게시글 작성자에게 알림 전송 - PostDetailVO post = postService.viewPostById(comment.getPostId()); - - /* 댓글 작성자랑 글쓴이가 똑같은 경우 중복 발생 예외 처리 -> 댓쓴이와 글쓴이가 다를 경우에만 글쓴이에게 알림 발송*/ - if(!(comment.getMemberId().equals(post.getMemberId()))) { - notificationService.send(post.getMemberId(), - replyAuthor.getNickname() + "님이 대댓글을 남겼습니다: " + reply.getContent()); - } } @Transactional From 3c46e5cba7be1a528895a593bd4c70194130983a Mon Sep 17 00:00:00 2001 From: orlzlL Date: Fri, 12 Apr 2024 16:13:57 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[feat]=20=EC=AA=BD=EC=A7=80=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 쪽지 발송, 쪽지 수신 확인(읽음 상태로 변경), 내가 보낸 쪽지 조회, 내가 받은 쪽지 조회, 안 읽은 쪽지 조회 구현 및 postman test 완료 --- .../letter/command/aggregate/Letter.java | 115 ++++++++++++++++++ .../command/controller/LetterController.java | 85 +++++++++++++ .../letter/command/dto/LetterDTO.java | 86 +++++++++++++ .../command/repository/LetterRepository.java | 21 ++++ .../letter/command/service/LetterService.java | 17 +++ .../command/service/LetterServiceImpl.java | 97 +++++++++++++++ 6 files changed, 421 insertions(+) create mode 100644 OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/aggregate/Letter.java create mode 100644 OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/controller/LetterController.java create mode 100644 OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/dto/LetterDTO.java create mode 100644 OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/repository/LetterRepository.java create mode 100644 OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterService.java create mode 100644 OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterServiceImpl.java diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/aggregate/Letter.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/aggregate/Letter.java new file mode 100644 index 0000000..cba388a --- /dev/null +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/aggregate/Letter.java @@ -0,0 +1,115 @@ +package org.omoknoone.onionhotsayyo.letter.command.aggregate; + +import java.time.LocalDateTime; + +import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.CreationTimestamp; +import org.omoknoone.onionhotsayyo.member.aggregate.Member; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.Table; + +@Entity +@Table(name = "letter") +public class Letter { + + @Id + @Column(name = "letter_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int letterId; + + @Column(name = "message") + private String message; + + @Column(name = "event_time") + @CreationTimestamp + private LocalDateTime eventTime; + + @Column(name = "is_checked") + @ColumnDefault("false") + private boolean isChecked; + + @JoinColumn(name = "send_id") + private String sendId; + + @JoinColumn(name = "receive_id") + private String receiveId; + + public Letter() { + } + + public Letter(int letterId, String message, LocalDateTime eventTime, boolean isChecked, String sendId, + String receiveId) { + this.letterId = letterId; + this.message = message; + this.eventTime = eventTime; + this.isChecked = isChecked; + this.sendId = sendId; + this.receiveId = receiveId; + } + + public int getLetterId() { + return letterId; + } + + public void setLetterId(int letterId) { + this.letterId = letterId; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public LocalDateTime getEventTime() { + return eventTime; + } + + public void setEventTime(LocalDateTime eventTime) { + this.eventTime = eventTime; + } + + public boolean isChecked() { + return isChecked; + } + + public void setChecked(boolean checked) { + isChecked = checked; + } + + public String getSendId() { + return sendId; + } + + public void setSendId(String sendId) { + this.sendId = sendId; + } + + public String getReceiveId() { + return receiveId; + } + + public void setReceiveId(String receiveId) { + this.receiveId = receiveId; + } + + @Override + public String toString() { + return "Letter{" + + "letterId=" + letterId + + ", message='" + message + '\'' + + ", eventTime=" + eventTime + + ", isChecked=" + isChecked + + ", sendId='" + sendId + '\'' + + ", receiveId='" + receiveId + '\'' + + '}'; + } +} diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/controller/LetterController.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/controller/LetterController.java new file mode 100644 index 0000000..9370059 --- /dev/null +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/controller/LetterController.java @@ -0,0 +1,85 @@ +package org.omoknoone.onionhotsayyo.letter.command.controller; + +import java.util.List; + +import org.modelmapper.ModelMapper; +import org.omoknoone.onionhotsayyo.letter.command.dto.LetterDTO; +import org.omoknoone.onionhotsayyo.letter.command.service.LetterService; +import org.omoknoone.onionhotsayyo.notification.command.service.NotificationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/letters") +public class LetterController { + private final LetterService letterService; + private final NotificationService notificationService; + private final ModelMapper modelMapper; + + @Autowired + public LetterController(LetterService letterService, NotificationService notificationService, + ModelMapper modelMapper) { + this.letterService = letterService; + this.notificationService = notificationService; + this.modelMapper = modelMapper; + } + + // 쪽지 발송 + @PostMapping("/send") + public ResponseEntity sendLetter(@RequestBody LetterDTO letterDTO) { + LetterDTO sendLetter = letterService.sendLetter(letterDTO); + return ResponseEntity.status(HttpStatus.CREATED).body(sendLetter); + } + + // 쪽지 수신 확인 + @PutMapping("/check/{letterId}") + public ResponseEntity checkLetter(@PathVariable(name = "letterId") int letterId) { + LetterDTO readLetter = letterService.checkLetter(letterId); + return ResponseEntity.status(HttpStatus.OK).body(readLetter); + } + + + // // 송수신 쪽지 모두 확인 + // @GetMapping("/list/myletter/{memberId}") + // public ResponseEntity> viewLetterByMe(@PathVariable(name = "memberId") String memberId) { + // List letterList = letterService.viewLetterByMe(memberId); + // return ResponseEntity.status(HttpStatus.OK).body(letterList); + // } + + // 내가 보낸 쪽지 + @GetMapping("/mysendletter/{memberId}") + public ResponseEntity> viewSendLetter(@PathVariable(name = "memberId") String memberId) { + List sendLetterList = letterService.viewSendLetter(memberId); + return ResponseEntity.status(HttpStatus.OK).body(sendLetterList); + } + + // 내가 받은 쪽지 + @GetMapping("/myreceiveletter/{memberId}") + public ResponseEntity> viewReceiveLetter(@PathVariable(name = "memberId") String memberId) { + List receiveLetter = letterService.viewReceiveLetter(memberId); + return ResponseEntity.status(HttpStatus.OK).body(receiveLetter); + } + + // 안 읽은 상태의 쪽지 조회 + @GetMapping("/unreadletter/{memberId}") + public ResponseEntity> viewUnreadLetter(@PathVariable(name = "memberId") String memberId) { + List unreadletter = letterService.viewUnreadLetter(memberId); + return ResponseEntity.status(HttpStatus.OK).body(unreadletter); + } + + + + + @GetMapping("/health_check") + public String healthCheck() { + return "Good"; + } +} diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/dto/LetterDTO.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/dto/LetterDTO.java new file mode 100644 index 0000000..da80c0a --- /dev/null +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/dto/LetterDTO.java @@ -0,0 +1,86 @@ +package org.omoknoone.onionhotsayyo.letter.command.dto; + +import java.time.LocalDateTime; + + +public class LetterDTO { + private int letterId; + private String sendId; + private String receiveId; + private String message; + private LocalDateTime eventTime; + private boolean isChecked; + + public LetterDTO() { + } + + public LetterDTO(int letterId, String sendId, String receiveId, String message, LocalDateTime eventTime, + boolean isChecked) { + this.letterId = letterId; + this.sendId = sendId; + this.receiveId = receiveId; + this.message = message; + this.eventTime = eventTime; + this.isChecked = isChecked; + } + + public int getLetterId() { + return letterId; + } + + public void setLetterId(int letterId) { + this.letterId = letterId; + } + + public String getSendId() { + return sendId; + } + + public void setSendId(String sendId) { + this.sendId = sendId; + } + + public String getReceiveId() { + return receiveId; + } + + public void setReceiveId(String receiveId) { + this.receiveId = receiveId; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public LocalDateTime getEventTime() { + return eventTime; + } + + public void setEventTime(LocalDateTime eventTime) { + this.eventTime = eventTime; + } + + public boolean isChecked() { + return isChecked; + } + + public void setChecked(boolean checked) { + isChecked = checked; + } + + @Override + public String toString() { + return "LetterDTO{" + + "letterId=" + letterId + + ", sendId='" + sendId + '\'' + + ", receiveId='" + receiveId + '\'' + + ", message='" + message + '\'' + + ", eventTime=" + eventTime + + ", isChecked=" + isChecked + + '}'; + } +} diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/repository/LetterRepository.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/repository/LetterRepository.java new file mode 100644 index 0000000..0d50e9e --- /dev/null +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/repository/LetterRepository.java @@ -0,0 +1,21 @@ +package org.omoknoone.onionhotsayyo.letter.command.repository; + +import java.util.List; + +import org.omoknoone.onionhotsayyo.letter.command.aggregate.Letter; +import org.omoknoone.onionhotsayyo.member.aggregate.Member; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface LetterRepository extends JpaRepository { + + Long countByReceiveIdAndIsChecked(String memberId, boolean isChecked); + List findAllByReceiveIdOrderByEventTimeDesc(Member receiver); + + List findBySendId(String memberId); + + List findByReceiveId(String memberId); + + List findByReceiveIdAndIsChecked(String memberId, boolean isChecked); + +} diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterService.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterService.java new file mode 100644 index 0000000..ef9b98f --- /dev/null +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterService.java @@ -0,0 +1,17 @@ +package org.omoknoone.onionhotsayyo.letter.command.service; + +import java.util.List; + +import org.omoknoone.onionhotsayyo.letter.command.dto.LetterDTO; + +public interface LetterService { + LetterDTO sendLetter(LetterDTO letterDTO); + + LetterDTO checkLetter(int letterId); + + List viewSendLetter(String memberId); + + List viewReceiveLetter(String memberId); + + List viewUnreadLetter(String memberId); +} diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterServiceImpl.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterServiceImpl.java new file mode 100644 index 0000000..a481406 --- /dev/null +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/letter/command/service/LetterServiceImpl.java @@ -0,0 +1,97 @@ +package org.omoknoone.onionhotsayyo.letter.command.service; + +import static java.time.LocalTime.*; + +import java.util.List; +import java.util.stream.Collectors; + +import org.modelmapper.ModelMapper; +import org.omoknoone.onionhotsayyo.letter.command.aggregate.Letter; +import org.omoknoone.onionhotsayyo.letter.command.dto.LetterDTO; +import org.omoknoone.onionhotsayyo.letter.command.repository.LetterRepository; +import org.omoknoone.onionhotsayyo.member.aggregate.Member; +import org.omoknoone.onionhotsayyo.member.dto.MemberDTO; +import org.omoknoone.onionhotsayyo.member.repository.MemberRepository; +import org.omoknoone.onionhotsayyo.member.service.MemberService; +import org.omoknoone.onionhotsayyo.notification.command.aggregate.Notification; +import org.omoknoone.onionhotsayyo.notification.command.repository.NotificationRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +public class LetterServiceImpl implements LetterService { + private final LetterRepository letterRepository; + private final MemberService memberService; + private final ModelMapper modelMapper; + + public LetterServiceImpl(LetterRepository letterRepository, MemberService memberService, ModelMapper modelMapper) { + this.letterRepository = letterRepository; + this.memberService = memberService; + this.modelMapper = modelMapper; + } + + @Override + public LetterDTO sendLetter(LetterDTO letterDTO) { + + Letter sendLetter = modelMapper.map(letterDTO, Letter.class); + letterRepository.save(sendLetter); + + return modelMapper.map(sendLetter, LetterDTO.class); + + } + + @Override + public LetterDTO checkLetter(int letterId) { + Letter checkLetter = letterRepository.findById(letterId) + .orElseThrow(() -> new IllegalArgumentException("쪽지를 찾을 수 없습니다.")); + + checkLetter.setChecked(true); + letterRepository.save(checkLetter); + + return modelMapper.map(checkLetter, LetterDTO.class); + } + + + @Override + public List viewSendLetter(String memberId) { + MemberDTO sender = memberService.getMemberDetailsByMemberId(memberId); + if(sender == null) { + throw new UsernameNotFoundException("맴버 ID " + memberId + " 를 찾을 수 없습니다."); + } + + List letters = letterRepository.findBySendId(memberId); + return letters.stream() + .map(letter -> modelMapper.map(letter, LetterDTO.class)) + .collect(Collectors.toList()); + } + + @Override + public List viewReceiveLetter(String memberId) { + + /* 여기서부터 */ + MemberDTO receiver = memberService.getMemberDetailsByMemberId(memberId); + if(receiver == null) { + throw new UsernameNotFoundException("맴버 ID " + memberId + " 를 찾을 수 없습니다."); + } + /* 여기까지 부분 추후에 메소드로 분리해서 사용하면 좋을 것 같아요 */ + + List letters = letterRepository.findByReceiveId(memberId); + return letters.stream() + .map(letter -> modelMapper.map(letter, LetterDTO.class)) + .collect(Collectors.toList()); + } + + @Override + public List viewUnreadLetter(String memberId) { + + List letters = letterRepository.findByReceiveIdAndIsChecked(memberId, false); + return letters.stream() + .map(letter -> modelMapper.map(letter, LetterDTO.class)) + .collect(Collectors.toList()); + } + + private LetterDTO entityToDto(Letter letter) { + return modelMapper.map(letter, LetterDTO.class); + } +} From 40a03996c9d65fe5ad6d2be88d5934d6319fbd01 Mon Sep 17 00:00:00 2001 From: orlzlL Date: Fri, 12 Apr 2024 16:19:08 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[feat]=20=EC=AA=BD=EC=A7=80=20=EB=B0=9C?= =?UTF-8?q?=EC=86=A1=20=EC=8B=9C=20=EC=95=8C=EB=A6=BC=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20(AOP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 쪽지가 발송될 때 받는 사람에게 알림 전송됨 --- .../command/service/NotificationAspect.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java index 32641a2..ceb4c93 100644 --- a/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java +++ b/OnionHotSayYo/src/main/java/org/omoknoone/onionhotsayyo/notification/command/service/NotificationAspect.java @@ -7,6 +7,7 @@ import org.omoknoone.onionhotsayyo.comment.command.dto.CommentDTO; import org.omoknoone.onionhotsayyo.comment.command.service.CommentService; import org.omoknoone.onionhotsayyo.follow.command.dto.FollowDTO; +import org.omoknoone.onionhotsayyo.letter.command.dto.LetterDTO; import org.omoknoone.onionhotsayyo.member.aggregate.Member; import org.omoknoone.onionhotsayyo.member.dto.MemberDTO; import org.omoknoone.onionhotsayyo.member.service.MemberService; @@ -53,6 +54,9 @@ private void replyServiceCreateReply(ReplyDTO replyDTO) {} @Pointcut("execution(* org.omoknoone.onionhotsayyo.follow.command.service.FollowService.followMember(..)) && args(followDTO)") private void followServiceFollowMember(FollowDTO followDTO) {} + // 쪽지 알림 + @Pointcut("execution(* org.omoknoone.onionhotsayyo.letter.command.service.LetterService.sendLetter(..)) && args(letterDTO)") + private void letterServiceSendLetter(LetterDTO letterDTO) {} @@ -101,7 +105,7 @@ public void afterCreateReply(JoinPoint joinPoint, ReplyDTO replyDTO) { // 팔로우 알림 @After("followServiceFollowMember(followDTO)") public void afterFollowMember(FollowDTO followDTO) { - + MemberDTO fromMember = memberService.getMemberDetailsByMemberId(followDTO.getFromMemberId()); notificationService.send(followDTO.getToMemberId(), fromMember.getNickname() + "님이 나를 팔로우 했습니다."); @@ -109,7 +113,15 @@ public void afterFollowMember(FollowDTO followDTO) { } + // 쪽지 알림 + @After("letterServiceSendLetter(letterDTO)") + public void afterSendLetter(LetterDTO letterDTO) { + + MemberDTO sender = memberService.getMemberDetailsByMemberId(letterDTO.getSendId()); + notificationService.send(letterDTO.getReceiveId(), sender.getNickname() + "님에게서 새로운 쪽지가 도착했습니다."); + System.out.println("새 쪽지 알림 전송 됨"); + }