-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathNotificationQueryService.java
More file actions
99 lines (81 loc) · 3.91 KB
/
NotificationQueryService.java
File metadata and controls
99 lines (81 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package com.example.RealMatch.notification.application.service;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.RealMatch.global.exception.CustomException;
import com.example.RealMatch.notification.domain.entity.Notification;
import com.example.RealMatch.notification.domain.entity.enums.NotificationCategory;
import com.example.RealMatch.notification.domain.entity.enums.NotificationKind;
import com.example.RealMatch.notification.domain.repository.NotificationRepository;
import com.example.RealMatch.notification.exception.NotificationErrorCode;
import com.example.RealMatch.notification.presentation.dto.response.NotificationDateGroup;
import com.example.RealMatch.notification.presentation.dto.response.NotificationListResponse;
import com.example.RealMatch.notification.presentation.dto.response.NotificationResponse;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class NotificationQueryService {
private final NotificationRepository notificationRepository;
private static final DateTimeFormatter DATE_LABEL_FORMATTER =
DateTimeFormatter.ofPattern("yy.MM.dd (E)", Locale.KOREAN);
public NotificationListResponse getNotifications(Long userId, String filter, int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
List<NotificationKind> kinds = resolveKinds(filter);
Page<Notification> notificationPage;
if (kinds == null) {
notificationPage = notificationRepository.findByUserId(userId, pageRequest);
} else {
notificationPage = notificationRepository.findByUserIdAndKindIn(userId, kinds, pageRequest);
}
List<NotificationResponse> items = notificationPage.getContent().stream()
.map(NotificationResponse::from)
.toList();
List<NotificationDateGroup> groups = buildDateGroups(notificationPage.getContent());
long unreadCount = notificationRepository.countUnreadByUserId(userId);
return new NotificationListResponse(
items,
groups,
unreadCount,
notificationPage.getTotalElements(),
notificationPage.getTotalPages(),
notificationPage.getNumber(),
notificationPage.getSize()
);
}
public long getUnreadCount(Long userId) {
return notificationRepository.countUnreadByUserId(userId);
}
private List<NotificationKind> resolveKinds(String filter) {
if (filter == null || "ALL".equalsIgnoreCase(filter)) {
return null;
}
try {
NotificationCategory category = NotificationCategory.valueOf(filter.toUpperCase());
return category.getKinds();
} catch (IllegalArgumentException e) {
throw new CustomException(NotificationErrorCode.NOTIFICATION_INVALID_FILTER);
}
}
private List<NotificationDateGroup> buildDateGroups(List<Notification> notifications) {
return notifications.stream()
.collect(Collectors.groupingBy(
n -> n.getCreatedAt().toLocalDate(),
LinkedHashMap::new,
Collectors.counting()
))
.entrySet().stream()
.map(entry -> NotificationDateGroup.of(
entry.getKey(),
entry.getValue().intValue(),
DATE_LABEL_FORMATTER))
.toList();
}
}