Skip to content

Commit

Permalink
[FEATURE] 자유게시판 사용자 차단 구현 완료 (#156)
Browse files Browse the repository at this point in the history
* ✨ BoardBlock 엔티티 구현

* ✨ 차단한 사용자의 게시글 조회 시 안보이게 구현

* ✨ 차단 해제 기능 구현(#150)

* ✨ 전체 게시물 조회 & 내 게시물 전체 조회에서 likeCount, commentCount 적용되게 수정(#150)

* ✨ 코드 최종 검사(#150)

* ✨ 댓글 생성 쪽 수정완료(#150)

* ✨ Controller에 내가 차단한 사용자 조회 제목 및 설명 추가(#150)

* ✨ 특정 사용자의 게시글 조회 기능 수정 및 merge 전 코드 최종점검(#150)

* ✨ 특정 사용자의 게시글 조회 기능 수정 및 merge 전 코드 최종점검(#150)

* ✨ 특정 사용자의 게시글 조회 기능 수정 및 merge 전 코드 최종점검(#150)
  • Loading branch information
600gramSik authored Jul 22, 2024
1 parent a577b5c commit 11aec2f
Show file tree
Hide file tree
Showing 16 changed files with 317 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.capstone.BnagFer.domain.board.dto.request.CreateCommentRequestDto;
import com.capstone.BnagFer.domain.board.dto.request.UpdateCommentRequestDto;
import com.capstone.BnagFer.domain.board.dto.response.*;
import com.capstone.BnagFer.domain.board.service.BoardBlockQueryService;
import com.capstone.BnagFer.domain.board.service.BoardBlockService;
import com.capstone.BnagFer.domain.board.service.BoardQueryService;
import com.capstone.BnagFer.domain.board.service.BoardService;
import com.capstone.BnagFer.global.annotation.LoginUser;
Expand All @@ -30,26 +32,29 @@
@RequestMapping("/board")
public class BoardController {
private final BoardService boardService;
private final BoardBlockService boardBlockService;
private final BoardQueryService boardQueryService;
private final BoardBlockQueryService boardBlockQueryService;


@GetMapping //게시판 리스트 조회
@Operation(summary = "게시판 목록 조회", description = "전체 게시판 목록을 조회합니다. 페이징 적용, 생성 날짜 기준 내림차순 정렬.")
public ApiResponse<Page<BoardListDto>> getBoardsList(

@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size)
@RequestParam(defaultValue = "10") int size,
@LoginUser User user)
{
Pageable pageable = PageRequest.of(page, size);
Page<BoardListDto> boardsList = boardQueryService.getBoards(pageable);
Page<BoardListDto> boardsList = boardQueryService.getBoards(user, pageable);
return onSuccess(boardsList);

}

@Operation(summary = "개별 게시물 조회", description = "단일 게시물의 내용을 조회합니다.")
@GetMapping("/{boardId}")
public ApiResponse<BoardDetailResponseDto> getBoard (@PathVariable(name = "boardId") Long boardId) {
BoardDetailResponseDto board = boardQueryService.getBoard(boardId);
public ApiResponse<BoardDetailResponseDto> getBoard (@LoginUser User user, @PathVariable(name = "boardId") Long boardId) {
BoardDetailResponseDto board = boardQueryService.getBoard(user, boardId);
return ApiResponse.onSuccess(board);
}

Expand All @@ -70,10 +75,11 @@ public ApiResponse<Page<BoardListDto>> getMyBoardsList(
public ApiResponse<Page<BoardListDto>> getUserBoardsList(
@PathVariable(name = "userId") Long userId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size)
@RequestParam(defaultValue = "10") int size,
@LoginUser User user)
{
Pageable pageable = PageRequest.of(page, size);
Page<BoardListDto> userBoardsList = boardQueryService.getUserBoards(userId, pageable);
Page<BoardListDto> userBoardsList = boardQueryService.getUserBoards(user, userId, pageable);
return onSuccess(userBoardsList);
}

Expand Down Expand Up @@ -143,4 +149,24 @@ public ApiResponse<Void> deleteComment(@PathVariable(name = "commentId") Long co
boardService.deleteComment(commentId, user);
return ApiResponse.noContent();
}
@Operation(summary = "자유게시판 사용자 차단", description = "차단을 하게되면, 차단한 사용자의 댓글, 게시글을 볼 수 없다.")
@PostMapping("/block/{isBlockedUserId}")
public ApiResponse<BoardBlockResponseDto> blockUser(@LoginUser User user, @PathVariable(name = "isBlockedUserId") Long isBlockedUserId) {
BoardBlockResponseDto boardBlockResponseDto = boardBlockService.blockUser(user, isBlockedUserId);
return ApiResponse.onSuccess(boardBlockResponseDto);
}

@Operation(summary = "자유게시판 사용자 차단해제", description = "차단을 해제하는 기능.")
@DeleteMapping("/block/{isBlockedUserId}")
public ApiResponse<Void> unblockUser(@LoginUser User user, @PathVariable(name = "isBlockedUserId") Long isBlockedUserId) {
boardBlockService.unblockUser(user, isBlockedUserId);
return ApiResponse.noContent();
}
@Operation(summary = "내가 차단한 사용자 조회", description = "내가 차단한 사용자를 조회해주는 기능")
@GetMapping("/blocked-users")
public ApiResponse<List<GetMyBoardBlockResponseDto>> getBlockedUsers(@LoginUser User currentUser) {
List<GetMyBoardBlockResponseDto> blockedUsers = boardBlockQueryService.getBlockedUsers(currentUser);
return ApiResponse.onSuccess(blockedUsers);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.capstone.BnagFer.domain.board.dto.request;

import com.capstone.BnagFer.domain.accounts.entity.User;
import com.capstone.BnagFer.domain.board.entity.BoardBlock;

public record BoardBlockRequestDto() {
public BoardBlock toEntity(User blockUser, User isBlockedUser) {
return BoardBlock.builder()
.blockUser(blockUser)
.isBlockedUser(isBlockedUser)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.capstone.BnagFer.domain.board.dto.response;

import com.capstone.BnagFer.domain.board.entity.BoardBlock;
import lombok.Builder;

import java.time.LocalDateTime;
@Builder
public record BoardBlockResponseDto(
Long id,
Long blockUser,
Long isBlockedUser,
LocalDateTime blockedAt
) {
public static BoardBlockResponseDto from(BoardBlock boardBlock) {
return BoardBlockResponseDto.builder()
.id(boardBlock.getId())
.blockUser(boardBlock.getBlockUser().getId())
.isBlockedUser(boardBlock.getIsBlockedUser().getId())
.blockedAt(boardBlock.getBlockedAt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ public record BoardDetailResponseDto(
Long likeCount,
Long commentCount
) {
public static BoardDetailResponseDto from(Board board, Long likeCount, Long commentCount) {
public static BoardDetailResponseDto from(Board board, Long likeCount, Long commentCount, List<Comment> filteredComments) {
return BoardDetailResponseDto.builder()
.id(board.getId())
.writerId(board.getUser().getId())
.writerNickName(board.getUser().getProfile().getNickname())
.boardTitle(board.getBoardTitle())
.boardContent(board.getBoardContent())
.images(BoardImageList.from(board.getImages()))
.commentList(CommentList.from(board.getComments()))
.commentList(CommentList.from(filteredComments))
.likeCount(likeCount)
.commentCount(commentCount)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,25 @@ public record BoardListDto(
Long commentCount

) {
public static BoardListDto from(Board board, Long commentCount, Long likeCount) {
public static BoardListDto from(Board board) {
return BoardListDto.builder()
.id(board.getId())
.userId(board.getUser().getId())
.writerNickName(board.getUser().getProfile().getNickname())
.boardTitle(board.getBoardTitle())
.likeCount(likeCount)
.commentCount(commentCount)
.likeCount((long) board.getLikes().size())
.commentCount((long) board.getComments().size())
.build();
}
public static BoardListDto from(Board board) {
return from(board, 0L, 0L);
}
public static List<BoardListDto> from(List<Board> boards) {
return boards.stream().map(board -> from(board, 0L, 0L)).collect(Collectors.toList());

public static List<BoardListDto> from(List<Board> boards, List<Long> blockedUserIds) {
return boards.stream()
.filter(board -> !blockedUserIds.contains(board.getUser().getId()))
.map(BoardListDto::from)
.collect(Collectors.toList());
}


}


Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.capstone.BnagFer.domain.board.dto.response;

import com.capstone.BnagFer.domain.board.entity.BoardBlock;
import lombok.Builder;

import java.time.LocalDateTime;
@Builder
public record GetMyBoardBlockResponseDto(
Long id,
Long isBlockedUser,
String nickName,
LocalDateTime blockedAt
) {
public static GetMyBoardBlockResponseDto from(BoardBlock boardBlock) {
return GetMyBoardBlockResponseDto.builder()
.id(boardBlock.getId())
.isBlockedUser(boardBlock.getIsBlockedUser().getId())
.nickName(boardBlock.getIsBlockedUser().getProfile().getNickname())
.blockedAt(boardBlock.getBlockedAt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import lombok.*;

import java.util.ArrayList;
import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.capstone.BnagFer.domain.board.entity;

import com.capstone.BnagFer.domain.accounts.entity.User;
import com.capstone.BnagFer.global.common.BaseEntity;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@Builder
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Table(name = "board_block")
public class BoardBlock extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "board_block_id", nullable = false)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "block_user_id")
private User blockUser;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "is_blocked_user_id")
private User isBlockedUser;

@Column(name = "blocked_at")
private LocalDateTime blockedAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.capstone.BnagFer.domain.board.repository;

import com.capstone.BnagFer.domain.accounts.entity.User;
import com.capstone.BnagFer.domain.board.entity.BoardBlock;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface BoardBlockRepository extends JpaRepository<BoardBlock, Long> {
boolean existsByBlockUserAndIsBlockedUser(User blockUser, User isBlockedUser);

void deleteByBlockUserAndIsBlockedUser(User blockUser, User isBlockedUser);

List<BoardBlock> findByBlockUser(User blockUser);

@Query("SELECT b.isBlockedUser.id FROM BoardBlock b WHERE b.blockUser.id = :blockUserId")
List<Long> findIsBlockUserIdsByBlockUserId(Long blockUserId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
@Repository
public interface BoardLikeRepository extends JpaRepository<Like, Long> {
Optional<Like> findByUserAndBoard(User user, Board board);
Long countByBoard(Board board);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ public interface BoardRepository extends JpaRepository<Board, Long> {
Page<Board> findAll(Pageable pageable);

Page<Board> findByUser(User user, Pageable pageable);

Page<Board> findByUserId(Long userId, Pageable pageable);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.capstone.BnagFer.domain.board.service;

import com.capstone.BnagFer.domain.accounts.entity.User;
import com.capstone.BnagFer.domain.board.dto.response.GetMyBoardBlockResponseDto;
import com.capstone.BnagFer.domain.board.entity.BoardBlock;
import com.capstone.BnagFer.domain.board.repository.BoardBlockRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BoardBlockQueryService {
private final BoardBlockRepository boardBlockRepository;
public List<GetMyBoardBlockResponseDto> getBlockedUsers(User user) {
List<BoardBlock> blockedUsers = boardBlockRepository.findByBlockUser(user);
return blockedUsers.stream()
.map(GetMyBoardBlockResponseDto::from)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.capstone.BnagFer.domain.board.service;

import com.capstone.BnagFer.domain.accounts.entity.User;
import com.capstone.BnagFer.domain.accounts.repository.UserJpaRepository;
import com.capstone.BnagFer.domain.board.dto.request.BoardBlockRequestDto;
import com.capstone.BnagFer.domain.board.dto.response.BoardBlockResponseDto;
import com.capstone.BnagFer.domain.board.entity.BoardBlock;
import com.capstone.BnagFer.domain.board.exception.BoardExceptionHandler;
import com.capstone.BnagFer.domain.board.repository.BoardBlockRepository;
import com.capstone.BnagFer.global.common.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class BoardBlockService {
private final BoardBlockRepository boardBlockRepository;
private final UserJpaRepository userRepository;

public BoardBlockResponseDto blockUser(User blockUser, Long isBlockedUserId) {
User blockedUser = userRepository.findById(isBlockedUserId)
.orElseThrow(() -> new BoardExceptionHandler(ErrorCode.USER_NOT_FOUND));
if (blockUser.getId().equals(isBlockedUserId)) {
throw new BoardExceptionHandler(ErrorCode.CANNOT_REPORT_YOURSELF);
}
if(boardBlockRepository.existsByBlockUserAndIsBlockedUser(blockUser, blockedUser)){
throw new BoardExceptionHandler(ErrorCode.ALREADY_BLOCKED);
}
BoardBlockRequestDto request = new BoardBlockRequestDto();
BoardBlock boardBlock = request.toEntity(blockUser, blockedUser);
boardBlockRepository.save(boardBlock);
return BoardBlockResponseDto.from(boardBlock);
}

public void unblockUser(User blockUser, Long isBlockedUserId) {
User blockedUser = userRepository.findById(isBlockedUserId)
.orElseThrow(() -> new BoardExceptionHandler(ErrorCode.USER_NOT_FOUND));
if (blockUser.getId().equals(isBlockedUserId)) {
throw new BoardExceptionHandler(ErrorCode.CANNOT_UNBLOCK_YOURSELF);
}
boardBlockRepository.deleteByBlockUserAndIsBlockedUser(blockUser, blockedUser);
}


}
Loading

0 comments on commit 11aec2f

Please sign in to comment.