Skip to content

Commit c67f9a6

Browse files
authored
Merge pull request #31 from Decodeat/Feat/#24
Feat/#24
2 parents 125bcac + 790a724 commit c67f9a6

File tree

5 files changed

+174
-1
lines changed

5 files changed

+174
-1
lines changed

src/main/java/com/DecodEat/domain/report/controller/ReportController.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
import com.DecodEat.global.apiPayload.ApiResponse;
99
import com.DecodEat.global.common.annotation.CurrentUser;
1010
import io.swagger.v3.oas.annotations.Operation;
11+
import io.swagger.v3.oas.annotations.Parameter;
12+
import io.swagger.v3.oas.annotations.Parameters;
1113
import io.swagger.v3.oas.annotations.tags.Tag;
1214
import lombok.RequiredArgsConstructor;
1315
import org.springframework.web.bind.annotation.*;
1416

17+
import java.util.List;
18+
1519
@RestController
1620
@RequiredArgsConstructor
1721
@RequestMapping("/api/reports")
@@ -41,4 +45,18 @@ public ApiResponse<ReportResponseDto> requestCheckImage(@CurrentUser User user,
4145

4246
return ApiResponse.onSuccess(reportService.requestCheckImage(user, productId, imageUrl));
4347
}
48+
@Operation(
49+
summary = "상품 수정 요청 조회 (관리자)",
50+
description = "관리자가 모든 상품 정보 수정 요청을 페이지별로 조회합니다. 영양 정보 수정과 이미지 확인 요청을 모두 포함합니다.")
51+
@Parameters({
52+
@Parameter(name = "page", description = "페이지 번호, 0부터 시작합니다.", example = "0"),
53+
@Parameter(name = "size", description = "한 페이지에 보여줄 항목 수", example = "10")
54+
})
55+
@GetMapping
56+
public ApiResponse<ReportResponseDto.ReportListResponseDTO> getReports(
57+
@RequestParam(defaultValue = "0") int page,
58+
@RequestParam(defaultValue = "10") int size
59+
) {
60+
return ApiResponse.onSuccess(reportService.getReports(page, size));
61+
}
4462
}

src/main/java/com/DecodEat/domain/report/converter/ReportConverter.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
import com.DecodEat.domain.report.dto.response.ReportResponseDto;
66
import com.DecodEat.domain.report.entity.ImageReport;
77
import com.DecodEat.domain.report.entity.NutritionReport;
8+
import com.DecodEat.domain.report.entity.ReportRecord;
89
import com.DecodEat.domain.report.entity.ReportStatus;
910
import com.DecodEat.domain.users.entity.User;
11+
import org.springframework.data.domain.Page;
12+
13+
import java.util.stream.Collectors;
1014

