콘텐츠 카테고리

- 등록 API 추가
This commit is contained in:
Klaus 2024-02-01 19:37:15 +09:00
parent dac5858541
commit 34c08d4345
7 changed files with 159 additions and 0 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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()
}
}

View File

@ -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)
)
}
}

View File

@ -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()
}
}

View File

@ -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
}
}
}

View File

@ -0,0 +1,6 @@
package kr.co.vividnext.sodalive.content.category
data class CreateCategoryRequest(
val title: String,
val contentIdList: List<Long>
)