diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/Favorite.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/Favorite.kt index 18d206f..55b3320 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/Favorite.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/Favorite.kt @@ -23,7 +23,7 @@ class Favorite( @MapsId("problemId") @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "problem_id", columnDefinition = "BIGINT", nullable = false) - val problemId: Problem, + val problem: Problem, @MapsId("userId") @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/FavoriteRepository.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/FavoriteRepository.kt index a4840bf..dcc1a16 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/FavoriteRepository.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/FavoriteRepository.kt @@ -1,7 +1,10 @@ package kr.hs.dsm.inq.domain.question.persistence.repository import kr.hs.dsm.inq.domain.question.persistence.Favorite +import kr.hs.dsm.inq.domain.question.persistence.FavoriteId import org.springframework.data.repository.CrudRepository interface FavoriteRepository: CrudRepository { + fun findById(id: FavoriteId): Favorite? + fun deleteById(id: FavoriteId) } \ No newline at end of file diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/QuestionSetsRepository.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/QuestionSetsRepository.kt index fb4f422..3c10f01 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/QuestionSetsRepository.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/QuestionSetsRepository.kt @@ -129,7 +129,7 @@ class CustomQuestionSetsRepositoryImpl( .innerJoin(author).on(author.id.eq(questionSets.author.id)) .leftJoin(liked).on(liked.id.userId.eq(user.id)).on(liked.post.eq(questionSets.post)) .leftJoin(post).on(post.id.eq(questionSets.post.id)) - .leftJoin(favorite).on(favorite.id.userId.eq(user.id)).on(favorite.problemId.eq(questionSets.problem)) + .leftJoin(favorite).on(favorite.id.userId.eq(user.id)).on(favorite.problem.eq(questionSets.problem)) .leftJoin(comments).on(comments.post.eq(questionSets.post)) .transform( GroupBy.groupBy(questionSets) diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/QuestionController.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/QuestionController.kt index 1afc90b..2a989be 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/QuestionController.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/QuestionController.kt @@ -118,7 +118,7 @@ class QuestionController( return questionService.answerQuestionInQuestionSet(questionId, answerRequest) } - @PostMapping("//{question-id}/difficulty") + @PostMapping("/{question-id}/difficulty") fun assessDifficulty( @PathVariable("question-id") questionId: Long, @RequestParam level: DifficultyLevel @@ -133,4 +133,14 @@ class QuestionController( fun getQuestionSetRank(@Valid @ModelAttribute request: GetQuestionSetRankRequest): GetQuestionSetResponse { return questionService.getQuestionSetRank(request) } + + @PostMapping("/{question-id}/favorite") + fun questionFavorite(@PathVariable("question-id") questionId: Long): FavoriteResponse{ + return questionService.questionFavorite(questionId) + } + + @PostMapping("/set/{question-set-id}/favorite") + fun questionSetFavorite(@PathVariable("question-set-id") questionSetId: Long): FavoriteResponse{ + return questionService.questionSetFavorite(questionSetId) + } } \ No newline at end of file diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Responses.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Responses.kt index 155c91e..647567c 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Responses.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Responses.kt @@ -326,4 +326,8 @@ data class DifficultyResponse( val normal: Int, val hard: Int, val veryHard: Int +) + +data class FavoriteResponse( + val isFavorite: Boolean ) \ No newline at end of file diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/service/QuestionService.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/service/QuestionService.kt index 440e755..10ce196 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/service/QuestionService.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/service/QuestionService.kt @@ -1,11 +1,5 @@ package kr.hs.dsm.inq.domain.question.service -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.ZoneId -import java.time.ZoneOffset -import java.time.ZonedDateTime -import java.util.Date import kr.hs.dsm.inq.common.util.SecurityUtil import kr.hs.dsm.inq.common.util.defaultPage import kr.hs.dsm.inq.domain.question.exception.AlreadyDislikedPostException @@ -13,7 +7,6 @@ import kr.hs.dsm.inq.domain.question.exception.AlreadyLikedPostException import kr.hs.dsm.inq.domain.question.exception.AnswerNotFoundException import kr.hs.dsm.inq.domain.question.exception.QuestionNotFoundException import kr.hs.dsm.inq.domain.question.exception.QuestionSetNotFoundException -import kr.hs.dsm.inq.domain.question.exception.* import kr.hs.dsm.inq.domain.question.persistence.* import kr.hs.dsm.inq.domain.question.persistence.dto.AnswersDto import kr.hs.dsm.inq.domain.question.persistence.dto.CategoriesDto @@ -38,7 +31,8 @@ class QuestionService( private val questionSetsRepository: QuestionSetsRepository, private val setQuestionRepository: SetQuestionRepository, private val questionSolvingHistoryRepository: QuestionSolvingHistoryRepository, - private val difficultyRepository: DifficultyRepository + private val difficultyRepository: DifficultyRepository, + private val favoriteRepository: FavoriteRepository, ) { fun createQuestion(request: CreateQuestionRequest): CreateQuestionResponses { @@ -483,4 +477,43 @@ class QuestionService( pageResponse = questionSetList ) } + + fun questionFavorite(questionId: Long): FavoriteResponse { + val user = SecurityUtil.getCurrentUser() + + val problem = questionsRepository.findByIdOrNull(questionId)?.problem + ?: throw QuestionNotFoundException + + return favorite(user, problem) + } + + fun questionSetFavorite(questionSetId: Long): FavoriteResponse { + val user = SecurityUtil.getCurrentUser() + + val problem = questionSetsRepository.findByIdOrNull(questionSetId)?.problem + ?: throw QuestionSetNotFoundException + + return favorite(user, problem) + } + + fun favorite(user: User, problem: Problem): FavoriteResponse{ + val id = FavoriteId( + problemId = problem.id, + userId = user.id, + ) + + return favoriteRepository.findById(id)?.let { + favoriteRepository.deleteById(id) + FavoriteResponse(false) + } ?: run { + favoriteRepository.save( + Favorite( + id = id, + problem = problem, + user = user + ) + ) + FavoriteResponse(true) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/kr/hs/dsm/inq/global/error/ErrorCode.kt b/src/main/kotlin/kr/hs/dsm/inq/global/error/ErrorCode.kt index 06b752a..20ff168 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/global/error/ErrorCode.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/global/error/ErrorCode.kt @@ -16,7 +16,7 @@ enum class DomainErrorCode( ANSWER_NOT_FOUND(ErrorStatus.NOT_FOUND, "Answer Not Found", 3), TAG_NOT_FOUND(ErrorStatus.NOT_FOUND, "Tag Not Found", 4), ATTENDANCE_NOT_FOUND(ErrorStatus.NOT_FOUND, "Attendance Not Found", 5), - QUESTION_SET_NOT_FOUND(ErrorStatus.NOT_FOUND, "Question Not Found", 6), + QUESTION_SET_NOT_FOUND(ErrorStatus.NOT_FOUND, "Question Set Not Found", 6), ALREADY_LIKED_POST(ErrorStatus.CONFLICT, "Already liked post", 1), ALREADY_DISLIKED_POST(ErrorStatus.CONFLICT, "Already disliked post", 2),