Skip to content

Commit

Permalink
Merge pull request #7 from AR-TTUBEOG/feature/3
Browse files Browse the repository at this point in the history
[Feat] Comment 작성, 수정, 삭제 구현
  • Loading branch information
choeun7 authored Jan 19, 2024
2 parents 495b03d + 68dc974 commit 324d94c
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,116 @@
package com.ttubeog.domain.comment.application;

import com.ttubeog.domain.comment.domain.Comment;
import com.ttubeog.domain.comment.domain.repository.CommentRepository;
import com.ttubeog.domain.comment.dto.request.UpdateCommentReq;
import com.ttubeog.domain.comment.dto.request.WriteCommentReq;
import com.ttubeog.domain.comment.dto.response.UpdateCommentRes;
import com.ttubeog.domain.comment.dto.response.WriteCommentRes;
import com.ttubeog.domain.member.domain.Member;
import com.ttubeog.domain.member.domain.repository.MemberRepository;
import com.ttubeog.global.DefaultAssert;
import com.ttubeog.global.config.security.token.UserPrincipal;
import com.ttubeog.global.payload.ApiResponse;
import com.ttubeog.global.payload.Message;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@RequiredArgsConstructor
@Service
@Transactional(readOnly = true)
public class CommentService {

private final CommentRepository commentRepository;
private final MemberRepository memberRepository;

// 댓글 작성
@Transactional
public ResponseEntity<?> writeComment(UserPrincipal userPrincipal, WriteCommentReq writeCommentReq) {

Optional<Member> memberOptional = memberRepository.findById(userPrincipal.getId());
DefaultAssert.isOptionalPresent(memberOptional);
Member member = memberOptional.get();

Comment comment = Comment.builder()
.content(writeCommentReq.getContent())
.latitude(writeCommentReq.getLatitude())
.longitude(writeCommentReq.getLongitude())
.member(member)
.build();

commentRepository.save(comment);

WriteCommentRes writeCommentRes = WriteCommentRes.builder()
.commentId(comment.getId())
.memberId(member.getId())
.content(comment.getContent())
.latitude(comment.getLatitude())
.longitude(comment.getLongitude())
.build();

ApiResponse apiResponse = ApiResponse.builder()
.check(true)
.information(writeCommentRes)
.build();

return ResponseEntity.ok(apiResponse);
}

// 댓글 수정
@Transactional
public ResponseEntity<?> updateComment(UserPrincipal userPrincipal, UpdateCommentReq updateCommentReq) {

Optional<Member> memberOptional = memberRepository.findById(userPrincipal.getId());
DefaultAssert.isOptionalPresent(memberOptional);

Optional<Comment> commentOptional = commentRepository.findById(updateCommentReq.getCommentId());
DefaultAssert.isOptionalPresent(commentOptional);
Comment comment = commentOptional.get();

Member commentWriter = comment.getMember();
if (commentWriter.getId() != memberOptional.get().getId()) {
DefaultAssert.isTrue(true, "해당 댓글의 작성자만 수정할 수 있습니다.");
}

comment.updateContent(updateCommentReq.getContent());
UpdateCommentRes updateCommentRes = UpdateCommentRes.builder()
.commentId(comment.getId())
.content(comment.getContent())
.build();

ApiResponse apiResponse = ApiResponse.builder()
.check(true)
.information(updateCommentRes)
.build();

return ResponseEntity.ok(apiResponse);
}

// 댓글 삭제
@Transactional
public ResponseEntity<?> deleteComment(UserPrincipal userPrincipal, Long commentId) {

Optional<Member> memberOptional = memberRepository.findById(userPrincipal.getId());
DefaultAssert.isOptionalPresent(memberOptional);

Optional<Comment> commentOptional = commentRepository.findById(commentId);
DefaultAssert.isOptionalPresent(commentOptional);
Comment comment = commentOptional.get();

commentRepository.delete(comment);

ApiResponse apiResponse = ApiResponse.builder()
.check(true)
.information(Message.builder().message("댓글이 정상적으로 삭제되었습니다.").build())
.build();

return ResponseEntity.ok(apiResponse);
}

// 댓글 조회

}
29 changes: 25 additions & 4 deletions src/main/java/com/ttubeog/domain/comment/domain/Comment.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
package com.ttubeog.domain.comment.domain;

