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 new file mode 100644 index 0000000..ae3f9dd --- /dev/null +++ b/src/main/java/com/back/catchmate/domain/board/converter/BoardConverter.java @@ -0,0 +1,13 @@ +package com.back.catchmate.domain.board.converter; + +import com.back.catchmate.domain.board.dto.BoardResponse.BoardInfo; +import com.back.catchmate.domain.board.entity.Board; +import org.springframework.stereotype.Component; + +@Component +public class BoardConverter { + public BoardInfo toBoardInfo(Board board) { + return BoardInfo.builder() + .title(board.getTitle()).build(); + } +} 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 026ce44..aeffd5f 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 @@ -29,6 +29,9 @@ public class Board extends BaseTimeEntity { @Column(name = "board_id") private Long id; + @Column(nullable = false) + private String title; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User user; diff --git a/src/main/java/com/back/catchmate/domain/enroll/controller/EnrollController.java b/src/main/java/com/back/catchmate/domain/enroll/controller/EnrollController.java index 7ce1891..8e217f5 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/controller/EnrollController.java +++ b/src/main/java/com/back/catchmate/domain/enroll/controller/EnrollController.java @@ -3,21 +3,27 @@ import com.back.catchmate.domain.enroll.dto.EnrollRequest.CreateEnrollRequest; import com.back.catchmate.domain.enroll.dto.EnrollResponse.CancelEnrollInfo; import com.back.catchmate.domain.enroll.dto.EnrollResponse.CreateEnrollInfo; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.PagedEnrollReceiveInfo; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.PagedEnrollRequestInfo; import com.back.catchmate.domain.enroll.service.EnrollService; import com.back.catchmate.global.jwt.JwtValidation; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.io.IOException; - @Tag(name = "직관 신청 관련 API") @RestController @RequestMapping("/enroll") @@ -27,10 +33,10 @@ public class EnrollController { @PostMapping("/{boardId}") @Operation(summary = "직관 신청 API", description = "직관 신청을 요청하는 API 입니다.") - public CreateEnrollInfo createEnroll(@Valid @RequestBody CreateEnrollRequest createEnrollRequest, - @PathVariable Long boardId, - @JwtValidation Long userId) throws IOException { - return enrollService.createEnroll(createEnrollRequest, boardId, userId); + public CreateEnrollInfo requestEnroll(@Valid @RequestBody CreateEnrollRequest createEnrollRequest, + @PathVariable Long boardId, + @JwtValidation Long userId) { + return enrollService.requestEnroll(createEnrollRequest, boardId, userId); } @DeleteMapping("/cancel/{enrollId}") @@ -39,4 +45,27 @@ public CancelEnrollInfo cancelEnroll(@PathVariable Long enrollId, @JwtValidation Long userId) { return enrollService.cancelEnroll(enrollId, userId); } + + @GetMapping("/request") + @Operation(summary = "내가 보낸 직관 신청 목록 조회 API", description = "내가 보낸 직관 신청 목록을 조회하는 API 입니다.") + public PagedEnrollRequestInfo getRequestEnrollList(@JwtValidation Long userId, + @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) + @Parameter(hidden = true) Pageable pageable) { + return enrollService.getRequestEnrollList(userId, pageable); + } + + @GetMapping("/receive/all") + @Operation(summary = "내가 작성한 게시글에 대한 직관 신청 목록 전체 조회 API", description = "내가 작성한 게시글에 대한 직관 신청 목록을 전체 조회하는 API 입니다.") + public PagedEnrollReceiveInfo getReceiveEnrollList(@JwtValidation Long userId, + @Parameter(hidden = true) Pageable pageable) { + return enrollService.getReceiveEnrollList(userId, pageable); + } + + @GetMapping("/receive") + @Operation(summary = "내가 작성한 게시글에 대한 직관 신청 목록 조회 API", description = "내가 작성한 게시글에 대한 직관 신청 목록을 조회하는 API 입니다.") + public PagedEnrollReceiveInfo getReceiveEnrollListByBoardId(@JwtValidation Long userId, + @RequestParam Long boardId, + @Parameter(hidden = true) Pageable pageable) { + return enrollService.getReceiveEnrollListByBoardId(userId, boardId, pageable); + } } diff --git a/src/main/java/com/back/catchmate/domain/enroll/converter/EnrollConverter.java b/src/main/java/com/back/catchmate/domain/enroll/converter/EnrollConverter.java index 7f89b05..8e17211 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/converter/EnrollConverter.java +++ b/src/main/java/com/back/catchmate/domain/enroll/converter/EnrollConverter.java @@ -1,19 +1,33 @@ package com.back.catchmate.domain.enroll.converter; +import com.back.catchmate.domain.board.converter.BoardConverter; +import com.back.catchmate.domain.board.dto.BoardResponse.BoardInfo; import com.back.catchmate.domain.board.entity.Board; import com.back.catchmate.domain.enroll.dto.EnrollRequest.CreateEnrollRequest; -import com.back.catchmate.domain.enroll.dto.EnrollResponse; import com.back.catchmate.domain.enroll.dto.EnrollResponse.CancelEnrollInfo; import com.back.catchmate.domain.enroll.dto.EnrollResponse.CreateEnrollInfo; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.EnrollReceiveInfo; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.EnrollRequestInfo; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.PagedEnrollReceiveInfo; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.PagedEnrollRequestInfo; import com.back.catchmate.domain.enroll.entity.AcceptStatus; import com.back.catchmate.domain.enroll.entity.Enroll; +import com.back.catchmate.domain.user.converter.UserConverter; +import com.back.catchmate.domain.user.dto.UserResponse.UserInfo; import com.back.catchmate.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; -import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; @Component +@RequiredArgsConstructor public class EnrollConverter { + private final UserConverter userConverter; + private final BoardConverter boardConverter; + public Enroll toEntity(CreateEnrollRequest createEnrollRequest, User user, Board board) { return Enroll.builder() .user(user) @@ -37,4 +51,59 @@ public CancelEnrollInfo toCancelEnrollInfo(Enroll enroll) { .deletedAt(enroll.getUpdatedAt()) .build(); } + + public PagedEnrollRequestInfo toPagedEnrollRequestInfo(Page enrollList) { + List enrollRequestInfoList = enrollList.stream() + .map(enroll -> { + UserInfo userInfo = userConverter.toUserInfo(enroll.getUser()); + BoardInfo boardInfo = boardConverter.toBoardInfo(enroll.getBoard()); + return toEnrollRequestInfo(enroll, userInfo, boardInfo); + }) + .collect(Collectors.toList()); + + return PagedEnrollRequestInfo.builder() + .enrollInfoList(enrollRequestInfoList) + .totalPages(enrollList.getTotalPages()) + .totalElements(enrollList.getTotalElements()) + .build(); + } + + public EnrollRequestInfo toEnrollRequestInfo(Enroll enroll, UserInfo userInfo, BoardInfo boardInfo) { + return EnrollRequestInfo.builder() + .enrollId(enroll.getId()) + .acceptStatus(enroll.getAcceptStatus()) + .description(enroll.getDescription()) + .requestDate(enroll.getCreatedAt()) + .userInfo(userInfo) + .boardInfo(boardInfo) + .build(); + } + + public PagedEnrollReceiveInfo toPagedEnrollReceiveInfo(Page enrollList) { + List enrollRequestInfoList = enrollList.stream() + .map(enroll -> { + UserInfo userInfo = userConverter.toUserInfo(enroll.getUser()); + BoardInfo boardInfo = boardConverter.toBoardInfo(enroll.getBoard()); + return toEnrollReceiveInfo(enroll, userInfo, boardInfo); + }) + .collect(Collectors.toList()); + + return PagedEnrollReceiveInfo.builder() + .enrollInfoList(enrollRequestInfoList) + .totalPages(enrollList.getTotalPages()) + .totalElements(enrollList.getTotalElements()) + .build(); + } + + public EnrollReceiveInfo toEnrollReceiveInfo(Enroll enroll, UserInfo userInfo, BoardInfo boardInfo) { + return EnrollReceiveInfo.builder() + .enrollId(enroll.getId()) + .acceptStatus(enroll.getAcceptStatus()) + .description(enroll.getDescription()) + .receiveDate(enroll.getCreatedAt()) + .isNew(enroll.isNew()) + .userInfo(userInfo) + .boardInfo(boardInfo) + .build(); + } } diff --git a/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollRequest.java b/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollRequest.java index e4e6719..dff376a 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollRequest.java +++ b/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollRequest.java @@ -1,6 +1,5 @@ package com.back.catchmate.domain.enroll.dto; -import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollResponse.java b/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollResponse.java index da1213a..a9b9c1a 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollResponse.java +++ b/src/main/java/com/back/catchmate/domain/enroll/dto/EnrollResponse.java @@ -9,22 +9,60 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +import java.util.List; public abstract class EnrollResponse { @Getter @Builder @NoArgsConstructor @AllArgsConstructor - public static class EnrollInfo { + public static class EnrollRequestInfo { private Long enrollId; private AcceptStatus acceptStatus; private String description; private LocalDateTime requestDate; + private UserInfo userInfo; + private BoardInfo boardInfo; + } + + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class EnrollReceiveInfo { + private Long enrollId; + private AcceptStatus acceptStatus; + private String description; + private LocalDateTime receiveDate; private boolean isNew; private UserInfo userInfo; private BoardInfo boardInfo; } + @Getter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class PagedEnrollRequestInfo { + private List enrollInfoList; + private Integer totalPages; + private Long totalElements; + private Boolean isFirst; + private Boolean isLast; + } + + @Getter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class PagedEnrollReceiveInfo { + private List enrollInfoList; + private Integer totalPages; + private Long totalElements; + private Boolean isFirst; + private Boolean isLast; + } + @Getter @Builder @NoArgsConstructor diff --git a/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java b/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java index c8a025b..c66f116 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java +++ b/src/main/java/com/back/catchmate/domain/enroll/repository/EnrollRepository.java @@ -1,10 +1,21 @@ package com.back.catchmate.domain.enroll.repository; import com.back.catchmate.domain.enroll.entity.Enroll; +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; +import org.springframework.data.repository.query.Param; import java.util.Optional; public interface EnrollRepository extends JpaRepository { Optional findByUserIdAndBoardId(Long userId, Long boardId); + + Page findByUserId(Long userId, Pageable pageable); + + @Query("SELECT e FROM Enroll e WHERE e.board.user.id = :userId") + Page findEnrollListByBoardWriter(@Param("userId") Long userId, Pageable pageable); + + Page findByBoardId(Long boardId, Pageable pageable); } diff --git a/src/main/java/com/back/catchmate/domain/enroll/service/EnrollService.java b/src/main/java/com/back/catchmate/domain/enroll/service/EnrollService.java index 8242890..7abd6ba 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/service/EnrollService.java +++ b/src/main/java/com/back/catchmate/domain/enroll/service/EnrollService.java @@ -3,11 +3,19 @@ import com.back.catchmate.domain.enroll.dto.EnrollRequest.CreateEnrollRequest; import com.back.catchmate.domain.enroll.dto.EnrollResponse.CancelEnrollInfo; import com.back.catchmate.domain.enroll.dto.EnrollResponse.CreateEnrollInfo; - -import java.io.IOException; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.PagedEnrollReceiveInfo; +import com.back.catchmate.domain.enroll.dto.EnrollResponse.PagedEnrollRequestInfo; +import org.springframework.data.domain.Pageable; public interface EnrollService { - CreateEnrollInfo createEnroll(CreateEnrollRequest request, Long boardId, Long userId) throws IOException; + CreateEnrollInfo requestEnroll(CreateEnrollRequest request, Long boardId, Long userId); CancelEnrollInfo cancelEnroll(Long enrollId, Long userId); + + PagedEnrollRequestInfo getRequestEnrollList(Long userId, Pageable pageable); + + PagedEnrollReceiveInfo getReceiveEnrollList(Long userId, Pageable pageable); + + PagedEnrollReceiveInfo getReceiveEnrollListByBoardId(Long userId, Long boardId, Pageable pageable); + } diff --git a/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java b/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java index e51cdca..66e0a88 100644 --- a/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java +++ b/src/main/java/com/back/catchmate/domain/enroll/service/EnrollServiceImpl.java @@ -13,10 +13,10 @@ import com.back.catchmate.global.error.ErrorCode; import com.back.catchmate.global.error.exception.BaseException; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import java.io.IOException; - @Service @RequiredArgsConstructor public class EnrollServiceImpl implements EnrollService { @@ -26,7 +26,7 @@ public class EnrollServiceImpl implements EnrollService { private final EnrollConverter enrollConverter; @Override - public CreateEnrollInfo createEnroll(CreateEnrollRequest request, Long boardId, Long userId) throws IOException { + public CreateEnrollInfo requestEnroll(CreateEnrollRequest request, Long boardId, Long userId) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); @@ -39,8 +39,8 @@ public CreateEnrollInfo createEnroll(CreateEnrollRequest request, Long boardId, enrollRepository.findByUserIdAndBoardId(user.getId(), board.getId()) .ifPresent(enroll -> { - throw new BaseException(ErrorCode.ENROLL_ALREADY_EXIST); - }); + throw new BaseException(ErrorCode.ENROLL_ALREADY_EXIST); + }); Enroll enroll = enrollConverter.toEntity(request, user, board); enrollRepository.save(enroll); @@ -63,4 +63,40 @@ public EnrollResponse.CancelEnrollInfo cancelEnroll(Long enrollId, Long userId) enrollRepository.delete(enroll); return enrollConverter.toCancelEnrollInfo(enroll); } + + @Override + public EnrollResponse.PagedEnrollRequestInfo getRequestEnrollList(Long userId, Pageable pageable) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); + + Page enrollList = enrollRepository.findByUserId(user.getId(), pageable); + return enrollConverter.toPagedEnrollRequestInfo(enrollList); + } + + @Override + public EnrollResponse.PagedEnrollReceiveInfo getReceiveEnrollList(Long userId, Pageable pageable) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); + + Page enrollList = enrollRepository.findEnrollListByBoardWriter(user.getId(), pageable); + return enrollConverter.toPagedEnrollReceiveInfo(enrollList); + } + + @Override + public EnrollResponse.PagedEnrollReceiveInfo getReceiveEnrollListByBoardId(Long userId, Long boardId, Pageable pageable) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); + + Board board = boardRepository.findById(boardId) + .orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND)); + + // 게시글 작성자가 맞는지 확인 + if (!board.getUser().equals(user)) { + throw new BaseException(ErrorCode.ENROLL_GET_INVALID); + } + + // 게시글에 신청된 목록 조회 + Page enrollList = enrollRepository.findByBoardId(boardId, pageable); + return enrollConverter.toPagedEnrollReceiveInfo(enrollList); + } } diff --git a/src/main/java/com/back/catchmate/domain/user/converter/UserConverter.java b/src/main/java/com/back/catchmate/domain/user/converter/UserConverter.java index 388b493..d7ef95f 100644 --- a/src/main/java/com/back/catchmate/domain/user/converter/UserConverter.java +++ b/src/main/java/com/back/catchmate/domain/user/converter/UserConverter.java @@ -1,5 +1,6 @@ package com.back.catchmate.domain.user.converter; +import com.back.catchmate.domain.club.converter.ClubConverter; import com.back.catchmate.domain.club.dto.ClubResponse.ClubInfo; import com.back.catchmate.domain.club.entity.Club; import com.back.catchmate.domain.user.dto.UserRequest; @@ -9,12 +10,16 @@ import com.back.catchmate.domain.user.entity.AlarmType; import com.back.catchmate.domain.user.entity.Provider; import com.back.catchmate.domain.user.entity.User; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import java.time.LocalDateTime; @Component +@RequiredArgsConstructor public class UserConverter { + private final ClubConverter clubConverter; + public User toEntity(UserRequest.UserJoinRequest request, Club favoriteClub, String providerIdWithProvider) { return User.builder() .email(request.getEmail()) @@ -43,7 +48,9 @@ public LoginInfo toLoginInfo(User user, String accessToken, String refreshToken) .build(); } - public UserInfo toUserInfo(User user, ClubInfo clubInfo) { + public UserInfo toUserInfo(User user) { + ClubInfo clubInfo = clubConverter.toClubInfo(user.getClub()); + return UserInfo.builder() .userId(user.getId()) .email(user.getEmail()) diff --git a/src/main/java/com/back/catchmate/domain/user/service/UserServiceImpl.java b/src/main/java/com/back/catchmate/domain/user/service/UserServiceImpl.java index 9f84676..ad3cbd8 100644 --- a/src/main/java/com/back/catchmate/domain/user/service/UserServiceImpl.java +++ b/src/main/java/com/back/catchmate/domain/user/service/UserServiceImpl.java @@ -1,13 +1,11 @@ package com.back.catchmate.domain.user.service; import com.back.catchmate.domain.club.converter.ClubConverter; -import com.back.catchmate.domain.club.dto.ClubResponse.ClubInfo; import com.back.catchmate.domain.club.entity.Club; import com.back.catchmate.domain.club.repository.ClubRepository; import com.back.catchmate.domain.user.converter.UserConverter; import com.back.catchmate.domain.user.dto.UserRequest.UserJoinRequest; import com.back.catchmate.domain.user.dto.UserRequest.UserProfileUpdateRequest; -import com.back.catchmate.domain.user.dto.UserResponse; import com.back.catchmate.domain.user.dto.UserResponse.LoginInfo; import com.back.catchmate.domain.user.dto.UserResponse.UpdateAlarmInfo; import com.back.catchmate.domain.user.dto.UserResponse.UserInfo; @@ -73,8 +71,7 @@ public UserInfo getMyProfile(Long userId) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - ClubInfo clubInfo = clubConverter.toClubInfo(user.getClub()); - return userConverter.toUserInfo(user, clubInfo); + return userConverter.toUserInfo(user); } // 다른 사용자의 프로필 정보를 가져오는 메서드 @@ -84,8 +81,7 @@ public UserInfo getOtherUserProfile(Long userId, Long profileUserId) { User user = userRepository.findById(profileUserId) .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); - ClubInfo clubInfo = clubConverter.toClubInfo(user.getClub()); - return userConverter.toUserInfo(user, clubInfo); + return userConverter.toUserInfo(user); } @Override 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 2af151c..42b0725 100644 --- a/src/main/java/com/back/catchmate/global/error/ErrorCode.java +++ b/src/main/java/com/back/catchmate/global/error/ErrorCode.java @@ -24,6 +24,7 @@ public enum ErrorCode { ENROLL_CANCEL_INVALID(HttpStatus.BAD_REQUEST, "직관 신청을 취소할 권한이 없습니다."), ENROLL_ACCEPT_INVALID(HttpStatus.BAD_REQUEST, "직관 신청을 수락할 권한이 없습니다."), ENROLL_REJECT_INVALID(HttpStatus.BAD_REQUEST, "직관 신청을 거절할 권한이 없습니다."), + ENROLL_GET_INVALID(HttpStatus.BAD_REQUEST, "직관 신청을 조회할 권한이 없습니다."), // 게시글 BOARD_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 게시글입니다."),