diff --git a/src/main/java/org/sopt/makers/internal/community/service/CommunityPostModifier.java b/src/main/java/org/sopt/makers/internal/community/service/CommunityPostModifier.java new file mode 100644 index 00000000..e6e8449c --- /dev/null +++ b/src/main/java/org/sopt/makers/internal/community/service/CommunityPostModifier.java @@ -0,0 +1,33 @@ +package org.sopt.makers.internal.community.service; + +import lombok.RequiredArgsConstructor; +import org.sopt.makers.internal.community.controller.dto.request.PostSaveRequest; +import org.sopt.makers.internal.community.repository.CommunityPostRepository; +import org.sopt.makers.internal.domain.Member; +import org.sopt.makers.internal.community.domain.CommunityPost; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; + +@Component +@RequiredArgsConstructor +public class CommunityPostModifier { + + private final CommunityPostRepository communityPostRepository; + + // CREATE + + public CommunityPost createCommunityPost(Member member, PostSaveRequest request) { + + return communityPostRepository.save(CommunityPost.builder() + .member(member) + .categoryId(request.categoryId()) + .title(request.title()) + .content(request.content()) + .images(request.images()) + .isQuestion(request.isQuestion()) + .isBlindWriter(request.isBlindWriter()) + .comments(new ArrayList<>()) + .build()); + } +} diff --git a/src/main/java/org/sopt/makers/internal/community/service/CommunityPostService.java b/src/main/java/org/sopt/makers/internal/community/service/CommunityPostService.java index 811e82fc..13a39109 100644 --- a/src/main/java/org/sopt/makers/internal/community/service/CommunityPostService.java +++ b/src/main/java/org/sopt/makers/internal/community/service/CommunityPostService.java @@ -7,12 +7,17 @@ import org.sopt.makers.internal.common.MakersMemberId; import org.sopt.makers.internal.common.SlackMessageUtil; import org.sopt.makers.internal.community.controller.dto.request.PostSaveRequest; -import org.sopt.makers.internal.community.domain.AnonymousProfileImage; import org.sopt.makers.internal.community.domain.CommunityPost; import org.sopt.makers.internal.community.domain.CommunityPostLike; import org.sopt.makers.internal.community.repository.CommunityPostLikeRepository; import org.sopt.makers.internal.community.repository.CommunityPostRepository; +import org.sopt.makers.internal.community.repository.anonymous.AnonymousNicknameRepository; +import org.sopt.makers.internal.community.repository.anonymous.AnonymousPostProfileRepository; import org.sopt.makers.internal.community.repository.category.CategoryRepository; +import org.sopt.makers.internal.community.service.anonymous.AnonymousNicknameRetriever; +import org.sopt.makers.internal.community.service.anonymous.AnonymousPostProfileModifier; +import org.sopt.makers.internal.community.service.anonymous.AnonymousPostProfileService; +import org.sopt.makers.internal.community.service.anonymous.AnonymousProfileImageRetriever; import org.sopt.makers.internal.domain.Member; import org.sopt.makers.internal.domain.community.*; import org.sopt.makers.internal.dto.community.*; @@ -21,6 +26,7 @@ import org.sopt.makers.internal.external.slack.SlackClient; import org.sopt.makers.internal.mapper.CommunityMapper; import org.sopt.makers.internal.mapper.CommunityResponseMapper; +import org.sopt.makers.internal.member.service.MemberRetriever; import org.sopt.makers.internal.repository.MemberRepository; import org.sopt.makers.internal.repository.PostRepository; import org.sopt.makers.internal.repository.community.*; @@ -34,7 +40,6 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; -import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -45,6 +50,16 @@ @Service public class CommunityPostService { + private final AnonymousPostProfileService anonymousPostProfileService; + + private final CommunityPostModifier communityPostModifier; + + private final AnonymousPostProfileModifier anonymousPostProfileModifier; + private final AnonymousProfileImageRetriever anonymousProfileImageRetriever; + private final AnonymousNicknameRetriever anonymousNicknameRetriever; + + private final MemberRetriever memberRetriever; + private final CommunityCommentRepository communityCommentRepository; private final CommunityPostLikeRepository communityPostLikeRepository; private final CommunityPostRepository communityPostRepository; @@ -107,38 +122,11 @@ public CommunityPostMemberVo getPostById(Long memberId, Long postId, Boolean isB @Transactional public PostSaveResponse createPost(Long writerId, PostSaveRequest request) { - Member member = MemberServiceUtil.findMemberById(memberRepository, writerId); - CommunityPost post = communityPostRepository.save(CommunityPost.builder() - .member(member) - .categoryId(request.categoryId()) - .title(request.title()) - .content(request.content()) - .hits(0) - .images(request.images()) - .isQuestion(request.isQuestion()) - .isBlindWriter(request.isBlindWriter()) - .comments(new ArrayList<>()) - .build()); - - if (request.isBlindWriter()) { - List lastFourAnonymousPostProfiles = anonymousPostProfileRepository.findTop4ByOrderByCreatedAtDesc(); - List lastFiftyAnonymousNickname = anonymousPostProfileRepository.findTop50ByOrderByCreatedAtDesc(); - List usedAnonymousProfileImages = lastFourAnonymousPostProfiles.stream() - .map(anonymousProfile -> anonymousProfile.getProfileImg().getId()).toList(); - List usedAnonymousNicknames = lastFiftyAnonymousNickname.stream() - .map(AnonymousPostProfile::getNickname).toList(); - - AnonymousProfileImage anonymousProfileImg = anonymousProfileImageService.getRandomProfileImage(usedAnonymousProfileImages); - AnonymousNickname anonymousNickname = AnonymousNicknameServiceUtil.getRandomNickname(anonymousNicknameRepository, usedAnonymousNicknames); - anonymousPostProfileRepository.save(AnonymousPostProfile.builder() - .member(member) - .nickname(anonymousNickname) - .profileImg(anonymousProfileImg) - .communityPost(post) - .build() - ); - } + Member member = memberRetriever.findMemberById(writerId); + CommunityPost post = communityPostModifier.createCommunityPost(member, request); + anonymousPostProfileService.createAnonymousPostProfile(request.isBlindWriter(), member, post); + // 비메이커스가 글 작성시 슬랙 발송 if (!MakersMemberId.getMakersMember().contains(member.getId()) && Objects.equals(activeProfile, "prod")) { val slackRequest = createPostSlackRequest(post.getId()); slackClient.postNotMakersMessage(slackRequest.toString()); diff --git a/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousNicknameRetriever.java b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousNicknameRetriever.java new file mode 100644 index 00000000..aca7b7ff --- /dev/null +++ b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousNicknameRetriever.java @@ -0,0 +1,24 @@ +package org.sopt.makers.internal.community.service.anonymous; + +import lombok.RequiredArgsConstructor; +import org.sopt.makers.internal.community.repository.anonymous.AnonymousNicknameRepository; +import org.sopt.makers.internal.domain.community.AnonymousNickname; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class AnonymousNicknameRetriever { + + private final AnonymousNicknameRepository anonymousNicknameRepository; + + public AnonymousNickname findRandomAnonymousNickname(List recentUsedAnonymousNicknames) { + if (recentUsedAnonymousNicknames.isEmpty()) { + return anonymousNicknameRepository.findRandomOne(); + } + + return anonymousNicknameRepository.findRandomOneByIdNotIn( + recentUsedAnonymousNicknames.stream().map(AnonymousNickname::getId).toList()); + } +} diff --git a/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileModifier.java b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileModifier.java new file mode 100644 index 00000000..e4a2c230 --- /dev/null +++ b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileModifier.java @@ -0,0 +1,28 @@ +package org.sopt.makers.internal.community.service.anonymous; + +import lombok.RequiredArgsConstructor; +import org.sopt.makers.internal.community.domain.AnonymousProfileImage; +import org.sopt.makers.internal.community.domain.CommunityPost; +import org.sopt.makers.internal.community.repository.anonymous.AnonymousPostProfileRepository; +import org.sopt.makers.internal.domain.Member; +import org.sopt.makers.internal.domain.community.AnonymousNickname; +import org.sopt.makers.internal.domain.community.AnonymousPostProfile; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class AnonymousPostProfileModifier { + + private final AnonymousPostProfileRepository anonymousPostProfileRepository; + + public void createAnonymousPostProfile(Member member, AnonymousNickname anonymousNickname, AnonymousProfileImage anonymousProfileImage, CommunityPost communityPost) { + + anonymousPostProfileRepository.save(AnonymousPostProfile.builder() + .member(member) + .nickname(anonymousNickname) + .profileImg(anonymousProfileImage) + .communityPost(communityPost) + .build() + ); + } +} diff --git a/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileRetriever.java b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileRetriever.java new file mode 100644 index 00000000..5a11466b --- /dev/null +++ b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileRetriever.java @@ -0,0 +1,20 @@ +package org.sopt.makers.internal.community.service.anonymous; + +import lombok.RequiredArgsConstructor; +import org.sopt.makers.internal.community.repository.anonymous.AnonymousPostProfileRepository; +import org.sopt.makers.internal.domain.community.AnonymousPostProfile; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class AnonymousPostProfileRetriever { + + private final AnonymousPostProfileRepository anonymousPostProfileRepository; + + public List getTopByOrderByCreatedAt(int limit) { + + return anonymousPostProfileRepository.findTopByOrderByIdDescWithLimit(limit); + } +} diff --git a/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileService.java b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileService.java new file mode 100644 index 00000000..a97b29f8 --- /dev/null +++ b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousPostProfileService.java @@ -0,0 +1,36 @@ +package org.sopt.makers.internal.community.service.anonymous; + +import lombok.RequiredArgsConstructor; +import org.sopt.makers.internal.community.domain.AnonymousProfileImage; +import org.sopt.makers.internal.community.domain.CommunityPost; +import org.sopt.makers.internal.domain.Member; +import org.sopt.makers.internal.domain.community.AnonymousNickname; +import org.sopt.makers.internal.domain.community.AnonymousPostProfile; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class AnonymousPostProfileService { + + private final AnonymousPostProfileModifier anonymousPostProfileModifier; + private final AnonymousPostProfileRetriever anonymousPostProfileRetriever; + private final AnonymousProfileImageRetriever anonymousProfileImageRetriever; + private final AnonymousNicknameRetriever anonymousNicknameRetriever; + + public void createAnonymousPostProfile(Boolean isBlindWriter, Member member, CommunityPost post) { + if (isBlindWriter) { + List lastFourAnonymousPostProfiles = anonymousPostProfileRetriever.getTopByOrderByCreatedAt(4); + List lastFiftyAnonymousPostProfiles = anonymousPostProfileRetriever.getTopByOrderByCreatedAt(50); + List usedAnonymousProfileImageIds = lastFourAnonymousPostProfiles.stream() + .map(anonymousProfile -> anonymousProfile.getProfileImg().getId()).toList(); + List usedAnonymousNicknames = lastFiftyAnonymousPostProfiles.stream() + .map(AnonymousPostProfile::getNickname).toList(); + + AnonymousNickname anonymousNickname = anonymousNicknameRetriever.findRandomAnonymousNickname(usedAnonymousNicknames); + AnonymousProfileImage anonymousProfileImage = anonymousProfileImageRetriever.getAnonymousProfileImage(usedAnonymousProfileImageIds); + anonymousPostProfileModifier.createAnonymousPostProfile(member, anonymousNickname, anonymousProfileImage, post); + } + } +} diff --git a/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousProfileImageRetriever.java b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousProfileImageRetriever.java new file mode 100644 index 00000000..76b83fc9 --- /dev/null +++ b/src/main/java/org/sopt/makers/internal/community/service/anonymous/AnonymousProfileImageRetriever.java @@ -0,0 +1,43 @@ +package org.sopt.makers.internal.community.service.anonymous; + +import lombok.RequiredArgsConstructor; +import org.sopt.makers.internal.community.domain.AnonymousProfileImage; +import org.sopt.makers.internal.community.repository.anonymous.AnonymousProfileImageRepository; +import org.sopt.makers.internal.exception.BusinessLogicException; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class AnonymousProfileImageRetriever { + + private final AnonymousProfileImageRepository anonymousProfileImageRepository; + + private static final Map profileImageMap = new HashMap<>(); + private final static Long MAKERS_LOGO_IMAGE_ID = 6L; + + @PostConstruct + public void initializeProfileImageMap() { + List anonymousProfileImages = anonymousProfileImageRepository.findAllByIdNot(MAKERS_LOGO_IMAGE_ID); + for (AnonymousProfileImage image : anonymousProfileImages) { + profileImageMap.put(image.getId(), image); + } + } + + public AnonymousProfileImage getAnonymousProfileImage(List recentUsedAnonymousProfileImageIds) { + if (recentUsedAnonymousProfileImageIds.isEmpty()) { + long randomImageNumber = (long) ((Math.random() * 5) + 1); + return profileImageMap.get(randomImageNumber); + } + + return profileImageMap.keySet().stream() + .filter(id -> !recentUsedAnonymousProfileImageIds.contains(id)) + .findFirst() + .map(profileImageMap::get) + .orElseThrow(() -> new BusinessLogicException("존재하지 않는 익명 프로필 ID 입니다.")); + } +}