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 @@ -39,7 +39,7 @@ public ApiResponse<PhotoAlbumResponseDTO.PhotoAlbumResultWithPresignedUrlDTO> ge
@PostMapping("")
@Operation(summary = "사진첩 등록 API", description = "사진첩을 등록하는 API 입니다.")
public ApiResponse<PhotoAlbumResponseDTO.PhotoAlbumResultWithPresignedUrlDTO> uploadPhotoAlbum(
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "imageRequestDTOs에는 presigned urls 호출로 받은 keyName, publicUrls 값만 전달")
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "imageRequestDTOs에는 presigned urls 호출로 받은 keyName 값만 전달")
@RequestBody PhotoAlbumRequestDTO.CreatePhotoAlbumDTO requestDTO,
@AuthenticationPrincipal(expression = "member") Member member){
return ApiResponse.onSuccess(photoAlbumService.createPhotoAlbum(requestDTO, member.getId()));
Expand All @@ -50,9 +50,9 @@ public ApiResponse<PhotoAlbumResponseDTO.PhotoAlbumResultWithPresignedUrlDTO> up
public ApiResponse<PhotoAlbumResponseDTO.PerformerPhotoAlbumDTO> getPhotoAlbumList(
@AuthenticationPrincipal(expression = "member") Member member,
@PathVariable("memberId") Long performerId,
@RequestParam(required = false) Long cursorId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return ApiResponse.onSuccess(photoAlbumService.getPhotoAlbumList(member.getId(), performerId, cursorId, size));
return ApiResponse.onSuccess(photoAlbumService.getPhotoAlbumList(member.getId(), performerId, page, size));
}

@PreAuthorize("hasRole('PERFORMER')")
Expand All @@ -76,9 +76,9 @@ public ApiResponse<String> deletePhotoAlbum(
@GetMapping("")
@Operation(summary = "메뉴에서 전체 사진첩 조회 API", description = "최근 올라온 사진첩을 전체 조회하는 API 입니다.")
public ApiResponse<PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO> getAllPhotoAlbum(
@RequestParam(required = false) Long cursorId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return ApiResponse.onSuccess(photoAlbumService.getAllPhotoAlbumList(cursorId, size));
return ApiResponse.onSuccess(photoAlbumService.getAllRecentPhotoAlbumList(page, size));
}

@GetMapping("/member/{memberId}/shows")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static class PerformerPhotoAlbumDTO {
private String performerName;
private Integer number;
private boolean hasNext;
private Long nextCursor;
private Integer nextPage;
}

@Builder
Expand All @@ -78,10 +78,10 @@ public static class MemberPhotoAlbumDTO {
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class ScrollMemberPhotoAlbumDTO { //커서 기반 페이징이지만 ui 관점에서 스크롤이라는 의미
public static class ScrollMemberPhotoAlbumDTO { //페이지 번호 기반
private List<MemberPhotoAlbumDTO> photoAlbumDTOs;
private boolean hasNext;
private Long nextCursor;
private Integer nextPage;
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cc.backend.photoAlbum.repository;

import cc.backend.photoAlbum.entity.PhotoAlbum;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -22,10 +23,11 @@ OR CAST(p.amateurShow.id AS string) LIKE %:keyword%

@Query("SELECT pa FROM PhotoAlbum pa " +
"JOIN pa.amateurShow a " +
"WHERE a.member.id = :performerId " +
"AND (:cursorId IS NULL OR pa.id < :cursorId) " +
"ORDER BY pa.updatedAt DESC")
List<PhotoAlbum> findByPerformerWithCursor(@Param("performerId") Long performerId, @Param("cursorId") Long cursorId, Pageable pageable
"WHERE a.member.id = :performerId "
)
Page<PhotoAlbum> findByPerformer(
@Param("performerId") Long performerId,
Pageable pageable
);

@Query("SELECT p FROM PhotoAlbum p WHERE (:cursorId IS NULL OR p.id < :cursorId) ORDER BY p.updatedAt DESC")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public interface PhotoAlbumService {

public PhotoAlbumResponseDTO.PhotoAlbumResultWithPresignedUrlDTO createPhotoAlbum(PhotoAlbumRequestDTO.CreatePhotoAlbumDTO requestDTO, Long memberId);
public PhotoAlbumResponseDTO.PhotoAlbumResultWithPresignedUrlDTO getPhotoAlbum(Long photoAlbumId, Long memberId);
public PhotoAlbumResponseDTO.PerformerPhotoAlbumDTO getPhotoAlbumList(Long memberId, Long performerId, Long cursorId, int size);
public PhotoAlbumResponseDTO.PerformerPhotoAlbumDTO getPhotoAlbumList(Long memberId, Long performerId, int page, int size);
public PhotoAlbumResponseDTO.PhotoAlbumResultDTO updatePhotoAlbum(Long photoAlbumId, PhotoAlbumRequestDTO.CreatePhotoAlbumDTO requestDTO, Long memberId);
public String deletePhotoAlbum(Long photoAlbumId, Long memberId);
public PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO getAllPhotoAlbumList(Long cursorId, int size);
public PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO getAllRecentPhotoAlbumList(int page, int size);
public PerformerShowListResponseDTO getPerformerShows(Long memberId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
import cc.backend.photoAlbum.entity.PhotoAlbum;
import cc.backend.photoAlbum.repository.PhotoAlbumRepository;
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.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -117,39 +115,35 @@ public PhotoAlbumResponseDTO.PhotoAlbumResultWithPresignedUrlDTO getPhotoAlbum(L
}

@Override
public PhotoAlbumResponseDTO.PerformerPhotoAlbumDTO getPhotoAlbumList(Long memberId, Long performerId, Long cursorId, int pageSize){
public PhotoAlbumResponseDTO.PerformerPhotoAlbumDTO getPhotoAlbumList(Long memberId, Long performerId, int page, int pageSize){
//로그인 검사
memberRepository.findById(memberId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_AUTHORIZED));
Member performer = memberRepository.findById(performerId)
.orElseThrow(()-> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

Pageable pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "createdAt"));
// 사진첩 단위 조회 (커서 기반)
List<PhotoAlbum> photoAlbums = photoAlbumRepository.findByPerformerWithCursor
(performerId, cursorId, PageRequest.of(0, pageSize + 1)
);

Page<PhotoAlbum> albumPage = photoAlbumRepository.findByPerformer(
performerId,
pageable
);
//다음 커서 설정
boolean hasNext = photoAlbums.size() > pageSize;
Long nextCursor = hasNext ? photoAlbums.get(pageSize - 1).getId() : null;

// 실제 응답할 데이터만 자르기(pageSize 보다 1개 더 가져옴)
List<PhotoAlbum> limitedAlbums = photoAlbums.stream()
.limit(pageSize)
.toList();
List<PhotoAlbum> albums = albumPage.getContent();

// 대표 이미지 가져오기
List<Long> albumIds = limitedAlbums.stream()
List<Long> albumIds = albums.stream()
.map(PhotoAlbum::getId)
.toList();

// 쿼리 한번에 다 가져오기
Map<Long, Image> albumImageMap = imageRepository.findFirstByContentIds(albumIds, FilePath.photoAlbum)
.stream()
.collect(Collectors.toMap(Image::getContentId, Function.identity()));


// DTO 변환
List<PhotoAlbumResponseDTO.SinglePhotoAlbumDTO> singlePhotoAlbumDTOs = limitedAlbums.stream()
List<PhotoAlbumResponseDTO.SinglePhotoAlbumDTO> singlePhotoAlbumDTOs = albums.stream()
.map(album -> {
Image coverImage = albumImageMap.get(album.getId());
return PhotoAlbumResponseDTO.SinglePhotoAlbumDTO.builder()
Expand All @@ -166,12 +160,15 @@ public PhotoAlbumResponseDTO.PerformerPhotoAlbumDTO getPhotoAlbumList(Long membe
})
.toList();

boolean hasNext = albumPage.hasNext();
Integer nextPage = hasNext ? page + 1 : null;

return PhotoAlbumResponseDTO.PerformerPhotoAlbumDTO.builder()
.singlePhotoAlbumDTOs(singlePhotoAlbumDTOs)
.performerName(performer.getName())
.number(singlePhotoAlbumDTOs.size())
.hasNext(hasNext)
.nextCursor(nextCursor)
.nextPage(nextPage)
.build();
}

Expand Down Expand Up @@ -284,18 +281,15 @@ public String deletePhotoAlbum(Long photoAlbumId, Long memberId) {
}

@Override
public PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO getAllPhotoAlbumList(Long cursorId, int size){
public PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO getAllRecentPhotoAlbumList(int page, int size){

Pageable pageable = PageRequest.of(0, size + 1);
List<PhotoAlbum> albums = photoAlbumRepository.findNextAlbums(cursorId, pageable);

// 실제 응답할 데이터만 자르기(size 보다 1개 더 가져옴)
List<PhotoAlbum> limitedAlbums = albums.stream()
.limit(size)
.toList();
// 최근 생성한 순서대로 photoAlbum 가져오기
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<PhotoAlbum> albumPage = photoAlbumRepository.findAll(pageable); // 또는 커스텀 쿼리 사용 가능
List<PhotoAlbum> albums = albumPage.getContent(); //Page 벗기기

// 대표 이미지 조회 (N+1 방지)
List<Long> albumIds = limitedAlbums.stream()
// 3. N+1 방지: 대표 이미지 조회
List<Long> albumIds = albums.stream()
.map(PhotoAlbum::getId)
.toList();

Expand All @@ -304,7 +298,7 @@ public PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO getAllPhotoAlbumList(Long
.collect(Collectors.toMap(Image::getContentId, Function.identity()));

//DTO 변환
List<PhotoAlbumResponseDTO.MemberPhotoAlbumDTO> dtoList = limitedAlbums.stream()
List<PhotoAlbumResponseDTO.MemberPhotoAlbumDTO> dtoList = albums.stream()
.map(album -> {
Image coverImage = albumImageMap.get(album.getId());
return PhotoAlbumResponseDTO.MemberPhotoAlbumDTO.builder()
Expand All @@ -318,12 +312,12 @@ public PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO getAllPhotoAlbumList(Long
.toList();

// 다음 커서 설정
boolean hasNext = albums.size() > size;
Long nextCursor = hasNext ? limitedAlbums.get(limitedAlbums.size() - 1).getId() : null;
boolean hasNext = albumPage.hasNext();
Integer nextPage = hasNext ? page + 1 : null;

return PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO.builder()
.photoAlbumDTOs(dtoList)
.nextCursor(nextCursor)
.nextPage(nextPage) // 커서 대신 다음 페이지 번호
.hasNext(hasNext)
.build();
}
Expand Down