Skip to content

Commit

Permalink
Merge pull request #29 from Modagbul/feat/alarm_minsu
Browse files Browse the repository at this point in the history
Feat/alarm : 알람 기능
  • Loading branch information
minsu20 authored Oct 9, 2023
2 parents 33b3056 + c830a04 commit 0c026ac
Show file tree
Hide file tree
Showing 26 changed files with 524 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,8 @@
import com.moing.backend.domain.board.application.mapper.BoardMapper;
import com.moing.backend.domain.board.domain.entity.Board;
import com.moing.backend.domain.board.domain.service.BoardSaveService;
import com.moing.backend.domain.boardRead.application.mapper.BoardReadMapper;
import com.moing.backend.domain.boardRead.application.service.CreateBoardReadUserCase;
import com.moing.backend.domain.boardRead.domain.entity.BoardRead;
import com.moing.backend.domain.boardRead.domain.service.BoardReadSaveService;
import com.moing.backend.domain.member.domain.entity.Member;
import com.moing.backend.domain.member.domain.service.MemberGetService;
import com.moing.backend.domain.team.application.service.CheckLeaderUserCase;
import com.moing.backend.domain.team.domain.entity.Team;
import com.moing.backend.domain.team.domain.service.TeamGetService;
import com.moing.backend.domain.teamMember.domain.entity.TeamMember;
import com.moing.backend.domain.teamMember.domain.service.TeamMemberGetService;
import com.moing.backend.global.config.security.dto.User;
import com.moing.backend.global.response.BaseServiceResponse;
import com.moing.backend.global.util.BaseService;
import lombok.RequiredArgsConstructor;
Expand All @@ -35,17 +25,22 @@ public class CreateBoardUserCase {
private final BoardMapper boardMapper;
private final CreateBoardReadUserCase createBoardReadUserCase;
private final BaseService baseService;
private final SendBoardAlarmUserCase sendBoardAlarmUserCase;

/**
* 게시글 생성
*/
public CreateBoardResponse createBoard(String socialId, Long teamId, CreateBoardRequest createBoardRequest) {
//1, 게시글 생성, 저장
BaseServiceResponse data=baseService.getCommonData(socialId, teamId);
boolean isLeader = checkLeaderUserCase.isTeamLeader(data.getMember(), data.getTeam());
boolean isLeader = checkLeaderUserCase.isTeamLeader(data.getMember(), data.getTeam()); //작성자 리더 여부
Board board=boardSaveService.saveBoard(boardMapper.toBoard(data.getMember(), data.getTeamMember(), data.getTeam(), createBoardRequest, isLeader));

//읽음 처리
//2. 읽음 처리 - 생성한 사람은 무조건 읽음
createBoardReadUserCase.createBoardRead(data.getTeam(), data.getMember(), board);

//3. 알림 보내기 - 공지인 경우
sendBoardAlarmUserCase.sendNewUploadAlarm(data, board);
return new CreateBoardResponse(board.getBoardId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ public class DeleteBoardUserCase {
* 게시글 삭제
*/
public void deleteBoard(String socialId, Long teamId, Long boardId){
//1. 게시글 조회
BaseBoardServiceResponse data= baseBoardService.getCommonData(socialId,teamId,boardId);
//2. 작성자인 경우
if (data.getTeamMember() == data.getBoard().getTeamMember()) {
//3. 삭제
boardDeleteService.deleteBoard(data.getBoard());
} else throw new NotAuthByBoardException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public class GetBoardUserCase {
* 게시글 상세 조회
*/
public GetBoardDetailResponse getBoardDetail(String socialId, Long teamId, Long boardId) {
// 1. 게시글 조회
BaseBoardServiceResponse data = baseBoardService.getCommonData(socialId, teamId, boardId);
//읽음 처리
// 2. 읽음 처리
createBoardReadUserCase.createBoardRead(data.getTeam(), data.getMember(), data.getBoard());
return boardMapper.toBoardDetail(data.getBoard(), data.getTeamMember() == data.getBoard().getTeamMember());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.moing.backend.domain.board.application.service;

import com.moing.backend.domain.board.domain.entity.Board;
import com.moing.backend.domain.member.domain.entity.Member;
import com.moing.backend.domain.team.domain.entity.Team;
import com.moing.backend.domain.teamMember.domain.service.TeamMemberGetService;
import com.moing.backend.global.config.fcm.dto.request.MultiRequest;
import com.moing.backend.global.config.fcm.service.FcmService;
import com.moing.backend.global.response.BaseServiceResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;

import static com.moing.backend.global.config.fcm.constant.NewUploadTitle.UPLOAD_NOTICE_NEW_TITLE;

@Service
@RequiredArgsConstructor
@Transactional
public class SendBoardAlarmUserCase {

private final TeamMemberGetService teamMemberGetService;
private final FcmService fcmService;

public void sendNewUploadAlarm(BaseServiceResponse baseServiceResponse, Board board) {
Member member = baseServiceResponse.getMember();
Team team = baseServiceResponse.getTeam();

if (board.isNotice() && member.isNewUploadPush()) {
String title = team.getName() + " " + UPLOAD_NOTICE_NEW_TITLE.getTitle();
String message = board.getTitle();
Optional<List<String>> fcmTokens = teamMemberGetService.getFcmTokensExceptMe(team.getTeamId(), member.getMemberId());
if (fcmTokens.isPresent() && !fcmTokens.get().isEmpty()) {
MultiRequest toMultiRequest = new MultiRequest(fcmTokens.get(), title, message);
fcmService.sendMultipleDevices(toMultiRequest);
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ public class UpdateBoardUserCase {
* 게시글 수정
*/
public UpdateBoardResponse updateBoard(String socialId, Long teamId, Long boardId, UpdateBoardRequest updateBoardRequest){
// 1. 게시글 조회
BaseBoardServiceResponse data= baseBoardService.getCommonData(socialId, teamId, boardId);
// 2. 게시글 작성자만
if (data.getTeamMember() == data.getBoard().getTeamMember()) {
// 3. 수정
data.getBoard().updateBoard(updateBoardRequest);
return new UpdateBoardResponse(data.getBoard().getBoardId());
} else throw new NotAuthByBoardException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ public class CreateBoardCommentUserCase {
private final BoardCommentMapper boardCommentMapper;
private final BaseBoardService baseBoardService;

/**
* 게시글 댓글 생성
*/
public CreateBoardCommentResponse createBoardComment(String socialId, Long teamId, Long boardId, CreateBoardCommentRequest createBoardCommentRequest) {
// 1. 게시글 댓글 생성
BaseBoardServiceResponse data = baseBoardService.getCommonData(socialId, teamId, boardId);
BoardComment boardComment = boardCommentSaveService.saveBoardComment(boardCommentMapper.toBoardComment(data.getTeamMember(), data.getBoard(), createBoardCommentRequest));
// 2. 게시글 댓글 개수 증가
data.getBoard().incrComNum();
return new CreateBoardCommentResponse(boardComment.getBoardCommentId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,19 @@ public class DeleteBoardCommentUserCase {
private final BoardCommentDeleteService boardCommentDeleteService;
private final BaseBoardService baseBoardService;

/**
* 게시글 댓글 삭제
*/

public void deleteBoardComment(String socialId, Long teamId, Long boardId, Long boardCommentId){
// 1. 게시글 댓글 조회
BaseBoardServiceResponse data = baseBoardService.getCommonData(socialId, teamId, boardId);
BoardComment boardComment=boardCommentGetService.getBoardComment(boardCommentId);
// 2. 게시글 댓글 작성자만
if (data.getTeamMember() == boardComment.getTeamMember()) {
// 3. 삭제
boardCommentDeleteService.deleteBoardComment(boardComment);
// 4. 댓글 개수 줄이기
data.getBoard().decrComNum();
} else throw new NotAuthByBoardCommentException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public class GetBoardCommentUserCase {
private final BoardCommentGetService boardCommentGetService;
private final BaseBoardService baseBoardService;

/**
* 게시글 댓글 전체 조회
*/
public GetBoardCommentResponse getBoardCommentAll(String socialId, Long teamId, Long boardId){
BaseBoardServiceResponse data = baseBoardService.getCommonData(socialId, teamId, boardId);
return boardCommentGetService.getBoardCommentAll(boardId, data.getTeamMember());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.moing.backend.domain.team.application.service;

import com.moing.backend.domain.teamMember.domain.service.TeamMemberGetService;
import com.moing.backend.global.config.fcm.dto.request.MultiRequest;
import com.moing.backend.global.config.fcm.service.FcmService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;

import static com.moing.backend.global.config.fcm.constant.NewUploadTitle.UPLOAD_NOTICE_NEW_TITLE;

@Service
@Transactional
@RequiredArgsConstructor
public class SendTeamAlarmUserCase {
private final TeamMemberGetService teamMemberGetService;
private final FcmService fcmService;

public void sendApprovalAlarm(Long teamId) {
//TODO: 승인, 반려 문구 constant로
String title = "소모임 승인 안내";
String message = "소모임이 승인되었습니다.";
sendAlarm(teamId, title, message);
}

public void sendRejectionAlarm(Long teamId) {
String title = "소모임 반려 안내";
String message = "소모임이 반려되었습니다.";
sendAlarm(teamId, title, message);
}

private void sendAlarm(Long teamId, String title, String message) {
Optional<List<String>> fcmTokens = teamMemberGetService.getFcmTokens(teamId);
if(fcmTokens.isPresent() && !fcmTokens.get().isEmpty()) {
MultiRequest toMultiRequest = new MultiRequest(fcmTokens.get(), title, message);
fcmService.sendMultipleDevices(toMultiRequest);
}
}
}

Original file line number Diff line number Diff line change
@@ -1,18 +1,45 @@
package com.moing.backend.domain.team.presentation;

import com.moing.backend.domain.team.application.service.CreateTeamUserCase;
import com.moing.backend.domain.team.application.service.SendTeamAlarmUserCase;
import com.moing.backend.global.response.SuccessResponse;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import static com.moing.backend.domain.team.presentation.constant.TeamResponseMessage.*;

@RestController
@AllArgsConstructor
@RequestMapping("/api/admin/team")
public class AdminTeamController {

//TODO 소모임 승인, 반려하기

private final CreateTeamUserCase createTeamService;
private final SendTeamAlarmUserCase sendTeamAlarmUserCase;

/**
* 소모임 승인 알림 보내기
* [POST] api/admin/team/approval/{teamId}
* 작성자 : 김민수
*/

@PostMapping("/approval/{teamId}")
public ResponseEntity<SuccessResponse> sendApproveAlarm(@PathVariable Long teamId) {
this.sendTeamAlarmUserCase.sendApprovalAlarm(teamId);
return ResponseEntity.ok(SuccessResponse.create(SEND_APPROVAL_ALARM_SUCCESS.getMessage()));
}

/**
* 소모임 반려 알림 보내기
* [POST] api/admin/team/rejection/{teamId}
* 작성자: 김민수
*/
@PostMapping("/rejection/{teamId}")
public ResponseEntity<SuccessResponse> sendRejectionAlarm(@PathVariable Long teamId){
this.sendTeamAlarmUserCase.sendRejectionAlarm(teamId);
return ResponseEntity.ok(SuccessResponse.create(SEND_REJECTION_ALARM_SUCCESS.getMessage()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public enum TeamResponseMessage {
GET_TEAM_SUCCESS("홈 화면에서 내 소모임을 모두 조회했습니다."),
SIGNIN_TEAM_SUCCESS("소모임에 가입하였습니다"),
DISBAND_TEAM_SUCCESS("[소모임장 권한] 소모임을 강제 종료했습니다."),
WITHDRAW_TEAM_SUCCESS("[소모임원 권한] 소모임을 탈퇴하였습니다");
WITHDRAW_TEAM_SUCCESS("[소모임원 권한] 소모임을 탈퇴하였습니다"),
SEND_APPROVAL_ALARM_SUCCESS("소모임 승인 알림을 보냈습니다."),
SEND_REJECTION_ALARM_SUCCESS("소모임 반려 알림을 보냈습니다.");
private final String message;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.moing.backend.domain.teamMember.domain.repository;

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

public interface TeamMemberCustomRepository {
List<Long> findMemberIdsByTeamId(Long teamId);
Optional<List<String>> findFcmTokensByTeamIdAndMemberId(Long teamId, Long memberId);
Optional<List<String>> findFcmTokensByTeamId(Long teamId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

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

import static com.moing.backend.domain.teamMember.domain.entity.QTeamMember.teamMember;

Expand All @@ -24,4 +25,23 @@ public List<Long> findMemberIdsByTeamId(Long teamId) {
.where(teamMember.team.isDeleted.eq(false))
.fetch();
}

@Override
public Optional<List<String>> findFcmTokensByTeamIdAndMemberId(Long teamId, Long memberId) {
return Optional.ofNullable(queryFactory.select(teamMember.member.fcmToken)
.from(teamMember)
.where(teamMember.team.teamId.eq(teamId)) //해당 소모임에 참여하고 있고
.where(teamMember.member.isNewUploadPush.eq(true)) //알림 설정 on해 있고
.where(teamMember.member.memberId.ne(memberId)) //지금 유저가 아닌 경우
.fetch());
}

@Override
public Optional<List<String>> findFcmTokensByTeamId(Long teamId) {
return Optional.ofNullable(queryFactory.select(teamMember.member.fcmToken)
.from(teamMember)
.where(teamMember.team.teamId.eq(teamId)) //해당 소모임에 참여하고 있고
.where(teamMember.member.isNewUploadPush.eq(true)) //알림 설정 on해 있고
.fetch());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import lombok.RequiredArgsConstructor;

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

@DomainService
@RequiredArgsConstructor
Expand All @@ -22,4 +23,13 @@ public List<Long> getTeamMemberIds(Long teamId){
public TeamMember getTeamMember(Member member, Team team){
return teamMemberRepository.findTeamMemberByTeamAndMember(team, member).orElseThrow(()-> new NotFoundByTeamIdException());
}

public Optional<List<String>> getFcmTokensExceptMe(Long teamId, Long memberId) {
return teamMemberRepository.findFcmTokensByTeamIdAndMemberId(teamId, memberId);
}

public Optional<List<String>> getFcmTokens(Long teamId) {
return teamMemberRepository.findFcmTokensByTeamId(teamId);
}

}
59 changes: 59 additions & 0 deletions src/main/java/com/moing/backend/global/config/fcm/FcmConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.moing.backend.global.config.fcm;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.messaging.FirebaseMessaging;
import com.moing.backend.global.config.fcm.exception.InitializeException;
import com.moing.backend.global.config.fcm.exception.MessagingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

@Configuration
@Slf4j
public class FcmConfig {


@Value("${firebase.config.path}")
private String firebaseConfigPath;

@Value("${firebase.config.projectId}")
private String projectId;

@Bean
public FirebaseApp firebaseApp() {
try {
FileInputStream serviceAccount = new FileInputStream(firebaseConfigPath);

FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setProjectId(projectId)
.build();

return FirebaseApp.initializeApp(options);
} catch (FileNotFoundException e) {
throw new IllegalStateException("파일을 찾을 수 없습니다." + e.getMessage());
} catch (IOException e) {
throw new InitializeException();
}
}

@Bean
public FirebaseMessaging firebaseMessaging() {
try {
return FirebaseMessaging.getInstance(firebaseApp());
} catch (IllegalStateException e) {
throw new MessagingException("FirebaseApp 초기화에 실패하였습니다." + e.getMessage());
} catch (NullPointerException e) {
throw new IllegalStateException("FirebaseApp을 불러오는데 실패하였습니다." + e.getMessage());
} catch (Exception e) {
throw new IllegalArgumentException("firebaseConfigPath를 읽어오는데 실패하였습니다." + e.getMessage());
}
}
}
Loading

0 comments on commit 0c026ac

Please sign in to comment.