Skip to content

Commit

Permalink
v1.8.7 (#367)
Browse files Browse the repository at this point in the history
  • Loading branch information
char-yb authored Mar 16, 2024
2 parents 8a0c92a + cd2e2d0 commit 49aabd3
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 20 deletions.
16 changes: 13 additions & 3 deletions src/main/java/com/depromeet/domain/feed/api/FeedController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.depromeet.domain.feed.application.FeedService;
import com.depromeet.domain.feed.dto.response.FeedOneByProfileResponse;
import com.depromeet.domain.feed.dto.response.FeedOneResponse;
import com.depromeet.domain.feed.dto.response.FeedSliceResponse;
import com.depromeet.domain.mission.domain.MissionVisibility;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -29,10 +30,19 @@ public List<FeedOneResponse> feedFindAll(
return feedService.findAllFeedByVisibility(visibility);
}

@Operation(summary = "피드 탭", description = "피드 탭을 조회합니다.")
@Operation(summary = "피드 탭 (페이지네이션)", description = "피드 탭을 조회합니다.")
@GetMapping("/me")
public List<FeedOneResponse> feedFindAll() {
return feedService.findAllFeed();
public FeedSliceResponse feedFindByPage(
@RequestParam int size,
@RequestParam(required = false) Long lastId,
@RequestParam(value = "visibility", required = false) MissionVisibility visibility) {
if (visibility == MissionVisibility.ALL) {
// 전체 피드 탭
return feedService.findAllFeed(size, lastId);
} else {
// 팔로워 피드 탭
return feedService.findFollowerFeed(size, lastId);
}
}

@Operation(summary = "프로필 피드", description = "피드 탭을 조회합니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.depromeet.domain.feed.dto.response.FeedOneByProfileResponse;
import com.depromeet.domain.feed.dto.response.FeedOneResponse;
import com.depromeet.domain.feed.dto.response.FeedSliceResponse;
import com.depromeet.domain.follow.dao.MemberRelationRepository;
import com.depromeet.domain.follow.domain.MemberRelation;
import com.depromeet.domain.member.dao.MemberRepository;
Expand All @@ -15,6 +16,7 @@
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -43,6 +45,28 @@ public List<FeedOneResponse> findAllFeedByVisibility(MissionVisibility visibilit
return missionRecordRepository.findFeedAll(sourceMembers);
}

// 전체 피드 탭
@Transactional(readOnly = true)
public FeedSliceResponse findAllFeed(int size, Long lastId) {
final List<Member> members = memberRepository.findAll();
Slice<FeedOneResponse> feedByVisibilityAndPage =
missionRecordRepository.findFeedByVisibilityAndPage(
size, lastId, members, List.of(MissionVisibility.ALL));
return FeedSliceResponse.from(feedByVisibilityAndPage);
}

// 팔로워 피드 탭
@Transactional(readOnly = true)
public FeedSliceResponse findFollowerFeed(int size, Long lastId) {
final Member currentMember = memberUtil.getCurrentMember();
List<Member> sourceMembers = getSourceMembers(currentMember.getId());

sourceMembers.add(currentMember);
Slice<FeedOneResponse> feedAllByPage =
missionRecordRepository.findFeedAllByPage(size, lastId, sourceMembers);
return FeedSliceResponse.from(feedAllByPage);
}

@Transactional(readOnly = true)
public List<FeedOneResponse> findAllFeed() {
final Member currentMember = memberUtil.getCurrentMember();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.depromeet.domain.feed.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import org.springframework.data.domain.Slice;

public record FeedSliceResponse(
@Schema(description = "피드 데이터") List<FeedOneResponse> content,
@Schema(description = "마지막 페이지 여부") Boolean last) {
public static FeedSliceResponse from(Slice<FeedOneResponse> feedResponses) {
return new FeedSliceResponse(feedResponses.getContent(), feedResponses.isLast());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
import java.time.LocalDateTime;
import java.util.List;
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;

@Repository
Expand Down Expand Up @@ -130,18 +127,4 @@ private BooleanExpression ltMissionId(Long lastId) {
private BooleanExpression durationStatusFinishedEq() {
return mission.durationStatus.eq(DurationStatus.FINISHED);
}

// 무한 스크롤 방식 처리하는 메서드
private Slice<Mission> checkLastPage(int size, List<Mission> result) {

boolean hasNext = false;

// 조회한 결과 개수가 요청한 페이지 사이즈보다 크면 뒤에 더 있음, next = true
if (result.size() > size) {
hasNext = true;
result.remove(size);
}
Pageable pageable = Pageable.unpaged();
return new SliceImpl<>(result, pageable, hasNext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.depromeet.domain.missionRecord.domain.MissionRecord;
import java.time.YearMonth;
import java.util.List;
import org.springframework.data.domain.Slice;

public interface MissionRecordRepositoryCustom {

Expand All @@ -23,4 +24,9 @@ List<FeedOneResponse> findFeedByVisibility(
boolean isCompletedMissionExistsToday(Long missionId);

void deleteByMissionRecordId(Long missionRecordId);

Slice<FeedOneResponse> findFeedAllByPage(int size, Long lastId, List<Member> members);

Slice<FeedOneResponse> findFeedByVisibilityAndPage(
int size, Long lastId, List<Member> members, List<MissionVisibility> visibility);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
import java.time.YearMonth;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.stereotype.Repository;

@Repository
Expand Down Expand Up @@ -101,6 +105,48 @@ public List<FeedOneResponse> findFeedByVisibility(
.fetch();
}

@Override
public Slice<FeedOneResponse> findFeedAllByPage(int size, Long lastId, List<Member> members) {
return findFeedByVisibilityAndPage(
size, lastId, members, List.of(MissionVisibility.FOLLOWER, MissionVisibility.ALL));
}

@Override
public Slice<FeedOneResponse> findFeedByVisibilityAndPage(
int size, Long lastId, List<Member> members, List<MissionVisibility> visibilities) {
List<FeedOneResponse> feedList =
jpaQueryFactory
.select(
Projections.constructor(
FeedOneResponse.class,
member.id,
member.profile.nickname,
member.profile.profileImageUrl,
mission.id,
mission.name,
missionRecord.id,
missionRecord.remark,
missionRecord.imageUrl,
missionRecord.duration,
mission.startedAt,
mission.finishedAt,
missionRecord.startedAt))
.from(missionRecord)
.leftJoin(missionRecord.mission, mission)
.on(mission.id.eq(missionRecord.mission.id))
.leftJoin(mission.member, member)
.on(mission.member.id.eq(missionRecord.mission.member.id))
.where(
ltMissionRecordId(lastId),
missionRecord.mission.member.in(members),
missionRecord.mission.visibility.in(visibilities),
uploadStatusCompleteEq())
.orderBy(missionRecord.finishedAt.desc())
.limit((long) size + 1)
.fetch();
return checkLastPage(size, feedList);
}

@Override
public List<MissionRecord> findFeedAllByMemberId(
Long memberId, List<MissionVisibility> visibilities) {
Expand Down Expand Up @@ -140,4 +186,26 @@ private BooleanExpression dayEq(int day) {
private BooleanExpression uploadStatusCompleteEq() {
return missionRecord.uploadStatus.eq(ImageUploadStatus.COMPLETE);
}

// no-offset 방식 처리하는 메서드
private BooleanExpression ltMissionRecordId(Long lastId) {
if (lastId == null) {
return null;
}
return missionRecord.id.lt(lastId);
}

// 무한 스크롤 방식 처리하는 메서드
private Slice<FeedOneResponse> checkLastPage(int size, List<FeedOneResponse> result) {

boolean hasNext = false;

// 조회한 결과 개수가 요청한 페이지 사이즈보다 크면 뒤에 더 있음, next = true
if (result.size() > size) {
hasNext = true;
result.remove(size);
}
Pageable pageable = PageRequest.ofSize(size);
return new SliceImpl<>(result, pageable, hasNext);
}
}

0 comments on commit 49aabd3

Please sign in to comment.