feat(notification): [API] 사용자 고유번호로 조회
This commit is contained in:
@@ -34,7 +34,6 @@ dependencies {
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
|
||||
/*implementation 'org.springframework.boot:spring-boot-starter-amqp'*/
|
||||
/*implementation 'org.springframework.boot:spring-boot-starter-security'*/
|
||||
/*implementation 'org.springframework.cloud:spring-cloud-starter-config'*/
|
||||
/*implementation 'org.springframework.kafka:spring-kafka'*/
|
||||
// https://mvnrepository.com/artifact/com.github.gavlyukovskiy/p6spy-spring-boot-starter
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.justpickup.notificationservice.domain.notification.dto;
|
||||
|
||||
import com.justpickup.notificationservice.domain.notification.entity.Notification;
|
||||
import com.justpickup.notificationservice.global.dto.Yn;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor(staticName = "of")
|
||||
public class FindNotificationDto {
|
||||
private Long id;
|
||||
private Long userId;
|
||||
private String message;
|
||||
private String title;
|
||||
private Yn readYn;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
public FindNotificationDto(Notification entity) {
|
||||
this.id = entity.getId();
|
||||
this.userId = entity.getUserId();
|
||||
this.message = entity.getMessage();
|
||||
this.title = entity.getTitle();
|
||||
this.readYn = entity.getReadYn();
|
||||
this.createdAt = entity.getCreatedAt();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.justpickup.notificationservice.domain.notification.entity;
|
||||
|
||||
import com.justpickup.notificationservice.global.dto.Yn;
|
||||
import com.justpickup.notificationservice.global.entity.BaseEntity;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
@@ -13,7 +14,7 @@ import javax.persistence.*;
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class Notification extends BaseEntity {
|
||||
|
||||
@Id @GeneratedValue
|
||||
@Id @GeneratedValue
|
||||
@Column(name = "notification_id")
|
||||
private Long id;
|
||||
|
||||
@@ -22,4 +23,28 @@ public class Notification extends BaseEntity {
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
private String title;
|
||||
|
||||
private String message;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Yn readYn;
|
||||
|
||||
// == 생성 메소드 == //
|
||||
public static Notification of(Long userId, String message, String title) {
|
||||
Notification notification = new Notification();
|
||||
notification.userId = userId;
|
||||
notification.message = message;
|
||||
notification.title = title;
|
||||
notification.readYn = Yn.N;
|
||||
return notification;
|
||||
}
|
||||
|
||||
public void modifyReadY() {
|
||||
this.readYn = Yn.Y;
|
||||
}
|
||||
|
||||
public void modifyReadN() {
|
||||
this.readYn = Yn.N;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.justpickup.notificationservice.domain.notification.repository;
|
||||
|
||||
import com.justpickup.notificationservice.domain.notification.entity.Notification;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface NotificationRepository extends JpaRepository<Notification, Long> {
|
||||
List<Notification> findByUserId(Long userId);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.justpickup.notificationservice.domain.notification.service;
|
||||
|
||||
import com.justpickup.notificationservice.domain.notification.dto.FindNotificationDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface NotificationService {
|
||||
List<FindNotificationDto> findNotificationByUserId(Long id);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.justpickup.notificationservice.domain.notification.service;
|
||||
|
||||
import com.justpickup.notificationservice.domain.notification.dto.FindNotificationDto;
|
||||
import com.justpickup.notificationservice.domain.notification.repository.NotificationRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class NotificationServiceImpl implements NotificationService {
|
||||
|
||||
private final NotificationRepository notificationRepository;
|
||||
|
||||
@Override
|
||||
public List<FindNotificationDto> findNotificationByUserId(Long userId) {
|
||||
return notificationRepository.findByUserId(userId)
|
||||
.stream()
|
||||
.map(FindNotificationDto::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.justpickup.notificationservice.domain.notification.web;
|
||||
|
||||
import com.justpickup.notificationservice.domain.notification.dto.FindNotificationDto;
|
||||
import com.justpickup.notificationservice.domain.notification.service.NotificationService;
|
||||
import com.justpickup.notificationservice.global.dto.Result;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/notification")
|
||||
public class NotificationController {
|
||||
|
||||
private final NotificationService notificationService;
|
||||
|
||||
@GetMapping("")
|
||||
public ResponseEntity<Result> getNotificationByUserId(@RequestHeader("user-id") String userIdHeader) {
|
||||
Long userId = Long.valueOf(userIdHeader);
|
||||
|
||||
List<FindNotificationDto> notifications = notificationService.findNotificationByUserId(userId);
|
||||
|
||||
GetNotificationResponse response = new GetNotificationResponse(notifications);
|
||||
return ResponseEntity.ok(Result.createSuccessResult(response));
|
||||
}
|
||||
|
||||
@Data @NoArgsConstructor
|
||||
static class GetNotificationResponse {
|
||||
private List<_Notification> notifications;
|
||||
|
||||
public GetNotificationResponse(List<FindNotificationDto> notifications) {
|
||||
this.notifications =
|
||||
notifications.stream().map(_Notification::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Data
|
||||
static class _Notification {
|
||||
private Long id;
|
||||
private String message;
|
||||
private String title;
|
||||
private boolean read;
|
||||
private String time;
|
||||
|
||||
public _Notification(FindNotificationDto dto) {
|
||||
this.id = dto.getId();
|
||||
this.message = dto.getMessage();
|
||||
this.title = dto.getTitle();
|
||||
this.read = dto.getReadYn().isY();
|
||||
this.time = dto.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.justpickup.notificationservice.global;
|
||||
|
||||
import com.justpickup.notificationservice.domain.notification.entity.Notification;
|
||||
import com.justpickup.notificationservice.domain.notification.repository.NotificationRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SqlCommandLineRunner implements CommandLineRunner {
|
||||
|
||||
private final NotificationRepository notificationRepository;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void run(String... args) throws Exception {
|
||||
for (long userId = 1; userId < 10; userId++) {
|
||||
List<Notification> notifications = new ArrayList<>();
|
||||
for (int notification = 1; notification <= 5; notification++) {
|
||||
Notification of = Notification.of(userId, notification + "번 매장의 주문이 수락되었습니다.", "주문이 수락되었어요");
|
||||
notifications.add(of);
|
||||
}
|
||||
for (int notification = 6; notification <= 10; notification++) {
|
||||
Notification of = Notification.of(userId, notification + "번 매장의 주문이 수락되었습니다.", "주문이 수락되었어요");
|
||||
of.modifyReadY();
|
||||
notifications.add(of);
|
||||
}
|
||||
notificationRepository.saveAll(notifications);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.justpickup.notificationservice.global.dto;
|
||||
|
||||
public enum Code {
|
||||
SUCCESS, ERROR
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.justpickup.notificationservice.global.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data @NoArgsConstructor
|
||||
public class Result<T> {
|
||||
private Code code;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
@Builder
|
||||
public Result(Code code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static Result createErrorResult(String message) {
|
||||
return Result.builder()
|
||||
.code(Code.ERROR)
|
||||
.message(message)
|
||||
.data(null)
|
||||
.build();
|
||||
}
|
||||
|
||||
// 해당 <T> 는 클래스의 T와 다름
|
||||
public static <T> Result createSuccessResult(T data) {
|
||||
return Result.builder()
|
||||
.code(Code.SUCCESS)
|
||||
.message("")
|
||||
.data(data)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Result success(){
|
||||
return Result.builder()
|
||||
.code(Code.SUCCESS)
|
||||
.message("성공")
|
||||
.data(null)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.justpickup.notificationservice.global.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum Yn {
|
||||
Y(true), N(false);
|
||||
|
||||
private boolean y;
|
||||
|
||||
Yn(boolean y) {
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,21 @@
|
||||
package com.justpickup.notificationservice.global.entity;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
public abstract class BaseEntity {
|
||||
|
||||
@CreationTimestamp
|
||||
private LocalDateTime createdAt;
|
||||
private Long createdBy;
|
||||
@UpdateTimestamp
|
||||
private LocalDateTime lastModifiedAt;
|
||||
private Long lastModifiedBy;
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.justpickup.notificationservice.global.exception;
|
||||
|
||||
import com.justpickup.notificationservice.global.dto.Result;
|
||||
import lombok.Getter;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
@Getter
|
||||
public class CustomException extends RuntimeException {
|
||||
|
||||
private HttpStatus status;
|
||||
private Result errorResult;
|
||||
|
||||
protected CustomException(HttpStatus status, String message) {
|
||||
this.status = status;
|
||||
this.errorResult = Result.createErrorResult(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.justpickup.notificationservice.global.exception;
|
||||
|
||||
import com.justpickup.notificationservice.global.dto.Result;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
@ExceptionHandler(CustomException.class)
|
||||
public ResponseEntity customExceptionHandler(CustomException ce) {
|
||||
HttpStatus status = ce.getStatus();
|
||||
Result errorResult = ce.getErrorResult();
|
||||
|
||||
return ResponseEntity.status(status)
|
||||
.body(errorResult);
|
||||
}
|
||||
|
||||
@ExceptionHandler(BindException.class)
|
||||
public ResponseEntity bindExceptionHandler(BindException exception) {
|
||||
return getValidationErrorBody(exception);
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException exception) {
|
||||
return getValidationErrorBody(exception);
|
||||
}
|
||||
|
||||
private ResponseEntity getValidationErrorBody(BindException exception) {
|
||||
BindingResult bindingResult = exception.getBindingResult();
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
bindingResult.getFieldErrors()
|
||||
.forEach(fieldError -> {
|
||||
builder.append("[");
|
||||
builder.append(fieldError.getField());
|
||||
builder.append("](은)는 ");
|
||||
builder.append(fieldError.getDefaultMessage());
|
||||
builder.append(" 입력된 값: [");
|
||||
builder.append(fieldError.getRejectedValue());
|
||||
builder.append("]");
|
||||
});
|
||||
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(Result.createErrorResult(builder.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user