diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock index 1ad87d6..2b1859b 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 34452bd..f96e492 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 3ea33cc..ed80e72 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 0a543fd..685232b 100644 --- a/src/main/java/likelion/MZConnent/api/club/ClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/ClubController.java @@ -3,10 +3,12 @@ import jakarta.validation.Valid; import likelion.MZConnent.domain.member.Member; import likelion.MZConnent.dto.club.request.CreateClubRequest; +import likelion.MZConnent.dto.club.response.ClubDetailResponse; import likelion.MZConnent.dto.club.response.CreateClubResponse; import likelion.MZConnent.dto.club.response.RegionCategoryResponse; import likelion.MZConnent.jwt.principle.UserPrinciple; import likelion.MZConnent.repository.member.MemberRepository; +import likelion.MZConnent.service.club.ClubInfoService; import likelion.MZConnent.service.club.ClubService; import likelion.MZConnent.service.club.RegionCategoryService; import lombok.RequiredArgsConstructor; @@ -24,6 +26,7 @@ @RequiredArgsConstructor public class ClubController { private final ClubService clubService; + private final ClubInfoService clubInfoService; private final MemberRepository memberRepository; private final RegionCategoryService regionCategoryService; @@ -56,4 +59,18 @@ public ResponseEntity joinClub(@PathVariable Long clubId, @AuthenticationPrincip clubService.joinClub(clubId, member); return ResponseEntity.ok(Map.of("message","모임 가입 성공")); } + + @GetMapping("/api/clubs/{clubId}") + public ResponseEntity getClubDetail(@PathVariable Long clubId, @AuthenticationPrincipal UserPrinciple userPrinciple) { + ClubDetailResponse clubDetail; + if (userPrinciple == null) { + clubDetail = clubInfoService.getClubDetail(clubId); + } else { + Member member = memberRepository.findByEmail(userPrinciple.getEmail()) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + clubDetail = clubInfoService.getClubDetail(clubId, member); + } + + return ResponseEntity.ok(clubDetail); + } } diff --git a/src/main/java/likelion/MZConnent/config/SecurityConfig.java b/src/main/java/likelion/MZConnent/config/SecurityConfig.java index f3b0526..905050f 100644 --- a/src/main/java/likelion/MZConnent/config/SecurityConfig.java +++ b/src/main/java/likelion/MZConnent/config/SecurityConfig.java @@ -30,10 +30,11 @@ public class SecurityConfig { "/api/auth/login", "/api/auth/logout", // 회원 "/api/categories/culture", // 문화 "/api/clubs", "/api/clubs/*/join", // 동아리 + "/api/clubs/*", "/swagger", "/swagger-ui.html", "/swagger-ui/**", "/api-docs", "/api-docs/**", "/v3/api-docs/**", //swagger }; private final String[] anonymousUrl = { - "/api/auth/signup", "/api/categories/region" + "/api/auth/signup", "/api/categories/region", "/api/clubs/*" }; diff --git a/src/main/java/likelion/MZConnent/dto/club/LeaderDto.java b/src/main/java/likelion/MZConnent/dto/club/LeaderDto.java new file mode 100644 index 0000000..89f5dab --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/LeaderDto.java @@ -0,0 +1,22 @@ +package likelion.MZConnent.dto.club; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@NoArgsConstructor +public class LeaderDto { + private String username; + private String profileImageUrl; + private List selfIntroductions; + + @Builder + public LeaderDto(String username, String profileImageUrl, List selfIntroductions) { + this.username = username; + this.profileImageUrl = profileImageUrl; + this.selfIntroductions = selfIntroductions; + } +} diff --git a/src/main/java/likelion/MZConnent/dto/club/SelfIntroductionDto.java b/src/main/java/likelion/MZConnent/dto/club/SelfIntroductionDto.java new file mode 100644 index 0000000..aef6082 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/SelfIntroductionDto.java @@ -0,0 +1,18 @@ +package likelion.MZConnent.dto.club; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class SelfIntroductionDto { + private Long cultureCategoryId; + private String name; + + @Builder + public SelfIntroductionDto(Long cultureCategoryId, String name) { + this.cultureCategoryId = cultureCategoryId; + this.name = name; + } +} diff --git a/src/main/java/likelion/MZConnent/dto/club/response/ClubDetailResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/ClubDetailResponse.java new file mode 100644 index 0000000..bdcbe17 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/ClubDetailResponse.java @@ -0,0 +1,55 @@ +package likelion.MZConnent.dto.club.response; + +import likelion.MZConnent.domain.club.AgeRestriction; +import likelion.MZConnent.domain.club.GenderRestriction; +import likelion.MZConnent.dto.club.LeaderDto; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +@Slf4j +@Getter +@NoArgsConstructor +public class ClubDetailResponse { + private Long clubId; + private String title; + private LocalDate meetingDate; + private LocalDateTime createdDate; + private String content; + private GenderRestriction genderRestriction; + private AgeRestriction ageRestriction; + private String cultureImageUrl; + private String cultureName; + private String regionName; + private int currentParticipant; + private int maxParticipant; + private String registrationStatus; + private List leader; + + @Builder + public ClubDetailResponse(Long clubId, String title, LocalDate meetingDate, LocalDateTime createdDate, String content, + GenderRestriction genderRestriction, AgeRestriction ageRestriction, String cultureImageUrl, + String cultureName, String regionName, int currentParticipant, int maxParticipant, + String registrationStatus, List leader) { + this.clubId = clubId; + this.title = title; + this.meetingDate = meetingDate; + this.createdDate = createdDate; + this.content = content; + this.genderRestriction = genderRestriction; + this.ageRestriction = ageRestriction; + this.cultureImageUrl = cultureImageUrl; + this.cultureName = cultureName; + this.regionName = regionName; + this.currentParticipant = currentParticipant; + this.maxParticipant = maxParticipant; + this.registrationStatus = registrationStatus; + this.leader = leader; + } + +} diff --git a/src/main/java/likelion/MZConnent/service/club/ClubInfoService.java b/src/main/java/likelion/MZConnent/service/club/ClubInfoService.java new file mode 100644 index 0000000..cdbba40 --- /dev/null +++ b/src/main/java/likelion/MZConnent/service/club/ClubInfoService.java @@ -0,0 +1,80 @@ +package likelion.MZConnent.service.club; + +import likelion.MZConnent.domain.club.ClubRole; +import likelion.MZConnent.domain.member.Member; +import likelion.MZConnent.dto.club.LeaderDto; +import likelion.MZConnent.dto.club.SelfIntroductionDto; +import likelion.MZConnent.dto.club.response.ClubDetailResponse; +import likelion.MZConnent.repository.club.ClubRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import likelion.MZConnent.domain.club.Club; + +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ClubInfoService { + private final ClubRepository clubRepository; + + // 로그인하지 않은 사용자 + public ClubDetailResponse getClubDetail(Long clubId) { + return buildClubDetailResponse(clubId, null); + } + + // 로그인한 사용자 + public ClubDetailResponse getClubDetail(Long clubId, Member member) { + return buildClubDetailResponse(clubId, member); + } + + private ClubDetailResponse buildClubDetailResponse(Long clubId, Member member) { + Club club = clubRepository.findById(clubId) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 모임입니다.")); + + List leaderResponses = club.getClubMembers().stream() + .filter(cm -> cm.getClubRole() == ClubRole.LEADER) + .map(cm -> LeaderDto.builder() + .username(cm.getMember().getUsername()) + .profileImageUrl(cm.getMember().getProfileImageUrl()) + .selfIntroductions(cm.getMember().getSelfIntroductions().stream() + .map(si -> SelfIntroductionDto.builder() + .cultureCategoryId(si.getCultureCategory().getId()) + .name(si.getCultureCategory().getName()) + .build()) + .collect(Collectors.toList())) + .build()) + .collect(Collectors.toList()); + + String registrationStatus = "신청하기"; + + // 로그인한 사용자가 해당 모임에 가입되어 있는지 확인 + if (member != null) { + boolean isMemberJoined = club.getClubMembers().stream() + .anyMatch(cm -> { + return cm.getMember().getId().equals(member.getId()); + }); + registrationStatus = isMemberJoined ? "신청완료" : "신청하기"; + } + + + return ClubDetailResponse.builder() + .clubId(club.getClubId()) + .title(club.getTitle()) + .meetingDate(club.getMeetingDate()) + .createdDate(club.getCreatedDate()) + .content(club.getContent()) + .genderRestriction(club.getGenderRestriction()) + .ageRestriction(club.getAgeRestriction()) + .cultureImageUrl(club.getCulture().getCultureImageUrl()) + .cultureName(club.getCulture().getName()) + .regionName(club.getRegion().getName()) + .currentParticipant(club.getCurrentParticipant()) + .maxParticipant(club.getMaxParticipant()) + .registrationStatus(registrationStatus) + .leader(leaderResponses) + .build(); + } +} diff --git a/src/main/java/likelion/MZConnent/service/club/ClubService.java b/src/main/java/likelion/MZConnent/service/club/ClubService.java index 80a958a..8e9153e 100644 --- a/src/main/java/likelion/MZConnent/service/club/ClubService.java +++ b/src/main/java/likelion/MZConnent/service/club/ClubService.java @@ -3,7 +3,6 @@ import jakarta.transaction.Transactional; 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; @@ -36,7 +35,7 @@ public CreateClubResponse createClub(CreateClubRequest request, Member member) { .meetingDate(request.getMeetingDate()) .createdDate(LocalDateTime.now()) .maxParticipant(request.getMaxParticipant()) - .currentParticipant(0) + .currentParticipant(1) .content(request.getContent()) .genderRestriction(request.getGenderRestriction()) .ageRestriction(request.getAgeRestriction())