Skip to content

Commit

Permalink
Merge pull request #46 from Likelion-YeungNam-Univ/feat/#43-notificat…
Browse files Browse the repository at this point in the history
…ion-crud

Feat/#43 notification crud
  • Loading branch information
jjjjjinseo authored Aug 2, 2024
2 parents 8662c78 + d7847ca commit e86646f
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.example.beginnerfitbe.alarm.controller;

import com.example.beginnerfitbe.alarm.domain.Alarm;
import com.example.beginnerfitbe.alarm.dto.AlarmDTO;
import com.example.beginnerfitbe.alarm.service.AlarmService;
import com.example.beginnerfitbe.jwt.util.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/alarm")
@RequiredArgsConstructor
public class AlarmController {

private final AlarmService alarmService;
private final JwtUtil jwtUtil; // JwtUtil 주입

@GetMapping
public ResponseEntity<List<AlarmDTO>> getAlarms(HttpServletRequest request) {
// JWT 토큰에서 사용자 ID 추출
String token = jwtUtil.resolveToken(request);
Long userId = jwtUtil.getUserId(token.substring(7));

// 사용자 ID로 알림 조회
List<Alarm> alarms = alarmService.getAlarmsByUserId(userId);
List<AlarmDTO> alarmDTOs = alarms.stream()
.map(AlarmDTO::fromEntity)
.collect(Collectors.toList());
return ResponseEntity.ok(alarmDTOs);
}

// 알림 체크 처리
@PutMapping("/{alarmId}/check")
public ResponseEntity<Void> checkAlarm(HttpServletRequest request, @PathVariable Long alarmId) {

String token = jwtUtil.resolveToken(request);
Long userId = jwtUtil.getUserId(token.substring(7));

// 알림 체크 처리
alarmService.checkAlarm(userId, alarmId);

return ResponseEntity.ok().build();
}


}
44 changes: 44 additions & 0 deletions src/main/java/com/example/beginnerfitbe/alarm/domain/Alarm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.beginnerfitbe.alarm.domain;

import com.example.beginnerfitbe.user.domain.User;
import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDateTime;

