Skip to content
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 @@ -3,13 +3,15 @@
import static org.websoso.WSSServer.exception.error.CustomAvatarError.AVATAR_NOT_FOUND;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.websoso.WSSServer.dto.popularFeed.PopularFeedGetResponse;
import org.websoso.WSSServer.user.domain.AvatarProfile;
import org.websoso.WSSServer.domain.Genre;
import org.websoso.WSSServer.domain.GenrePreference;
Expand All @@ -19,7 +21,6 @@
import org.websoso.WSSServer.dto.feed.FeedsGetResponse;
import org.websoso.WSSServer.dto.feed.InterestFeedGetResponse;
import org.websoso.WSSServer.dto.feed.InterestFeedsGetResponse;
import org.websoso.WSSServer.dto.popularFeed.PopularFeedGetResponse;
import org.websoso.WSSServer.dto.popularFeed.PopularFeedsGetResponse;
import org.websoso.WSSServer.dto.user.UserBasicInfo;
import org.websoso.WSSServer.exception.exception.CustomAvatarException;
Expand All @@ -43,7 +44,6 @@ public class FeedFindApplication {
private final FeedServiceImpl feedServiceImpl;
private final NovelServiceImpl novelServiceImpl;

private static final String DEFAULT_CATEGORY = "all";
private static final int DEFAULT_PAGE_NUMBER = 0;

//ToDo : 의존성 제거 필요 부분
Expand Down Expand Up @@ -109,10 +109,6 @@ private List<Genre> getPreferenceGenres(User user) {
return genrePreferenceRepository.findByUser(user).stream().map(GenrePreference::getGenre).toList();
}

private static String getChosenCategoryOrDefault(String category) {
return Optional.ofNullable(category).orElse(DEFAULT_CATEGORY);
}

private Slice<Feed> findFeedsByCategoryLabel(Long lastFeedId, Long userId, PageRequest pageRequest,
FeedGetOption feedGetOption, List<Genre> genres) {
return feedServiceImpl.findFeedsByCategoryLabel(lastFeedId, userId, pageRequest, feedGetOption,
Expand All @@ -134,49 +130,43 @@ private FeedInfo createFeedInfo(Feed feed, User user) {
@Transactional(readOnly = true)
public PopularFeedsGetResponse getPopularFeeds(User user, int size) {
List<PopularFeed> popularFeeds = Optional.ofNullable(user)
.map(u -> findPopularFeedsWithUser(u.getUserId(), size))
.orElseGet(() -> findPopularFeedsWithoutUser(size));
.map(u -> feedServiceImpl.findPopularFeedsWithUser(u.getUserId(), size))
.orElseGet(() -> feedServiceImpl.findPopularFeedsWithoutUser(size));

// TODO: PopularFeeds에 이런 메서드들이 더 많으면 일급 함수 객체 만들어도 괜찮을듯
List<Long> novelIds = popularFeeds.stream()
.map(f -> f.getFeed().getNovelId())
.filter(Objects::nonNull)
.distinct()
.toList();

Map<Long, Novel> novelMap = novelServiceImpl.getNovelsWithGenresByIds(novelIds).stream()
.collect(Collectors.toMap(Novel::getNovelId, novel -> novel));
Map<Long, Novel> novelMap = novelServiceImpl.getNovelsWithGenresByIds(novelIds)
.stream()
.collect(Collectors.toMap(
Novel::getNovelId,
Function.identity()
));

List<PopularFeedGetResponse> popularFeedGetResponses = mapToPopularFeedGetResponseList(popularFeeds, novelMap);

return PopularFeedsGetResponse.of(popularFeedGetResponses);
}

private List<PopularFeed> findPopularFeedsWithUser(Long userId, int size) {
return feedServiceImpl.findPopularFeedsWithUser(userId, size);
}

private List<PopularFeed> findPopularFeedsWithoutUser(int size) {
return feedServiceImpl.findPopularFeedsWithoutUser(size);
}

private static List<PopularFeedGetResponse> mapToPopularFeedGetResponseList(List<PopularFeed> popularFeeds,
Map<Long, Novel> novelMap) {
private static List<PopularFeedGetResponse> mapToPopularFeedGetResponseList(
List<PopularFeed> popularFeeds,
Map<Long, Novel> novelMap
) {
return popularFeeds.stream()
.map(popularFeed -> {
Novel novel = novelMap.get(popularFeed.getFeed().getNovelId());
String novelImage = Optional.ofNullable(novel).map(Novel::getNovelImage).orElse(null);
String novelGenreImage = Optional.ofNullable(novel)
.flatMap(FeedFindApplication::getFirstNovelGenreImage)
.orElse(null);

return PopularFeedGetResponse.of(popularFeed, novelImage, novelGenreImage);
}).toList();
}

private static Optional<String> getFirstNovelGenreImage(Novel novel) {
return novel.getNovelGenres().stream()
.findFirst()
.map(novelGenre -> novelGenre.getGenre().getGenreImage());
return PopularFeedGetResponse.of(
popularFeed,
novel == null ? null : novel.getNovelImage(),
novel == null ? null : novel.getFirstGenreName()
);
})
.toList();
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ public record PopularFeedGetResponse(
Boolean isSpoiler,
Boolean isPublic,
String novelImage,
String novelGenreImage
String novelGenre
) {

public static PopularFeedGetResponse of(PopularFeed popularFeed, String novelImage, String novelGenreImage) {
public static PopularFeedGetResponse of(PopularFeed popularFeed, String novelImage, String novelGenre) {
return new PopularFeedGetResponse(
popularFeed.getFeed().getFeedId(),
popularFeed.getFeed().getFeedContent(),
Expand All @@ -22,7 +22,7 @@ public static PopularFeedGetResponse of(PopularFeed popularFeed, String novelIma
popularFeed.getFeed().getIsSpoiler(),
popularFeed.getFeed().getIsPublic(),
novelImage,
novelGenreImage
novelGenre
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@

public interface PopularFeedCustomRepository {

List<PopularFeed> findTodayPopularFeeds(Long userId, int size);
/**
* 로그인 사용자가 조회 가능한 인기 피드를 조회한다.
* 차단한 사용자 및 차단당한 사용자의 피드는 제외한다.
*/
List<PopularFeed> findPopularFeedsForMember(Long userId, int size);

List<PopularFeed> findOrderByPopularFeedIdDesc(int size);
/**
* 비회원이 조회 가능한 인기 피드를 조회한다.
*/
List<PopularFeed> findPopularFeedsForGuest(int size);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import static org.websoso.WSSServer.user.domain.QUser.user;


import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;

import java.util.List;
import java.util.stream.Stream;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
Expand All @@ -22,44 +23,56 @@ public class PopularFeedCustomRepositoryImpl implements PopularFeedCustomReposit
private final JPAQueryFactory jpaQueryFactory;

@Override
public List<PopularFeed> findTodayPopularFeeds(Long userId, int size) {
List<Long> blockingIds = jpaQueryFactory
.select(block.blockedId)
.from(block)
.where(block.blockingId.eq(userId))
.fetch();

List<Long> blockedIds = jpaQueryFactory
.select(block.blockingId)
.from(block)
.where(block.blockedId.eq(userId))
.fetch();

List<Long> blockIds = Stream.concat(blockingIds.stream(), blockedIds.stream())
.distinct()
.toList();
public List<PopularFeed> findPopularFeedsForMember(Long userId, int size) {
List<Long> blockIds = getBlockIds(userId);

return jpaQueryFactory
.selectFrom(popularFeed)
.join(popularFeed.feed, feed)
.join(feed.user, user)
.where(user.userId.notIn(blockIds),
popularFeed.feed.isPublic.isTrue(),
popularFeed.feed.isHidden.isFalse())
.where(
feed.isPublic.isTrue(),
feed.isHidden.isFalse(),
user.userId.notIn(blockIds)
)
.orderBy(popularFeed.popularFeedId.desc())
.limit(size)
.fetch();
}

@Override
public List<PopularFeed> findOrderByPopularFeedIdDesc(int size) {
public List<PopularFeed> findPopularFeedsForGuest(int size) {
return jpaQueryFactory
.selectFrom(popularFeed)
.join(popularFeed.feed, feed)
.where(feed.isPublic.isTrue(),
feed.isHidden.isFalse())
.where(
feed.isPublic.isTrue(),
feed.isHidden.isFalse()
)
.orderBy(popularFeed.popularFeedId.desc())
.limit(size)
.fetch();
}

/**
* 본인이 차단했거나, 본인을 차단한 사용자의 ID를 조회한다.
*
* @param userId 사용자 ID
* @return 차단 사용자 ID
*/
private List<Long> getBlockIds(Long userId) {
NumberExpression<Long> blockUserId = new CaseBuilder()
.when(block.blockingId.eq(userId)).then(block.blockedId)
.otherwise(block.blockingId);

return jpaQueryFactory
.select(blockUserId)
.from(block)
.where(
block.blockingId.eq(userId)
.or(block.blockedId.eq(userId))
)
.distinct()
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ public Optional<FeedImage> findThumbnailFeedImageByFeedId(Long feedId) {

@Transactional(readOnly = true)
public List<PopularFeed> findPopularFeedsWithUser(Long userId, int size) {
return popularFeedRepository.findTodayPopularFeeds(userId, size);
return popularFeedRepository.findPopularFeedsForMember(userId, size);
}

@Transactional(readOnly = true)
public List<PopularFeed> findPopularFeedsWithoutUser(int size) {
return popularFeedRepository.findOrderByPopularFeedIdDesc(size);
return popularFeedRepository.findPopularFeedsForGuest(size);
}

@Transactional(readOnly = true)
Expand Down
Loading