-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[FEAT] 질문 답변 조회 기능
- Loading branch information
Showing
14 changed files
with
250 additions
and
16 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
plu-api/src/main/kotlin/com/th/plu/api/controller/answer/AnswerController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.th.plu.api.controller.answer | ||
|
||
import com.th.plu.api.config.interceptor.Auth | ||
import com.th.plu.api.config.resolver.MemberId | ||
import com.th.plu.api.controller.answer.dto.response.AnswerInfoResponse | ||
import com.th.plu.api.service.answer.AnswerService | ||
import com.th.plu.common.dto.response.ApiResponse | ||
import io.swagger.v3.oas.annotations.Operation | ||
import io.swagger.v3.oas.annotations.tags.Tag | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
@Tag(name = "Answer") | ||
@RestController | ||
@RequestMapping("/api") | ||
class AnswerController( | ||
private val answerService: AnswerService | ||
) { | ||
@Auth | ||
@Operation(summary = "답변 조회") | ||
@GetMapping("/v1/answer/{answerId}") | ||
fun findAnswerById(@PathVariable answerId: Long, @MemberId memberId: Long): ApiResponse<AnswerInfoResponse> { | ||
return ApiResponse.success(answerService.findAnswerInfoById(answerId, memberId)) | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
plu-api/src/main/kotlin/com/th/plu/api/controller/answer/dto/response/AnswerInfoResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.th.plu.api.controller.answer.dto.response | ||
|
||
import com.th.plu.domain.domain.answer.Answer | ||
import com.th.plu.domain.domain.question.Question | ||
import java.time.LocalDateTime | ||
|
||
data class AnswerInfoResponse( | ||
val questionDate: LocalDateTime, | ||
val questionTitle: String, | ||
val answer: String, | ||
val likeCount: Int, | ||
val elementImageUrl: String, | ||
val colorCode: String | ||
) { | ||
companion object { | ||
fun of(question: Question, answer: Answer): AnswerInfoResponse { | ||
return AnswerInfoResponse( | ||
questionDate = question.modifiedAt, | ||
questionTitle = question.title, | ||
answer = answer.content, | ||
likeCount = answer.getLikeCount(), | ||
elementImageUrl = question.elementType.elementImageUrl, | ||
colorCode = question.elementType.colorCode | ||
) | ||
} | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
plu-api/src/main/kotlin/com/th/plu/api/service/answer/AnswerService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.th.plu.api.service.answer | ||
|
||
import com.th.plu.api.controller.answer.dto.response.AnswerInfoResponse | ||
import com.th.plu.domain.domain.answer.explorer.AnswerExplorer | ||
import com.th.plu.domain.domain.answer.explorer.QuestionExplorer | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
@Service | ||
class AnswerService( | ||
private val questionExplorer: QuestionExplorer, | ||
private val answerExplorer: AnswerExplorer, | ||
private val answerValidator: AnswerValidator | ||
) { | ||
@Transactional(readOnly = true) | ||
fun findAnswerInfoById(answerId: Long, memberId: Long): AnswerInfoResponse { | ||
val answer = answerExplorer.findAnswerById(answerId) | ||
if (!answer.isPublic) { | ||
answerValidator.validateIsMemberOwnerOfAnswer(answerId, memberId) | ||
} | ||
val question = questionExplorer.findQuestionById(answer.getQuestionId()) | ||
|
||
return AnswerInfoResponse.of(question, answer) | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
plu-api/src/main/kotlin/com/th/plu/api/service/answer/AnswerValidator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.th.plu.api.service.answer | ||
|
||
import com.th.plu.common.exception.code.ErrorCode | ||
import com.th.plu.common.exception.model.ValidationException | ||
import com.th.plu.domain.domain.answer.explorer.AnswerExplorer | ||
import com.th.plu.domain.domain.answer.repository.AnswerRepository | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class AnswerValidator( | ||
private val answerExplorer: AnswerExplorer, | ||
private val answerRepository: AnswerRepository | ||
) { | ||
fun validateIsMemberOwnerOfAnswer(answerId: Long, memberId: Long) { | ||
val answer = answerExplorer.findAnswerById(answerId) | ||
if (answer.member.id != memberId) { | ||
throw ValidationException(ErrorCode.INVALID_ANSWER_OWNER, | ||
"멤버 (ID: ${memberId})는 답변 (ID: ${answerId})의 답변자가 아니기 때문에 답변 정보에 접근할 수 없습니다.") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
plu-domain/src/main/kotlin/com/th/plu/domain/domain/answer/explorer/AnswerExplorer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.th.plu.domain.domain.answer.explorer | ||
|
||
import com.th.plu.common.exception.code.ErrorCode | ||
import com.th.plu.common.exception.model.NotFoundException | ||
import com.th.plu.domain.domain.answer.Answer | ||
import com.th.plu.domain.domain.answer.repository.AnswerRepository | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class AnswerExplorer( | ||
private val answerRepository: AnswerRepository | ||
) { | ||
fun findAnswerById(id: Long): Answer { | ||
return answerRepository.findAnswerById(id) | ||
?: throw NotFoundException(ErrorCode.NOT_FOUND_ANSWER_EXCEPTION, "존재하지 않는 답변(ID: $id) 입니다") | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
plu-domain/src/main/kotlin/com/th/plu/domain/domain/like/Like.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.th.plu.domain.domain.like | ||
|
||
import com.th.plu.domain.domain.answer.Answer | ||
import com.th.plu.domain.domain.common.BaseEntity | ||
import com.th.plu.domain.domain.member.Member | ||
import com.th.plu.domain.domain.question.Question | ||
import jakarta.persistence.* | ||
|
||
@Table(name = "likes") | ||
@Entity | ||
class Like( | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "like_id") | ||
var id: Long? = null, | ||
|
||
@ManyToOne(fetch = FetchType.LAZY, cascade = [CascadeType.ALL]) | ||
@JoinColumn(name = "member_id", nullable = false) | ||
var member: Member, | ||
|
||
@ManyToOne(fetch = FetchType.LAZY, cascade = [CascadeType.ALL]) | ||
@JoinColumn(name = "answer_id", nullable = false) | ||
var answer: Answer, | ||
|
||
@ManyToOne(fetch = FetchType.LAZY, cascade = [CascadeType.ALL]) | ||
@JoinColumn(name = "question_id", nullable = false) | ||
var question: Question | ||
|
||
) : BaseEntity() { | ||
|
||
companion object { | ||
fun newInstance( | ||
member: Member, answer: Answer, question: Question | ||
): Like { | ||
return Like( | ||
member = member, | ||
answer = answer, | ||
question = question | ||
) | ||
} | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
plu-domain/src/main/kotlin/com/th/plu/domain/domain/like/repository/LikeRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.th.plu.domain.domain.like.repository | ||
|
||
import com.th.plu.domain.domain.member.Member | ||
import org.springframework.data.jpa.repository.JpaRepository | ||
|
||
interface LikeRepository : JpaRepository<Member, Long>, LikeRepositoryCustom { | ||
} |
8 changes: 8 additions & 0 deletions
8
plu-domain/src/main/kotlin/com/th/plu/domain/domain/like/repository/LikeRepositoryCustom.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.th.plu.domain.domain.like.repository | ||
|
||
import com.th.plu.domain.domain.like.Like | ||
|
||
interface LikeRepositoryCustom { | ||
|
||
fun findLikeById(id: Long): Like? | ||
} |
16 changes: 16 additions & 0 deletions
16
plu-domain/src/main/kotlin/com/th/plu/domain/domain/like/repository/LikeRepositoryImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.th.plu.domain.domain.like.repository | ||
|
||
import com.querydsl.jpa.impl.JPAQueryFactory | ||
import com.th.plu.domain.domain.like.Like | ||
import com.th.plu.domain.domain.like.QLike.like | ||
import org.springframework.stereotype.Repository | ||
|
||
@Repository | ||
class LikeRepositoryImpl(private val queryFactory: JPAQueryFactory) : LikeRepositoryCustom { | ||
override fun findLikeById(id: Long): Like? { | ||
return queryFactory | ||
.selectFrom(like) | ||
.where(like.id.eq(id)) | ||
.fetchOne(); | ||
} | ||
} |
6 changes: 3 additions & 3 deletions
6
plu-domain/src/main/kotlin/com/th/plu/domain/domain/question/ElementType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
plu-domain/src/main/kotlin/com/th/plu/domain/domain/question/explorer/QuestionExplorer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.th.plu.domain.domain.answer.explorer | ||
|
||
import com.th.plu.common.exception.code.ErrorCode | ||
import com.th.plu.common.exception.model.NotFoundException | ||
import com.th.plu.domain.domain.question.Question | ||
import com.th.plu.domain.domain.question.repository.QuestionRepository | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class QuestionExplorer( | ||
private val questionRepository: QuestionRepository | ||
) { | ||
fun findQuestionById(id: Long): Question { | ||
return questionRepository.findQuestionById(id) | ||
?: throw NotFoundException(ErrorCode.NOT_FOUND_QUESTION_EXCEPTION, "존재하지 않는 질문(ID: $id) 입니다") | ||
} | ||
} |