Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 경험 선물 조회 Paging API 구현 #266

Merged
merged 2 commits into from
Feb 21, 2024
Merged
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 @@ -7,40 +7,29 @@
import com.shallwe.domain.experiencegift.dto.response.ExperienceRes;
import com.shallwe.domain.experiencegift.dto.response.ExperienceSttCategoryRes;
import com.shallwe.global.config.security.token.UserPrincipal;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

import java.util.List;

public interface ExperienceGiftService {

List<ExperienceRes> searchExperience(UserPrincipal userPrincipal, String title);

ExperienceDetailRes getExperienceDetails(final UserPrincipal userPrincipal, Long ExperienceGiftId);

List<ExperienceSttCategoryRes> highSttCategoryPricedGift(UserPrincipal userPrincipal, Long SttCategoryId);

List<ExperienceSttCategoryRes> lowSttCategoryPricedGift(UserPrincipal userPrincipal, Long sttCategoryId);

List<ExperienceExpCategoryRes> highExpCategoryPricedGift(UserPrincipal userPrincipal, Long expCategoryId);

List<ExperienceExpCategoryRes> lowExpCategoryPricedGift(UserPrincipal userPrincipal, Long expCategoryId);

List<ExperienceSttCategoryRes> getPopularSttGift(UserPrincipal userPrincipal, Long sttCategoryId);

List<ExperienceExpCategoryRes> getPopulaExpGift(UserPrincipal userPrincipal, Long expCategoryId);

ExperienceMainRes mainPage(UserPrincipal userPrincipal);

List<ExperienceRes> getAllPopularGift(UserPrincipal userPrincipal);

void registerExperienceGift(UserPrincipal userPrincipal, ShopOwnerExperienceReq shopOwnerExperienceReq);

ShopOwnerMainRes mainAdminExperienceGift(UserPrincipal userPrincipal);

List<ShopOwnerExperienceRes> getExperienceGift(UserPrincipal userPrincipal);

void modifyExperienceGift(Long experienceGiftId, UserPrincipal userPrincipal, ShopOwnerExperienceReq shopOwnerExperienceReq);

void deleteExperienceGift(Long experienceGiftId, UserPrincipal userPrincipal);

ShopOwnerExperienceDetailsRes getExperienceGiftDetails(UserPrincipal userPrincipal, Long experienceGiftId);
Slice<ExperienceGiftRes> getPagedExperienceGifts(Pageable pageable, String sttCategory, String searchCondition, String expCategory, String sortCondition);

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import com.shallwe.global.config.security.token.UserPrincipal;
import com.shallwe.global.utils.AwsS3ImageUrlUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -329,4 +331,10 @@ public List<ExperienceExpCategoryRes> getPopulaExpGift(UserPrincipal userPrincip
}).collect(Collectors.toList());
}

@Override
public Slice<ExperienceGiftRes> getPagedExperienceGifts(final Pageable pageable, final String sttCategory,
final String searchCondition, final String expCategory, final String sortCondition) {
return experienceGiftRepository.findPagedExperienceGifts(pageable, sttCategory, searchCondition, expCategory, sortCondition);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,41 @@
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "experience_gift")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
public class ExperienceGift extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "title")
private String title;

@Column(name = "price")
private Long price;

@Column(name = "description")
private String description;

@Column(name = "gift_img_url")
private String giftImgUrl;

@Column(name = "location")
private String location;

@Column(name = "note")
private String note;

@Column(name = "reservation_count")
private Long reservationCount; // 인기순 정렬을 위한 WAITING이 아닌 Reservation 개수 카운트

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "subtitle_id")
private Subtitle subtitle;

private Long price;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "experience_category_id")
private ExperienceCategory experienceCategory;
Expand All @@ -35,18 +53,10 @@ public class ExperienceGift extends BaseEntity {
@JoinColumn(name = "situation_category_id")
private SituationCategory situationCategory;

private String description;

private String giftImgKey;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "shopOwner_id")
private ShopOwner shopOwner;

