Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

import app.bottlenote.alcohols.dto.request.AdminCurationSearchRequest;
import app.bottlenote.alcohols.dto.response.AdminCurationListResponse;
import app.bottlenote.alcohols.dto.response.AlcoholsSearchItem;
import app.bottlenote.alcohols.dto.response.CurationKeywordResponse;
import app.bottlenote.global.service.cursor.CursorResponse;
import java.util.List;
import java.util.Optional;
import java.util.Set;
Expand All @@ -18,12 +15,6 @@ public interface CurationKeywordRepository {

Optional<CurationKeyword> findByNameContainingAndIsActiveTrue(String name);

CursorResponse<CurationKeywordResponse> searchCurationKeywords(
String keyword, Long alcoholId, Long cursor, Integer pageSize);

CursorResponse<AlcoholsSearchItem> getCurationAlcohols(
Long curationId, Long cursor, Integer pageSize);

Optional<Set<Long>> findAlcoholIdsByKeyword(String keyword);

// Admin용 메서드
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,13 @@

import app.bottlenote.alcohols.dto.request.AdminCurationSearchRequest;
import app.bottlenote.alcohols.dto.response.AdminCurationListResponse;
import app.bottlenote.alcohols.dto.response.AlcoholsSearchItem;
import app.bottlenote.alcohols.dto.response.CurationKeywordResponse;
import app.bottlenote.global.service.cursor.CursorResponse;
import java.util.Optional;
import java.util.Set;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface CustomCurationKeywordRepository {

CursorResponse<CurationKeywordResponse> searchCurationKeywords(
String keyword, Long alcoholId, Long cursor, Integer pageSize);

CursorResponse<AlcoholsSearchItem> getCurationAlcohols(
Long curationId, Long cursor, Integer pageSize);

Optional<Set<Long>> findAlcoholIdsByKeyword(String keyword);

Page<AdminCurationListResponse> searchForAdmin(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
package app.bottlenote.alcohols.repository;

import static app.bottlenote.alcohols.domain.QAlcohol.alcohol;
import static app.bottlenote.alcohols.domain.QCurationKeyword.curationKeyword;
import static app.bottlenote.picks.domain.QPicks.picks;
import static app.bottlenote.rating.domain.QRating.rating;
import static app.bottlenote.review.domain.QReview.review;

import app.bottlenote.alcohols.domain.CurationKeyword;
import app.bottlenote.alcohols.dto.request.AdminCurationSearchRequest;
import app.bottlenote.alcohols.dto.response.AdminCurationListResponse;
import app.bottlenote.alcohols.dto.response.AlcoholsSearchItem;
import app.bottlenote.alcohols.dto.response.CurationKeywordResponse;
import app.bottlenote.global.service.cursor.CursorPageable;
import app.bottlenote.global.service.cursor.CursorResponse;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -30,110 +21,6 @@ public class CustomCurationKeywordRepositoryImpl implements CustomCurationKeywor

private final JPAQueryFactory queryFactory;

@Override
public CursorResponse<CurationKeywordResponse> searchCurationKeywords(
String keyword, Long alcoholId, Long cursor, Integer pageSize) {
List<CurationKeywordResponse> results =
queryFactory
.select(
Projections.fields(
CurationKeywordResponse.class,
curationKeyword.id.as("id"),
curationKeyword.name.as("name"),
curationKeyword.description.as("description"),
curationKeyword.coverImageUrl.as("coverImageUrl"),
curationKeyword.alcoholIds.size().as("alcoholCount"),
curationKeyword.displayOrder.as("displayOrder")))
.from(curationKeyword)
.where(
curationKeyword.isActive.isTrue(),
keywordContains(keyword),
alcoholIdIn(alcoholId),
curationKeyword.id.gt(cursor))
.orderBy(curationKeyword.displayOrder.asc(), curationKeyword.id.desc())
.limit(pageSize + 1)
.fetch();

CursorPageable pageable = CursorPageable.of(results, cursor, pageSize);
List<CurationKeywordResponse> content =
results.size() > pageSize ? results.subList(0, pageSize) : results;

return CursorResponse.of(content, pageable);
}

@Override
public CursorResponse<AlcoholsSearchItem> getCurationAlcohols(
Long curationId, Long cursor, Integer pageSize) {
CurationKeyword curation =
queryFactory
.selectFrom(curationKeyword)
.where(curationKeyword.id.eq(curationId))
.fetchOne();

if (curation == null || curation.getAlcoholIds().isEmpty()) {
return CursorResponse.of(
List.of(),
CursorPageable.builder()
.currentCursor(cursor)
.cursor(cursor)
.pageSize((long) pageSize)
.hasNext(false)
.build());
}

List<Long> alcoholIdsList = curation.getAlcoholIds().stream().toList();

List<AlcoholsSearchItem> results =
queryFactory
.select(
Projections.fields(
AlcoholsSearchItem.class,
alcohol.id.as("alcoholId"),
alcohol.korName.as("korName"),
alcohol.engName.as("engName"),
alcohol.korCategory.as("korCategoryName"),
alcohol.engCategory.as("engCategoryName"),
alcohol.imageUrl.as("imageUrl"),
rating
.ratingPoint
.rating
.avg()
.multiply(2)
.castToNum(Double.class)
.round()
.divide(2)
.coalesce(0.0)
.as("rating"),
rating.id.countDistinct().as("ratingCount"),
review.id.countDistinct().as("reviewCount"),
picks.id.countDistinct().as("pickCount"),
Expressions.asBoolean(false).as("isPicked")))
.from(alcohol)
.leftJoin(rating)
.on(alcohol.id.eq(rating.id.alcoholId))
.leftJoin(review)
.on(alcohol.id.eq(review.alcoholId))
.leftJoin(picks)
.on(alcohol.id.eq(picks.alcoholId))
.where(alcohol.id.in(alcoholIdsList), alcohol.id.gt(cursor), alcohol.deletedAt.isNull())
.groupBy(
alcohol.id,
alcohol.korName,
alcohol.engName,
alcohol.korCategory,
alcohol.engCategory,
alcohol.imageUrl)
// .orderBy()
.limit(pageSize + 1)
.fetch();

CursorPageable pageable = CursorPageable.of(results, cursor, pageSize);
List<AlcoholsSearchItem> content =
results.size() > pageSize ? results.subList(0, pageSize) : results;

return CursorResponse.of(content, pageable);
}

@Override
public java.util.Optional<java.util.Set<Long>> findAlcoholIdsByKeyword(String keyword) {
if (keyword == null || keyword.isBlank()) {
Expand All @@ -156,19 +43,6 @@ private BooleanExpression keywordContains(String keyword) {
: null;
}

private BooleanExpression alcoholIdIn(Long alcoholId) {
if (alcoholId == null) {
return null;
}

return Expressions.numberTemplate(
Long.class,
"CASE WHEN {0} MEMBER OF {1} THEN 1 ELSE 0 END",
alcoholId,
curationKeyword.alcoholIds)
.eq(1L);
}

@Override
public Page<AdminCurationListResponse> searchForAdmin(
AdminCurationSearchRequest request, Pageable pageable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@
import app.bottlenote.alcohols.domain.RegionRepository;
import app.bottlenote.alcohols.domain.TastingTagRepository;
import app.bottlenote.alcohols.dto.request.AdminReferenceSearchRequest;
import app.bottlenote.alcohols.dto.request.CurationKeywordSearchRequest;
import app.bottlenote.alcohols.dto.response.AlcoholsSearchItem;
import app.bottlenote.alcohols.dto.response.CategoryItem;
import app.bottlenote.alcohols.dto.response.CurationKeywordResponse;
import app.bottlenote.alcohols.dto.response.RegionsItem;
import app.bottlenote.global.data.response.GlobalResponse;
import app.bottlenote.global.service.cursor.CursorResponse;
import java.util.List;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -48,19 +44,6 @@ public List<CategoryItem> getAlcoholCategory(AlcoholType type) {
return alcoholQueryRepository.findAllCategories(type);
}

@Transactional(readOnly = true)
public CursorResponse<CurationKeywordResponse> searchCurationKeywords(
CurationKeywordSearchRequest request) {
return curationKeywordRepository.searchCurationKeywords(
request.keyword(), request.alcoholId(), request.cursor(), request.pageSize().intValue());
}

@Transactional(readOnly = true)
public CursorResponse<AlcoholsSearchItem> getCurationAlcohols(
Long curationId, Long cursor, Long pageSize) {
return curationKeywordRepository.getCurationAlcohols(curationId, cursor, pageSize.intValue());
}

@Transactional(readOnly = true)
public Optional<Set<Long>> getCurationAlcoholIds(String keyword) {
return curationKeywordRepository.findAlcoholIdsByKeyword(keyword);
Expand Down
112 changes: 0 additions & 112 deletions bottlenote-product-api/src/docs/asciidoc/api/alcohols/curations.adoc

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
- 큐레이션 키워드로 검색 시, 해당 큐레이션에 포함된 위스키 목록이 반환됩니다
- 예: `봄 추천 위스키`, `여름 추천 위스키`, `비 오는 날 추천 위스키` 등
- 큐레이션 키워드는 동적으로 관리되므로, 새로운 큐레이션이 추가되거나 기존 큐레이션이 수정될 수 있습니다
- 사용 가능한 큐레이션 키워드 목록은 <<_큐레이션_키워드_조회,큐레이션 키워드 조회 API>>를 통해 확인할 수 있습니다
- 특정 큐레이션의 위스키만 조회하려면 <<_큐레이션_위스키_목록_조회,큐레이션 위스키 목록 조회 API>>를 사용하는 것을 권장합니다

[discrete]
==== 요청 파라미터 ====
Expand Down
Loading
Loading