Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.midas.shootpointer.domain.highlight.entity.HighlightEntity;
import com.midas.shootpointer.domain.highlight.helper.HighlightHelper;
import com.midas.shootpointer.domain.member.entity.Member;
import com.midas.shootpointer.domain.post.dto.request.PostRequest;
import com.midas.shootpointer.domain.post.dto.response.*;
import com.midas.shootpointer.domain.post.entity.PostDocument;
import com.midas.shootpointer.domain.post.helper.elastic.PostElasticSearchHelper;
Expand All @@ -29,86 +30,86 @@ public class PostManager {
private PostElasticSearchHelper postElasticSearchHelper;

@Transactional
public Long save(Member member, PostEntity postEntity, UUID highlightId){
public Long save(Member member, PostRequest request) {
/**
* 1.ν•˜μ΄λΌμ΄νŠΈ μ˜μƒ 뢈러였기.
*/
HighlightEntity highlightEntity=highlightHelper.findHighlightByHighlightId(highlightId);
HighlightEntity highlightEntity = highlightHelper.findHighlightByHighlightId(request.getHighlightId());

/*
* 2. Highlight URL이 μœ μ €μ˜ μ˜μƒμœΌλ‘œ 일치 μ—¬λΆ€.
*/
postHelper.isValidateHighlightId(member,highlightId);
postHelper.isValidateHighlightId(member, request.getHighlightId());

/*
* 3. ν•΄μ‹œνƒœκ·Έκ°€ μ˜¬λ°”λ₯Έ μ§€ μ—¬λΆ€.
*/
postHelper.isValidPostHashTag(postEntity.getHashTag());
postHelper.isValidPostHashTag(request.getHashTag());

/**
* 4. ν•˜μ΄λΌμ΄νŠΈ μ €μž₯.
*/
postEntity.setHighlight(highlightEntity);
PostEntity savedPostEntity = postHelper.save(request, member, highlightEntity);

/*
* 5. κ²Œμ‹œλ¬Ό ElasticSearch Document μ €μž₯ (쑰건뢀).
*/
if (postElasticSearchHelper != null) {
postElasticSearchHelper.createPostDocument(postEntity);
postElasticSearchHelper.createPostDocument(savedPostEntity);
}


return postHelper.save(postEntity).getPostId();
return savedPostEntity.getPostId();
}

@Transactional
public Long update(PostEntity newPost,Member member,Long postId){
UUID highlightId=newPost.getHighlight().getHighlightId();
public Long update(PostRequest request, Member member, Long postId) {
UUID highlightId = request.getHighlightId();
/**
* 1. κ²Œμ‹œλ¬Όμ΄ μ‘΄μž¬ν•˜λŠ” μ§€ μ—¬λΆ€
*/
PostEntity existedPost=postHelper.findPostByPostId(postId);
PostEntity existedPost = postHelper.findPostByPostId(postId);

/**
* 2. κ²Œμ‹œλ¬Όμ΄ λ©€λ²„μ˜ κ²Œμ‹œλ¬ΌμΈμ§€ 확인
*/
postHelper.isMembersPost(existedPost,member);
postHelper.isMembersPost(existedPost, member);

/**
* 3.ν•˜μ΄λΌμ΄νŠΈ μ˜μƒ 뢈러였기.
*/
HighlightEntity highlightEntity=highlightHelper.findHighlightByHighlightId(highlightId);
HighlightEntity highlightEntity = highlightHelper.findHighlightByHighlightId(highlightId);

/**
* 4. Highlight URL이 μœ μ €μ˜ μ˜μƒμœΌλ‘œ 일치 μ—¬λΆ€.
*/
postHelper.isValidateHighlightId(member,highlightId);
postHelper.isValidateHighlightId(member, highlightId);

/**
* 5. ν•΄μ‹œνƒœκ·Έκ°€ μ˜¬λ°”λ₯Έ μ§€ μ—¬λΆ€.
*/
postHelper.isValidPostHashTag(newPost.getHashTag());
postHelper.isValidPostHashTag(request.getHashTag());

/**
/**
* 6. μˆ˜μ • μ§„ν–‰
*/
existedPost=postHelper.update(newPost,existedPost,highlightEntity);
existedPost = postHelper.update(request, existedPost, highlightEntity);

return existedPost.getPostId();
}

@Transactional
public Long delete(Long postId,Member member){
public Long delete(Long postId, Member member) {
/**
* 1. κ²Œμ‹œλ¬Όμ΄ μ‘΄μž¬ν•˜λŠ” μ§€ μ—¬λΆ€
*/
PostEntity postEntity=postHelper.findPostByPostId(postId);
PostEntity postEntity = postHelper.findPostByPostId(postId);


/**
* 2. κ²Œμ‹œλ¬Όμ΄ λ©€λ²„μ˜ κ²Œμ‹œλ¬ΌμΈμ§€ 확인
*/
postHelper.isMembersPost(postEntity,member);
postHelper.isMembersPost(postEntity, member);

/**
* 3. 논리적 μ‚­μ œ 처리
Expand All @@ -118,49 +119,49 @@ public Long delete(Long postId,Member member){
}

@Transactional(readOnly = true)
public PostResponse singleRead(Long postId){
public PostResponse singleRead(Long postId) {
/**
* 1. postMapper : entity -> dto λ³€ν™˜.
*/
return postMapper.entityToDto(postHelper.findPostByPostId(postId));
}

@Transactional(readOnly = true)
public PostListResponse multiRead(Long lastPostId,String type,int size){
public PostListResponse multiRead(Long lastPostId, String type, int size) {
/**
* 1. type μ˜¬λ°”λ₯Έμ§€ 확인.
*/
PostOrderType orderType=postHelper.isValidAndGetPostOrderType(type);
PostOrderType orderType = postHelper.isValidAndGetPostOrderType(type);

/**
* 2. type = POPULAR (인기순) / LATEST (μ΅œμ‹ μˆœ) μ •λ ¬ ν›„ 쑰회.
*/
PostListResponse response = null;
switch (orderType){
case popular -> response=postMapper.
entityToDto(postHelper.getPopularPostListBySliceAndNoOffset(lastPostId,size));
switch (orderType) {
case popular -> response = postMapper.
entityToDto(postHelper.getPopularPostListBySliceAndNoOffset(lastPostId, size));

case latest -> response=postMapper.
entityToDto(postHelper.getLatestPostListBySliceAndNoOffset(lastPostId,size));
case latest -> response = postMapper.
entityToDto(postHelper.getLatestPostListBySliceAndNoOffset(lastPostId, size));
}
return response;
}

@Transactional(readOnly = true)
public PostListResponse getPostEntitiesByPostTitleOrPostContent(String search,Long postId,int size){
public PostListResponse getPostEntitiesByPostTitleOrPostContent(String search, Long postId, int size) {
/**
* 1. 제λͺ© + λ‚΄μš© κ²Œμ‹œλ¬Ό 쑰회.
*/
return postMapper.entityToDto(postHelper.getPostEntitiesByPostTitleOrPostContent(search,postId,size));
return postMapper.entityToDto(postHelper.getPostEntitiesByPostTitleOrPostContent(search, postId, size));
}

@Transactional(readOnly = true)
public PostListResponse getPostByPostTitleOrPostContentByElasticSearch(String search,int size,PostSort sort){
PostListResponseFactory factory=new PostListResponseFactory(postMapper);
public PostListResponse getPostByPostTitleOrPostContentByElasticSearch(String search, int size, PostSort sort) {
PostListResponseFactory factory = new PostListResponseFactory(postMapper);

/**
* 0. ElasticSearchκ°€ μ‚¬μš© κ°€λŠ₯ν•œ κ²½μš°μ—λ§Œ μ‹€ν–‰
*/
*/
if (postElasticSearchHelper == null) {
//일반 검색
return getPostEntitiesByPostTitleOrPostContent(search, sort.lastPostId(), size);
Expand All @@ -170,34 +171,34 @@ public PostListResponse getPostByPostTitleOrPostContentByElasticSearch(String se
* 1. size 및 검색값 μœ νš¨μ„± 검증.
*/
postHelper.isValidSize(size);
if (!postHelper.isValidInput(search)){
if (!postHelper.isValidInput(search)) {
//빈 값인 경우 -> 빈 리슀트 λ°˜ν™˜.
return PostListResponse.withSort(sort.lastPostId(), Collections.emptyList(),sort);
return PostListResponse.withSort(sort.lastPostId(), Collections.emptyList(), sort);
}

/**
* 2. ν•΄μ‹œνƒœκ·Έ κΈ°λ°˜μΈμ§€ 일반 검색어 κΈ°λ°˜μΈμ§€ 확인
* ν•΄μ‹œνƒœκ·Έ 기반인 경우
*/
if (postElasticSearchHelper.isHashTagSearch(search)){
String cleanedSearch=postElasticSearchHelper.refinedHashTag(search);
if (postElasticSearchHelper.isHashTagSearch(search)) {
String cleanedSearch = postElasticSearchHelper.refinedHashTag(search);
List<PostSearchHit> postByHashTagByElasticSearch = postElasticSearchHelper.getPostByHashTagByElasticSearch(cleanedSearch, size, sort);

return factory.build(postByHashTagByElasticSearch,sort);
return factory.build(postByHashTagByElasticSearch, sort);
}

/**
* 3. 일반 검색어 기반 κ²Œμ‹œλ¬Ό 검색 쑰회
* κ²Œμ‹œλ¬Ό μ •λ ¬ 쑰건 + 검색어 κ²Œμ‹œλ¬Ό 검색 , _score 쑰회
*/
List<PostSearchHit> responses=postElasticSearchHelper.getPostByTitleOrContentByElasticSearch(search,size,sort);
List<PostSearchHit> responses = postElasticSearchHelper.getPostByTitleOrContentByElasticSearch(search, size, sort);

return factory.build(responses,sort);
return factory.build(responses, sort);
}

@Transactional(readOnly = true)
public List<SearchAutoCompleteResponse> suggest(String keyword){
PostListResponseFactory factory=new PostListResponseFactory(postMapper);
public List<SearchAutoCompleteResponse> suggest(String keyword) {
PostListResponseFactory factory = new PostListResponseFactory(postMapper);
/**
* 0. ElasticSearchκ°€ μ‚¬μš© κ°€λŠ₯ν•œ κ²½μš°μ—λ§Œ μ‹€ν–‰
*/
Expand All @@ -209,7 +210,7 @@ public List<SearchAutoCompleteResponse> suggest(String keyword){
/**
* 1.검색값 μœ νš¨μ„± 검증.
*/
if (!postHelper.isValidInput(keyword)){
if (!postHelper.isValidInput(keyword)) {
//빈 값인 경우 -> 빈 리슀트 λ°˜ν™˜.
return Collections.emptyList();
}
Expand All @@ -218,8 +219,8 @@ public List<SearchAutoCompleteResponse> suggest(String keyword){
2. ν•΄μ‹œνƒœκ·Έ κΈ°λ°˜μΈμ§€ 일반 검색어 κΈ°λ°˜μΈμ§€ 확인
ν•΄μ‹œνƒœκ·Έ 기반인 경우
*/
if (postElasticSearchHelper.isHashTagSearch(keyword)){
String cleanedKeyword=postElasticSearchHelper.refinedHashTag(keyword);
if (postElasticSearchHelper.isHashTagSearch(keyword)) {
String cleanedKeyword = postElasticSearchHelper.refinedHashTag(keyword);
List<String> postByHashTagByElasticSearch = postElasticSearchHelper.suggestCompleteSearchWithHashTag(cleanedKeyword);

return factory.build(postByHashTagByElasticSearch);
Expand All @@ -233,7 +234,7 @@ public List<SearchAutoCompleteResponse> suggest(String keyword){

return factory.build(postByHashTagByElasticSearch);
}

@Transactional(readOnly = true)
public PostListResponse getMyPosts(UUID memberId) {
List<Long> postIds = postHelper.findPostIdsByMemberId(memberId);
Expand All @@ -244,18 +245,18 @@ public PostListResponse getMyPosts(UUID memberId) {

List<PostEntity> postEntities = postHelper.findPostsByPostIds(postIds);
List<PostResponse> postResponses = postEntities.stream()
.map(postMapper::entityToDto)
.toList();
.map(postMapper::entityToDto)
.toList();

Long lastPostId = postEntities.isEmpty() ? null : postEntities.get(postEntities.size() - 1).getPostId();

return PostListResponse.of(lastPostId, postResponses);
}

@Transactional(readOnly = true)
public PostListResponse getMyLikedPosts(UUID memId,Long lastPostId,int size){
public PostListResponse getMyLikedPosts(UUID memId, Long lastPostId, int size) {
//1. μœ μ €κ°€ μ’‹μ•„μš” λˆ„λ₯Έ κ²Œμ‹œλ¬Ό 쑰회
List<PostEntity> postEntities=postHelper.getMyLikedPost(memId,lastPostId,size);
List<PostEntity> postEntities = postHelper.getMyLikedPost(memId, lastPostId, size);

//2. entity -> dto λ³€ν™˜
return postMapper.entityToDto(postEntities);
Expand All @@ -265,38 +266,40 @@ public PostListResponse getMyLikedPosts(UUID memId,Long lastPostId,int size){
* List<PostSearchHit> -> PostListResponse λ³€ν™˜ inner class
*/
@RequiredArgsConstructor
static class PostListResponseFactory{
static class PostListResponseFactory {

private final PostMapper mapper;
public PostListResponse build(List<PostSearchHit> responses,PostSort sort){
if (responses.isEmpty()){

public PostListResponse build(List<PostSearchHit> responses, PostSort sort) {
if (responses.isEmpty()) {
//빈 값인 경우 -> 빈 리슀트 λ°˜ν™˜.
return PostListResponse.withSort(sort.lastPostId(), Collections.emptyList(),sort);
return PostListResponse.withSort(sort.lastPostId(), Collections.emptyList(), sort);
}

//결과값이 μ‘΄μž¬ν•˜λŠ” 경우 - λ§ˆμ§€λ§‰ κ²Œμ‹œλ¬Όμ˜ μ •λ ¬ κΈ°μ€€ 전솑
int last=responses.size()-1;
int last = responses.size() - 1;

PostDocument lastResponse=responses.get(last).doc();
PostSort newSort=new PostSort(responses.get(last)._score(),
PostDocument lastResponse = responses.get(last).doc();
PostSort newSort = new PostSort(responses.get(last)._score(),
lastResponse.getLikeCnt(),
lastResponse.getPostId()
);

/**
* List<PostDocument> -> List<PostResponse> ν˜•νƒœλ‘œ λ³€ν™˜
*/
List<PostResponse> postResponses=responses.stream()
.map(hit->mapper.documentToResponse(hit.doc()))
List<PostResponse> postResponses = responses.stream()
.map(hit -> mapper.documentToResponse(hit.doc()))
.toList();

return PostListResponse.withSort(lastResponse.getPostId(),postResponses,newSort);
return PostListResponse.withSort(lastResponse.getPostId(), postResponses, newSort);
}
public List<SearchAutoCompleteResponse> build(List<String> responses){

public List<SearchAutoCompleteResponse> build(List<String> responses) {
/**
* 1. responsesκ°€ 빈 값인지 확인
*/
if (responses==null) return Collections.emptyList();
if (responses == null) return Collections.emptyList();

return responses.stream()
.map(SearchAutoCompleteResponse::of)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.midas.shootpointer.domain.post.business.command;

import com.midas.shootpointer.domain.member.entity.Member;
import com.midas.shootpointer.domain.post.entity.PostEntity;
import com.midas.shootpointer.domain.post.dto.request.PostRequest;

public interface PostCommandService {
Long create(PostEntity post, Member member);
Long create(PostRequest request, Member member);

Long update(PostEntity post, Member member,Long postId);
Long update(PostRequest request, Member member,Long postId);

Long delete(Member member,Long postId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.midas.shootpointer.domain.member.entity.Member;
import com.midas.shootpointer.domain.post.business.PostManager;
import com.midas.shootpointer.domain.post.dto.request.PostRequest;
import com.midas.shootpointer.domain.post.entity.PostEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -14,14 +15,15 @@ public class PostCommandServiceImpl implements PostCommandService{

@Transactional
@Override
public Long create(PostEntity post, Member member) {
return postManager.save(member,post,post.getHighlight().getHighlightId());
public Long create(PostRequest request, Member member) {
return postManager.save(member,request);
}


@Transactional
@Override
public Long update(PostEntity post, Member member,Long postId) {
return postManager.update(post,member,postId);
public Long update(PostRequest request, Member member, Long postId) {
return postManager.update(request,member,postId);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.midas.shootpointer.domain.member.entity.Member;
import com.midas.shootpointer.domain.post.business.command.PostCommandService;
import com.midas.shootpointer.domain.post.dto.request.PostRequest;
import com.midas.shootpointer.domain.post.entity.PostEntity;
import com.midas.shootpointer.domain.post.mapper.PostMapper;
import com.midas.shootpointer.global.dto.ApiResponse;
import com.midas.shootpointer.global.security.SecurityUtils;
Expand Down Expand Up @@ -51,8 +50,7 @@ public ResponseEntity<ApiResponse<Long>> create(
@RequestBody PostRequest request
) {
Member member=SecurityUtils.getCurrentMember();
PostEntity entity=postMapper.dtoToEntity(request,member);
return ResponseEntity.ok(ApiResponse.created(postCommandService.create(entity,member)));
return ResponseEntity.ok(ApiResponse.created(postCommandService.create(request,member)));
}

@Operation(
Expand Down Expand Up @@ -84,8 +82,7 @@ public ResponseEntity<ApiResponse<Long>> update(
@PathVariable(value = "postId") Long postId
){
Member member=SecurityUtils.getCurrentMember();
PostEntity entity=postMapper.dtoToEntity(request,member);
return ResponseEntity.ok(ApiResponse.ok(postCommandService.update(entity,member,postId)));
return ResponseEntity.ok(ApiResponse.ok(postCommandService.update(request,member,postId)));
}


Expand Down
Loading