Skip to content

Commit 6088c75

Browse files
committed
[EA3-138] feature: 모집글 댓글 CUD 추가
1 parent 2aff186 commit 6088c75

File tree

9 files changed

+110
-6
lines changed

9 files changed

+110
-6
lines changed

src/main/java/grep/neogul_coder/domain/recruitment/RecruitmentErrorCode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public enum RecruitmentErrorCode implements ErrorCode {
99
NOT_STUDY_LEADER(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.name(), "스터디의 리더가 아닙니다."),
1010
NOT_FOUND_STUDY_MEMBER(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.name(), "스터디에 참여하고 있지 않은 회원 입니다."),
1111
NOT_FOUND(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.name(), "모집글을 찾지 못했습니다."),
12+
NOT_FOUND_COMMENT(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.name(), "댓글을 찾지 못했습니다"),
1213
NOT_OWNER(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.name(), "모집글을 등록한 당사자가 아닙니다.");
1314

1415
private static final String BASIC_MESSAGE = "RECRUITMENT";

src/main/java/grep/neogul_coder/domain/recruitment/comment/RecruitmentPostComment.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,12 @@ private RecruitmentPostComment(RecruitmentPost recruitmentPost, long userId, Str
3030
this.userId = userId;
3131
this.content = content;
3232
}
33+
34+
public void update(String content) {
35+
this.content = content;
36+
}
37+
38+
public void delete() {
39+
this.activated = false;
40+
}
3341
}

src/main/java/grep/neogul_coder/domain/recruitment/comment/controller/RecruitmentPostCommentController.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,40 @@
22

33
import grep.neogul_coder.domain.recruitment.comment.controller.dto.request.RecruitmentCommentSaveRequest;
44
import grep.neogul_coder.domain.recruitment.comment.controller.dto.request.RecruitmentCommentUpdateRequest;
5+
import grep.neogul_coder.domain.recruitment.comment.service.RecruitmentPostCommentService;
56
import grep.neogul_coder.global.auth.Principal;
67
import grep.neogul_coder.global.response.ApiResponse;
8+
import jakarta.validation.Valid;
9+
import lombok.RequiredArgsConstructor;
710
import org.springframework.security.core.annotation.AuthenticationPrincipal;
811
import org.springframework.web.bind.annotation.*;
912

