Skip to content

Commit

Permalink
Merge pull request #208 from bankidz/refactor/notificationCategory
Browse files Browse the repository at this point in the history
refactor: 알림에 카테고리 Enum으로 추가 및 알림 전부 읽었는지 확인하는 api 추가 #207
  • Loading branch information
sanbonai06 authored Sep 8, 2022
2 parents 6380870 + 683eeb8 commit 1213ff2
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 26 deletions.
19 changes: 19 additions & 0 deletions src/main/java/com/ceos/bankids/constant/NotificationCategory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.ceos.bankids.constant;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum NotificationCategory implements EnumMapperType {

CHALLENGE,
LEVEL,
NOTICE,
FAMILY;

@Override
public String getCode() {
return name();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import com.ceos.bankids.config.CommonResponse;
import com.ceos.bankids.constant.ChallengeStatus;
import com.ceos.bankids.constant.ErrorCode;
import com.ceos.bankids.constant.NotificationCategory;
import com.ceos.bankids.domain.Challenge;
import com.ceos.bankids.domain.ChallengeUser;
import com.ceos.bankids.domain.FamilyUser;
import com.ceos.bankids.domain.Notification;
import com.ceos.bankids.domain.User;
import com.ceos.bankids.dto.AllSendNotificationDTO;
import com.ceos.bankids.dto.NotificationDTO;
import com.ceos.bankids.dto.NotificationIsReadDTO;
import com.ceos.bankids.dto.NotificationListDTO;
import com.ceos.bankids.exception.ForbiddenException;
import com.ceos.bankids.repository.NotificationRepository;
Expand Down Expand Up @@ -56,16 +58,17 @@ public CommonResponse<String> allSendNotification(

String title = allSendNotificationRequest.getTitle();
String message = allSendNotificationRequest.getMessage();
NotificationCategory notificationCategory = NotificationCategory.NOTICE;
userRepository.findAll().stream()
.filter(user -> user.getExpoToken() != null && !Objects.equals(user.getExpoToken(),
"web"))
.forEach(user -> {
if (user.getNoticeOptIn()) {
expoNotificationService.sendMessage(user, title, message,
allSendNotificationRequest.getNewMap());
allSendNotificationRequest.getNewMap(), notificationCategory);
} else {
Notification notification = Notification.builder().user(user).title(title)
.message(message).build();
.message(message).notificationCategory(notificationCategory).build();
notificationRepository.save(notification);
}
});
Expand All @@ -83,6 +86,18 @@ public CommonResponse<NotificationListDTO> getNotificationList(
return CommonResponse.onSuccess(notificationListDTOS);
}

@ApiOperation(value = "유저 안읽은 알림 있는지 확인")
@GetMapping(value = "/isRead", produces = "application/json; charset=utf-8")
public CommonResponse<NotificationIsReadDTO> getNotificationIsAllRead(
@AuthenticationPrincipal User authUser) {

log.info("api = 안읽은 알림 있는지 확인 user = {}", authUser.getId());
NotificationIsReadDTO notificationIsReadDTO = expoNotificationService.readNotificationIsAllRead(
authUser);
return CommonResponse.onSuccess(notificationIsReadDTO);
}


@ApiOperation(value = "유저 알림 읽음 확인")
@PatchMapping(value = "/{notificationId}", produces = "application/json; charset=utf-8")
public CommonResponse<NotificationDTO> patchNotification(@AuthenticationPrincipal User authUser,
Expand All @@ -109,9 +124,12 @@ public void notification(Challenge challenge, User authUser) {
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("challengeId", challenge.getId());
newMap.put("userId", authUser.getId());
Boolean checkServiceOptIn = checkServiceOptIn(authUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.CHALLENGE;
Boolean checkServiceOptIn = checkServiceOptIn(authUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(authUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(authUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("유저 {}의 돈길 {}의 {} 상태변경 알림", authUser.getId(), challenge.getId(),
challenge.getChallengeStatus());
Expand All @@ -125,9 +143,12 @@ public void userLevelUpMinusOne(User authUser) {
String notificationBody = "레벨업하기까지 \uD83D\uDD381 개\uD83D\uDD38의 돈길만 완주하면 돼요";
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("userId", authUser.getId());
Boolean checkServiceOptIn = checkServiceOptIn(authUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.LEVEL;
Boolean checkServiceOptIn = checkServiceOptIn(authUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(authUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(authUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("유저 id = {}의 레벨업 직전 알림", authUser.getId());
}
Expand All @@ -141,9 +162,12 @@ public void userLevelUpHalf(User authUser) {

HashMap<String, Object> newMap = new HashMap<>();
newMap.put("userId", authUser.getId());
Boolean checkServiceOptIn = checkServiceOptIn(authUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.LEVEL;
Boolean checkServiceOptIn = checkServiceOptIn(authUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(authUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(authUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("유저 id = {}의 레벨업 절반 달성 알림", authUser.getId());
}
Expand All @@ -158,9 +182,12 @@ public void createPendingChallengeNotification(User contractUser, ChallengeUser
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("user", challengeUser.getUser().getId());
newMap.put("challenge", challengeUser.getChallenge().getId());
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.CHALLENGE;
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("부모 유저 id = {}에게 유저 id = {} 돈길 id = {} 의 돈길 제안", contractUser.getId(),
challengeUser.getUser().getId(), challengeUser.getChallenge().getId());
Expand All @@ -176,9 +203,12 @@ public void runProgressNotification(User contractUser, ChallengeUser challengeUs
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("user", challengeUser.getUser().getId());
newMap.put("challenge", challengeUser.getChallenge().getId());
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.CHALLENGE;
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("부모 유저 id = {}에게 유저 id = {}의 돈길 id = {} 돈길 걷기 알림 전송", contractUser.getId(),
challengeUser.getUser().getId(), challengeUser.getChallenge().getId());
Expand All @@ -195,9 +225,12 @@ public void achieveChallengeNotification(User contractUser, ChallengeUser challe
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("user", challengeUser.getUser().getId());
newMap.put("challenge", challengeUser.getChallenge().getId());
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.CHALLENGE;
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("부모 유저 id = {}에게 유저 id = {}의 돈길 id = {} 돈길 완주 알림 전송", contractUser.getId(),
challengeUser.getUser().getId(), challengeUser.getChallenge().getId());
Expand All @@ -212,9 +245,12 @@ public void kidLevelUpNotification(User contractUser, User user, Long level, Lon
user.getUsername() + "님이 레벨" + level + "에서 레벨" + afterLevel + "로 올랐어요! 확인해볼까요?";
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("user", user.getId());
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.LEVEL;
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("부모 유저 id = {}에게 유저 id = {}의 레벨업 알림 전송", contractUser.getId(), user.getId());
}
Expand All @@ -228,9 +264,12 @@ public void challengeFailedNotification(User contractUser, ChallengeUser challen
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("user", challengeUser.getUser().getId());
newMap.put("challenge", challengeUser.getChallenge().getId());
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody);
NotificationCategory notificationCategory = NotificationCategory.CHALLENGE;
Boolean checkServiceOptIn = checkServiceOptIn(contractUser, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap);
expoNotificationService.sendMessage(contractUser, title, notificationBody, newMap,
notificationCategory);
}
log.info("부모 유저 id = {}에게 유저 id = {}의 돈길 id = {} 돈길 실패 알림 전송", contractUser.getId(),
challengeUser.getChallenge().getId(), challengeUser.getChallenge().getId());
Expand All @@ -242,21 +281,26 @@ public void newFamilyUserNotification(User newFamilyUser, List<FamilyUser> famil
String title = "가족그룹\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66에 새로 참여했어요";
String notificationBody = "누가 가족그룹에 참여했는지 확인해요!\uD83D\uDCAB";
HashMap<String, Object> newMap = new HashMap<>();
NotificationCategory notificationCategory = NotificationCategory.FAMILY;
// newMap.put("user", newFamilyUser.getId());
familyUserList.forEach(familyUser -> {
User user = familyUser.getUser();
Boolean checkServiceOptIn = checkServiceOptIn(user, title, notificationBody);
Boolean checkServiceOptIn = checkServiceOptIn(user, title, notificationBody,
notificationCategory);
if (checkServiceOptIn) {
expoNotificationService.sendMessage(user, title, notificationBody, newMap);
expoNotificationService.sendMessage(user, title, notificationBody, newMap,
notificationCategory);
}
log.info("기존 가족 구성원 id = {}에게 유저 id = {}의 가족 참여 알림 전송", familyUser.getUser().getId(),
newFamilyUser.getId());
});
}

private Boolean checkServiceOptIn(User user, String title, String body) {
private Boolean checkServiceOptIn(User user, String title, String body,
NotificationCategory notificationCategory) {
if (!user.getServiceOptIn()) {
Notification notification = Notification.builder().user(user).title(title).message(body)
.notificationCategory(notificationCategory)
.build();
notificationRepository.save(notification);
return false;
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/ceos/bankids/domain/Notification.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.ceos.bankids.domain;

import com.ceos.bankids.constant.NotificationCategory;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
Expand Down Expand Up @@ -40,6 +43,10 @@ public class Notification extends AbstractTimestamp {
@ColumnDefault(value = "false")
private Boolean isRead;

@Column(nullable = false)
@Enumerated(EnumType.STRING)
private NotificationCategory notificationCategory;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userId", nullable = false)
private User user;
Expand All @@ -50,12 +57,15 @@ public Notification(
String title,
String message,
Boolean isRead,
NotificationCategory notificationCategory,
User user
) {

this.id = id;
this.title = title;
this.message = message;
this.isRead = isRead;
this.notificationCategory = notificationCategory;
this.user = user;
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/ceos/bankids/dto/NotificationDTO.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ceos.bankids.dto;

import com.ceos.bankids.constant.NotificationCategory;
import com.ceos.bankids.domain.Notification;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
Expand Down Expand Up @@ -27,6 +28,9 @@ public class NotificationDTO {
@ApiModelProperty(example = "false")
private Boolean isRead;

@ApiModelProperty(example = "CHALLENGE")
private NotificationCategory notificationCategory;

@ApiModelProperty(example = "2022/07/05 05:05:05")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy/MM/dd hh:mm:ss", timezone = "Asia/Seoul")
private Timestamp createdAt;
Expand All @@ -36,6 +40,7 @@ public NotificationDTO(Notification notification) {
this.title = notification.getTitle();
this.message = notification.getMessage();
this.isRead = notification.getIsRead();
this.notificationCategory = notification.getNotificationCategory();
this.createdAt = notification.getCreatedAt();
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/ceos/bankids/dto/NotificationIsReadDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ceos.bankids.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

@ApiModel(value = "읽지 않은 알림 확인 DTO")
@Getter
@ToString
@EqualsAndHashCode
public class NotificationIsReadDTO {

@ApiModelProperty(example = "true")
private Boolean isAllRead;

public NotificationIsReadDTO(Boolean isAllRead) {
this.isAllRead = isAllRead;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface NotificationRepository extends
public List<Notification> findAllByUserId(Long userId);

// @Query("select n from Notification n where n.id < ")
public Page<Notification> findByIdLessThanAndUserIdOrderByIdDesc(Long id, Long userId,
public Page<Notification> findByIdLessThanEqualAndUserIdOrderByIdDesc(Long id, Long userId,
Pageable pageRequest);

public Page<Notification> findByUserIdOrderByIdDesc(Long userId, Pageable pageRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.ceos.bankids.domain.User;
import com.ceos.bankids.dto.NotificationDTO;
import com.ceos.bankids.dto.NotificationIsReadDTO;
import com.ceos.bankids.dto.NotificationListDTO;
import org.springframework.stereotype.Service;

Expand All @@ -11,4 +12,6 @@ public interface ExpoNotificationService {
public NotificationListDTO readNotificationList(User user, Long lastId);

public NotificationDTO updateNotification(User user, Long notificationId);

public NotificationIsReadDTO readNotificationIsAllRead(User user);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.ceos.bankids.service;

import com.ceos.bankids.constant.ErrorCode;
import com.ceos.bankids.constant.NotificationCategory;
import com.ceos.bankids.domain.Notification;
import com.ceos.bankids.domain.User;
import com.ceos.bankids.dto.NotificationDTO;
import com.ceos.bankids.dto.NotificationIsReadDTO;
import com.ceos.bankids.dto.NotificationListDTO;
import com.ceos.bankids.exception.BadRequestException;
import com.ceos.bankids.exception.ForbiddenException;
Expand Down Expand Up @@ -56,12 +58,12 @@ public NotificationListDTO readNotificationList(User user, Long lastId) {
return new NotificationListDTO(lastNotificationId, true, notificationDTOS);
}
}
List<NotificationDTO> notificationDTOList = notificationRepository.findByIdLessThanAndUserIdOrderByIdDesc(
List<NotificationDTO> notificationDTOList = notificationRepository.findByIdLessThanEqualAndUserIdOrderByIdDesc(
lastId, user.getId(), pageRequest).stream()
.map(NotificationDTO::new).collect(Collectors.toList());
NotificationDTO lastNotification = notificationDTOList.get(notificationDTOList.size() - 1);
Long last = lastNotification.getId();
if (notificationDTOList.size() <= 11L) {
if (notificationDTOList.size() == 11L) {
notificationDTOList.remove(10);
return new NotificationListDTO(last, false, notificationDTOList);
} else {
Expand All @@ -86,12 +88,28 @@ public NotificationDTO updateNotification(User user, Long notificationId) {
return new NotificationDTO(notification);
}

@Transactional(readOnly = true)
@Override
public NotificationIsReadDTO readNotificationIsAllRead(User user) {

List<Notification> notificationList = notificationRepository.findAllByUserId(user.getId())
.stream()
.filter(notification -> !notification.getIsRead()).collect(
Collectors.toList());
if (notificationList.size() == 0) {
return new NotificationIsReadDTO(true);
} else {
return new NotificationIsReadDTO(false);
}
}

@Transactional
public void deleteAllNotification(User user) {
notificationRepository.deleteAllByUserId(user.getId());
}

public void sendMessage(User user, String title, String body, Map<String, Object> data) {
public void sendMessage(User user, String title, String body, Map<String, Object> data,
NotificationCategory notificationCategory) {

String token = user.getExpoToken();
if (token == null) {
Expand Down Expand Up @@ -123,7 +141,7 @@ public void sendMessage(User user, String title, String body, Map<String, Object
}
//Todo 메서드 인자가 user로 바뀌면 데이터 베이스에 꽂기
Notification notification = Notification.builder().title(title).message(body).user(user)
.build();
.notificationCategory(notificationCategory).build();
notificationRepository.save(notification);
List<ExpoPushTicket> allTickets = new ArrayList<>();
for (CompletableFuture<List<ExpoPushTicket>> messageReplyFuture : messageRepliesFutures) {
Expand Down

0 comments on commit 1213ff2

Please sign in to comment.