| @@ -65,6 +65,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) { | |||||||
|             .where( |             .where( | ||||||
|                 order.createdAt.goe(startDate) |                 order.createdAt.goe(startDate) | ||||||
|                     .and(order.createdAt.loe(endDate)) |                     .and(order.createdAt.loe(endDate)) | ||||||
|  |                     .and(order.isActive.isTrue) | ||||||
|             ) |             ) | ||||||
|             .groupBy(audioContent.id, order.type, orderFormattedDate, order.can) |             .groupBy(audioContent.id, order.type, orderFormattedDate, order.can) | ||||||
|             .orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc()) |             .orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc()) | ||||||
|   | |||||||
| @@ -105,6 +105,7 @@ class AudioContentController(private val service: AudioContentService) { | |||||||
|     fun getAudioContentList( |     fun getAudioContentList( | ||||||
|         @RequestParam("creator-id") creatorId: Long, |         @RequestParam("creator-id") creatorId: Long, | ||||||
|         @RequestParam("sort-type", required = false) sortType: SortType = SortType.NEWEST, |         @RequestParam("sort-type", required = false) sortType: SortType = SortType.NEWEST, | ||||||
|  |         @RequestParam("category-id", required = false) categoryId: Long? = 0, | ||||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, | ||||||
|         pageable: Pageable |         pageable: Pageable | ||||||
|     ) = run { |     ) = run { | ||||||
| @@ -114,6 +115,7 @@ class AudioContentController(private val service: AudioContentService) { | |||||||
|             service.getAudioContentList( |             service.getAudioContentList( | ||||||
|                 creatorId = creatorId, |                 creatorId = creatorId, | ||||||
|                 sortType = sortType, |                 sortType = sortType, | ||||||
|  |                 categoryId = categoryId ?: 0, | ||||||
|                 member = member, |                 member = member, | ||||||
|                 offset = pageable.offset, |                 offset = pageable.offset, | ||||||
|                 limit = pageable.pageSize.toLong() |                 limit = pageable.pageSize.toLong() | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import com.querydsl.core.types.dsl.Expressions | |||||||
| import com.querydsl.jpa.impl.JPAQueryFactory | import com.querydsl.jpa.impl.JPAQueryFactory | ||||||
| import kr.co.vividnext.sodalive.content.QAudioContent.audioContent | import kr.co.vividnext.sodalive.content.QAudioContent.audioContent | ||||||
| import kr.co.vividnext.sodalive.content.QBundleAudioContent.bundleAudioContent | import kr.co.vividnext.sodalive.content.QBundleAudioContent.bundleAudioContent | ||||||
|  | import kr.co.vividnext.sodalive.content.category.QCategoryContent.categoryContent | ||||||
| import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment | import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment | ||||||
| import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike | import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike | ||||||
| import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem | import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem | ||||||
| @@ -37,6 +38,7 @@ interface AudioContentQueryRepository { | |||||||
|         coverImageHost: String, |         coverImageHost: String, | ||||||
|         isAdult: Boolean = false, |         isAdult: Boolean = false, | ||||||
|         sortType: SortType = SortType.NEWEST, |         sortType: SortType = SortType.NEWEST, | ||||||
|  |         categoryId: Long = 0, | ||||||
|         offset: Long = 0, |         offset: Long = 0, | ||||||
|         limit: Long = 10 |         limit: Long = 10 | ||||||
|     ): List<GetAudioContentListItem> |     ): List<GetAudioContentListItem> | ||||||
| @@ -144,6 +146,7 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) | |||||||
|         coverImageHost: String, |         coverImageHost: String, | ||||||
|         isAdult: Boolean, |         isAdult: Boolean, | ||||||
|         sortType: SortType, |         sortType: SortType, | ||||||
|  |         categoryId: Long, | ||||||
|         offset: Long, |         offset: Long, | ||||||
|         limit: Long |         limit: Long | ||||||
|     ): List<GetAudioContentListItem> { |     ): List<GetAudioContentListItem> { | ||||||
| @@ -163,6 +166,10 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) | |||||||
|             where = where.and(audioContent.isAdult.isFalse) |             where = where.and(audioContent.isAdult.isFalse) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (categoryId > 0) { | ||||||
|  |             where = where.and(categoryContent.category.id.eq(categoryId)) | ||||||
|  |         } | ||||||
|  |  | ||||||
|         return queryFactory |         return queryFactory | ||||||
|             .select( |             .select( | ||||||
|                 QGetAudioContentListItem( |                 QGetAudioContentListItem( | ||||||
| @@ -180,6 +187,8 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) | |||||||
|                 ) |                 ) | ||||||
|             ) |             ) | ||||||
|             .from(audioContent) |             .from(audioContent) | ||||||
|  |             .leftJoin(categoryContent) | ||||||
|  |             .on(audioContent.id.eq(categoryContent.content.id).and(categoryContent.isActive.ne(false))) | ||||||
|             .leftJoin(pinContent) |             .leftJoin(pinContent) | ||||||
|             .on(audioContent.id.eq(pinContent.content.id).and(pinContent.isActive.ne(false))) |             .on(audioContent.id.eq(pinContent.content.id).and(pinContent.isActive.ne(false))) | ||||||
|             .where(where) |             .where(where) | ||||||
|   | |||||||
| @@ -624,6 +624,7 @@ class AudioContentService( | |||||||
|         creatorId: Long, |         creatorId: Long, | ||||||
|         sortType: SortType, |         sortType: SortType, | ||||||
|         member: Member, |         member: Member, | ||||||
|  |         categoryId: Long = 0, | ||||||
|         offset: Long, |         offset: Long, | ||||||
|         limit: Long |         limit: Long | ||||||
|     ): GetAudioContentListResponse { |     ): GetAudioContentListResponse { | ||||||
| @@ -637,6 +638,7 @@ class AudioContentService( | |||||||
|             coverImageHost = coverImageHost, |             coverImageHost = coverImageHost, | ||||||
|             isAdult = member.auth != null, |             isAdult = member.auth != null, | ||||||
|             sortType = sortType, |             sortType = sortType, | ||||||
|  |             categoryId = categoryId, | ||||||
|             offset = offset, |             offset = offset, | ||||||
|             limit = limit |             limit = limit | ||||||
|         ) |         ) | ||||||
|   | |||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | import kr.co.vividnext.sodalive.common.BaseEntity | ||||||
|  | import kr.co.vividnext.sodalive.member.Member | ||||||
|  | import javax.persistence.Entity | ||||||
|  | import javax.persistence.FetchType | ||||||
|  | import javax.persistence.JoinColumn | ||||||
|  | import javax.persistence.ManyToOne | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | data class Category( | ||||||
|  |     var title: String, | ||||||
|  |     var orders: Int = 1, | ||||||
|  |     var isActive: Boolean = true | ||||||
|  | ) : BaseEntity() { | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "member_id", nullable = false) | ||||||
|  |     var member: Member? = null | ||||||
|  | } | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | import kr.co.vividnext.sodalive.common.BaseEntity | ||||||
|  | import kr.co.vividnext.sodalive.content.AudioContent | ||||||
|  | import javax.persistence.Entity | ||||||
|  | import javax.persistence.FetchType | ||||||
|  | import javax.persistence.JoinColumn | ||||||
|  | import javax.persistence.ManyToOne | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | data class CategoryContent( | ||||||
|  |     var orders: Int = 1, | ||||||
|  |     var isActive: Boolean = true | ||||||
|  | ) : BaseEntity() { | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "content_id", nullable = false) | ||||||
|  |     var content: AudioContent? = null | ||||||
|  |  | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "category_id", nullable = false) | ||||||
|  |     var category: Category? = null | ||||||
|  | } | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | import com.querydsl.jpa.impl.JPAQueryFactory | ||||||
|  | import kr.co.vividnext.sodalive.content.category.QCategoryContent.categoryContent | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository | ||||||
|  |  | ||||||
|  | interface CategoryContentRepository : JpaRepository<CategoryContent, Long>, CategoryContentQueryRepository | ||||||
|  |  | ||||||
|  | interface CategoryContentQueryRepository { | ||||||
|  |     fun findByContentIdAndCategoryId(contentId: Long, categoryId: Long): CategoryContent? | ||||||
|  |     fun deleteByCategoryId(categoryId: Long) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class CategoryContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : CategoryContentQueryRepository { | ||||||
|  |     override fun findByContentIdAndCategoryId(contentId: Long, categoryId: Long): CategoryContent? { | ||||||
|  |         return queryFactory | ||||||
|  |             .selectFrom(categoryContent) | ||||||
|  |             .where( | ||||||
|  |                 categoryContent.content.id.eq(contentId) | ||||||
|  |                     .and(categoryContent.category.id.eq(categoryId)) | ||||||
|  |             ) | ||||||
|  |             .fetchFirst() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun deleteByCategoryId(categoryId: Long) { | ||||||
|  |         queryFactory | ||||||
|  |             .update(categoryContent) | ||||||
|  |             .set(categoryContent.isActive, false) | ||||||
|  |             .where(categoryContent.category.id.eq(categoryId)) | ||||||
|  |             .execute() | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,63 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | import kr.co.vividnext.sodalive.common.ApiResponse | ||||||
|  | import kr.co.vividnext.sodalive.common.SodaException | ||||||
|  | import kr.co.vividnext.sodalive.member.Member | ||||||
|  | import org.springframework.security.access.prepost.PreAuthorize | ||||||
|  | import org.springframework.security.core.annotation.AuthenticationPrincipal | ||||||
|  | import org.springframework.web.bind.annotation.DeleteMapping | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable | ||||||
|  | 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("/category") | ||||||
|  | class CategoryController(private val service: CategoryService) { | ||||||
|  |     @PostMapping | ||||||
|  |     @PreAuthorize("hasRole('CREATOR')") | ||||||
|  |     fun createCategory( | ||||||
|  |         @RequestBody request: CreateCategoryRequest, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.createCategory(request = request, member = member)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PutMapping | ||||||
|  |     @PreAuthorize("hasRole('CREATOR')") | ||||||
|  |     fun modifyCategory( | ||||||
|  |         @RequestBody request: ModifyCategoryRequest, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.modifyCategory(request = request, member = member)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @DeleteMapping("/{id}") | ||||||
|  |     @PreAuthorize("hasRole('CREATOR')") | ||||||
|  |     fun deleteCategory( | ||||||
|  |         @PathVariable("id") categoryId: Long, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.deleteCategory(categoryId = categoryId, member = member)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping | ||||||
|  |     fun getCategoryList( | ||||||
|  |         @RequestParam creatorId: Long, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.getCategoryList(creatorId = creatorId, memberId = member.id!!)) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,45 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | import com.querydsl.jpa.impl.JPAQueryFactory | ||||||
|  | import kr.co.vividnext.sodalive.content.category.QCategory.category | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository | ||||||
|  |  | ||||||
|  | interface CategoryRepository : JpaRepository<Category, Long>, CategoryQueryRepository | ||||||
|  |  | ||||||
|  | interface CategoryQueryRepository { | ||||||
|  |     fun findByTitleAndMemberId(title: String, memberId: Long): Category? | ||||||
|  |  | ||||||
|  |     fun findByIdAndMemberId(categoryId: Long, memberId: Long): Category? | ||||||
|  |  | ||||||
|  |     fun findByCreatorId(creatorId: Long): List<GetCategoryListResponse> | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class CategoryQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : CategoryQueryRepository { | ||||||
|  |     override fun findByTitleAndMemberId(title: String, memberId: Long): Category? { | ||||||
|  |         return queryFactory | ||||||
|  |             .selectFrom(category) | ||||||
|  |             .where( | ||||||
|  |                 category.title.eq(title) | ||||||
|  |                     .and(category.member.id.eq(memberId)) | ||||||
|  |             ) | ||||||
|  |             .fetchFirst() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun findByIdAndMemberId(categoryId: Long, memberId: Long): Category? { | ||||||
|  |         return queryFactory | ||||||
|  |             .selectFrom(category) | ||||||
|  |             .where( | ||||||
|  |                 category.id.eq(categoryId) | ||||||
|  |                     .and(category.member.id.eq(memberId)) | ||||||
|  |             ) | ||||||
|  |             .fetchFirst() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun findByCreatorId(creatorId: Long): List<GetCategoryListResponse> { | ||||||
|  |         return queryFactory | ||||||
|  |             .select(QGetCategoryListResponse(category.id, category.title)) | ||||||
|  |             .from(category) | ||||||
|  |             .where(category.member.id.eq(creatorId)) | ||||||
|  |             .fetch() | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,99 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | import kr.co.vividnext.sodalive.common.SodaException | ||||||
|  | import kr.co.vividnext.sodalive.content.AudioContentRepository | ||||||
|  | import kr.co.vividnext.sodalive.member.Member | ||||||
|  | import kr.co.vividnext.sodalive.member.block.BlockMemberRepository | ||||||
|  | import org.springframework.stereotype.Service | ||||||
|  | import org.springframework.transaction.annotation.Transactional | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | class CategoryService( | ||||||
|  |     private val repository: CategoryRepository, | ||||||
|  |     private val contentRepository: AudioContentRepository, | ||||||
|  |     private val blockMemberRepository: BlockMemberRepository, | ||||||
|  |     private val categoryContentRepository: CategoryContentRepository | ||||||
|  | ) { | ||||||
|  |     @Transactional | ||||||
|  |     fun createCategory(request: CreateCategoryRequest, member: Member) { | ||||||
|  |         validateTitle(title = request.title) | ||||||
|  |         val category = repository.findByTitleAndMemberId(title = request.title, memberId = member.id!!) | ||||||
|  |             ?: repository.save( | ||||||
|  |                 Category(title = request.title).apply { | ||||||
|  |                     this.member = member | ||||||
|  |                 } | ||||||
|  |             ) | ||||||
|  |         category.isActive = true | ||||||
|  |  | ||||||
|  |         for (contentId in request.contentIdList) { | ||||||
|  |             val content = contentRepository.findByIdAndActive(contentId = contentId) | ||||||
|  |                 ?: continue | ||||||
|  |  | ||||||
|  |             val categoryContent = categoryContentRepository.findByContentIdAndCategoryId( | ||||||
|  |                 contentId = contentId, | ||||||
|  |                 categoryId = category.id!! | ||||||
|  |             ) ?: categoryContentRepository.save( | ||||||
|  |                 CategoryContent().apply { | ||||||
|  |                     this.content = content | ||||||
|  |                     this.category = category | ||||||
|  |                 } | ||||||
|  |             ) | ||||||
|  |             categoryContent.isActive = true | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Transactional | ||||||
|  |     fun modifyCategory(request: ModifyCategoryRequest, member: Member) { | ||||||
|  |         val category = repository.findByIdAndMemberId(categoryId = request.categoryId, memberId = member.id!!) | ||||||
|  |             ?: throw SodaException("잘못된 요청입니다.") | ||||||
|  |  | ||||||
|  |         if (!request.title.isNullOrBlank()) { | ||||||
|  |             validateTitle(title = request.title) | ||||||
|  |             category.title = request.title | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         for (contentId in request.addContentIdList) { | ||||||
|  |             val content = contentRepository.findByIdAndActive(contentId = contentId) | ||||||
|  |                 ?: continue | ||||||
|  |  | ||||||
|  |             val categoryContent = categoryContentRepository.findByContentIdAndCategoryId( | ||||||
|  |                 contentId = contentId, | ||||||
|  |                 categoryId = category.id!! | ||||||
|  |             ) ?: categoryContentRepository.save( | ||||||
|  |                 CategoryContent().apply { | ||||||
|  |                     this.content = content | ||||||
|  |                     this.category = category | ||||||
|  |                 } | ||||||
|  |             ) | ||||||
|  |             categoryContent.isActive = true | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         for (contentId in request.removeContentIdList) { | ||||||
|  |             val categoryContent = categoryContentRepository.findByContentIdAndCategoryId( | ||||||
|  |                 contentId = contentId, | ||||||
|  |                 categoryId = category.id!! | ||||||
|  |             ) ?: continue | ||||||
|  |             categoryContent.isActive = false | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Transactional | ||||||
|  |     fun deleteCategory(categoryId: Long, member: Member) { | ||||||
|  |         val category = repository.findByIdAndMemberId(categoryId = categoryId, memberId = member.id!!) | ||||||
|  |             ?: throw SodaException("잘못된 요청입니다.") | ||||||
|  |         category.isActive = false | ||||||
|  |  | ||||||
|  |         categoryContentRepository.deleteByCategoryId(categoryId = categoryId) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun getCategoryList(creatorId: Long, memberId: Long): List<GetCategoryListResponse> { | ||||||
|  |         val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = creatorId) | ||||||
|  |         if (isBlocked) throw SodaException("잘못된 접근입니다.") | ||||||
|  |  | ||||||
|  |         return repository.findByCreatorId(creatorId = creatorId) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun validateTitle(title: String) { | ||||||
|  |         if (title.length < 2) throw SodaException("카테고리명은 2글자 이상 입력하세요") | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | data class CreateCategoryRequest( | ||||||
|  |     val title: String, | ||||||
|  |     val contentIdList: List<Long> | ||||||
|  | ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | import com.querydsl.core.annotations.QueryProjection | ||||||
|  |  | ||||||
|  | data class GetCategoryListResponse @QueryProjection constructor( | ||||||
|  |     val categoryId: Long, | ||||||
|  |     val category: String | ||||||
|  | ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package kr.co.vividnext.sodalive.content.category | ||||||
|  |  | ||||||
|  | data class ModifyCategoryRequest( | ||||||
|  |     val categoryId: Long, | ||||||
|  |     val title: String?, | ||||||
|  |     val addContentIdList: List<Long>, | ||||||
|  |     val removeContentIdList: List<Long> | ||||||
|  | ) | ||||||
| @@ -116,16 +116,14 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac | |||||||
|                     order.can.sum() |                     order.can.sum() | ||||||
|                 ) |                 ) | ||||||
|             ) |             ) | ||||||
|             .from(useCanCalculate) |             .from(order) | ||||||
|             .innerJoin(useCanCalculate.useCan, useCan) |  | ||||||
|             .innerJoin(useCan.order, order) |  | ||||||
|             .innerJoin(order.audioContent, audioContent) |             .innerJoin(order.audioContent, audioContent) | ||||||
|             .innerJoin(audioContent.member, member) |             .innerJoin(audioContent.member, member) | ||||||
|             .where( |             .where( | ||||||
|                 useCanCalculate.status.eq(UseCanCalculateStatus.RECEIVED) |                 order.createdAt.goe(startDate) | ||||||
|                     .and(useCanCalculate.recipientCreatorId.eq(memberId)) |  | ||||||
|                     .and(order.createdAt.goe(startDate)) |  | ||||||
|                     .and(order.createdAt.loe(endDate)) |                     .and(order.createdAt.loe(endDate)) | ||||||
|  |                     .and(order.isActive.isTrue) | ||||||
|  |                     .and(order.creator.id.eq(memberId)) | ||||||
|             ) |             ) | ||||||
|             .groupBy(audioContent.id, order.type, orderFormattedDate, order.can) |             .groupBy(audioContent.id, order.type, orderFormattedDate, order.can) | ||||||
|             .offset(offset) |             .offset(offset) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user