Skip to content

Commit

Permalink
Merge pull request #59 from YAPP-Github/feature/MAFOO-93
Browse files Browse the repository at this point in the history
[MAFOO-93] feat: 앨범 순서 관련 API 및 기능 추가
  • Loading branch information
CChuYong authored Aug 24, 2024
2 parents 84bef84 + d0b7bb5 commit 587ddaa
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 4 deletions.
17 changes: 17 additions & 0 deletions photo-service/src/main/java/kr/mafoo/photo/api/AlbumApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import kr.mafoo.photo.annotation.RequestMemberId;
import kr.mafoo.photo.annotation.ULID;
import kr.mafoo.photo.controller.dto.request.AlbumCreateRequest;
import kr.mafoo.photo.controller.dto.request.AlbumUpdateDisplayIndexRequest;
import kr.mafoo.photo.controller.dto.request.AlbumUpdateRequest;
import kr.mafoo.photo.controller.dto.response.AlbumResponse;
import org.springframework.validation.annotation.Validated;
Expand Down Expand Up @@ -64,6 +65,22 @@ Mono<AlbumResponse> updateAlbum(
AlbumUpdateRequest request
);

@Operation(summary = "앨범 표기 순서 변경", description = "앨범의 표기 순서를 변경합니다.")
@PatchMapping("/{albumId}/display-index")
Mono<AlbumResponse> updateAlbumDisplayIndex(
@RequestMemberId
String memberId,

@ULID
@Parameter(description = "앨범 ID", example = "test_album_id")
@PathVariable
String albumId,

@Valid
@RequestBody
AlbumUpdateDisplayIndexRequest request
);