1013
@RequestMapping("/recruitment-posts/comments")
14+
@RequiredArgsConstructor
1115
@RestController
1216
public class RecruitmentPostCommentController implements RecruitmentPostCommentSpecification {
1317

18+
private final RecruitmentPostCommentService commentService;
19+
1420
@PostMapping
15-
public ApiResponse<Void> save(@RequestBody RecruitmentCommentSaveRequest request,
21+
public ApiResponse<Long> save(@RequestBody @Valid RecruitmentCommentSaveRequest request,
1622
@AuthenticationPrincipal Principal userDetails) {
17-
return ApiResponse.noContent();
23+
long commentId = commentService.save(request, userDetails.getUserId());
24+
return ApiResponse.success(commentId);
1825
}
1926

2027
@PutMapping("/{comment-id}")
2128
public ApiResponse<Void> update(@PathVariable("comment-id") long commentId,
2229
@RequestBody RecruitmentCommentUpdateRequest request,
2330
@AuthenticationPrincipal Principal userDetails) {
31+
commentService.update(request, commentId, userDetails.getUserId());
2432
return ApiResponse.noContent();
2533
}
2634

2735
@DeleteMapping("/{comment-id}")
2836
public ApiResponse<Void> delete(@PathVariable("comment-id") long commentId,
2937
@AuthenticationPrincipal Principal userDetails) {
38+
commentService.delete(commentId, userDetails.getUserId());
3039
return ApiResponse.noContent();
3140
}
3241
}

src/main/java/grep/neogul_coder/domain/recruitment/comment/controller/RecruitmentPostCommentSpecification.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
public interface RecruitmentPostCommentSpecification {
1212

1313
@Operation(summary = "모집글 댓글 작성", description = "모집글에 대한 댓글을 작성 합니다.")
14-
ApiResponse<Void> save(RecruitmentCommentSaveRequest request, Principal userDetails);
14+
ApiResponse<Long> save(RecruitmentCommentSaveRequest request, Principal userDetails);
1515

1616
@Operation(summary = "모집글 댓글 수정", description = "모집글에 대한 댓글을 수정 합니다.")
1717
ApiResponse<Void> update(long commentId, RecruitmentCommentUpdateRequest request, Principal userDetails);

src/main/java/grep/neogul_coder/domain/recruitment/comment/controller/dto/request/RecruitmentCommentSaveRequest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package grep.neogul_coder.domain.recruitment.comment.controller.dto.request;
22

3+
import grep.neogul_coder.domain.recruitment.comment.RecruitmentPostComment;
4+
import grep.neogul_coder.domain.recruitment.post.RecruitmentPost;
35
import io.swagger.v3.oas.annotations.media.Schema;
46
import lombok.Getter;
57

@@ -11,4 +13,16 @@ public class RecruitmentCommentSaveRequest {
1113

1214
@Schema(example = "저도 참여 할래요!", description = "모집글 내용")
1315
private String content;
16+
17+
private RecruitmentCommentSaveRequest() {
18+
}
19+
20+
public RecruitmentPostComment toEntity(RecruitmentPost post, long userId){
21+
return RecruitmentPostComment.builder()
22+
.recruitmentPost(post)
23+
.userId(userId)
24+
.content(this.content)
25+
.build();
26+
}
27+
1428
}

src/main/java/grep/neogul_coder/domain/recruitment/comment/controller/dto/request/RecruitmentCommentUpdateRequest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
@Getter
77
public class RecruitmentCommentUpdateRequest {
88

9-
@Schema(example = "2", description = "모집글 ID")
10-
private long postId;
11-
129
@Schema(example = "저도 참여 할래요!", description = "모집글 내용")
1310
private String content;
1411
}

src/main/java/grep/neogul_coder/domain/recruitment/comment/repository/RecruitmentPostCommentQueryRepository.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.springframework.stereotype.Repository;
99

1010
import java.util.List;
11+
import java.util.Optional;
1112

1213
import static grep.neogul_coder.domain.recruitment.comment.QRecruitmentPostComment.recruitmentPostComment;
1314
import static grep.neogul_coder.domain.users.entity.QUser.user;
@@ -51,4 +52,15 @@ public List<CommentsWithWriterInfo> findCommentsWithWriterInfo(Long recruitmentP
5152
)
5253
.fetch();
5354
}
55+
56+
public Optional<RecruitmentPostComment> findMyCommentBy(long commentId, long userId) {
57+
RecruitmentPostComment comment = queryFactory.selectFrom(recruitmentPostComment)
58+
.where(
59+
recruitmentPostComment.activated.isTrue(),
60+
recruitmentPostComment.id.eq(commentId),
61+
recruitmentPostComment.userId.eq(userId)
62+
)
63+
.fetchOne();
64+
return Optional.ofNullable(comment);
65+
}
5466
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package grep.neogul_coder.domain.recruitment.comment.service;
2+
3+
import grep.neogul_coder.domain.recruitment.RecruitmentErrorCode;
4+
import grep.neogul_coder.domain.recruitment.comment.RecruitmentPostComment;
5+
import grep.neogul_coder.domain.recruitment.comment.controller.dto.request.RecruitmentCommentSaveRequest;
6+
import grep.neogul_coder.domain.recruitment.comment.controller.dto.request.RecruitmentCommentUpdateRequest;
7+
import grep.neogul_coder.domain.recruitment.comment.repository.RecruitmentPostCommentQueryRepository;
8+
import grep.neogul_coder.domain.recruitment.comment.repository.RecruitmentPostCommentRepository;
9+
import grep.neogul_coder.domain.recruitment.post.RecruitmentPost;
10+
import grep.neogul_coder.domain.recruitment.post.repository.RecruitmentPostQueryRepository;
11+
import grep.neogul_coder.global.exception.business.NotFoundException;
12+
import lombok.RequiredArgsConstructor;
13+
import org.springframework.stereotype.Service;
14+
import org.springframework.transaction.annotation.Transactional;
15+
16+
import static grep.neogul_coder.domain.recruitment.RecruitmentErrorCode.*;
17+
18+
@Transactional(readOnly = true)
19+
@RequiredArgsConstructor
20+
@Service
21+
public class RecruitmentPostCommentService {
22+
23+
private final RecruitmentPostQueryRepository postRepository;
24+
private final RecruitmentPostCommentRepository commentRepository;
25+
private final RecruitmentPostCommentQueryRepository commentQueryRepository;
26+
27+
@Transactional
28+
public long save(RecruitmentCommentSaveRequest request, long userId) {
29+
RecruitmentPost myPost = postRepository.findMyPostBy(request.getPostId(), userId)
30+
.orElseThrow(() -> new NotFoundException(NOT_FOUND));
31+
32+
return commentRepository.save(request.toEntity(myPost, userId)).getId();
33+
}
34+
35+
@Transactional
36+
public void update(RecruitmentCommentUpdateRequest request, long commentId, long userId) {
37+
RecruitmentPostComment comment = commentQueryRepository.findMyCommentBy(commentId, userId)
38+
.orElseThrow(() -> new NotFoundException(NOT_FOUND_COMMENT));
39+
40+
comment.update(request.getContent());
41+
}
42+
43+
@Transactional
44+
public void delete(long commentId, long userId) {
45+
RecruitmentPostComment comment = commentQueryRepository.findMyCommentBy(commentId, userId)
46+
.orElseThrow(() -> new NotFoundException(NOT_FOUND_COMMENT));
47+
48+
comment.delete();
49+
}
50+
}

src/main/java/grep/neogul_coder/domain/recruitment/post/repository/RecruitmentPostQueryRepository.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.querydsl.core.BooleanBuilder;
44
import com.querydsl.core.types.dsl.BooleanExpression;
55
import com.querydsl.jpa.impl.JPAQueryFactory;
6+
import grep.neogul_coder.domain.recruitment.post.QRecruitmentPost;
67
import grep.neogul_coder.domain.recruitment.post.RecruitmentPost;
78
import grep.neogul_coder.domain.recruitment.post.controller.dto.request.PagingCondition;
89
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.QRecruitmentPostWithStudyInfo;
@@ -15,6 +16,7 @@
1516
import org.springframework.stereotype.Repository;
1617

1718
import java.util.List;
19+
import java.util.Optional;
1820
import java.util.function.Supplier;
1921

2022
import static grep.neogul_coder.domain.recruitment.post.QRecruitmentPost.recruitmentPost;
@@ -123,6 +125,17 @@ public Page<RecruitmentPost> findAllByFilter(PagingCondition condition, Long use
123125
return new PageImpl<>(content, condition.toPageable(), count == null ? 0 : count);
124126
}
125127

128+
public Optional<RecruitmentPost> findMyPostBy(long postId, long userId) {
129+
RecruitmentPost findRecruitmentPost = queryFactory.selectFrom(recruitmentPost)
130+
.where(
131+
recruitmentPost.activated.isTrue(),
132+
recruitmentPost.userId.eq(userId),
133+
recruitmentPost.id.eq(postId)
134+
)
135+
.fetchOne();
136+
return Optional.ofNullable(findRecruitmentPost);
137+
}
138+
126139
private BooleanBuilder equalsStudyType(StudyType studyType) {
127140
return nullSafeBuilder(() -> study.studyType.eq(studyType));
128141
}

0 commit comments

Comments
 (0)