아웃소싱 프로젝트 (2)

신성훈·2024년 6월 24일
0

TIL

목록 보기
44/162
post-thumbnail

프로젝트 담당

  • 댓글 CRUD
  • 댓글 내용 유효성 확인(댓글 내용이 빈 칸인지 등)

Entity

package com.sparta.outsourcing.comment.entity;

import com.sparta.outsourcing.board.entity.Board;
import com.sparta.outsourcing.comment.dto.CommentRequestDTO;
import com.sparta.outsourcing.common.AnonymousNameGenerator;
import com.sparta.outsourcing.common.Timestamped;
import com.sparta.outsourcing.user.entity.User;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
@Table(name = "comments")
public class Comment extends Timestamped {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "공백이거나 null인 것은 불가합니다.")
    @Column(name = "comment", nullable = false)
    private String comment;

    @ManyToOne
    @JoinColumn(name = "board_id")
    private Board board;

    private String generatedname;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @Column(name = "likes")
    private Long like;

    public Comment(Board board, CommentRequestDTO commentRequestDTO, User user){
        this.board = board;
        this.comment = commentRequestDTO.getComment();
        this.generatedname = AnonymousNameGenerator.nameGenerate();
        this.user = user;
        this.like = 0L;
    }

    public void updateComment(CommentRequestDTO requestDTO) {
        this.comment = requestDTO.getComment();
    }

    public void decreaseLike() {
        this.like--;
    }

    public void increaseLike() {
        this.like++;
    }
}

Controller

package com.sparta.outsourcing.comment.controller;