@Operation(summary = "앨범 삭제", description = "앨범을 삭제합니다.")
@DeleteMapping("/{albumId}")
Mono<Void> deleteAlbum(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import kr.mafoo.photo.api.AlbumApi;
import kr.mafoo.photo.controller.dto.request.AlbumCreateRequest;
import kr.mafoo.photo.controller.dto.request.AlbumUpdateDisplayIndexRequest;
import kr.mafoo.photo.controller.dto.request.AlbumUpdateRequest;
import kr.mafoo.photo.controller.dto.response.AlbumResponse;
import kr.mafoo.photo.domain.AlbumType;
Expand Down Expand Up @@ -55,6 +56,13 @@ public Mono<AlbumResponse> updateAlbum(String memberId, String albumId, AlbumUpd
.map(AlbumResponse::fromEntity);
}

@Override
public Mono<AlbumResponse> updateAlbumDisplayIndex(String memberId, String albumId, AlbumUpdateDisplayIndexRequest request) {
return albumService
.moveAlbumDisplayIndex(albumId, memberId, request.newDisplayIndex())
.map(AlbumResponse::fromEntity);
}


@Override
public Mono<Void> deleteAlbum(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package kr.mafoo.photo.controller.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;

@Schema(description = "앨범 수정 요청")
public record AlbumUpdateDisplayIndexRequest(
@NotNull
@Min(0)
@Schema(description = "대상 인덱스", example = "1")
Integer newDisplayIndex
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public class AlbumEntity implements Persistable<String> {
@Column("owner_member_id")
private String ownerMemberId;

@Column("display_index")
private Integer displayIndex;

@CreatedDate
@Column("created_at")
private LocalDateTime createdAt;
Expand Down Expand Up @@ -92,6 +95,7 @@ public static AlbumEntity newAlbum(String albumId, String albumName, AlbumType a
album.ownerMemberId = ownerMemberId;
album.isNew = true;
album.photoCount = 0;
album.displayIndex = 0;
return album;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package kr.mafoo.photo.exception;

public class AlbumIndexIsSameException extends DomainException {
public AlbumIndexIsSameException() {
super(ErrorCode.ALBUM_DISPLAY_INDEX_IS_SAME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public enum ErrorCode {
REQUEST_INPUT_NOT_VALID("EX0002", "입력 값이 올바르지 않습니다."),

ALBUM_NOT_FOUND("AE0001", "앨범을 찾을 수 없습니다"),
ALBUM_DISPLAY_INDEX_IS_SAME("AE0002", "옮기려는 대상 앨범 인덱스가 같습니다"),
PHOTO_NOT_FOUND("PE0001", "사진을 찾을 수 없습니다"),
PHOTO_BRAND_NOT_EXISTS("PE002", "사진 브랜드가 존재하지 않습니다"),
PHOTO_QR_URL_EXPIRED("PE003", "사진 저장을 위한 QR URL이 만료되었습니다"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
package kr.mafoo.photo.repository;

import kr.mafoo.photo.domain.AlbumEntity;
import org.springframework.data.r2dbc.repository.Modifying;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public interface AlbumRepository extends R2dbcRepository<AlbumEntity, String> {
Flux<AlbumEntity> findAllByOwnerMemberId(String ownerMemberId);
Flux<AlbumEntity> findAllByOwnerMemberIdOrderByDisplayIndex(String ownerMemberId);

@Modifying
@Query("UPDATE album SET display_index = display_index + 1 WHERE owner_member_id = :ownerMemberId")
Mono<Void> pushDisplayIndex(String ownerMemberId);

@Modifying
@Query("UPDATE album SET display_index = display_index + 1 WHERE owner_member_id = :ownerMemberId " +
"AND display_index BETWEEN :startIndex AND :lastIndex")
Mono<Void> pushDisplayIndexBetween(String ownerMemberId, Integer startIndex, Integer lastIndex);

@Modifying
@Query("UPDATE album SET display_index = display_index -1 WHERE owner_member_id = :ownerMemberId " +
"AND display_index BETWEEN :startIndex AND :lastIndex")
Mono<Void> popDisplayIndexBetween(String ownerMemberId, Integer startIndex, Integer lastIndex);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import kr.mafoo.photo.domain.AlbumEntity;
import kr.mafoo.photo.domain.AlbumType;
import kr.mafoo.photo.exception.AlbumIndexIsSameException;
import kr.mafoo.photo.exception.AlbumNotFoundException;
import kr.mafoo.photo.repository.AlbumRepository;
import kr.mafoo.photo.util.IdGenerator;
Expand All @@ -19,11 +20,35 @@ public class AlbumService {
@Transactional
public Mono<AlbumEntity> createNewAlbum(String ownerMemberId, String albumName, AlbumType albumType) {
AlbumEntity albumEntity = AlbumEntity.newAlbum(IdGenerator.generate(), albumName, albumType, ownerMemberId);
return albumRepository.save(albumEntity);
return albumRepository
.pushDisplayIndex(ownerMemberId) //전부 인덱스 한칸 밀기
.then(albumRepository.save(albumEntity));
}

@Transactional
public Mono<AlbumEntity> moveAlbumDisplayIndex(String albumId, String requestMemberId, Integer displayIndex) {
return findByAlbumId(albumId, requestMemberId)
.flatMap(album -> {
Integer currentDisplayIndex = album.getDisplayIndex();
Mono<Void> pushAlbumIndexPublisher;
if(displayIndex < currentDisplayIndex) {
pushAlbumIndexPublisher = albumRepository
.pushDisplayIndexBetween(requestMemberId, displayIndex, currentDisplayIndex -1);
} else if(displayIndex > currentDisplayIndex) {
pushAlbumIndexPublisher = albumRepository
.popDisplayIndexBetween(requestMemberId, currentDisplayIndex + 1, displayIndex);
} else {
pushAlbumIndexPublisher = Mono.error(new AlbumIndexIsSameException());
}
return pushAlbumIndexPublisher.then(Mono.defer(() -> {
album.setDisplayIndex(displayIndex);
return albumRepository.save(album);
}));
});
}

public Flux<AlbumEntity> findAllByOwnerMemberId(String ownerMemberId) {
return albumRepository.findAllByOwnerMemberId(ownerMemberId);
return albumRepository.findAllByOwnerMemberIdOrderByDisplayIndex(ownerMemberId);
}

public Mono<AlbumEntity> findByAlbumId(String albumId, String requestMemberId) {
Expand All @@ -50,7 +75,10 @@ public Mono<Void> deleteAlbumById(String albumId, String requestMemberId) {
// 내 앨범이 아니면 그냥 없는 앨범 처리
return Mono.error(new AlbumNotFoundException());
} else {
return albumRepository.deleteById(albumId);
return albumRepository
.deleteById(albumId)
.then(albumRepository.popDisplayIndexBetween(
requestMemberId, albumEntity.getDisplayIndex(), Integer.MAX_VALUE));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
ALTER TABLE `album`
ADD `display_index` INTEGER NOT NULL DEFAULT 0 COMMENT '표시순' after `owner_member_id`;
CREATE INDEX `idx_album_display_index` ON `album`(`display_index`);

WITH RankedAlbums AS (
SELECT
id,
owner_member_id,
ROW_NUMBER() OVER (PARTITION BY owner_member_id ORDER BY created_at DESC) - 1 AS new_index
FROM album
)
UPDATE album
JOIN RankedAlbums
ON album.id = RankedAlbums.id
SET album.display_index = RankedAlbums.new_index;

0 comments on commit 587ddaa

Please sign in to comment.