package kr.re.etri.autoflow.specification; import jakarta.annotation.PostConstruct; import jakarta.persistence.EntityManager; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.Attribute; import jakarta.persistence.metamodel.EntityType; import jakarta.persistence.metamodel.Metamodel; import kr.re.etri.autoflow.entity.MinioAttachmentEntity; import lombok.extern.slf4j.Slf4j; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import java.time.LocalDate; import java.util.Set; import java.util.stream.Collectors; @Slf4j @Component public class MinioAttachmentSpecification { private final EntityManager entityManager; private Set stringFields; public MinioAttachmentSpecification(EntityManager entityManager) { this.entityManager = entityManager; } @PostConstruct public void init() { Metamodel metamodel = entityManager.getMetamodel(); EntityType entityType = metamodel.entity(MinioAttachmentEntity.class); // 문자열 타입 필드명만 추출 stringFields = entityType.getAttributes().stream() .filter(attr -> attr.getJavaType().equals(String.class)) .map(Attribute::getName) .collect(Collectors.toSet()); log.info("MinioAttachmentEntity string fields: {}", stringFields); } public Specification searchByConditions( String refType, Integer refId, String searchType, String keyword, LocalDate startDate, LocalDate endDate ) { return (root, query, cb) -> { Predicate predicate = cb.conjunction(); // refType 조건 추가 if (refType != null && !refType.isBlank()) { predicate = cb.and(predicate, cb.equal(root.get("refType"), refType)); } // refId 조건 추가 if (refId != null ) { predicate = cb.and(predicate, cb.equal(root.get("refId"), refId)); } // keyword 검색 if (keyword != null && !keyword.isEmpty()) { if (searchType == null || searchType.isEmpty() || "전체".equalsIgnoreCase(searchType) || "all".equalsIgnoreCase(searchType)) { Predicate orPredicate = cb.disjunction(); for (String field : stringFields) { orPredicate = cb.or(orPredicate, cb.like(cb.lower(root.get(field)), "%" + keyword.toLowerCase() + "%")); } predicate = cb.and(predicate, orPredicate); } else if (stringFields.contains(searchType)) { predicate = cb.and(predicate, cb.like(cb.lower(root.get(searchType)), "%" + keyword.toLowerCase() + "%")); } } // 날짜 검색 if (startDate != null) { predicate = cb.and(predicate, cb.greaterThanOrEqualTo(root.get("regDt"), startDate.atStartOfDay())); } if (endDate != null) { predicate = cb.and(predicate, cb.lessThanOrEqualTo(root.get("regDt"), endDate.atTime(23, 59, 59))); } return predicate; }; } }