@Entity
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Alarm {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long alarmId;

@Column(nullable = false)
private boolean alarmChecked;

@Column(nullable = false)
private LocalDateTime alarmDate;

@Column(nullable = false)
private String alarmMessage;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userId")
private User user;

@Column(nullable = false)
@Enumerated(EnumType.STRING) // Enum 값을 문자열로 저장
private AlarmType alarmType; // 추가된 enum 필드

@Builder
public Alarm(User user, boolean alarmChecked, String alarmMessage, AlarmType alarmType) {
this.user = user;
this.alarmChecked = alarmChecked;
this.alarmDate = LocalDateTime.now();
this.alarmMessage = alarmMessage;
this.alarmType = alarmType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.beginnerfitbe.alarm.domain;

public enum AlarmType {
FRIEND_REQUEST, // 친구 요청
COMMENT_ALARM, // 게시글 댓글 알림
CHALLENGE_REMINDER, // 오늘의 챌린지 남은 알림
FRIEND_ACCEPTANCE // 친구 수락 알림
}
34 changes: 34 additions & 0 deletions src/main/java/com/example/beginnerfitbe/alarm/dto/AlarmDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.beginnerfitbe.alarm.dto;

import com.example.beginnerfitbe.alarm.domain.Alarm;
import com.example.beginnerfitbe.alarm.domain.AlarmType;
import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AlarmDTO {

private Long alarmId;
private boolean alarmChecked;
private LocalDateTime alarmDate;
private String alarmMessage;
private Long userId;
private AlarmType alarmType;

public static AlarmDTO fromEntity(Alarm alarm) {
return AlarmDTO.builder()
.alarmId(alarm.getAlarmId())
.alarmChecked(alarm.isAlarmChecked())
.alarmDate(alarm.getAlarmDate())
.alarmMessage(alarm.getAlarmMessage())
.userId(alarm.getUser().getId())
.alarmType(alarm.getAlarmType())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.beginnerfitbe.alarm.repository;

import com.example.beginnerfitbe.alarm.domain.Alarm;
import com.example.beginnerfitbe.user.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface AlarmRepository extends JpaRepository<Alarm, Long> {

List<Alarm> findByUser(User user);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.example.beginnerfitbe.alarm.service;

import com.example.beginnerfitbe.alarm.domain.Alarm;
import com.example.beginnerfitbe.alarm.domain.AlarmType;
import com.example.beginnerfitbe.alarm.repository.AlarmRepository;
import com.example.beginnerfitbe.user.domain.User;
import com.example.beginnerfitbe.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@RequiredArgsConstructor
public class AlarmService {

private final AlarmRepository alarmRepository;
private final UserRepository userRepository;

public void createAlarm(User receiver, String alarmMessage, AlarmType alarmType) {
Alarm alarm = Alarm.builder()
.user(receiver)
.alarmChecked(false)
.alarmMessage(alarmMessage)
.alarmType(alarmType) // 알림 타입 추가
.build();
alarmRepository.save(alarm);
}

public List<Alarm> getAlarmsByUserId(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다."));
return alarmRepository.findByUser(user);
}

public void checkAlarm(Long userId, Long alarmId) {
// alarmId에 해당하는 알림 객체 찾기
Alarm alarm = alarmRepository.findById(alarmId)
.orElseThrow(() -> new RuntimeException("해당 알림이 존재하지 않습니다."));

// 알림의 userId와 일치하는지 확인
if (!alarm.getUser().getId().equals(userId)) {
throw new RuntimeException("해당 알림을 가진 사용자를 찾을 수 없습니다.");
}

// alarmChecked를 true로 변경
alarm.setAlarmChecked(true);
alarmRepository.save(alarm); // 변경사항 저장
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.beginnerfitbe.challengeparticipant.service;

import com.example.beginnerfitbe.alarm.domain.AlarmType;
import com.example.beginnerfitbe.alarm.service.AlarmService;
import com.example.beginnerfitbe.challengeparticipant.domain.ChallengeParticipant;
import com.example.beginnerfitbe.challengeparticipant.dto.ChallengeParticipantDTO;
import com.example.beginnerfitbe.challengeparticipant.dto.ChallengeRankingDto;
Expand All @@ -26,6 +28,7 @@ public class ChallengeParticipantService {
private final ChallengeParticipantRepository challengeParticipantRepository;
private final UserRepository userRepository;
private final FriendRepository friendRepository;
private final AlarmService alarmService;

public List<OtherUserDto> getAcceptedFriends(Long userId) {
// 수락된 친구 목록 가져오기
Expand Down Expand Up @@ -175,9 +178,30 @@ public void completeChallenge(Long userId, Long challengeId) {
.findByUserIdAndChallenge_ChallengeIdAndChallengeCompletedDate(userId, challengeId, currentDate)
.orElseThrow(() -> new RuntimeException("Challenge participant not found")); // 예외 처리

// isCompleted를 true로 변경
participant.setCompleted(true); // setter 메서드 필요

participant.setCompleted(true); // isCompleted를 true로 변경
challengeParticipantRepository.save(participant); // 변경사항 저장


// 해당 사용자의 오늘 날짜에 해당하는 챌린지 참가자 목록 가져오기 (challengeId 제거)
List<ChallengeParticipant> participants = challengeParticipantRepository
.findByUserIdAndChallengeCompletedDate(userId, currentDate);

// isCompleted가 true인 참가자의 수를 세기
long completedCount = participants.stream()
.filter(ChallengeParticipant::isCompleted)
.count();

// completedCount가 2일 경우 알림 생성
if (completedCount == 2) {
String alarmMessage = "";
// 알림 생성
alarmService.createAlarm(participant.getUser(), alarmMessage, AlarmType.CHALLENGE_REMINDER);
}




}

public void notcompleteChallenge(Long userId, Long challengeId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.beginnerfitbe.comment.service;

import com.example.beginnerfitbe.alarm.domain.AlarmType;
import com.example.beginnerfitbe.alarm.service.AlarmService;
import com.example.beginnerfitbe.comment.domain.Comment;
import com.example.beginnerfitbe.comment.dto.CommentCreateDto;
import com.example.beginnerfitbe.comment.dto.CommentDto;
Expand All @@ -26,8 +28,9 @@ public class CommentService {
private final PostRepository postRepository;
private final UserRepository userRepository;
private final CommentRepository commentRepository;
private final AlarmService alarmService;

public ResponseEntity<StateResponse> create(Long userId, Long postId,CommentCreateDto commentCreateDto){
public ResponseEntity<StateResponse> create(Long userId, Long postId, CommentCreateDto commentCreateDto){
Post post = postRepository.findById(postId).orElseThrow(() -> new IllegalArgumentException("not found post"));
User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("not found user"));

Expand All @@ -39,6 +42,10 @@ public ResponseEntity<StateResponse> create(Long userId, Long postId,CommentCrea
.build();

commentRepository.save(comment);

String alarmMessage = user.getName() + " "+postId;
alarmService.createAlarm(post.getUser(), alarmMessage, AlarmType.COMMENT_ALARM); // 알림 생성

return ResponseEntity.ok(StateResponse.builder().code("SUCCESS").message("댓글을 성공적으로 생성했습니다.").build());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.beginnerfitbe.friend.service;

import com.example.beginnerfitbe.alarm.domain.AlarmType;
import com.example.beginnerfitbe.alarm.service.AlarmService;
import com.example.beginnerfitbe.friend.domain.Friend;
import com.example.beginnerfitbe.friend.dto.FriendDTO;
import com.example.beginnerfitbe.friend.repository.FriendRepository;
Expand All @@ -23,6 +25,7 @@ public class FriendService {

private final FriendRepository friendRepository;
private final UserRepository userRepository;
private final AlarmService alarmService;

@Transactional
public FriendDTO sendPathRequest(Long senderId, Long receiverId) {
Expand Down Expand Up @@ -51,7 +54,6 @@ else if (reexistingFriend.isPresent()) {
throw new RuntimeException("이미 친구 요청이 온 사용자입니다. 친구 요청을 수락해주세요.");
}


else {
Friend friend = Friend.builder()
.sender(sender)
Expand All @@ -61,6 +63,10 @@ else if (reexistingFriend.isPresent()) {
.build();

Friend savedFriend = friendRepository.save(friend);

String alarmMessage = sender.getName();
alarmService.createAlarm(receiver, alarmMessage, AlarmType.FRIEND_REQUEST);

return FriendDTO.fromEntity(savedFriend);
}
}
Expand Down Expand Up @@ -101,6 +107,10 @@ else if (reexistingFriend.isPresent()) {
.build();

Friend savedFriend = friendRepository.save(friend);

String alarmMessage = sender.getName();
alarmService.createAlarm(receiver, alarmMessage, AlarmType.FRIEND_REQUEST);

return FriendDTO.fromEntity(savedFriend);
}

Expand Down Expand Up @@ -210,6 +220,12 @@ public void acceptFriendRequest(Long senderId, Long receiverId) {

friend.accept();
friendRepository.save(friend);

// 알림 메시지 생성
String alarmMessage =friend.getReceiver().getName();

// 알림 생성
alarmService.createAlarm(friend.getSender(), alarmMessage, AlarmType.FRIEND_ACCEPTANCE);
}

public void rejectFriendRequest(Long senderId, Long receiverId) {
Expand Down
9 changes: 4 additions & 5 deletions src/main/java/com/example/beginnerfitbe/user/domain/User.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package com.example.beginnerfitbe.user.domain;

import com.example.beginnerfitbe.alarm.domain.Alarm;
import com.example.beginnerfitbe.attendance.domain.Attendance;
import com.example.beginnerfitbe.challengeparticipant.domain.ChallengeParticipant;
import com.example.beginnerfitbe.declaration.domain.Declaration;
import com.example.beginnerfitbe.like.domain.PostLike;
import com.example.beginnerfitbe.playlist.domain.Playlist;
import com.example.beginnerfitbe.post.domain.Post;
import com.example.beginnerfitbe.scrap.domain.Scrap;
import com.example.beginnerfitbe.weight.domain.WeightRecord;
import jakarta.persistence.*;
import lombok.*;
Expand Down Expand Up @@ -71,6 +67,9 @@ public class User {
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<ChallengeParticipant> challengeParticipants = new ArrayList<>();

@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<Alarm> alarms = new ArrayList<>();


@Builder
public User(String email, String name, String password, String profileUrl, double height, double weight, double targetWeight, String date, String targetDate, int exerciseTime, List<String> exerciseIntensity, List<String> exerciseGoals, List<String> concernedAreas) {
Expand Down

0 comments on commit e86646f

Please sign in to comment.