test #164

Merged
klaus merged 2 commits from test into main 2024-04-15 12:31:43 +00:00
13 changed files with 263 additions and 3 deletions

View File

@ -0,0 +1,30 @@
package kr.co.vividnext.sodalive.admin.content.series.genre
import kr.co.vividnext.sodalive.common.ApiResponse
import org.springframework.security.access.prepost.PreAuthorize
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.RestController
@RestController
@PreAuthorize("hasRole('ADMIN')")
@RequestMapping("/admin/audio-content/series/genre")
class AdminContentSeriesGenreController(private val service: AdminContentSeriesGenreService) {
@PostMapping
fun createSeriesGenre(@RequestBody request: CreateSeriesGenreRequest) =
ApiResponse.ok(service.createSeriesGenre(genre = request.genre), "생성되었습니다.")
@PutMapping
fun modifySeriesGenre(@RequestBody request: ModifySeriesGenreRequest) = ApiResponse.ok(
service.modifySeriesGenre(request = request),
"수정되었습니다."
)
@PutMapping("/orders")
fun modifySeriesGenreOrders(@RequestBody request: ModifySeriesGenreOrderRequest) = ApiResponse.ok(
service.modifySeriesGenreOrders(ids = request.ids),
"수정되었습니다."
)
}

View File

@ -0,0 +1,9 @@
package kr.co.vividnext.sodalive.admin.content.series.genre
import org.springframework.data.jpa.repository.JpaRepository
interface AdminContentSeriesGenreRepository : JpaRepository<SeriesGenre, Long>, AdminContentSeriesGenreQueryRepository
interface AdminContentSeriesGenreQueryRepository
class AdminContentSeriesGenreQueryRepositoryImpl : AdminContentSeriesGenreQueryRepository

View File

@ -0,0 +1,49 @@
package kr.co.vividnext.sodalive.admin.content.series.genre
import kr.co.vividnext.sodalive.common.SodaException
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class AdminContentSeriesGenreService(private val repository: AdminContentSeriesGenreRepository) {
@Transactional
fun createSeriesGenre(genre: String) {
val seriesGenre = SeriesGenre(genre = genre.trim())
repository.save(seriesGenre)
}
@Transactional
fun modifySeriesGenre(request: ModifySeriesGenreRequest) {
if (request.genre == null && request.isAdult == null && request.isActive == null) {
throw SodaException("변경사항이 없습니다.")
}
val seriesGenre = repository.findByIdOrNull(id = request.id)
?: throw SodaException("잘못된 요청입니다.")
if (request.genre != null) {
seriesGenre.genre = request.genre
}
if (request.isAdult != null) {
seriesGenre.isAdult = request.isAdult
}
if (request.isActive != null) {
seriesGenre.isActive = request.isActive
}
}
@Transactional
fun modifySeriesGenreOrders(ids: List<Long>) {
for (index in ids.indices) {
val seriesGenre = repository.findByIdOrNull(ids[index])
if (seriesGenre != null) {
seriesGenre.orders = index + 1
}
}
}
}

View File

@ -0,0 +1,3 @@
package kr.co.vividnext.sodalive.admin.content.series.genre
data class CreateSeriesGenreRequest(val genre: String, val isAdult: Boolean)

View File

@ -0,0 +1,5 @@
package kr.co.vividnext.sodalive.admin.content.series.genre
data class ModifySeriesGenreRequest(val id: Long, val genre: String?, val isAdult: Boolean?, val isActive: Boolean?)
data class ModifySeriesGenreOrderRequest(val ids: List<Long>)

View File

@ -0,0 +1,17 @@
package kr.co.vividnext.sodalive.admin.content.series.genre
import kr.co.vividnext.sodalive.common.BaseEntity
import javax.persistence.Column
import javax.persistence.Entity
@Entity
data class SeriesGenre(
@Column(nullable = false)
var genre: String,
@Column(nullable = false)
var isAdult: Boolean = false,
@Column(nullable = false)
var isActive: Boolean = true,
@Column(nullable = false)
var orders: Int = 1
) : BaseEntity()

View File

@ -269,10 +269,21 @@ class ChargeService(
productId,
purchaseToken
)
charge.payment!!.status = PaymentStatus.COMPLETE
member.charge(charge.chargeCan, 0, "aos")
return true
val response = androidPublisher.purchases().products()
.get("kr.co.vividnext.sodalive", productId, purchaseToken)
.execute() ?: throw SodaException("결제정보에 오류가 있습니다.")
if (response.consumptionState == 1) {
charge.payment!!.status = PaymentStatus.COMPLETE
member.charge(charge.chargeCan, 0, "aos")
return true
} else {
attempt += 1
Thread.sleep(delay)
delay *= 2
}
} catch (e: Exception) {
lastError = e
attempt += 1
@ -280,6 +291,7 @@ class ChargeService(
delay *= 2
}
}
lastError?.printStackTrace()
return false
}

