diff --git a/src/main/java/com/cmc/suppin/SuppinApplication.java b/src/main/java/com/cmc/suppin/SuppinApplication.java index 90c0eed..995c389 100644 --- a/src/main/java/com/cmc/suppin/SuppinApplication.java +++ b/src/main/java/com/cmc/suppin/SuppinApplication.java @@ -2,12 +2,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication +@EnableJpaAuditing public class SuppinApplication { - public static void main(String[] args) { - SpringApplication.run(SuppinApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(SuppinApplication.class, args); + } } diff --git a/src/main/java/com/cmc/suppin/event/crawl/converter/CommentConverter.java b/src/main/java/com/cmc/suppin/event/crawl/converter/CommentConverter.java index 2c50b9d..8dd1cdc 100644 --- a/src/main/java/com/cmc/suppin/event/crawl/converter/CommentConverter.java +++ b/src/main/java/com/cmc/suppin/event/crawl/converter/CommentConverter.java @@ -3,15 +3,18 @@ import com.cmc.suppin.event.crawl.domain.Comment; import com.cmc.suppin.event.events.domain.Event; +import java.time.LocalDateTime; + public class CommentConverter { - public static Comment toCommentEntity(String author, String text, String time, String url, Event event) { + public static Comment toCommentEntity(String author, String text, LocalDateTime commentDate, String url, Event event) { return Comment.builder() .author(author) .commentText(text) - .commentDate(time) + .commentDate(commentDate) .url(url) .event(event) .build(); } } + diff --git a/src/main/java/com/cmc/suppin/event/crawl/converter/DateConverter.java b/src/main/java/com/cmc/suppin/event/crawl/converter/DateConverter.java new file mode 100644 index 0000000..62883c4 --- /dev/null +++ b/src/main/java/com/cmc/suppin/event/crawl/converter/DateConverter.java @@ -0,0 +1,47 @@ +package com.cmc.suppin.event.crawl.converter; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DateConverter { + + public static LocalDateTime convertRelativeTime(String relativeTime) { + LocalDateTime now = LocalDateTime.now(); + if (relativeTime.contains("일 전")) { + int days = extractNumber(relativeTime); + return now.minusDays(days); + } else if (relativeTime.contains("시간 전")) { + int hours = extractNumber(relativeTime); + return now.minusHours(hours); + } else if (relativeTime.contains("분 전")) { + int minutes = extractNumber(relativeTime); + return now.minusMinutes(minutes); + } else if (relativeTime.contains("주 전")) { + int weeks = extractNumber(relativeTime); + return now.minusWeeks(weeks); + } else if (relativeTime.contains("개월 전")) { + int months = extractNumber(relativeTime); + return now.minusMonths(months); + } else if (relativeTime.contains("년 전")) { + int years = extractNumber(relativeTime); + return now.minusYears(years); + } + return now; + } + + private static int extractNumber(String relativeTime) { + Pattern pattern = Pattern.compile("\\d+"); + Matcher matcher = pattern.matcher(relativeTime); + if (matcher.find()) { + return Integer.parseInt(matcher.group()); + } + return 0; + } + + public static String formatLocalDateTime(LocalDateTime dateTime) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + return dateTime.format(formatter); + } +} diff --git a/src/main/java/com/cmc/suppin/event/crawl/service/CrawlService.java b/src/main/java/com/cmc/suppin/event/crawl/service/CrawlService.java index 07073c2..3981280 100644 --- a/src/main/java/com/cmc/suppin/event/crawl/service/CrawlService.java +++ b/src/main/java/com/cmc/suppin/event/crawl/service/CrawlService.java @@ -1,6 +1,7 @@ package com.cmc.suppin.event.crawl.service; import com.cmc.suppin.event.crawl.converter.CommentConverter; +import com.cmc.suppin.event.crawl.converter.DateConverter; import com.cmc.suppin.event.crawl.domain.Comment; import com.cmc.suppin.event.crawl.domain.repository.CommentRepository; import com.cmc.suppin.event.events.domain.Event; @@ -21,6 +22,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.HashSet; import java.util.Set; @@ -35,18 +37,12 @@ public class CrawlService { private final MemberRepository memberRepository; public void crawlYoutubeComments(String url, Long eventId, String userId) { - log.info("Start crawling comments for URL: {} by user: {}", url, userId); - Member member = memberRepository.findByUserIdAndStatusNot(userId, UserStatus.DELETED) .orElseThrow(() -> new IllegalArgumentException("Member not found")); - log.info("Member found: {}", member.getId()); - Event event = eventRepository.findByIdAndMemberId(eventId, member.getId()) .orElseThrow(() -> new IllegalArgumentException("Event not found")); - log.info("Event found: {}", event.getId()); - System.setProperty("webdriver.chrome.driver", "src/main/resources/drivers/chromedriver"); ChromeOptions options = new ChromeOptions(); @@ -84,9 +80,9 @@ public void crawlYoutubeComments(String url, Long eventId, String userId) { uniqueComments.add(text); // 엔티티 저장 - Comment comment = CommentConverter.toCommentEntity(author, text, time, url, event); + LocalDateTime actualCommentDate = DateConverter.convertRelativeTime(time); + Comment comment = CommentConverter.toCommentEntity(author, text, actualCommentDate, url, event); commentRepository.save(comment); - log.info("Comment saved: {}", comment.getId()); } } } @@ -97,3 +93,4 @@ public void crawlYoutubeComments(String url, Long eventId, String userId) { } } } + diff --git a/src/main/java/com/cmc/suppin/member/controller/dto/MemberRequestDTO.java b/src/main/java/com/cmc/suppin/member/controller/dto/MemberRequestDTO.java index 871ddd2..379ca53 100644 --- a/src/main/java/com/cmc/suppin/member/controller/dto/MemberRequestDTO.java +++ b/src/main/java/com/cmc/suppin/member/controller/dto/MemberRequestDTO.java @@ -3,6 +3,7 @@ import jakarta.persistence.Id; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,6 +15,9 @@ public class MemberRequestDTO { @NoArgsConstructor @AllArgsConstructor public static class JoinDTO { + + private TermsAgreeDTO termsAgree; + @NotBlank(message = "아이디를 입력해주세요") @Id private String userId; @@ -32,8 +36,27 @@ public static class JoinDTO { @NotBlank(message = "휴대폰 번호를 입력해주세요") private String phone; + private String userType; + @NotBlank(message = "이메일 인증번호를 입력해주세요") private String verificationCode; + + } + + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class TermsAgreeDTO { + @NotNull(message = "14세 이상 동의 여부를 선택해주세요") + private Boolean ageOver14Agree; + + @NotNull(message = "서비스 이용 동의 여부를 선택해주세요") + private Boolean serviceUseAgree; + + @NotNull(message = "개인정보 수집 및 이용 동의 여부를 선택해주세요") + private Boolean personalInfoAgree; + + private Boolean marketingAgree; // 선택 사항 } @Getter diff --git a/src/main/java/com/cmc/suppin/member/converter/MemberConverter.java b/src/main/java/com/cmc/suppin/member/converter/MemberConverter.java index 21727da..201b575 100644 --- a/src/main/java/com/cmc/suppin/member/converter/MemberConverter.java +++ b/src/main/java/com/cmc/suppin/member/converter/MemberConverter.java @@ -3,6 +3,7 @@ import com.cmc.suppin.member.controller.dto.MemberRequestDTO; import com.cmc.suppin.member.controller.dto.MemberResponseDTO; import com.cmc.suppin.member.domain.Member; +import com.cmc.suppin.member.domain.TermsAgree; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; @@ -11,13 +12,24 @@ @Component public class MemberConverter { - public Member toEntity(MemberRequestDTO.JoinDTO request, PasswordEncoder encoder) { + public Member toMemberEntity(MemberRequestDTO.JoinDTO request, PasswordEncoder encoder) { return Member.builder() .userId(request.getUserId()) .name(request.getName()) .password(encoder.encode(request.getPassword())) .email(request.getEmail()) .phoneNumber(request.getPhone()) + .userType(request.getUserType()) + .build(); + } + + public TermsAgree toTermsAgreeEntity(MemberRequestDTO.TermsAgreeDTO termsAgreeDTO, Member member) { + return TermsAgree.builder() + .ageOver14Agree(termsAgreeDTO.getAgeOver14Agree()) + .serviceUseAgree(termsAgreeDTO.getServiceUseAgree()) + .personalInfoAgree(termsAgreeDTO.getPersonalInfoAgree()) + .marketingAgree(termsAgreeDTO.getMarketingAgree()) + .member(member) .build(); } diff --git a/src/main/java/com/cmc/suppin/member/domain/Member.java b/src/main/java/com/cmc/suppin/member/domain/Member.java index 87f0118..d972b99 100644 --- a/src/main/java/com/cmc/suppin/member/domain/Member.java +++ b/src/main/java/com/cmc/suppin/member/domain/Member.java @@ -24,7 +24,7 @@ public class Member extends BaseDateTimeEntity { @Column(name = "member_id") private Long id; - @OneToMany(mappedBy = "member") + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) private List eventList = new ArrayList<>(); @Column(columnDefinition = "VARCHAR(30)", nullable = false) @@ -50,13 +50,15 @@ public class Member extends BaseDateTimeEntity { @Enumerated(EnumType.STRING) private UserStatus status; - // 추가된 생성자 - public Member(String name, String password, String email, String phoneNumber, UserRole role) { - this.name = name; - this.password = password; - this.email = email; - this.phoneNumber = phoneNumber; - this.role = role; + @Column(columnDefinition = "VARCHAR(50)", nullable = false) + private String userType; + + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) + private List termsAgreeList = new ArrayList<>(); + + public void addTermsAgree(TermsAgree termsAgree) { + termsAgree.setMember(this); + this.termsAgreeList.add(termsAgree); } public boolean isDeleted() { diff --git a/src/main/java/com/cmc/suppin/member/domain/TermsAgree.java b/src/main/java/com/cmc/suppin/member/domain/TermsAgree.java new file mode 100644 index 0000000..9d9a9c7 --- /dev/null +++ b/src/main/java/com/cmc/suppin/member/domain/TermsAgree.java @@ -0,0 +1,34 @@ +package com.cmc.suppin.member.domain; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TermsAgree { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + @Column(nullable = false) + private Boolean ageOver14Agree; + + @Column(nullable = false) + private Boolean serviceUseAgree; + + @Column(nullable = false) + private Boolean personalInfoAgree; + + @Column(nullable = true) + private Boolean marketingAgree; +} + diff --git a/src/main/java/com/cmc/suppin/member/service/MemberService.java b/src/main/java/com/cmc/suppin/member/service/MemberService.java index 6940584..f1455a6 100644 --- a/src/main/java/com/cmc/suppin/member/service/MemberService.java +++ b/src/main/java/com/cmc/suppin/member/service/MemberService.java @@ -10,6 +10,7 @@ import com.cmc.suppin.member.converter.MemberConverter; import com.cmc.suppin.member.domain.EmailVerificationToken; import com.cmc.suppin.member.domain.Member; +import com.cmc.suppin.member.domain.TermsAgree; import com.cmc.suppin.member.domain.repository.EmailVerificationTokenRepository; import com.cmc.suppin.member.domain.repository.MemberRepository; import com.cmc.suppin.member.exception.MemberException; @@ -62,9 +63,13 @@ public Member join(MemberRequestDTO.JoinDTO request) { } // DTO를 Entity로 변환 - Member member = memberConverter.toEntity(request, passwordEncoder); + Member member = memberConverter.toMemberEntity(request, passwordEncoder); member.setStatus(UserStatus.ACTIVE); + // 약관 동의 항목 처리 + TermsAgree termsAgree = memberConverter.toTermsAgreeEntity(request.getTermsAgree(), member); + member.addTermsAgree(termsAgree); + // 회원 정보 저장 memberRepository.save(member); @@ -167,7 +172,7 @@ private void saveVerificationToken(String email, String code) { emailVerificationTokenRepository.deleteByEmail(email); emailVerificationTokenRepository.save(verificationToken); } - + private Member getMember(Long memberId) { return memberRepository.findByIdAndStatusNot(memberId, UserStatus.DELETED)