Skip to content

Commit

Permalink
[Feat] 미확인 알림개수조회 기능구현 & 나에게 온 알림리스트 조회기능 구현#119
Browse files Browse the repository at this point in the history
  • Loading branch information
parseyong committed Jul 23, 2024
1 parent 99711d6 commit 0c780d1
Show file tree
Hide file tree
Showing 21 changed files with 229 additions and 26 deletions.
25 changes: 25 additions & 0 deletions src/main/java/me/snaptime/alarm/controller/AlarmController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import me.snaptime.alarm.common.AlarmType;
import me.snaptime.alarm.dto.res.FindAlarmsDto;
import me.snaptime.alarm.service.AlarmService;
import me.snaptime.common.CommonResponseDto;
import me.snaptime.reply.dto.res.FindParentReplyResDto;
Expand Down Expand Up @@ -69,6 +70,30 @@ public ResponseEntity<CommonResponseDto<FindParentReplyResDto>> readReplyAlarm(
alarmService.readSnapAlarm(userDetails.getUsername(), replyAlarmId)));
}

@GetMapping("/count/not-read")
@Operation(summary = "미확인알림개수 조회", description = "확인되지 않은 알림개수를 조회합니다.")
public ResponseEntity<CommonResponseDto<Long>> findNotReadAlarmCnt(
@AuthenticationPrincipal UserDetails userDetails) {

return ResponseEntity.status(HttpStatus.OK)
.body(new CommonResponseDto("미확인 알림개수 조회성공",
alarmService.findNotReadAlarmCnt(userDetails.getUsername())));
}

@GetMapping
@Operation(summary = "알림리스트 조회", description = "자신에게 온 알림리스트를 조회합니다.<br>"+
"읽지않은 알림을 먼저 보여주며 시간순으로 정렬하여 반환합니다.<br>"+
"알림타입별로 반환되는 데이터가 다릅니다. 팔로우알림에는 snapUrl정보가 없으며 "+
"댓글알림에만 댓글내용을 보여주는 previewText값이 있습니다.<br>"+
"각 알림타입별로 alarmId값이 부여되기 때문에 타입이 다른 알림의 경우 id값이 중복될 수 있습니다.")
public ResponseEntity<CommonResponseDto<FindAlarmsDto>> findalarms(
@AuthenticationPrincipal UserDetails userDetails) {

return ResponseEntity.status(HttpStatus.OK)
.body(new CommonResponseDto("알림리스트 조회성공",
alarmService.findAlarms(userDetails.getUsername())));
}