View File

@ -0,0 +1,42 @@
package kr.co.vividnext.sodalive.creator.admin.content.series
import kr.co.vividnext.sodalive.admin.content.series.genre.SeriesGenre
import kr.co.vividnext.sodalive.common.BaseEntity
import javax.persistence.CollectionTable
import javax.persistence.Column
import javax.persistence.ElementCollection
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.FetchType
import javax.persistence.JoinColumn
import javax.persistence.OneToOne
enum class SeriesPublishedDaysOfWeek {
SUN, MON, TUE, WED, THU, FRI, SAT, RANDOM
}
enum class SeriesState {
PROCEEDING, SUSPEND, COMPLETE
}
@Entity
data class Series(
var title: String,
@Column(columnDefinition = "TEXT", nullable = false)
var introduction: String,
@Enumerated(value = EnumType.STRING)
var state: SeriesState = SeriesState.PROCEEDING,
@ElementCollection(targetClass = SeriesPublishedDaysOfWeek::class, fetch = FetchType.EAGER)
@Enumerated(value = EnumType.STRING)
@CollectionTable(name = "series_published_days_of_week", joinColumns = [JoinColumn(name = "series_id")])
val publishedDaysOfWeek: Set<SeriesPublishedDaysOfWeek> = mutableSetOf(),
var isAdult: Boolean = false,
var isActive: Boolean = true
) : BaseEntity() {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "genre_id", nullable = false)
var genre: SeriesGenre? = null
var coverImage: String? = null
}

View File

@ -0,0 +1,24 @@
package kr.co.vividnext.sodalive.creator.admin.content.series.genre
import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.member.Member
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@PreAuthorize("hasRole('CREATOR')")
@RequestMapping("/creator-admin/audio-content/series/genre")
class CreatorAdminContentSeriesGenreController(private val service: CreatorAdminContentSeriesGenreService) {
@GetMapping
fun getGenreList(
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
ApiResponse.ok(service.getGenreList(isAdult = member.auth != null))
}
}

View File

@ -0,0 +1,32 @@
package kr.co.vividnext.sodalive.creator.admin.content.series.genre
import com.querydsl.jpa.impl.JPAQueryFactory
import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre
import kr.co.vividnext.sodalive.admin.content.series.genre.SeriesGenre
import org.springframework.data.jpa.repository.JpaRepository
interface CreatorAdminContentSeriesGenreRepository :
JpaRepository<SeriesGenre, Long>, CreatorAdminContentSeriesGenreQueryRepository
interface CreatorAdminContentSeriesGenreQueryRepository {
fun getGenreList(isAdult: Boolean): List<GetGenreListResponse>
}
class CreatorAdminContentSeriesGenreQueryRepositoryImpl(
private val queryFactory: JPAQueryFactory
) : CreatorAdminContentSeriesGenreQueryRepository {
override fun getGenreList(isAdult: Boolean): List<GetGenreListResponse> {
var where = seriesGenre.isActive.isTrue
if (!isAdult) {
where = where.and(seriesGenre.isAdult.isFalse)
}
return queryFactory
.select(QGetGenreListResponse(seriesGenre.id, seriesGenre.genre))
.from(seriesGenre)
.where(where)
.orderBy(seriesGenre.orders.asc())
.fetch()
}
}

View File

@ -0,0 +1,10 @@
package kr.co.vividnext.sodalive.creator.admin.content.series.genre
import org.springframework.stereotype.Service
@Service
class CreatorAdminContentSeriesGenreService(private val repository: CreatorAdminContentSeriesGenreRepository) {
fun getGenreList(isAdult: Boolean): List<GetGenreListResponse> {
return repository.getGenreList(isAdult = isAdult)
}
}

View File

@ -0,0 +1,5 @@
package kr.co.vividnext.sodalive.creator.admin.content.series.genre
import com.querydsl.core.annotations.QueryProjection
data class GetGenreListResponse @QueryProjection constructor(val id: Long, val genre: String)

View File

@ -0,0 +1,22 @@
package kr.co.vividnext.sodalive.creator.admin.content.series.keyword
import kr.co.vividnext.sodalive.common.BaseEntity
import kr.co.vividnext.sodalive.content.hashtag.HashTag
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
import javax.persistence.Entity
import javax.persistence.FetchType
import javax.persistence.JoinColumn
import javax.persistence.ManyToOne
@Entity
class SeriesKeyword : BaseEntity() {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "series_id", nullable = false)
var series: Series? = null
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "keyword_id", nullable = false)
var keyword: HashTag? = null
var isActive: Boolean = true
}