Skip to content

Commit d64732c

Browse files
authored
Merge pull request #124 from Team-Nuvibe/dev
dev to main
2 parents 79d4552 + 8fc26a0 commit d64732c

8 files changed

Lines changed: 70 additions & 5 deletions

File tree

src/main/java/com/umc/nuvibe/domain/archive/controller/ArchiveBoardController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,15 @@ public Response<Void> addBoardImage(
156156
archiveBoardService.addBoardImage(userId, boardId, request);
157157
return Response.of(ArchiveResultCode.BOARD_IMAGE_ADD_SUCCESS);
158158
}
159+
160+
// 보드간 이미지 이동
161+
@PatchMapping("/{boardId}/images/move")
162+
@Operation(summary = "이미지 이동", description = "선택한 이미지를 다른 보드로 이동합니다.")
163+
public Response<Void> moveImages(
164+
@AuthUser Long userId,
165+
@Parameter(description = "보드 ID") @PathVariable Long boardId,
166+
@Valid @RequestBody BoardImageMoveRequest request) {
167+
archiveBoardService.moveImages(userId, boardId, request);
168+
return Response.ok(ArchiveResultCode.BOARD_IMAGE_MOVE_SUCCESS,null);
169+
}
159170
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.umc.nuvibe.domain.archive.dto.request;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.NotEmpty;
5+
import jakarta.validation.constraints.NotNull;
6+
7+
import java.util.List;
8+
9+
10+
// 보드 간 이미지 이동 요청 DTO
11+
@Schema(description = "보드 간 이미지 이동 요청")
12+
public record BoardImageMoveRequest(
13+
14+
@Schema(description = "이동 대상 보드 ID", example = "2")
15+
@NotNull(message = "이동할 보드를 선택해주세요.")
16+
Long targetBoardId,
17+
18+
@Schema(description = "이동할 보드 이미지 ID 목록", example = "[1, 2, 3]")
19+
@NotEmpty(message = "이동할 이미지를 선택해주세요.")
20+
List<Long> boardImageIds
21+
) {}

src/main/java/com/umc/nuvibe/domain/archive/entity/BoardImage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ public BoardImage(ArchiveBoard board, Image image) {
2828
this.board = board;
2929
this.image = image;
3030
}
31+
3132
}

src/main/java/com/umc/nuvibe/domain/archive/repository/BoardImageRepository.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,13 @@ List<Image> findImagesByDate(
266266
"WHERE bi.board.id IN :boardIds " +
267267
"GROUP BY bi.board.id")
268268
List<Object[]> countDistinctTagsByBoardIds(@Param("boardIds") List<Long> boardIds);
269+
270+
// 보드 내 이미지 ID 목록으로 보드 이미지 조회
271+
long countByIdInAndBoardId(List<Long> ids, Long boardId);
272+
273+
@Modifying
274+
@Query("UPDATE BoardImage bi SET bi.board.id = :targetBoardId WHERE bi.id IN :ids AND bi.board.id = :sourceBoardId")
275+
int bulkMoveToBoard(@Param("ids") List<Long> ids,
276+
@Param("sourceBoardId") Long sourceBoardId,
277+
@Param("targetBoardId") Long targetBoardId);
269278
}

src/main/java/com/umc/nuvibe/domain/archive/service/ArchiveBoardService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@ public interface ArchiveBoardService {
4444
// 보드 내 이미지 추가(채팅용)
4545
void addBoardImageForChat(Long userId, Long boardId, Long imageId);
4646

47+
// 보드 간 이미지 이동
48+
void moveImages(Long userId, Long sourceBoardId, BoardImageMoveRequest request);
49+
4750
}

src/main/java/com/umc/nuvibe/domain/archive/service/ArchiveBoardServiceImpl.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,27 @@ private void addBoardImageInternal(Long userId, Long boardId, Long imageId) {
252252
build());
253253
}
254254

255+
// 보드 간 이미지 이동
256+
@Override
257+
@Transactional
258+
public void moveImages(Long userId, Long sourceBoardId, BoardImageMoveRequest request) {
259+
// 1. 출발/도착 보드 소유권 검증
260+
ArchiveBoard sourceBoard = findBoardByIdAndUserId(sourceBoardId, userId);
261+
ArchiveBoard targetBoard = findBoardByIdAndUserId(request.targetBoardId(), userId);
262+
263+
// 2. 같은 보드로 이동 방지
264+
if (sourceBoard.getId().equals(targetBoard.getId())) {
265+
throw new BusinessException(ArchiveErrorCode.SAME_BOARD_MOVE);
266+
}
255267

268+
// 3. 이미지 존재 여부 검증 (중복 ID 방어 포함)
269+
List<Long> uniqueIds = request.boardImageIds().stream().distinct().toList();
270+
long count = boardImageRepository.countByIdInAndBoardId(uniqueIds, sourceBoardId);
271+
if (count != uniqueIds.size()) {
272+
throw new BusinessException(ArchiveErrorCode.BOARD_IMAGE_NOT_FOUND);
273+
}
256274

257-
258-
259-
275+
// 4. 벌크 업데이트
276+
boardImageRepository.bulkMoveToBoard(uniqueIds, sourceBoardId, targetBoard.getId());
277+
}
260278
}

src/main/java/com/umc/nuvibe/global/apiPayLoad/error/ArchiveErrorCode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ public enum ArchiveErrorCode implements ErrorCode {
1414
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "ARCHIVE003", "사용자를 찾을 수 없습니다."),
1515
DUPLICATE_BOARD_NAME(HttpStatus.CONFLICT, "ARCHIVE004", "이미 존재하는 보드 이름입니다."),
1616
BOARD_ACCESS_DENIED(HttpStatus.FORBIDDEN, "ARCHIVE005", "해당 보드에 접근 권한이 없습니다."),
17-
BOARD_IMAGE_ALREADY_EXISTS(HttpStatus.CONFLICT, "ARCHIVE006", "이미 다른 보드에 포함된 이미지입니다.")
17+
BOARD_IMAGE_ALREADY_EXISTS(HttpStatus.CONFLICT, "ARCHIVE006", "이미 다른 보드에 포함된 이미지입니다."),
18+
SAME_BOARD_MOVE(HttpStatus.BAD_REQUEST, "ARCHIVE007", "같은 보드로는 이동할 수 없습니다.")
1819
;
1920

2021
private final HttpStatus httpStatus;

src/main/java/com/umc/nuvibe/global/apiPayLoad/result/ArchiveResultCode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public enum ArchiveResultCode implements ResultCode {
2222
BOARD_DELETE_SUCCESS(HttpStatus.NO_CONTENT, "ARCHIVE007", "보드 삭제 성공"),
2323
BOARD_IMAGE_DELETE_SUCCESS(HttpStatus.NO_CONTENT, "ARCHIVE008", "이미지 삭제 성공"),
2424
//추가
25-
BOARD_IMAGE_ADD_SUCCESS(HttpStatus.OK, "ARCHIVE009", "이미지가 보드에 추가되었습니다.");
25+
BOARD_IMAGE_ADD_SUCCESS(HttpStatus.OK, "ARCHIVE009", "이미지가 보드에 추가되었습니다."),
26+
BOARD_IMAGE_MOVE_SUCCESS(HttpStatus.OK, "ARCHIVE010", "이미지 이동 성공");
2627

2728

2829
private final HttpStatus httpStatus;

0 commit comments

Comments
 (0)