콘텐츠 카테고리
- 등록 API 추가
This commit is contained in:
		| @@ -0,0 +1,18 @@ | ||||
| package kr.co.vividnext.sodalive.content.category | ||||
|  | ||||
| import kr.co.vividnext.sodalive.common.BaseEntity | ||||
| import kr.co.vividnext.sodalive.member.Member | ||||
| import javax.persistence.Entity | ||||
| import javax.persistence.FetchType | ||||
| import javax.persistence.JoinColumn | ||||
| import javax.persistence.ManyToOne | ||||
|  | ||||
| @Entity | ||||
| data class Category( | ||||
|     val title: String, | ||||
|     var isActive: Boolean = true | ||||
| ) : BaseEntity() { | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "member_id", nullable = false) | ||||
|     var member: Member? = null | ||||
| } | ||||
| @@ -0,0 +1,21 @@ | ||||
| package kr.co.vividnext.sodalive.content.category | ||||
|  | ||||
| import kr.co.vividnext.sodalive.common.BaseEntity | ||||
| import kr.co.vividnext.sodalive.content.AudioContent | ||||
| import javax.persistence.Entity | ||||
| import javax.persistence.FetchType | ||||
| import javax.persistence.JoinColumn | ||||
| import javax.persistence.ManyToOne | ||||
|  | ||||
| @Entity | ||||
| data class CategoryContent( | ||||
|     var isActive: Boolean = true | ||||
| ) : BaseEntity() { | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "content_id", nullable = false) | ||||
|     var content: AudioContent? = null | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "category_id", nullable = false) | ||||
|     var category: Category? = null | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| package kr.co.vividnext.sodalive.content.category | ||||
|  | ||||
| import com.querydsl.jpa.impl.JPAQueryFactory | ||||
| import kr.co.vividnext.sodalive.content.category.QCategoryContent.categoryContent | ||||
| import org.springframework.data.jpa.repository.JpaRepository | ||||
|  | ||||
| interface CategoryContentRepository : JpaRepository<CategoryContent, Long>, CategoryContentQueryRepository | ||||
|  | ||||
| interface CategoryContentQueryRepository { | ||||
|     fun findByContentIdAndCategoryId(contentId: Long, categoryId: Long): CategoryContent? | ||||
| } | ||||
|  | ||||
| class CategoryContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : CategoryContentQueryRepository { | ||||
|     override fun findByContentIdAndCategoryId(contentId: Long, categoryId: Long): CategoryContent? { | ||||
|         return queryFactory | ||||
|             .selectFrom(categoryContent) | ||||
|             .where( | ||||
|                 categoryContent.content.id.eq(contentId) | ||||
|                     .and(categoryContent.category.id.eq(categoryId)) | ||||
|             ) | ||||
|             .fetchFirst() | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,28 @@ | ||||
| package kr.co.vividnext.sodalive.content.category | ||||
|  | ||||
| import kr.co.vividnext.sodalive.common.ApiResponse | ||||
| import kr.co.vividnext.sodalive.common.SodaException | ||||
| import kr.co.vividnext.sodalive.member.Member | ||||
| import org.springframework.security.access.prepost.PreAuthorize | ||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal | ||||
| import org.springframework.web.bind.annotation.PostMapping | ||||
| import org.springframework.web.bind.annotation.RequestBody | ||||
| import org.springframework.web.bind.annotation.RequestMapping | ||||
| import org.springframework.web.bind.annotation.RestController | ||||
|  | ||||
| @RestController | ||||
| @RequestMapping("/category") | ||||
| class CategoryController(private val service: CategoryService) { | ||||
|     @PostMapping | ||||
|     @PreAuthorize("hasRole('CREATOR')") | ||||
|     fun createCategory( | ||||
|         @RequestBody request: CreateCategoryRequest, | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|  | ||||
|         ApiResponse.ok( | ||||
|             service.createCategory(request = request, member = member) | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| package kr.co.vividnext.sodalive.content.category | ||||
|  | ||||
| import com.querydsl.jpa.impl.JPAQueryFactory | ||||
| import kr.co.vividnext.sodalive.content.category.QCategory.category | ||||
| import org.springframework.data.jpa.repository.JpaRepository | ||||
|  | ||||
| interface CategoryRepository : JpaRepository<Category, Long>, CategoryQueryRepository | ||||
|  | ||||
| interface CategoryQueryRepository { | ||||
|     fun findByTitleAndMemberId(title: String, memberId: Long): Category? | ||||
| } | ||||
|  | ||||
| class CategoryQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : CategoryQueryRepository { | ||||
|     override fun findByTitleAndMemberId(title: String, memberId: Long): Category? { | ||||
|         return queryFactory | ||||
|             .selectFrom(category) | ||||
|             .where( | ||||
|                 category.title.eq(title) | ||||
|                     .and(category.member.id.eq(memberId)) | ||||
|             ) | ||||
|             .fetchFirst() | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,40 @@ | ||||
| package kr.co.vividnext.sodalive.content.category | ||||
|  | ||||
| import kr.co.vividnext.sodalive.content.AudioContentRepository | ||||
| import kr.co.vividnext.sodalive.member.Member | ||||
| import org.springframework.stereotype.Service | ||||
| import org.springframework.transaction.annotation.Transactional | ||||
|  | ||||
| @Service | ||||
| class CategoryService( | ||||
|     private val repository: CategoryRepository, | ||||
|     private val contentRepository: AudioContentRepository, | ||||
|     private val categoryContentRepository: CategoryContentRepository | ||||
| ) { | ||||
|     @Transactional | ||||
|     fun createCategory(request: CreateCategoryRequest, member: Member) { | ||||
|         val category = repository.findByTitleAndMemberId(title = request.title, memberId = member.id!!) | ||||
|             ?: repository.save( | ||||
|                 Category(title = request.title).apply { | ||||
|                     this.member = member | ||||
|                 } | ||||
|             ) | ||||
|         category.isActive = true | ||||
|  | ||||
|         for (contentId in request.contentIdList) { | ||||
|             val content = contentRepository.findByIdAndActive(contentId = contentId) | ||||
|                 ?: continue | ||||
|  | ||||
|             val categoryContent = categoryContentRepository.findByContentIdAndCategoryId( | ||||
|                 contentId = contentId, | ||||
|                 categoryId = category.id!! | ||||
|             ) ?: categoryContentRepository.save( | ||||
|                 CategoryContent().apply { | ||||
|                     this.content = content | ||||
|                     this.category = category | ||||
|                 } | ||||
|             ) | ||||
|             categoryContent.isActive = true | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| package kr.co.vividnext.sodalive.content.category | ||||
|  | ||||
| data class CreateCategoryRequest( | ||||
|     val title: String, | ||||
|     val contentIdList: List<Long> | ||||
| ) | ||||
		Reference in New Issue
	
	Block a user