Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 미확인 알림개수조회 기능구현 & 나에게 온 알림리스트 조회기능 구현 #120

Merged
merged 5 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading