Skip to content

Commit

Permalink
Merge pull request #6 from Modagbul/main
Browse files Browse the repository at this point in the history
소모임 승인, 반려 알림 히스토리 저장
  • Loading branch information
minsu20 authored Dec 9, 2023
2 parents 72ed28a + 6fa224f commit 9b78777
Show file tree
Hide file tree
Showing 23 changed files with 527 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.moing.bo.backend.domain.history.application.dto.response;

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

@Getter
@AllArgsConstructor
@Builder
public class GetAlarmCountResponse {

private String count;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.moing.bo.backend.domain.history.application.dto.response;

import com.moing.bo.backend.domain.history.domain.entity.AlarmType;
import com.querydsl.core.annotations.QueryProjection;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Getter
@AllArgsConstructor
@Builder
public class GetAlarmHistoryResponse {

private Long alarmHistoryId;

private AlarmType type;

private String path;

private String idInfo;

private String title;

private String body;

private String name;

private Boolean isRead;

private String createdDate;

@QueryProjection
public GetAlarmHistoryResponse(Long alarmHistoryId, AlarmType type, String path, String idInfo, String title, String body, String name, boolean isRead, LocalDateTime createdDate) {
this.alarmHistoryId = alarmHistoryId;
this.type = type;
this.path = path;
this.idInfo = idInfo;
this.title = title;
this.body = body;
this.name = name;
this.isRead = isRead;
this.createdDate = formatCreatedDate(createdDate);
}

public String formatCreatedDate(LocalDateTime createdDate) {
LocalDateTime currentDateTime = LocalDateTime.now();

LocalDateTime midnightOfCreatedDate = createdDate.toLocalDate().atStartOfDay();

if (currentDateTime.isAfter(midnightOfCreatedDate.plusDays(1))) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M월 d일");
return midnightOfCreatedDate.plusDays(1).format(dateFormatter);
} else {
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("a h:mm");
return currentDateTime.format(timeFormatter);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.moing.bo.backend.domain.history.application.dto.response;

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

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MemberIdAndToken {

private String fcmToken;
private Long memberId;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.moing.bo.backend.domain.history.application.mapper;

import com.moing.bo.backend.domain.history.application.dto.response.MemberIdAndToken;
import com.moing.bo.backend.domain.history.domain.entity.AlarmHistory;
import com.moing.bo.backend.domain.history.domain.entity.AlarmType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

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

@Component
@RequiredArgsConstructor
public class AlarmHistoryMapper {

public AlarmHistory toAlarmHistory(AlarmType type, String path, String idInfo, Long receiverId, String title, String body, String name) {
return AlarmHistory.builder()
.type(type)
.path(path)
.idInfo(idInfo)
.receiverId(receiverId)
.title(title)
.body(body)
.name(name)
.isRead(false)
.build();
}

public List<String> getFcmTokens(Optional<List<MemberIdAndToken>> memberIdAndTokens) {
return memberIdAndTokens.map(list -> list.stream()
.map(MemberIdAndToken::getFcmToken)
.collect(Collectors.toList()))
.orElse(Collections.emptyList());
}

public List<Long> getMemberIds(Optional<List<MemberIdAndToken>> memberIdAndTokens) {
return memberIdAndTokens.map(list -> list.stream()
.map(MemberIdAndToken::getMemberId)
.collect(Collectors.toList()))
.orElse(Collections.emptyList());
}

public List<AlarmHistory> getAlarmHistories(String idInfo, List<Long> memberIds, String title, String body, String teamName, AlarmType alarmType, String path) {
return memberIds.stream()
.map(memberId -> toAlarmHistory(alarmType, path, idInfo, memberId, title, body, teamName))
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.moing.bo.backend.domain.history.application.service;

import com.moing.bo.backend.domain.history.application.dto.response.MemberIdAndToken;
import com.moing.bo.backend.domain.history.application.mapper.AlarmHistoryMapper;
import com.moing.bo.backend.domain.history.domain.entity.AlarmHistory;
import com.moing.bo.backend.domain.history.domain.entity.AlarmType;
import com.moing.bo.backend.domain.history.domain.service.AlarmHistorySaveService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

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

@Service
@RequiredArgsConstructor
public class SaveMultiAlarmHistoryUseCase {

private final AlarmHistoryMapper alarmHistoryMapper;
private final AlarmHistorySaveService alarmHistorySaveService;

@Async
public void saveAlarmHistories(Optional<List<MemberIdAndToken>> memberIdAndTokens, String idInfo, String title, String body, String name, AlarmType alarmType, String path) {
List<Long> memberIds = alarmHistoryMapper.getMemberIds(memberIdAndTokens);
List<AlarmHistory> alarmHistories = alarmHistoryMapper.getAlarmHistories(idInfo, memberIds, title, body, name, alarmType, path);
alarmHistorySaveService.saveAlarmHistories(alarmHistories);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.moing.bo.backend.domain.history.application.service;

import com.moing.bo.backend.domain.history.application.mapper.AlarmHistoryMapper;
import com.moing.bo.backend.domain.history.domain.entity.AlarmHistory;
import com.moing.bo.backend.domain.history.domain.entity.AlarmType;
import com.moing.bo.backend.domain.history.domain.service.AlarmHistorySaveService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class SaveSingleAlarmHistoryUseCase {

private final AlarmHistoryMapper alarmHistoryMapper;
private final AlarmHistorySaveService alarmHistorySaveService;

@Async
public void saveAlarmHistory(Long memberId, String idInfo, String title, String body, String name, AlarmType alarmType, String path) {
AlarmHistory alarmHistory = alarmHistoryMapper.toAlarmHistory(alarmType, path, idInfo, memberId, title, body, name);
alarmHistorySaveService.saveAlarmHistory(alarmHistory);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.moing.bo.backend.domain.history.domain.entity;

import com.moing.bo.backend.global.entity.BaseTimeEntity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class AlarmHistory extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "alarm_history_id")
private Long id;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private AlarmType type;

@Column(nullable = false)
private String path;

private String idInfo;

private Long receiverId;

@Column(nullable = false)
private String title;

@Column(nullable = false)
private String body;

@Column(nullable = false)
private String name;

private boolean isRead;

public void readAlarmHistory() {
this.isRead = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.moing.bo.backend.domain.history.domain.entity;

import lombok.Getter;

@Getter
public enum AlarmType {
NEW_UPLOAD,
FIRE,
REMIND,
APPROVE_TEAM,
REJECT_TEAM
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.moing.bo.backend.domain.history.domain.entity;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum PagePath {

NOTICE_PATH("/post/detail"),

MISSION_PATH("/missions/prove"),

MISSION_ALL_PTAH("/missions"),

HOME_PATH("/home");


private final String value;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.moing.bo.backend.domain.history.domain.repository;

import com.moing.bo.backend.domain.history.application.dto.response.GetAlarmHistoryResponse;

import java.util.List;

public interface AlarmHistoryCustomRepository {

List<GetAlarmHistoryResponse> findAlarmHistoriesByMemberId(Long memberId);

String findUnreadAlarmCount(Long memberId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.moing.bo.backend.domain.history.domain.repository;

import com.moing.backend.domain.history.application.dto.response.GetAlarmHistoryResponse;
import com.moing.backend.domain.history.application.dto.response.QGetAlarmHistoryResponse;
import com.querydsl.jpa.impl.JPAQueryFactory;

import javax.persistence.EntityManager;
import java.util.List;

import static com.moing.backend.domain.history.domain.entity.QAlarmHistory.alarmHistory;

public class AlarmHistoryCustomRepositoryImpl implements AlarmHistoryCustomRepository {

private final JPAQueryFactory queryFactory;

public AlarmHistoryCustomRepositoryImpl(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}

@Override
public List<GetAlarmHistoryResponse> findAlarmHistoriesByMemberId(Long memberId) {
return queryFactory.select(new QGetAlarmHistoryResponse(alarmHistory.id,
alarmHistory.type,
alarmHistory.path,
alarmHistory.idInfo,
alarmHistory.title,
alarmHistory.body,
alarmHistory.name,
alarmHistory.isRead,
alarmHistory.createdDate))
.from(alarmHistory)
.where(alarmHistory.receiverId.eq(memberId))
.orderBy(alarmHistory.createdDate.desc())
.fetch();
}

@Override
public String findUnreadAlarmCount(Long memberId) {
Long count = queryFactory.select(alarmHistory.count())
.from(alarmHistory)
.where(alarmHistory.receiverId.eq(memberId)
.and(alarmHistory.isRead.eq(false)))
.fetchOne();

return count != null ? (count > 99 ? "99+" : count.toString()) : "0";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.moing.bo.backend.domain.history.domain.repository;

import com.moing.bo.backend.domain.history.domain.entity.AlarmHistory;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface AlarmHistoryRepository extends JpaRepository<AlarmHistory, Long>, AlarmHistoryCustomRepository {

Optional<AlarmHistory> findAlarmHistoryByIdAndReceiverId(Long id, Long receiverId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.moing.bo.backend.domain.history.domain.service;


import com.moing.bo.backend.domain.history.application.dto.response.GetAlarmHistoryResponse;
import com.moing.bo.backend.domain.history.domain.entity.AlarmHistory;
import com.moing.bo.backend.domain.history.domain.repository.AlarmHistoryRepository;
import com.moing.bo.backend.global.annotation.DomainService;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;

import java.util.List;

@DomainService
@Transactional
@RequiredArgsConstructor
public class AlarmHistoryGetService {

private final AlarmHistoryRepository alarmHistoryRepository;

public List<GetAlarmHistoryResponse> getAlarmHistories(Long memberId) {
return alarmHistoryRepository.findAlarmHistoriesByMemberId(memberId);
}

public AlarmHistory getAlarmHistory(Long alarmHistoryId, Long memberId) {
return alarmHistoryRepository.findAlarmHistoryByIdAndReceiverId(alarmHistoryId, memberId).orElseThrow(NotFoundAlarmHistoryException::new);
}

public String getUnreadAlarmCount(Long memberId) {
return alarmHistoryRepository.findUnreadAlarmCount(memberId);
}
}
Loading

0 comments on commit 9b78777

Please sign in to comment.