Compare commits
No commits in common. "25083fb0e4fc0b32f00e2c1e6503e8de37bf1f0c" and "d2dc0452554b1d17a397522e5988aa58ef4d595b" have entirely different histories.
25083fb0e4
...
d2dc045255
|
@ -60,9 +60,4 @@ class AdminContentCurationController(private val service: AdminContentCurationSe
|
||||||
fun removeItemInCuration(
|
fun removeItemInCuration(
|
||||||
@RequestBody request: RemoveItemInCurationRequest
|
@RequestBody request: RemoveItemInCurationRequest
|
||||||
) = ApiResponse.ok(service.removeItemInCuration(request), "큐레이션 아이템을 제거했습니다.")
|
) = ApiResponse.ok(service.removeItemInCuration(request), "큐레이션 아이템을 제거했습니다.")
|
||||||
|
|
||||||
@PutMapping("/orders/item")
|
|
||||||
fun updateItemInCurationOrders(
|
|
||||||
@RequestBody request: UpdateCurationItemOrdersRequest
|
|
||||||
) = ApiResponse.ok(service.updateItemInCurationOrders(request), "수정되었습니다.")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,6 @@ class AdminContentCurationItemQueryRepositoryImpl(
|
||||||
audioContentCuration.id.eq(curationId),
|
audioContentCuration.id.eq(curationId),
|
||||||
audioContentCurationItem.isActive.isTrue
|
audioContentCurationItem.isActive.isTrue
|
||||||
)
|
)
|
||||||
.orderBy(audioContentCurationItem.orders.asc())
|
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +99,6 @@ class AdminContentCurationItemQueryRepositoryImpl(
|
||||||
audioContentCuration.id.eq(curationId),
|
audioContentCuration.id.eq(curationId),
|
||||||
audioContentCurationItem.isActive.isTrue
|
audioContentCurationItem.isActive.isTrue
|
||||||
)
|
)
|
||||||
.orderBy(audioContentCurationItem.orders.asc())
|
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,19 +150,4 @@ class AdminContentCurationService(
|
||||||
|
|
||||||
audioContentCurationItem?.isActive = false
|
audioContentCurationItem?.isActive = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
|
||||||
fun updateItemInCurationOrders(request: UpdateCurationItemOrdersRequest) {
|
|
||||||
val ids = request.itemIds
|
|
||||||
for (index in ids.indices) {
|
|
||||||
val item = contentCurationItemRepository.findByCurationIdAndItemId(
|
|
||||||
curationId = request.curationId,
|
|
||||||
itemId = ids[index]
|
|
||||||
)
|
|
||||||
|
|
||||||
if (item != null) {
|
|
||||||
item.orders = index + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.admin.content.curation
|
|
||||||
|
|
||||||
data class UpdateCurationItemOrdersRequest(
|
|
||||||
val curationId: Long,
|
|
||||||
val itemIds: List<Long>
|
|
||||||
)
|
|
|
@ -1,72 +0,0 @@
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
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), "수정되었습니다.")
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
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>
|
|
||||||
fun isExistsTag(tag: String): Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
@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()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isExistsTag(tag: String): Boolean {
|
|
||||||
return queryFactory
|
|
||||||
.select(contentHashTagCuration.id)
|
|
||||||
.from(contentHashTagCuration)
|
|
||||||
.where(
|
|
||||||
contentHashTagCuration.tag.eq(tag),
|
|
||||||
contentHashTagCuration.isActive.isTrue
|
|
||||||
)
|
|
||||||
.fetch().isNotEmpty()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
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) {
|
|
||||||
var tag = request.tag.trim()
|
|
||||||
if (!tag.startsWith("#")) {
|
|
||||||
tag = "#$tag"
|
|
||||||
}
|
|
||||||
|
|
||||||
val isExists = repository.isExistsTag(tag = tag)
|
|
||||||
|
|
||||||
if (isExists) {
|
|
||||||
throw SodaException("이미 등록된 태그 입니다.")
|
|
||||||
}
|
|
||||||
|
|
||||||
repository.save(
|
|
||||||
ContentHashTagCuration(
|
|
||||||
tag = tag,
|
|
||||||
isAdult = request.isAdult
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
fun updateContentHashTagCuration(request: UpdateContentHashTagCurationRequest) {
|
|
||||||
val hashTagCuration = repository.findByIdOrNull(id = request.id)
|
|
||||||
?: throw SodaException("잘못된 요청입니다.")
|
|
||||||
|
|
||||||
if (request.tag != null) {
|
|
||||||
var tag = request.tag.trim()
|
|
||||||
if (!tag.startsWith("#")) {
|
|
||||||
tag = "#$tag"
|
|
||||||
}
|
|
||||||
|
|
||||||
hashTagCuration.tag = 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
|
|
||||||
item.isActive = true
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
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>
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
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
|
|
||||||
)
|
|
|
@ -1,12 +0,0 @@
|
||||||
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
|
|
||||||
)
|
|
|
@ -32,7 +32,6 @@ data class AudioContent(
|
||||||
var title: String,
|
var title: String,
|
||||||
@Column(columnDefinition = "TEXT", nullable = false)
|
@Column(columnDefinition = "TEXT", nullable = false)
|
||||||
var detail: String,
|
var detail: String,
|
||||||
var playCount: Long = 0,
|
|
||||||
var price: Int = 0,
|
var price: Int = 0,
|
||||||
var releaseDate: LocalDateTime? = null,
|
var releaseDate: LocalDateTime? = null,
|
||||||
val limited: Int? = null,
|
val limited: Int? = null,
|
||||||
|
|
|
@ -81,12 +81,6 @@ interface AudioContentQueryRepository {
|
||||||
limit: Long = 20
|
limit: Long = 20
|
||||||
): List<GetAudioContentMainItem>
|
): List<GetAudioContentMainItem>
|
||||||
|
|
||||||
fun totalAlarmCountByTheme(
|
|
||||||
memberId: Long,
|
|
||||||
theme: List<String>,
|
|
||||||
isAdult: Boolean = false
|
|
||||||
): Int
|
|
||||||
|
|
||||||
fun totalCountByTheme(
|
fun totalCountByTheme(
|
||||||
memberId: Long,
|
memberId: Long,
|
||||||
theme: String = "",
|
theme: String = "",
|
||||||
|
@ -492,39 +486,6 @@ class AudioContentQueryRepositoryImpl(
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun totalAlarmCountByTheme(memberId: Long, theme: List<String>, isAdult: Boolean): Int {
|
|
||||||
val blockMemberCondition = blockMember.member.id.eq(member.id)
|
|
||||||
.and(blockMember.isActive.isTrue)
|
|
||||||
.and(blockMember.blockedMember.id.eq(memberId))
|
|
||||||
|
|
||||||
var where = audioContent.isActive.isTrue
|
|
||||||
.and(audioContent.duration.isNotNull)
|
|
||||||
.and(
|
|
||||||
audioContent.releaseDate.isNull
|
|
||||||
.or(audioContent.releaseDate.loe(LocalDateTime.now()))
|
|
||||||
.or(audioContent.member.id.eq(memberId))
|
|
||||||
)
|
|
||||||
.and(blockMember.id.isNull)
|
|
||||||
|
|
||||||
if (!isAdult) {
|
|
||||||
where = where.and(audioContent.isAdult.isFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theme.isNotEmpty()) {
|
|
||||||
where = where.and(audioContentTheme.theme.`in`(theme))
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryFactory
|
|
||||||
.select(audioContent.id)
|
|
||||||
.from(audioContent)
|
|
||||||
.innerJoin(audioContent.member, member)
|
|
||||||
.innerJoin(audioContent.theme, audioContentTheme)
|
|
||||||
.leftJoin(blockMember).on(blockMemberCondition)
|
|
||||||
.where(where)
|
|
||||||
.fetch()
|
|
||||||
.size
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun totalCountByTheme(memberId: Long, theme: String, isAdult: Boolean, contentType: ContentType): Int {
|
override fun totalCountByTheme(memberId: Long, theme: String, isAdult: Boolean, contentType: ContentType): Int {
|
||||||
var where = audioContent.isActive.isTrue
|
var where = audioContent.isActive.isTrue
|
||||||
.and(audioContent.duration.isNotNull)
|
.and(audioContent.duration.isNotNull)
|
||||||
|
@ -698,7 +659,6 @@ class AudioContentQueryRepositoryImpl(
|
||||||
|
|
||||||
override fun getAudioContentMainBannerList(isAdult: Boolean): List<AudioContentBanner> {
|
override fun getAudioContentMainBannerList(isAdult: Boolean): List<AudioContentBanner> {
|
||||||
var where = audioContentBanner.isActive.isTrue
|
var where = audioContentBanner.isActive.isTrue
|
||||||
.and(audioContentBanner.tab.isNull)
|
|
||||||
|
|
||||||
if (!isAdult) {
|
if (!isAdult) {
|
||||||
where = where.and(audioContentBanner.isAdult.isFalse)
|
where = where.and(audioContentBanner.isAdult.isFalse)
|
||||||
|
@ -706,7 +666,6 @@ class AudioContentQueryRepositoryImpl(
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.selectFrom(audioContentBanner)
|
.selectFrom(audioContentBanner)
|
||||||
.leftJoin(audioContentBanner.tab, audioContentMainTab)
|
|
||||||
.leftJoin(audioContentBanner.event, event)
|
.leftJoin(audioContentBanner.event, event)
|
||||||
.leftJoin(audioContentBanner.creator, member)
|
.leftJoin(audioContentBanner.creator, member)
|
||||||
.where(where)
|
.where(where)
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
|
@ -31,7 +31,6 @@ class AudioContentMainTabRepository(
|
||||||
val where = member.isActive.isTrue
|
val where = member.isActive.isTrue
|
||||||
.and(member.role.eq(MemberRole.CREATOR))
|
.and(member.role.eq(MemberRole.CREATOR))
|
||||||
.and(audioContent.isActive.isTrue)
|
.and(audioContent.isActive.isTrue)
|
||||||
.and(audioContent.price.gt(0))
|
|
||||||
.and(audioContent.duration.isNotNull)
|
.and(audioContent.duration.isNotNull)
|
||||||
.and(audioContent.limited.isNull)
|
.and(audioContent.limited.isNull)
|
||||||
.and(audioContentTheme.isActive.isTrue)
|
.and(audioContentTheme.isActive.isTrue)
|
||||||
|
@ -60,39 +59,4 @@ class AudioContentMainTabRepository(
|
||||||
.limit(20)
|
.limit(20)
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findCreatorWithHasFreeContent(memberId: Long, minCount: Int): List<ContentCreatorResponse> {
|
|
||||||
val blockMemberCondition = blockMember.member.id.eq(member.id)
|
|
||||||
.and(blockMember.isActive.isTrue)
|
|
||||||
.and(blockMember.blockedMember.id.eq(memberId))
|
|
||||||
|
|
||||||
val where = member.isActive.isTrue
|
|
||||||
.and(member.role.eq(MemberRole.CREATOR))
|
|
||||||
.and(audioContent.isActive.isTrue)
|
|
||||||
.and(audioContent.price.loe(0))
|
|
||||||
.and(audioContent.duration.isNotNull)
|
|
||||||
.and(audioContent.limited.isNull)
|
|
||||||
.and(blockMember.id.isNull)
|
|
||||||
|
|
||||||
return queryFactory
|
|
||||||
.select(
|
|
||||||
QContentCreatorResponse(
|
|
||||||
member.id,
|
|
||||||
member.nickname,
|
|
||||||
member.profileImage.prepend("/").prepend(imageHost)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.from(member)
|
|
||||||
.innerJoin(audioContent).on(member.id.eq(audioContent.member.id))
|
|
||||||
.leftJoin(blockMember).on(blockMemberCondition)
|
|
||||||
.where(where)
|
|
||||||
.groupBy(member.id)
|
|
||||||
.having(audioContent.id.count().goe(minCount))
|
|
||||||
.orderBy(
|
|
||||||
Expressions.numberTemplate(Double::class.java, "function('rand')").asc()
|
|
||||||
)
|
|
||||||
.offset(0)
|
|
||||||
.limit(20)
|
|
||||||
.fetch()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package kr.co.vividnext.sodalive.content.main.tab
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
||||||
|
|
||||||
|
data class GetPopularContentByCreatorResponse(
|
||||||
|
val salesRankContentList: List<GetAudioContentRankingItem>,
|
||||||
|
val salesCountRankContentList: List<GetAudioContentRankingItem>
|
||||||
|
)
|
|
@ -1,7 +1,7 @@
|
||||||
package kr.co.vividnext.sodalive.content.main.tab.alarm
|
package kr.co.vividnext.sodalive.content.main.tab.alarm
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.GetNewContentAllResponse
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
||||||
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
||||||
|
@ -86,7 +86,7 @@ class AudioContentMainTabAlarmService(
|
||||||
member: Member,
|
member: Member,
|
||||||
offset: Long,
|
offset: Long,
|
||||||
limit: Long
|
limit: Long
|
||||||
): GetNewContentAllResponse {
|
): List<GetAudioContentMainItem> {
|
||||||
val alarmThemeList = if (theme.isNotBlank()) {
|
val alarmThemeList = if (theme.isNotBlank()) {
|
||||||
listOf(theme)
|
listOf(theme)
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,20 +96,12 @@ class AudioContentMainTabAlarmService(
|
||||||
val memberId = member.id!!
|
val memberId = member.id!!
|
||||||
val isAdult = member.auth != null
|
val isAdult = member.auth != null
|
||||||
|
|
||||||
val totalCount = contentRepository.totalAlarmCountByTheme(
|
return contentRepository.findAlarmContentByTheme(
|
||||||
memberId = memberId,
|
|
||||||
theme = alarmThemeList,
|
|
||||||
isAdult = isAdult
|
|
||||||
)
|
|
||||||
|
|
||||||
val items = contentRepository.findAlarmContentByTheme(
|
|
||||||
memberId = memberId,
|
memberId = memberId,
|
||||||
theme = alarmThemeList,
|
theme = alarmThemeList,
|
||||||
isAdult = isAdult,
|
isAdult = isAdult,
|
||||||
offset = offset,
|
offset = offset,
|
||||||
limit = limit
|
limit = limit
|
||||||
)
|
)
|
||||||
|
|
||||||
return GetNewContentAllResponse(totalCount, items)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ package kr.co.vividnext.sodalive.content.main.tab.asmr
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
||||||
import kr.co.vividnext.sodalive.content.ContentType
|
import kr.co.vividnext.sodalive.content.ContentType
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
||||||
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.AudioContentMainTabRepository
|
import kr.co.vividnext.sodalive.content.main.tab.AudioContentMainTabRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
||||||
|
import kr.co.vividnext.sodalive.content.main.tab.GetPopularContentByCreatorResponse
|
||||||
import kr.co.vividnext.sodalive.event.EventService
|
import kr.co.vividnext.sodalive.event.EventService
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import kr.co.vividnext.sodalive.rank.RankingService
|
import kr.co.vividnext.sodalive.rank.RankingService
|
||||||
|
@ -68,8 +68,18 @@ class AudioContentMainTabAsmrService(
|
||||||
minCount = 4
|
minCount = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val salesRankContentList = if (creatorList.isNotEmpty()) {
|
||||||
|
rankingService.fetchCreatorContentBySalesTop2(
|
||||||
|
creatorId = creatorList[0].creatorId,
|
||||||
|
isAdult = isAdult,
|
||||||
|
theme = theme
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
val salesCountRankContentList = if (creatorList.isNotEmpty()) {
|
val salesCountRankContentList = if (creatorList.isNotEmpty()) {
|
||||||
rankingService.fetchCreatorContentBySalesCountTop4(
|
rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
creatorId = creatorList[0].creatorId,
|
creatorId = creatorList[0].creatorId,
|
||||||
isAdult = isAdult,
|
isAdult = isAdult,
|
||||||
theme = theme
|
theme = theme
|
||||||
|
@ -97,17 +107,30 @@ class AudioContentMainTabAsmrService(
|
||||||
newAsmrContentList = newAsmrContentList,
|
newAsmrContentList = newAsmrContentList,
|
||||||
rankAsmrContentList = rankAsmrContentList,
|
rankAsmrContentList = rankAsmrContentList,
|
||||||
creatorList = creatorList,
|
creatorList = creatorList,
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
salesCountRankContentList = salesCountRankContentList,
|
salesCountRankContentList = salesCountRankContentList,
|
||||||
eventBannerList = eventBannerList,
|
eventBannerList = eventBannerList,
|
||||||
curationList = curationList
|
curationList = curationList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
|
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): GetPopularContentByCreatorResponse {
|
||||||
return rankingService.fetchCreatorContentBySalesCountTop4(
|
val theme = "ASMR"
|
||||||
|
val salesRankContentList = rankingService.fetchCreatorContentBySalesTop2(
|
||||||
creatorId = creatorId,
|
creatorId = creatorId,
|
||||||
isAdult = isAdult,
|
isAdult = isAdult,
|
||||||
theme = "ASMR"
|
theme = theme
|
||||||
|
)
|
||||||
|
|
||||||
|
val salesCountRankContentList = rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
|
creatorId = creatorId,
|
||||||
|
isAdult = isAdult,
|
||||||
|
theme = theme
|
||||||
|
)
|
||||||
|
|
||||||
|
return GetPopularContentByCreatorResponse(
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
|
salesCountRankContentList = salesCountRankContentList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ data class GetContentMainTabAsmrResponse(
|
||||||
val newAsmrContentList: List<GetAudioContentMainItem>,
|
val newAsmrContentList: List<GetAudioContentMainItem>,
|
||||||
val rankAsmrContentList: List<GetAudioContentRankingItem>,
|
val rankAsmrContentList: List<GetAudioContentRankingItem>,
|
||||||
val creatorList: List<ContentCreatorResponse>,
|
val creatorList: List<ContentCreatorResponse>,
|
||||||
|
val salesRankContentList: List<GetAudioContentRankingItem>,
|
||||||
val salesCountRankContentList: List<GetAudioContentRankingItem>,
|
val salesCountRankContentList: List<GetAudioContentRankingItem>,
|
||||||
val eventBannerList: GetEventResponse,
|
val eventBannerList: GetEventResponse,
|
||||||
val curationList: List<GetContentCurationResponse>
|
val curationList: List<GetContentCurationResponse>
|
||||||
|
|
|
@ -82,15 +82,4 @@ class AudioContentMainTabContentController(private val service: AudioContentMain
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/recommend-content-by-tag")
|
|
||||||
fun getRecommendedContentByTag(
|
|
||||||
@RequestParam tag: String,
|
|
||||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
|
||||||
) = run {
|
|
||||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
|
||||||
ApiResponse.ok(
|
|
||||||
service.getRecommendedContentByTag(memberId = member.id!!, tag = tag)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,7 @@ import kr.co.vividnext.sodalive.content.ContentType
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
||||||
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
import kr.co.vividnext.sodalive.content.main.tab.GetPopularContentByCreatorResponse
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
|
||||||
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
|
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
|
||||||
import kr.co.vividnext.sodalive.event.EventService
|
import kr.co.vividnext.sodalive.event.EventService
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
|
@ -20,9 +19,7 @@ class AudioContentMainTabContentService(
|
||||||
private val audioContentRepository: AudioContentRepository,
|
private val audioContentRepository: AudioContentRepository,
|
||||||
private val audioContentThemeRepository: AudioContentThemeQueryRepository,
|
private val audioContentThemeRepository: AudioContentThemeQueryRepository,
|
||||||
private val rankingService: RankingService,
|
private val rankingService: RankingService,
|
||||||
private val eventService: EventService,
|
private val eventService: EventService
|
||||||
private val tagCurationService: ContentMainTabTagCurationService,
|
|
||||||
private val curationRepository: AudioContentCurationQueryRepository
|
|
||||||
) {
|
) {
|
||||||
fun fetchData(
|
fun fetchData(
|
||||||
isAdultContentVisible: Boolean,
|
isAdultContentVisible: Boolean,
|
||||||
|
@ -31,11 +28,10 @@ class AudioContentMainTabContentService(
|
||||||
): GetContentMainTabContentResponse {
|
): GetContentMainTabContentResponse {
|
||||||
val memberId = member.id!!
|
val memberId = member.id!!
|
||||||
val isAdult = member.auth != null
|
val isAdult = member.auth != null
|
||||||
val tabId = 3L
|
|
||||||
|
|
||||||
// 단편 배너
|
// 단편 배너
|
||||||
val contentBannerList = bannerService.getBannerList(
|
val contentBannerList = bannerService.getBannerList(
|
||||||
tabId = tabId,
|
tabId = 3,
|
||||||
memberId = memberId,
|
memberId = memberId,
|
||||||
isAdult = isAdult
|
isAdult = isAdult
|
||||||
)
|
)
|
||||||
|
@ -73,14 +69,14 @@ class AudioContentMainTabContentService(
|
||||||
// 이벤트 배너
|
// 이벤트 배너
|
||||||
val eventBannerList = eventService.getEventList(isAdult = isAdult)
|
val eventBannerList = eventService.getEventList(isAdult = isAdult)
|
||||||
|
|
||||||
val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20(
|
val contentRankCreatorList = rankingService.fetchCreatorByContentRevenueRankTop20(
|
||||||
memberId = member.id!!,
|
memberId = member.id!!,
|
||||||
startDate = dailyRankingStartDate.minusDays(1),
|
startDate = dailyRankingStartDate.minusDays(1),
|
||||||
endDate = dailyRankingEndDate
|
endDate = dailyRankingEndDate
|
||||||
)
|
)
|
||||||
|
|
||||||
val salesCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
|
val salesRankContentList = if (contentRankCreatorList.isNotEmpty()) {
|
||||||
rankingService.fetchCreatorContentBySalesCountTop4(
|
rankingService.fetchCreatorContentBySalesTop2(
|
||||||
creatorId = contentRankCreatorList[0].creatorId,
|
creatorId = contentRankCreatorList[0].creatorId,
|
||||||
isAdult = member.auth != null
|
isAdult = member.auth != null
|
||||||
)
|
)
|
||||||
|
@ -88,30 +84,15 @@ class AudioContentMainTabContentService(
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val tagList = if (isAdult) {
|
val salesCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
|
||||||
tagCurationService.getTagList(isAdult = isAdult)
|
rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
|
creatorId = contentRankCreatorList[0].creatorId,
|
||||||
|
isAdult = member.auth != null
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val tagCurationContentList = if (tagList.isNotEmpty()) {
|
|
||||||
tagCurationService.getTagCurationContentList(memberId = memberId, tag = tagList[0])
|
|
||||||
} else {
|
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
val curationList = curationRepository.findByContentMainTabId(tabId = tabId, isAdult = isAdult)
|
|
||||||
.map {
|
|
||||||
GetContentCurationResponse(
|
|
||||||
title = it.title,
|
|
||||||
items = audioContentRepository.findAudioContentByCurationIdV2(
|
|
||||||
curationId = it.id!!,
|
|
||||||
memberId = memberId,
|
|
||||||
isAdult = isAdult
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetContentMainTabContentResponse(
|
return GetContentMainTabContentResponse(
|
||||||
bannerList = contentBannerList,
|
bannerList = contentBannerList,
|
||||||
contentThemeList = themeOfContentList,
|
contentThemeList = themeOfContentList,
|
||||||
|
@ -119,11 +100,9 @@ class AudioContentMainTabContentService(
|
||||||
rankSortTypeList = listOf("매출", "댓글", "좋아요"),
|
rankSortTypeList = listOf("매출", "댓글", "좋아요"),
|
||||||
rankContentList = rankContentList,
|
rankContentList = rankContentList,
|
||||||
contentRankCreatorList = contentRankCreatorList,
|
contentRankCreatorList = contentRankCreatorList,
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
salesCountRankContentList = salesCountRankContentList,
|
salesCountRankContentList = salesCountRankContentList,
|
||||||
eventBannerList = eventBannerList,
|
eventBannerList = eventBannerList
|
||||||
tagList = tagList,
|
|
||||||
tagCurationContentList = tagCurationContentList,
|
|
||||||
curationList = curationList
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,14 +144,20 @@ class AudioContentMainTabContentService(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
|
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): GetPopularContentByCreatorResponse {
|
||||||
return rankingService.fetchCreatorContentBySalesCountTop4(
|
val salesRankContentList = rankingService.fetchCreatorContentBySalesTop2(
|
||||||
creatorId = creatorId,
|
creatorId = creatorId,
|
||||||
isAdult = isAdult
|
isAdult = isAdult
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fun getRecommendedContentByTag(memberId: Long, tag: String): List<GetAudioContentMainItem> {
|
val salesCountRankContentList = rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
return tagCurationService.getTagCurationContentList(memberId = memberId, tag = tag)
|
creatorId = creatorId,
|
||||||
|
isAdult = isAdult
|
||||||
|
)
|
||||||
|
|
||||||
|
return GetPopularContentByCreatorResponse(
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
|
salesCountRankContentList = salesCountRankContentList
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.content.main.tab.content
|
|
||||||
|
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
|
||||||
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
|
||||||
import kr.co.vividnext.sodalive.content.main.QGetAudioContentMainItem
|
|
||||||
import kr.co.vividnext.sodalive.content.main.curation.tag.QContentHashTagCuration.contentHashTagCuration
|
|
||||||
import kr.co.vividnext.sodalive.content.main.curation.tag.QContentHashTagCurationItem.contentHashTagCurationItem
|
|
||||||
import kr.co.vividnext.sodalive.member.QMember.member
|
|
||||||
import kr.co.vividnext.sodalive.member.block.QBlockMember.blockMember
|
|
||||||
import org.springframework.beans.factory.annotation.Value
|
|
||||||
import org.springframework.stereotype.Repository
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
class ContentMainTabTagCurationRepository(
|
|
||||||
private val queryFactory: JPAQueryFactory,
|
|
||||||
|
|
||||||
@Value("\${cloud.aws.cloud-front.host}")
|
|
||||||
private val imageHost: String
|
|
||||||
) {
|
|
||||||
fun getTagList(isAdult: Boolean): List<String> {
|
|
||||||
var where = contentHashTagCuration.isActive.isTrue
|
|
||||||
.and(audioContent.isActive.isTrue)
|
|
||||||
.and(audioContent.duration.isNotNull)
|
|
||||||
.and(audioContent.limited.isNull)
|
|
||||||
.and(contentHashTagCurationItem.isActive.isTrue)
|
|
||||||
|
|
||||||
if (!isAdult) {
|
|
||||||
where = where.and(contentHashTagCuration.isAdult.isFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryFactory
|
|
||||||
.select(contentHashTagCuration.tag)
|
|
||||||
.from(contentHashTagCuration)
|
|
||||||
.innerJoin(contentHashTagCurationItem)
|
|
||||||
.on(contentHashTagCurationItem.curation.id.eq(contentHashTagCuration.id))
|
|
||||||
.innerJoin(contentHashTagCurationItem.content, audioContent)
|
|
||||||
.where(where)
|
|
||||||
.groupBy(contentHashTagCuration.id)
|
|
||||||
.having(contentHashTagCurationItem.id.countDistinct().gt(0))
|
|
||||||
.orderBy(contentHashTagCuration.orders.asc())
|
|
||||||
.fetch()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getTagCurationContentList(memberId: Long, tag: String): List<GetAudioContentMainItem> {
|
|
||||||
val blockMemberCondition = blockMember.member.id.eq(member.id)
|
|
||||||
.and(blockMember.isActive.isTrue)
|
|
||||||
.and(blockMember.blockedMember.id.eq(memberId))
|
|
||||||
|
|
||||||
val where = audioContent.isActive.isTrue
|
|
||||||
.and(audioContent.duration.isNotNull)
|
|
||||||
.and(audioContent.limited.isNull)
|
|
||||||
.and(blockMember.id.isNull)
|
|
||||||
.and(contentHashTagCurationItem.isActive.isTrue)
|
|
||||||
.and(contentHashTagCuration.tag.eq(tag))
|
|
||||||
|
|
||||||
return queryFactory
|
|
||||||
.select(
|
|
||||||
QGetAudioContentMainItem(
|
|
||||||
audioContent.id,
|
|
||||||
audioContent.coverImage.prepend("/").prepend(imageHost),
|
|
||||||
audioContent.title,
|
|
||||||
member.id,
|
|
||||||
member.profileImage.prepend("/").prepend(imageHost),
|
|
||||||
member.nickname,
|
|
||||||
audioContent.price,
|
|
||||||
audioContent.duration
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.from(contentHashTagCurationItem)
|
|
||||||
.innerJoin(contentHashTagCurationItem.curation, contentHashTagCuration)
|
|
||||||
.innerJoin(contentHashTagCurationItem.content, audioContent)
|
|
||||||
.innerJoin(audioContent.member, member)
|
|
||||||
.leftJoin(blockMember).on(blockMemberCondition)
|
|
||||||
.where(where)
|
|
||||||
.orderBy(contentHashTagCurationItem.orders.asc())
|
|
||||||
.fetch()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.content.main.tab.content
|
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
|
||||||
import org.springframework.stereotype.Service
|
|
||||||
|
|
||||||
@Service
|
|
||||||
class ContentMainTabTagCurationService(private val repository: ContentMainTabTagCurationRepository) {
|
|
||||||
fun getTagList(isAdult: Boolean): List<String> {
|
|
||||||
return repository.getTagList(isAdult = isAdult)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getTagCurationContentList(memberId: Long, tag: String): List<GetAudioContentMainItem> {
|
|
||||||
return repository.getTagCurationContentList(memberId = memberId, tag = tag)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,6 @@ import kr.co.vividnext.sodalive.content.main.ContentCreatorResponse
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerResponse
|
import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerResponse
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
|
||||||
import kr.co.vividnext.sodalive.event.GetEventResponse
|
import kr.co.vividnext.sodalive.event.GetEventResponse
|
||||||
|
|
||||||
data class GetContentMainTabContentResponse(
|
data class GetContentMainTabContentResponse(
|
||||||
|
@ -15,9 +14,7 @@ data class GetContentMainTabContentResponse(
|
||||||
val rankSortTypeList: List<String>,
|
val rankSortTypeList: List<String>,
|
||||||
val rankContentList: List<GetAudioContentRankingItem>,
|
val rankContentList: List<GetAudioContentRankingItem>,
|
||||||
val contentRankCreatorList: List<ContentCreatorResponse>,
|
val contentRankCreatorList: List<ContentCreatorResponse>,
|
||||||
|
val salesRankContentList: List<GetAudioContentRankingItem>,
|
||||||
val salesCountRankContentList: List<GetAudioContentRankingItem>,
|
val salesCountRankContentList: List<GetAudioContentRankingItem>,
|
||||||
val eventBannerList: GetEventResponse,
|
val eventBannerList: GetEventResponse
|
||||||
val tagList: List<String>,
|
|
||||||
val tagCurationContentList: List<GetAudioContentMainItem>,
|
|
||||||
val curationList: List<GetContentCurationResponse>
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -60,19 +60,4 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/popular-content-by-creator")
|
|
||||||
fun getPopularContentByCreator(
|
|
||||||
@RequestParam creatorId: Long,
|
|
||||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
|
||||||
) = run {
|
|
||||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
|
||||||
|
|
||||||
ApiResponse.ok(
|
|
||||||
service.getPopularContentByCreator(
|
|
||||||
creatorId = creatorId,
|
|
||||||
isAdult = member.auth != null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,25 +3,20 @@ package kr.co.vividnext.sodalive.content.main.tab.free
|
||||||
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
||||||
import kr.co.vividnext.sodalive.content.ContentType
|
import kr.co.vividnext.sodalive.content.ContentType
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
||||||
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.AudioContentMainTabRepository
|
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.RecommendSeriesRepository
|
import kr.co.vividnext.sodalive.content.main.tab.RecommendSeriesRepository
|
||||||
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
|
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import kr.co.vividnext.sodalive.rank.RankingService
|
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class AudioContentMainTabFreeService(
|
class AudioContentMainTabFreeService(
|
||||||
private val repository: AudioContentMainTabRepository,
|
|
||||||
private val bannerService: AudioContentBannerService,
|
private val bannerService: AudioContentBannerService,
|
||||||
private val recommendSeriesRepository: RecommendSeriesRepository,
|
private val recommendSeriesRepository: RecommendSeriesRepository,
|
||||||
private val curationRepository: AudioContentCurationQueryRepository,
|
private val curationRepository: AudioContentCurationQueryRepository,
|
||||||
private val contentRepository: AudioContentRepository,
|
private val contentRepository: AudioContentRepository,
|
||||||
private val rankingService: RankingService,
|
|
||||||
private val audioContentRepository: AudioContentRepository,
|
private val audioContentRepository: AudioContentRepository,
|
||||||
private val audioContentThemeRepository: AudioContentThemeQueryRepository
|
private val audioContentThemeRepository: AudioContentThemeQueryRepository
|
||||||
) {
|
) {
|
||||||
|
@ -58,6 +53,7 @@ class AudioContentMainTabFreeService(
|
||||||
val newFreeContentList = if (themeList.isNotEmpty()) {
|
val newFreeContentList = if (themeList.isNotEmpty()) {
|
||||||
audioContentRepository.findByTheme(
|
audioContentRepository.findByTheme(
|
||||||
memberId = member.id!!,
|
memberId = member.id!!,
|
||||||
|
theme = themeList[0],
|
||||||
isAdult = member.auth != null,
|
isAdult = member.auth != null,
|
||||||
contentType = ContentType.ALL,
|
contentType = ContentType.ALL,
|
||||||
offset = 0,
|
offset = 0,
|
||||||
|
@ -68,13 +64,6 @@ class AudioContentMainTabFreeService(
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val creatorList = repository.findCreatorWithHasFreeContent(memberId, 4)
|
|
||||||
val playCountRankContentList = if (creatorList.isNotEmpty()) {
|
|
||||||
rankingService.fetchFreeContentByCreatorIdTop4(creatorList[0].creatorId, isAdult)
|
|
||||||
} else {
|
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
val curationList = curationRepository.findByContentMainTabId(tabId = tabId, isAdult = isAdult)
|
val curationList = curationRepository.findByContentMainTabId(tabId = tabId, isAdult = isAdult)
|
||||||
.filter { it.title != "크리에이터 소개" }
|
.filter { it.title != "크리에이터 소개" }
|
||||||
.map {
|
.map {
|
||||||
|
@ -98,8 +87,6 @@ class AudioContentMainTabFreeService(
|
||||||
recommendSeriesList = recommendSeriesList,
|
recommendSeriesList = recommendSeriesList,
|
||||||
themeList = themeList,
|
themeList = themeList,
|
||||||
newFreeContentList = newFreeContentList,
|
newFreeContentList = newFreeContentList,
|
||||||
creatorList = creatorList,
|
|
||||||
playCountRankContentList = playCountRankContentList,
|
|
||||||
curationList = curationList
|
curationList = curationList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -145,8 +132,4 @@ class AudioContentMainTabFreeService(
|
||||||
isFree = true
|
isFree = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
|
|
||||||
return rankingService.fetchFreeContentByCreatorIdTop4(creatorId, isAdult)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package kr.co.vividnext.sodalive.content.main.tab.free
|
package kr.co.vividnext.sodalive.content.main.tab.free
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.content.main.ContentCreatorResponse
|
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerResponse
|
import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerResponse
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetRecommendSeriesListResponse
|
import kr.co.vividnext.sodalive.content.main.tab.GetRecommendSeriesListResponse
|
||||||
|
@ -14,7 +12,5 @@ data class GetContentMainTabFreeResponse(
|
||||||
val recommendSeriesList: List<GetRecommendSeriesListResponse>,
|
val recommendSeriesList: List<GetRecommendSeriesListResponse>,
|
||||||
val themeList: List<String>,
|
val themeList: List<String>,
|
||||||
val newFreeContentList: List<GetAudioContentMainItem>,
|
val newFreeContentList: List<GetAudioContentMainItem>,
|
||||||
val creatorList: List<ContentCreatorResponse>,
|
|
||||||
val playCountRankContentList: List<GetAudioContentRankingItem>,
|
|
||||||
val curationList: List<GetContentCurationResponse>
|
val curationList: List<GetContentCurationResponse>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package kr.co.vividnext.sodalive.content.main.tab.home
|
package kr.co.vividnext.sodalive.content.main.tab.home
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
||||||
|
import kr.co.vividnext.sodalive.content.main.tab.GetPopularContentByCreatorResponse
|
||||||
import kr.co.vividnext.sodalive.event.EventService
|
import kr.co.vividnext.sodalive.event.EventService
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import kr.co.vividnext.sodalive.notice.ServiceNoticeService
|
import kr.co.vividnext.sodalive.notice.ServiceNoticeService
|
||||||
|
@ -74,17 +74,27 @@ class AudioContentMainTabHomeService(
|
||||||
|
|
||||||
/* 채널별 인기 콘텐츠
|
/* 채널별 인기 콘텐츠
|
||||||
* - 콘텐츠를 4개 이상 등록한 채널
|
* - 콘텐츠를 4개 이상 등록한 채널
|
||||||
* - 주간 콘텐츠 판매 개수 Top 20 채널
|
* - 주간 콘텐츠 매출 Top 20 채널
|
||||||
* - 해당 채널의 누적 판매 개수 Top 4
|
* - 해당 채널의 누적 매출 Top 2
|
||||||
|
* - 해당 채널의 누적 판매 개수 Top 2
|
||||||
*/
|
*/
|
||||||
val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20(
|
val contentRankCreatorList = rankingService.fetchCreatorByContentRevenueRankTop20(
|
||||||
memberId = member.id!!,
|
memberId = member.id!!,
|
||||||
startDate = startDate.minusDays(1),
|
startDate = startDate.minusDays(1),
|
||||||
endDate = endDate
|
endDate = endDate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val salesRankContentList = if (contentRankCreatorList.isNotEmpty()) {
|
||||||
|
rankingService.fetchCreatorContentBySalesTop2(
|
||||||
|
creatorId = contentRankCreatorList[0].creatorId,
|
||||||
|
isAdult = member.auth != null
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
val salesCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
|
val salesCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
|
||||||
rankingService.fetchCreatorContentBySalesCountTop4(
|
rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
creatorId = contentRankCreatorList[0].creatorId,
|
creatorId = contentRankCreatorList[0].creatorId,
|
||||||
isAdult = member.auth != null
|
isAdult = member.auth != null
|
||||||
)
|
)
|
||||||
|
@ -101,14 +111,25 @@ class AudioContentMainTabHomeService(
|
||||||
rankContentList = rankContentList,
|
rankContentList = rankContentList,
|
||||||
eventBannerList = eventBannerList,
|
eventBannerList = eventBannerList,
|
||||||
contentRankCreatorList = contentRankCreatorList,
|
contentRankCreatorList = contentRankCreatorList,
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
salesCountRankContentList = salesCountRankContentList
|
salesCountRankContentList = salesCountRankContentList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
|
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): GetPopularContentByCreatorResponse {
|
||||||
return rankingService.fetchCreatorContentBySalesCountTop4(
|
val salesRankContentList = rankingService.fetchCreatorContentBySalesTop2(
|
||||||
creatorId = creatorId,
|
creatorId = creatorId,
|
||||||
isAdult = isAdult
|
isAdult = isAdult
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val salesCountRankContentList = rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
|
creatorId = creatorId,
|
||||||
|
isAdult = isAdult
|
||||||
|
)
|
||||||
|
|
||||||
|
return GetPopularContentByCreatorResponse(
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
|
salesCountRankContentList = salesCountRankContentList
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,5 +18,6 @@ data class GetContentMainTabHomeResponse(
|
||||||
val rankContentList: List<GetAudioContentRankingItem>,
|
val rankContentList: List<GetAudioContentRankingItem>,
|
||||||
val eventBannerList: GetEventResponse,
|
val eventBannerList: GetEventResponse,
|
||||||
val contentRankCreatorList: List<ContentCreatorResponse>,
|
val contentRankCreatorList: List<ContentCreatorResponse>,
|
||||||
|
val salesRankContentList: List<GetAudioContentRankingItem>,
|
||||||
val salesCountRankContentList: List<GetAudioContentRankingItem>
|
val salesCountRankContentList: List<GetAudioContentRankingItem>
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,11 +2,11 @@ package kr.co.vividnext.sodalive.content.main.tab.replay
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
import kr.co.vividnext.sodalive.content.AudioContentRepository
|
||||||
import kr.co.vividnext.sodalive.content.ContentType
|
import kr.co.vividnext.sodalive.content.ContentType
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
|
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
|
||||||
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.AudioContentMainTabRepository
|
import kr.co.vividnext.sodalive.content.main.tab.AudioContentMainTabRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
|
||||||
|
import kr.co.vividnext.sodalive.content.main.tab.GetPopularContentByCreatorResponse
|
||||||
import kr.co.vividnext.sodalive.event.EventService
|
import kr.co.vividnext.sodalive.event.EventService
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import kr.co.vividnext.sodalive.rank.RankingService
|
import kr.co.vividnext.sodalive.rank.RankingService
|
||||||
|
@ -68,8 +68,18 @@ class AudioContentMainTabLiveReplayService(
|
||||||
minCount = 4
|
minCount = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val salesRankContentList = if (creatorList.isNotEmpty()) {
|
||||||
|
rankingService.fetchCreatorContentBySalesTop2(
|
||||||
|
creatorId = creatorList[0].creatorId,
|
||||||
|
isAdult = isAdult,
|
||||||
|
theme = theme
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
val salesCountRankContentList = if (creatorList.isNotEmpty()) {
|
val salesCountRankContentList = if (creatorList.isNotEmpty()) {
|
||||||
rankingService.fetchCreatorContentBySalesCountTop4(
|
rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
creatorId = creatorList[0].creatorId,
|
creatorId = creatorList[0].creatorId,
|
||||||
isAdult = isAdult,
|
isAdult = isAdult,
|
||||||
theme = theme
|
theme = theme
|
||||||
|
@ -97,17 +107,30 @@ class AudioContentMainTabLiveReplayService(
|
||||||
newLiveReplayContentList = newLiveReplayContentList,
|
newLiveReplayContentList = newLiveReplayContentList,
|
||||||
rankLiveReplayContentList = rankLiveReplayContentList,
|
rankLiveReplayContentList = rankLiveReplayContentList,
|
||||||
creatorList = creatorList,
|
creatorList = creatorList,
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
salesCountRankContentList = salesCountRankContentList,
|
salesCountRankContentList = salesCountRankContentList,
|
||||||
eventBannerList = eventBannerList,
|
eventBannerList = eventBannerList,
|
||||||
curationList = curationList
|
curationList = curationList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
|
fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): GetPopularContentByCreatorResponse {
|
||||||
return rankingService.fetchCreatorContentBySalesCountTop4(
|
val theme = "다시듣기"
|
||||||
|
val salesRankContentList = rankingService.fetchCreatorContentBySalesTop2(
|
||||||
creatorId = creatorId,
|
creatorId = creatorId,
|
||||||
isAdult = isAdult,
|
isAdult = isAdult,
|
||||||
theme = "다시듣기"
|
theme = theme
|
||||||
|
)
|
||||||
|
|
||||||
|
val salesCountRankContentList = rankingService.fetchCreatorContentBySalesCountTop2(
|
||||||
|
creatorId = creatorId,
|
||||||
|
isAdult = isAdult,
|
||||||
|
theme = theme
|
||||||
|
)
|
||||||
|
|
||||||
|
return GetPopularContentByCreatorResponse(
|
||||||
|
salesRankContentList = salesRankContentList,
|
||||||
|
salesCountRankContentList = salesCountRankContentList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ data class GetContentMainTabLiveReplayResponse(
|
||||||
val newLiveReplayContentList: List<GetAudioContentMainItem>,
|
val newLiveReplayContentList: List<GetAudioContentMainItem>,
|
||||||
val rankLiveReplayContentList: List<GetAudioContentRankingItem>,
|
val rankLiveReplayContentList: List<GetAudioContentRankingItem>,
|
||||||
val creatorList: List<ContentCreatorResponse>,
|
val creatorList: List<ContentCreatorResponse>,
|
||||||
|
val salesRankContentList: List<GetAudioContentRankingItem>,
|
||||||
val salesCountRankContentList: List<GetAudioContentRankingItem>,
|
val salesCountRankContentList: List<GetAudioContentRankingItem>,
|
||||||
val eventBannerList: GetEventResponse,
|
val eventBannerList: GetEventResponse,
|
||||||
val curationList: List<GetContentCurationResponse>
|
val curationList: List<GetContentCurationResponse>
|
||||||
|
|
|
@ -336,7 +336,7 @@ class RankingRepository(
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchCreatorBySellContentCountRankTop20(
|
fun fetchCreatorByContentRevenueRankTop20(
|
||||||
memberId: Long,
|
memberId: Long,
|
||||||
startDate: LocalDateTime,
|
startDate: LocalDateTime,
|
||||||
endDate: LocalDateTime
|
endDate: LocalDateTime
|
||||||
|
@ -350,12 +350,9 @@ class RankingRepository(
|
||||||
.and(order.createdAt.goe(startDate))
|
.and(order.createdAt.goe(startDate))
|
||||||
.and(order.createdAt.lt(startDate))
|
.and(order.createdAt.lt(startDate))
|
||||||
|
|
||||||
val memberCondition = member.isActive.isTrue
|
val where = member.isActive.isTrue
|
||||||
.and(member.role.eq(MemberRole.CREATOR))
|
.and(member.role.eq(MemberRole.CREATOR))
|
||||||
.and(member.id.eq(audioContent.member.id))
|
.and(audioContent.isActive.isTrue)
|
||||||
|
|
||||||
val where = audioContent.isActive.isTrue
|
|
||||||
.and(audioContent.price.gt(0))
|
|
||||||
.and(audioContent.duration.isNotNull)
|
.and(audioContent.duration.isNotNull)
|
||||||
.and(audioContent.limited.isNull)
|
.and(audioContent.limited.isNull)
|
||||||
.and(blockMember.id.isNull)
|
.and(blockMember.id.isNull)
|
||||||
|
@ -368,20 +365,71 @@ class RankingRepository(
|
||||||
member.profileImage.prepend("/").prepend(imageHost)
|
member.profileImage.prepend("/").prepend(imageHost)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.from(audioContent)
|
.from(member)
|
||||||
.innerJoin(member).on(memberCondition)
|
.innerJoin(audioContent).on(member.id.eq(audioContent.member.id))
|
||||||
.leftJoin(order).on(ordersCondition)
|
.leftJoin(order).on(ordersCondition)
|
||||||
.leftJoin(blockMember).on(blockMemberCondition)
|
.leftJoin(blockMember).on(blockMemberCondition)
|
||||||
.where(where)
|
.where(where)
|
||||||
.groupBy(member.id)
|
.groupBy(member.id)
|
||||||
.having(audioContent.id.count().goe(4))
|
.having(audioContent.id.count().goe(4))
|
||||||
.orderBy(order.id.count().desc(), member.id.desc())
|
.orderBy(
|
||||||
|
order.can.sum().desc(),
|
||||||
|
Expressions.numberTemplate(Double::class.java, "function('rand')").asc()
|
||||||
|
)
|
||||||
.offset(0)
|
.offset(0)
|
||||||
.limit(20)
|
.limit(20)
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchCreatorContentBySalesCountTop4(
|
fun fetchCreatorContentBySalesTop2(
|
||||||
|
creatorId: Long,
|
||||||
|
isAdult: Boolean,
|
||||||
|
theme: String
|
||||||
|
): List<GetAudioContentRankingItem> {
|
||||||
|
var where = member.isActive.isTrue
|
||||||
|
.and(member.role.eq(MemberRole.CREATOR))
|
||||||
|
.and(audioContent.isActive.isTrue)
|
||||||
|
.and(audioContent.duration.isNotNull)
|
||||||
|
.and(audioContent.limited.isNull)
|
||||||
|
.and(audioContentTheme.isActive.isTrue)
|
||||||
|
.and(order.isActive.isTrue)
|
||||||
|
.and(member.id.eq(creatorId))
|
||||||
|
|
||||||
|
if (!isAdult) {
|
||||||
|
where = where.and(series.isAdult.isFalse)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.isNotBlank()) {
|
||||||
|
where = where.and(audioContentTheme.theme.eq(theme))
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
QGetAudioContentRankingItem(
|
||||||
|
audioContent.id,
|
||||||
|
audioContent.title,
|
||||||
|
audioContent.coverImage.prepend("/").prepend(imageHost),
|
||||||
|
audioContentTheme.theme,
|
||||||
|
audioContent.price,
|
||||||
|
audioContent.duration,
|
||||||
|
member.id,
|
||||||
|
member.nickname,
|
||||||
|
member.profileImage.prepend("/").prepend(imageHost)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(order)
|
||||||
|
.innerJoin(order.audioContent, audioContent)
|
||||||
|
.innerJoin(audioContent.theme, audioContentTheme)
|
||||||
|
.innerJoin(audioContent.member, member)
|
||||||
|
.where(where)
|
||||||
|
.groupBy(audioContent.id)
|
||||||
|
.orderBy(order.can.sum().desc())
|
||||||
|
.offset(0)
|
||||||
|
.limit(2)
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetchCreatorContentBySalesCountTop2(
|
||||||
creatorId: Long,
|
creatorId: Long,
|
||||||
isAdult: Boolean,
|
isAdult: Boolean,
|
||||||
theme: String
|
theme: String
|
||||||
|
@ -425,7 +473,7 @@ class RankingRepository(
|
||||||
.groupBy(audioContent.id)
|
.groupBy(audioContent.id)
|
||||||
.orderBy(order.id.count().desc())
|
.orderBy(order.id.count().desc())
|
||||||
.offset(0)
|
.offset(0)
|
||||||
.limit(4)
|
.limit(2)
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,41 +556,4 @@ class RankingRepository(
|
||||||
.limit(10)
|
.limit(10)
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
|
|
||||||
var where = member.isActive.isTrue
|
|
||||||
.and(member.id.eq(creatorId))
|
|
||||||
.and(member.role.eq(MemberRole.CREATOR))
|
|
||||||
.and(audioContent.isActive.isTrue)
|
|
||||||
.and(audioContent.duration.isNotNull)
|
|
||||||
.and(audioContent.limited.isNull)
|
|
||||||
.and(audioContent.price.loe(0))
|
|
||||||
|
|
||||||
if (!isAdult) {
|
|
||||||
where = where.and(series.isAdult.isFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryFactory
|
|
||||||
.select(
|
|
||||||
QGetAudioContentRankingItem(
|
|
||||||
audioContent.id,
|
|
||||||
audioContent.title,
|
|
||||||
audioContent.coverImage.prepend("/").prepend(imageHost),
|
|
||||||
audioContentTheme.theme,
|
|
||||||
audioContent.price,
|
|
||||||
audioContent.duration,
|
|
||||||
member.id,
|
|
||||||
member.nickname,
|
|
||||||
member.profileImage.prepend("/").prepend(imageHost)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.from(audioContent)
|
|
||||||
.innerJoin(audioContent.theme, audioContentTheme)
|
|
||||||
.innerJoin(audioContent.member, member)
|
|
||||||
.where(where)
|
|
||||||
.orderBy(audioContent.playCount.desc())
|
|
||||||
.offset(0)
|
|
||||||
.limit(4)
|
|
||||||
.fetch()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,20 +181,28 @@ class RankingService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchCreatorBySellContentCountRankTop20(
|
fun fetchCreatorByContentRevenueRankTop20(
|
||||||
memberId: Long,
|
memberId: Long,
|
||||||
startDate: LocalDateTime,
|
startDate: LocalDateTime,
|
||||||
endDate: LocalDateTime
|
endDate: LocalDateTime
|
||||||
): List<ContentCreatorResponse> {
|
): List<ContentCreatorResponse> {
|
||||||
return repository.fetchCreatorBySellContentCountRankTop20(memberId, startDate, endDate)
|
return repository.fetchCreatorByContentRevenueRankTop20(memberId, startDate, endDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchCreatorContentBySalesCountTop4(
|
fun fetchCreatorContentBySalesTop2(
|
||||||
creatorId: Long,
|
creatorId: Long,
|
||||||
isAdult: Boolean,
|
isAdult: Boolean,
|
||||||
theme: String = ""
|
theme: String = ""
|
||||||
): List<GetAudioContentRankingItem> {
|
): List<GetAudioContentRankingItem> {
|
||||||
return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, theme)
|
return repository.fetchCreatorContentBySalesTop2(creatorId, isAdult, theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetchCreatorContentBySalesCountTop2(
|
||||||
|
creatorId: Long,
|
||||||
|
isAdult: Boolean,
|
||||||
|
theme: String = ""
|
||||||
|
): List<GetAudioContentRankingItem> {
|
||||||
|
return repository.fetchCreatorContentBySalesCountTop2(creatorId, isAdult, theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchCreatorBySeriesRevenueRankTop20(
|
fun fetchCreatorBySeriesRevenueRankTop20(
|
||||||
|
@ -209,8 +217,4 @@ class RankingService(
|
||||||
val seriesList = repository.fetchCreatorSeriesBySales(creatorId = creatorId, isAdult = isAdult)
|
val seriesList = repository.fetchCreatorSeriesBySales(creatorId = creatorId, isAdult = isAdult)
|
||||||
return seriesToSeriesListItem(seriesList, isAdult)
|
return seriesToSeriesListItem(seriesList, isAdult)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
|
|
||||||
return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue