사용자는 자신이 팔로우하는 다른 사용자의 활동(좋아요, 댓글, 팔로우)에 대한 알림을 받을 수 있으며, 해당 활동과 관련된 게시물도 함께 볼 수 있습니다.
Notification 엔티티 구현
Notification 엔티티는 사용자 간의 상호작용(좋아요, 댓글, 팔로우)에 대한 알림 정보를 저장합니다.
@Getter
@Setter
@Entity
@Table(name = "notifications")
@NoArgsConstructor
public class Notification extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
private NotiType type;
@ManyToOne
@JoinColumn(name="from_user_id")
private User fromUser;
@ManyToOne
@JoinColumn(name="to_user_id")
private User toUser;
@Column(name = "created_at")
private LocalDateTime createdAt;
}
NotiType Enum 구현
NotiType enum은 알림의 유형(좋아요, 댓글, 팔로우)을 정의합니다.
@Getter
public enum NotiType {
LIKE("좋아요"), COMMENT("댓글"), FOLLOW("팔로우");
NotiType(String key) {
this.key = key;
}
private String key;
}
NotificationDto 구현
NotificationDto는 알림 정보를 전달하기 위한 DTO입니다. 알림 메시지를 포함합니다.
@Getter
@AllArgsConstructor
public class NotificationDto {
private String message;
public static NotificationDto getNotification(Notification notification) {
String message = "";
message += notification.getFromUser().getName();
message += "님이 ";
message += notification.getToUser().getName();
if (notification.getType().equals(COMMENT)) message += "님의 글에 댓글을 남겼습니다.";
if (notification.getType().equals(LIKE)) message += "님의 글을 좋아합니다.";
if (notification.getType().equals(FOLLOW)) message += "님을 팔로우 합니다.";
return new NotificationDto(message);
}
}
NotificationRepository 구현
NotificationRepository는 알림 정보에 대한 데이터베이스 접근을 관리합니다.
public interface NotificationRepository extends JpaRepository<Notification, Long> {
@Query(value = "INSERT INTO notifications(from_user_id, to_user_id, type, created_at) VALUES(?1, ?2, ?3, now())", nativeQuery = true)
int mSave(Long fromUserId, Long toUserId, String type);
Notification findByToUserId(Long userId);
boolean existsByToUserId(Long userId);
}
알림 생성 로직 추가
각각의 알림을 저장하기 위해 설계합니다.
notificationRepository.mSave(userId, post.getUser().getId(), NotiType.LIKE.name());
notificationRepository.mSave(userId, post.getUser().getId(), NotiType.COMMENT.name());
notificationRepository.mSave(followerId, followingId, NotiType.FOLLOW.name());
NewsFeedDto 구현
NewsFeedDto는 뉴스피드 정보를 전달하기 위한 DTO입니다. 알림 리스트와 게시물 리스트를 포함합니다.
@Getter
@AllArgsConstructor
public class NewsFeedDto {
private List<NotificationDto> notificationDtos;
private List<PostDto> postDtos;
public static NewsFeedDto getNewsfeedDto(List<Notification> notifications, List<Post> posts) {
return new NewsFeedDto(
notifications.stream().map(NotificationDto::getNotification).collect(Collectors.toList()),
posts.stream().map(PostDto::getPostDto).collect(Collectors.toList())
);
}
}
FollowService 수정
FollowService에서는 사용자의 뉴스피드를 생성하는 로직을 구현합니다. 팔로우하는 사용자의 활동과 게시물을 조회하여 뉴스피드를 생성합니다.
@Transactional(readOnly = true)
public List<NewsFeedDto> getFeeds(Long userId) {
userRepository.findById(userId).orElseThrow(
() -> new BadRequestException("팔로워 사용자를 찾을 수 없습니다.")
);
List<Long> followingIds = followRepository.findByFollowerId(userId).stream()
.map(follow -> follow.getFollowing().getId())
.collect(Collectors.toList());
List<Notification> notifications = new ArrayList<>();
List<Post> posts = new ArrayList<>();
for (int i = 0; i < followingIds.size(); i++) {
if(notificationRepository.existsByToUserId(followingIds.get(i))){ // notification
notifications.add(notificationRepository.findByToUserId(followingIds.get(i)));
}
if(postRepository.existsByUserId(followingIds.get(i))){ // post
posts.add(postRepository.findByUserId(followingIds.get(i)));
}
}
List<NewsFeedDto> newsFeedDtos = new ArrayList<>();
newsFeedDtos.add(NewsFeedDto.getNewsfeedDto(notifications,posts));
return newsFeedDtos;
}
결론
이 구현을 통해 사용자는 자신이 팔로우하는 다른 사용자들의 활동에 대한 알림을 받을 수 있으며, 이를 통해 커뮤니티 내에서의 상호작용과 정보 공유를 촉진할 수 있습니다. 사용자는 뉴스피드를 통해 최신 활동과 관련된 게시물을 쉽게 확인할 수 있으며, 이는 사용자 경험을 향상시키는 중요한 요소가 됩니다.
'프로젝트 (Java) > 예약마켓' 카테고리의 다른 글
[프로젝트] 23. 로그아웃 기능을 위한 Redis 추가 (0) | 2024.01.29 |
---|---|
[프로젝트] 22. 뉴스피드 알림 기능 리팩토링 (0) | 2024.01.29 |
[프로젝트] 20. 뉴스피드 기능 추가 (0) | 2024.01.29 |
[프로젝트] 19. 연관관계 매핑을 통한 회원 탈퇴 기능 (0) | 2024.01.27 |
[프로젝트] 18. 게시물 댓글 작성 및 삭제 기능 (0) | 2024.01.26 |