diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/exception/exceptions.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/exception/exceptions.kt index ec41991..ea045e2 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/exception/exceptions.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/exception/exceptions.kt @@ -9,7 +9,7 @@ object QuestionNotFoundException : CustomException( ) object QuestionSetNotFoundException : CustomException( - DomainErrorCode.QUESTION_NOT_FOUND + DomainErrorCode.QUESTION_SET_NOT_FOUND ) object AnswerNotFoundException : CustomException( diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/QuestionSets.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/QuestionSets.kt index 5449abf..9f1dc34 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/QuestionSets.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/QuestionSets.kt @@ -18,6 +18,9 @@ class QuestionSets ( @Column(columnDefinition = "DATETIME(6)", nullable = false, updatable = false) var createdAt: LocalDateTime = LocalDateTime.now(), + @Column(columnDefinition = "VARCHAR(1000)", nullable = false) + var description: String, + @Column(columnDefinition = "INT", nullable = false) var answerCount: Int, @@ -27,6 +30,9 @@ class QuestionSets ( @Column(columnDefinition = "INT", nullable = false) var likeCount: Int, + @Column(columnDefinition = "INT", nullable = false) + val dislikeCount: Int, + @Column(columnDefinition = "INT", nullable = false) var viewCount: Int, diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/CategoriesDto.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/CategoriesDto.kt index 312a629..d782b28 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/CategoriesDto.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/CategoriesDto.kt @@ -1,8 +1,11 @@ package kr.hs.dsm.inq.domain.question.persistence.dto +import com.querydsl.core.annotations.QueryProjection import kr.hs.dsm.inq.domain.question.persistence.Category +import org.aspectj.weaver.patterns.TypePatternQuestions.Question +import java.util.Objects -class CategoriesDto ( +class CategoriesDto @QueryProjection constructor ( val category: Category, val count: Int ) \ No newline at end of file diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/QuestionSetDetailDto.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/QuestionSetDetailDto.kt index b5dfab6..e766d46 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/QuestionSetDetailDto.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/dto/QuestionSetDetailDto.kt @@ -10,11 +10,12 @@ class QuestionSetDetailDto @QueryProjection constructor( val questionSetId: Long, val name: String, val createdAt: LocalDateTime, + val description: String, val username: String, val job: String, val jobDuration: Int, - val category: Category, val likeCount: Int, + val dislikeCount: Int, val viewCount: Int, val isLiked: Boolean, val isDisliked: Boolean, 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 f175045..24b5ac6 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 @@ -1,22 +1,22 @@ package kr.hs.dsm.inq.domain.question.persistence.repository +import com.querydsl.core.ResultTransformer import com.querydsl.core.group.GroupBy +import com.querydsl.core.types.Expression +import com.querydsl.core.types.Ops +import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQuery import com.querydsl.jpa.impl.JPAQueryFactory import kr.hs.dsm.inq.common.util.PageResponse import kr.hs.dsm.inq.common.util.PageUtil import kr.hs.dsm.inq.domain.question.persistence.* -import kr.hs.dsm.inq.domain.question.persistence.QAnswers.answers import kr.hs.dsm.inq.domain.question.persistence.QComments.comments import kr.hs.dsm.inq.domain.question.persistence.QQuestionSets.questionSets import kr.hs.dsm.inq.domain.question.persistence.QQuestionSolvingHistory.questionSolvingHistory import kr.hs.dsm.inq.domain.question.persistence.QQuestionTags.questionTags +import kr.hs.dsm.inq.domain.question.persistence.QQuestions.questions import kr.hs.dsm.inq.domain.question.persistence.QTags.tags -import kr.hs.dsm.inq.domain.question.persistence.dto.QAnswersDto -import kr.hs.dsm.inq.domain.question.persistence.dto.QQuestionSetDetailDto -import kr.hs.dsm.inq.domain.question.persistence.dto.QQuestionSetDto -import kr.hs.dsm.inq.domain.question.persistence.dto.QuestionSetDetailDto -import kr.hs.dsm.inq.domain.question.persistence.dto.QuestionSetDto +import kr.hs.dsm.inq.domain.question.persistence.dto.* import kr.hs.dsm.inq.domain.user.persistence.QUser import kr.hs.dsm.inq.domain.user.persistence.User import org.springframework.data.repository.CrudRepository @@ -35,7 +35,7 @@ interface CustomQuestionSetsRepository { page: Long ): PageResponse - fun queryQuestionSetDtoById( + fun queryQuestionSetDetailDtoById( user: User, id: Long ): QuestionSetDetailDto? @@ -67,11 +67,12 @@ class CustomQuestionSetsRepositoryImpl( } @Transactional - override fun queryQuestionSetDtoById( + override fun queryQuestionSetDetailDtoById( user: User, id: Long ): QuestionSetDetailDto? { - queryFactory + + queryFactory .update(questionSets) .set(questionSets.viewCount, questionSets.viewCount.add(1)) .where(questionSets.id.eq(id)) @@ -119,12 +120,13 @@ class CustomQuestionSetsRepositoryImpl( val author = QUser("writer") val liked = QLike("liked") val favorite = QFavorite("favorite") + return@run leftJoin(questionTags).on(questionTags.problems.eq(questionSets.problem)) .leftJoin(tags).on(tags.id.eq(questionTags.id.tagId)) .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(favorite).on(favorite.id.userId.eq(user.id)).on(favorite.problemId.eq(questionSets.problem)) - .rightJoin(comments).on(comments.post.eq(questionSets.post)) + .leftJoin(comments).on(comments.post.eq(questionSets.post)) .transform( GroupBy.groupBy(questionSets) .list( @@ -132,19 +134,20 @@ class CustomQuestionSetsRepositoryImpl( /* questionSetId = */ questionSets.id, /* name = */ questionSets.name, /* createdAt = */ questionSets.createdAt, + /* description = */ questionSets.description, /* username = */ author.username, /* job = */ author.job, /* jobDuration = */ author.jobDuration, - /* category = */ questionSets.category, /* likeCount = */ questionSets.likeCount, + /* dislikeCount = */ questionSets.dislikeCount, /* viewCount = */ questionSets.viewCount, /* isLiked = */ liked.isLiked.isTrue, /* isDisliked = */ liked.isLiked.isFalse, /* isFavorite = */ favorite.isNotNull, /* tagList = */ GroupBy.list(tags), - /* comments = */ GroupBy.list(comments) + /* commentList = */ GroupBy.list(comments) ) ) ) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/SetQuestionRepository.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/SetQuestionRepository.kt index e4e6fc6..715ad18 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/SetQuestionRepository.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/persistence/repository/SetQuestionRepository.kt @@ -4,5 +4,6 @@ import kr.hs.dsm.inq.domain.question.persistence.SetQuestion import kr.hs.dsm.inq.domain.question.persistence.SetQuestionId import org.springframework.data.repository.CrudRepository -interface SetQuestionRepository : CrudRepository { +interface SetQuestionRepository : CrudRepository, CustomQuestionRepository { + fun findAllBySetId(setId: Long): List } \ No newline at end of file diff --git a/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Requests.kt b/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Requests.kt index 945048e..7b8cf29 100644 --- a/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Requests.kt +++ b/src/main/kotlin/kr/hs/dsm/inq/domain/question/presentation/dto/Requests.kt @@ -45,6 +45,7 @@ data class GetPopularQuestionRequest( data class QuestionSetsRequest( val questionSetName: String, + val description: String, val category: Category, val questionId: List, val tag: List, 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 7f73f2c..1d10555 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 @@ -2,10 +2,7 @@ package kr.hs.dsm.inq.domain.question.presentation.dto import kr.hs.dsm.inq.common.util.PageResponse import kr.hs.dsm.inq.common.util.PageUtil -import kr.hs.dsm.inq.domain.question.persistence.Category -import kr.hs.dsm.inq.domain.question.persistence.Comments -import kr.hs.dsm.inq.domain.question.persistence.QuestionSets -import kr.hs.dsm.inq.domain.question.persistence.Tags +import kr.hs.dsm.inq.domain.question.persistence.* import kr.hs.dsm.inq.domain.question.persistence.dto.* import java.time.LocalDateTime import java.util.Date @@ -195,8 +192,8 @@ data class GetQuestionSetResponse( val hasNext: Boolean, val questionSetsList: List, ) { - companion object{ - fun of(pageResponse: PageResponse) = pageResponse.run{ + companion object { + fun of(pageResponse: PageResponse) = pageResponse.run { GetQuestionSetResponse( hasNext = hasNext, questionSetsList = list.map { QuestionSet.of(it) } @@ -205,21 +202,21 @@ data class GetQuestionSetResponse( } } -data class QuestionSet ( - val questionSetId : Long?, - val questionSetName : String?, +data class QuestionSet( + val questionSetId: Long?, + val questionSetName: String?, val createdAt: LocalDateTime, val category: Category?, - val username : String?, - val job : String?, - val jobDuration : Int?, - val tags : List?, - val isAnswered : Boolean?, - val likeCount : Int?, - val viewCount : Int?, + val username: String?, + val job: String?, + val jobDuration: Int?, + val tags: List?, + val isAnswered: Boolean?, + val likeCount: Int?, + val viewCount: Int?, ) { companion object { - fun of (dto: QuestionSetDto) = dto.run { + fun of(dto: QuestionSetDto) = dto.run { QuestionSet( questionSetId = questionSetId, questionSetName = questionSetName, @@ -241,11 +238,13 @@ data class GetQuestionSetDetailResponse( val questionSetId: Long, val name: String, val createdAt: LocalDateTime, + val description: String, val username: String, val job: String, val jobDuration: Int, - val category: Category, + val category: List?, val likeCount: Int, + val dislikeCount: Int, val viewCount: Int, val isLiked: Boolean, val isDisliked: Boolean, @@ -254,16 +253,26 @@ data class GetQuestionSetDetailResponse( val comments: List ) { companion object { - fun of(questionSetDetail: QuestionSetDetailDto) = questionSetDetail.run { + fun of(questionSetDetail: QuestionSetDetailDto, questionList: List) = questionSetDetail.run { GetQuestionSetDetailResponse( questionSetId = questionSetId, name = name, createdAt = createdAt, + description = description, username = username, job = job, jobDuration = jobDuration, - category = category, + category = questionList + .groupingBy { it.category } + .eachCount() + .map { + CategoriesDto( + category = it.key, + count = it.value + ) + }, likeCount = likeCount, + dislikeCount = dislikeCount, viewCount = viewCount, isLiked = isLiked, isDisliked = isDisliked, 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 4b0aeee..3c17daf 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 @@ -7,6 +7,7 @@ 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 @@ -319,8 +320,10 @@ class QuestionService( QuestionSets( name = request.questionSetName, answerCount = 0, + description = request.description, category = request.category, likeCount = 0, + dislikeCount = 0, viewCount = 0, post = post, problem = problem, @@ -395,11 +398,14 @@ class QuestionService( val user = SecurityUtil.getCurrentUser() val questionSetDetail = questionSetId.run { - questionSetsRepository.queryQuestionSetDtoById(user, questionSetId) + questionSetsRepository.queryQuestionSetDetailDtoById(user, questionSetId) ?: throw QuestionSetNotFoundException } - return GetQuestionSetDetailResponse.of(questionSetDetail) + val setQuestionList = setQuestionRepository.findAllBySetId(questionSetDetail.questionSetId) + val questionList = questionsRepository.findByIdIn(setQuestionList.map { it.question.id }) + + return GetQuestionSetDetailResponse.of(questionSetDetail, questionList) } fun answerQuestionSet(questionSetId: Long){