1115
public class ReportConverter {
1216
public static ReportResponseDto toReportResponseDto(Long productId, String type){
@@ -44,4 +48,57 @@ public static ImageReport toImageReport(Long reporterId, Product product, String
4448
.build();
4549
}
4650

51+
// 영양 정보 신고 내용 매핑
52+
public static ReportResponseDto.ReportedNutritionInfo toReportedNutritionInfo(NutritionReport nutritionReport){
53+
return ReportResponseDto.ReportedNutritionInfo.builder()
54+
.calcium(nutritionReport.getCalcium())
55+
.carbohydrate(nutritionReport.getCarbohydrate())
56+
.cholesterol(nutritionReport.getCholesterol())
57+
.dietaryFiber(nutritionReport.getDietaryFiber())
58+
.energy(nutritionReport.getEnergy())
59+
.fat(nutritionReport.getFat())
60+
.protein(nutritionReport.getProtein())
61+
.satFat(nutritionReport.getSatFat())
62+
.sodium(nutritionReport.getSodium())
63+
.sugar(nutritionReport.getSugar())
64+
.transFat(nutritionReport.getTransFat())
65+
.build();
66+
}
67+
68+
public static ReportResponseDto.ReportListItemDTO toReportListItemDTO(ReportRecord reportRecord){
69+
ReportResponseDto.ReportListItemDTO.ReportListItemDTOBuilder builder = ReportResponseDto.ReportListItemDTO.builder()
70+
.reportId(reportRecord.getId())
71+
.reporterId(reportRecord.getReporterId())
72+
.productId(reportRecord.getProduct().getProductId())
73+
.productName(reportRecord.getProduct().getProductName())
74+
.reportStatus(reportRecord.getReportStatus())
75+
.createdAt(reportRecord.getCreatedAt());
76+
77+
// 영양정보 관련인지 이미지 관련인지 구분
78+
if(reportRecord instanceof NutritionReport){
79+
NutritionReport nutritionReport = (NutritionReport) reportRecord;
80+
builder.reportType("NUTRITION_UPDATE")
81+
.nutritionRequestInfo(toReportedNutritionInfo(nutritionReport));
82+
83+
} else if (reportRecord instanceof ImageReport) {
84+
ImageReport imageReport = (ImageReport) reportRecord;
85+
builder.reportType("INAPPROPRIATE_IMAGE")
86+
.imageUrl(imageReport.getImageUrl());
87+
}
88+
89+
return builder.build();
90+
}
91+
public static ReportResponseDto.ReportListResponseDTO toReportListResponseDTO(Page<ReportRecord> reportPage) {
92+
return ReportResponseDto.ReportListResponseDTO.builder()
93+
// 1. 신고 목록 변환
94+
.reportList(reportPage.getContent().stream()
95+
.map(ReportConverter::toReportListItemDTO)
96+
.collect(Collectors.toList()))
97+
// 2. 페이징 정보 매핑
98+
.totalPage(reportPage.getTotalPages())
99+
.totalElements(reportPage.getTotalElements())
100+
.isFirst(reportPage.isFirst())
101+
.isLast(reportPage.isLast())
102+
.build();
103+
}
47104
}

src/main/java/com/DecodEat/domain/report/dto/response/ReportResponseDto.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.DecodEat.domain.report.dto.response;
22

3+
import com.DecodEat.domain.report.dto.request.ProductNutritionUpdateRequestDto;
4+
import com.DecodEat.domain.report.entity.ReportStatus;
35
import io.swagger.v3.oas.annotations.media.Schema;
46
import jakarta.validation.constraints.NotNull;
57
import lombok.AllArgsConstructor;
68
import lombok.Builder;
79
import lombok.Getter;
810
import lombok.NoArgsConstructor;
11+
import java.util.List;
12+
import java.time.LocalDateTime;
913

1014
@Getter
1115
@NoArgsConstructor
@@ -20,4 +24,84 @@ public class ReportResponseDto {
2024
@NotNull
2125
@Schema(name = "신고 유형", example = "영양 정보 수정")
2226
String reportContent;
27+
28+
@Getter
29+
@Builder
30+
@NoArgsConstructor
31+
@AllArgsConstructor
32+
@Schema(description = "신고된 영양정보 내용")
33+
public static class ReportedNutritionInfo {
34+
private Double calcium;
35+
private Double carbohydrate;
36+
private Double cholesterol;
37+
private Double dietaryFiber;
38+
private Double energy;
39+
private Double fat;
40+
private Double protein;
41+
private Double satFat;
42+
private Double sodium;
43+
private Double sugar;
44+
private Double transFat;
45+
}
46+
47+
48+
@Getter
49+
@Builder
50+
@NoArgsConstructor
51+
@AllArgsConstructor
52+
@Schema(description = "관리자용 신고 리스트 아이템")
53+
public static class ReportListItemDTO {
54+
55+
@Schema(description = "신고 ID", example = "1")
56+
private Long reportId;
57+
58+
@Schema(description = "신고자 ID", example = "2")
59+
private Long reporterId;
60+
61+
@Schema(description = "상품 ID", example = "13")
62+
private Long productId;
63+
64+
@Schema(description = "상품명", example = "맛있는 사과")
65+
private String productName;
66+
67+
@Schema(description = "신고 유형", example = "NUTRITION_UPDATE")
68+
private String reportType;
69+
70+
@Schema(description = "처리 상태", example = "IN_PROGRESS")
71+
private ReportStatus reportStatus;
72+
73+
@Schema(description = "신고일")
74+
private LocalDateTime createdAt;
75+
76+
@Schema(description = "신고된 이미지 URL (이미지 신고인 경우)", example = "http://example.com/inappropriate.jpg", nullable = true)
77+
private String imageUrl;
78+
79+
@Schema(description = "신고된 영양정보 수정 요청 내용 (영양정보 신고인 경우)", nullable = true)
80+
private ReportedNutritionInfo nutritionRequestInfo;
81+
82+
}
83+
84+
@Getter
85+
@Builder
86+
@NoArgsConstructor
87+
@AllArgsConstructor
88+
@Schema(description = "관리자용 신고 리스트")
89+
public static class ReportListResponseDTO {
90+
91+
@Schema(description = "신고 내역 목록")
92+
private List<ReportListItemDTO> reportList;
93+
94+
@Schema(description = "총 페이지 수")
95+
private Integer totalPage;
96+
97+
@Schema(description = "총 신고 내역 수")
98+
private Long totalElements;
99+
100+
@Schema(description = "마지막 페이지 여부")
101+
private Boolean isLast;
102+
103+
@Schema(description = "첫 페이지 여부")
104+
private Boolean isFirst;
105+
}
106+
23107
}

src/main/java/com/DecodEat/domain/report/service/ReportService.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
import com.DecodEat.domain.report.converter.ReportConverter;
66
import com.DecodEat.domain.report.dto.request.ProductNutritionUpdateRequestDto;
77
import com.DecodEat.domain.report.dto.response.ReportResponseDto;
8+
import com.DecodEat.domain.report.entity.ReportRecord;
89
import com.DecodEat.domain.report.repository.ImageReportRepository;
910
import com.DecodEat.domain.report.repository.NutritionReportRepository;
11+
import com.DecodEat.domain.report.repository.ReportRecordRepository;
1012
import com.DecodEat.domain.users.entity.User;
1113
import com.DecodEat.global.exception.GeneralException;
1214
import lombok.RequiredArgsConstructor;
15+
import org.springframework.data.domain.Page;
16+
import org.springframework.data.domain.PageRequest;
17+
import org.springframework.data.domain.Pageable;
18+
import org.springframework.data.domain.Sort;
1319
import org.springframework.stereotype.Service;
1420
import org.springframework.transaction.annotation.Transactional;
1521

@@ -22,6 +28,7 @@ public class ReportService {
2228
private final ProductRepository productRepository;
2329
private final NutritionReportRepository nutritionReportRepository;
2430
private final ImageReportRepository imageReportRepository;
31+
private final ReportRecordRepository reportRecordRepository;
2532

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

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

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

src/main/java/com/DecodEat/global/config/CorsConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public CorsConfigurationSource corsConfigurationSource() {
1616
CorsConfiguration configuration = new CorsConfiguration();
1717

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

0 commit comments

Comments
 (0)