From f4db0aab4331bafc993e03befb5136edc00b8a81 Mon Sep 17 00:00:00 2001 From: oosedus Date: Thu, 25 Jul 2024 02:59:31 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 ++ .../MZConnent/api/club/ClubController.java | 43 ++++++++++ .../MZConnent/config/SecurityConfig.java | 1 + .../dto/club/request/CreateClubRequest.java | 41 ++++++++++ .../dto/club/response/CreateClubResponse.java | 40 +++++++++ .../MZConnent/service/club/ClubService.java | 82 +++++++++++++++++++ 6 files changed, 213 insertions(+) create mode 100644 .gitignore create mode 100644 src/main/java/likelion/MZConnent/api/club/ClubController.java create mode 100644 src/main/java/likelion/MZConnent/dto/club/request/CreateClubRequest.java create mode 100644 src/main/java/likelion/MZConnent/dto/club/response/CreateClubResponse.java create mode 100644 src/main/java/likelion/MZConnent/service/club/ClubService.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f51a4e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +build +.idea +.gradle +src/main/resources/application-secret.yml +src/main/resources/application-local.yml +.DS_Store \ No newline at end of file diff --git a/src/main/java/likelion/MZConnent/api/club/ClubController.java b/src/main/java/likelion/MZConnent/api/club/ClubController.java new file mode 100644 index 0000000..35d5883 --- /dev/null +++ b/src/main/java/likelion/MZConnent/api/club/ClubController.java @@ -0,0 +1,43 @@ +package likelion.MZConnent.api.club; + +import jakarta.validation.Valid; +import likelion.MZConnent.domain.member.Member; +import likelion.MZConnent.dto.club.request.CreateClubRequest; +import likelion.MZConnent.dto.club.response.CreateClubResponse; +import likelion.MZConnent.dto.member.MemberInfoDto; +import likelion.MZConnent.jwt.principle.UserPrinciple; +import likelion.MZConnent.repository.member.MemberRepository; +import likelion.MZConnent.service.club.ClubService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class ClubController { + private final ClubService clubService; + private final MemberRepository memberRepository; + + @PostMapping("/api/clubs") + public ResponseEntity createClub(@Valid @RequestBody CreateClubRequest request, @AuthenticationPrincipal UserPrinciple userPrinciple, BindingResult bindingResult) { + + if (bindingResult.hasErrors()) { + String errorMessage = bindingResult.getAllErrors().get(0).getDefaultMessage(); + throw new IllegalArgumentException(errorMessage); + } + + String email = userPrinciple.getEmail(); + Member member = memberRepository.findByEmail(email).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + + CreateClubResponse response = clubService.createClub(request, member); + return ResponseEntity.ok(response); + } +} diff --git a/src/main/java/likelion/MZConnent/config/SecurityConfig.java b/src/main/java/likelion/MZConnent/config/SecurityConfig.java index cdf8cfb..935bcee 100644 --- a/src/main/java/likelion/MZConnent/config/SecurityConfig.java +++ b/src/main/java/likelion/MZConnent/config/SecurityConfig.java @@ -29,6 +29,7 @@ public class SecurityConfig { private final String[] permitAllUrl = {"/error", "/api/auth/login", "/api/auth/logout", // 회원 "/api/categories/culture", // 문화 + "/api/clubs", // 동아리 "/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/dto/club/request/CreateClubRequest.java b/src/main/java/likelion/MZConnent/dto/club/request/CreateClubRequest.java new file mode 100644 index 0000000..e52ee81 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/request/CreateClubRequest.java @@ -0,0 +1,41 @@ +package likelion.MZConnent.dto.club.request; + +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import likelion.MZConnent.domain.club.AgeRestriction; +import likelion.MZConnent.domain.club.GenderRestriction; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CreateClubRequest { + private Long cultureId; + private Long regionId; + + @NotNull + @Size(min = 2, max = 255, message = "제목은 2자 이상, 255자 이하여야합니다.") + private String title; + + @NotNull + private LocalDate meetingDate; + + @NotNull + private int maxParticipant; + + @NotNull + private String content; + + @NotNull + @Enumerated(EnumType.STRING) + private GenderRestriction genderRestriction; + + @NotNull + @Enumerated(EnumType.STRING) + private AgeRestriction ageRestriction; +} diff --git a/src/main/java/likelion/MZConnent/dto/club/response/CreateClubResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/CreateClubResponse.java new file mode 100644 index 0000000..d34d397 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/CreateClubResponse.java @@ -0,0 +1,40 @@ +package likelion.MZConnent.dto.club.response; + +import likelion.MZConnent.domain.club.AgeRestriction; +import likelion.MZConnent.domain.club.GenderRestriction; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class CreateClubResponse { + private Long cultureId; + private Long regionId; + private String title; + private LocalDate meetingDate; + private LocalDateTime createdDate; + private int maxParticipant; + private String content; + private GenderRestriction genderRestriction; + private AgeRestriction ageRestriction; + private String status; + + @Builder + public CreateClubResponse(Long cultureId, Long regionId, String title, LocalDate meetingDate, LocalDateTime createdDate, int maxParticipant, String content, GenderRestriction genderRestriction, AgeRestriction ageRestriction, String status) { + this.cultureId = cultureId; + this.regionId = regionId; + this.title = title; + this.meetingDate = meetingDate; + this.createdDate = createdDate; + this.maxParticipant = maxParticipant; + this.content = content; + this.genderRestriction = genderRestriction; + this.ageRestriction = ageRestriction; + this.status = status; + } +} diff --git a/src/main/java/likelion/MZConnent/service/club/ClubService.java b/src/main/java/likelion/MZConnent/service/club/ClubService.java new file mode 100644 index 0000000..03e8c14 --- /dev/null +++ b/src/main/java/likelion/MZConnent/service/club/ClubService.java @@ -0,0 +1,82 @@ +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.culture.Culture; +import likelion.MZConnent.domain.member.Member; +import likelion.MZConnent.dto.club.request.CreateClubRequest; +import likelion.MZConnent.dto.club.response.CreateClubResponse; +import likelion.MZConnent.repository.club.ClubMemberRepository; +import likelion.MZConnent.repository.club.ClubRepository; +import likelion.MZConnent.repository.club.RegionCategoryRepository; +import likelion.MZConnent.repository.culture.CultureRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +@Service +@RequiredArgsConstructor +public class ClubService { + private final CultureRepository cultureRepository; + private final RegionCategoryRepository regionCategoryRepository; + private final ClubRepository clubRepository; + private final ClubMemberRepository clubMemberRepository; + + + @Transactional + public CreateClubResponse createClub(CreateClubRequest request, Member member) { + + Culture culture = cultureRepository.findById(request.getCultureId()).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 문화입니다.")); + RegionCategory region = regionCategoryRepository.findById(request.getRegionId()).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 지역입니다.")); + + Club club = Club.builder() + .title(request.getTitle()) + .meetingDate(request.getMeetingDate()) + .createdDate(LocalDateTime.now()) + .maxParticipant(request.getMaxParticipant()) + .currentParticipant(0) + .content(request.getContent()) + .genderRestriction(request.getGenderRestriction()) + .ageRestriction(request.getAgeRestriction()) + .culture(culture) + .region(region) + .status("OPEN") + .build(); + + try { + clubRepository.save(club); + } catch (Exception e) { + throw new IllegalArgumentException("클럽 생성에 실패했습니다."); + } + + ClubMember clubMember = ClubMember.builder() + .club(club) + .member(member) + .clubRole(ClubRole.LEADER) + .build(); + + try { + clubMemberRepository.save(clubMember); + } catch (Exception e) { + throw new IllegalArgumentException("클럽 멤버 생성에 실패했습니다."); + } + + return new CreateClubResponse( + club.getCulture().getCultureId(), + club.getRegion().getRegionId(), + club.getTitle(), + club.getMeetingDate(), + club.getCreatedDate(), + club.getMaxParticipant(), + club.getContent(), + club.getGenderRestriction(), + club.getAgeRestriction(), + club.getStatus() + ); + } + +}