@DeleteMapping ("/{alarmId}")
@Operation(summary = "알림을 삭제합니다.", description =
"읽음 여부와 상관없이 알림을 삭제합니다.<br>" +
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/me/snaptime/alarm/domain/ReplyAlarm.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,21 @@ public class ReplyAlarm extends BaseTimeEntity {
@Enumerated(EnumType.STRING)
@Column(nullable = false, name = "alarm_type")
private AlarmType alarmType;


// 댓글이 변경되더라도 기존 댓글내용을 유지하기 위해 Reply와 연관관계를 맺지않음
@Column(nullable = false, name = "reply_message")
private String replyMessage;

@Column(name = "is_read",nullable = false)
private boolean isRead = false;

@Builder
protected ReplyAlarm(User sender, User receiver, Snap snap, String messgae, AlarmType alarmType){
protected ReplyAlarm(User sender, User receiver, Snap snap, String replyMessage, AlarmType alarmType){
this.sender=sender;
this.receiver=receiver;
this.alarmType=alarmType;
this.snap=snap;
this.replyMessage=replyMessage;
}

public void readAlarm(){
Expand Down
68 changes: 68 additions & 0 deletions src/main/java/me/snaptime/alarm/dto/res/AlarmInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package me.snaptime.alarm.dto.res;

import lombok.Builder;
import lombok.Getter;
import me.snaptime.alarm.common.AlarmType;
import me.snaptime.alarm.domain.FollowAlarm;
import me.snaptime.alarm.domain.ReplyAlarm;
import me.snaptime.alarm.domain.SnapAlarm;

import java.time.LocalDateTime;

@Builder
public record AlarmInfo(
Long alarmId,
String snapPhotoURL,
String senderName,
String senderProfilePhotoURL,
String timeAgo,
String previewText,
AlarmType alarmType,
@Getter
LocalDateTime createdDate

) {
public static AlarmInfo toDtoByFollowAlarm(String senderProfilePhotoURL, String timeAgo, FollowAlarm followAlarm){

return AlarmInfo.builder()
.alarmId(followAlarm.getFollowAlarmId())
.snapPhotoURL(null)
.senderName(followAlarm.getSender().getName())
.senderProfilePhotoURL(senderProfilePhotoURL)
.timeAgo(timeAgo)
.previewText(null)
.alarmType(followAlarm.getAlarmType())
.createdDate(followAlarm.getCreatedDate())
.build();
}

public static AlarmInfo toDtoBySnapAlarm(String senderProfilePhotoURL, String snapPhotoURL,
String timeAgo, SnapAlarm snapAlarm){

return AlarmInfo.builder()
.alarmId(snapAlarm.getSnapAlarmId())
.snapPhotoURL(snapPhotoURL)
.senderName(snapAlarm.getSender().getName())
.senderProfilePhotoURL(senderProfilePhotoURL)
.timeAgo(timeAgo)
.previewText(null)
.alarmType(snapAlarm.getAlarmType())
.createdDate(snapAlarm.getCreatedDate())
.build();
}

public static AlarmInfo toDtoByReplyAlarm(String senderProfilePhotoURL, String snapPhotoURL,
String timeAgo, ReplyAlarm replyAlarm){

return AlarmInfo.builder()
.alarmId(replyAlarm.getReplyAlarmId())
.snapPhotoURL(snapPhotoURL)
.senderName(replyAlarm.getSender().getName())
.senderProfilePhotoURL(senderProfilePhotoURL)
.timeAgo(timeAgo)
.previewText(replyAlarm.getReplyMessage())
.alarmType(replyAlarm.getAlarmType())
.createdDate(replyAlarm.getCreatedDate())
.build();
}
}
22 changes: 22 additions & 0 deletions src/main/java/me/snaptime/alarm/dto/res/FindAlarmsDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package me.snaptime.alarm.dto.res;

import lombok.Builder;

import java.util.List;

@Builder
public record FindAlarmsDto(

List<AlarmInfo> notReadAlarmInfos,
List<AlarmInfo> readAlarmInfos

) {
public static FindAlarmsDto toDto(List<AlarmInfo> notReadAlarmInfos, List<AlarmInfo> readAlarmInfos){

return FindAlarmsDto.builder()
.notReadAlarmInfos(notReadAlarmInfos)
.readAlarmInfos(readAlarmInfos)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package me.snaptime.alarm.repository;

import me.snaptime.alarm.domain.FollowAlarm;
import me.snaptime.user.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface FollowAlarmRepository extends JpaRepository<FollowAlarm,Long> {

List<FollowAlarm> findByReceiverAndIsRead(User user, boolean isRead);

Long countByReceiverAndIsRead(User user, boolean isRead);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package me.snaptime.alarm.repository;

import me.snaptime.alarm.domain.ReplyAlarm;
import me.snaptime.user.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface ReplyAlarmRepository extends JpaRepository<ReplyAlarm,Long> {

List<ReplyAlarm> findByReceiverAndIsRead(User user, boolean isRead);

Long countByReceiverAndIsRead(User user, boolean isRead);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package me.snaptime.alarm.repository;

import me.snaptime.alarm.domain.SnapAlarm;
import me.snaptime.user.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface SnapAlarmRepository extends JpaRepository<SnapAlarm,Long> {

List<SnapAlarm> findByReceiverAndIsRead(User user, boolean isRead);

Long countByReceiverAndIsRead(User user, boolean isRead);
}
4 changes: 2 additions & 2 deletions src/main/java/me/snaptime/alarm/service/AlarmService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ public interface AlarmService {
FindParentReplyResDto readReplyAlarm(String reqLoginId, Long replyAlarmId);

//유저의 모든 알림을 불러옵니다.
Object findAlarms(Long reqLoginId);
Object findAlarms(String reqLoginId);

// 읽지않은 알림이 몇개인지 조회합니다.
Long findNotReadAlarmCnt(Long reqLoginId);
Long findNotReadAlarmCnt(String reqLoginId);

/*
알림을 삭제합니다.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ public interface CreateAlarmService {
receiver : 알림을 받는 유저
alarmType : 알림타입
*/
void createReplyAlarm(User sender, User receiver, Snap snap, String message);
void createReplyAlarm(User sender, User receiver, Snap snap, String replyMessage);
}
72 changes: 68 additions & 4 deletions src/main/java/me/snaptime/alarm/service/impl/AlarmServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import me.snaptime.alarm.domain.FollowAlarm;
import me.snaptime.alarm.domain.ReplyAlarm;
import me.snaptime.alarm.domain.SnapAlarm;
import me.snaptime.alarm.dto.res.AlarmInfo;
import me.snaptime.alarm.dto.res.FindAlarmsDto;
import me.snaptime.alarm.repository.FollowAlarmRepository;
import me.snaptime.alarm.repository.ReplyAlarmRepository;
import me.snaptime.alarm.repository.SnapAlarmRepository;
Expand All @@ -17,9 +19,16 @@
import me.snaptime.reply.service.ReplyService;
import me.snaptime.snap.dto.res.FindSnapResDto;
import me.snaptime.snap.service.SnapService;
import me.snaptime.user.domain.User;
import me.snaptime.user.repository.UserRepository;
import me.snaptime.util.TimeAgoCalculator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
Expand All @@ -28,6 +37,7 @@ public class AlarmServiceImpl implements AlarmService {
private final SnapAlarmRepository snapAlarmRepository;
private final FollowAlarmRepository followAlarmRepository;
private final ReplyAlarmRepository replyAlarmRepository;
private final UserRepository userRepository;
private final FriendService friendService;
private final SnapService snapService;
private final ReplyService replyService;
Expand Down Expand Up @@ -81,13 +91,21 @@ public FindParentReplyResDto readReplyAlarm(String reqLoginId, Long replyAlarmId
}

@Override
public Object findAlarms(Long reqLoginId) {
return null;
public FindAlarmsDto findAlarms(String reqLoginId) {
User reqUser = userRepository.findByLoginId(reqLoginId)
.orElseThrow(() -> new CustomException(ExceptionCode.USER_NOT_EXIST));

return FindAlarmsDto.toDto(findSortedAlarms(reqUser,false), findSortedAlarms(reqUser,true));
}

@Override
public Long findNotReadAlarmCnt(Long reqLoginId) {
return null;
public Long findNotReadAlarmCnt(String reqLoginId) {
User reqUser = userRepository.findByLoginId(reqLoginId)
.orElseThrow(() -> new CustomException(ExceptionCode.USER_NOT_EXIST));

return followAlarmRepository.countByReceiverAndIsRead(reqUser,false)+
snapAlarmRepository.countByReceiverAndIsRead(reqUser, false)+
replyAlarmRepository.countByReceiverAndIsRead(reqUser, false);
}

@Override
Expand Down Expand Up @@ -127,4 +145,50 @@ private void isMyAlarm(String reqLoginId, String alarmReceiverLoginId){
throw new CustomException(ExceptionCode.ACCESS_FAIL_ALARM);

}

// 알림을 최신순으로 정렬하여 조회합니다.
private List<AlarmInfo> findSortedAlarms(User reqUser, boolean isRead){

List<AlarmInfo> alarmInfos = new ArrayList<>();

List<FollowAlarm> followAlarms = followAlarmRepository.findByReceiverAndIsRead(reqUser,isRead);
List<ReplyAlarm> replyAlarms = replyAlarmRepository.findByReceiverAndIsRead(reqUser,isRead);
List<SnapAlarm> snapAlarms = snapAlarmRepository.findByReceiverAndIsRead(reqUser,isRead);

followAlarms.forEach(followAlarm -> {

User sender = followAlarm.getSender();
String profilePhotoURL = urlComponent.makeProfileURL(sender.getProfilePhoto().getProfilePhotoId());
String timeAgo = TimeAgoCalculator.findTimeAgo(followAlarm.getCreatedDate());

AlarmInfo alarmInfo = AlarmInfo.toDtoByFollowAlarm(profilePhotoURL, timeAgo, followAlarm);
alarmInfos.add(alarmInfo);
});

replyAlarms.forEach(replyAlarm -> {

User sender = replyAlarm.getSender();
String profilePhotoURL = urlComponent.makeProfileURL(sender.getProfilePhoto().getProfilePhotoId());
String snapPhotoURL = urlComponent.makePhotoURL(replyAlarm.getSnap().getFileName(),false);
String timeAgo = TimeAgoCalculator.findTimeAgo(replyAlarm.getCreatedDate());

AlarmInfo alarmInfo = AlarmInfo.toDtoByReplyAlarm(profilePhotoURL, snapPhotoURL, timeAgo, replyAlarm);
alarmInfos.add(alarmInfo);
});

snapAlarms.forEach(snapAlarm -> {

User sender = snapAlarm.getSender();
String profilePhotoURL = urlComponent.makeProfileURL(sender.getProfilePhoto().getProfilePhotoId());
String snapPhotoURL = urlComponent.makePhotoURL(snapAlarm.getSnap().getFileName(),false);
String timeAgo = TimeAgoCalculator.findTimeAgo(snapAlarm.getCreatedDate());

AlarmInfo alarmInfo = AlarmInfo.toDtoBySnapAlarm(profilePhotoURL, snapPhotoURL, timeAgo, snapAlarm);
alarmInfos.add(alarmInfo);
});

alarmInfos.sort(Comparator.comparing(AlarmInfo::getCreatedDate).reversed());
return alarmInfos;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ public void createFollowAlarm(User sender, User receiver) {

@Override
@Transactional
public void createReplyAlarm(User sender, User receiver, Snap snap, String message) {
public void createReplyAlarm(User sender, User receiver, Snap snap, String replyMessage) {
ReplyAlarm replyAlarm = ReplyAlarm.builder()
.sender(sender)
.receiver(receiver)
.snap(snap)
.messgae(message)
.replyMessage(replyMessage)
.alarmType(AlarmType.REPLY)
.build();

Expand Down
1 change: 1 addition & 0 deletions src/main/java/me/snaptime/common/BaseTimeEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@EntityListeners(value = {AuditingEntityListener.class})
@MappedSuperclass
public abstract class BaseTimeEntity {

@CreatedDate
private LocalDateTime createdDate;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.snaptime.redis;
package me.snaptime.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.snaptime.redis;
package me.snaptime.jwt.redis;

import jakarta.persistence.Id;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.snaptime.redis;
package me.snaptime.jwt.redis;

import org.springframework.data.repository.CrudRepository;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public record AddChildReplyReqDto(
description = "대댓글로 등록할 내용을 입력해주세요"
)
@NotBlank(message = "내용을 입력해주세요")
String content,
String replyMessage,

@Schema(
example = "1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public record AddParentReplyReqDto(
description = "댓글로 등록할 내용을 입력해주세요"
)
@NotBlank(message = "내용을 입력해주세요")
String content,
String replyMessage,

@Schema(
example = "1",
Expand Down
Loading

0 comments on commit 0c780d1

Please sign in to comment.