diff --git a/src/main/java/com/back/catchmate/domain/board/controller/BoardController.java b/src/main/java/com/back/catchmate/domain/board/controller/BoardController.java index aa936b2..3746c2e 100644 --- a/src/main/java/com/back/catchmate/domain/board/controller/BoardController.java +++ b/src/main/java/com/back/catchmate/domain/board/controller/BoardController.java @@ -55,7 +55,7 @@ public PagedBoardInfo getBoardList(@JwtValidation Long userId, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate gameStartDate, @RequestParam(required = false) Integer maxPerson, @RequestParam(required = false) Long preferredTeamId, - @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) + @PageableDefault(sort = "liftUpDate", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { return boardService.getBoardList(userId, gameStartDate, maxPerson, preferredTeamId, pageable); } @@ -112,4 +112,11 @@ public BoardDeleteInfo deleteBoard(@JwtValidation Long userId, @PathVariable Long boardId) { return boardService.deleteBoard(userId, boardId); } + + @PatchMapping("/{boardId}/lift-up") + @Operation(summary = "게시글 끌어올리기 API", description = "게시글을 끌어올립니다.") + public BoardInfo updateLiftUpDate(@JwtValidation Long userId, + @PathVariable Long boardId){ + return boardService.updateLiftUpDate(userId, boardId); + } } diff --git a/src/main/java/com/back/catchmate/domain/board/converter/BoardConverter.java b/src/main/java/com/back/catchmate/domain/board/converter/BoardConverter.java index 4c39730..754c888 100644 --- a/src/main/java/com/back/catchmate/domain/board/converter/BoardConverter.java +++ b/src/main/java/com/back/catchmate/domain/board/converter/BoardConverter.java @@ -13,6 +13,7 @@ import com.back.catchmate.domain.user.dto.UserResponse.UserInfo; import com.back.catchmate.domain.user.entity.User; import lombok.RequiredArgsConstructor; +import org.springframework.cglib.core.Local; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Component; @@ -36,6 +37,7 @@ public Board toEntity(User user, Game game, Club cheerClub, CreateOrUpdateBoardR .preferredGender(boardRequest.getPreferredGender()) .preferredAgeRange(String.join(",", boardRequest.getPreferredAgeRange())) .isCompleted(boardRequest.getIsCompleted()) + .liftUpDate(LocalDateTime.now()) .build(); } @@ -66,6 +68,7 @@ public BoardInfo toBoardInfo(Board board, Game game) { .preferredGender(board.getPreferredGender()) .preferredAgeRange(board.getPreferredAgeRange()) .gameInfo(gameInfo) + .liftUpDate(board.getLiftUpDate()) .userInfo(userInfo) .build(); } diff --git a/src/main/java/com/back/catchmate/domain/board/dto/BoardResponse.java b/src/main/java/com/back/catchmate/domain/board/dto/BoardResponse.java index 415454e..9167455 100644 --- a/src/main/java/com/back/catchmate/domain/board/dto/BoardResponse.java +++ b/src/main/java/com/back/catchmate/domain/board/dto/BoardResponse.java @@ -26,6 +26,7 @@ public static class BoardInfo { private String preferredGender; private String preferredAgeRange; private GameInfo gameInfo; + private LocalDateTime liftUpDate; private UserInfo userInfo; } diff --git a/src/main/java/com/back/catchmate/domain/board/entity/Board.java b/src/main/java/com/back/catchmate/domain/board/entity/Board.java index dc9a5ad..785d4f1 100644 --- a/src/main/java/com/back/catchmate/domain/board/entity/Board.java +++ b/src/main/java/com/back/catchmate/domain/board/entity/Board.java @@ -15,6 +15,7 @@ import lombok.Setter; import lombok.ToString; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -74,6 +75,9 @@ public class Board extends BaseTimeEntity { @Column(nullable = false) private Boolean isCompleted = false; + @Column(name = "lift_up_date", nullable = false) + private LocalDateTime liftUpDate; + public boolean isWriterSameAsLoginUser(User user) { return this.user.getId().equals(user.getId()); } diff --git a/src/main/java/com/back/catchmate/domain/board/repository/BoardRepository.java b/src/main/java/com/back/catchmate/domain/board/repository/BoardRepository.java index 4f7f772..4fe728a 100644 --- a/src/main/java/com/back/catchmate/domain/board/repository/BoardRepository.java +++ b/src/main/java/com/back/catchmate/domain/board/repository/BoardRepository.java @@ -16,6 +16,8 @@ public interface BoardRepository extends JpaRepository, BoardReposi int softDeleteByUserIdAndBoardId(@Param("userId") Long userId, @Param("boardId") Long boardId); @Query("SELECT b FROM Board b WHERE b.id = :boardId AND b.deletedAt IS NULL AND b.isCompleted = true") + Optional findByIdAndDeletedAtIsNullAndIsCompleted(Long boardId); + Optional findByIdAndDeletedAtIsNull(Long boardId); Page findAllByUserIdAndDeletedAtIsNullAndIsCompletedIsTrue(Long userId, Pageable pageable); diff --git a/src/main/java/com/back/catchmate/domain/board/repository/BoardRepositoryImpl.java b/src/main/java/com/back/catchmate/domain/board/repository/BoardRepositoryImpl.java index ad2baec..e78da22 100644 --- a/src/main/java/com/back/catchmate/domain/board/repository/BoardRepositoryImpl.java +++ b/src/main/java/com/back/catchmate/domain/board/repository/BoardRepositoryImpl.java @@ -55,7 +55,7 @@ public Page findFilteredBoards(LocalDate gameDate, Integer maxPerson, Lon .leftJoin(board.club, club).fetchJoin() .leftJoin(board.game, game).fetchJoin() .where(builder) - .orderBy(board.createdAt.desc()); + .orderBy(board.liftUpDate.desc()); // 페이징 처리 long total = query.fetchCount(); diff --git a/src/main/java/com/back/catchmate/domain/board/service/BoardService.java b/src/main/java/com/back/catchmate/domain/board/service/BoardService.java index 9883b9e..48810ea 100644 --- a/src/main/java/com/back/catchmate/domain/board/service/BoardService.java +++ b/src/main/java/com/back/catchmate/domain/board/service/BoardService.java @@ -5,6 +5,7 @@ import com.back.catchmate.domain.board.dto.BoardResponse.BoardInfo; import com.back.catchmate.domain.board.dto.BoardResponse.PagedBoardInfo; import org.springframework.data.domain.Pageable; +import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; @@ -22,4 +23,6 @@ public interface BoardService { BoardInfo getTempBoard(Long userId, Long boardId); BoardDeleteInfo deleteBoard(Long userId, Long boardId); + + BoardInfo updateLiftUpDate(Long userId, Long boardId); } diff --git a/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java b/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java index 476a9a4..3070f5e 100644 --- a/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java +++ b/src/main/java/com/back/catchmate/domain/board/service/BoardServiceImpl.java @@ -105,7 +105,7 @@ public BoardInfo getBoard(Long userId, Long boardId) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - Board board = boardRepository.findByIdAndDeletedAtIsNull(boardId) + Board board = boardRepository.findByIdAndDeletedAtIsNullAndIsCompleted(boardId) .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); return boardConverter.toBoardInfo(board, board.getGame()); @@ -161,4 +161,27 @@ public BoardDeleteInfo deleteBoard(Long userId, Long boardId) { return boardConverter.toBoardDeleteInfo(boardId); } + + @Override + @Transactional + public BoardInfo updateLiftUpDate(Long userId, Long boardId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); + + Board board = boardRepository.findByIdAndDeletedAtIsNullAndIsCompleted(boardId) + .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); + + if (user.isDifferentUserFrom(board.getUser())) { + throw new BaseException(ErrorCode.BOARD_BAD_REQUEST); + } + + // note: 3일 간격으로 수정할 수 있음. + if (board.getLiftUpDate().plusDays(3).isBefore(LocalDateTime.now())) { + board.setLiftUpDate(LocalDateTime.now()); + } else { + throw new BaseException(ErrorCode.BOARD_NOT_ALLOWED_UPDATE_LIFTUPDATE); + } + + return boardConverter.toBoardInfo(board, board.getGame()); + } } diff --git a/src/main/java/com/back/catchmate/global/error/ErrorCode.java b/src/main/java/com/back/catchmate/global/error/ErrorCode.java index 41d25ed..2bfacbb 100644 --- a/src/main/java/com/back/catchmate/global/error/ErrorCode.java +++ b/src/main/java/com/back/catchmate/global/error/ErrorCode.java @@ -32,6 +32,7 @@ public enum ErrorCode { TEMP_BOARD_BAD_REQUEST(HttpStatus.NOT_FOUND, "임시 저장된 글을 불러올 권한이 없습니다."), BOARD_DELETED(HttpStatus.NOT_FOUND, "삭제된 게시글이거나 잘못된 접근입니다."), BOARD_BAD_REQUEST(HttpStatus.BAD_REQUEST, "자신의 게시글만 수정할 수 있습니다."), + BOARD_NOT_ALLOWED_UPDATE_LIFTUPDATE(HttpStatus.BAD_REQUEST, "마지막으로 끌어올리기 한 지 3일이 지나야 업데이트 가능합니다."), INVALID_ACCESS_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 액세스 토큰입니다."), INVALID_REFRESH_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 리프레시 토큰입니다."), ALREADY_BOOKMARK(HttpStatus.BAD_REQUEST, "이미 찜한 게시글입니다."),