package kr.re.etri.autoflow.service; import kr.re.etri.autoflow.entity.DatasetAttachmentEntity; import kr.re.etri.autoflow.entity.DatasetEntity; import kr.re.etri.autoflow.payload.request.BaseSearchRequest; import kr.re.etri.autoflow.repository.DatasetAttachmentRepository; import kr.re.etri.autoflow.repository.DatasetRepository; import kr.re.etri.autoflow.specification.DatasetSpecification; import lombok.RequiredArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.data.domain.*; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @Service @RequiredArgsConstructor @Transactional(readOnly = true) public class DatasetService { private final DatasetRepository datasetRepository; private final DatasetAttachmentRepository datasetAttachmentRepository; private final DatasetSpecification datasetSpecification; private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public List findAll() { return datasetRepository.findAll(); } public Optional findById(Long id) { return datasetRepository.findById(id); } public Page search(BaseSearchRequest request) { int pageIndex = request.getPage() > 0 ? request.getPage() - 1 : 0; Pageable pageable = PageRequest.of( pageIndex, request.getSize(), Sort.by(Sort.Direction.fromString(request.getSortDirection()), request.getSortField()) ); LocalDate startDate = parseDate(request.getStartDate()); LocalDate endDate = parseDate(request.getEndDate()); Specification spec = datasetSpecification.searchByConditions( request.getSearchType(), request.getKeyword(), startDate, endDate ); return datasetRepository.findAll(spec, pageable); } private LocalDate parseDate(String dateStr) { if (dateStr == null || dateStr.isBlank()) return null; try { return LocalDate.parse(dateStr, formatter); } catch (DateTimeParseException e) { throw new IllegalArgumentException("날짜 형식이 잘못되었습니다. yyyy-MM-dd 형식이어야 합니다: " + dateStr); } } @Transactional public DatasetEntity create(DatasetEntity dataset) { return datasetRepository.save(dataset); } @Transactional public Optional update(Long id) { return datasetRepository.findById(id); } @Transactional public boolean delete(Long id) { if (!datasetRepository.existsById(id)) { return false; } datasetRepository.deleteById(id); return true; } @Transactional public DatasetEntity createWithFiles(DatasetEntity dataset, List files) { DatasetEntity saved = datasetRepository.save(dataset); if (files != null && !files.isEmpty()) { List attachments = new ArrayList<>(); for (MultipartFile file : files) { DatasetAttachmentEntity attachment = DatasetAttachmentEntity.builder() .originalName(file.getOriginalFilename()) .storedName(storeFile(file)) // 실제 파일 저장 로직 필요 .contentType(file.getContentType()) .size(file.getSize()) .regUserId(dataset.getRegUserId()) .regDt(LocalDateTime.now()) .title(file.getOriginalFilename()) .version(1) .description("") .build(); attachments.add(attachment); } // attachment 저장 datasetAttachmentRepository.saveAll(attachments); // 엔티티에 첨부파일 리스트 설정 //saved.setFiles(attachments); } return saved; } // 파일 저장 예시 private String storeFile(MultipartFile file) { // TODO: MinIO 또는 로컬 스토리지에 실제 저장 후 경로 반환 String storedName = UUID.randomUUID() + "-" + file.getOriginalFilename(); // file.transferTo(new File(uploadPath + storedName)); return storedName; } }