From 3e09cb7fb36b396e87b23bcef13338eb1aad153e Mon Sep 17 00:00:00 2001 From: leeheefull Date: Wed, 11 Dec 2024 22:35:51 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B7=B8=EB=A3=B9=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=20=EC=9D=91=EB=8B=B5=EA=B0=92=EC=97=90=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/group/application/GroupFacade.kt | 8 ++++++-- .../group/application/GroupTagService.kt | 8 ++++++++ .../infrastructure/GroupTagQRepository.kt | 3 +++ .../infrastructure/GroupTagQRepositoryImpl.kt | 19 +++++++++++++++++++ .../result/GroupTagQueryResult.kt | 8 ++++++++ .../model/response/SearchGroupResponse.kt | 7 +++++-- 6 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/result/GroupTagQueryResult.kt diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt index ca8b5f8..7ce31cc 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt @@ -258,15 +258,19 @@ class GroupFacade( suspend fun searchGroup(user: AuthUser, keyword: String?, pageRequest: HeroPageRequest): Page { val groups = groupService.findByKeywordAndPage(keyword, pageRequest.toDefault()) + val groupIds = groups.content.map { group -> group.id } - val groupUserByUid = groups.content.map { group -> group.id } + val groupUserByUid = groupIds .run { groupUserService.findByUidAndGroupIdIn(user.uid, this) } .associateBy { groupUser -> groupUser.groupId } + val groupTagsByGroupId = groupTagService.findGroupTagNamesByGroupIds(groupIds) + return groups .map { group -> val hasJoined = groupUserByUid[group.id] != null - SearchGroupResponse.from(group, hasJoined) + val groupTags = groupTagsByGroupId[group.id] + SearchGroupResponse.from(group, hasJoined, groupTags) } } diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt index 622269e..6fc63c1 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt @@ -50,6 +50,14 @@ class GroupTagService( } } + suspend fun findGroupTagNamesByGroupIds(groupIds: List): Map> { + return withContext(Dispatchers.IO) { + groupTagRepository.findByGroupIds(groupIds) + .groupBy { it.groupId } + .mapValues { entry -> entry.value.map { it.tagName } } + } + } + fun validateGroupTag(tagNames: List) { if (tagNames.size > 3) { throw InvalidRequestException(ErrorCode.OVER_COUNT_GROUP_TAG_ERROR) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt index 6cf05f8..70e513d 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt @@ -1,9 +1,12 @@ package com.hero.alignlab.domain.group.infrastructure import com.hero.alignlab.domain.group.domain.GroupTag +import com.hero.alignlab.domain.group.infrastructure.result.GroupTagQueryResult interface GroupTagQRepository { fun findByGroupId(groupId: Long): List + fun findByGroupIds(groupIds: List): List + fun deleteGroupTagMapByGroupId(groupId: Long) } \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt index 529eba4..220f20f 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt @@ -3,6 +3,8 @@ package com.hero.alignlab.domain.group.infrastructure import com.hero.alignlab.domain.group.domain.GroupTag import com.hero.alignlab.domain.group.domain.QGroupTag.groupTag import com.hero.alignlab.domain.group.domain.QGroupTagMap.groupTagMap +import com.hero.alignlab.domain.group.infrastructure.result.GroupTagQueryResult +import com.querydsl.core.types.Projections import com.querydsl.jpa.impl.JPAQueryFactory class GroupTagQRepositoryImpl( @@ -15,6 +17,23 @@ class GroupTagQRepositoryImpl( .fetch() } + override fun findByGroupIds(groupIds: List): List { + return queryFactory + .select( + Projections.constructor( + GroupTagQueryResult::class.java, + groupTag.id, + groupTagMap.groupId, + groupTag.name, + ) + ) + .from(groupTag) + .join(groupTagMap).on(groupTag.id.eq(groupTagMap.tagId)) + .where(groupTagMap.groupId.`in`(groupIds)) + .fetch() + } + + override fun deleteGroupTagMapByGroupId(groupId: Long) { queryFactory.delete(groupTagMap) .where(groupTagMap.groupId.eq(groupId)) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/result/GroupTagQueryResult.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/result/GroupTagQueryResult.kt new file mode 100644 index 0000000..47eeb41 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/result/GroupTagQueryResult.kt @@ -0,0 +1,8 @@ +package com.hero.alignlab.domain.group.infrastructure.result + +/** QueryDsl Projection Class(수정 주의) */ +class GroupTagQueryResult( + val tagId: Long, + val groupId: Long, + val tagName: String, +) \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/SearchGroupResponse.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/SearchGroupResponse.kt index 535577a..a760227 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/SearchGroupResponse.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/SearchGroupResponse.kt @@ -15,16 +15,19 @@ data class SearchGroupResponse( val isHidden: Boolean, /** 그룹에 속해 있는지 여부 */ val hasJoined: Boolean, + /** 그룹 태그 리스트 */ + val tagNames: List, ) { companion object { - fun from(group: Group, hasJoined: Boolean): SearchGroupResponse { + fun from(group: Group, hasJoined: Boolean, tagNames: List?): SearchGroupResponse { return SearchGroupResponse( id = group.id, userCount = group.userCount, userCapacity = group.userCapacity, name = group.name, isHidden = group.isHidden, - hasJoined = hasJoined + hasJoined = hasJoined, + tagNames = tagNames ?: emptyList(), ) } }