test #259
|
@ -0,0 +1,72 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.content.curation.tag
|
||||||
|
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
|
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.ContentHashTagCurationItem
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.QContentHashTagCuration.contentHashTagCuration
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.QContentHashTagCurationItem.contentHashTagCurationItem
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
|
||||||
|
interface AdminContentHashTagCurationItemRepository :
|
||||||
|
JpaRepository<ContentHashTagCurationItem, Long>,
|
||||||
|
AdminContentHashTagCurationItemQueryRepository
|
||||||
|
|
||||||
|
interface AdminContentHashTagCurationItemQueryRepository {
|
||||||
|
fun getContentHashTagCurationItemList(curationId: Long): List<GetAdminHashTagCurationItemResponse>
|
||||||
|
fun findByCurationIdAndContentId(curationId: Long, contentId: Long?): ContentHashTagCurationItem?
|
||||||
|
fun findByCurationIdAndItemId(curationId: Long, itemId: Long): ContentHashTagCurationItem?
|
||||||
|
}
|
||||||
|
|
||||||
|
class AdminContentHashTagCurationItemQueryRepositoryImpl(
|
||||||
|
val queryFactory: JPAQueryFactory,
|
||||||
|
|
||||||
|
@Value("\${cloud.aws.cloud-front.host}")
|
||||||
|
private val imageHost: String
|
||||||
|
) : AdminContentHashTagCurationItemQueryRepository {
|
||||||
|
override fun getContentHashTagCurationItemList(curationId: Long): List<GetAdminHashTagCurationItemResponse> {
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
QGetAdminHashTagCurationItemResponse(
|
||||||
|
contentHashTagCurationItem.id,
|
||||||
|
audioContent.title,
|
||||||
|
audioContent.detail,
|
||||||
|
audioContent.coverImage.prepend("/").prepend(imageHost),
|
||||||
|
audioContent.member.nickname.coalesce(""),
|
||||||
|
audioContent.isAdult
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(contentHashTagCurationItem)
|
||||||
|
.innerJoin(contentHashTagCurationItem.curation, contentHashTagCuration)
|
||||||
|
.innerJoin(contentHashTagCurationItem.content, audioContent)
|
||||||
|
.where(
|
||||||
|
contentHashTagCuration.id.eq(curationId),
|
||||||
|
contentHashTagCurationItem.isActive.isTrue,
|
||||||
|
audioContent.isActive.isTrue
|
||||||
|
)
|
||||||
|
.orderBy(contentHashTagCurationItem.orders.asc())
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findByCurationIdAndContentId(curationId: Long, contentId: Long?): ContentHashTagCurationItem? {
|
||||||
|
return queryFactory
|
||||||
|
.selectFrom(contentHashTagCurationItem)
|
||||||
|
.innerJoin(contentHashTagCurationItem.curation, contentHashTagCuration)
|
||||||
|
.innerJoin(contentHashTagCurationItem.content, audioContent)
|
||||||
|
.where(
|
||||||
|
contentHashTagCuration.id.eq(curationId),
|
||||||
|
audioContent.id.eq(contentId)
|
||||||
|
)
|
||||||
|
.fetchFirst()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findByCurationIdAndItemId(curationId: Long, itemId: Long): ContentHashTagCurationItem? {
|
||||||
|
return queryFactory.selectFrom(contentHashTagCurationItem)
|
||||||
|
.innerJoin(contentHashTagCurationItem.curation, contentHashTagCuration)
|
||||||
|
.where(
|
||||||
|
contentHashTagCuration.id.eq(curationId),
|
||||||
|
contentHashTagCurationItem.id.eq(itemId)
|
||||||
|
)
|
||||||
|
.fetchFirst()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.content.curation.tag
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.AddItemToCurationRequest
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.RemoveItemInCurationRequest
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.UpdateCurationItemOrdersRequest
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/audio-content/tag/curation")
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
class AdminHashTagCurationController(private val service: AdminHashTagCurationService) {
|
||||||
|
@GetMapping
|
||||||
|
fun getContentHashTagCurationList() = ApiResponse.ok(service.getContentHashTagCurationList())
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
fun createContentHashTagCuration(
|
||||||
|
@RequestBody request: CreateContentHashTagCurationRequest
|
||||||
|
) = ApiResponse.ok(service.createContentHashTagCuration(request))
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
fun updateContentHashTagCuration(
|
||||||
|
@RequestBody request: UpdateContentHashTagCurationRequest
|
||||||
|
) = ApiResponse.ok(service.updateContentHashTagCuration(request))
|
||||||
|
|
||||||
|
@PutMapping("/orders")
|
||||||
|
fun updateContentHashTagCurationOrders(
|
||||||
|
@RequestBody request: UpdateContentHashTagCurationOrderRequest
|
||||||
|
) = ApiResponse.ok(service.updateContentHashTagCurationOrders(request.ids), "수정되었습니다.")
|
||||||
|
|
||||||
|
@GetMapping("/items")
|
||||||
|
fun getHashTagCurationItemList(
|
||||||
|
@RequestParam curationId: Long
|
||||||
|
) = ApiResponse.ok(service.getHashTagCurationItemList(curationId = curationId))
|
||||||
|
|
||||||
|
@GetMapping("/search/content")
|
||||||
|
fun searchHashTagCurationContentItem(
|
||||||
|
@RequestParam curationId: Long,
|
||||||
|
@RequestParam searchWord: String
|
||||||
|
) = ApiResponse.ok(service.searchHashTagCurationContentItem(curationId, searchWord))
|
||||||
|
|
||||||
|
@PostMapping("/add/item")
|
||||||
|
fun addItemToHashTagCuration(
|
||||||
|
@RequestBody request: AddItemToCurationRequest
|
||||||
|
) = ApiResponse.ok(service.addItemToHashTagCuration(request), "큐레이션 아이템을 등록했습니다.")
|
||||||
|
|
||||||
|
@PutMapping("/remove/item")
|
||||||
|
fun removeItemInHashTagCuration(
|
||||||
|
@RequestBody request: RemoveItemInCurationRequest
|
||||||
|
) = ApiResponse.ok(service.removeItemInHashTagCuration(request), "큐레이션 아이템을 제거했습니다.")
|
||||||
|
|
||||||
|
@PutMapping("/orders/item")
|
||||||
|
fun updateItemInHashTagCurationOrders(
|
||||||
|
@RequestBody request: UpdateCurationItemOrdersRequest
|
||||||
|
) = ApiResponse.ok(service.updateItemInHashTagCurationOrders(request), "수정되었습니다.")
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.content.curation.tag
|
||||||
|
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.QSearchCurationItemResponse
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.SearchCurationItemResponse
|
||||||
|
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.ContentHashTagCuration
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.QContentHashTagCuration.contentHashTagCuration
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.QContentHashTagCurationItem.contentHashTagCurationItem
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
interface AdminHashTagCurationRepository :
|
||||||
|
JpaRepository<ContentHashTagCuration, Long>,
|
||||||
|
AdminHashTagCurationQueryRepository
|
||||||
|
|
||||||
|
interface AdminHashTagCurationQueryRepository {
|
||||||
|
fun getContentHashTagCurationList(): List<GetAdminContentHashTagCurationResponse>
|
||||||
|
fun searchHashTagCurationContentItem(curationId: Long, searchWord: String): List<SearchCurationItemResponse>
|
||||||
|
}
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class AdminHashTagCurationQueryRepositoryImpl(
|
||||||
|
private val queryFactory: JPAQueryFactory,
|
||||||
|
|
||||||
|
@Value("\${cloud.aws.cloud-front.host}")
|
||||||
|
private val imageHost: String
|
||||||
|
) : AdminHashTagCurationQueryRepository {
|
||||||
|
override fun getContentHashTagCurationList(): List<GetAdminContentHashTagCurationResponse> {
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
QGetAdminContentHashTagCurationResponse(
|
||||||
|
contentHashTagCuration.id,
|
||||||
|
contentHashTagCuration.tag,
|
||||||
|
contentHashTagCuration.isAdult
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(contentHashTagCuration)
|
||||||
|
.where(contentHashTagCuration.isActive.isTrue)
|
||||||
|
.orderBy(contentHashTagCuration.orders.asc())
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun searchHashTagCurationContentItem(
|
||||||
|
curationId: Long,
|
||||||
|
searchWord: String
|
||||||
|
): List<SearchCurationItemResponse> {
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
QSearchCurationItemResponse(
|
||||||
|
audioContent.id,
|
||||||
|
audioContent.title,
|
||||||
|
audioContent.coverImage.prepend("/").prepend(imageHost)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(audioContent)
|
||||||
|
.leftJoin(contentHashTagCurationItem)
|
||||||
|
.on(
|
||||||
|
audioContent.id.eq(contentHashTagCurationItem.content.id)
|
||||||
|
.and(contentHashTagCurationItem.curation.id.eq(curationId))
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
audioContent.duration.isNotNull
|
||||||
|
.and(audioContent.member.isNotNull)
|
||||||
|
.and(audioContent.isActive.isTrue)
|
||||||
|
.and(audioContent.title.contains(searchWord))
|
||||||
|
.and(contentHashTagCurationItem.id.isNull)
|
||||||
|
)
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.content.curation.tag
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.AddItemToCurationRequest
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.RemoveItemInCurationRequest
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.SearchCurationItemResponse
|
||||||
|
import kr.co.vividnext.sodalive.admin.content.curation.UpdateCurationItemOrdersRequest
|
||||||
|
import kr.co.vividnext.sodalive.common.SodaException
|
||||||
|
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.ContentHashTagCuration
|
||||||
|
import kr.co.vividnext.sodalive.content.main.curation.tag.ContentHashTagCurationItem
|
||||||
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import org.springframework.transaction.annotation.Transactional
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class AdminHashTagCurationService(
|
||||||
|
private val repository: AdminHashTagCurationRepository,
|
||||||
|
private val itemRepository: AdminContentHashTagCurationItemRepository,
|
||||||
|
private val audioContentRepository: AudioContentRepository
|
||||||
|
) {
|
||||||
|
@Transactional
|
||||||
|
fun createContentHashTagCuration(request: CreateContentHashTagCurationRequest) {
|
||||||
|
repository.save(
|
||||||
|
ContentHashTagCuration(
|
||||||
|
tag = request.tag,
|
||||||
|
isAdult = request.isAdult
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun updateContentHashTagCuration(request: UpdateContentHashTagCurationRequest) {
|
||||||
|
val hashTagCuration = repository.findByIdOrNull(id = request.id)
|
||||||
|
?: throw SodaException("잘못된 요청입니다.")
|
||||||
|
|
||||||
|
if (request.tag != null) {
|
||||||
|
hashTagCuration.tag = request.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.isAdult != null) {
|
||||||
|
hashTagCuration.isAdult = request.isAdult
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.isActive != null) {
|
||||||
|
hashTagCuration.isActive = request.isActive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun updateContentHashTagCurationOrders(ids: List<Long>) {
|
||||||
|
for (index in ids.indices) {
|
||||||
|
val contentHashTagCuration = repository.findByIdOrNull(ids[index])
|
||||||
|
|
||||||
|
if (contentHashTagCuration != null) {
|
||||||
|
contentHashTagCuration.orders = index + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getContentHashTagCurationList(): List<GetAdminContentHashTagCurationResponse> {
|
||||||
|
return repository.getContentHashTagCurationList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getHashTagCurationItemList(curationId: Long): List<GetAdminHashTagCurationItemResponse> {
|
||||||
|
return itemRepository.getContentHashTagCurationItemList(curationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun searchHashTagCurationContentItem(curationId: Long, searchWord: String): List<SearchCurationItemResponse> {
|
||||||
|
return repository.searchHashTagCurationContentItem(curationId, searchWord)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun addItemToHashTagCuration(request: AddItemToCurationRequest) {
|
||||||
|
val curation = repository.findByIdOrNull(id = request.curationId)
|
||||||
|
?: throw SodaException("잘못된 요청입니다.")
|
||||||
|
|
||||||
|
request.itemIdList.forEach { contentId ->
|
||||||
|
val audioContent = audioContentRepository.findByIdAndActive(contentId)
|
||||||
|
|
||||||
|
if (audioContent != null) {
|
||||||
|
val item = itemRepository.findByCurationIdAndContentId(
|
||||||
|
curationId = request.curationId,
|
||||||
|
contentId = audioContent.id
|
||||||
|
) ?: ContentHashTagCurationItem()
|
||||||
|
item.curation = curation
|
||||||
|
item.content = audioContent
|
||||||
|
itemRepository.save(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun removeItemInHashTagCuration(request: RemoveItemInCurationRequest) {
|
||||||
|
val item = itemRepository.findByCurationIdAndItemId(
|
||||||
|
curationId = request.curationId,
|
||||||
|
itemId = request.itemId
|
||||||
|
)
|
||||||
|
|
||||||
|
item?.isActive = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun updateItemInHashTagCurationOrders(request: UpdateCurationItemOrdersRequest) {
|
||||||
|
val ids = request.itemIds
|
||||||
|
for (index in ids.indices) {
|
||||||
|
val item = itemRepository.findByCurationIdAndItemId(
|
||||||
|
curationId = request.curationId,
|
||||||
|
itemId = ids[index]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (item != null) {
|
||||||
|
item.orders = index + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.content.curation.tag
|
||||||
|
|
||||||
|
data class CreateContentHashTagCurationRequest(
|
||||||
|
val tag: String,
|
||||||
|
val isAdult: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
data class UpdateContentHashTagCurationRequest(
|
||||||
|
val id: Long,
|
||||||
|
val tag: String?,
|
||||||
|
val isAdult: Boolean?,
|
||||||
|
val isActive: Boolean?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class UpdateContentHashTagCurationOrderRequest(
|
||||||
|
val ids: List<Long>
|
||||||
|
)
|
|
@ -0,0 +1,9 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.content.curation.tag
|
||||||
|
|
||||||
|
import com.querydsl.core.annotations.QueryProjection
|
||||||
|
|
||||||
|
data class GetAdminContentHashTagCurationResponse @QueryProjection constructor(
|
||||||
|
val id: Long,
|
||||||
|
val tag: String,
|
||||||
|
val isAdult: Boolean
|
||||||
|
)
|
|
@ -0,0 +1,12 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.content.curation.tag
|
||||||
|
|
||||||
|
import com.querydsl.core.annotations.QueryProjection
|
||||||
|
|
||||||
|
data class GetAdminHashTagCurationItemResponse @QueryProjection constructor(
|
||||||
|
val id: Long,
|
||||||
|
val title: String,
|
||||||
|
val desc: String,
|
||||||
|
val coverImageUrl: String,
|
||||||
|
val creatorNickname: String,
|
||||||
|
val isAdult: Boolean
|
||||||
|
)
|
|
@ -0,0 +1,30 @@
|
||||||
|
package kr.co.vividnext.sodalive.content.main.curation.tag
|
||||||
|
|
||||||
|
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 ContentHashTagCuration(
|
||||||
|
var tag: String,
|
||||||
|
var orders: Int = 1,
|
||||||
|
var isAdult: Boolean = false,
|
||||||
|
var isActive: Boolean = true
|
||||||
|
) : BaseEntity()
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class ContentHashTagCurationItem(
|
||||||
|
var orders: Int = 1,
|
||||||
|
var isActive: Boolean = true
|
||||||
|
) : BaseEntity() {
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "curation_id", nullable = false)
|
||||||
|
var curation: ContentHashTagCuration? = null
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "content_id", nullable = false)
|
||||||
|
var content: AudioContent? = null
|
||||||
|
}
|
Loading…
Reference in New Issue