import com.ttubeog.domain.common.BaseEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import com.ttubeog.domain.member.domain.Member;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(name = "comment")
public class Comment extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "content")
private String content;

@Column(name = "latitude")
private Float latitude;

@Column(name = "longitude")
private Float longitude;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

public void updateContent(String content) {
this.content = content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.ttubeog.domain.comment.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
public class UpdateCommentReq {

@Schema(description = "댓글 ID")
private Long commentId;

@Schema(description = "댓글 내용")
private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.ttubeog.domain.comment.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
@Schema(description = "댓글 작성 Request")
public class WriteCommentReq {

@Schema(description = "댓글 내용")
private String content;
@Schema(description = "위도")
private Float latitude;
@Schema(description = "경도")
private Float longitude;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ttubeog.domain.comment.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;

@Data
public class UpdateCommentRes {

@Schema(description = "댓글 ID")
private Long commentId;

@Schema(description = "내용")
private String content;

@Builder
public UpdateCommentRes(Long commentId, String content) {
this.commentId = commentId;
this.content = content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.ttubeog.domain.comment.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;

@Data
public class WriteCommentRes {

@Schema(description = "댓글 ID")
private Long commentId;

@Schema(description = "작성자 ID")
private Long memberId;

@Schema(description = "내용")
private String content;

@Schema(description = "위도")
private Float latitude;

@Schema(description = "경도")
private Float longitude;

@Builder
public WriteCommentRes(Long commentId, Long memberId, String content, Float latitude, Float longitude) {
this.commentId = commentId;
this.memberId = memberId;
this.content = content;
this.latitude = latitude;
this.longitude = longitude;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,75 @@
package com.ttubeog.domain.comment.presentation;

import org.springframework.web.bind.annotation.RestController;
import com.ttubeog.domain.comment.application.CommentService;
import com.ttubeog.domain.comment.dto.request.UpdateCommentReq;
import com.ttubeog.domain.comment.dto.request.WriteCommentReq;
import com.ttubeog.domain.comment.dto.response.UpdateCommentRes;
import com.ttubeog.domain.comment.dto.response.WriteCommentRes;
import com.ttubeog.global.config.security.token.CurrentUser;
import com.ttubeog.global.config.security.token.UserPrincipal;
import com.ttubeog.global.payload.ErrorResponse;
import com.ttubeog.global.payload.Message;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@Tag(name = "Comment", description = "Comment API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/comment")
public class CommentController {

private final CommentService commentService;

// 댓글 작성
@Operation(summary = "댓글 작성", description = "댓글을 작성합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "댓글 작성 성공", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = WriteCommentRes.class) ) } ),
@ApiResponse(responseCode = "400", description = "댓글 작성 실패", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class) ) } )
})
@PostMapping
public ResponseEntity<?> writeComment(
@Parameter(description = "AccessToken을 입력해주세요.", required = true) @CurrentUser UserPrincipal userPrincipal,
@Valid @RequestBody WriteCommentReq writeCommentReq
) {
return commentService.writeComment(userPrincipal, writeCommentReq);
}

// 댓글 수정
@Operation(summary = "댓글 수정", description = "댓글 내용을 수정합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "댓글 수정 성공", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UpdateCommentRes.class) ) } ),
@ApiResponse(responseCode = "400", description = "댓글 수정 실패", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class) ) } )
})
@PatchMapping
public ResponseEntity<?> updateComment(
@Parameter(description = "AccessToken을 입력해주세요.", required = true) @CurrentUser UserPrincipal userPrincipal,
@Valid @RequestBody UpdateCommentReq updateCommentReq
) {
return commentService.updateComment(userPrincipal, updateCommentReq);
}

// 댓글 삭제
@Operation(summary = "댓글 삭제", description = "댓글을 삭제합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "댓글 삭제 성공", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = Message.class) ) } ),
@ApiResponse(responseCode = "400", description = "댓글 삭제 실패", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class) ) } )
})
@DeleteMapping("/{commentId}")
public ResponseEntity<?> deleteComment(
@Parameter(description = "AccessToken을 입력해주세요.", required = true) @CurrentUser UserPrincipal userPrincipal,
@PathVariable Long commentId
) {
return commentService.deleteComment(userPrincipal, commentId);
}

// 댓글 조회
}

0 comments on commit 324d94c

Please sign in to comment.