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
2 changes: 1 addition & 1 deletion src/main/java/cc/backend/image/entity/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class Image {
// S3 객체 키 (예: "board/1.png") - 삭제나 조회 시 필요(객체 url에서 버킷 url 뺀 나머지 = filepath + 파일이름)
private String keyName;

// 외부에 공개할 수 있는 URL (예: https://bucket.s3.region.amazonaws.com/board/1.png)
// 정적인 컨텐츠 전용 URL (poster, notice, actor 이미지 전용)
private String imageUrl;

// 버킷 내 디렉토리 경로 (board, photoAlbum)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/cc/backend/image/service/ImageService.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public ImageResponseDTO.ImageResultWithPresignedUrlDTO getPosterImage(String key


public List<ImageResponseDTO.ImageResultWithPresignedUrlDTO> getImages(List<Image> images, Long memberId) {

//로그인 검사
memberRepository.findById(memberId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_AUTHORIZED));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,18 @@ public ApiResponse<PhotoAlbumResponseDTO.PhotoAlbumResultDTO> updatePhotoAlbum(
@Operation(summary = "사진첩 삭제 API", description = "공연별 사진첩을 삭제하는 API 입니다.")
public ApiResponse<String> deletePhotoAlbum(
@PathVariable("photoAlbumId") Long photoAlbumId,
@AuthenticationPrincipal(expression = "member") Member member) {
@AuthenticationPrincipal(expression = "member") Member member
) {
return ApiResponse.onSuccess(photoAlbumService.deletePhotoAlbum(photoAlbumId, member.getId()));
}

@GetMapping("")
@Operation(summary = "메뉴에서 전체 사진첩 조회 API", description = "최근 올라온 사진첩을 전체 조회하는 API 입니다.")
public ApiResponse<PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO> getAllPhotoAlbum(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return ApiResponse.onSuccess(photoAlbumService.getAllRecentPhotoAlbumList(page, size));
@RequestParam(defaultValue = "10") int size,
@AuthenticationPrincipal(expression = "member") Member member) {
return ApiResponse.onSuccess(photoAlbumService.getAllRecentPhotoAlbumList(member.getId(), page, size));
}

@GetMapping("/member/{memberId}/shows")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ public interface PhotoAlbumService {
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 getAllRecentPhotoAlbumList(int page, int size);
public PhotoAlbumResponseDTO.ScrollMemberPhotoAlbumDTO getAllRecentPhotoAlbumList(Long memberId, int page, int size);
public PerformerShowListResponseDTO getPerformerShows(Long memberId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -281,32 +281,40 @@ public String deletePhotoAlbum(Long photoAlbumId, Long memberId) {
}

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

//로그인 검사
memberRepository.findById(memberId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_AUTHORIZED));

// 최근 생성한 순서대로 photoAlbum 가져오기
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<PhotoAlbum> albumPage = photoAlbumRepository.findAll(pageable); // 또는 커스텀 쿼리 사용 가능
Page<PhotoAlbum> albumPage = photoAlbumRepository.findAll(pageable);
List<PhotoAlbum> albums = albumPage.getContent(); //Page 벗기기

// 3. N+1 방지: 대표 이미지 조회
// N+1 방지: 대표 이미지 조회
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()));
List<Image> images = imageRepository.findFirstByContentIds(albumIds, FilePath.photoAlbum);

// 1. images 전체를 한 번에 imageService에 넘김 -> 사진첩 개수만큼의 presignedUrl 발급을 한번에
List<ImageResponseDTO.ImageResultWithPresignedUrlDTO> imageDTOs = imageService.getImages(images, memberId);

// 2. DTO를 contentId 기준으로 Map으로 변환 -> 각 사진첩 dto에 발급받은 url 뿌려줌
Map<Long, ImageResponseDTO.ImageResultWithPresignedUrlDTO> albumImageMap = imageDTOs.stream()
.collect(Collectors.toMap(ImageResponseDTO.ImageResultWithPresignedUrlDTO::getContentId, Function.identity()));
//DTO 변환
List<PhotoAlbumResponseDTO.MemberPhotoAlbumDTO> dtoList = albums.stream()
.map(album -> {
Image coverImage = albumImageMap.get(album.getId());
ImageResponseDTO.ImageResultWithPresignedUrlDTO coverImageDTO = albumImageMap.get(album.getId());
return PhotoAlbumResponseDTO.MemberPhotoAlbumDTO.builder()
.photoAlbumId(album.getId())
.memberId(album.getAmateurShow().getMember().getId())
.performerName(album.getAmateurShow().getMember().getName())
.amateurShowName(album.getAmateurShow().getName())
.imageUrl(coverImage != null ? coverImage.getImageUrl() : null)
.imageUrl(coverImageDTO != null ? coverImageDTO.getPresignedUrl() : null)
.build();
})
.toList();
Expand Down