Skip to content

Commit

Permalink
[feat] 알림 (단일 조회, 목록 조회, 삭제) api 구현 (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
soeunkk committed Aug 29, 2022
1 parent 62686a4 commit db96f89
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@

import com.nadoyagsa.pillaroid.common.dto.ApiResponse;
import com.nadoyagsa.pillaroid.common.exception.BadRequestException;
import com.nadoyagsa.pillaroid.common.exception.ForbiddenException;
import com.nadoyagsa.pillaroid.common.exception.InternalServerException;
import com.nadoyagsa.pillaroid.common.exception.NotFoundException;
import com.nadoyagsa.pillaroid.common.exception.UnauthorizedException;
import com.nadoyagsa.pillaroid.dto.AlarmTimeDto;
import com.nadoyagsa.pillaroid.dto.AlarmTimeResponse;
import com.nadoyagsa.pillaroid.dto.FavoritesDTO;
import com.nadoyagsa.pillaroid.dto.FavoritesResponse;
import com.nadoyagsa.pillaroid.dto.NotificationDto;
import com.nadoyagsa.pillaroid.dto.NotificationResponse;
import com.nadoyagsa.pillaroid.dto.NotificationTimeResponse;
import com.nadoyagsa.pillaroid.entity.Favorites;
import com.nadoyagsa.pillaroid.entity.User;
import com.nadoyagsa.pillaroid.jwt.AuthTokenProvider;
import com.nadoyagsa.pillaroid.service.AlarmTimeService;
import com.nadoyagsa.pillaroid.service.FavoritesService;
import com.nadoyagsa.pillaroid.service.NotificationService;
import com.nadoyagsa.pillaroid.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
Expand All @@ -32,14 +37,17 @@ public class UserController {
private final UserService userService;
private final FavoritesService favoritesService;
private final AlarmTimeService alarmTimeService;
private final NotificationService notificationService;

@Autowired
public UserController(AuthTokenProvider authTokenProvider, UserService userService,
FavoritesService favoritesService, AlarmTimeService alarmTimeService) {
FavoritesService favoritesService, AlarmTimeService alarmTimeService,
NotificationService notificationService) {
this.authTokenProvider = authTokenProvider;
this.userService = userService;
this.favoritesService = favoritesService;
this.alarmTimeService = alarmTimeService;
this.notificationService = notificationService;
}

/* 즐겨찾기 */
Expand Down Expand Up @@ -160,6 +168,37 @@ public ApiResponse<AlarmTimeResponse> saveUserAlarmTime(HttpServletRequest reque
return ApiResponse.success(alarmTime);
}

/* 알림 */
// 의약품에 대한 사용자 알림 조회
@GetMapping("/notifications/{mid}")
public ApiResponse<NotificationResponse> getUserNotification(HttpServletRequest request, @PathVariable("mid") int medicineIdx) {
User user = findUserByToken(request)
.orElseThrow(() -> UnauthorizedException.UNAUTHORIZED_USER);

NotificationResponse notification = notificationService.findNotificationByUserAndMedicineIdx(user, medicineIdx);
return ApiResponse.success(notification);
}

// 사용자의 의약품 알림 목록 조회
@GetMapping("/notifications/list")
public ApiResponse<List<NotificationResponse>> getUserNotificationList(HttpServletRequest request) {
User user = findUserByToken(request)
.orElseThrow(() -> UnauthorizedException.UNAUTHORIZED_USER);

List<NotificationResponse> notifications = notificationService.findNotificationByUser(user);
return ApiResponse.success(notifications);
}

// 의약품에 대한 사용자 알림 삭제
@DeleteMapping("/notifications/{nid}")
public ApiResponse<NotificationTimeResponse> deleteUserNotification(HttpServletRequest request, @PathVariable("nid") long notificationIdx) throws ForbiddenException {
User user = findUserByToken(request)
.orElseThrow(() -> UnauthorizedException.UNAUTHORIZED_USER);

NotificationTimeResponse notificationAndTime = notificationService.deleteNotification(user, notificationIdx); // 알림 데이터 삭제
return ApiResponse.success(notificationAndTime);
}

// 사용자 jwt 토큰으로부터 회원 정보 조회
public Optional<User> findUserByToken(HttpServletRequest request) {
try {
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/com/nadoyagsa/pillaroid/dto/NotificationDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.nadoyagsa.pillaroid.dto;

import javax.validation.constraints.NotNull;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class NotificationDto {
private long userIdx;

@NotNull(message = "medicineIdx 필수")
private int medicineIdx;

@NotNull(message = "name 필수")
private String name;

@NotNull(message = "period 필수")
private int period;

private String dosage;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.nadoyagsa.pillaroid.dto;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class NotificationResponse {
private long notificationIdx;
private String name;
private int period;
private String dosage;
}
16 changes: 16 additions & 0 deletions src/main/java/com/nadoyagsa/pillaroid/dto/NotificationTimeDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.nadoyagsa.pillaroid.dto;

import java.time.LocalTime;

import com.fasterxml.jackson.annotation.JsonInclude;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class NotificationTimeDto {
private long notificationTimeIdx;
private LocalTime time;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.nadoyagsa.pillaroid.dto;

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

import com.fasterxml.jackson.annotation.JsonInclude;
import com.nadoyagsa.pillaroid.entity.Notification;
import com.nadoyagsa.pillaroid.entity.NotificationTime;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class NotificationTimeResponse {
private long notificationIdx;
private String name;
private long period;
private String dosage;
private List<NotificationTimeDto> notificationTimes;

public NotificationTimeResponse(Notification notification, List<NotificationTime> notificationTimes) {
this.notificationIdx = notification.getNotificationIdx();
this.name = notification.getName();
this.period = notification.getPeriod();
this.dosage = notification.getDosage();
this.notificationTimes = notificationTimes.stream()
.map(NotificationTime::toNotificationTimeDto)
.collect(Collectors.toList());
}
}
58 changes: 58 additions & 0 deletions src/main/java/com/nadoyagsa/pillaroid/entity/Notification.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.nadoyagsa.pillaroid.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.nadoyagsa.pillaroid.dto.NotificationResponse;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@Table(name = "notification")
@Entity
public class Notification {
@Id
@Column(name = "notification_idx")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long notificationIdx;

@ManyToOne
@JoinColumn(name = "user_idx")
private User user;

@ManyToOne
@JoinColumn(name = "medicine_idx")
private Medicine medicine;

@Column(name = "name")
private String name;

@Column
private int period;

@Column
private String dosage;

public NotificationResponse toNotificationResponse() {
return NotificationResponse.builder()
.notificationIdx(this.notificationIdx)
.name(this.name)
.period(this.period)
.dosage(this.dosage)
.build();
}

}
44 changes: 44 additions & 0 deletions src/main/java/com/nadoyagsa/pillaroid/entity/NotificationTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.nadoyagsa.pillaroid.entity;

import java.time.LocalTime;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.nadoyagsa.pillaroid.dto.NotificationTimeDto;
import com.nadoyagsa.pillaroid.dto.NotificationTimeResponse;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@Table(name = "notification_time")
@Entity
public class NotificationTime {
@Id
@Column(name = "notification_time_idx")
private Long notificationTimeIdx;

@OneToOne
@JoinColumn(name = "notification_idx")
private Notification notification;

@Column
private LocalTime time;

public NotificationTimeDto toNotificationTimeDto() {
return NotificationTimeDto.builder()
.notificationTimeIdx(this.notificationTimeIdx)
.time(this.time)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.nadoyagsa.pillaroid.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.nadoyagsa.pillaroid.entity.Medicine;
import com.nadoyagsa.pillaroid.entity.Notification;
import com.nadoyagsa.pillaroid.entity.User;

public interface NotificationRepository extends JpaRepository<Notification, Long> {
Optional<Notification> findByUserAndMedicine(User user, Medicine medicine);

@Query("SELECT f FROM Notification f WHERE f.user.userIdx = :userIdx AND f.medicine.medicineIdx = :medicineIdx")
Optional<Notification> findByUserIdxAndMedicineIdx(@Param("userIdx") long userIdx, @Param("medicineIdx") int medicineIdx);

List<Notification> findByUser(User user);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.nadoyagsa.pillaroid.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.nadoyagsa.pillaroid.entity.Notification;
import com.nadoyagsa.pillaroid.entity.NotificationTime;

public interface NotificationTimeRepository extends JpaRepository<NotificationTime, Long> {
List<NotificationTime> findByNotification(Notification notification);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.nadoyagsa.pillaroid.service;

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

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nadoyagsa.pillaroid.common.exception.BadRequestException;
import com.nadoyagsa.pillaroid.common.exception.ForbiddenException;
import com.nadoyagsa.pillaroid.common.exception.NotFoundException;
import com.nadoyagsa.pillaroid.dto.NotificationResponse;
import com.nadoyagsa.pillaroid.dto.NotificationTimeDto;
import com.nadoyagsa.pillaroid.dto.NotificationTimeResponse;
import com.nadoyagsa.pillaroid.entity.Medicine;
import com.nadoyagsa.pillaroid.entity.Notification;
import com.nadoyagsa.pillaroid.entity.NotificationTime;
import com.nadoyagsa.pillaroid.entity.User;
import com.nadoyagsa.pillaroid.repository.MedicineRepository;
import com.nadoyagsa.pillaroid.repository.NotificationRepository;
import com.nadoyagsa.pillaroid.repository.NotificationTimeRepository;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class NotificationService {

private final NotificationRepository notificationRepository;
private final NotificationTimeRepository notificationTimeRepository;
private final MedicineRepository medicineRepository;

// 의약품에 해당하는 사용자 알림 조회
public NotificationResponse findNotificationByUserAndMedicineIdx(User user, int medicineIdx) {
Medicine medicine = medicineRepository.findById(medicineIdx)
.orElseThrow(() -> BadRequestException.BAD_PARAMETER);
Notification notification = notificationRepository.findByUserAndMedicine(user, medicine)
.orElseThrow(() -> NotFoundException.DATA_NOT_FOUND);
return notification.toNotificationResponse();
}

// 사용자 관련 알림 목록 조회
public List<NotificationResponse> findNotificationByUser(User user) {
List<Notification> notifications = notificationRepository.findByUser(user);
return notifications.stream()
.map(Notification::toNotificationResponse)
.collect(Collectors.toList());
}

// 의약품에 해당하는 사용자 알림 삭제
@Transactional
public NotificationTimeResponse deleteNotification(User user, long notificationIdx) throws NotFoundException, ForbiddenException {
// 알림 데이터가 있는지 검사
Notification notification = notificationRepository.findById(notificationIdx)
.orElseThrow(() -> NotFoundException.DATA_NOT_FOUND);

// 사용자 본인이 데이터를 지우는 것인지 검사
if (!Objects.equals(notification.getUser().getUserIdx(), user.getUserIdx())) {
throw ForbiddenException.deleteForbidden;
}

List<NotificationTime> notificationTimes = notificationTimeRepository.findByNotification(notification); // 삭제할 알림과 관련된 시간 데이터 조회
notificationRepository.deleteById(notification.getNotificationIdx()); // 데이터 삭제

// 전달할 Response 생성
List<NotificationTimeDto> notificationTimeDtos = notificationTimes.stream()
.map(NotificationTime::toNotificationTimeDto)
.collect(Collectors.toList());

return NotificationTimeResponse.builder()
.notificationIdx(notificationIdx)
.notificationTimes(notificationTimeDtos)
.build();
}
}

0 comments on commit db96f89

Please sign in to comment.