-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [feat] : MemberQueryDSL Repo 추가 * [feat] : 작성한 질문 전체 조회 응답 DTO 추가 * [feat] : MemberErrorCode 추가 * [feat] : 작성한 질문 전체 조회 컨트롤러/비즈니스 로직 작성 * [test] : 특정 회원 작성 질문 목록 검색 테스트 * [feat] : 댓글 단 질문 목록 응답 DTO 추가 * [feat] : 댓글 단 질문 목록 QueryDSL 추가 * [feat] : 댓글 단 질문 목록 에러코드 추가 * [feat] : 댓글 단 질문 전체 조회 컨트롤러/비즈니스 로직 추가 * [test] : 특정 회원 답변 작성 질문 목록 리스트 조회 테스트 * [test] 마이페이지 - 나의활동 API 통합 테스트 추가 * [feat #38] 질문글 상호작용 API (#44) * [style] : 정적 팩토리 메서드 네이밍 변경 * [style] : enum 라벨 필드명 변경 * [feat] : 게시글 상호작용 에러코드 추가 * [feat] : postInteraction mapper 추가 * [feat] : postInteraction 상태 변경 메서드 추가 * [feat] : postInteractionCount 필드 변경 메서드 추가 * [feat] : 게시글 상호작용 응답 추가 * [feat] : 게시글 상호작용, 게시글 상호작용수 repository 추가 * [feat] : 게시글 상호작용(추천, 북마크) 활성화, 비활성화 비즈니스 로직 작성 * [feat] : 게시글 상호작용(추천, 북마크) 활성화, 비활성화 API 메서드 작성 * [feat] : 상호작용 에러 코드 추가 및 네이밍 변경 * [refactor] : 질문글 비즈니스 메서드 파라미터 변경 * [feat] : 질문글 상호작용 생성 전 검증 로직 추가 * [test] : 상호작용, 상호작용 수 fixture 추가 * [fix] : 상태변경 로직 오류 수정 * [feat] : 상태변경 에러코드 수정 * [feat] : 응답 필드에 라벨로 반환 * [test] : 상호작용 활성화/비활성화 단위 테스트 * [style] : 코드 리포멧팅 * [feat] : 컨트롤러 파라미터 어노테이션 수정 * [feat] : 게시글 상호작용 생성 시 기존에 게시글 상호작용 수 엔티티 존재하는지 검증 * [test] : 게시글 상호작용 생성 시 기존에 게시글 상호작용 수 엔티티 존재하는지 로직 추가에 대한 테스트 반영 * [test] : 이메일 중복 저장 방지를 위해 memberFixture 객체 추가 * [fix] : 도메인 비즈니스 로직 오류 수정 * [test] : 게시글 상호작용 통합 테스트 작성 * [rename] : 상호작용, 상호작용 수 엔티티명 변경 * [style] : 코드 리포멧팅 * [feat #45] 게시글 상세 조회 응답 필드 추가 (#46) * [feat] : 질문글 등록 응답 dto 생성 * [feat] : 상세 조회 응답 dto에 추천수, 북마크수 필드 추가 * [feat] : 상세 조회 DTO, 등록 DTO 분리 * [feat] : 북마크수, 추천수 구하는 비즈니스 로직 추가 * [refactor] : fixture 메서드명 수정 * [feat] : 북마크수, 추천수 구하는 비즈니스 로직 테스트 * [feat] : API별 DTO 분리 반영 * [test] : dto 응답 필드 추가 반영 * [style] : 코드 리포멧팅 * [fix] : DTO mapper 함수명 수정 * [feat] : 엔티티 필드명 수정 * [fix] : PostInteractionCount -> InteractionCount 네이밍 변경으로 인한 오류 수정 * [test] : repoisitory 테스트 실패 수정 * [fix] : 게시글 스크랩/추천해요 총 개수 제대로 매핑되도록 쿼리 수정 * [fix] : 작성 질문/답변 단 질문 응답 DTO 스크랩/추천해요 충 개수 필드 수정 * [test] : 스크랩/추천해요 총 개수에 관한 테스트 추가 * [feat] : 답변 단 질문 목록 조회시 가장 최신 답변 1개만 가져오도록 쿼리 추가 * [test] : 답변 단 질문 목록 조회 관련 Repostiory/Controller 테스트 작성 * [fix] : 연산 타입 일치화(+1 -> +1L) * [fix] : 질문 목록 id 값이 아닌 updatedAt() 내림차순으로 정렬 변경 --------- Co-authored-by: Son Gahyun <[email protected]>
- Loading branch information
Showing
10 changed files
with
715 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
...main/java/com/dnd/gongmuin/member/dto/response/AnsweredQuestionPostsByMemberResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package com.dnd.gongmuin.member.dto.response; | ||
|
||
import com.dnd.gongmuin.answer.domain.Answer; | ||
import com.dnd.gongmuin.post_interaction.domain.InteractionCount; | ||
import com.dnd.gongmuin.question_post.domain.QuestionPost; | ||
import com.querydsl.core.annotations.QueryProjection; | ||
|
||
public record AnsweredQuestionPostsByMemberResponse( | ||
Long questionPostId, | ||
String title, | ||
String content, | ||
String jobGroup, | ||
int reward, | ||
String questionPostUpdatedAt, | ||
boolean isChosen, | ||
int savedTotalCount, | ||
int recommendTotalCount, | ||
Long answerId, | ||
String answerContent, | ||
String answerUpdatedAt | ||
) { | ||
|
||
@QueryProjection | ||
public AnsweredQuestionPostsByMemberResponse( | ||
QuestionPost questionPost, | ||
InteractionCount savedCount, | ||
InteractionCount recommendCount, | ||
Answer answer) { | ||
this( | ||
questionPost.getId(), | ||
questionPost.getTitle(), | ||
questionPost.getContent(), | ||
questionPost.getJobGroup().getLabel(), | ||
questionPost.getReward(), | ||
questionPost.getUpdatedAt().toString(), | ||
questionPost.getIsChosen(), | ||
extractTotalCount(savedCount), | ||
extractTotalCount(recommendCount), | ||
answer.getId(), | ||
answer.getContent(), | ||
answer.getUpdatedAt().toString() | ||
); | ||
} | ||
|
||
private static int extractTotalCount(InteractionCount interactionCount) { | ||
return interactionCount != null ? interactionCount.getCount() : 0; | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/java/com/dnd/gongmuin/member/dto/response/QuestionPostsByMemberResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.dnd.gongmuin.member.dto.response; | ||
|
||
import com.dnd.gongmuin.post_interaction.domain.InteractionCount; | ||
import com.dnd.gongmuin.question_post.domain.QuestionPost; | ||
import com.querydsl.core.annotations.QueryProjection; | ||
|
||
public record QuestionPostsByMemberResponse( | ||
Long questionPostId, | ||
String title, | ||
String content, | ||
String jobGroup, | ||
int reward, | ||
String updatedAt, | ||
boolean isChosen, | ||
int savedTotalCount, | ||
int recommendTotalCount | ||
) { | ||
|
||
@QueryProjection | ||
public QuestionPostsByMemberResponse( | ||
QuestionPost questionPost, | ||
InteractionCount savedCount, | ||
InteractionCount recommendCount | ||
) { | ||
this( | ||
questionPost.getId(), | ||
questionPost.getTitle(), | ||
questionPost.getContent(), | ||
questionPost.getJobGroup().getLabel(), | ||
questionPost.getReward(), | ||
questionPost.getUpdatedAt().toString(), | ||
questionPost.getIsChosen(), | ||
extractTotalCount(savedCount), | ||
extractTotalCount(recommendCount) | ||
); | ||
} | ||
|
||
private static int extractTotalCount(InteractionCount interactionCount) { | ||
return interactionCount != null ? interactionCount.getCount() : 0; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/main/java/com/dnd/gongmuin/member/repository/MemberCustom.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.dnd.gongmuin.member.repository; | ||
|
||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.domain.Slice; | ||
|
||
import com.dnd.gongmuin.member.domain.Member; | ||
import com.dnd.gongmuin.member.dto.response.AnsweredQuestionPostsByMemberResponse; | ||
import com.dnd.gongmuin.member.dto.response.QuestionPostsByMemberResponse; | ||
|
||
public interface MemberCustom { | ||
Slice<QuestionPostsByMemberResponse> getQuestionPostsByMember(Member member, Pageable pageable); | ||
|
||
Slice<AnsweredQuestionPostsByMemberResponse> getAnsweredQuestionPostsByMember(Member member, Pageable pageable); | ||
} |
101 changes: 101 additions & 0 deletions
101
src/main/java/com/dnd/gongmuin/member/repository/MemberCustomImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package com.dnd.gongmuin.member.repository; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.domain.Slice; | ||
import org.springframework.data.domain.SliceImpl; | ||
|
||
import com.dnd.gongmuin.answer.domain.QAnswer; | ||
import com.dnd.gongmuin.member.domain.Member; | ||
import com.dnd.gongmuin.member.dto.response.AnsweredQuestionPostsByMemberResponse; | ||
import com.dnd.gongmuin.member.dto.response.QAnsweredQuestionPostsByMemberResponse; | ||
import com.dnd.gongmuin.member.dto.response.QQuestionPostsByMemberResponse; | ||
import com.dnd.gongmuin.member.dto.response.QuestionPostsByMemberResponse; | ||
import com.dnd.gongmuin.post_interaction.domain.InteractionType; | ||
import com.dnd.gongmuin.post_interaction.domain.QInteractionCount; | ||
import com.dnd.gongmuin.question_post.domain.QQuestionPost; | ||
import com.querydsl.jpa.JPAExpressions; | ||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
public class MemberCustomImpl implements MemberCustom { | ||
|
||
private final JPAQueryFactory queryFactory; | ||
|
||
@Override | ||
public Slice<QuestionPostsByMemberResponse> getQuestionPostsByMember(Member member, Pageable pageable) { | ||
QQuestionPost qp = QQuestionPost.questionPost; | ||
QInteractionCount saved = new QInteractionCount("SAVED"); | ||
QInteractionCount recommend = new QInteractionCount("RECOMMEND"); | ||
|
||
List<QuestionPostsByMemberResponse> content = queryFactory | ||
.select(new QQuestionPostsByMemberResponse(qp, saved, recommend)) | ||
.from(qp) | ||
.leftJoin(saved) | ||
.on(qp.id.eq(saved.questionPostId).and(saved.type.eq(InteractionType.SAVED))) | ||
.leftJoin(recommend) | ||
.on(qp.id.eq(recommend.questionPostId).and(recommend.type.eq(InteractionType.RECOMMEND))) | ||
.where(qp.member.eq(member)) | ||
.orderBy(qp.updatedAt.desc()) | ||
.offset(pageable.getOffset()) | ||
.limit(pageable.getPageSize() + 1L) | ||
.fetch(); | ||
|
||
boolean hasNext = hasNext(pageable.getPageSize(), content); | ||
|
||
return new SliceImpl<>(content, pageable, hasNext); | ||
} | ||
|
||
@Override | ||
public Slice<AnsweredQuestionPostsByMemberResponse> getAnsweredQuestionPostsByMember( | ||
Member member, Pageable pageable) { | ||
QQuestionPost qp = QQuestionPost.questionPost; | ||
QInteractionCount saved = new QInteractionCount("SAVED"); | ||
QInteractionCount recommend = new QInteractionCount("RECOMMEND"); | ||
QAnswer aw1 = new QAnswer("answer1"); | ||
QAnswer aw2 = new QAnswer("answer2"); | ||
|
||
List<AnsweredQuestionPostsByMemberResponse> content = | ||
queryFactory | ||
.select(new QAnsweredQuestionPostsByMemberResponse(qp, saved, recommend, aw1)) | ||
.from(qp) | ||
.join(aw1) | ||
.on(aw1.id.eq( | ||
JPAExpressions | ||
.select(aw2.id) | ||
.from(aw2) | ||
.where(aw2.questionPostId.eq(qp.id) | ||
.and(aw2.member.eq(member)) | ||
.and(aw2.updatedAt.eq( | ||
JPAExpressions | ||
.select(aw2.updatedAt.max()) | ||
.from(aw2) | ||
.where(aw2.questionPostId.eq(qp.id) | ||
.and(aw2.member.eq(member))) | ||
))) | ||
)) | ||
.leftJoin(saved) | ||
.on(qp.id.eq(saved.questionPostId).and(saved.type.eq(InteractionType.SAVED))) | ||
.leftJoin(recommend) | ||
.on(qp.id.eq(recommend.questionPostId).and(recommend.type.eq(InteractionType.RECOMMEND))) | ||
.orderBy(qp.updatedAt.desc()) | ||
.offset(pageable.getOffset()) | ||
.limit(pageable.getPageSize() + 1L) | ||
.fetch(); | ||
|
||
boolean hasNext = hasNext(pageable.getPageSize(), content); | ||
|
||
return new SliceImpl<>(content, pageable, hasNext); | ||
} | ||
|
||
private <T> boolean hasNext(int pageSize, List<T> content) { | ||
if (content.size() <= pageSize) { | ||
return false; | ||
} | ||
content.remove(pageSize); | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.