Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/hotfix/api' into dev-check
Browse files Browse the repository at this point in the history
  • Loading branch information
versatile0010 committed Nov 22, 2023
2 parents 4048b88 + 2d58d36 commit 5f04577
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package com.numberone.backend.domain.disaster.service;

import com.numberone.backend.domain.disaster.event.DisasterEvent;
import com.numberone.backend.domain.disaster.util.DisasterType;
import com.numberone.backend.domain.friendship.entity.Friendship;
import com.numberone.backend.domain.member.entity.Member;
import com.numberone.backend.domain.member.repository.MemberRepository;
import com.numberone.backend.domain.notification.entity.NotificationEntity;
import com.numberone.backend.domain.notification.entity.NotificationTag;
import com.numberone.backend.domain.notification.repository.NotificationRepository;
import com.numberone.backend.domain.notificationdisaster.entity.NotificationDisaster;
import com.numberone.backend.domain.notificationdisaster.repository.NotificationDisasterRepository;
import com.numberone.backend.domain.notificationregion.repository.NotificationRegionRepository;
import com.numberone.backend.exception.notfound.NotFoundMemberException;
import com.numberone.backend.support.fcm.service.FcmMessageProvider;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;

Expand All @@ -28,6 +32,8 @@ public class DisasterEventHandler {
private final FcmMessageProvider fcmMessageProvider;
private final NotificationRepository notificationRepository;
private final NotificationRegionRepository notificationRegionRepository;
private final NotificationDisasterRepository notificationDisasterRepository;


@Transactional(jakarta.transaction.Transactional.TxType.REQUIRES_NEW)
@TransactionalEventListener
Expand All @@ -36,36 +42,51 @@ public void sendFcmMessagesByPresentLocation(DisasterEvent disasterEvent) {
log.info("[sendFcmMessagesByPresentLocation]");

String type = disasterEvent.getType().code2kor();
String location = disasterEvent.getLocation();
String disasterLocation = disasterEvent.getLocation();
Long disasterNum = disasterEvent.getDisasterNum();
String title = String.format("[긴급] %s %s 발생", location, type);
String title = String.format("[긴급] %s %s 발생", disasterLocation, type);
String message = "대피로에 접속하여 행동요령을 확인하세요!";

// 현재 재난 위치에 있는 회원에게 알림을 보낸다.
log.info("현재 재난 위치에 있는 회원에게 알림을 전송합니다.");
List<Long> memberIdListByPresentLocation = memberRepository.findAllByLocation(location);
// 현재 재난 위치에 있는 회원 아이디 리스트
List<Long> memberIdListByOnlyPresentLocation = memberRepository.findAllByLocation(disasterLocation);


List<String> targetMemberFcmTokens = memberIdListByPresentLocation.stream().map(memberId -> {
// 현재 재난 위치에 있으면서, 지금 발생한 재난 유형이 온보딩 때 선택한 재난 유형에 속하는 경우 핸들링
List<Long> memberIdListByPresentLocationAndOnboardingDisasterTypes = memberIdListByOnlyPresentLocation.stream().filter(
memberId -> {
List<DisasterType> enableDisasterTypes = notificationDisasterRepository.findAllByMemberId(memberId)
.stream().map(NotificationDisaster::getDisasterType).toList();
return enableDisasterTypes.contains(disasterEvent.getType());
}).map(memberId -> {
Member member = memberRepository.findById(memberId)
.orElseThrow(NotFoundMemberException::new);
NotificationEntity savedNotificationEntity = notificationRepository.save(
new NotificationEntity(member, disasterEvent.getType(), disasterEvent.getMessage(), true, location)
new NotificationEntity(member, disasterEvent.getType(), disasterEvent.getMessage(), true, disasterLocation)
);
member.updateSafety(false);
log.info("received member id: {} Notification id: {} ", member.getId(), savedNotificationEntity.getId());
log.info(title);
log.info(message);
return member.getId();
}).filter(Objects::nonNull).toList();

List<String> fcmTokensByPresentLocationAndOnboardingDisasterType = memberIdListByPresentLocationAndOnboardingDisasterTypes.stream().map(memberId -> {
Member member = memberRepository.findById(memberId)
.orElseThrow(NotFoundMemberException::new);
return member.getFcmToken();
}).filter(Objects::nonNull).toList();

// fcm 메세지 일괄 전송
fcmMessageProvider.sendFcmToMembers(targetMemberFcmTokens, title, message, NotificationTag.DISASTER);
log.info("현재 재난 위치에 있는, {} 재난 유형을 허용한 회원들에게 알림을 전송합니다.", type);
fcmMessageProvider.sendFcmToMembers(fcmTokensByPresentLocationAndOnboardingDisasterType, title, message, NotificationTag.DISASTER);



log.info("위험 지역에 위치한 회원의 가족에게 알림을 보냅니다.");
// 해당 회원의 가족에게 알림을 보낸다.
String messageToFriend = "";
String titleToFriend = "";
memberIdListByPresentLocation.forEach(memberId -> {
memberIdListByOnlyPresentLocation.forEach(memberId -> {
Member member = memberRepository.findById(memberId)
.orElseThrow(NotFoundMemberException::new);

Expand Down Expand Up @@ -93,28 +114,30 @@ public void sendFcmMessagesByPresentLocation(DisasterEvent disasterEvent) {
);
});

// 중복 알람 방지
List<Long> memberIdListByOnboardingRegions = memberRepository.findAll()
// 온보딩때 선택한 지역에 대한 알림을 받고자 하는 회원 리스트를 필터링합니다.
// 이때 중복 알림 발송을 방지하기 위한 필터링 작업을 먼저 수행합니다.
List<Long> distinctMemberIdListByOnboardingRegions = memberRepository.findAll()
.stream().map(Member::getId)
.filter(id -> !memberIdListByPresentLocation.contains(id))
.filter(id -> !memberIdListByPresentLocationAndOnboardingDisasterTypes.contains(id))
.toList();


log.info("회원이 재난문자 알림을 받고자 하는 지역에 대한 푸시알람을 중복을 제거하여 보냅니다.");
// 해당 회원의 온보딩 리스트를 기준으로 알림을 보낸다.
List<String> targetFcmListByOnboardingRegions = memberIdListByOnboardingRegions.stream()
// 해당 회원의 온보딩 리스트 및 알림을 허용하는 재난 유형을 기준으로 알림을 보낸다.
List<String> targetFcmsByOnboardingRegionsAndDisasterTypes = distinctMemberIdListByOnboardingRegions.stream()
.flatMap(memberId -> {
Member member = memberRepository.findById(memberId)
.orElseThrow(NotFoundMemberException::new);
boolean isMatched = notificationRegionRepository.findByMemberId(memberId)
.stream().anyMatch(
region -> region.getLocation().contains(location)
region -> region.getLocation().contains(disasterLocation)
);
notificationRepository.save(
new NotificationEntity(member, disasterEvent.getType(), disasterEvent.getMessage(), true, location)
new NotificationEntity(member, disasterEvent.getType(), disasterEvent.getMessage(), true, disasterLocation)
);
return isMatched ? Stream.of(member.getFcmToken()) : Stream.empty();
return isMatched ? Stream.of(member.getFcmToken()) : null;
}).filter(Objects::nonNull).toList();
fcmMessageProvider.sendFcmToMembers(targetFcmListByOnboardingRegions, title, message, NotificationTag.DISASTER);
fcmMessageProvider.sendFcmToMembers(targetFcmsByOnboardingRegionsAndDisasterTypes, title, message, NotificationTag.DISASTER);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import com.numberone.backend.domain.notificationdisaster.entity.NotificationDisaster;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface NotificationDisasterRepository extends JpaRepository<NotificationDisaster, Long> {
void deleteAllByMemberId(Long memberId);
List<NotificationDisaster> findAllByMemberId(Long memberId);

}

0 comments on commit 5f04577

Please sign in to comment.