diff --git a/backend/src/main/java/com/project/capstone/book/controller/BookController.java b/backend/src/main/java/com/project/capstone/book/controller/BookController.java index f0ce60f90f..a143214931 100644 --- a/backend/src/main/java/com/project/capstone/book/controller/BookController.java +++ b/backend/src/main/java/com/project/capstone/book/controller/BookController.java @@ -1,5 +1,6 @@ package com.project.capstone.book.controller; +import com.project.capstone.book.controller.dto.AddBookRequest; import com.project.capstone.book.service.BookService; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; diff --git a/backend/src/main/java/com/project/capstone/book/controller/AddBookRequest.java b/backend/src/main/java/com/project/capstone/book/controller/dto/AddBookRequest.java similarity index 82% rename from backend/src/main/java/com/project/capstone/book/controller/AddBookRequest.java rename to backend/src/main/java/com/project/capstone/book/controller/dto/AddBookRequest.java index 3c7483dc50..d4fbe48912 100644 --- a/backend/src/main/java/com/project/capstone/book/controller/AddBookRequest.java +++ b/backend/src/main/java/com/project/capstone/book/controller/dto/AddBookRequest.java @@ -1,4 +1,4 @@ -package com.project.capstone.book.controller; +package com.project.capstone.book.controller.dto; public record AddBookRequest( String isbn, diff --git a/backend/src/main/java/com/project/capstone/book/controller/dto/BookResponse.java b/backend/src/main/java/com/project/capstone/book/controller/dto/BookResponse.java new file mode 100644 index 0000000000..0a8c3a31e9 --- /dev/null +++ b/backend/src/main/java/com/project/capstone/book/controller/dto/BookResponse.java @@ -0,0 +1,15 @@ +package com.project.capstone.book.controller.dto; + +import com.project.capstone.book.domain.Book; + +public record BookResponse( + Long id, + String isbn, + String title, + String author, + String publisher +) { + public BookResponse(Book book) { + this(book.getId(), book.getIsbn(), book.getTitle(), book.getAuthor(), book.getPublisher()); + } +} diff --git a/backend/src/main/java/com/project/capstone/book/domain/Book.java b/backend/src/main/java/com/project/capstone/book/domain/Book.java index 7667c75f75..a55e49f2a5 100644 --- a/backend/src/main/java/com/project/capstone/book/domain/Book.java +++ b/backend/src/main/java/com/project/capstone/book/domain/Book.java @@ -1,7 +1,7 @@ package com.project.capstone.book.domain; import com.fasterxml.jackson.annotation.JsonManagedReference; -import com.project.capstone.book.controller.AddBookRequest; +import com.project.capstone.book.controller.dto.AddBookRequest; import com.project.capstone.club.domain.Club; import com.project.capstone.content.domain.Content; import com.project.capstone.mybook.domain.MyBook; diff --git a/backend/src/main/java/com/project/capstone/book/service/BookService.java b/backend/src/main/java/com/project/capstone/book/service/BookService.java index 53c42ed3a2..5e25445a65 100644 --- a/backend/src/main/java/com/project/capstone/book/service/BookService.java +++ b/backend/src/main/java/com/project/capstone/book/service/BookService.java @@ -1,6 +1,6 @@ package com.project.capstone.book.service; -import com.project.capstone.book.controller.AddBookRequest; +import com.project.capstone.book.controller.dto.AddBookRequest; import com.project.capstone.book.domain.Book; import com.project.capstone.book.domain.BookRepository; import com.project.capstone.book.exception.BookException; diff --git a/backend/src/main/java/com/project/capstone/club/controller/ClubController.java b/backend/src/main/java/com/project/capstone/club/controller/ClubController.java index 508063a297..99082527a7 100644 --- a/backend/src/main/java/com/project/capstone/club/controller/ClubController.java +++ b/backend/src/main/java/com/project/capstone/club/controller/ClubController.java @@ -1,6 +1,7 @@ package com.project.capstone.club.controller; import com.project.capstone.auth.domain.PrincipalDetails; +import com.project.capstone.book.controller.dto.AddBookRequest; import com.project.capstone.club.controller.dto.ClubCreateRequest; import com.project.capstone.club.controller.dto.ClubResponse; import com.project.capstone.club.service.ClubService; @@ -60,14 +61,22 @@ public ResponseEntity out(@AuthenticationPrincipal PrincipalDetails details, @PutMapping("/delegate") public ResponseEntity delegateManager(@AuthenticationPrincipal PrincipalDetails details, @RequestParam UUID memberId, @RequestParam Long clubId) { - clubService.delegateManager(details, memberId, clubId); + clubService.delegateManager(details.getUserId(), memberId, clubId); return ResponseEntity.ok().body("위임 완료"); } // 멤버 추방하기 @GetMapping("/expel") public ResponseEntity expelMember(@AuthenticationPrincipal PrincipalDetails details, @RequestParam UUID memberId, @RequestParam Long clubId) { - clubService.expelMember(details, memberId, clubId); + clubService.expelMember(details.getUserId(), memberId, clubId); return ResponseEntity.ok().body("추방 완료"); } + + // 대표책 선정하기 + @PostMapping("/book") + public ResponseEntity setBook(@AuthenticationPrincipal PrincipalDetails details, + @RequestBody AddBookRequest request, @RequestParam Long clubId) { + clubService.setBook(details.getUserId(), request, clubId); + return ResponseEntity.ok().body("선정 완료"); + } } diff --git a/backend/src/main/java/com/project/capstone/club/controller/dto/ClubResponse.java b/backend/src/main/java/com/project/capstone/club/controller/dto/ClubResponse.java index 32ba370d47..da9a934fac 100644 --- a/backend/src/main/java/com/project/capstone/club/controller/dto/ClubResponse.java +++ b/backend/src/main/java/com/project/capstone/club/controller/dto/ClubResponse.java @@ -1,6 +1,8 @@ package com.project.capstone.club.controller.dto; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.project.capstone.book.controller.dto.BookResponse; +import com.project.capstone.book.domain.Book; import com.project.capstone.club.domain.Club; import com.project.capstone.club.domain.PublicStatus; import com.project.capstone.post.controller.dto.PostResponse; @@ -12,7 +14,7 @@ public record ClubResponse ( Long id, - Long bookId, + BookResponse book, String topic, String name, LocalDateTime createdAt, @@ -22,7 +24,7 @@ public record ClubResponse ( ) { public ClubResponse(Club club) { - this(club.getId(), club.getBook() == null ? null : club.getBook().getId(), club.getTopic(), club.getName(), club.getCreatedAt(), club.getMaximum(), + this(club.getId(), club.getBook() == null ? null : createBookResponse(club.getBook()), club.getTopic(), club.getName(), club.getCreatedAt(), club.getMaximum(), club.getPublicStatus(), createPostResponseList(club.getPosts())); } @@ -33,4 +35,8 @@ private static List createPostResponseList(List postList) { } return postResponseList; } + + private static BookResponse createBookResponse(Book book) { + return new BookResponse(book); + } } \ No newline at end of file diff --git a/backend/src/main/java/com/project/capstone/club/domain/Club.java b/backend/src/main/java/com/project/capstone/club/domain/Club.java index 49ec27da46..b374ef6ab3 100644 --- a/backend/src/main/java/com/project/capstone/club/domain/Club.java +++ b/backend/src/main/java/com/project/capstone/club/domain/Club.java @@ -23,6 +23,7 @@ @NoArgsConstructor @AllArgsConstructor @Getter +@Setter @Builder @ToString public class Club { @@ -59,6 +60,7 @@ public class Club { private List quizzes = new ArrayList<>(); @ManyToOne + @JoinColumn(name = "book_id") private Book book; public Club(ClubCreateRequest request, UUID memberId) { diff --git a/backend/src/main/java/com/project/capstone/club/domain/ClubRepository.java b/backend/src/main/java/com/project/capstone/club/domain/ClubRepository.java index 56c1815329..1a65fcb65c 100644 --- a/backend/src/main/java/com/project/capstone/club/domain/ClubRepository.java +++ b/backend/src/main/java/com/project/capstone/club/domain/ClubRepository.java @@ -1,5 +1,6 @@ package com.project.capstone.club.domain; +import com.project.capstone.book.domain.Book; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -15,4 +16,8 @@ public interface ClubRepository extends JpaRepository { @Modifying(clearAutomatically = true) @Query("update Club c set c.managerId = :id") void updateManager(UUID id); + + @Modifying(clearAutomatically = true) + @Query("update Club c set c.book = :book where c.id = :id") + void updateBook(Book book, Long id); } diff --git a/backend/src/main/java/com/project/capstone/club/exception/ClubExceptionType.java b/backend/src/main/java/com/project/capstone/club/exception/ClubExceptionType.java index 75fbf8de72..43b7b8788a 100644 --- a/backend/src/main/java/com/project/capstone/club/exception/ClubExceptionType.java +++ b/backend/src/main/java/com/project/capstone/club/exception/ClubExceptionType.java @@ -13,7 +13,8 @@ public enum ClubExceptionType implements ExceptionType { CLUB_NOT_FOUND(NOT_FOUND, 101, "해당 모임을 찾을 수 없습니다."), EXIT_WITHOUT_DELEGATION(BAD_REQUEST, 102, "모임장은 위임 후 모임을 나갈 수 있습니다."), - UNAUTHORIZED_ACTION(UNAUTHORIZED, 103, "모임장만 할 수 있는 기능입니다.") + UNAUTHORIZED_ACTION(UNAUTHORIZED, 103, "모임장만 할 수 있는 기능입니다."), + INVALID_TARGET(BAD_REQUEST, 104, "모임장을 추방 또는 위임할 수 없습니다.") ; private final HttpStatus status; diff --git a/backend/src/main/java/com/project/capstone/club/service/ClubService.java b/backend/src/main/java/com/project/capstone/club/service/ClubService.java index 32b3881b18..5ae6fa1575 100644 --- a/backend/src/main/java/com/project/capstone/club/service/ClubService.java +++ b/backend/src/main/java/com/project/capstone/club/service/ClubService.java @@ -1,6 +1,8 @@ package com.project.capstone.club.service; -import com.project.capstone.auth.domain.PrincipalDetails; +import com.project.capstone.book.controller.dto.AddBookRequest; +import com.project.capstone.book.domain.Book; +import com.project.capstone.book.domain.BookRepository; import com.project.capstone.club.controller.dto.ClubCreateRequest; import com.project.capstone.club.controller.dto.ClubResponse; import com.project.capstone.club.domain.Club; @@ -32,6 +34,7 @@ public class ClubService { private final ClubRepository clubRepository; private final MemberClubRepository memberClubRepository; private final MemberRepository memberRepository; + private final BookRepository bookRepository; public List searchByTopic(String topic) { List clubResponseList = new ArrayList<>(); @@ -84,25 +87,39 @@ public void out(String userId, Long clubId) { } @Transactional - public void delegateManager(PrincipalDetails details, UUID memberId, Long clubId) { - checkIsManagerAndTargetIsClubMember(details, memberId, clubId); + public void delegateManager(String managerId, UUID memberId, Long clubId) { + if (managerId.equals(memberId.toString())) { + throw new ClubException(INVALID_TARGET); + } + checkIsManagerAndTargetIsClubMember(managerId, memberId, clubId); clubRepository.updateManager(memberId); } @Transactional - public void expelMember(PrincipalDetails details, UUID memberId, Long clubId) { - checkIsManagerAndTargetIsClubMember(details, memberId, clubId); + public void expelMember(String managerId, UUID memberId, Long clubId) { + if (managerId.equals(memberId.toString())) { + throw new ClubException(INVALID_TARGET); + } + checkIsManagerAndTargetIsClubMember(managerId, memberId, clubId); memberClubRepository.deleteMemberClubByClub_IdAndMember_Id(clubId, memberId); } - private void checkIsManagerAndTargetIsClubMember(PrincipalDetails details, UUID memberId, Long clubId) { + private void checkIsManagerAndTargetIsClubMember(String managerId, UUID memberId, Long clubId) { + Member member = memberRepository.findMemberById(memberId).orElseThrow( + () -> new MemberException(MEMBER_NOT_FOUND) + ); + Club club = checkIsManager(managerId, clubId); + if (memberClubRepository.findMemberClubByMemberAndClub(member, club).isEmpty()) { + throw new MemberClubException(MEMBERCLUB_NOT_FOUND); + } + } + + private Club checkIsManager(String managerId, Long clubId) { Club club = findClubById(clubId); - if (!club.getManagerId().toString().equals(details.getUserId())) { + if (!club.getManagerId().toString().equals(managerId)) { throw new ClubException(UNAUTHORIZED_ACTION); } - if (memberClubRepository.findMemberClubByMember_IdAndClub_Id(memberId, clubId).isEmpty()) { - throw new MemberClubException(MEMBERCLUB_NOT_FOUND); - } + return club; } private Club findClubById(Long clubId) { @@ -115,4 +132,14 @@ public ClubResponse getClub(Long clubId) { Club club = findClubById(clubId); return new ClubResponse(club); } + + @Transactional + public void setBook(String managerId, AddBookRequest request, Long clubId) { + Club club = checkIsManager(managerId, clubId); + Book book = bookRepository.findBookByIsbn(request.isbn()).orElseGet( + () -> bookRepository.save(new Book(request)) + ); + club.setBook(book); + clubRepository.updateBook(book, clubId); + } } diff --git a/backend/src/main/java/com/project/capstone/member/controller/MemberController.java b/backend/src/main/java/com/project/capstone/member/controller/MemberController.java index f9e7213f5f..1c7a3c9a40 100644 --- a/backend/src/main/java/com/project/capstone/member/controller/MemberController.java +++ b/backend/src/main/java/com/project/capstone/member/controller/MemberController.java @@ -1,7 +1,7 @@ package com.project.capstone.member.controller; import com.project.capstone.auth.domain.PrincipalDetails; -import com.project.capstone.book.controller.AddBookRequest; +import com.project.capstone.book.controller.dto.AddBookRequest; import com.project.capstone.member.controller.dto.MemberResponse; import com.project.capstone.member.controller.dto.MyBookResponse; import com.project.capstone.member.service.MemberService; diff --git a/backend/src/main/java/com/project/capstone/member/service/MemberService.java b/backend/src/main/java/com/project/capstone/member/service/MemberService.java index a704f7d791..6465b63bed 100644 --- a/backend/src/main/java/com/project/capstone/member/service/MemberService.java +++ b/backend/src/main/java/com/project/capstone/member/service/MemberService.java @@ -1,6 +1,6 @@ package com.project.capstone.member.service; -import com.project.capstone.book.controller.AddBookRequest; +import com.project.capstone.book.controller.dto.AddBookRequest; import com.project.capstone.book.domain.Book; import com.project.capstone.book.domain.BookRepository; import com.project.capstone.member.controller.dto.MemberResponse; diff --git a/backend/src/main/java/com/project/capstone/memberclub/domain/MemberClubRepository.java b/backend/src/main/java/com/project/capstone/memberclub/domain/MemberClubRepository.java index 57db974b48..b68f07f4ea 100644 --- a/backend/src/main/java/com/project/capstone/memberclub/domain/MemberClubRepository.java +++ b/backend/src/main/java/com/project/capstone/memberclub/domain/MemberClubRepository.java @@ -1,5 +1,7 @@ package com.project.capstone.memberclub.domain; +import com.project.capstone.club.domain.Club; +import com.project.capstone.member.domain.Member; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -11,4 +13,6 @@ public interface MemberClubRepository extends JpaRepository { void deleteMemberClubByClub_IdAndMember_Id(Long clubId, UUID memberId); Optional findMemberClubByMember_IdAndClub_Id(UUID memberId, Long clubId); List findMemberClubsByMember_Id(UUID memberId); + Optional findMemberClubByMemberAndClub(Member member, Club club); + }