private String location;

private String note;

@OneToMany(mappedBy = "experienceGift")
private List<ExperienceGiftImage> imgList = new ArrayList<>();

Expand Down Expand Up @@ -74,15 +84,23 @@ public void update(ShopOwnerExperienceReq shopOwnerExperienceReq, Subtitle subti
this.note=shopOwnerExperienceReq.getNote();
}

public void addReservationCount() {
this.reservationCount++;
}

public void subtractReservationCount() {
this.reservationCount--;
}

@Builder
public ExperienceGift(String title, Subtitle subtitle, Long price, ExperienceCategory experienceCategory, SituationCategory situationCategory, String description, String giftImgKey, ShopOwner shopOwner, String location, String note, List<ExperienceGiftImage> imgList) {
public ExperienceGift(String title, Subtitle subtitle, Long price, ExperienceCategory experienceCategory, SituationCategory situationCategory, String description, String giftImgUrl, ShopOwner shopOwner, String location, String note, List<ExperienceGiftImage> imgList) {
this.title = title;
this.subtitle = subtitle;
this.price = price;
this.experienceCategory = experienceCategory;
this.situationCategory = situationCategory;
this.description = description;
this.giftImgKey = giftImgKey;
this.giftImgUrl = giftImgUrl;
this.shopOwner = shopOwner;
this.location = location;
this.note = note;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.shallwe.domain.experiencegift.domain;

import com.shallwe.domain.common.BaseEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "experience_gift_experience_category")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class ExperienceGiftExperienceCategory extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(nullable = false, name = "experience_gift_id")
private ExperienceGift experienceGift;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(nullable = false, name = "experience_category_id")
private ExperienceCategory experienceCategory;

@Builder
public ExperienceGiftExperienceCategory(ExperienceGift experienceGift, ExperienceCategory experienceCategory) {
this.experienceGift = experienceGift;
this.experienceCategory = experienceCategory;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.shallwe.domain.experiencegift.domain;

import com.shallwe.domain.common.BaseEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "experience_gift_situation_category")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class ExperienceGiftSituationCategory extends BaseEntity {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(nullable = false, name = "experience_gift_id")
private ExperienceGift experienceGift;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(nullable = false, name = "situation_category_id")
private SituationCategory situationCategory;

@Builder
public ExperienceGiftSituationCategory(ExperienceGift experienceGift, SituationCategory situationCategory) {
this.experienceGift = experienceGift;
this.situationCategory = situationCategory;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.shallwe.domain.experiencegift.domain.repository;

import com.shallwe.domain.experiencegift.domain.ExperienceGift;
import com.shallwe.domain.experiencegift.dto.response.ExperienceGiftRes;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

import java.util.List;

Expand All @@ -13,5 +16,5 @@ public interface ExperienceGiftQuerydslRepository {
List<ExperienceGift> findPopularGiftsBySttCategoryId(Long sttCategoryId);
List<ExperienceGift> findPopularGiftsByExpCategoryId(Long ExpCategoryId);
List<ExperienceGift> findAllPopularGifts();

Slice<ExperienceGiftRes> findPagedExperienceGifts(Pageable pageable, String sttCategory, String searchCondition, String expCategory, String sortCondition);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
package com.shallwe.domain.experiencegift.domain.repository;

import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.shallwe.domain.common.Status;
import com.shallwe.domain.experiencegift.domain.ExperienceGift;
import com.shallwe.domain.experiencegift.domain.QExperienceCategory;
import com.shallwe.domain.experiencegift.domain.QExperienceGiftExperienceCategory;
import com.shallwe.domain.experiencegift.domain.QSituationCategory;
import com.shallwe.domain.experiencegift.dto.response.ExperienceGiftRes;
import com.shallwe.domain.experiencegift.dto.response.QExperienceGiftRes;
import com.shallwe.domain.reservation.domain.QReservation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.stereotype.Repository;

import java.util.List;

import static com.shallwe.domain.experiencegift.domain.QExperienceCategory.*;
import static com.shallwe.domain.experiencegift.domain.QExperienceGift.experienceGift;
import static com.shallwe.domain.experiencegift.domain.QExperienceGiftExperienceCategory.*;
import static com.shallwe.domain.experiencegift.domain.QExperienceGiftSituationCategory.*;
import static com.shallwe.domain.experiencegift.domain.QSituationCategory.*;
import static com.shallwe.global.config.Constant.ExperienceGiftConstant.*;


@RequiredArgsConstructor
Expand Down Expand Up @@ -92,4 +107,70 @@ public List<ExperienceGift> findAllPopularGifts() {
.fetch();
}

@Override
public Slice<ExperienceGiftRes> findPagedExperienceGifts(final Pageable pageable, final String sttCategory, final String searchCondition, final String expCategory, final String sortCondition) {
List<ExperienceGiftRes> results = queryFactory
.select(new QExperienceGiftRes(
experienceGift.id,
experienceGift.giftImgUrl,
experienceGift.subtitle.title,
experienceGift.title,
experienceGift.price
))
.distinct()
.from(experienceGift)
.leftJoin(experienceGift.subtitle)
.leftJoin(experienceGiftExperienceCategory).on(experienceGiftExperienceCategory.experienceGift.id.eq(experienceGift.id))
.leftJoin(experienceGiftSituationCategory).on(experienceGiftSituationCategory.experienceGift.id.eq(experienceGift.id))
.where(
experienceGift.status.eq(Status.ACTIVE),
sttCategoryEq(sttCategory),
expCategoryEq(expCategory),
searchConditionEq(searchCondition)
)
.orderBy(orderBy(sortCondition)) // WAITING이 아닌 예약의 개수를 기준으로 정렬
.offset(pageable.getOffset())
.limit(pageable.getPageSize() + 1) // +1 해서 다음 페이지가 있는지 체크
.fetch();

boolean hasNext = results.size() > pageable.getPageSize();
List<ExperienceGiftRes> content = hasNext ? results.subList(0, pageable.getPageSize()) : results;

return new SliceImpl<>(content, pageable, hasNext);
}

private BooleanExpression searchConditionEq(String searchCondition) {
if (searchCondition == null) {
return null;
}
return experienceGift.title.contains(searchCondition).or(experienceGift.subtitle.title.contains(searchCondition));
}

private BooleanExpression sttCategoryEq(String sttCategory) {
if (sttCategory == null) {
return null;
}
return experienceGiftSituationCategory.situationCategory.sttCategory.eq(sttCategory);
}

private BooleanExpression expCategoryEq(String expCategory) {
if (expCategory == null) {
return null;
}
return experienceGiftExperienceCategory.experienceCategory.expCategory.eq(expCategory);
}

private OrderSpecifier<?> orderBy(String condition) {
if (condition.equals(POPULAR_EXPERIENCE_GIFT)) { // 인기순
return experienceGift.reservationCount.desc().nullsLast();
}
if (condition.equals(HIGH_PRICED_ORDER)) { // 가격 높은 순
return experienceGift.price.desc();
}
if (condition.equals(LOW_PRICED_ORDER)) { // 가격 낮은 순
return experienceGift.price.asc();
}
return experienceGift.reservationCount.desc().nullsLast(); // Default 인기순
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.shallwe.domain.experiencegift.dto.response;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Data;

@Data
public class ExperienceGiftRes {

private Long experienceGiftId;
private String giftImgUrl;
private String subtitle;
private String title;
private Long price;

@QueryProjection
public ExperienceGiftRes(Long experienceGiftId, String giftImgUrl, String subtitle, String title, Long price) {
this.experienceGiftId = experienceGiftId;
this.giftImgUrl = giftImgUrl;
this.subtitle = subtitle;
this.title = title;
this.price = price;
}

}
Loading
Loading