Skip to content

Commit 3238244

Browse files
authored
Merge pull request #46 from DMU-DebugVisual/feat/notification-post-link
feat: 알림 클릭 시 게시물 이동 기능 추가(#45)
2 parents 94f4b5f + 61beb8d commit 3238244

File tree

4 files changed

+106
-10
lines changed

4 files changed

+106
-10
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.dmu.debug_visual.community.dto;
2+
3+
import com.dmu.debug_visual.community.entity.Notification;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
7+
import java.time.LocalDateTime;
8+
9+
/**
10+
* 알림 정보를 프론트엔드에 전달하기 위한 DTO
11+
*/
12+
@Getter
13+
@Builder
14+
public class NotificationResponse {
15+
private Long notificationId;
16+
private String message;
17+
private boolean isRead;
18+
private Notification.NotificationType notificationType;
19+
private LocalDateTime createdAt;
20+
private Long postId;
21+
22+
/**
23+
* Notification 엔티티를 NotificationResponse DTO로 변환하는 정적 팩토리 메소드
24+
*/
25+
public static NotificationResponse fromEntity(Notification notification) {
26+
return NotificationResponse.builder()
27+
.notificationId(notification.getId())
28+
.message(notification.getMessage())
29+
.isRead(notification.isRead())
30+
.notificationType(notification.getNotificationType())
31+
.createdAt(notification.getCreatedAt())
32+
.postId(notification.getPostId())
33+
.build();
34+
}
35+
}

src/main/java/com/dmu/debug_visual/community/entity/Notification.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
@Entity
1010
@Getter
11-
@Setter
11+
@Setter // 참고: 엔티티에 @Setter를 사용하는 것은 객체의 상태를 쉽게 변경할 수 있어 위험할 수 있습니다. 가능하면 markAsRead() 같은 명확한 메소드를 사용하는 것이 좋습니다.
1212
@Builder
1313
@NoArgsConstructor
1414
@AllArgsConstructor
@@ -17,18 +17,40 @@ public class Notification {
1717
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
1818
private Long id;
1919

20-
@ManyToOne(optional = false)
20+
@ManyToOne(fetch = FetchType.LAZY, optional = false)
21+
@JoinColumn(name = "receiver_id") // 외래키 컬럼 이름을 명시적으로 지정해주는 것이 좋습니다.
2122
private User receiver;
2223

24+
@Column(nullable = false)
2325
private String message;
2426

2527
@Builder.Default
28+
@Column(nullable = false)
2629
private boolean isRead = false;
2730

2831
private LocalDateTime createdAt;
2932

33+
// ✨ [추가] 알림 타입을 구분하기 위한 필드 (예: 댓글, 좋아요)
34+
@Enumerated(EnumType.STRING)
35+
@Column(nullable = false)
36+
private NotificationType notificationType;
37+
38+
public enum NotificationType {
39+
COMMENT, // 댓글
40+
LIKE // 좋아요
41+
}
42+
43+
// ✨ [추가] 알림을 클릭했을 때 이동할 게시물의 ID
44+
@Column
45+
private Long postId;
46+
3047
@PrePersist
3148
public void prePersist() {
3249
this.createdAt = LocalDateTime.now();
3350
}
51+
52+
// 읽음 처리 편의 메소드
53+
public void markAsRead() {
54+
this.isRead = true;
55+
}
3456
}

src/main/java/com/dmu/debug_visual/community/service/CommentService.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class CommentService {
2020

2121
Comment parent = null;
2222

23+
@Transactional // ✨ 알림 생성까지 하나의 트랜잭션으로 묶어주는 것이 안전합니다.
2324
public Long createComment(CommentRequestDTO dto, User user) {
2425
Post post = postRepository.findById(dto.getPostId())
2526
.orElseThrow(() -> new RuntimeException("게시글 없음"));
@@ -35,21 +36,30 @@ public Long createComment(CommentRequestDTO dto, User user) {
3536
parent = commentRepository.findById(dto.getParentId())
3637
.orElseThrow(() -> new RuntimeException("상위 댓글 없음"));
3738

38-
// 대댓글의 부모가 null이 아니면(즉, 대댓글에 대댓글을 다는 경우) 에러 발생
3939
if (parent.getParent() != null) {
4040
throw new IllegalArgumentException("대댓글에는 답글을 달 수 없습니다.");
4141
}
4242

4343
builder.parent(parent);
4444

4545
if (!user.getUserNum().equals(parent.getWriter().getUserNum())) {
46-
notificationService.notify(parent.getWriter(), user.getName() + "님이 댓글에 답글을 남겼습니다.");
46+
// ✨ 대댓글 알림 시 postId 추가
47+
notificationService.notify(
48+
parent.getWriter(),
49+
user.getName() + "님이 댓글에 답글을 남겼습니다.",
50+
post.getId() // ✨ 게시물 ID 전달
51+
);
4752
}
4853
}
4954

5055
// 게시글 작성자에게 알림 (작성자 본인이 아닌 경우)
5156
if (!user.getUserNum().equals(post.getWriter().getUserNum())) {
52-
notificationService.notify(post.getWriter(), user.getName() + "님이 게시글에 댓글을 남겼습니다.");
57+
// ✨ 게시글 댓글 알림 시 postId 추가
58+
notificationService.notify(
59+
post.getWriter(),
60+
user.getName() + "님이 게시글에 댓글을 남겼습니다.",
61+
post.getId() // ✨ 게시물 ID 전달
62+
);
5363
}
5464

5565
return commentRepository.save(builder.build()).getId();

src/main/java/com/dmu/debug_visual/community/service/NotificationService.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.dmu.debug_visual.user.User;
66
import lombok.RequiredArgsConstructor;
77
import org.springframework.stereotype.Service;
8+
import org.springframework.transaction.annotation.Transactional;
89

910
import java.util.List;
1011

@@ -14,12 +15,27 @@ public class NotificationService {
1415

1516
private final NotificationRepository notificationRepository;
1617

18+
/**
19+
* 일반 알림을 생성합니다. (게시물 ID가 없는 경우)
20+
* @param receiver 알림을 받을 사용자
21+
* @param message 알림 내용
22+
*/
23+
@Transactional
1724
public void notify(User receiver, String message) {
18-
Notification notification = Notification.builder()
19-
.receiver(receiver)
20-
.message(message)
21-
.build();
22-
notificationRepository.save(notification);
25+
// postId가 없는 경우, null로 저장합니다.
26+
// 좋아요 기능 등에서 이 메소드를 호출할 수 있습니다.
27+
createAndSaveNotification(receiver, message, null, Notification.NotificationType.LIKE); // 기본 타입을 LIKE 등으로 설정
28+
}
29+
30+
/**
31+
* 게시물과 관련된 알림을 생성합니다. (댓글 등)
32+
* @param receiver 알림을 받을 사용자
33+
* @param message 알림 내용
34+
* @param postId 관련된 게시물의 ID
35+
*/
36+
@Transactional
37+
public void notify(User receiver, String message, Long postId) {
38+
createAndSaveNotification(receiver, message, postId, Notification.NotificationType.COMMENT);
2339
}
2440

2541
public List<Notification> getUserNotifications(User user) {
@@ -35,4 +51,17 @@ public void markAsRead(Long notificationId, User user) {
3551
notification.setRead(true);
3652
notificationRepository.save(notification);
3753
}
54+
55+
/**
56+
* Notification 엔티티를 생성하고 저장하는 private 헬퍼 메소드
57+
*/
58+
private void createAndSaveNotification(User receiver, String message, Long postId, Notification.NotificationType type) {
59+
Notification notification = Notification.builder()
60+
.receiver(receiver)
61+
.message(message)
62+
.notificationType(type)
63+
.postId(postId) // postId가 null이 아니면 저장, null이면 null로 저장
64+
.build();
65+
notificationRepository.save(notification);
66+
}
3867
}

0 commit comments

Comments
 (0)