diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/board/service/BoardService.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/board/service/BoardService.java index 00da9bf..6ab3ea8 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/board/service/BoardService.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/board/service/BoardService.java @@ -100,5 +100,4 @@ public Response deleteBoard(Long boardId) { return Response.of(HttpStatus.OK, "게시물 삭제 완료"); } - } \ No newline at end of file diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/dto/CommentCommandReq.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/dto/CommentCommandReq.java new file mode 100644 index 0000000..0ddc2d3 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/dto/CommentCommandReq.java @@ -0,0 +1,8 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.comment.dto; + +public record CommentCommandReq ( + Long commentId, + String commentContent +) +{ +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/dto/CommentUpdateReq.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/dto/CommentUpdateReq.java new file mode 100644 index 0000000..48b5160 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/dto/CommentUpdateReq.java @@ -0,0 +1,5 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.comment.dto; + +public record CommentUpdateReq (String commentContent) +{ +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/CommentEntity.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/CommentEntity.java index 9a5adc7..bdd2dde 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/CommentEntity.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/CommentEntity.java @@ -12,6 +12,7 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import kr.hs.dgsw.SOPO_server_v2.domain.board.entity.BoardEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.dto.CommentUpdateReq; import kr.hs.dgsw.SOPO_server_v2.domain.member.entity.MemberEntity; import kr.hs.dgsw.SOPO_server_v2.global.common.entity.BaseTimeEntity; import lombok.Getter; @@ -59,5 +60,11 @@ public class CommentEntity extends BaseTimeEntity { // 부모 @OnDelete(action = OnDeleteAction.CASCADE) private MemberEntity member; + public void addChildrenComment(SubCommentEntity comment) { + this.children.add(comment); + } + public void update(CommentUpdateReq updateReq) { + this.commentContent = updateReq.commentContent(); + } } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/SubCommentEntity.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/SubCommentEntity.java index 11c709d..7611603 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/SubCommentEntity.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/entity/SubCommentEntity.java @@ -1,5 +1,6 @@ package kr.hs.dgsw.SOPO_server_v2.domain.comment.entity; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -8,6 +9,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.dto.CommentUpdateReq; import kr.hs.dgsw.SOPO_server_v2.domain.member.entity.MemberEntity; import kr.hs.dgsw.SOPO_server_v2.global.common.entity.BaseTimeEntity; import lombok.Getter; @@ -31,7 +33,8 @@ public class SubCommentEntity extends BaseTimeEntity { private Long subCommentId; // 대댓글 내용 - private String content; + @Column(name = "sub_comment_content") + private String subCommentContent; // 부모 댓글 @ManyToOne(fetch = FetchType.LAZY) @@ -43,4 +46,8 @@ public class SubCommentEntity extends BaseTimeEntity { @JoinColumn(name = "member_id", nullable = false) @OnDelete(action = OnDeleteAction.CASCADE) private MemberEntity member; + + public void update(CommentUpdateReq updateReq) { + this.subCommentContent = updateReq.commentContent(); + } } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/repository/CommentRepository.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/repository/CommentRepository.java new file mode 100644 index 0000000..9f584ee --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/repository/CommentRepository.java @@ -0,0 +1,9 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.comment.repository; + +import kr.hs.dgsw.SOPO_server_v2.domain.comment.entity.CommentEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CommentRepository extends JpaRepository { +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/repository/SubCommentRepository.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/repository/SubCommentRepository.java new file mode 100644 index 0000000..a4c5f80 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/repository/SubCommentRepository.java @@ -0,0 +1,10 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.comment.repository; + + +import kr.hs.dgsw.SOPO_server_v2.domain.comment.entity.SubCommentEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SubCommentRepository extends JpaRepository { +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/service/CommentService.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/service/CommentService.java new file mode 100644 index 0000000..520cf1f --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/comment/service/CommentService.java @@ -0,0 +1,127 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.comment.service; + +import jakarta.transaction.Transactional; +import kr.hs.dgsw.SOPO_server_v2.domain.board.entity.BoardEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.board.repository.BoardRepository; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.dto.CommentCommandReq; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.dto.CommentUpdateReq; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.entity.CommentEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.entity.SubCommentEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.repository.CommentRepository; +import kr.hs.dgsw.SOPO_server_v2.domain.comment.repository.SubCommentRepository; +import kr.hs.dgsw.SOPO_server_v2.domain.member.entity.MemberEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.member.enums.MemberCategory; +import kr.hs.dgsw.SOPO_server_v2.global.error.custom.board.BoardNotFound; +import kr.hs.dgsw.SOPO_server_v2.global.error.custom.comment.CommentNotFound; +import kr.hs.dgsw.SOPO_server_v2.global.error.custom.member.MemberNotCoincideException; +import kr.hs.dgsw.SOPO_server_v2.global.infra.security.GetCurrentMember; +import kr.hs.dgsw.SOPO_server_v2.global.response.Response; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +@Service +@Transactional +@RequiredArgsConstructor +public class CommentService { + + private final CommentRepository commentRepository; + private final BoardRepository boardRepository; + private final GetCurrentMember getCurrentMember; + private final SubCommentRepository subCommentRepository; + + + // 댓글 생성 + public Response createComment(Long boardId, CommentCommandReq commentCommandReq) { + MemberEntity curMember = getCurrentMember.current(); + + if (commentCommandReq.commentId() == null) { // Comment + + BoardEntity board = boardRepository.findById(boardId) + .orElseThrow(() -> BoardNotFound.EXCEPTION); + + CommentEntity.builder() + .commentContent(commentCommandReq.commentContent()) + .board(board) + .member(curMember) + .children(null) + .build(); + + } else { // SubComment + + CommentEntity comment = commentRepository.findById(commentCommandReq.commentId()) + .orElseThrow(() -> CommentNotFound.EXCEPTION); + + SubCommentEntity subComment = SubCommentEntity.builder() + .subCommentContent(commentCommandReq.commentContent()) + .parent(comment) + .member(curMember) + .build(); + + comment.addChildrenComment(subComment); + + } + + return Response.of(HttpStatus.OK, "댓글 생성 성공!"); + } + + // 댓글 수정 + public Response updateComment(Long commentId, CommentUpdateReq commentUpdateReq) { + MemberEntity curMember = getCurrentMember.current(); + + CommentEntity comment = commentRepository.findById(commentId) + .orElseThrow(() -> CommentNotFound.EXCEPTION); + + notMemberComment(curMember, comment); + + comment.update(commentUpdateReq); + + return Response.of(HttpStatus.OK, "댓글 수정 완료!"); + } + + // 대댓글 수정 + public Response updateSubComment(Long subCommentId, CommentUpdateReq commentUpdateReq) { + MemberEntity curMember = getCurrentMember.current(); + + SubCommentEntity subComment = subCommentRepository.findById(subCommentId) + .orElseThrow(() -> CommentNotFound.EXCEPTION); + + notMemberSubComment(curMember, subComment); + + subComment.update(commentUpdateReq); + + return Response.of(HttpStatus.OK, "대댓글 수정 완료!"); + } + + // 댓글 삭제 +// public Response deleteComment(Long subCommentId) { +// MemberEntity curMember = getCurrentMember.current(); +// +// +// +// } + + // 대댓글 삭제 +// public Response deleteSubComment(Long subCommentId) { +// MemberEntity curMember = getCurrentMember.current(); +// +// +// } + + + + private void notMemberComment(MemberEntity curMember, CommentEntity comment) { + if (!comment.getMember().getMemberId().equals(curMember.getMemberId()) && curMember.getMemberCategory() == MemberCategory.USER) { + throw MemberNotCoincideException.EXCEPTION; + } + } + + private void notMemberSubComment(MemberEntity curMember, SubCommentEntity comment) { + if (!comment.getMember().getMemberId().equals(curMember.getMemberId()) && curMember.getMemberCategory() == MemberCategory.USER) { + throw MemberNotCoincideException.EXCEPTION; + } + } + + + +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/contest/repository/ContestRepository.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/contest/repository/ContestRepository.java index 67621a9..73e0c97 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/contest/repository/ContestRepository.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/contest/repository/ContestRepository.java @@ -2,8 +2,12 @@ import kr.hs.dgsw.SOPO_server_v2.domain.contest.entity.ContestEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.lang.reflect.Member; +import java.util.List; + @Repository public interface ContestRepository extends JpaRepository { } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/entity/EnrollEntity.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/entity/EnrollEntity.java index 4630259..8512e85 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/entity/EnrollEntity.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/entity/EnrollEntity.java @@ -1,6 +1,7 @@ package kr.hs.dgsw.SOPO_server_v2.domain.enroll.entity; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -26,7 +27,7 @@ public class EnrollEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long EnrollIdx; - @ManyToOne() + @ManyToOne @JoinColumn(name = "fk_member_id") private MemberEntity member; diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/service/EnrollService.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/service/EnrollService.java index fe14dd2..c1ea15f 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/service/EnrollService.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/enroll/service/EnrollService.java @@ -60,6 +60,18 @@ public Response toggle(Long contestId) { return Response.of(HttpStatus.OK, "신청 취소 성공"); } +// if (enroll.isPresent()) { +// enrollRepository.delete(enroll.get()); +// return Response.of(HttpStatus.OK, "신청 취소 성공"); +// } +// +// if (contest.getContestState() == ContestState.DISABLED) { +// return Response.of(HttpStatus.OK, "신청이 마감되었습니다."); +// } +// else { +// enrollContest(curMember, contest); +// return Response.of(HttpStatus.OK, "신청 성공"); +// } } public void enrollContest(MemberEntity member, ContestEntity contest) { @@ -130,13 +142,13 @@ public Response refuseContest(Long contestId, String memberId) { throw MemberNotCoincideException.EXCEPTION; } - // enroll 찾기 - Optional enroll = enrollRepository.findByMemberAndContest(member, contest); - if (contest.getContestMax().equals(contest.getContestPerson())) { contest.stateUpdateDisabled(); } + // enroll 찾기 + Optional enroll = enrollRepository.findByMemberAndContest(member, contest); + // enroll 삭제 enroll.ifPresent(enrollRepository::delete); diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/controller/LikeController.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/controller/LikeController.java index e240859..8485db9 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/controller/LikeController.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/controller/LikeController.java @@ -17,7 +17,7 @@ public class LikeController { private final LikeService likeService; @PatchMapping("{id}") - public Response patch(@PathVariable @RequestParam Long id, @RequestParam LikeCategory category) { + public Response patch(@PathVariable Long id, @RequestParam LikeCategory category) { return likeService.toggle(id, category); } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/service/LikeService.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/service/LikeService.java index f9dbdb8..7ef8d89 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/service/LikeService.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/like/service/LikeService.java @@ -63,7 +63,7 @@ else if (category == LikeCategory.CONTEST) { return Response.of(HttpStatus.OK, "좋아요 생성 완료"); } else { contestRepository.delete(like.get().getContest()); - contest.likeUpdate(1); + contest.likeUpdate(-1); return Response.of(HttpStatus.OK, "좋아요 취소 완료"); } } @@ -84,7 +84,7 @@ private void addBoardLike(MemberEntity member, BoardEntity board) { ); } - public void addContestLike(MemberEntity member, ContestEntity contest) { + private void addContestLike(MemberEntity member, ContestEntity contest) { likeRepository.save( LikeEntity.builder() .contest(contest) diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/error/custom/comment/CommentNotFound.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/error/custom/comment/CommentNotFound.java new file mode 100644 index 0000000..e30e043 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/error/custom/comment/CommentNotFound.java @@ -0,0 +1,13 @@ +package kr.hs.dgsw.SOPO_server_v2.global.error.custom.comment; + +import kr.hs.dgsw.SOPO_server_v2.global.error.exception.BusinessException; +import kr.hs.dgsw.SOPO_server_v2.global.error.exception.StatusEnum; + +public class CommentNotFound extends BusinessException { + public static final BusinessException EXCEPTION = new CommentNotFound(); + + public CommentNotFound() { + super(StatusEnum.COMMENT_NOT_FOUND); + } + +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/error/exception/StatusEnum.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/error/exception/StatusEnum.java index 74f1d2e..9fdea70 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/error/exception/StatusEnum.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/error/exception/StatusEnum.java @@ -57,10 +57,13 @@ public enum StatusEnum { BOARD_NOT_FOUND(404, "게시물을 찾을 수 없습니다."), // contest - CONTEST_NOT_FOUND(404, "대회를 찾을 수 없습니다"), + CONTEST_NOT_FOUND(404, "대회를 찾을 수 없습니다."), // enroll - ENROLL_NOT_FOUND(404, "신청을 찾을 수 없습니다"); + ENROLL_NOT_FOUND(404, "신청을 찾을 수 없습니다."), + + // comment + COMMENT_NOT_FOUND(404, "부모 댓글을 찾을 수 없습니다."); private final int statusCode; private final String message;