diff --git a/src/main/java/org/slams/server/chat/service/ChatContentsService.java b/src/main/java/org/slams/server/chat/service/ChatContentsService.java index d8a9857e..2d4de10c 100644 --- a/src/main/java/org/slams/server/chat/service/ChatContentsService.java +++ b/src/main/java/org/slams/server/chat/service/ChatContentsService.java @@ -79,7 +79,7 @@ public ChatContentsResponse saveChatLoudSpeakerContent(LoudspeakerNotificationRe .orElseThrow(() -> new UserNotFoundException("해당 작성자는 존재하지 않는 사용자입니다.")); ChatLoudSpeakerContent chatLoudSpeakerContent = chatLoudSpeakerContentRepository.save( - ChatLoudSpeakerContent.of(request.getStartTime()) + ChatLoudSpeakerContent.of(request.getStartTime().getHour()) ); ChatContents chatContents = ChatContents.createLoudspeakerContent( ChatContentType.LOUDSPEAKER, diff --git a/src/main/java/org/slams/server/common/dto/BaseDto.java b/src/main/java/org/slams/server/common/dto/BaseDto.java new file mode 100644 index 00000000..0a5f9caa --- /dev/null +++ b/src/main/java/org/slams/server/common/dto/BaseDto.java @@ -0,0 +1,11 @@ +package org.slams.server.common.dto; + +import java.time.LocalDateTime; + +/** + * Created by yunyun on 2022/01/24. + */ +public class BaseDto { + private LocalDateTime createdAt; + private LocalDateTime updatedAt; +} diff --git a/src/main/java/org/slams/server/notification/dto/response/CourtInfo.java b/src/main/java/org/slams/server/common/dto/Court.java similarity index 64% rename from src/main/java/org/slams/server/notification/dto/response/CourtInfo.java rename to src/main/java/org/slams/server/common/dto/Court.java index 330b2746..5e10bc6f 100644 --- a/src/main/java/org/slams/server/notification/dto/response/CourtInfo.java +++ b/src/main/java/org/slams/server/common/dto/Court.java @@ -1,18 +1,20 @@ -package org.slams.server.notification.dto.response; +package org.slams.server.common.dto; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Builder; import lombok.Getter; import org.slams.server.court.entity.Texture; +import org.slams.server.notification.common.ValidationMessage; import static com.google.common.base.Preconditions.checkArgument; import static org.apache.commons.lang3.StringUtils.isNotEmpty; /** - * Created by yunyun on 2021/12/14. + * Created by yunyun on 2022/01/24. */ - @Getter -public class CourtInfo { +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Court { private final Long id; private final String name; private final double latitude; @@ -22,7 +24,7 @@ public class CourtInfo { private final Texture texture; @Builder - public CourtInfo( + public Court( Long id, String name, double latitude, @@ -31,9 +33,9 @@ public CourtInfo( int basketCount, Texture texture ){ - checkArgument(id != null, "userId는 null을 허용하지 않습니다."); - checkArgument(isNotEmpty(name), "농구장는 빈값을 허용하지 않습니다."); - checkArgument(basketCount >= 0, "골대 개수는 0이상만 가능합니다."); + checkArgument(id != null, ValidationMessage.NOTNULL_ID); + checkArgument(isNotEmpty(name), ValidationMessage.NOT_EMPTY_NAME); + checkArgument(basketCount > 0, ValidationMessage.MORE_THAN_ONE_BASKET_COUNT); this.id = id; this.name = name; diff --git a/src/main/java/org/slams/server/common/dto/Follow.java b/src/main/java/org/slams/server/common/dto/Follow.java new file mode 100644 index 00000000..584d7b97 --- /dev/null +++ b/src/main/java/org/slams/server/common/dto/Follow.java @@ -0,0 +1,24 @@ +package org.slams.server.common.dto; + +/** + * Created by yunyun on 2022/01/24. + */ + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Builder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Follow extends BaseDto{ + private User creator; + private User receiver; + + @Builder + public Follow( + User creator, + User receiver + ){ + this.creator = creator; + this.receiver = receiver; + } + +} diff --git a/src/main/java/org/slams/server/common/dto/User.java b/src/main/java/org/slams/server/common/dto/User.java new file mode 100644 index 00000000..ce0fec9d --- /dev/null +++ b/src/main/java/org/slams/server/common/dto/User.java @@ -0,0 +1,47 @@ +package org.slams.server.common.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Builder; +import org.slams.server.notification.common.ValidationMessage; +import org.slams.server.user.entity.Position; +import org.slams.server.user.entity.Proficiency; + +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; + +/** + * Created by yunyun on 2022/01/24. + */ + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class User extends BaseDto{ + + private Long id; + private String nickname; + private String profileImage; + private String description; + private Proficiency proficiency; + private List positions; + + @Builder + public User( + Long id, + String nickname, + String profileImage, + String description, + Proficiency proficiency, + List positions + ){ + checkArgument(id != null, ValidationMessage.NOTNULL_ID); + checkArgument(isNotEmpty(nickname), ValidationMessage.NOT_EMPTY_NICKNAME); + + this.id = id; + this.nickname = nickname; + this.profileImage = profileImage; + this.description = description; + this.positions = positions; + + } +} diff --git a/src/main/java/org/slams/server/common/query/DummyCourtQuery.java b/src/main/java/org/slams/server/common/query/DummyCourtQuery.java index 8a20152d..2ad0751c 100644 --- a/src/main/java/org/slams/server/common/query/DummyCourtQuery.java +++ b/src/main/java/org/slams/server/common/query/DummyCourtQuery.java @@ -126,11 +126,11 @@ public void insertExcel() throws IOException, InvalidFormatException { } public void insertNotificationDummy(Long userId, int dataSize){ - LoudspeakerNotificationRequest request = new LoudspeakerNotificationRequest(1L, LocalDateTime.now().getHour(), 1L); + LoudspeakerNotificationRequest request = new LoudspeakerNotificationRequest(1L, LocalDateTime.now(), LocalDateTime.now().plusHours(2L), 1L); int index = 0; while (index < dataSize){ - notificationService.saveForLoudSpeakerNotification(request, userId); + notificationService.saveForLoudSpeakerNotification(request, userId, userId); index = index + 1; } diff --git a/src/main/java/org/slams/server/notification/common/ValidationMessage.java b/src/main/java/org/slams/server/notification/common/ValidationMessage.java new file mode 100644 index 00000000..14a09c19 --- /dev/null +++ b/src/main/java/org/slams/server/notification/common/ValidationMessage.java @@ -0,0 +1,37 @@ +package org.slams.server.notification.common; + +/** + * Created by yunyun on 2022/01/24. + */ +public enum ValidationMessage { + // common + NOTNULL_ID("Id는 NULL 을 허용하지 않습니다."), + + // user + NOTNULL_USERID("UserId는 NULL 을 허용하지 않습니다."), + NOTNULL_USER("User 정보는 NULL 을 허용하지 않습니다."), + NOT_EMPTY_NICKNAME("nickname은 빈값을 허용하지 않습니다."), + + // notification + NOTNULL_NOTIFICATION_TYPE("Notification Type 정보는 NULL 을 허용하지 않습니다."), + + // court + NOTNULL_COURT("경기장 정보는 NULL 을 허용하지 않습니다."), + NOTNULL_START_TIME("경기 시작 시간의 정보는 NULL 을 허용하지 않습니다."), + NOTNULL_END_TIME("경기 끝 시간의 정보는 NULL 을 허용하지 않습니다."), + NOT_EMPTY_NAME("경기장 이름은 빈값을 허용하지 않습니다."), + + MORE_THAN_ONE_BASKET_COUNT("골대의 개수는 1개 이상이어야 합니다.") + ; + + + private String message; + + ValidationMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} \ No newline at end of file diff --git a/src/main/java/org/slams/server/notification/controller/NotificationWebSocketController.java b/src/main/java/org/slams/server/notification/controller/NotificationWebSocketController.java index d6a1b00e..b35cd019 100644 --- a/src/main/java/org/slams/server/notification/controller/NotificationWebSocketController.java +++ b/src/main/java/org/slams/server/notification/controller/NotificationWebSocketController.java @@ -105,21 +105,21 @@ public void saveLoudSpeakerAndThenSending( LoudspeakerNotificationRequest request, SimpMessageHeaderAccessor headerAccessor ){ - Long userId = websocketUtil.findTokenFromHeader(headerAccessor); - List bookerIds = reservationRepository.findBeakerIdByCourtId(request.getCourtId()); + Long sendId = websocketUtil.findTokenFromHeader(headerAccessor); + List receiverIds = reservationRepository.findBeakerIdByCourtId(request.getCourtId()); - for (Long bookId : bookerIds){ - if (bookId.equals(userId)){ + for (Long receiverId : receiverIds){ + if (receiverId.equals(sendId)){ continue; } - NotificationResponse notification = notificationService.saveForLoudSpeakerNotification(request, bookId); + NotificationResponse notification = notificationService.saveForLoudSpeakerNotification(request, receiverId, sendId); websocket.convertAndSend( - String.format("/user/%d/notification", bookId), + String.format("/user/%d/notification", receiverId), notification ); } - ChatContentsResponse chatContentsResponse = chatContentsService.saveChatLoudSpeakerContent(request, userId); + ChatContentsResponse chatContentsResponse = chatContentsService.saveChatLoudSpeakerContent(request, sendId); websocket.convertAndSend( String.format("/user/%d/chat", request.getCourtId()), chatContentsResponse diff --git a/src/main/java/org/slams/server/notification/convertor/NotificationConvertor.java b/src/main/java/org/slams/server/notification/convertor/NotificationConvertor.java index ff645d33..c817fd7c 100644 --- a/src/main/java/org/slams/server/notification/convertor/NotificationConvertor.java +++ b/src/main/java/org/slams/server/notification/convertor/NotificationConvertor.java @@ -1,17 +1,15 @@ package org.slams.server.notification.convertor; +import org.slams.server.common.dto.Court; +import org.slams.server.common.dto.Follow; +import org.slams.server.common.dto.User; import org.slams.server.notification.Exception.InvalidNotificationTypeException; -import org.slams.server.notification.dto.response.CourtInfo; -import org.slams.server.notification.dto.response.FollowerInfo; -import org.slams.server.notification.dto.response.LoudspeakerInfo; +import org.slams.server.notification.dto.response.Loudspeaker; import org.slams.server.notification.dto.response.NotificationResponse; -import org.slams.server.notification.entity.FollowNotification; -import org.slams.server.notification.entity.LoudSpeakerNotification; -import org.slams.server.notification.entity.NotificationIndex; +import org.slams.server.notification.entity.Notification; import org.slams.server.notification.entity.NotificationType; import org.springframework.stereotype.Component; -import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @@ -22,31 +20,33 @@ @Component public class NotificationConvertor { - public List toDtoList(List notifications){ - /** null 유효성 검사 추가 **/ - // followNotificationList + public List toDtoList(List notifications){ + + if (notifications.isEmpty()){ + return Collections.emptyList(); + } return notifications.stream() .map(v -> toDto(v)) .collect(Collectors.toList()); } - public NotificationResponse toDto(NotificationIndex notification){ - if (notification.getNotificationType().equals(NotificationType.LOUDSPEAKER)){ + public NotificationResponse toDto(Notification notification){ + if (notification.getType().equals(NotificationType.LOUDSPEAKER)){ return NotificationResponse.createForLoudspeakerNotification( notification.getId(), NotificationType.LOUDSPEAKER, - LoudspeakerInfo.builder() - .courtInfo(CourtInfo.builder() - .id(notification.getLoudSpeakerNotification().getCourt().getId()) - .name(notification.getLoudSpeakerNotification().getCourt().getName()) - .texture(notification.getLoudSpeakerNotification().getCourt().getTexture()) - .longitude(notification.getLoudSpeakerNotification().getCourt().getLongitude()) - .latitude(notification.getLoudSpeakerNotification().getCourt().getLatitude()) - .image(notification.getLoudSpeakerNotification().getCourt().getImage()) - .basketCount(notification.getLoudSpeakerNotification().getCourt().getBasketCount()) + Loudspeaker.builder() + .court(Court.builder() + .id(notification.getLoudSpeaker().getCourt().getId()) + .name(notification.getLoudSpeaker().getCourt().getName()) + .texture(notification.getLoudSpeaker().getCourt().getTexture()) + .longitude(notification.getLoudSpeaker().getCourt().getLongitude()) + .latitude(notification.getLoudSpeaker().getCourt().getLatitude()) + .image(notification.getLoudSpeaker().getCourt().getImage()) + .basketCount(notification.getLoudSpeaker().getCourt().getBasketCount()) .build()) - .startTime(notification.getLoudSpeakerNotification().getStartTime()) + .startTime(notification.getLoudSpeaker().getStartTime()) .build(), notification.isRead(), notification.isClicked(), @@ -55,14 +55,18 @@ public NotificationResponse toDto(NotificationIndex notification){ ); } - if (notification.getNotificationType().equals(NotificationType.FOLLOWING)){ + if (notification.getType().equals(NotificationType.FOLLOW)){ return NotificationResponse.createForFollowNotification( notification.getId(), - NotificationType.FOLLOWING, - FollowerInfo.builder() - .userId(notification.getFollowNotification().getCreator().getId()) - .userImage(notification.getFollowNotification().getCreator().getProfileImage()) - .userNickname(notification.getFollowNotification().getCreator().getNickname()) + NotificationType.FOLLOW, + Follow.builder() + .creator( + User.builder() + .id(notification.getFollow().getFollower().getId()) + .profileImage(notification.getFollow().getFollower().getProfileImage()) + .nickname(notification.getFollow().getFollower().getNickname()) + .build() + ) .build(), notification.isRead(), notification.isClicked(), @@ -73,71 +77,6 @@ public NotificationResponse toDto(NotificationIndex notification){ throw new InvalidNotificationTypeException("존재하지 않는 공지 타입입니다."); } -// -// public List toDtoListForLoudspeakerNotification(List loudSpeakerNotificationList){ -// /** null 유효성 검사 추가 **/ -// // followNotificationList -// -// return loudSpeakerNotificationList.stream() -// .map(v -> toDtoForLoudNotification(v)) -// .collect(Collectors.toList()); -// } -// -// public NotificationResponse toDtoForFollowNotification(FollowNotification followNotification){ -// /** null 유효성 검사 추가 **/ -// //followNotification.getNotification(); -// //followNotification.getFollower(); -// -// return NotificationResponse.createForFollowNotification( -// followNotification.getNotificationType(), -// FollowerInfo.builder() -// .userId(followNotification.getCreator().getId()) -// .userImage(followNotification.getCreator().getProfileImage()) -// .userNickname(followNotification.getCreator().getNickname()) -// .build(), -// followNotification.isRead(), -// followNotification.isClicked(), -// followNotification.getCreatedAt(), -// followNotification.getUpdateAt() -// ); -// } -// -// public NotificationResponse toDtoForLoudNotification(LoudSpeakerNotification loudSpeakerNotification){ -// -// return NotificationResponse.createForLoudspeakerNotification( -// loudSpeakerNotification.getNotificationType(), -// LoudspeakerInfo.builder() -// .courtInfo(CourtInfo.builder() -// .id(loudSpeakerNotification.getCourt().getId()) -// .basketCount(loudSpeakerNotification.getCourt().getBasketCount()) -// .image(loudSpeakerNotification.getCourt().getImage()) -// .latitude(loudSpeakerNotification.getCourt().getLatitude()) -// .longitude(loudSpeakerNotification.getCourt().getLongitude()) -// .name(loudSpeakerNotification.getCourt().getName()) -// .texture(loudSpeakerNotification.getCourt().getTexture()) -// .build() -// ) -// .startTime(loudSpeakerNotification.getStartTime()) -// .build(), -// loudSpeakerNotification.isRead(), -// loudSpeakerNotification.isClicked(), -// loudSpeakerNotification.getCreatedAt(), -// loudSpeakerNotification.getUpdateAt() -// ); -// } -// -// /** created로 정렬 **/ -// public List mergeListForFollowNotificationAndLoudspeakerNotification( -// List followNotificationList, -// List loudSpeakerNotificationList -// ){ -// followNotificationList.addAll(loudSpeakerNotificationList); -// if(followNotificationList.size() > 0){ -// Collections.sort(followNotificationList); -// return followNotificationList; -// } -// return Collections.emptyList(); -// } } diff --git a/src/main/java/org/slams/server/notification/dto/request/LoudspeakerNotificationRequest.java b/src/main/java/org/slams/server/notification/dto/request/LoudspeakerNotificationRequest.java index 2d0485d6..4943fb16 100644 --- a/src/main/java/org/slams/server/notification/dto/request/LoudspeakerNotificationRequest.java +++ b/src/main/java/org/slams/server/notification/dto/request/LoudspeakerNotificationRequest.java @@ -3,6 +3,8 @@ import lombok.Getter; import lombok.Setter; +import java.time.LocalDateTime; + /** * Created by yunyun on 2021/12/14. */ @@ -10,15 +12,17 @@ @Getter public class LoudspeakerNotificationRequest { private final Long courtId; - private final int startTime; + private final LocalDateTime startTime; + private final LocalDateTime endTime; private final Long reservationId; - public LoudspeakerNotificationRequest(Long courtId, int startTime, Long reservationId){ + public LoudspeakerNotificationRequest(Long courtId, LocalDateTime startTime, LocalDateTime endTime, Long reservationId){ /** websocket으로 runtimeException을 낼 경우, 세션 끊어지는가? * 혹시 모르니까, 객체에 값을 넣기 전에 유효성 검사를 하자. */ this.courtId = courtId; this.startTime = startTime; + this.endTime = endTime; this.reservationId = reservationId; } diff --git a/src/main/java/org/slams/server/notification/dto/response/FollowerInfo.java b/src/main/java/org/slams/server/notification/dto/response/FollowerInfo.java deleted file mode 100644 index 2a1b3fa5..00000000 --- a/src/main/java/org/slams/server/notification/dto/response/FollowerInfo.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.slams.server.notification.dto.response; - -import lombok.Builder; -import lombok.Getter; - -import static com.google.common.base.Preconditions.checkArgument; -import static org.apache.commons.lang3.StringUtils.isNotEmpty; - -/** - * Created by yunyun on 2021/12/14. - */ - -@Getter -public class FollowerInfo { - private final Long userId; - private final String userNickname; - private final String userImage; - - @Builder - public FollowerInfo( - Long userId, - String userNickname, - String userImage - ){ - checkArgument(userId != null, "userId는 null을 허용하지 않습니다."); - checkArgument(isNotEmpty(userNickname), "userNickname는 빈값을 허용하지 않습니다."); - - this.userId = userId; - this.userNickname = userNickname; - this.userImage = userImage; - } -} diff --git a/src/main/java/org/slams/server/notification/dto/response/Loudspeaker.java b/src/main/java/org/slams/server/notification/dto/response/Loudspeaker.java new file mode 100644 index 00000000..9cb38f9f --- /dev/null +++ b/src/main/java/org/slams/server/notification/dto/response/Loudspeaker.java @@ -0,0 +1,43 @@ +package org.slams.server.notification.dto.response; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Builder; +import org.slams.server.common.dto.Court; +import org.slams.server.common.dto.User; +import org.slams.server.notification.common.ValidationMessage; + +import java.time.LocalDateTime; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Created by yunyun on 2022/01/24. + */ + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Loudspeaker { + private Long id; + private User user; + private Court court; + private LocalDateTime startTime; + + @Builder + public Loudspeaker( + Long id, + User user, + Court court, + LocalDateTime startTime + ){ + checkArgument(id != null, ValidationMessage.NOTNULL_ID); + checkArgument(user != null, ValidationMessage.NOTNULL_USER); + checkArgument(court != null, ValidationMessage.NOTNULL_COURT); + checkArgument(startTime != null, ValidationMessage.NOTNULL_START_TIME); + + this.id = id; + this.user = user; + this.court = court; + this.startTime = startTime; + } + + +} diff --git a/src/main/java/org/slams/server/notification/dto/response/LoudspeakerInfo.java b/src/main/java/org/slams/server/notification/dto/response/LoudspeakerInfo.java deleted file mode 100644 index e8fbe55c..00000000 --- a/src/main/java/org/slams/server/notification/dto/response/LoudspeakerInfo.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.slams.server.notification.dto.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Getter; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Created by yunyun on 2021/12/14. - */ - -@Getter -public class LoudspeakerInfo { - - @JsonProperty("courtInfo") - private final CourtInfo courtInfo; - private final int startTime; - - @Builder - public LoudspeakerInfo( - CourtInfo courtInfo, - int startTime) { - checkArgument(courtInfo != null, "courtInfo는 null을 허용하지 않습니다."); - checkArgument(0<= startTime && startTime<25, "경기 시작시간은 0이상 24시이하만 가능합니다."); - - this.courtInfo = courtInfo; - this.startTime = startTime; - } -} diff --git a/src/main/java/org/slams/server/notification/dto/response/NotificationResponse.java b/src/main/java/org/slams/server/notification/dto/response/NotificationResponse.java index 54b16438..52259ae2 100644 --- a/src/main/java/org/slams/server/notification/dto/response/NotificationResponse.java +++ b/src/main/java/org/slams/server/notification/dto/response/NotificationResponse.java @@ -1,7 +1,8 @@ package org.slams.server.notification.dto.response; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Getter; +import org.slams.server.common.dto.Follow; import org.slams.server.notification.entity.NotificationType; import java.time.LocalDateTime; @@ -13,17 +14,16 @@ */ @Getter +@JsonInclude(JsonInclude.Include.NON_NULL) public class NotificationResponse { private final Long id; private final NotificationType type; - @JsonProperty("followerInfo") - private final FollowerInfo followerInfo; + private final Follow follow; - @JsonProperty("loudspeakerInfo") - private final LoudspeakerInfo loudspeakerInfo; + private final Loudspeaker loudspeaker; private final Boolean isRead; @@ -36,8 +36,8 @@ public class NotificationResponse { private NotificationResponse( Long id, NotificationType type, - FollowerInfo followerInfo, - LoudspeakerInfo loudspeakerInfo, + Follow follow, + Loudspeaker loudspeaker, boolean isRead, boolean isClicked, LocalDateTime createdAt, @@ -45,8 +45,8 @@ private NotificationResponse( ){ this.id = id; this.type = type; - this.followerInfo = followerInfo; - this.loudspeakerInfo = loudspeakerInfo; + this.follow = follow; + this.loudspeaker = loudspeaker; this.isRead = isRead; this.isClicked = isClicked; this.createdAt = createdAt; @@ -56,25 +56,25 @@ private NotificationResponse( public static NotificationResponse createForFollowNotification( Long id, NotificationType type, - FollowerInfo followerInfo, + Follow follow, boolean isRead, boolean isClicked, LocalDateTime createdAt, LocalDateTime updatedAt ){ - return new NotificationResponse(id, type, followerInfo, null, isRead, isClicked, createdAt, updatedAt); + return new NotificationResponse(id, type, follow, null, isRead, isClicked, createdAt, updatedAt); } public static NotificationResponse createForLoudspeakerNotification( Long id, NotificationType type, - LoudspeakerInfo loudspeakerInfo, + Loudspeaker loudspeaker, boolean isRead, boolean isClicked, LocalDateTime createdAt, LocalDateTime updatedAt ){ - return new NotificationResponse(id, type, null, loudspeakerInfo, isRead, isClicked, createdAt, updatedAt); + return new NotificationResponse(id, type, null, loudspeaker, isRead, isClicked, createdAt, updatedAt); } } diff --git a/src/main/java/org/slams/server/notification/entity/FollowNotification.java b/src/main/java/org/slams/server/notification/entity/FollowNotification.java deleted file mode 100644 index 54d5fef5..00000000 --- a/src/main/java/org/slams/server/notification/entity/FollowNotification.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.slams.server.notification.entity; - -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.slams.server.common.BaseEntity; -import org.slams.server.user.entity.User; - -import javax.persistence.*; - -import java.util.UUID; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Created by yunyun on 2021/12/14. - */ - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Table(name = "follow_notification") -public class FollowNotification { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="id") - private Long id; - - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "creator_id", nullable = false, referencedColumnName = "id") - private User creator; - - @Column - private Long userId; - - @Column - private Long checkCreatorId ; - - private FollowNotification(User creator, Long userId, Long checkCreatorId){ - checkArgument(creator != null, "creator 정보는 null을 허용하지 않습니다."); - checkArgument(userId != null, "userId 정보는 null을 허용하지 않습니다."); - - this.creator = creator; - this.userId = userId; - this.checkCreatorId = checkCreatorId; - } - - @Builder - public FollowNotification(Long id, User creator, Long userId, Long checkCreatorId){ - checkArgument(id != null, "id는 null을 허용하지 않습니다."); - checkArgument(creator != null, "creator 정보는 null을 허용하지 않습니다."); - checkArgument(userId != null, "userId 정보는 null을 허용하지 않습니다."); - - this.id = id; - this.creator = creator; - this.userId = userId; - this.checkCreatorId = checkCreatorId; - } - - public static FollowNotification of(User creator, Long userId, Long checkCreatorId){ - return new FollowNotification(creator, userId, checkCreatorId); - } - -} diff --git a/src/main/java/org/slams/server/notification/entity/LoudSpeaker.java b/src/main/java/org/slams/server/notification/entity/LoudSpeaker.java new file mode 100644 index 00000000..3a33b2f5 --- /dev/null +++ b/src/main/java/org/slams/server/notification/entity/LoudSpeaker.java @@ -0,0 +1,89 @@ +package org.slams.server.notification.entity; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.slams.server.common.BaseEntity; +import org.slams.server.court.entity.Court; +import org.slams.server.notification.common.ValidationMessage; +import org.slams.server.user.entity.User; + +import javax.persistence.*; + +import java.time.LocalDateTime; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Created by yunyun on 2021/12/14. + */ + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +@Table(name = "loudspeaker") +public class LoudSpeaker extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id") + private Long id; + + @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JoinColumn(name = "user_id", referencedColumnName = "id") + private User user; + + @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JoinColumn(name = "court_id", referencedColumnName = "id") + private Court court; + + @Column + private LocalDateTime startTime; + + @Column + private LocalDateTime endTime; + + public LoudSpeaker ( + Long id, + User user, + Court court, + LocalDateTime startTime, + LocalDateTime endTime + ){ + checkArgument(id != null, ValidationMessage.NOTNULL_ID); + checkArgument(user != null, ValidationMessage.NOTNULL_USER); + checkArgument(court != null, ValidationMessage.NOTNULL_COURT); + checkArgument(startTime != null, ValidationMessage.NOTNULL_START_TIME); + checkArgument(endTime != null, ValidationMessage.NOTNULL_END_TIME); + this.id = id; + this.user = user; + this.court = court; + this.startTime = startTime; + this.endTime = endTime; + } + + private LoudSpeaker( + User user, + Court court, + LocalDateTime startTime, + LocalDateTime endTime + ){ + checkArgument(user != null, ValidationMessage.NOTNULL_USER); + checkArgument(court != null, ValidationMessage.NOTNULL_COURT); + checkArgument(startTime != null, ValidationMessage.NOTNULL_START_TIME); + checkArgument(endTime != null, ValidationMessage.NOTNULL_END_TIME); + this.user = user; + this.court = court; + this.startTime = startTime; + this.endTime = endTime; + } + + public static LoudSpeaker of( + User user, + Court court, + LocalDateTime startTime, + LocalDateTime endTime + ){ + return new LoudSpeaker(user, court, startTime, endTime); + } +} diff --git a/src/main/java/org/slams/server/notification/entity/LoudSpeakerNotification.java b/src/main/java/org/slams/server/notification/entity/LoudSpeakerNotification.java deleted file mode 100644 index 7696f823..00000000 --- a/src/main/java/org/slams/server/notification/entity/LoudSpeakerNotification.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.slams.server.notification.entity; - -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.slams.server.common.BaseEntity; -import org.slams.server.court.entity.Court; - -import javax.persistence.*; -import java.util.List; -import java.util.UUID; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Created by yunyun on 2021/12/14. - */ - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Table(name = "loudspeaker_notification") -public class LoudSpeakerNotification { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="id") - private Long id; - - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "court_id", nullable = false, referencedColumnName = "id") - private Court court; - - @Column - private int startTime; - - @Column - private Long userId; - - private LoudSpeakerNotification(Court court, int startTime, Long userId){ - checkArgument(court != null, "court 정보는 null을 허용하지 않습니다."); - checkArgument(0<= startTime && startTime<25, "경기 시작시간은 0이상 24시이하만 가능합니다."); - checkArgument(userId != null, "userId 정보는 null을 허용하지 않습니다."); - - this.court = court; - this.startTime = startTime; - this.userId = userId; - } - - @Builder - public LoudSpeakerNotification(Long id, Court court, int startTime, Long userId){ - checkArgument(id != null, "id는 null을 허용하지 않습니다."); - checkArgument(court != null, "court 정보는 null을 허용하지 않습니다."); - checkArgument(userId != null, "userId 정보는 null을 허용하지 않습니다."); - checkArgument(0<= startTime && startTime<25, "경기 시작시간은 0이상 24시이하만 가능합니다."); - - this.id = id; - this.court = court; - this.startTime = startTime; - this.userId = userId; - } - - public static LoudSpeakerNotification of(Court court, int startTime, Long userId){ - return new LoudSpeakerNotification(court, startTime, userId); - } - - -} diff --git a/src/main/java/org/slams/server/notification/entity/Notification.java b/src/main/java/org/slams/server/notification/entity/Notification.java new file mode 100644 index 00000000..b254e114 --- /dev/null +++ b/src/main/java/org/slams/server/notification/entity/Notification.java @@ -0,0 +1,92 @@ +package org.slams.server.notification.entity; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.slams.server.common.BaseEntity; +import org.slams.server.follow.entity.Follow; +import org.slams.server.notification.common.ValidationMessage; + +import javax.persistence.*; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Created by yunyun on 2021/12/03. + */ + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +@Table(name = "notification") +public class Notification extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id") + private Long id; + + @Column(nullable = false) + private Long userId; + + @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JoinColumn(name = "follow_id", referencedColumnName = "id") + private Follow follow; + + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "loudspeaker_id", referencedColumnName = "id") + private LoudSpeaker loudSpeaker; + + @Enumerated(EnumType.STRING) + private NotificationType type; + + @Column(columnDefinition = "boolean default false") + private boolean isRead; + + @Column(columnDefinition = "boolean default false") + private boolean isClicked; + + public Notification(Long id, + Long userId, + Follow follow, + LoudSpeaker loudSpeaker, + NotificationType type, + boolean isRead, + boolean isClicked){ + checkArgument(id != null, ValidationMessage.NOTNULL_ID); + checkArgument(userId != null, ValidationMessage.NOTNULL_USERID); + checkArgument(type != null, ValidationMessage.NOTNULL_NOTIFICATION_TYPE); + this.id = id; + this.userId = userId; + this.follow = follow; + this.loudSpeaker = loudSpeaker; + this.isRead = isRead; + this.isClicked = isClicked; + } + + private Notification( + Long userId, + Follow follow, + LoudSpeaker loudSpeaker, + NotificationType type + ){ + checkArgument(id != null, ValidationMessage.NOTNULL_ID); + checkArgument(userId != null, ValidationMessage.NOTNULL_USERID); + checkArgument(type != null, ValidationMessage.NOTNULL_NOTIFICATION_TYPE); + this.userId = userId; + this.follow = follow; + this.loudSpeaker = loudSpeaker; + this.type = type; + } + + + public static Notification createLoudSpeaker(Long userId, LoudSpeaker loudSpeaker){ + return new Notification(userId, null, loudSpeaker, NotificationType.LOUDSPEAKER); + + } + + public static Notification createFollow(Long userId, Follow follow){ + return new Notification(userId, follow, null, NotificationType.FOLLOW); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/slams/server/notification/entity/NotificationIndex.java b/src/main/java/org/slams/server/notification/entity/NotificationIndex.java deleted file mode 100644 index 3a5d7b82..00000000 --- a/src/main/java/org/slams/server/notification/entity/NotificationIndex.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.slams.server.notification.entity; - -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.slams.server.common.BaseEntity; - -import javax.persistence.*; - -import java.util.UUID; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Created by yunyun on 2021/12/03. - */ - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Table(name = "notification_index") -public class NotificationIndex extends BaseEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="id") - private Long id; - - @Column(nullable = false) - private Long userId; - - @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) - @JoinColumn(name = "follow_noti_id", referencedColumnName = "id") - private FollowNotification followNotification; - - @OneToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "loudspeaker_noti_id", referencedColumnName = "id") - private LoudSpeakerNotification loudSpeakerNotification; - - @Enumerated(EnumType.STRING) - private NotificationType notificationType; - - @Column(columnDefinition = "boolean default false") - private boolean isRead; - - @Column(columnDefinition = "boolean default false") - private boolean isClicked; - - @Column - private Long checkCreatorId ; - - private NotificationIndex(Long userId, FollowNotification followNotification, Long checkCreatorId){ - checkArgument(userId != null, "userId는 null을 허용하지 않습니다."); - this.userId = userId; - this.notificationType = NotificationType.FOLLOWING; - this.followNotification = followNotification; - this.checkCreatorId = checkCreatorId; - } - - private NotificationIndex(Long userId, LoudSpeakerNotification loudSpeakerNotification){ - checkArgument(userId != null, "userId는 null을 허용하지 않습니다."); - this.userId = userId; - this.notificationType = NotificationType.LOUDSPEAKER; - this.loudSpeakerNotification = loudSpeakerNotification; - } - - public NotificationIndex(Long id, Long userId, FollowNotification followNotification, - NotificationType notificationType, boolean isRead, boolean isClicked, Long checkCreatorId){ - checkArgument(id != null, "id는 null을 허용하지 않습니다."); - checkArgument(userId != null, "userId는 null을 허용하지 않습니다."); - checkArgument(notificationType != null, "notificationType 정보는 null을 허용하지 않습니다."); - this.id = id; - this.userId = userId; - this.followNotification = followNotification; - this.notificationType = notificationType; - this.isRead = isRead; - this.isClicked = isClicked; - this.checkCreatorId = checkCreatorId; - } - - public NotificationIndex(Long id, Long userId, LoudSpeakerNotification loudSpeakerNotification, - NotificationType notificationType, boolean isRead, boolean isClicked){ - checkArgument(id != null, "id는 null을 허용하지 않습니다."); - checkArgument(userId != null, "userId는 null을 허용하지 않습니다."); - checkArgument(notificationType != null, "notificationType 정보는 null을 허용하지 않습니다."); - this.id = id; - this.userId = userId; - this.loudSpeakerNotification = loudSpeakerNotification; - this.notificationType = notificationType; - this.isRead = isRead; - this.isClicked = isClicked; - } - - public static NotificationIndex createLoudSpeakerNoti(Long userId, LoudSpeakerNotification loudSpeakerNotification){ - return new NotificationIndex(userId, loudSpeakerNotification); - - } - - public static NotificationIndex createFollowNoti(Long userId, FollowNotification followNotification, Long checkCreatorId){ - return new NotificationIndex(userId, followNotification, checkCreatorId); - } - - -} diff --git a/src/main/java/org/slams/server/notification/entity/NotificationType.java b/src/main/java/org/slams/server/notification/entity/NotificationType.java index 7b8c4083..133a0c1c 100644 --- a/src/main/java/org/slams/server/notification/entity/NotificationType.java +++ b/src/main/java/org/slams/server/notification/entity/NotificationType.java @@ -4,6 +4,6 @@ * Created by yunyun on 2021/12/03. */ public enum NotificationType { - FOLLOWING, + FOLLOW, LOUDSPEAKER; } diff --git a/src/main/java/org/slams/server/notification/repository/FollowNotificationRepository.java b/src/main/java/org/slams/server/notification/repository/FollowNotificationRepository.java deleted file mode 100644 index 3ddacbe2..00000000 --- a/src/main/java/org/slams/server/notification/repository/FollowNotificationRepository.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.slams.server.notification.repository; - -import org.slams.server.notification.entity.FollowNotification; -import org.slams.server.notification.entity.LoudSpeakerNotification; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.transaction.annotation.Transactional; - -import javax.persistence.CascadeType; -import java.lang.annotation.Native; -import java.util.List; -import java.util.Optional; - -/** - * Created by yunyun on 2021/12/15. - */ -public interface FollowNotificationRepository extends JpaRepository { - - - @Query("SELECT f.id FROM FollowNotification f WHERE f.creator.id=:userId AND f.userId=:receiverId") - List findByReceiverIdAndUserId( - @Param("receiverId") Long receiverId, - @Param("userId") Long userId - ); - - @Query("SELECT f FROM FollowNotification f WHERE f.creator.id=:userId AND f.userId=:receiverId") - Optional findOneByReceiverIdAndUserId( - @Param("receiverId") Long receiverId, - @Param("userId") Long userId - ); - - @Transactional - @Modifying - @Query("DELETE FROM FollowNotification n WHERE n.checkCreatorId=:userId AND n.userId=:receiverId") - void deleteByReceiverIdAndUserId( - @Param("receiverId") Long receiverId, - @Param("userId") Long userId - ); - -} diff --git a/src/main/java/org/slams/server/notification/repository/LoudSpeakerNotificationRepository.java b/src/main/java/org/slams/server/notification/repository/LoudSpeakerNotificationRepository.java deleted file mode 100644 index d965013b..00000000 --- a/src/main/java/org/slams/server/notification/repository/LoudSpeakerNotificationRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.slams.server.notification.repository; - -import org.slams.server.notification.entity.FollowNotification; -import org.slams.server.notification.entity.LoudSpeakerNotification; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; - -/** - * Created by yunyun on 2021/12/15. - */ -public interface LoudSpeakerNotificationRepository extends JpaRepository { - -} diff --git a/src/main/java/org/slams/server/notification/repository/LoudspeakerRepository.java b/src/main/java/org/slams/server/notification/repository/LoudspeakerRepository.java new file mode 100644 index 00000000..5d4d91db --- /dev/null +++ b/src/main/java/org/slams/server/notification/repository/LoudspeakerRepository.java @@ -0,0 +1,11 @@ +package org.slams.server.notification.repository; + +import org.slams.server.notification.entity.LoudSpeaker; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * Created by yunyun on 2021/12/15. + */ +public interface LoudspeakerRepository extends JpaRepository { + +} diff --git a/src/main/java/org/slams/server/notification/repository/NotificationIndexRepository.java b/src/main/java/org/slams/server/notification/repository/NotificationIndexRepository.java deleted file mode 100644 index 02fcd592..00000000 --- a/src/main/java/org/slams/server/notification/repository/NotificationIndexRepository.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.slams.server.notification.repository; - -import org.slams.server.notification.entity.NotificationIndex; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * Created by yunyun on 2021/12/08. - */ - -public interface NotificationIndexRepository extends JpaRepository { - - @Query("SELECT a.id FROM NotificationIndex a WHERE a.userId =:userId AND a.id < :lastId ORDER BY a.createdAt desc") - List findIdByUserLessThanAlarmIdByCreated( - @Param("userId") Long userId, - @Param("lastId") Long lastId, - Pageable pageable - ); - - @Query("SELECT a.id FROM NotificationIndex a WHERE a.userId =:userId ORDER BY a.createdAt desc") - List findIdByUserByCreated( - @Param("userId") Long userId, - Pageable pageable - ); - - @Query("SELECT a FROM NotificationIndex a WHERE a.userId =:userId AND a.id < :lastId ORDER BY a.createdAt desc") - List findAllByUserLessThanAlarmIdByCreated( - @Param("userId") Long userId, - @Param("lastId") Long lastId, - Pageable pageable - ); - - @Query("SELECT a FROM NotificationIndex a WHERE a.userId =:userId ORDER BY a.createdAt desc") - List findAllByUserByCreated( - @Param("userId") Long userId, - Pageable pageable - ); - - @Transactional - @Modifying() - @Query("UPDATE NotificationIndex n SET n.isClicked=:status WHERE n.userId=:userId") - Integer updateIsClicked( - @Param("userId") Long userId, - @Param("status") boolean status - ); - - @Transactional - @Modifying() - @Query("UPDATE NotificationIndex n SET n.isRead=:status WHERE n.userId=:userId") - Integer updateIsRead( - @Param("userId") Long userId, - @Param("status") boolean status - ); - - @Transactional - @Modifying - @Query("DELETE FROM NotificationIndex n WHERE n.checkCreatorId=:userId AND n.userId=:receiverId") - void deleteByReceiverIdAndUserId( - @Param("receiverId") Long receiverId, - @Param("userId") Long userId - ); - - @Query("SELECT n FROM NotificationIndex n WHERE n.checkCreatorId=:creatorId AND n.userId=:receiverId") - NotificationIndex findByReceiverIdAndCreatorId( - @Param("receiverId") Long receiverId, - @Param("creatorId") Long creatorId - ); - -} diff --git a/src/main/java/org/slams/server/notification/repository/NotificationRepository.java b/src/main/java/org/slams/server/notification/repository/NotificationRepository.java new file mode 100644 index 00000000..fa0fb458 --- /dev/null +++ b/src/main/java/org/slams/server/notification/repository/NotificationRepository.java @@ -0,0 +1,76 @@ +package org.slams.server.notification.repository; + +import org.slams.server.notification.entity.Notification; +import org.slams.server.notification.entity.NotificationType; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * Created by yunyun on 2021/12/08. + */ + +public interface NotificationRepository extends JpaRepository { + + @Query("SELECT a.id FROM Notification a WHERE a.userId =:userId AND a.id < :lastId ORDER BY a.createdAt desc") + List findIdByUserLessThanAlarmIdByCreated( + @Param("userId") Long userId, + @Param("lastId") Long lastId, + Pageable pageable + ); + + @Query("SELECT a.id FROM Notification a WHERE a.userId =:userId ORDER BY a.createdAt desc") + List findIdByUserByCreated( + @Param("userId") Long userId, + Pageable pageable + ); + + @Query("SELECT a FROM Notification a WHERE a.userId =:userId AND a.id < :lastId ORDER BY a.createdAt desc") + List findAllByUserLessThanAlarmIdByCreated( + @Param("userId") Long userId, + @Param("lastId") Long lastId, + Pageable pageable + ); + + @Query("SELECT a FROM Notification a WHERE a.userId =:userId ORDER BY a.createdAt desc") + List findAllByUserByCreated( + @Param("userId") Long userId, + Pageable pageable + ); + + @Transactional + @Modifying() + @Query("UPDATE Notification n SET n.isClicked=:status WHERE n.userId=:userId") + Integer updateIsClicked( + @Param("userId") Long userId, + @Param("status") boolean status + ); + + @Transactional + @Modifying() + @Query("UPDATE Notification n SET n.isRead=:status WHERE n.userId=:userId") + Integer updateIsRead( + @Param("userId") Long userId, + @Param("status") boolean status + ); + + @Transactional + @Modifying + @Query("DELETE FROM Notification n WHERE n.follow.follower.id=:sendId AND n.userId=:receiverId AND n.type='FOLLOW'") + void deleteByReceiverIdAndSendIdOnFollowNotification( + @Param("receiverId") Long receiverId, + @Param("sendId") Long sendId + ); + +// @Query("SELECT n FROM Notification n WHERE n.checkCreatorId=:creatorId AND n.userId=:receiverId") +// Notification findByReceiverIdAndCreatorId( +// @Param("receiverId") Long receiverId, +// @Param("creatorId") Long creatorId +// ); + +} diff --git a/src/main/java/org/slams/server/notification/service/NotificationService.java b/src/main/java/org/slams/server/notification/service/NotificationService.java index e416e73a..bf2b749b 100644 --- a/src/main/java/org/slams/server/notification/service/NotificationService.java +++ b/src/main/java/org/slams/server/notification/service/NotificationService.java @@ -5,21 +5,18 @@ import org.slams.server.court.entity.Court; import org.slams.server.court.exception.CourtNotFoundException; import org.slams.server.court.repository.CourtRepository; -import org.slams.server.notification.Exception.InvalidCourtStartTimeException; -import org.slams.server.notification.Exception.NotificationNotFoundException; +import org.slams.server.follow.entity.Follow; +import org.slams.server.follow.exception.FollowNotFoundException; +import org.slams.server.follow.repository.FollowRepository; import org.slams.server.notification.convertor.NotificationConvertor; import org.slams.server.notification.dto.request.FollowNotificationRequest; import org.slams.server.notification.dto.request.LoudspeakerNotificationRequest; import org.slams.server.notification.dto.request.UpdateIsClickedStatusRequest; import org.slams.server.notification.dto.response.NotificationResponse; -import org.slams.server.notification.entity.FollowNotification; -import org.slams.server.notification.entity.LoudSpeakerNotification; -import org.slams.server.notification.entity.NotificationIndex; -import org.slams.server.notification.entity.NotificationType; -import org.slams.server.notification.repository.FollowNotificationRepository; -import org.slams.server.notification.repository.LoudSpeakerNotificationRepository; -import org.slams.server.notification.repository.NotificationIndexRepository; -import org.slams.server.reservation.exception.ReservationNotFoundException; +import org.slams.server.notification.entity.LoudSpeaker; +import org.slams.server.notification.entity.Notification; +import org.slams.server.notification.repository.LoudspeakerRepository; +import org.slams.server.notification.repository.NotificationRepository; import org.slams.server.reservation.repository.ReservationRepository; import org.slams.server.user.entity.User; import org.slams.server.user.exception.UserNotFoundException; @@ -40,55 +37,63 @@ @RequiredArgsConstructor public class NotificationService { - private final NotificationIndexRepository notificationRepository; - private final FollowNotificationRepository followNotificationRepository; - private final LoudSpeakerNotificationRepository loudSpeakerNotificationRepository; + private final NotificationRepository notificationRepository; + private final LoudspeakerRepository loudSpeakerNotificationRepository; private final UserRepository userRepository; + private final FollowRepository followRepository; private final NotificationConvertor notificationConvertor; private final CourtRepository courtRepository; private final ReservationRepository reservationRepository; - public NotificationResponse saveForLoudSpeakerNotification(LoudspeakerNotificationRequest request, Long userId){ + public NotificationResponse saveForLoudSpeakerNotification(LoudspeakerNotificationRequest request, Long receiverId, Long sendId){ /** 예약 도메인 관련 **/ /** 테스트를 위해 주석처리 var reservation = reservationRepository.findById(request.getReservationId()) .orElseThrow(() -> new ReservationNotFoundException("존재하지 않은 예약입니다.")); **/ - if(LocalDateTime.now().getHour() - request.getStartTime() < 0 && LocalDateTime.now().getHour() - request.getStartTime() <= 1) { - throw new InvalidCourtStartTimeException("경기 시작 1시간 이전에만 확성기 기능을 사용하실 수 있습니다."); - } + + /** start time 과 end time 보낼지, start time과 time block으로 보낼지 결정해야 함. 전자라면, start time < end time 요효성 검사해야함 **/ Court court = courtRepository .findById(request.getCourtId()) .orElseThrow(() -> new CourtNotFoundException("해당 코트가 존재하지 않습니다.")); + User sender = userRepository.findById(sendId) + .orElseThrow(() -> new UserNotFoundException("공지를 보내는 이는 존재하지 않는 사용지 입니다.")); - LoudSpeakerNotification loudSpeakerNotification = LoudSpeakerNotification.of( + LoudSpeaker loudSpeakerNotification = LoudSpeaker.of( + sender, court, request.getStartTime(), - userId + request.getEndTime() ); return notificationConvertor.toDto(notificationRepository.save( - NotificationIndex.createLoudSpeakerNoti(userId, loudSpeakerNotificationRepository.save(loudSpeakerNotification)) + Notification.createLoudSpeaker(receiverId, loudSpeakerNotificationRepository.save(loudSpeakerNotification)) )); } public NotificationResponse saveForFollowNotification(FollowNotificationRequest request, Long userId){ - Optional followNotificationForChecked = followNotificationRepository.findOneByReceiverIdAndUserId(request.getReceiverId(), userId); User creator = userRepository .findById(userId) .orElseThrow(() -> new UserNotFoundException("팔로우한 해당 사용자는 존재하지 않는 사용자 입니다.")); - FollowNotification followNotification = FollowNotification.of( - creator, - request.getReceiverId(), - userId - ); + User receiver = userRepository + .findById(request.getReceiverId()) + .orElseThrow(() -> new UserNotFoundException("팔로우 당한 사용자는 존재하지 않는 사용자 입니다.")); + + /** follow service 에서 follow 저장하는 로직의 리턴 값을 저장된 객체로 요청해보기. 지금 리턴값은 void 임 + * 불필요하게 user 정보를 들고 와서 저장하게 됨. + * **/ + + + Follow follow = followRepository + .findByFollowerAndFollowing(creator, receiver) + .orElseThrow(() -> new FollowNotFoundException("존재하지 않는 follow 정보 입니다.")); return notificationConvertor.toDto(notificationRepository.save( - NotificationIndex.createFollowNoti(request.getReceiverId(), followNotificationRepository.save(followNotification), userId) + Notification.createFollow(request.getReceiverId(), follow) )); } @@ -97,7 +102,7 @@ public List findAllByUserId(Long userId, CursorPageRequest return notificationConvertor.toDtoList(cursorPageForFindAllByUserId(userId, cursorRequest)); } - public List cursorPageForFindAllByUserId(Long userId, CursorPageRequest cursorRequest){ + public List cursorPageForFindAllByUserId(Long userId, CursorPageRequest cursorRequest){ PageRequest pageable = PageRequest.of(0, cursorRequest.getSize()); return cursorRequest.getIsFirst() ? notificationRepository.findAllByUserByCreated(userId, pageable) : @@ -134,12 +139,11 @@ public void updateIsClickedStatus(UpdateIsClickedStatusRequest request, Long use @Transactional public void deleteFollowNotification(FollowNotificationRequest request, Long userId){ - notificationRepository.deleteByReceiverIdAndUserId(request.getReceiverId(), userId); - followNotificationRepository.deleteByReceiverIdAndUserId(request.getReceiverId(), userId); + notificationRepository.deleteByReceiverIdAndSendIdOnFollowNotification(request.getReceiverId(), userId); } - public NotificationIndex findByReceiverIdCreatorId(Long receiverId, Long creatorId){ - return notificationRepository.findByReceiverIdAndCreatorId(receiverId, creatorId); - } +// public Notification findByReceiverIdCreatorId(Long receiverId, Long creatorId){ +// return notificationRepository.findByReceiverIdAndCreatorId(receiverId, creatorId); +// } } diff --git a/src/main/java/org/slams/server/user/service/UserService.java b/src/main/java/org/slams/server/user/service/UserService.java index 92682eb7..b2860dc5 100644 --- a/src/main/java/org/slams/server/user/service/UserService.java +++ b/src/main/java/org/slams/server/user/service/UserService.java @@ -2,18 +2,11 @@ import lombok.RequiredArgsConstructor; import org.slams.server.common.api.CursorPageRequest; -import org.slams.server.common.api.CursorPageResponse; import org.slams.server.common.utils.AwsS3Uploader; -import org.slams.server.court.entity.Texture; import org.slams.server.favorite.repository.FavoriteRepository; import org.slams.server.follow.repository.FollowRepository; -import org.slams.server.notification.dto.response.CourtInfo; -import org.slams.server.notification.dto.response.FollowerInfo; -import org.slams.server.notification.dto.response.LoudspeakerInfo; import org.slams.server.notification.dto.response.NotificationResponse; -import org.slams.server.notification.entity.NotificationIndex; -import org.slams.server.notification.entity.NotificationType; import org.slams.server.notification.service.NotificationService; import org.slams.server.user.dto.request.ExtraUserInfoRequest; import org.slams.server.user.dto.response.*; @@ -21,22 +14,15 @@ import org.slams.server.user.exception.SameUserException; import org.slams.server.user.exception.UserNotFoundException; import org.slams.server.user.repository.UserRepository; -import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import javax.management.Notification; import java.io.IOException; import java.text.MessageFormat; -import java.time.LocalDateTime; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import static org.slams.server.notification.entity.NotificationType.FOLLOWING; -import static org.slams.server.notification.entity.NotificationType.LOUDSPEAKER; - @Transactional(readOnly = true) @Service @RequiredArgsConstructor diff --git a/src/test/java/org/slams/server/chat/service/ChatContentsServiceTest.java b/src/test/java/org/slams/server/chat/service/ChatContentsServiceTest.java index 10bd7aab..b73da5e8 100644 --- a/src/test/java/org/slams/server/chat/service/ChatContentsServiceTest.java +++ b/src/test/java/org/slams/server/chat/service/ChatContentsServiceTest.java @@ -139,7 +139,8 @@ void saveChatLoudSpeakerContent(){ //Given LoudspeakerNotificationRequest request = new LoudspeakerNotificationRequest( court.getId(), - 10, + LocalDateTime.now(), + LocalDateTime.now().plusHours(2L), reservation.getId() ); Long userId = user.getId(); diff --git a/src/test/java/org/slams/server/notification/controller/NotificationControllerTest.java b/src/test/java/org/slams/server/notification/controller/NotificationControllerTest.java index 5f5f67fb..a2adb65c 100644 --- a/src/test/java/org/slams/server/notification/controller/NotificationControllerTest.java +++ b/src/test/java/org/slams/server/notification/controller/NotificationControllerTest.java @@ -3,9 +3,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.*; import org.slams.server.court.repository.CourtRepository; -import org.slams.server.notification.repository.FollowNotificationRepository; -import org.slams.server.notification.repository.LoudSpeakerNotificationRepository; -import org.slams.server.notification.repository.NotificationIndexRepository; +import org.slams.server.notification.repository.LoudspeakerRepository; +import org.slams.server.notification.repository.NotificationRepository; import org.slams.server.notification.service.NotificationService; import org.slams.server.user.repository.UserRepository; import org.slams.server.user.service.UserService; @@ -46,7 +45,7 @@ class NotificationControllerTest { ObjectMapper objectMapper; @Autowired - private NotificationIndexRepository notificationIndexRepository; + private NotificationRepository notificationIndexRepository; @Autowired private NotificationService notificationService; @@ -58,10 +57,7 @@ class NotificationControllerTest { private UserRepository userRepository; @Autowired - private FollowNotificationRepository followNotificationRepository; - - @Autowired - private LoudSpeakerNotificationRepository loudSpeakerNotificationRepository; + private LoudspeakerRepository loudSpeakerNotificationRepository; @Autowired private UserService userService; diff --git a/src/test/java/org/slams/server/user/controller/UserControllerTest.java b/src/test/java/org/slams/server/user/controller/UserControllerTest.java index 1744a277..3cef4ec8 100644 --- a/src/test/java/org/slams/server/user/controller/UserControllerTest.java +++ b/src/test/java/org/slams/server/user/controller/UserControllerTest.java @@ -5,10 +5,6 @@ import org.junit.jupiter.api.Test; import org.slams.server.court.entity.Court; import org.slams.server.court.entity.Texture; -import org.slams.server.notification.dto.response.CourtInfo; -import org.slams.server.notification.dto.response.FollowerInfo; -import org.slams.server.notification.dto.response.LoudspeakerInfo; -import org.slams.server.notification.dto.response.NotificationResponse; import org.slams.server.user.dto.request.ExtraUserInfoRequest; import org.slams.server.user.dto.response.*; import org.slams.server.user.entity.Position; @@ -27,7 +23,6 @@ import org.springframework.core.io.support.ResourcePropertySource; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -35,14 +30,12 @@ import java.io.IOException; import java.time.LocalDateTime; import java.util.Arrays; -import java.util.Collections; import java.util.List; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; -import static org.slams.server.notification.entity.NotificationType.FOLLOWING; -import static org.slams.server.notification.entity.NotificationType.LOUDSPEAKER; +import static org.slams.server.notification.entity.NotificationType.FOLLOW; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;