Skip to content

Commit f5b258e

Browse files
authored
Merge pull request #94 from MT-TEAM-Org/epic/뉴스-대댓글기능
epic: 뉴스 대댓글기능
2 parents e520c3b + 772dd22 commit f5b258e

26 files changed

+1059
-6
lines changed

src/main/java/org/myteam/server/global/exception/ErrorCode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public enum ErrorCode {
5252
BAN_NOT_FOUND(HttpStatus.NOT_FOUND, "Ban not found"),
5353
NEWS_NOT_FOUND(HttpStatus.NOT_FOUND, "News not found"),
5454
NEWS_COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "New Comment not found"),
55+
NEWS_REPLY_NOT_FOUND(HttpStatus.NOT_FOUND, "New Reply not found"),
5556

5657
// 409 Conflict,
5758
USER_ALREADY_EXISTS(HttpStatus.CONFLICT, "User already exists"),
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.myteam.server.news.controller;
2+
3+
import static org.myteam.server.global.web.response.ResponseStatus.*;
4+
5+
import org.myteam.server.global.web.response.ResponseDto;
6+
import org.myteam.server.news.dto.controller.request.NewsCommentRequest;
7+
import org.myteam.server.news.dto.controller.request.NewsReplyRequest;
8+
import org.myteam.server.news.dto.controller.request.NewsReplySaveRequest;
9+
import org.myteam.server.news.dto.controller.request.NewsReplyUpdateRequest;
10+
import org.myteam.server.news.dto.service.response.NewsReplyListResponse;
11+
import org.myteam.server.news.dto.service.response.NewsReplyResponse;
12+
import org.myteam.server.news.service.NewsReplyReadService;
13+
import org.myteam.server.news.service.NewsReplyService;
14+
import org.myteam.server.util.ClientUtils;
15+
import org.springframework.http.ResponseEntity;
16+
import org.springframework.web.bind.annotation.DeleteMapping;
17+
import org.springframework.web.bind.annotation.GetMapping;
18+
import org.springframework.web.bind.annotation.PatchMapping;
19+
import org.springframework.web.bind.annotation.PathVariable;
20+
import org.springframework.web.bind.annotation.PostMapping;
21+
import org.springframework.web.bind.annotation.RequestBody;
22+
import org.springframework.web.bind.annotation.RequestMapping;
23+
import org.springframework.web.bind.annotation.RestController;
24+
25+
import jakarta.servlet.http.HttpServletRequest;
26+
import jakarta.validation.Valid;
27+
import lombok.RequiredArgsConstructor;
28+
29+
@RestController
30+
@RequiredArgsConstructor
31+
@RequestMapping("/api/news/reply")
32+
public class NewsReplyController {
33+
34+
private final NewsReplyService newsReplyService;
35+
private final NewsReplyReadService newsReplyReadService;
36+
37+
@PostMapping
38+
private ResponseEntity<ResponseDto<NewsReplyResponse>> save(
39+
@RequestBody @Valid NewsReplySaveRequest newsSaveRequest, HttpServletRequest request) {
40+
return ResponseEntity.ok(new ResponseDto<>(
41+
SUCCESS.name(),
42+
"뉴스 대댓글 저장 성공",
43+
newsReplyService.save(newsSaveRequest.toServiceRequest(ClientUtils.getRemoteIP(request)))));
44+
}
45+
46+
@GetMapping
47+
private ResponseEntity<ResponseDto<NewsReplyListResponse>> findByNewsId(
48+
@RequestBody @Valid NewsReplyRequest newsReplyRequest) {
49+
return ResponseEntity.ok(new ResponseDto<>(
50+
SUCCESS.name(),
51+
"뉴스 대댓글 조회 성공",
52+
newsReplyReadService.findByNewsCommentId(newsReplyRequest.toServiceRequest())));
53+
}
54+
55+
@PatchMapping
56+
private ResponseEntity<ResponseDto<Long>> update(
57+
@RequestBody @Valid NewsReplyUpdateRequest newsReplyUpdateRequest) {
58+
return ResponseEntity.ok(new ResponseDto<>(
59+
SUCCESS.name(),
60+
"뉴스 대댓글 수정 성공",
61+
newsReplyService.update(newsReplyUpdateRequest.toServiceRequest())));
62+
}
63+
64+
@DeleteMapping("/{newsReplyId}")
65+
private ResponseEntity<ResponseDto<Long>> delete(@PathVariable Long newsReplyId) {
66+
return ResponseEntity.ok(new ResponseDto<>(
67+
SUCCESS.name(),
68+
"뉴스 대댓글 삭제 성공",
69+
newsReplyService.delete(newsReplyId)));
70+
}
71+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.myteam.server.news.domain;
2+
3+
import org.myteam.server.global.domain.Base;
4+
import org.myteam.server.member.entity.Member;
5+
6+
import jakarta.persistence.Entity;
7+
import jakarta.persistence.FetchType;
8+
import jakarta.persistence.GeneratedValue;
9+
import jakarta.persistence.GenerationType;
10+
import jakarta.persistence.Id;
11+
import jakarta.persistence.ManyToOne;
12+
import lombok.AccessLevel;
13+
import lombok.Builder;
14+
import lombok.Getter;
15+
import lombok.NoArgsConstructor;
16+
17+
@Getter
18+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
19+
@Entity(name = "p_news_reply")
20+
public class NewsReply extends Base {
21+
22+
@Id
23+
@GeneratedValue(strategy = GenerationType.IDENTITY)
24+
private Long id;
25+
26+
@ManyToOne(fetch = FetchType.LAZY)
27+
private NewsComment newsComment;
28+
29+
@ManyToOne(fetch = FetchType.LAZY)
30+
private Member member;
31+
32+
private String comment;
33+
34+
private String ip;
35+
36+
@Builder
37+
public NewsReply(Long id, NewsComment newsComment, Member member, String comment, String ip) {
38+
this.id = id;
39+
this.newsComment = newsComment;
40+
this.member = member;
41+
this.comment = comment;
42+
this.ip = ip;
43+
}
44+
45+
public void confirmMember(Member member) {
46+
this.member.confirmMemberEquals(member);
47+
}
48+
49+
public void updateComment(String comment) {
50+
this.comment = comment;
51+
}
52+
53+
public static NewsReply createNewsReply(NewsComment newsComment, Member member, String comment, String ip) {
54+
return NewsReply.builder()
55+
.newsComment(newsComment)
56+
.member(member)
57+
.comment(comment)
58+
.ip(ip)
59+
.build();
60+
}
61+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.myteam.server.news.dto.controller.request;
2+
3+
import org.myteam.server.global.page.request.PageInfoRequest;
4+
import org.myteam.server.news.dto.service.request.NewsCommentServiceRequest;
5+
import org.myteam.server.news.dto.service.request.NewsReplyServiceRequest;
6+
7+
import jakarta.validation.constraints.NotNull;
8+
import lombok.Builder;
9+
import lombok.Getter;
10+
import lombok.NoArgsConstructor;
11+
12+
@Getter
13+
@NoArgsConstructor
14+
public class NewsReplyRequest extends PageInfoRequest {
15+
16+
@NotNull(message = "뉴스 대댓글 ID는 필수입니다.")
17+
private Long newsCommentId;
18+
19+
@Builder
20+
public NewsReplyRequest(Long newsCommentId, int page, int size) {
21+
super(page, size);
22+
this.newsCommentId = newsCommentId;
23+
}
24+
25+
public NewsReplyServiceRequest toServiceRequest() {
26+
return NewsReplyServiceRequest.builder()
27+
.newsCommentId(newsCommentId)
28+
.size(getSize())
29+
.page(getPage())
30+
.build();
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.myteam.server.news.dto.controller.request;
2+
3+
import org.myteam.server.news.dto.service.request.NewsReplySaveServiceRequest;
4+
5+
import jakarta.validation.constraints.NotNull;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
10+
@Getter
11+
@NoArgsConstructor
12+
public class NewsReplySaveRequest {
13+
14+
@NotNull(message = "뉴스 댓글 ID는 필수입니다.")
15+
private Long newsCommentId;
16+
@NotNull(message = "뉴스 대댓글은 필수입니다.")
17+
private String comment;
18+
19+
@Builder
20+
public NewsReplySaveRequest(Long newsCommentId, String comment) {
21+
this.newsCommentId = newsCommentId;
22+
this.comment = comment;
23+
}
24+
25+
public NewsReplySaveServiceRequest toServiceRequest(String ip) {
26+
return NewsReplySaveServiceRequest.builder()
27+
.newsCommentId(newsCommentId)
28+
.comment(comment)
29+
.ip(ip)
30+
.build();
31+
}
32+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.myteam.server.news.dto.controller.request;
2+
3+
import org.myteam.server.news.dto.service.request.NewsReplyUpdateServiceRequest;
4+
5+
import jakarta.validation.constraints.NotNull;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
10+
@Getter
11+
@NoArgsConstructor
12+
public class NewsReplyUpdateRequest {
13+
14+
@NotNull(message = "뉴스 대댓글 ID는 필수입니다.")
15+
private Long newsReplyId;
16+
@NotNull(message = "뉴스 대댓글 내용은 필수입니다.")
17+
private String comment;
18+
19+
@Builder
20+
public NewsReplyUpdateRequest(Long newsReplyId, String comment) {
21+
this.newsReplyId = newsReplyId;
22+
this.comment = comment;
23+
}
24+
25+
public NewsReplyUpdateServiceRequest toServiceRequest() {
26+
return NewsReplyUpdateServiceRequest.builder()
27+
.newsReplyId(newsReplyId)
28+
.comment(comment)
29+
.build();
30+
}
31+
}

src/main/java/org/myteam/server/news/dto/repository/NewsCommentDto.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.myteam.server.news.dto.repository;
22

3+
import java.time.LocalDateTime;
4+
35
import lombok.Getter;
46
import lombok.NoArgsConstructor;
57

@@ -12,12 +14,14 @@ public class NewsCommentDto {
1214
private NewsCommentMemberDto memberDto;
1315
private String comment;
1416
private String ip;
17+
private LocalDateTime createTime;
1518

16-
public NewsCommentDto(Long newsCommentId, Long newsId, NewsCommentMemberDto memberDto, String comment, String ip) {
19+
public NewsCommentDto(Long newsCommentId, Long newsId, NewsCommentMemberDto memberDto, String comment, String ip, LocalDateTime createTime) {
1720
this.newsCommentId = newsCommentId;
1821
this.newsId = newsId;
1922
this.memberDto = memberDto;
2023
this.comment = comment;
2124
this.ip = ip;
25+
this.createTime = createTime;
2226
}
2327
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.myteam.server.news.dto.repository;
2+
3+
import java.time.LocalDateTime;
4+
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
@Getter
9+
@NoArgsConstructor
10+
public class NewsReplyDto {
11+
12+
private Long newsReplyId;
13+
private Long newsCommentId;
14+
private NewsReplyMemberDto memberDto;
15+
private String comment;
16+
private String ip;
17+
private LocalDateTime createTime;
18+
19+
public NewsReplyDto(Long newsReplyId, Long newsCommentId, NewsReplyMemberDto memberDto, String comment,
20+
String ip, LocalDateTime createTime) {
21+
this.newsReplyId = newsReplyId;
22+
this.newsCommentId = newsCommentId;
23+
this.memberDto = memberDto;
24+
this.comment = comment;
25+
this.ip = ip;
26+
this.createTime = createTime;
27+
}
28+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.myteam.server.news.dto.repository;
2+
3+
import lombok.Getter;
4+
import lombok.NoArgsConstructor;
5+
6+
@Getter
7+
@NoArgsConstructor
8+
public class NewsReplyMemberDto {
9+
private Long id;
10+
private String nickName;
11+
12+
public NewsReplyMemberDto(Long id, String nickName) {
13+
this.id = id;
14+
this.nickName = nickName;
15+
}
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.myteam.server.news.dto.service.request;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
7+
@Getter
8+
@NoArgsConstructor
9+
public class NewsReplySaveServiceRequest {
10+
private Long newsCommentId;
11+
private String comment;
12+
private String ip;
13+
14+
@Builder
15+
public NewsReplySaveServiceRequest(Long newsCommentId, String comment, String ip) {
16+
this.newsCommentId = newsCommentId;
17+
this.comment = comment;
18+
this.ip = ip;
19+
}
20+
}

0 commit comments

Comments
 (0)