본문 바로가기

TIL

2023.02.17 유저 신고 기능 구현

entity

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
public class ReportHistory extends TimeStamp {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @ManyToOne
  @JoinColumn(nullable = false)
  private User reporter;

  private String reporterUserName;

  @ManyToOne
  @JoinColumn(nullable = false)
  private User reportedUser;
  private String reportedUsername;

  @Column(nullable = false)
  private String content;

  @Column
  private int reportCount;


  public ReportHistory(User reporter, User reportedUser, String content) {
    this.reporterUserName = reporter.getUsername();
    this.reportedUsername = reportedUser.getUsername();
    this.reporter = reporter;
    this.reportedUser = reportedUser;
    this.content = content;
    this.reportCount = getReportCount();
  }
}

신고자와 신고된 사용자의 username을 User의 username을 통해 가져온다. 

신고 내용과 신고된 사용자의 신고 당한 횟수가 저장된다.

 

 Service

import com.sparta.hotbody.report.dto.ReportRequestDto;
import com.sparta.hotbody.report.dto.ReportResponseDto;
import com.sparta.hotbody.report.entity.ReportHistory;
import com.sparta.hotbody.report.exception.AlreadyReportException;
import com.sparta.hotbody.report.exception.NotSelfReportException;
import com.sparta.hotbody.report.repository.ReportRepository;
import com.sparta.hotbody.user.entity.User;
import com.sparta.hotbody.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Service
public class ReportService {
  private final static int NORMAL_USER_REPORT_LIMIT_FOR_BEING_REPORTED = 3;
  public final ReportRepository reportRepository;
  public final UserRepository userRepository;
  
  public final ReportRepository userReportHistoryRepository;

  @Transactional
  public ReportResponseDto reportUser(User reporter, ReportRequestDto reportRequestDto) {
    validateUserReportRequest(reporter, reportRequestDto); // 자기 자신 혹은 중복 신고인지 확인
    User reported = userRepository.findByUsername(reportRequestDto.getReportedUsername()).orElseThrow(RuntimeException::new);
    ReportHistory userReportHistory = createUserReportHistory(reporter, reported, reportRequestDto);
    userReportHistory.setReportCount(userReportHistoryRepository.findByReportedUsername(reportRequestDto.getReportedUsername()).size());
    checkUserStatusIsBeingReported(reported, reportRequestDto);
    return new ReportResponseDto(userReportHistory.getReporter().getUsername(), reported.getUsername(), reportRequestDto.getContent(), userReportHistory.getCreatedAt());
  }

  private void checkUserStatusIsBeingReported(User reported, ReportRequestDto reportRequestDto) {
    if (userReportHistoryRepository.findByReportedUsername(reportRequestDto.getReportedUsername()).size() //특정 유저의 신고된 횟수가 3이상 이면
        >= NORMAL_USER_REPORT_LIMIT_FOR_BEING_REPORTED) {
      reported.reportedUserChangeRole(); // 역할을 REPORTED(신고된 유저)로 변경
    }
  }

  private ReportHistory createUserReportHistory(User reporter, User reported, ReportRequestDto reportRequestDto) {
    ReportHistory userReportHistory = new ReportHistory(reporter, reported, reportRequestDto.getContent());
    userReportHistoryRepository.save(userReportHistory);
    return userReportHistory;
  }

  private void validateUserReportRequest(User reporter, ReportRequestDto reportRequestDto) {
    if (reporter.getUsername().equals(reportRequestDto.getReportedUsername())) {
      throw new NotSelfReportException();
    }
    if (userReportHistoryRepository.existsByReporterUsernameAndReportedUsername(reporter.getUsername(), reportRequestDto.getReportedUsername())) {
      throw new AlreadyReportException();
    }
  }


}
  1. 자기 자신 혹은 중복 신고인지 확인
  2. 신고된 사용자를 변수에 저장
  3. 신고자, 신고된 사용자, 신고내용 저장
  4. 신고된 사용자의 이름을 검색하여 해당 유저가 신고당한 횟수 저장
  5. 신고 횟수가 3번 이상이면 신고자의 역할을 변경
  6. Response반환

어려웠던 점

  1. 자기 자신 혹은 중복 신고인지 확인하는 것
  2. 신고 횟수 저장

해결법

  1. 신고자와 신고된 자의 사용자 이름을 비교하여 해결, 신고자와 신고된 자가 이미 존재하는 지 여부 판별
  2. 신고된 자의 사용자 이름을 검색하여 사이즈를 저장

'TIL' 카테고리의 다른 글

2023.02.15 S3 이미지 업로드 ( 프로필, 게시판)  (0) 2023.02.15
Index  (1) 2023.02.14
[WIL] 2023.02.06~02.10  (0) 2023.02.13
운동, 식단 관리 및 정보 공유 웹사이트(1)  (0) 2023.02.09
CI/CD  (0) 2023.01.31