import com.sparta.outsourcing.comment.dto.CommentRequestDTO;
import com.sparta.outsourcing.comment.dto.CommentResponseDTO;
import com.sparta.outsourcing.comment.service.CommentService;
import com.sparta.outsourcing.security.UserDetailsImpl;
import com.sparta.outsourcing.user.dto.CommonResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class CommentController {

    private final CommentService commentService;

    //Comment 전체 조회
    @GetMapping("/boards/{boardId}/comments")
    public ResponseEntity<CommonResponse<List<CommentResponseDTO>>> viewAllComment(@PathVariable(value = "boardId") Long boardId) {
        List<CommentResponseDTO> responseDTOList = commentService.viewAllComment(boardId);
        CommonResponse<List<CommentResponseDTO>> response = new CommonResponse<>("댓글조회 성공", HttpStatus.OK.value(),responseDTOList);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    //Comment 작성
    @PostMapping("/boards/{boardId}/comments")
    public ResponseEntity<CommonResponse<CommentResponseDTO>> createComment(@PathVariable(value = "boardId") Long boardId,
                                            @RequestBody @Valid CommentRequestDTO commentRequestDTO,
                                            @AuthenticationPrincipal UserDetailsImpl userDetails) {
        CommentResponseDTO comment = commentService.createComment(boardId, commentRequestDTO, userDetails.getUser());
        CommonResponse<CommentResponseDTO> response = new CommonResponse<>("댓글이 작성되었습니다.", HttpStatus.CREATED.value(),comment);
        return new ResponseEntity<>(response, HttpStatus.CREATED);
    }

    //Comment 수정
    @PutMapping("/boards/{boardId}/comments/{commentId}")
    public ResponseEntity<CommonResponse<CommentResponseDTO>> updateComment(@PathVariable(value = "boardId") Long boardId,
                                                                           @PathVariable(value = "commentId") Long commentId,
                                                                           @RequestBody @Valid CommentRequestDTO commentRequestDTO,
                                                                           @AuthenticationPrincipal UserDetailsImpl userDetails) {
        CommentResponseDTO comment = commentService.updateComment(boardId, commentId, commentRequestDTO, userDetails.getUser());
        CommonResponse<CommentResponseDTO> response = new CommonResponse<>("댓글 수정이 완료되었습니다.", HttpStatus.OK.value(), comment);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    //Comment 삭제
    @DeleteMapping("/boards/{boardId}/comments/{commentId}")
    public ResponseEntity<String> deleteComment(@PathVariable(value = "boardId") Long boardId,
                                                @PathVariable(value = "commentId") Long commentId,
                                                @AuthenticationPrincipal UserDetailsImpl userDetails) {
        commentService.deleteComment(boardId, commentId, userDetails.getUser());
        return ResponseEntity.ok("댓글이 삭제 되었습니다.");
    }




}

Service

package com.sparta.outsourcing.comment.service;

import com.sparta.outsourcing.board.entity.Board;
import com.sparta.outsourcing.board.repository.BoardRepository;
import com.sparta.outsourcing.comment.dto.CommentRequestDTO;
import com.sparta.outsourcing.comment.dto.CommentResponseDTO;
import com.sparta.outsourcing.comment.entity.Comment;
import com.sparta.outsourcing.comment.repository.CommentRepository;
import com.sparta.outsourcing.exception.ForbiddenException;
import com.sparta.outsourcing.exception.NotFoundException;
import com.sparta.outsourcing.user.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class CommentService {

    private final BoardRepository boardRepository;
    private final CommentRepository commentRepository;


    //댓글 전체 조회
    public List<CommentResponseDTO> viewAllComment(Long boardId) {
        boardRepository.findById(boardId).orElseThrow(
                () -> new NotFoundException("선택한 게시물이 없습니다.")
        );

        List<Comment> comments = commentRepository.findAllByBoardId(boardId);
        return comments.stream().map(CommentResponseDTO::new).toList();
    }

    // 댓글 작성
    public CommentResponseDTO createComment(Long boardId, CommentRequestDTO commentRequestDTO, User user) {
        Board board = boardRepository.findById(boardId).orElseThrow(
                () -> new NotFoundException("선택한 게시물이 없습니다.")
        );
        Comment comment = new Comment(board, commentRequestDTO, user);
        Comment saveComment = commentRepository.save(comment);
        return new CommentResponseDTO(saveComment);
    }

    // 댓글 수정
    @Transactional
    public CommentResponseDTO updateComment(Long boardId,Long commentId, CommentRequestDTO commentRequestDTO, User user) {
        boardRepository.findById(boardId).orElseThrow(
                () -> new NotFoundException("선택한 게시물이 없습니다.")
        );

        Comment comment = commentRepository.findById(commentId).orElseThrow(
                () -> new NotFoundException("조회한 댓글이 없습니다.")
        );

        if (Objects.equals(comment.getUser().getUserUid(), user.getUserUid())) {
            comment.updateComment(commentRequestDTO);
        } else {
            throw new NotFoundException("사용자 ID가 일치하지 않습니다.");
        }
        return new CommentResponseDTO(comment);
    }

    public void deleteComment(Long boardId, Long commentId, User user) {
        boardRepository.findById(boardId).orElseThrow(
                () -> new NotFoundException("선택한 게시물이 없습니다.")
        );

        Comment comment = commentRepository.findById(commentId).orElseThrow(
                () -> new NotFoundException("조회한 댓글이 없습니다.")
        );

        if (Objects.equals(comment.getUser().getUserUid(), user.getUserUid())) {
            commentRepository.delete(comment);
        } else {
            throw new NotFoundException("사용자 ID가 일치하지 않습니다.");
        }
    }

    public void decreaseCommentLike(Long contentId) {
        Comment comment = commentRepository.findById(contentId).orElseThrow(() -> new NotFoundException("댓글을 찾을 수 없습니다."));
        comment.decreaseLike();
    }

    public void increaseCommentLike(Long contentId) {
        Comment comment = commentRepository.findById(contentId).orElseThrow(() -> new NotFoundException("댓글을 찾을 수 없습니다."));
        comment.increaseLike();
    }

    public void validateCommentLike(Long userId, Long contentId) {
        Comment comment = commentRepository.findById(contentId).orElseThrow(() -> new NotFoundException("댓글을 찾을 수 없습니다."));
        if(comment.getUser().getId().equals(userId)) {
            throw new ForbiddenException("해당 댓글의 작성자입니다.");
        }
    }
}

Repository

package com.sparta.outsourcing.comment.repository;

import com.sparta.outsourcing.comment.entity.Comment;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface CommentRepository extends JpaRepository<Comment, Long> {

    List<Comment> findAllByBoardId(Long boardId);
}

DTO

package com.sparta.outsourcing.comment.dto;

import jakarta.validation.constraints.NotBlank;
import lombok.Getter;

@Getter
public class CommentRequestDTO {

    @NotBlank(message = "공백이거나 null인 것은 불가합니다.")
    private String comment;
}
package com.sparta.outsourcing.comment.dto;

import com.sparta.outsourcing.comment.entity.Comment;
import lombok.Getter;

@Getter
public class CommentResponseDTO {
    private Long id;
    private String comment;
    private String generatedname;
    private Long boardId;
    private Long userId;

    public CommentResponseDTO(Comment comment) {
        this.id = comment.getId();
        this.comment = comment.getComment();
        this.generatedname = comment.getGeneratedname();
        this.boardId = comment.getBoard().getId();
        this.userId = comment.getUser().getId();
    }
}
profile
조급해하지 말고, 흐름을 만들고, 기록하면서 쌓아가자.

0개의 댓글