Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Feat: 알림 조회 문구의 구체화 및 읽음 처리 기능 #85

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import treehouse.server.api.comment.presentation.dto.CommentRequestDTO;
import treehouse.server.api.comment.presentation.dto.CommentResponseDTO;
import treehouse.server.api.member.implementation.MemberQueryAdapter;
import treehouse.server.api.notification.business.NotificationService;
import treehouse.server.api.notification.presentation.dto.NotificationRequestDTO;
import treehouse.server.api.post.implement.PostQueryAdapter;
import treehouse.server.api.reaction.business.ReactionMapper;
import treehouse.server.api.reaction.implementation.ReactionCommandAdapter;
Expand All @@ -28,6 +30,7 @@
import treehouse.server.global.entity.comment.Comment;
import treehouse.server.global.entity.comment.CommentType;
import treehouse.server.global.entity.member.Member;
import treehouse.server.global.entity.notification.NotificationType;
import treehouse.server.global.entity.post.Post;
import treehouse.server.global.entity.reaction.Reaction;
import treehouse.server.global.entity.report.Report;
Expand Down Expand Up @@ -63,6 +66,8 @@ public class CommentService {

private final BranchQueryAdapter branchQueryAdapter;

private final NotificationService notificationService;


public void reportComment(User user, CommentRequestDTO.reportComment request, Long treehouseId, Long postId, Long commentId){

Expand Down Expand Up @@ -161,6 +166,14 @@ public CommentResponseDTO.CommentIdResponseDto createComment(User user, Long tre

Comment comment = CommentMapper.toComment(writer, post, request.getContext(), CommentType.PARENT, -1L);
Long commentId = commentCommandAdapter.createComment(comment).getId();

//알림 생성
NotificationRequestDTO.createNotification notificationRequest = new NotificationRequestDTO.createNotification();
notificationRequest.setReceiverId(post.getWriter().getId()); // 여기서 receiver 설정 (예시)
notificationRequest.setTargetId(post.getId());
notificationRequest.setType(NotificationType.COMMENT); // 알림 타입 설정 (예시)
notificationService.createNotification(user, treehouseId, notificationRequest, null);

return CommentMapper.toIdResponseDto(commentId);
}

Expand All @@ -175,6 +188,13 @@ public CommentResponseDTO.CommentIdResponseDto createReply(User user, Long treeh

Comment comment = CommentMapper.toComment(writer, post, request.getContext(), CommentType.CHILD, parentId);
Long replyId = commentCommandAdapter.createComment(comment).getId();
//알림 생성
NotificationRequestDTO.createNotification notificationRequest = new NotificationRequestDTO.createNotification();
notificationRequest.setReceiverId(comment.getWriter().getId()); // 여기서 receiver 설정 (예시)
notificationRequest.setTargetId(comment.getId());
notificationRequest.setType(NotificationType.REPLY); // 알림 타입 설정 (예시)
notificationService.createNotification(user, treehouseId, notificationRequest, null);

return CommentMapper.toIdResponseDto(replyId);
}

Expand Down Expand Up @@ -208,6 +228,13 @@ public String reactToComment(User user, Long treehouseId, Long commentId, Commen

member.addReaction(savedReaction);

//알림 생성
NotificationRequestDTO.createNotification notificationRequest = new NotificationRequestDTO.createNotification();
notificationRequest.setReceiverId(comment.getWriter().getId()); // 여기서 receiver 설정 (예시)
notificationRequest.setTargetId(comment.getId());
notificationRequest.setType(NotificationType.COMMENT_REACTION); // 알림 타입 설정 (예시)
notificationService.createNotification(user, treehouseId, notificationRequest, savedReaction.getReactionName());

return request.getReactionName() + " is saved";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
import treehouse.server.api.invitation.presentation.dto.InvitationRequestDTO;
import treehouse.server.api.invitation.presentation.dto.InvitationResponseDTO;
import treehouse.server.api.member.implementation.MemberQueryAdapter;
import treehouse.server.api.notification.business.NotificationService;
import treehouse.server.api.notification.presentation.dto.NotificationRequestDTO;
import treehouse.server.api.treehouse.implementation.TreehouseQueryAdapter;
import treehouse.server.api.user.implement.UserQueryAdapter;
import treehouse.server.global.entity.Invitation.Invitation;
import treehouse.server.global.entity.User.User;
import treehouse.server.global.entity.member.Member;
import treehouse.server.global.entity.notification.NotificationType;
import treehouse.server.global.entity.treeHouse.TreeHouse;
import treehouse.server.global.exception.GlobalErrorCode;
import treehouse.server.global.exception.ThrowClass.InvitationException;
Expand All @@ -38,6 +41,8 @@ public class InvitationService {

private final UserQueryAdapter userQueryAdapter;

private final NotificationService notificationService;

private static final Integer treeMemberRandomProfileSize = 3;


Expand Down Expand Up @@ -84,6 +89,13 @@ public InvitationResponseDTO.createInvitation createInvitation(User user, Invita

Invitation invitation = invitationCommandAdapter.saveInvitation(InvitationMapper.toInvitation(request.getPhoneNumber(), sender, receiverUser, treehouse));

//알림 생성
NotificationRequestDTO.createNotification notificationRequest = new NotificationRequestDTO.createNotification();
notificationRequest.setReceiverId(receiverUser.getId()); // 여기서 receiver 설정 (예시)
notificationRequest.setTargetId(invitation.getId());
notificationRequest.setType(NotificationType.INVITATION); // 알림 타입 설정 (예시)
notificationService.createNotification(user, invitation.getTreeHouse().getId(), notificationRequest, null);

// 리턴하기

return InvitationMapper.toCreateInvitationDTO(invitation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,41 @@

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import treehouse.server.api.notification.presentation.dto.NotificationRequestDTO;
import treehouse.server.api.notification.presentation.dto.NotificationResponseDTO;
import treehouse.server.global.common.util.TimeFormatter;
import treehouse.server.global.entity.User.User;
import treehouse.server.global.entity.member.Member;
import treehouse.server.global.entity.notification.Notification;
import treehouse.server.global.entity.notification.NotificationType;

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

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class NotificationMapper {

public static Notification toNotification(Member sender, Member receiver, NotificationRequestDTO.createNotification request, String reactionName) {

return Notification.builder()
.sender(sender)
.receiver(receiver)
.type(request.getType())
.targetId(request.getTargetId())
.title(NotificationUtil.getTitle(request.getType()))
.body(NotificationUtil.getBody(request.getType(), sender, request.getTargetId(), reactionName))
.receivedTime(LocalDateTime.now())
.build();
}

public static NotificationResponseDTO.getNotification toGetNotification(Notification notification, User user) {
return NotificationResponseDTO.getNotification.builder()
.type(notification.getType())
.profileImageUrl(notification.getSender().getProfileImageUrl())
.userName(notification.getSender().getName())
.receivedTime(String.valueOf(notification.getReceivedTime()))
.title(notification.getTitle())
.body(notification.getBody())
.receivedTime(TimeFormatter.format(notification.getReceivedTime()))
.treehouseId(notification.getSender().getTreeHouse().getId())
.treehouseName(notification.getSender().getTreeHouse().getName())
.isChecked(notification.isChecked())
Expand All @@ -29,4 +49,10 @@ public static NotificationResponseDTO.getNotifications toGetNotifications(List<N
.notifications(notificationDtos)
.build();
}

public static NotificationResponseDTO.readNotification toReadNotification(Notification notification) {
return NotificationResponseDTO.readNotification.builder()
.notificationId(notification.getId())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import treehouse.server.api.member.implementation.MemberQueryAdapter;
import treehouse.server.api.notification.implement.NotificationCommandAdapter;
import treehouse.server.api.notification.implement.NotificationQueryAdapter;
import treehouse.server.api.notification.presentation.dto.NotificationRequestDTO;
import treehouse.server.api.notification.presentation.dto.NotificationResponseDTO;
import treehouse.server.api.treehouse.implementation.TreehouseQueryAdapter;
import treehouse.server.global.entity.User.User;
import treehouse.server.global.entity.member.Member;
import treehouse.server.global.entity.notification.Notification;
import treehouse.server.global.entity.treeHouse.TreeHouse;

import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -18,8 +23,29 @@
@Slf4j
public class NotificationService {

private final NotificationCommandAdapter notificationCommandAdapter;
private final NotificationQueryAdapter notificationQueryAdapter;

private final MemberQueryAdapter memberQueryAdapter;

private final TreehouseQueryAdapter treehouseQueryAdapter;

/**
* 알림 생성하는 로직
* @param user
* @return
*/

@Transactional
public void createNotification(User user, Long treehouseId, NotificationRequestDTO.createNotification request, String reactionName) {
TreeHouse treeHouse = treehouseQueryAdapter.getTreehouseById(treehouseId);
Member sender = memberQueryAdapter.findByUserAndTreehouse(user, treeHouse);
Member receiver = memberQueryAdapter.findById(request.getReceiverId());

Notification notification = NotificationMapper.toNotification(sender, receiver, request, reactionName);
notificationCommandAdapter.createNotification(notification);
}

/**
* 사용자의 알림을 조회하는 로직
* @param user
Expand All @@ -40,4 +66,16 @@ public NotificationResponseDTO.getNotifications getNotifications(User user){ //@
.collect(Collectors.toList());
return NotificationMapper.toGetNotifications(notificationDtos);
}

/**
* 사용자의 알림을 읽음 처리하는 로직
* @param user
* @return
*/
@Transactional
public NotificationResponseDTO.readNotification readNotification(User user, Long notificationId){
Notification notification = notificationQueryAdapter.findById(notificationId);
notificationCommandAdapter.readNotification(notification);
return NotificationMapper.toReadNotification(notification);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package treehouse.server.api.notification.business;

import org.apache.commons.lang3.function.TriFunction;
import treehouse.server.global.entity.member.Member;
import treehouse.server.global.entity.notification.NotificationType;

import java.util.EnumMap;
import java.util.Map;

public class NotificationUtil {

private static final Map<NotificationType, String> titleMap = new EnumMap<>(NotificationType.class);
private static final Map<NotificationType, TriFunction<Member, Long, String, String>> bodyMap = new EnumMap<>(NotificationType.class);

static {
titleMap.put(NotificationType.COMMENT, "댓글 알림");
titleMap.put(NotificationType.REPLY, "대댓글 알림");
titleMap.put(NotificationType.INVITATION, "초대 알림");
titleMap.put(NotificationType.POST_REACTION, "게시글 반응 알림");
titleMap.put(NotificationType.COMMENT_REACTION, "댓글 반응 알림");

bodyMap.put(NotificationType.COMMENT, (sender, targetId, reactionName) -> sender.getName() + " 님이 댓글을 남겼습니다.");
bodyMap.put(NotificationType.REPLY, (sender, targetId, reactionName) -> sender.getName() + " 님이 답글을 남겼습니다.");
bodyMap.put(NotificationType.INVITATION, (sender, targetId, reactionName) -> sender.getName() + " 님이 트리하우스에 초대했습니다.");
bodyMap.put(NotificationType.POST_REACTION, (sender, targetId, reactionName) -> sender.getName() + " 님이 게시글에 " + reactionName + "을(를) 눌렀습니다.");
bodyMap.put(NotificationType.COMMENT_REACTION, (sender, targetId, reactionName) -> sender.getName() + " 님이 댓글에 " + reactionName + "을(를) 눌렀습니다.");
}

public static String getTitle(NotificationType type) {
return titleMap.getOrDefault(type, "Notification");
}

public static String getBody(NotificationType type, Member sender, Long targetId, String reactionName) {
return bodyMap.getOrDefault(type, (s, t, r) -> "알림이 있습니다.").apply(sender, targetId, reactionName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,23 @@

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import treehouse.server.api.notification.persistence.NotificationRepository;
import treehouse.server.global.annotations.Adapter;
import treehouse.server.global.entity.notification.Notification;

@Adapter
@RequiredArgsConstructor
@Slf4j
public class NotificationCommandAdapter {

private final NotificationRepository notificationRepository;

public void createNotification(Notification notification){
notificationRepository.save(notification);
}

public void readNotification(Notification notification) {
notification.setChecked(true);
notificationRepository.save(notification);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
package treehouse.server.api.notification.implement;

import lombok.RequiredArgsConstructor;
import treehouse.server.api.notification.persistence.NotificationRepository;
import treehouse.server.global.annotations.Adapter;
import treehouse.server.global.entity.notification.Notification;
import treehouse.server.global.exception.GlobalErrorCode;
import treehouse.server.global.exception.ThrowClass.NotificationException;

@Adapter
@RequiredArgsConstructor
public class NotificationQueryAdapter {

private final NotificationRepository notificationRepository;
public Notification findById(Long notificationId) {
return notificationRepository.findById(notificationId)
.orElseThrow(() -> new NotificationException(GlobalErrorCode.NOTIFICATION_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
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.RestController;
import treehouse.server.api.notification.business.NotificationService;
import treehouse.server.api.notification.presentation.dto.NotificationResponseDTO;
Expand All @@ -30,4 +32,13 @@ public CommonResponse<NotificationResponseDTO.getNotifications> getNotifications
){
return CommonResponse.onSuccess(notificationService.getNotifications(user));
}

@PostMapping("/users/notifications/{notificationId}")
@Operation(summary = "알림 확인 🔑 ✅", description = "사용자의 알림을 확인하여 '읽음' 상태로 변경합니다.")
public CommonResponse<NotificationResponseDTO.readNotification> readNotification(
@AuthMember @Parameter(hidden = true) User user,
@PathVariable Long notificationId
){
return CommonResponse.onSuccess(notificationService.readNotification(user, notificationId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package treehouse.server.api.notification.presentation.dto;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import treehouse.server.api.notification.business.NotificationService;
import treehouse.server.global.entity.notification.NotificationType;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class NotificationRequestDTO {

@Getter
@Setter
public static class createNotification {

private String title;
private String body;
private NotificationType type;
private Long targetId;
private Long receiverId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class NotificationResponseDTO {
@AllArgsConstructor
public static class getNotification {
private NotificationType type;
private String title;
private String body;
private String profileImageUrl;
private String userName;
private String receivedTime;
Expand All @@ -30,4 +32,12 @@ public static class getNotification {
public static class getNotifications {
List<NotificationResponseDTO.getNotification> notifications;
}

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class readNotification {
private Long notificationId;
}
}
Loading
Loading