fix(subbanner): 언어 설정과 국가별 공개 필터를 추가한다
This commit is contained in:
+1
-1
@@ -18,7 +18,7 @@ class AudioRecommendationFacade(
|
||||
) {
|
||||
fun getRecommendations(member: Member?, lang: Lang): AudioRecommendationsResponse {
|
||||
val result = queryService.getRecommendations(member, lang)
|
||||
val subBanners = subBannerService.findVisibleByPlacement(SubBannerPlacement.CONTENT_RECOMMENDATION)
|
||||
val subBanners = subBannerService.findVisibleByPlacement(SubBannerPlacement.CONTENT_RECOMMENDATION, member)
|
||||
.map { SubBannerResponse.from(it, cloudFrontHost) }
|
||||
return AudioRecommendationsResponse.from(result, subBanners)
|
||||
}
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ class HomeRecommendationFacade(
|
||||
lang = bannerLang
|
||||
)
|
||||
.map { RecommendationBannerResponse.from(it.toBanner()) },
|
||||
subBanners = subBannerService.findVisibleByPlacement(SubBannerPlacement.HOME_RECOMMENDATION)
|
||||
subBanners = subBannerService.findVisibleByPlacement(SubBannerPlacement.HOME_RECOMMENDATION, member)
|
||||
.map { SubBannerResponse.from(it, cloudFrontHost) },
|
||||
recentlyActiveCreators = queryService.findRecentlyActiveCreators(
|
||||
HOME_ACTIVE_CREATOR_LIMIT,
|
||||
|
||||
+6
-2
@@ -1,6 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.v2.subbanner.adapter.out.persistence
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.adapter.out.persistence.QSubBannerEntity.subBannerEntity
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBanner
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBannerPlacement
|
||||
@@ -25,12 +26,13 @@ class DefaultSubBannerRepository(
|
||||
.fetch()
|
||||
.map { it.toDomain() }
|
||||
|
||||
override fun findVisibleByPlacement(placement: SubBannerPlacement, now: LocalDateTime): List<SubBanner> {
|
||||
override fun findVisibleByPlacement(placement: SubBannerPlacement, lang: Lang, now: LocalDateTime): List<SubBanner> {
|
||||
val visibleAt = now.truncatedTo(ChronoUnit.SECONDS)
|
||||
return queryFactory
|
||||
.selectFrom(subBannerEntity)
|
||||
.where(
|
||||
subBannerEntity.placement.eq(placement),
|
||||
subBannerEntity.lang.eq(lang),
|
||||
subBannerEntity.isActive.isTrue,
|
||||
subBannerEntity.startDate.isNull.or(subBannerEntity.startDate.loe(visibleAt)),
|
||||
subBannerEntity.endDate.isNull.or(subBannerEntity.endDate.goe(visibleAt))
|
||||
@@ -51,7 +53,8 @@ class DefaultSubBannerRepository(
|
||||
subBanner.androidDeepLink,
|
||||
subBanner.iosDeepLink,
|
||||
startDate,
|
||||
endDate
|
||||
endDate,
|
||||
lang = subBanner.lang
|
||||
).also { entityManager.persist(it) }
|
||||
} else {
|
||||
entityManager.find(SubBannerEntity::class.java, subBanner.id).apply {
|
||||
@@ -62,6 +65,7 @@ class DefaultSubBannerRepository(
|
||||
iosDeepLink = subBanner.iosDeepLink
|
||||
this.startDate = startDate
|
||||
this.endDate = endDate
|
||||
lang = subBanner.lang
|
||||
}
|
||||
}
|
||||
return entity.toDomain()
|
||||
|
||||
+8
-2
@@ -1,6 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.v2.subbanner.adapter.out.persistence
|
||||
|
||||
import kr.co.vividnext.sodalive.common.BaseEntity
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBanner
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBannerPlacement
|
||||
import org.hibernate.annotations.DynamicUpdate
|
||||
@@ -39,7 +40,12 @@ class SubBannerEntity(
|
||||
var endDate: LocalDateTime?,
|
||||
|
||||
@Column(name = "is_active", nullable = false)
|
||||
var isActive: Boolean = true
|
||||
var isActive: Boolean = true,
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "lang", nullable = false, length = 10)
|
||||
var lang: Lang = Lang.KO
|
||||
) : BaseEntity() {
|
||||
fun toDomain(): SubBanner = SubBanner(id, placement, imagePath, webUrl, androidDeepLink, iosDeepLink, startDate, endDate)
|
||||
fun toDomain(): SubBanner =
|
||||
SubBanner(id, placement, imagePath, webUrl, androidDeepLink, iosDeepLink, startDate, endDate, lang)
|
||||
}
|
||||
|
||||
+19
-4
@@ -6,6 +6,9 @@ import com.fasterxml.jackson.databind.JsonNode
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import kr.co.vividnext.sodalive.utils.generateFileName
|
||||
import kr.co.vividnext.sodalive.utils.validateImage
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBanner
|
||||
@@ -33,6 +36,7 @@ class SubBannerService(
|
||||
private val repository: SubBannerRepository,
|
||||
private val s3Uploader: S3Uploader,
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val memberContentPreferenceService: MemberContentPreferenceService,
|
||||
@Value("\${cloud.aws.s3.bucket}") private val bucket: String,
|
||||
private val nowProvider: () -> LocalDateTime = { LocalDateTime.now(ZoneOffset.UTC) }
|
||||
) {
|
||||
@@ -40,9 +44,10 @@ class SubBannerService(
|
||||
fun findAllByPlacement(placement: SubBannerPlacement): List<SubBanner> = repository.findAllByPlacement(placement)
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun findVisibleByPlacement(placement: SubBannerPlacement): List<SubBanner> {
|
||||
fun findVisibleByPlacement(placement: SubBannerPlacement, member: Member?): List<SubBanner> {
|
||||
val now = nowProvider().truncatedTo(ChronoUnit.SECONDS)
|
||||
return repository.findVisibleByPlacement(placement, now)
|
||||
val lang = if (memberContentPreferenceService.resolveCountryCode(member) == "JP") Lang.JA else Lang.KO
|
||||
return repository.findVisibleByPlacement(placement, lang, now)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -61,7 +66,8 @@ class SubBannerService(
|
||||
androidDeepLink = input.androidDeepLink,
|
||||
iosDeepLink = input.iosDeepLink,
|
||||
startDate = startDate,
|
||||
endDate = endDate
|
||||
endDate = endDate,
|
||||
lang = input.lang
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -83,7 +89,8 @@ class SubBannerService(
|
||||
androidDeepLink = input.androidDeepLink,
|
||||
iosDeepLink = input.iosDeepLink,
|
||||
startDate = startDate,
|
||||
endDate = endDate
|
||||
endDate = endDate,
|
||||
lang = if (fields.has("lang")) input.lang else existing.lang
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -118,6 +125,14 @@ class SubBannerService(
|
||||
val value = fields[field]
|
||||
if (value != null && !value.isNull && !value.isTextual) invalidRequest()
|
||||
}
|
||||
fields["lang"]?.let { value ->
|
||||
if (!value.isTextual) invalidRequest()
|
||||
try {
|
||||
Lang.fromCode(value.textValue())
|
||||
} catch (_: IllegalArgumentException) {
|
||||
invalidRequest()
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.v2.subbanner.domain
|
||||
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import java.time.LocalDateTime
|
||||
|
||||
data class SubBanner(
|
||||
@@ -10,7 +11,8 @@ data class SubBanner(
|
||||
val androidDeepLink: String?,
|
||||
val iosDeepLink: String?,
|
||||
val startDate: LocalDateTime?,
|
||||
val endDate: LocalDateTime?
|
||||
val endDate: LocalDateTime?,
|
||||
val lang: Lang = Lang.KO
|
||||
) {
|
||||
init {
|
||||
require(!webUrl.isNullOrBlank() || !androidDeepLink.isNullOrBlank() || !iosDeepLink.isNullOrBlank()) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.v2.subbanner.dto
|
||||
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBanner
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBannerPlacement
|
||||
import java.time.LocalDateTime
|
||||
@@ -15,7 +16,8 @@ data class AdminSubBannerResponse(
|
||||
val androidDeepLink: String?,
|
||||
val iosDeepLink: String?,
|
||||
val startDate: String?,
|
||||
val endDate: String?
|
||||
val endDate: String?,
|
||||
val lang: Lang
|
||||
) {
|
||||
companion object {
|
||||
fun from(banner: SubBanner, cloudFrontHost: String): AdminSubBannerResponse = AdminSubBannerResponse(
|
||||
@@ -26,7 +28,8 @@ data class AdminSubBannerResponse(
|
||||
androidDeepLink = banner.androidDeepLink,
|
||||
iosDeepLink = banner.iosDeepLink,
|
||||
startDate = formatDate(banner.startDate),
|
||||
endDate = formatDate(banner.endDate)
|
||||
endDate = formatDate(banner.endDate),
|
||||
lang = banner.lang
|
||||
)
|
||||
|
||||
private fun formatDate(value: LocalDateTime?): String? = value?.atZone(ZoneOffset.UTC)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.v2.subbanner.dto
|
||||
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBannerPlacement
|
||||
|
||||
data class SubBannerRequest(
|
||||
@@ -8,5 +9,6 @@ data class SubBannerRequest(
|
||||
val androidDeepLink: String?,
|
||||
val iosDeepLink: String?,
|
||||
val startDate: String? = null,
|
||||
val endDate: String? = null
|
||||
val endDate: String? = null,
|
||||
val lang: Lang = Lang.KO
|
||||
)
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.v2.subbanner.port.out
|
||||
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBanner
|
||||
import kr.co.vividnext.sodalive.v2.subbanner.domain.SubBannerPlacement
|
||||
import java.time.LocalDateTime
|
||||
@@ -7,7 +8,7 @@ import java.time.LocalDateTime
|
||||
interface SubBannerRepository {
|
||||
fun findById(id: Long): SubBanner?
|
||||
fun findAllByPlacement(placement: SubBannerPlacement): List<SubBanner>
|
||||
fun findVisibleByPlacement(placement: SubBannerPlacement, now: LocalDateTime): List<SubBanner>
|
||||
fun findVisibleByPlacement(placement: SubBannerPlacement, lang: Lang, now: LocalDateTime): List<SubBanner>
|
||||
fun save(subBanner: SubBanner): SubBanner
|
||||
fun deleteById(id: Long)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user