Skip to content

Commit

Permalink
feat : 데일리 답변에 대한 신고 기능 추가, 유저 신고 로직 수정 #114
Browse files Browse the repository at this point in the history
  • Loading branch information
bongsh0112 committed Nov 28, 2023
1 parent 5716f0b commit 34d8495
Show file tree
Hide file tree
Showing 20 changed files with 293 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import tify.server.api.answer.model.response.RetrieveAnswerCountResponse;
import tify.server.api.answer.model.response.RetrieveAnswerDTO;
import tify.server.api.answer.model.response.AnswerReportResponse;
import tify.server.api.answer.model.vo.RetrieveAnswerCountVo;
import tify.server.api.answer.model.vo.RetrieveAnswerVo;
import tify.server.api.answer.service.CreateDailyAnswerReportUseCase;
import tify.server.api.answer.service.RetrieveDailyAnswerCountUseCase;
import tify.server.api.answer.service.RetrieveDailyAnswerUseCase;
import tify.server.api.common.slice.SliceResponse;
Expand All @@ -24,18 +27,26 @@ public class AnswerController {

private final RetrieveDailyAnswerUseCase retrieveDailyAnswerUseCase;
private final RetrieveDailyAnswerCountUseCase retrieveDailyAnswerCountUseCase;
private final CreateDailyAnswerReportUseCase createDailyAnswerReportUseCase;

@Operation(summary = "데일리 질문에 대한 답변을 모두 조회합니다.")
@GetMapping
public SliceResponse<RetrieveAnswerDTO> getAnswers(
public SliceResponse<RetrieveAnswerVo> getAnswers(
@PathVariable Long questionId,
@ParameterObject @PageableDefault(size = 10) Pageable pageable) {
return retrieveDailyAnswerUseCase.execute(questionId, pageable);
}

@Operation(summary = "데일리 질문에 대한 답변 개수를 조회합니다.")
@GetMapping(value = "/counts")
public RetrieveAnswerCountResponse getAnswerCounts(@PathVariable Long questionId) {
public RetrieveAnswerCountVo getAnswerCounts(@PathVariable Long questionId) {
return retrieveDailyAnswerCountUseCase.execute(questionId);
}

@Operation(summary = "데일리 질문에 대한 답변을 신고합니다.")
@PostMapping(value = "/{answerId}/report")
public ResponseEntity<AnswerReportResponse> postAnswerReport(
@PathVariable Long questionId, @PathVariable Long answerId) {
return createDailyAnswerReportUseCase.execute(answerId);
}
}
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;

@Getter
@Builder
public class AnswerReportResponse {

private final Long userId;

private final Long answerId;

private final boolean reportSuccess;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tify.server.api.answer.model.vo;


import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class RetrieveAnswerCountVo {

private final Long answerCount;

public static RetrieveAnswerCountVo of(Long answerCount) {
return RetrieveAnswerCountVo.builder().answerCount(answerCount).build();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tify.server.api.answer.model.response;
package tify.server.api.answer.model.vo;


import java.util.Objects;
Expand All @@ -9,14 +9,14 @@

@Getter
@Builder
public class RetrieveAnswerDTO {
public class RetrieveAnswerVo {

private final AnswerInfoVo answerInfo;

private final Boolean isMine;

public static RetrieveAnswerDTO of(AnswerVo answerVo, Long currentUserId) {
return RetrieveAnswerDTO.builder()
public static RetrieveAnswerVo of(AnswerVo answerVo, Long currentUserId) {
return RetrieveAnswerVo.builder()
.answerInfo(AnswerInfoVo.from(answerVo))
.isMine(Objects.equals(answerVo.getUser().getId(), currentUserId))
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package tify.server.api.answer.service;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK;

import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.answer.model.response.AnswerReportResponse;
import tify.server.api.config.security.SecurityUtils;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.question.adaptor.AnswerReportAdaptor;
import tify.server.domain.domains.question.domain.AnswerReport;
import tify.server.domain.domains.question.validator.AnswerReportValidator;

@UseCase
@RequiredArgsConstructor
public class CreateDailyAnswerReportUseCase {

private final AnswerReportAdaptor answerReportAdaptor;
private final AnswerReportValidator answerReportValidator;

@Transactional
public ResponseEntity<AnswerReportResponse> execute(Long answerId) {
Long currentUserId = SecurityUtils.getCurrentUserId();
Optional<AnswerReport> report =
answerReportAdaptor.optionalQueryByUserIdAndAnswerId(currentUserId, answerId);
if (report.isPresent()) {
AnswerReportResponse response =
AnswerReportResponse.builder()
.userId(currentUserId)
.answerId(answerId)
.reportSuccess(false)
.build();
return new ResponseEntity<>(response, new HttpHeaders(), BAD_REQUEST);
} else {
answerReportValidator.isMyAnswer(currentUserId, answerId);
answerReportAdaptor.save(
AnswerReport.builder().reportUserId(currentUserId).answerId(answerId).build());
AnswerReportResponse response =
AnswerReportResponse.builder()
.userId(currentUserId)
.answerId(answerId)
.reportSuccess(true)
.build();
return new ResponseEntity<>(response, new HttpHeaders(), OK);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.answer.model.response.RetrieveAnswerCountResponse;
import tify.server.api.answer.model.vo.RetrieveAnswerCountVo;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.question.adaptor.AnswerAdaptor;
import tify.server.domain.domains.question.adaptor.DailyQuestionAdaptor;
Expand All @@ -17,9 +17,9 @@ public class RetrieveDailyAnswerCountUseCase {
private final DailyQuestionAdaptor dailyQuestionAdaptor;

@Transactional(readOnly = true)
public RetrieveAnswerCountResponse execute(Long questionId) {
public RetrieveAnswerCountVo execute(Long questionId) {
DailyQuestion dailyQuestion = dailyQuestionAdaptor.query(questionId);
Long answerCount = answerAdaptor.queryAnswerCount(questionId);
return RetrieveAnswerCountResponse.of(answerCount);
return RetrieveAnswerCountVo.of(answerCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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.RetrieveAnswerDTO;
import tify.server.api.answer.model.vo.RetrieveAnswerVo;
import tify.server.api.common.slice.SliceResponse;
import tify.server.api.utils.UserUtils;
import tify.server.core.annotation.UseCase;
Expand All @@ -29,7 +29,7 @@ public class RetrieveDailyAnswerUseCase {
private final UserUtils userUtils;

@Transactional(readOnly = true)
public SliceResponse<RetrieveAnswerDTO> execute(Long questionId, Pageable pageable) {
public SliceResponse<RetrieveAnswerVo> execute(Long questionId, Pageable pageable) {
DailyQuestion dailyQuestion = dailyQuestionAdaptor.query(questionId);
Long currentUserId = userUtils.getUserId();
List<Long> userIdList =
Expand All @@ -42,6 +42,6 @@ public SliceResponse<RetrieveAnswerDTO> execute(Long questionId, Pageable pageab
new AnswerCondition(dailyQuestion.getId(), userIdList, pageable);
Slice<AnswerVo> answers = answerAdaptor.searchAnswer(currentUserId, answerCondition);
return SliceResponse.of(
answers.map(answerVo -> RetrieveAnswerDTO.of(answerVo, currentUserId)));
answers.map(answerVo -> RetrieveAnswerVo.of(answerVo, currentUserId)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import tify.server.api.common.slice.SliceResponse;
import tify.server.api.user.model.dto.request.PatchNeighborsOrdersRequest;
import tify.server.api.user.model.dto.request.PutUserProfileRequest;
import tify.server.api.user.model.dto.request.UserOnBoardingRequest;
import tify.server.api.user.model.dto.response.OnBoardingStatusResponse;
import tify.server.api.user.model.dto.response.UserReportResponse;
import tify.server.api.user.model.dto.vo.MutualFriendsVo;
import tify.server.api.user.model.dto.vo.MyDailyQuestionAnswerVo;
import tify.server.api.user.model.dto.vo.UserDailyQuestionAnswerVo;
Expand Down Expand Up @@ -215,8 +217,8 @@ public void deleteUserBlock(@PathVariable Long toUserId) {

@Operation(summary = "유저를 신고합니다.")
@PostMapping("/report/{userId}")
public void postUserReport(@PathVariable Long userId) {
createUserReportUseCase.execute(userId);
public ResponseEntity<UserReportResponse> postUserReport(@PathVariable Long userId) {
return createUserReportUseCase.execute(userId);
}

@Operation(summary = "유저가 당한 신고의 정보를 조회합니다.")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package tify.server.api.user.model.dto.response;


import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class UserReportResponse {

private final Long fromUserId;
private final Long toUserId;
private final boolean reportSuccess;
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
package tify.server.api.user.service;

import static org.springframework.http.HttpStatus.*;

import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.config.security.SecurityUtils;
import tify.server.api.user.model.dto.response.UserReportResponse;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.user.adaptor.UserAdaptor;
import tify.server.domain.domains.user.adaptor.UserReportAdaptor;
import tify.server.domain.domains.user.domain.UserReport;
import tify.server.domain.domains.user.validator.UserValidator;

@UseCase
@RequiredArgsConstructor
public class CreateUserReportUseCase {

private final UserReportAdaptor userReportAdaptor;
private final UserAdaptor userAdaptor;
private final UserValidator userValidator;

@Transactional
public void execute(Long userId) {
public ResponseEntity<UserReportResponse> execute(Long userId) {
Long currentUserId = SecurityUtils.getCurrentUserId();
userReportAdaptor.save(
UserReport.builder()
.fromUserId(currentUserId)
.toUserId(userAdaptor.query(userId).getId())
.build());
Optional<UserReport> report =
userReportAdaptor.optionalQueryByFromUserIdAndToUserId(currentUserId, userId);
if (report.isPresent()) { // 이미 신고가 존재할 때
UserReportResponse response =
UserReportResponse.builder()
.fromUserId(currentUserId)
.toUserId(userId)
.reportSuccess(false)
.build();
return new ResponseEntity<>(response, new HttpHeaders(), BAD_REQUEST);
} else { // 새로운 신고일 때
userReportAdaptor.save(
UserReport.builder()
.fromUserId(currentUserId)
.toUserId(userAdaptor.query(userId).getId())
.build());
UserReportResponse response =
UserReportResponse.builder()
.fromUserId(currentUserId)
.toUserId(userId)
.reportSuccess(true)
.build();
return new ResponseEntity<>(response, new HttpHeaders(), OK);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package tify.server.domain.domains.question.adaptor;


import java.util.Optional;
import lombok.RequiredArgsConstructor;
import tify.server.core.annotation.Adaptor;
import tify.server.domain.domains.question.domain.AnswerReport;
import tify.server.domain.domains.question.exception.AnswerReportNotFoundException;
import tify.server.domain.domains.question.repository.AnswerReportRepository;

@Adaptor
@RequiredArgsConstructor
public class AnswerReportAdaptor {

private final AnswerReportRepository answerReportRepository;

public AnswerReport query(Long id) {
return answerReportRepository
.findById(id)
.orElseThrow(() -> AnswerReportNotFoundException.EXCEPTION);
}

public Optional<AnswerReport> optionalQueryByUserIdAndAnswerId(Long userId, Long answerId) {
return answerReportRepository.findByAnswerIdAndReportUserId(answerId, userId);
}

public void save(AnswerReport answerReport) {
answerReportRepository.save(answerReport);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package tify.server.domain.domains.question.domain;


import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import tify.server.domain.domains.AbstractTimeStamp;

@Getter
@Entity
@Table(name = "tbl_answer_report")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class AnswerReport extends AbstractTimeStamp {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotNull private Long answerId;

@NotNull private Long reportUserId;

@Builder
public AnswerReport(Long answerId, Long reportUserId) {
this.answerId = answerId;
this.reportUserId = reportUserId;
}
}
Loading

0 comments on commit 34d8495

Please sign in to comment.