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 @@ -8,10 +8,14 @@
import com.DecodEat.global.apiPayload.ApiResponse;
import com.DecodEat.global.common.annotation.CurrentUser;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/reports")
Expand Down Expand Up @@ -41,4 +45,18 @@ public ApiResponse<ReportResponseDto> requestCheckImage(@CurrentUser User user,

return ApiResponse.onSuccess(reportService.requestCheckImage(user, productId, imageUrl));
}
@Operation(
summary = "상품 수정 요청 조회 (관리자)",
description = "관리자가 모든 상품 정보 수정 요청을 페이지별로 조회합니다. 영양 정보 수정과 이미지 확인 요청을 모두 포함합니다.")
@Parameters({
@Parameter(name = "page", description = "페이지 번호, 0부터 시작합니다.", example = "0"),
@Parameter(name = "size", description = "한 페이지에 보여줄 항목 수", example = "10")
})
@GetMapping
public ApiResponse<ReportResponseDto.ReportListResponseDTO> getReports(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
) {
return ApiResponse.onSuccess(reportService.getReports(page, size));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
import com.DecodEat.domain.report.dto.response.ReportResponseDto;
import com.DecodEat.domain.report.entity.ImageReport;
import com.DecodEat.domain.report.entity.NutritionReport;
import com.DecodEat.domain.report.entity.ReportRecord;
import com.DecodEat.domain.report.entity.ReportStatus;
import com.DecodEat.domain.users.entity.User;
import org.springframework.data.domain.Page;

import java.util.stream.Collectors;

public class ReportConverter {
public static ReportResponseDto toReportResponseDto(Long productId, String type){
Expand Down Expand Up @@ -44,4 +48,57 @@ public static ImageReport toImageReport(Long reporterId, Product product, String
.build();
}

// 영양 정보 신고 내용 매핑
public static ReportResponseDto.ReportedNutritionInfo toReportedNutritionInfo(NutritionReport nutritionReport){
return ReportResponseDto.ReportedNutritionInfo.builder()
.calcium(nutritionReport.getCalcium())
.carbohydrate(nutritionReport.getCarbohydrate())
.cholesterol(nutritionReport.getCholesterol())
.dietaryFiber(nutritionReport.getDietaryFiber())
.energy(nutritionReport.getEnergy())
.fat(nutritionReport.getFat())
.protein(nutritionReport.getProtein())
.satFat(nutritionReport.getSatFat())
.sodium(nutritionReport.getSodium())
.sugar(nutritionReport.getSugar())
.transFat(nutritionReport.getTransFat())
.build();
}

public static ReportResponseDto.ReportListItemDTO toReportListItemDTO(ReportRecord reportRecord){
ReportResponseDto.ReportListItemDTO.ReportListItemDTOBuilder builder = ReportResponseDto.ReportListItemDTO.builder()
.reportId(reportRecord.getId())
.reporterId(reportRecord.getReporterId())
.productId(reportRecord.getProduct().getProductId())
.productName(reportRecord.getProduct().getProductName())
.reportStatus(reportRecord.getReportStatus())
.createdAt(reportRecord.getCreatedAt());

// 영양정보 관련인지 이미지 관련인지 구분
if(reportRecord instanceof NutritionReport){
NutritionReport nutritionReport = (NutritionReport) reportRecord;
builder.reportType("NUTRITION_UPDATE")
.nutritionRequestInfo(toReportedNutritionInfo(nutritionReport));

} else if (reportRecord instanceof ImageReport) {
ImageReport imageReport = (ImageReport) reportRecord;
builder.reportType("INAPPROPRIATE_IMAGE")
.imageUrl(imageReport.getImageUrl());
}

return builder.build();
}
public static ReportResponseDto.ReportListResponseDTO toReportListResponseDTO(Page<ReportRecord> reportPage) {
return ReportResponseDto.ReportListResponseDTO.builder()
// 1. 신고 목록 변환
.reportList(reportPage.getContent().stream()
.map(ReportConverter::toReportListItemDTO)
.collect(Collectors.toList()))
// 2. 페이징 정보 매핑
.totalPage(reportPage.getTotalPages())
.totalElements(reportPage.getTotalElements())
.isFirst(reportPage.isFirst())
.isLast(reportPage.isLast())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.DecodEat.domain.report.dto.response;

import com.DecodEat.domain.report.dto.request.ProductNutritionUpdateRequestDto;
import com.DecodEat.domain.report.entity.ReportStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.List;
import java.time.LocalDateTime;

@Getter
@NoArgsConstructor
Expand All @@ -20,4 +24,84 @@ public class ReportResponseDto {
@NotNull
@Schema(name = "신고 유형", example = "영양 정보 수정")
String reportContent;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "신고된 영양정보 내용")
public static class ReportedNutritionInfo {
private Double calcium;
private Double carbohydrate;
private Double cholesterol;
private Double dietaryFiber;
private Double energy;
private Double fat;
private Double protein;
private Double satFat;
private Double sodium;
private Double sugar;
private Double transFat;
}


@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "관리자용 신고 리스트 아이템")
public static class ReportListItemDTO {

@Schema(description = "신고 ID", example = "1")
private Long reportId;

@Schema(description = "신고자 ID", example = "2")
private Long reporterId;

@Schema(description = "상품 ID", example = "13")
private Long productId;

@Schema(description = "상품명", example = "맛있는 사과")
private String productName;

@Schema(description = "신고 유형", example = "NUTRITION_UPDATE")
private String reportType;

@Schema(description = "처리 상태", example = "IN_PROGRESS")
private ReportStatus reportStatus;

@Schema(description = "신고일")
private LocalDateTime createdAt;

@Schema(description = "신고된 이미지 URL (이미지 신고인 경우)", example = "http://example.com/inappropriate.jpg", nullable = true)
private String imageUrl;

@Schema(description = "신고된 영양정보 수정 요청 내용 (영양정보 신고인 경우)", nullable = true)
private ReportedNutritionInfo nutritionRequestInfo;

}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "관리자용 신고 리스트")
public static class ReportListResponseDTO {

@Schema(description = "신고 내역 목록")
private List<ReportListItemDTO> reportList;

@Schema(description = "총 페이지 수")
private Integer totalPage;

@Schema(description = "총 신고 내역 수")
private Long totalElements;

@Schema(description = "마지막 페이지 여부")
private Boolean isLast;

@Schema(description = "첫 페이지 여부")
private Boolean isFirst;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
import com.DecodEat.domain.report.converter.ReportConverter;
import com.DecodEat.domain.report.dto.request.ProductNutritionUpdateRequestDto;
import com.DecodEat.domain.report.dto.response.ReportResponseDto;
import com.DecodEat.domain.report.entity.ReportRecord;
import com.DecodEat.domain.report.repository.ImageReportRepository;
import com.DecodEat.domain.report.repository.NutritionReportRepository;
import com.DecodEat.domain.report.repository.ReportRecordRepository;
import com.DecodEat.domain.users.entity.User;
import com.DecodEat.global.exception.GeneralException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -22,6 +28,7 @@ public class ReportService {
private final ProductRepository productRepository;
private final NutritionReportRepository nutritionReportRepository;
private final ImageReportRepository imageReportRepository;
private final ReportRecordRepository reportRecordRepository;

public ReportResponseDto requestUpdateNutrition(User user, Long productId, ProductNutritionUpdateRequestDto requestDto){

Expand All @@ -41,4 +48,11 @@ public ReportResponseDto requestCheckImage(User user, Long productId, String ima
return ReportConverter.toReportResponseDto(productId,"상품 사진 확인 요청 완료");
}

@Transactional(readOnly = true)
public ReportResponseDto.ReportListResponseDTO getReports(int page, int size) {
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<ReportRecord> reportPage = reportRecordRepository.findAll(pageable);
return ReportConverter.toReportListResponseDTO(reportPage);
}

}
2 changes: 1 addition & 1 deletion src/main/java/com/DecodEat/global/config/CorsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();

configuration.setAllowedOriginPatterns(List.of( "https://decodeat.netlify.app",
"http://localhost:8080","http://localhost:5173" ));
"http://localhost:8080","http://localhost:5173", "http://decodeat.store", "https://decodeat.store" ));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true); // 쿠키/인증정보 포함 허용
Expand Down
Loading