Skip to content

Commit 83f7187

Browse files
authored
Epic/inquiry 문의하기 정렬처리 (#105)
1 parent 07ffd39 commit 83f7187

File tree

16 files changed

+352
-21
lines changed

16 files changed

+352
-21
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,14 @@ public enum ErrorCode {
5454
NEWS_NOT_FOUND(HttpStatus.NOT_FOUND, "News not found"),
5555
NEWS_COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "New Comment not found"),
5656
NEWS_REPLY_NOT_FOUND(HttpStatus.NOT_FOUND, "New Reply not found"),
57+
INQUIRY_NOT_FOUND(HttpStatus.NOT_FOUND, "Inquiry not found"),
58+
INQUIRY_ANSWER_NOT_FOUND(HttpStatus.NOT_FOUND, "Inquiry answer not found"),
5759
NEWS_COUNT_NOT_FOUND(HttpStatus.NOT_FOUND, "News Count not found"),
5860

5961
// 409 Conflict,
6062
USER_ALREADY_EXISTS(HttpStatus.CONFLICT, "User already exists"),
61-
BAN_ALREADY_EXISTS(HttpStatus.CONFLICT, "This user already exists");
63+
BAN_ALREADY_EXISTS(HttpStatus.CONFLICT, "This user already exists"),
64+
INQUIRY_ANSWER_ALREADY_EXISTS(HttpStatus.CONFLICT, "This inquiry already exists");
6265

6366
private final HttpStatus status;
6467
private final String msg;

src/main/java/org/myteam/server/global/security/config/SecurityConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public class SecurityConfig {
8989
/** @brief Check Access Admin */"/test/admin/**",
9090

9191
"/api/admin/**",
92+
"/api/inquiries/answers/**",
9293
};
9394
/* member 접근 권한 */
9495
private static final String[] PERMIT_MEMBER_URLS = new String[]{
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.myteam.server.inquiry.controller;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.myteam.server.global.page.request.PageInfoRequest;
6+
import org.myteam.server.global.web.response.ResponseDto;
7+
import org.myteam.server.inquiry.service.InquiryAnswerReadService;
8+
import org.myteam.server.inquiry.service.InquiryAnswerWriteService;
9+
import org.springframework.http.ResponseEntity;
10+
import org.springframework.web.bind.annotation.*;
11+
12+
import static org.myteam.server.global.web.response.ResponseStatus.SUCCESS;
13+
14+
@Slf4j
15+
@RestController
16+
@RequestMapping("/api/inquiries/answers")
17+
@RequiredArgsConstructor
18+
public class InquiryAnswerController {
19+
20+
private final InquiryAnswerWriteService inquiryAnswerWriteService;
21+
22+
@PostMapping("/{inquiryId}")
23+
public ResponseEntity<ResponseDto<String>> addAnswer(@PathVariable Long inquiryId, @RequestBody String answerContent) {
24+
inquiryAnswerWriteService.createAnswer(inquiryId, answerContent);
25+
return ResponseEntity.ok(new ResponseDto<>(
26+
SUCCESS.name(),
27+
"답변이 성공적으로 등록되었습니다.",
28+
null
29+
));
30+
}
31+
32+
@PutMapping("/{inquiryId}")
33+
public ResponseEntity<ResponseDto<String>> updateAnswer(@PathVariable Long inquiryId, @RequestBody String updateContent) {
34+
inquiryAnswerWriteService.updateAnswer(inquiryId, updateContent);
35+
return ResponseEntity.ok(new ResponseDto<>(
36+
SUCCESS.name(),
37+
"답변이 성공적으로 수정되었습니다.",
38+
null
39+
));
40+
}
41+
42+
@DeleteMapping("/{inquiryId}")
43+
public ResponseEntity<ResponseDto<String>> deleteAnswer(@PathVariable Long inquiryId) {
44+
inquiryAnswerWriteService.deleteAnswer(inquiryId);
45+
return ResponseEntity.ok(new ResponseDto<>(
46+
SUCCESS.name(),
47+
"답변이 성공적으로 삭제되었습니다.",
48+
null
49+
));
50+
}
51+
52+
}

src/main/java/org/myteam/server/inquiry/controller/InquiryController.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import org.myteam.server.global.page.request.PageInfoRequest;
88
import org.myteam.server.global.page.response.PageCustomResponse;
99
import org.myteam.server.global.web.response.ResponseDto;
10-
import org.myteam.server.inquiry.domain.Inquiry;
10+
import org.myteam.server.inquiry.dto.request.InquiryFindRequest;
1111
import org.myteam.server.inquiry.dto.request.InquiryRequest;
1212
import org.myteam.server.inquiry.dto.response.InquiryResponse;
1313
import org.myteam.server.inquiry.service.InquiryReadService;
@@ -28,7 +28,7 @@ public class InquiryController {
2828
private final InquiryReadService inquiryReadService;
2929
private final InquiryWriteService inquiryWriteService;
3030

31-
@PostMapping()
31+
@PostMapping
3232
public ResponseEntity<ResponseDto<String>> createInquiry(@Valid @RequestBody InquiryRequest inquiryRequest,
3333
HttpServletRequest request) {
3434
String clientIp = ClientUtils.getRemoteIP(request);
@@ -42,8 +42,8 @@ public ResponseEntity<ResponseDto<String>> createInquiry(@Valid @RequestBody Inq
4242
}
4343

4444
@GetMapping("/my")
45-
public ResponseEntity<ResponseDto<PageCustomResponse<InquiryResponse>>> getMyInquiries(@RequestParam UUID memberPublicId, PageInfoRequest pageInfoRequest) {
46-
PageCustomResponse<InquiryResponse> content = inquiryReadService.getInquiriesByMember(memberPublicId, pageInfoRequest);
45+
public ResponseEntity<ResponseDto<PageCustomResponse<InquiryResponse>>> getMyInquiries(@ModelAttribute @Valid InquiryFindRequest request) {
46+
PageCustomResponse<InquiryResponse> content = inquiryReadService.getInquiriesByMember(request);
4747

4848
return ResponseEntity.ok(new ResponseDto<>(
4949
SUCCESS.name(),

src/main/java/org/myteam/server/inquiry/domain/Inquiry.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class Inquiry {
1818
@GeneratedValue(strategy = GenerationType.IDENTITY)
1919
private Long id;
2020

21+
@NotNull(message = "문의 내용이 없으면 안됩니다.")
2122
private String content;
2223

2324
@ManyToOne(optional = true, cascade = CascadeType.REMOVE)
@@ -28,4 +29,11 @@ public class Inquiry {
2829

2930
@Column(name = "created_at", nullable = false, updatable = false)
3031
private LocalDateTime createdAt;
32+
33+
@OneToOne(mappedBy = "inquiry", cascade = CascadeType.ALL, orphanRemoval = true)
34+
private InquiryAnswer inquiryAnswer;
35+
36+
public void addAnswer(InquiryAnswer inquiryAnswer) {
37+
this.inquiryAnswer = inquiryAnswer;
38+
}
3139
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.myteam.server.inquiry.domain;
2+
3+
import jakarta.persistence.*;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.time.LocalDateTime;
10+
11+
@Entity
12+
@Getter
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
@Builder
16+
public class InquiryAnswer {
17+
18+
@Id
19+
@GeneratedValue(strategy = GenerationType.IDENTITY)
20+
private Long id;
21+
22+
@OneToOne
23+
@JoinColumn(name = "inquiry_id", nullable = false, unique = true)
24+
private Inquiry inquiry;
25+
26+
@Column(nullable = false)
27+
private String content;
28+
29+
@Column(name = "answered_at", nullable = false)
30+
private LocalDateTime answeredAt;
31+
32+
public static InquiryAnswer createAnswer(Inquiry inquiry, String content) {
33+
return InquiryAnswer.builder()
34+
.inquiry(inquiry)
35+
.content(content)
36+
.answeredAt(LocalDateTime.now())
37+
.build();
38+
}
39+
40+
public void updateContent(String content) {
41+
this.content = content;
42+
this.answeredAt = LocalDateTime.now();
43+
}
44+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.myteam.server.inquiry.domain;
2+
3+
public enum InquiryOrderType {
4+
RECENT,
5+
ANSWERED
6+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.myteam.server.inquiry.dto.request;
2+
3+
import jakarta.validation.constraints.NotNull;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
import lombok.Setter;
8+
import org.myteam.server.global.page.request.PageInfoRequest;
9+
import org.myteam.server.global.page.request.PageInfoServiceRequest;
10+
import org.myteam.server.inquiry.domain.InquiryOrderType;
11+
12+
import java.util.UUID;
13+
14+
@Getter
15+
@Setter
16+
@NoArgsConstructor
17+
public class InquiryFindRequest extends PageInfoServiceRequest {
18+
19+
@NotNull(message = "멤버 id는 필수입니다.")
20+
private UUID memberPublicId;
21+
22+
@NotNull(message = "문의하기 정렬 타입은 필수입니다.")
23+
private InquiryOrderType orderType;
24+
25+
@Builder
26+
public InquiryFindRequest(UUID memberPublicId, InquiryOrderType orderType, int page, int size) {
27+
super(page, size);
28+
this.memberPublicId = memberPublicId;
29+
this.orderType = orderType;
30+
}
31+
}

src/main/java/org/myteam/server/inquiry/dto/response/InquiryResponse.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.NoArgsConstructor;
66
import lombok.AllArgsConstructor;
77
import org.myteam.server.inquiry.domain.Inquiry;
8+
import org.myteam.server.inquiry.domain.InquiryAnswer;
89

910
import java.time.LocalDateTime;
1011

@@ -18,14 +19,20 @@ public class InquiryResponse {
1819
private String memberNickname;
1920
private String clientIp;
2021
private LocalDateTime createdAt;
22+
private String answerContent;
23+
private LocalDateTime answeredAt;
2124

2225
// Entity -> DTO 변환 메서드
2326
public static InquiryResponse createInquiryResponse(Inquiry inquiry) {
27+
InquiryAnswer inquiryAnswer = inquiry.getInquiryAnswer();
28+
2429
return InquiryResponse.builder()
2530
.id(inquiry.getId())
2631
.content(inquiry.getContent())
2732
.memberNickname(inquiry.getMember().getNickname())
2833
.createdAt(inquiry.getCreatedAt())
34+
.answerContent(inquiryAnswer != null ? inquiryAnswer.getContent() : "답변 없음")
35+
.answeredAt(inquiryAnswer != null ? inquiryAnswer.getAnsweredAt() : null)
2936
.build();
3037
}
3138
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.myteam.server.inquiry.repository;
2+
3+
import org.myteam.server.inquiry.domain.Inquiry;
4+
import org.myteam.server.inquiry.domain.InquiryAnswer;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.stereotype.Repository;
7+
8+
@Repository
9+
public interface InquiryAnswerRepository extends JpaRepository<InquiryAnswer, Long> {
10+
InquiryAnswer findByInquiryId(Long inquiryId);
11+
}

0 commit comments

Comments
 (0)