From 7f47cec87c6a20766baee56d5d4ced34ee262b29 Mon Sep 17 00:00:00 2001 From: mashin2002 Date: Tue, 13 Aug 2024 12:12:37 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=AF=BC=EC=9B=90=20CR=20A?= =?UTF-8?q?PI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UnmappedImageCleanupScheduler.java | 18 ++++ .../controller/ComplaintController.java | 59 ++++++++++++ .../dto/request/ComplaintRequestDTO.java | 37 ++++++++ .../dto/response/ComplaintResponseDTO.java | 83 ++++++++++++++++ .../domain/complaint/entity/Complaint.java | 1 + .../domain/complaint/entity/ComplaintImg.java | 4 + .../exception/ComplaintErrorCode.java | 27 ++++++ .../exception/ComplaintException.java | 12 +++ .../repository/ComplaintImgRepository.java | 23 +++++ .../repository/ComplaintRepository.java | 19 ++++ .../service/ComplaintCommandService.java | 14 +++ .../service/ComplaintCommandServiceImpl.java | 95 +++++++++++++++++++ .../service/ComplaintQueryService.java | 14 +++ .../service/ComplaintQueryServiceImpl.java | 54 +++++++++++ 14 files changed, 460 insertions(+) create mode 100644 src/main/java/com/example/template/domain/complaint/controller/ComplaintController.java create mode 100644 src/main/java/com/example/template/domain/complaint/dto/request/ComplaintRequestDTO.java create mode 100644 src/main/java/com/example/template/domain/complaint/dto/response/ComplaintResponseDTO.java create mode 100644 src/main/java/com/example/template/domain/complaint/exception/ComplaintErrorCode.java create mode 100644 src/main/java/com/example/template/domain/complaint/exception/ComplaintException.java create mode 100644 src/main/java/com/example/template/domain/complaint/repository/ComplaintImgRepository.java create mode 100644 src/main/java/com/example/template/domain/complaint/repository/ComplaintRepository.java create mode 100644 src/main/java/com/example/template/domain/complaint/service/ComplaintCommandService.java create mode 100644 src/main/java/com/example/template/domain/complaint/service/ComplaintCommandServiceImpl.java create mode 100644 src/main/java/com/example/template/domain/complaint/service/ComplaintQueryService.java create mode 100644 src/main/java/com/example/template/domain/complaint/service/ComplaintQueryServiceImpl.java diff --git a/src/main/java/com/example/template/domain/board/scheduler/UnmappedImageCleanupScheduler.java b/src/main/java/com/example/template/domain/board/scheduler/UnmappedImageCleanupScheduler.java index 7c84a9f..6ea8055 100644 --- a/src/main/java/com/example/template/domain/board/scheduler/UnmappedImageCleanupScheduler.java +++ b/src/main/java/com/example/template/domain/board/scheduler/UnmappedImageCleanupScheduler.java @@ -2,6 +2,8 @@ import com.example.template.domain.board.entity.BoardImg; import com.example.template.domain.board.repository.BoardImgRepository; +import com.example.template.domain.complaint.entity.ComplaintImg; +import com.example.template.domain.complaint.repository.ComplaintImgRepository; import com.example.template.domain.message.entity.MessageImg; import com.example.template.domain.message.repository.MessageImgRepository; import com.example.template.global.config.aws.S3Manager; @@ -20,6 +22,7 @@ public class UnmappedImageCleanupScheduler { private final BoardImgRepository boardImgRepository; private final MessageImgRepository messageImgRepository; + private final ComplaintImgRepository complaintImgRepository; private final S3Manager s3Manager; @Scheduled(cron = "0 0 3 * * ?") // 매일 새벽 3시에 실행 @@ -48,6 +51,21 @@ public void cleanupUnmappedMessageImages() { log.info("[cleanupUnmappedMessageImages 실행] 쪽지 이미지 삭제완료"); } + + @Scheduled(cron = "0 0 4 * * ?") // 매일 새벽 4시에 실행 + @Transactional + public void cleanupUnmappedComplaintImages() { + List unmappedImages = complaintImgRepository.findUnmappedImages(); + + for (ComplaintImg image : unmappedImages) { + s3Manager.deleteFile(image.getImgUrl()); + complaintImgRepository.delete(image); + } + + log.info("[cleanupUnmappedComplaintImages 실행] 민원 이미지 삭제완료"); + } + + // TODO: 테스트용 수동 트리거 메서드 - 삭제 예정 public void manualCleanup() { this.cleanupUnmappedImages(); diff --git a/src/main/java/com/example/template/domain/complaint/controller/ComplaintController.java b/src/main/java/com/example/template/domain/complaint/controller/ComplaintController.java new file mode 100644 index 0000000..c98ed2f --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/controller/ComplaintController.java @@ -0,0 +1,59 @@ +package com.example.template.domain.complaint.controller; + +import com.example.template.domain.complaint.dto.request.ComplaintRequestDTO; +import com.example.template.domain.complaint.dto.response.ComplaintResponseDTO; +import com.example.template.domain.complaint.service.ComplaintCommandService; +import com.example.template.domain.complaint.service.ComplaintQueryService; +import com.example.template.domain.member.entity.Member; +import com.example.template.global.annotation.AuthenticatedMember; +import com.example.template.global.apiPayload.ApiResponse; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/complaints") +public class ComplaintController { + + private final ComplaintQueryService complaintQueryService; + private final ComplaintCommandService complaintCommandService; + + @Operation(summary = "민원글 쓰기 전 충전소 이름 얻어오기",description = "민원글 쓰기 누를 때 호출") + @GetMapping("/station/{stationId}") + ApiResponse getStationName(@PathVariable("stationId") Long stationId){ + return ApiResponse.onSuccess(complaintQueryService.getStationName(stationId)); + } + + @Operation(summary = "이미지 업로드", description = "민원글에 첨부할 이미지를 업로드.") + @PostMapping(value = "/images", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ApiResponse uploadImages( + @RequestPart("images") List images) { + return ApiResponse.onSuccess(complaintCommandService.uploadImages(images)); + } + + @Operation(summary = "새 민원글 작성") + @PostMapping() + public ApiResponse createComplaint(@AuthenticatedMember Member member, + @Valid @RequestBody ComplaintRequestDTO.CreateComplaintDTO createComplaintDTO) { + return ApiResponse.onSuccess(complaintCommandService.createComplaint(member, createComplaintDTO)); + } + + + @Operation(summary = "내가 쓴 민원글 상세 조회") + @GetMapping("/{complaintId}") + ApiResponsegetComplaintDetail(@AuthenticatedMember Member member, @PathVariable("complaintId") Long complaintId){ + return ApiResponse.onSuccess(complaintQueryService.getComplaintDetail(member, complaintId)); + } + + @Operation(summary = "내가 쓴 민원글 목록 조회") + @GetMapping() + ApiResponse> getComplaintList(@AuthenticatedMember Member member){ + return ApiResponse.onSuccess(complaintQueryService.getComplaintList(member)); + } +} diff --git a/src/main/java/com/example/template/domain/complaint/dto/request/ComplaintRequestDTO.java b/src/main/java/com/example/template/domain/complaint/dto/request/ComplaintRequestDTO.java new file mode 100644 index 0000000..9f7dd5a --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/dto/request/ComplaintRequestDTO.java @@ -0,0 +1,37 @@ +package com.example.template.domain.complaint.dto.request; + +import com.example.template.domain.complaint.entity.Complaint; +import com.example.template.domain.complaint.entity.ComplaintType; +import com.example.template.domain.member.entity.Member; +import com.example.template.domain.station.entity.Station; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +public class ComplaintRequestDTO { + @Getter + @Builder + public static class CreateComplaintDTO { + + private Long stationId; + @NotNull(message = "제목은 필수입니다.") + private String title; + @NotNull(message = "내용은 필수입니다.") + private String content; + @NotNull(message = "카테고리는 필수입니다.") + private ComplaintType complaintType; + + private List images; + + public static Complaint toEntity(CreateComplaintDTO createComplaintDTO, Station station, Member member) { + return Complaint.builder() + .title(createComplaintDTO.getTitle()) + .complaintType(createComplaintDTO.getComplaintType()) + .content(createComplaintDTO.getContent()) + .member(member) + .station(station).build(); + } + } +} diff --git a/src/main/java/com/example/template/domain/complaint/dto/response/ComplaintResponseDTO.java b/src/main/java/com/example/template/domain/complaint/dto/response/ComplaintResponseDTO.java new file mode 100644 index 0000000..bd7d3be --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/dto/response/ComplaintResponseDTO.java @@ -0,0 +1,83 @@ +package com.example.template.domain.complaint.dto.response; + +import com.example.template.domain.complaint.entity.Complaint; +import com.example.template.domain.complaint.entity.ComplaintImg; +import com.example.template.domain.complaint.entity.ComplaintType; +import com.example.template.domain.station.entity.Station; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@RequiredArgsConstructor +public class ComplaintResponseDTO { + + @Builder + @Getter + public static class getStationDTO{ + private String stationName; + + public static getStationDTO from(Station station) { + return getStationDTO.builder() + .stationName(station.getName()).build(); + } + } + + @Builder + @JsonInclude(JsonInclude.Include.NON_NULL) + @Getter + public static class ComplaintDTO { + private Long complaintId; + private String title; + private String content; + private ComplaintType complaintType; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + private List images; + + public static ComplaintDTO from(Complaint complaint, List complaintImgList){ + List complaintImgURL = complaintImgList.stream() + .map(ComplaintImg::getImgUrl) + .collect(Collectors.toList()); + + return ComplaintDTO.builder() + .complaintId(complaint.getId()) + .complaintType(complaint.getComplaintType()) + .title(complaint.getTitle()) + .content(complaint.getContent()) + .images(complaintImgURL) + .createdAt(complaint.getCreatedAt()) + .updatedAt(complaint.getUpdatedAt()) + .build(); + } + + //목록조회를 위해 이미지가 없는 버전 + public static ComplaintDTO from(Complaint complaint){ + return ComplaintDTO.builder() + .complaintId(complaint.getId()) + .complaintType(complaint.getComplaintType()) + .title(complaint.getTitle()) + .content(complaint.getContent()) + .createdAt(complaint.getCreatedAt()) + .updatedAt(complaint.getUpdatedAt()) + .build(); + } + + public static List from(List complaints) { + return complaints.stream() + .map(ComplaintDTO::from) + .collect(Collectors.toList()); + } + } + + @Getter + @Builder + public static class ComplaintImgDTO { + private List images; + } +} diff --git a/src/main/java/com/example/template/domain/complaint/entity/Complaint.java b/src/main/java/com/example/template/domain/complaint/entity/Complaint.java index fcbbafe..4e602c8 100644 --- a/src/main/java/com/example/template/domain/complaint/entity/Complaint.java +++ b/src/main/java/com/example/template/domain/complaint/entity/Complaint.java @@ -36,4 +36,5 @@ public class Complaint extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "station_id") private Station station; + } diff --git a/src/main/java/com/example/template/domain/complaint/entity/ComplaintImg.java b/src/main/java/com/example/template/domain/complaint/entity/ComplaintImg.java index 515244b..7a23bf1 100644 --- a/src/main/java/com/example/template/domain/complaint/entity/ComplaintImg.java +++ b/src/main/java/com/example/template/domain/complaint/entity/ComplaintImg.java @@ -22,4 +22,8 @@ public class ComplaintImg { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "complaint_id") private Complaint complaint; + + public void updateComplaint(Complaint complaint) { + this.complaint = complaint; + } } diff --git a/src/main/java/com/example/template/domain/complaint/exception/ComplaintErrorCode.java b/src/main/java/com/example/template/domain/complaint/exception/ComplaintErrorCode.java new file mode 100644 index 0000000..0b77e72 --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/exception/ComplaintErrorCode.java @@ -0,0 +1,27 @@ +package com.example.template.domain.complaint.exception; + +import com.example.template.global.apiPayload.ApiResponse; +import com.example.template.global.apiPayload.code.status.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum ComplaintErrorCode implements BaseErrorCode { + + // BOARD 에러 + COMPLAINT_NOT_FOUND(HttpStatus.NOT_FOUND, "COMPLAINT404", "민원글을 찾을 수 없습니다."), + + //IMAGE 에러 + INVALID_IMAGE_URLS(HttpStatus.BAD_REQUEST, "COMPLAINT400", "일부 이미지 URL이 유효하지 않거나 찾을 수 없습니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ApiResponse getErrorResponse() { + return ApiResponse.onFailure(code, message); + } +} diff --git a/src/main/java/com/example/template/domain/complaint/exception/ComplaintException.java b/src/main/java/com/example/template/domain/complaint/exception/ComplaintException.java new file mode 100644 index 0000000..f9a0d52 --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/exception/ComplaintException.java @@ -0,0 +1,12 @@ +package com.example.template.domain.complaint.exception; + +import com.example.template.global.apiPayload.code.status.BaseErrorCode; +import com.example.template.global.apiPayload.exception.GeneralException; +import lombok.Getter; + +@Getter +public class ComplaintException extends GeneralException { + public ComplaintException(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/com/example/template/domain/complaint/repository/ComplaintImgRepository.java b/src/main/java/com/example/template/domain/complaint/repository/ComplaintImgRepository.java new file mode 100644 index 0000000..0b266ee --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/repository/ComplaintImgRepository.java @@ -0,0 +1,23 @@ +package com.example.template.domain.complaint.repository; + +import com.example.template.domain.complaint.entity.ComplaintImg; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + + +@Repository +public interface ComplaintImgRepository extends JpaRepository { + + @Query("SELECT c FROM ComplaintImg c WHERE c.complaint.id = :complaintId") + List findAllByComplaintId(@Param("complaintId")Long complaintId); + + + List findAllByImgUrlIn(List images); + + @Query("SELECT c FROM ComplaintImg c WHERE c.complaint IS NULL") + List findUnmappedImages(); +} diff --git a/src/main/java/com/example/template/domain/complaint/repository/ComplaintRepository.java b/src/main/java/com/example/template/domain/complaint/repository/ComplaintRepository.java new file mode 100644 index 0000000..60fce77 --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/repository/ComplaintRepository.java @@ -0,0 +1,19 @@ +package com.example.template.domain.complaint.repository; + +import com.example.template.domain.complaint.entity.Complaint; +import com.example.template.domain.member.entity.Member; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ComplaintRepository extends JpaRepository { + + @Query("SELECT c FROM Complaint c WHERE c.member.id = :memberId") + List findAllByMemberId(@Param("memberId")Long memberId); + + Complaint findByIdAndMember(Long complaintId, Member member); +} diff --git a/src/main/java/com/example/template/domain/complaint/service/ComplaintCommandService.java b/src/main/java/com/example/template/domain/complaint/service/ComplaintCommandService.java new file mode 100644 index 0000000..a643293 --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/service/ComplaintCommandService.java @@ -0,0 +1,14 @@ +package com.example.template.domain.complaint.service; + +import com.example.template.domain.complaint.dto.request.ComplaintRequestDTO; +import com.example.template.domain.complaint.dto.response.ComplaintResponseDTO; +import com.example.template.domain.member.entity.Member; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +public interface ComplaintCommandService { + ComplaintResponseDTO.ComplaintImgDTO uploadImages(List images); + + ComplaintResponseDTO.ComplaintDTO createComplaint(Member member, ComplaintRequestDTO.CreateComplaintDTO createComplaintDTO); +} diff --git a/src/main/java/com/example/template/domain/complaint/service/ComplaintCommandServiceImpl.java b/src/main/java/com/example/template/domain/complaint/service/ComplaintCommandServiceImpl.java new file mode 100644 index 0000000..1aeddf5 --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/service/ComplaintCommandServiceImpl.java @@ -0,0 +1,95 @@ +package com.example.template.domain.complaint.service; + +import com.example.template.domain.complaint.dto.request.ComplaintRequestDTO; +import com.example.template.domain.complaint.dto.response.ComplaintResponseDTO; +import com.example.template.domain.complaint.entity.Complaint; +import com.example.template.domain.complaint.entity.ComplaintImg; +import com.example.template.domain.complaint.exception.ComplaintErrorCode; +import com.example.template.domain.complaint.exception.ComplaintException; +import com.example.template.domain.complaint.repository.ComplaintImgRepository; +import com.example.template.domain.complaint.repository.ComplaintRepository; +import com.example.template.domain.member.entity.Member; +import com.example.template.domain.station.entity.Station; +import com.example.template.domain.station.exception.StationErrorCode; +import com.example.template.domain.station.exception.StationException; +import com.example.template.domain.station.repository.StationRepository; +import com.example.template.global.config.aws.S3Manager; +import com.example.template.global.util.s3.entity.Uuid; +import com.example.template.global.util.s3.repository.UuidRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +@Transactional +public class ComplaintCommandServiceImpl implements ComplaintCommandService{ + + private final ComplaintImgRepository complaintImgRepository; + private final S3Manager s3Manager; + private final UuidRepository uuidRepository; + private final StationRepository stationRepository; + private final ComplaintRepository complaintRepository; + @Override + public ComplaintResponseDTO.ComplaintImgDTO uploadImages(List images) { + List keyNames = new ArrayList<>(); + List uuids = new ArrayList<>(); + + // UUID 생성 및 키 이름 생성 + for (MultipartFile image : images) { + if (image != null && !image.isEmpty()) { + String uuid = UUID.randomUUID().toString(); + Uuid savedUuid = Uuid.builder().uuid(uuid).build(); + uuids.add(savedUuid); + keyNames.add(s3Manager.generateComplaintKeyName(savedUuid)); + } + } + // UUID 저장 + uuidRepository.saveAll(uuids); + + List imageUrls = s3Manager.uploadFiles(keyNames, images); + + // 이미지 엔티티 생성 및 저장 (연결x) + List complaintImgs = imageUrls.stream() + .map(url -> ComplaintImg.builder().imgUrl(url).build()) + .toList(); + complaintImgRepository.saveAll(complaintImgs); + + // ComplaintImgUrl 생성 및 반환 + return ComplaintResponseDTO.ComplaintImgDTO.builder() + .images(imageUrls) + .build(); + } + + @Override + public ComplaintResponseDTO.ComplaintDTO createComplaint(Member member, ComplaintRequestDTO.CreateComplaintDTO createComplaintDTO) { + Station station = stationRepository.findById(createComplaintDTO.getStationId()). + orElseThrow(() -> new StationException(StationErrorCode.NOT_FOUND)); + Complaint complaint = ComplaintRequestDTO.CreateComplaintDTO.toEntity(createComplaintDTO, station, member); + + List complaintImgs = null; + if (createComplaintDTO.getImages() != null && !createComplaintDTO.getImages().isEmpty()) { + complaintImgs = complaintImgRepository.findAllByImgUrlIn(createComplaintDTO.getImages()); + + // S3에 등록되지 않은 이미지를 가지고 접근 + if (complaintImgs.size() != createComplaintDTO.getImages().size()) { + throw new ComplaintException(ComplaintErrorCode.INVALID_IMAGE_URLS); + } + complaintImgs.forEach(img -> img.updateComplaint(complaint)); + } + + Complaint savedComplaint = complaintRepository.save(complaint); + + if(complaintImgs!=null) { + return ComplaintResponseDTO.ComplaintDTO.from(savedComplaint, complaintImgs); + } + return ComplaintResponseDTO.ComplaintDTO.from(savedComplaint); + } + + +} diff --git a/src/main/java/com/example/template/domain/complaint/service/ComplaintQueryService.java b/src/main/java/com/example/template/domain/complaint/service/ComplaintQueryService.java new file mode 100644 index 0000000..0775fba --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/service/ComplaintQueryService.java @@ -0,0 +1,14 @@ +package com.example.template.domain.complaint.service; + +import com.example.template.domain.complaint.dto.response.ComplaintResponseDTO; +import com.example.template.domain.member.entity.Member; + +import java.util.List; + +public interface ComplaintQueryService { + ComplaintResponseDTO.getStationDTO getStationName(Long stationId); + + ComplaintResponseDTO.ComplaintDTO getComplaintDetail(Member member, Long complaintId); + + List getComplaintList(Member member); +} diff --git a/src/main/java/com/example/template/domain/complaint/service/ComplaintQueryServiceImpl.java b/src/main/java/com/example/template/domain/complaint/service/ComplaintQueryServiceImpl.java new file mode 100644 index 0000000..7abd739 --- /dev/null +++ b/src/main/java/com/example/template/domain/complaint/service/ComplaintQueryServiceImpl.java @@ -0,0 +1,54 @@ +package com.example.template.domain.complaint.service; + +import com.example.template.domain.complaint.dto.response.ComplaintResponseDTO; +import com.example.template.domain.complaint.entity.Complaint; +import com.example.template.domain.complaint.entity.ComplaintImg; +import com.example.template.domain.complaint.exception.ComplaintErrorCode; +import com.example.template.domain.complaint.exception.ComplaintException; +import com.example.template.domain.complaint.repository.ComplaintImgRepository; +import com.example.template.domain.complaint.repository.ComplaintRepository; +import com.example.template.domain.member.entity.Member; +import com.example.template.domain.station.entity.Station; +import com.example.template.domain.station.exception.StationErrorCode; +import com.example.template.domain.station.exception.StationException; +import com.example.template.domain.station.repository.StationRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@RequiredArgsConstructor +@Service +@Transactional(readOnly = true) +public class ComplaintQueryServiceImpl implements ComplaintQueryService{ + + private final StationRepository stationRepository; + private final ComplaintRepository complaintRepository; + private final ComplaintImgRepository complaintImgRepository; + + @Override + public ComplaintResponseDTO.getStationDTO getStationName(Long stationId) { + Station station = stationRepository.findById(stationId).orElseThrow(()->new StationException(StationErrorCode.NOT_FOUND)); + return ComplaintResponseDTO.getStationDTO.from(station); + } + + @Override + public ComplaintResponseDTO.ComplaintDTO getComplaintDetail(Member member, Long complaintId) { + Complaint complaint = complaintRepository.findByIdAndMember(complaintId, member); + if(complaint == null){ + throw new ComplaintException(ComplaintErrorCode.COMPLAINT_NOT_FOUND); + } + List complaintImgList = complaintImgRepository.findAllByComplaintId(complaint.getId()); + if(complaintImgList == null){ + throw new ComplaintException(ComplaintErrorCode.INVALID_IMAGE_URLS); + } + return ComplaintResponseDTO.ComplaintDTO.from(complaint); + } + + @Override + public List getComplaintList(Member member) { + List complaintList = complaintRepository.findAllByMemberId(member.getId()); + return ComplaintResponseDTO.ComplaintDTO.from(complaintList); + } +}