parent
dac5858541
commit
34c08d4345
|
@ -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>
|
||||||
|
)
|
Loading…
Reference in New Issue