diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock index 3b99159..73d8a67 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.lock and b/.gradle/8.8/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock index 550b45c..296485c 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.lock and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 36d1f71..e57fe59 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/src/main/java/likelion/MZConnent/api/club/ClubController.java b/src/main/java/likelion/MZConnent/api/club/ClubController.java index 64349cb..0a543fd 100644 --- a/src/main/java/likelion/MZConnent/api/club/ClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/ClubController.java @@ -17,6 +17,8 @@ import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; +import java.util.Map; + @Slf4j @RestController @RequiredArgsConstructor @@ -46,4 +48,12 @@ public ResponseEntity getAllRegionCategories() { log.info("전체 지역 카테고리: {}", all.getRegionCategories()); return ResponseEntity.ok(all); } + + @PostMapping("/api/clubs/{clubId}/join") + public ResponseEntity joinClub(@PathVariable Long clubId, @AuthenticationPrincipal UserPrinciple userPrinciple) { + String email = userPrinciple.getEmail(); + Member member = memberRepository.findByEmail(email).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + clubService.joinClub(clubId, member); + return ResponseEntity.ok(Map.of("message","모임 가입 성공")); + } } diff --git a/src/main/java/likelion/MZConnent/config/SecurityConfig.java b/src/main/java/likelion/MZConnent/config/SecurityConfig.java index d1282d1..f3b0526 100644 --- a/src/main/java/likelion/MZConnent/config/SecurityConfig.java +++ b/src/main/java/likelion/MZConnent/config/SecurityConfig.java @@ -29,7 +29,7 @@ public class SecurityConfig { private final String[] permitAllUrl = {"/error", "/api/auth/login", "/api/auth/logout", // 회원 "/api/categories/culture", // 문화 - "/api/clubs", // 동아리 + "/api/clubs", "/api/clubs/*/join", // 동아리 "/swagger", "/swagger-ui.html", "/swagger-ui/**", "/api-docs", "/api-docs/**", "/v3/api-docs/**", //swagger }; private final String[] anonymousUrl = { diff --git a/src/main/java/likelion/MZConnent/domain/club/Club.java b/src/main/java/likelion/MZConnent/domain/club/Club.java index f0bdfe0..91a6558 100644 --- a/src/main/java/likelion/MZConnent/domain/club/Club.java +++ b/src/main/java/likelion/MZConnent/domain/club/Club.java @@ -7,6 +7,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import java.time.LocalDate; import java.time.LocalDateTime; @@ -14,6 +15,7 @@ @Entity @Getter +@Setter @NoArgsConstructor public class Club { @Id @@ -48,10 +50,6 @@ public class Club { @Column(nullable = false) private String status; - @ManyToOne - @JoinColumn(name = "memberId", nullable = false) - private Member member; - @ManyToOne @JoinColumn(name = "cultureId", nullable = false) private Culture culture; @@ -60,7 +58,7 @@ public class Club { @JoinColumn(name = "regionId", nullable = false) private RegionCategory region; - @OneToMany(mappedBy = "club") + @OneToMany(mappedBy = "club", cascade = CascadeType.ALL) private List chats; @OneToMany(mappedBy = "club") @@ -68,7 +66,7 @@ public class Club { @Builder - public Club(String title, LocalDate meetingDate, LocalDateTime createdDate, String content, GenderRestriction genderRestriction, AgeRestriction ageRestriction, int currentParticipant, int maxParticipant, String status, Member member, Culture culture, RegionCategory region) { + public Club(String title, LocalDate meetingDate, LocalDateTime createdDate, String content, GenderRestriction genderRestriction, AgeRestriction ageRestriction, int currentParticipant, int maxParticipant, String status, Culture culture, RegionCategory region) { this.title = title; this.meetingDate = meetingDate; this.createdDate = createdDate; @@ -78,7 +76,6 @@ public Club(String title, LocalDate meetingDate, LocalDateTime createdDate, Stri this.currentParticipant = currentParticipant; this.maxParticipant = maxParticipant; this.status = status; - this.member = member; this.culture = culture; this.region = region; } diff --git a/src/main/java/likelion/MZConnent/domain/member/Member.java b/src/main/java/likelion/MZConnent/domain/member/Member.java index 05952c5..206c7d3 100644 --- a/src/main/java/likelion/MZConnent/domain/member/Member.java +++ b/src/main/java/likelion/MZConnent/domain/member/Member.java @@ -60,8 +60,6 @@ public class Member { @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) private List selfIntroductions = new ArrayList<>(); - @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) - private List clubs; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) private List reviewComments; diff --git a/src/main/java/likelion/MZConnent/repository/club/ClubMemberRepository.java b/src/main/java/likelion/MZConnent/repository/club/ClubMemberRepository.java index 884bcba..419958c 100644 --- a/src/main/java/likelion/MZConnent/repository/club/ClubMemberRepository.java +++ b/src/main/java/likelion/MZConnent/repository/club/ClubMemberRepository.java @@ -1,9 +1,14 @@ package likelion.MZConnent.repository.club; +import likelion.MZConnent.domain.club.Club; import likelion.MZConnent.domain.club.ClubMember; +import likelion.MZConnent.domain.member.Member; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface ClubMemberRepository extends JpaRepository { + Optional findByClubAndMember(Club club, Member member); } diff --git a/src/main/java/likelion/MZConnent/service/club/ClubService.java b/src/main/java/likelion/MZConnent/service/club/ClubService.java index 03e8c14..c0a7b35 100644 --- a/src/main/java/likelion/MZConnent/service/club/ClubService.java +++ b/src/main/java/likelion/MZConnent/service/club/ClubService.java @@ -1,11 +1,9 @@ package likelion.MZConnent.service.club; import jakarta.transaction.Transactional; -import likelion.MZConnent.domain.club.Club; -import likelion.MZConnent.domain.club.ClubMember; -import likelion.MZConnent.domain.club.ClubRole; -import likelion.MZConnent.domain.club.RegionCategory; +import likelion.MZConnent.domain.club.*; import likelion.MZConnent.domain.culture.Culture; +import likelion.MZConnent.domain.member.Gender; import likelion.MZConnent.domain.member.Member; import likelion.MZConnent.dto.club.request.CreateClubRequest; import likelion.MZConnent.dto.club.response.CreateClubResponse; @@ -79,4 +77,38 @@ public CreateClubResponse createClub(CreateClubRequest request, Member member) { ); } + @Transactional + public void joinClub(Long clubId, Member member) { + Club club = clubRepository.findById(clubId) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 클럽입니다.")); + + validateJoinClub(club, member); + + ClubMember clubMember = ClubMember.builder() + .club(club) + .member(member) + .clubRole(ClubRole.MEMBER) + .build(); + + clubMemberRepository.save(clubMember); + club.setCurrentParticipant(club.getCurrentParticipant() + 1); + } + + private void validateJoinClub(Club club, Member member) { + if (clubMemberRepository.findByClubAndMember(club, member).isPresent()) { + throw new IllegalArgumentException("이미 가입한 클럽입니다."); + } + + if (club.getCurrentParticipant() >= club.getMaxParticipant()) { + throw new IllegalArgumentException("정원이 초과되어 가입할 수 없습니다."); + } + + if (club.getAgeRestriction() != AgeRestriction.ALL && !(club.getAgeRestriction().equals(member.getAge()))) { + throw new IllegalArgumentException("나이 제한으로 가입할 수 없습니다."); + } + + if (club.getGenderRestriction() != GenderRestriction.ALL && !(club.getGenderRestriction().equals(member.getGender()))) { + throw new IllegalArgumentException("성별 제한으로 가입할 수 없습니다."); + } + } }