Skip to content

Commit

Permalink
[FEATURE] 특정 데일리 질문에 대한 친구들의 답변 몰아보기 API 작성 (#118)
Browse files Browse the repository at this point in the history
* feat : 특정 데일리 질문에 대한 친구들의 답변 몰아보기 API 작성

* edit : 무한스크롤 삭제, list 조회로 변경 #112
  • Loading branch information
bongsh0112 authored Nov 29, 2023
1 parent 5716f0b commit 22ffb5c
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;
import tify.server.api.answer.model.response.NeighborAnswerInfoDTO;
import tify.server.api.answer.model.response.RetrieveAnswerCountResponse;
import tify.server.api.answer.model.response.RetrieveAnswerDTO;
import tify.server.api.answer.service.RetrieveDailyAnswerCountUseCase;
Expand Down Expand Up @@ -38,4 +40,15 @@ public SliceResponse<RetrieveAnswerDTO> getAnswers(
public RetrieveAnswerCountResponse getAnswerCounts(@PathVariable Long questionId) {
return retrieveDailyAnswerCountUseCase.execute(questionId);
}

@Operation(
summary = "특정 유저의 친구들이 해당 데일리 질문에 답변을 남겼는지 조회하고, 남겼다면 답변의 정보를 조회합니다.",
description = "답변을 남기지 않았다면 답변 필드가 null")
@GetMapping("/{userId}/neighbors")
public List<NeighborAnswerInfoDTO> getNeighborAnswerInfoList(
@PathVariable Long questionId,
@PathVariable Long userId,
@ParameterObject @PageableDefault(size = 10) Pageable pageable) {
return retrieveDailyAnswerUseCase.executeNeighborAnswerList(questionId, userId, pageable);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tify.server.api.answer.model.response;


import lombok.Builder;
import lombok.Getter;
import tify.server.api.answer.model.vo.AnswerInfoVo;
import tify.server.domain.domains.user.dto.model.RetrieveNeighborDTO;

@Getter
@Builder
public class NeighborAnswerInfoDTO {

private final RetrieveNeighborDTO neighborInfo;

private final AnswerInfoVo answerInfo;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.Objects;
import lombok.Builder;
import lombok.Getter;
import tify.server.api.answer.vo.AnswerInfoVo;
import tify.server.api.answer.model.vo.AnswerInfoVo;
import tify.server.domain.domains.question.dto.model.AnswerVo;

@Getter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package tify.server.api.answer.vo;
package tify.server.api.answer.model.vo;


import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Optional;
import lombok.Builder;
import lombok.Getter;
import tify.server.domain.domains.question.domain.Answer;
import tify.server.domain.domains.question.dto.model.AnswerVo;

@Getter
Expand All @@ -30,4 +32,13 @@ public static AnswerInfoVo from(AnswerVo answer) {
.content(answer.getAnswer().getContent())
.build();
}

public static AnswerInfoVo from(Answer answer) {
return AnswerInfoVo.builder()
.id(Optional.ofNullable(answer).map(Answer::getId).orElse(null))
.questionId(Optional.ofNullable(answer).map(Answer::getQuestionId).orElse(null))
.userId(Optional.ofNullable(answer).map(Answer::getUserId).orElse(null))
.content(Optional.ofNullable(answer).map(Answer::getContent).orElse(null))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,48 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.answer.model.response.NeighborAnswerInfoDTO;
import tify.server.api.answer.model.response.RetrieveAnswerDTO;
import tify.server.api.answer.model.vo.AnswerInfoVo;
import tify.server.api.common.slice.SliceResponse;
import tify.server.api.utils.UserUtils;
import tify.server.api.config.security.SecurityUtils;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.question.adaptor.AnswerAdaptor;
import tify.server.domain.domains.question.adaptor.DailyQuestionAdaptor;
import tify.server.domain.domains.question.domain.Answer;
import tify.server.domain.domains.question.domain.DailyQuestion;
import tify.server.domain.domains.question.dto.condition.AnswerCondition;
import tify.server.domain.domains.question.dto.model.AnswerVo;
import tify.server.domain.domains.user.adaptor.NeighborAdaptor;
import tify.server.domain.domains.user.adaptor.UserAdaptor;
import tify.server.domain.domains.user.adaptor.UserBlockAdaptor;
import tify.server.domain.domains.user.domain.Neighbor;
import tify.server.domain.domains.user.domain.User;
import tify.server.domain.domains.user.domain.UserBlock;
import tify.server.domain.domains.user.dto.condition.NeighborCondition;
import tify.server.domain.domains.user.dto.model.RetrieveNeighborDTO;

@Slf4j
@UseCase
@RequiredArgsConstructor
public class RetrieveDailyAnswerUseCase {

private final UserAdaptor userAdaptor;
private final AnswerAdaptor answerAdaptor;
private final UserBlockAdaptor userBlockAdaptor;
private final NeighborAdaptor neighborAdaptor;
private final DailyQuestionAdaptor dailyQuestionAdaptor;
private final UserUtils userUtils;

@Transactional(readOnly = true)
public SliceResponse<RetrieveAnswerDTO> execute(Long questionId, Pageable pageable) {
DailyQuestion dailyQuestion = dailyQuestionAdaptor.query(questionId);
Long currentUserId = userUtils.getUserId();
Long currentUserId = SecurityUtils.getCurrentUserId();
List<Long> userIdList =
new ArrayList<>(
neighborAdaptor.queryAllByFromUserIdAndIsView(currentUserId, true).stream()
Expand All @@ -44,4 +57,37 @@ public SliceResponse<RetrieveAnswerDTO> execute(Long questionId, Pageable pageab
return SliceResponse.of(
answers.map(answerVo -> RetrieveAnswerDTO.of(answerVo, currentUserId)));
}

@Transactional(readOnly = true)
public List<NeighborAnswerInfoDTO> executeNeighborAnswerList(
Long questionId, Long userId, Pageable pageable) {
List<User> neighborList =
neighborAdaptor.queryAllByFromUserId(userId).stream()
.map(Neighbor::getToUserId)
.map(userAdaptor::query)
.toList();
List<Long> blockedIdList =
userBlockAdaptor.queryAllByFromUserId(userId).stream()
.map(UserBlock::getToUserId)
.toList();
List<Long> friendIdList =
neighborAdaptor.queryAllByFromUserId(userId).stream()
.map(Neighbor::getToUserId)
.toList();
NeighborCondition neighborCondition =
new NeighborCondition(userId, blockedIdList, friendIdList);
List<RetrieveNeighborDTO> neighbors = neighborAdaptor.searchNeighbors(neighborCondition);
return neighbors.stream()
.map(
dto -> {
Optional<Answer> answer =
answerAdaptor.optionalQueryByQuestionAndUser(
questionId, dto.getNeighborId());
return NeighborAnswerInfoDTO.builder()
.neighborInfo(dto)
.answerInfo(AnswerInfoVo.from(answer.orElse(null)))
.build();
})
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ public Optional<Neighbor> queryByFromUserIdAndToUserId(Long userId, Long neighbo
}

public List<RetrieveNeighborDTO> searchNeighbors(NeighborCondition neighborCondition) {
return neighborRepository.searchToPage(neighborCondition);
return neighborRepository.searchNeighbors(neighborCondition);
}

public Slice<RetrieveNeighborDTO> searchNeighbors(
NeighborCondition neighborCondition, Pageable pageable) {
return neighborRepository.searchNeighborsToPage(neighborCondition, pageable);
}

public boolean existsNeighbor(Long userId, Long neighborId) {
Expand All @@ -70,7 +75,7 @@ public void delete(Neighbor neighbor) {
}

public List<RetrieveNeighborDTO> searchBirthdayNeighbors(NeighborCondition neighborCondition) {
return neighborRepository.searchBirthToPage(neighborCondition);
return neighborRepository.searchBirthdayNeighbors(neighborCondition);
}

public void saveNeighborApplication(NeighborApplication neighborApplication) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@


import java.util.List;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import tify.server.domain.domains.user.dto.condition.NeighborCondition;
import tify.server.domain.domains.user.dto.model.RetrieveNeighborDTO;

public interface NeighborCustomRepository {

List<RetrieveNeighborDTO> searchToPage(NeighborCondition neighborCondition);
List<RetrieveNeighborDTO> searchNeighbors(NeighborCondition neighborCondition);

List<RetrieveNeighborDTO> searchBirthToPage(NeighborCondition neighborCondition);
List<RetrieveNeighborDTO> searchBirthdayNeighbors(NeighborCondition neighborCondition);

Slice<RetrieveNeighborDTO> searchNeighborsToPage(
NeighborCondition neighborCondition, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import java.time.ZoneId;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import tify.server.domain.common.util.SliceUtil;
import tify.server.domain.domains.user.dto.condition.NeighborCondition;
import tify.server.domain.domains.user.dto.model.RetrieveNeighborDTO;

Expand All @@ -17,7 +20,7 @@ public class NeighborCustomRepositoryImpl implements NeighborCustomRepository {
private final JPAQueryFactory queryFactory;

@Override
public List<RetrieveNeighborDTO> searchToPage(NeighborCondition neighborCondition) {
public List<RetrieveNeighborDTO> searchNeighbors(NeighborCondition neighborCondition) {
return queryFactory
.select(
Projections.constructor(
Expand Down Expand Up @@ -45,7 +48,7 @@ public List<RetrieveNeighborDTO> searchToPage(NeighborCondition neighborConditio
}

@Override
public List<RetrieveNeighborDTO> searchBirthToPage(NeighborCondition neighborCondition) {
public List<RetrieveNeighborDTO> searchBirthdayNeighbors(NeighborCondition neighborCondition) {
LocalDateTime today = LocalDateTime.now(ZoneId.of("Asia/Seoul"));
String monthAndYear =
String.format("%02d%02d", today.getMonth().getValue(), today.getDayOfMonth());
Expand Down Expand Up @@ -75,4 +78,37 @@ public List<RetrieveNeighborDTO> searchBirthToPage(NeighborCondition neighborCon
.orderBy(neighbor.order.asc())
.fetch();
}

@Override
public Slice<RetrieveNeighborDTO> searchNeighborsToPage(
NeighborCondition neighborCondition, Pageable pageable) {
List<RetrieveNeighborDTO> retrieveNeighborDTOS =
queryFactory
.select(
Projections.constructor(
RetrieveNeighborDTO.class,
neighbor.toUserId,
neighbor.fromUserId,
user.profile.thumbNail,
user.profile.userName,
user.profile.birth,
user.onBoardingStatus.name,
neighbor.order,
neighbor.isView,
neighbor.isNew,
user.updatedAt,
neighbor.viewedAt))
.from(neighbor)
.join(user)
.on(user.id.eq(neighbor.toUserId))
.where(
neighbor.fromUserId.eq(neighborCondition.getCurrentUserId()),
neighbor.toUserId.notIn(neighborCondition.getBlockedUserIdList()),
neighbor.toUserId.in(neighborCondition.getFriendIdList()))
.orderBy(neighbor.order.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
return SliceUtil.valueOf(retrieveNeighborDTOS, pageable);
}
}

0 comments on commit 22ffb5c

Please sign in to comment.