From c91b768aa30a2f95e24202b4d18f639933ac1ca9 Mon Sep 17 00:00:00 2001 From: bjkim Date: Wed, 17 Sep 2025 19:19:56 +0900 Subject: [PATCH] =?UTF-8?q?[ADD]=20DataGroup=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20(Entity,=20Repository?= =?UTF-8?q?,=20Service,=20Controller)=20=EB=B0=8F=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EC=85=8B=20=EC=83=9D=EC=84=B1=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/DataGroupController.java | 87 +++++++++++++++ .../controllers/DatasetController.java | 71 ++++++++++--- .../autoflow/controllers/MinIOController.java | 5 +- .../etri/autoflow/entity/DataGroupEntity.java | 72 +++++++++++++ .../entity/DatasetAttachmentEntity.java | 4 + .../etri/autoflow/entity/DatasetEntity.java | 8 +- .../payload/request/DataGroupRequest.java | 40 +++++++ .../repository/DataGroupRepository.java | 12 +++ .../autoflow/service/DataGroupService.java | 100 ++++++++++++++++++ .../etri/autoflow/service/DatasetService.java | 4 +- .../specification/DataGroupSpecification.java | 80 ++++++++++++++ 11 files changed, 459 insertions(+), 24 deletions(-) create mode 100644 src/main/java/kr/re/etri/autoflow/controllers/DataGroupController.java create mode 100644 src/main/java/kr/re/etri/autoflow/entity/DataGroupEntity.java create mode 100644 src/main/java/kr/re/etri/autoflow/payload/request/DataGroupRequest.java create mode 100644 src/main/java/kr/re/etri/autoflow/repository/DataGroupRepository.java create mode 100644 src/main/java/kr/re/etri/autoflow/service/DataGroupService.java create mode 100644 src/main/java/kr/re/etri/autoflow/specification/DataGroupSpecification.java diff --git a/src/main/java/kr/re/etri/autoflow/controllers/DataGroupController.java b/src/main/java/kr/re/etri/autoflow/controllers/DataGroupController.java new file mode 100644 index 0000000..0b173db --- /dev/null +++ b/src/main/java/kr/re/etri/autoflow/controllers/DataGroupController.java @@ -0,0 +1,87 @@ +package kr.re.etri.autoflow.controllers; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.tags.Tag; +import kr.re.etri.autoflow.entity.DataGroupEntity; +import kr.re.etri.autoflow.payload.request.BaseSearchRequest; +import kr.re.etri.autoflow.payload.request.ProjectRequest; +import kr.re.etri.autoflow.service.DataGroupService; +import kr.re.etri.autoflow.service.ProjectService; +import lombok.RequiredArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.data.domain.Page; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Tag(name = "데이터 그룹", description = "Project CRUD 기능 제공") +@CrossOrigin(origins = "*", maxAge = 3600) +@RestController +@RequestMapping("/api/datagroup") +@RequiredArgsConstructor +public class DataGroupController { + + private final DataGroupService dataGroupService; + + @Operation(summary = "전체 프로젝트 목록 조회") + @GetMapping + public ResponseEntity> getAllProjects() { + return ResponseEntity.ok(dataGroupService.findAll()); + } + + @Operation(summary = "ID로 프로젝트 조회") + @GetMapping("/{id}") + public ResponseEntity getProjectById( + @Parameter(description = "조회할 프로젝트 ID", required = true, in = ParameterIn.PATH) + @PathVariable("id") Long id) { + + return dataGroupService.findById(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @Operation(summary = "검색 및 페이지네이션 프로젝트 목록 조회") + @GetMapping("/search") + public ResponseEntity> searchProjects( + @ParameterObject @ModelAttribute BaseSearchRequest request) { + Page page = dataGroupService.search(request); + return ResponseEntity.ok(page); + } + + @Operation(summary = "프로젝트 생성") + @PostMapping + public ResponseEntity createProject(@RequestBody DataGroupEntity project) { + try { + DataGroupEntity saved = dataGroupService.create(project); + return ResponseEntity.ok(saved); + } catch (IllegalArgumentException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + @Operation(summary = "프로젝트 수정") + @PutMapping("/{id}") + public ResponseEntity updateProject( + @Parameter(description = "수정할 프로젝트 ID", required = true, in = ParameterIn.PATH) + @PathVariable("id") Long id, + @RequestBody ProjectRequest dto) { + + return dataGroupService.update(id, dto) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @Operation(summary = "프로젝트 삭제") + @DeleteMapping("/{id}") + public ResponseEntity deleteProject( + @Parameter(description = "삭제할 프로젝트 ID", required = true, in = ParameterIn.PATH) + @PathVariable("id") Long id) { + if (dataGroupService.delete(id)) { + return ResponseEntity.noContent().build(); + } + return ResponseEntity.notFound().build(); + } +} diff --git a/src/main/java/kr/re/etri/autoflow/controllers/DatasetController.java b/src/main/java/kr/re/etri/autoflow/controllers/DatasetController.java index a45ccc2..eb33a34 100644 --- a/src/main/java/kr/re/etri/autoflow/controllers/DatasetController.java +++ b/src/main/java/kr/re/etri/autoflow/controllers/DatasetController.java @@ -7,7 +7,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import kr.re.etri.autoflow.entity.DatasetEntity; import kr.re.etri.autoflow.entity.ProjectEntity; import kr.re.etri.autoflow.payload.request.BaseSearchRequest; -import kr.re.etri.autoflow.payload.request.DatasetRequest; import kr.re.etri.autoflow.service.DatasetService; import lombok.RequiredArgsConstructor; import org.springdoc.core.annotations.ParameterObject; @@ -53,29 +52,67 @@ public class DatasetController { return ResponseEntity.ok(page); } - @Operation(summary = "데이터셋 생성 (Swagger 전용)") +// @Operation(summary = "데이터셋 생성 (Swagger 전용, 첨부파일 포함, DTO 미사용)") +// @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) +// public ResponseEntity createDataset( +// @Parameter(description = "데이터셋 이름", required = true) +// @RequestParam("dsNm") String dsNm, +// @Parameter(description = "데이터셋 설명", required = false) +// @RequestParam(value = "dsDesc", required = false) String dsDesc, +// @Parameter(description = "삭제 여부", required = false, example = "N") +// @RequestParam(value = "delYn", required = false, defaultValue = "N") String delYn, +// @Parameter(description = "등록 유저 ID", required = true) +// @RequestParam("regUserId") String regUserId, +// @Parameter(description = "등록 유저 이름", required = false) +// @RequestParam(value = "regUserNm", required = false) String regUserNm, +// @Parameter(description = "첨부파일", required = false) +// @RequestPart(value = "files", required = false) List files +// ) { +// // Entity 생성 +// DatasetEntity dataset = DatasetEntity.builder() +// .dsNm(dsNm) +// .dsDesc(dsDesc) +// .delYn(delYn) +// .regUserId(regUserId) +// .regUserNm(regUserNm) +// .build(); +// +// // Service 호출 (Dataset 저장 + 첨부파일 업로드 처리) +// DatasetEntity savedDataset = datasetService.createWithFiles(dataset, files); +// +// return ResponseEntity.ok(savedDataset); +// } + + + @Operation(summary = "데이터셋 생성 + 첨부파일 업로드 (Swagger 전용)") @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity createDataset( - @Parameter(description = "데이터셋 정보", required = true) - @ModelAttribute DatasetRequest request, + public ResponseEntity createDatasetWithFiles( + @Parameter(description = "데이터셋 이름", required = true) + @RequestParam("dsNm") String dsNm, + @Parameter(description = "데이터셋 설명", required = false) + @RequestParam(value = "dsDesc", required = false) String dsDesc, + @Parameter(description = "삭제 여부", required = false, example = "N") + @RequestParam(value = "delYn", required = false, defaultValue = "N") String delYn, + @Parameter(description = "등록 유저 ID", required = true) + @RequestParam("regUserId") String regUserId, + @Parameter(description = "등록 유저 이름", required = false) + @RequestParam(value = "regUserNm", required = false) String regUserNm, @Parameter(description = "첨부파일", required = false) - @RequestPart(value = "files", required = false) List files) { - - // DTO → Entity 변환 + @RequestPart(value = "files", required = false) List files + ) { DatasetEntity dataset = DatasetEntity.builder() - .dsNm(request.getDsNm()) - .dsDesc(request.getDsDesc()) - .delYn(request.getDelYn()) - .regUserId(request.getRegUserId()) - .regUserNm(request.getRegUserNm()) + .dsNm(dsNm) + .dsDesc(dsDesc) + .delYn(delYn) + .regUserId(regUserId) + .regUserNm(regUserNm) .build(); - System.out.println("DatasetController.createDataset: " + dataset.toString()); - - DatasetEntity saved = datasetService.createWithFiles(dataset, files); - return ResponseEntity.ok(saved); + DatasetEntity savedDataset = datasetService.createWithFiles(dataset, files); + return ResponseEntity.ok(savedDataset); } + // // @Operation(summary = "데이터셋 생성") // @PostMapping diff --git a/src/main/java/kr/re/etri/autoflow/controllers/MinIOController.java b/src/main/java/kr/re/etri/autoflow/controllers/MinIOController.java index 1c1e353..e223e62 100644 --- a/src/main/java/kr/re/etri/autoflow/controllers/MinIOController.java +++ b/src/main/java/kr/re/etri/autoflow/controllers/MinIOController.java @@ -85,7 +85,9 @@ public class MinIOController { @RequestParam(value = "title", required = false, defaultValue = "배터리 퍼센트 데이터 셋") String title, @RequestParam(value = "description", required = false, defaultValue = "배터리 퍼센트 데이터 모음") String description, @RequestParam(value = "version", required = false, defaultValue = "1") Integer version, - @RequestParam(value = "regUserId") String regUserId + @RequestParam(value = "regUserId") String regUserId, + @RequestParam(value = "refId") Long refId + ) { try (InputStream is = file.getInputStream()) { String storedName = UUID.randomUUID() + "-" + file.getOriginalFilename(); @@ -114,6 +116,7 @@ public class MinIOController { .version(version) .description(description) .regUserId(regUserId) + .refId(refId) .build(); DatasetAttachmentEntity saved = datasetAttachmentRepository.save(attachment); diff --git a/src/main/java/kr/re/etri/autoflow/entity/DataGroupEntity.java b/src/main/java/kr/re/etri/autoflow/entity/DataGroupEntity.java new file mode 100644 index 0000000..3192608 --- /dev/null +++ b/src/main/java/kr/re/etri/autoflow/entity/DataGroupEntity.java @@ -0,0 +1,72 @@ +package kr.re.etri.autoflow.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.Comment; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Schema(description = "데이터그룹") +@Comment("데이터그룹") +@Entity +@Table(name = "tb_datagroup") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class DataGroupEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Schema(description = "ID", example = "null") + @Comment("ID") + private Long id; + + @Schema(description = "데이터셋 이름", example = "배터리 상태 데이터 셋") + @Comment("데이터셋 이름") + private String dsNm; + + @Schema(description = "데이터셋 설명", example = "EV6 차량의 배터리 상태 모음") + @Comment("데이터셋 설명") + private String dsDesc; + + @Schema(description = "삭제 여부", example = "N") + @Comment("삭제 여부") + private String delYn; + + @CreatedDate + @Schema(description = "등록 일자") + @Comment("등록 일자") + private LocalDateTime regDate; + + @Schema(description = "등록 유저 ID", example = "system") + @Comment("등록 유저 ID") + private String regUserId; + + @Schema(description = "등록 유저 이름", example = "시스템") + @Comment("등록 유저 이름") + private String regUserNm; + + @LastModifiedDate + @Schema(description = "수정 일자") + @Comment("수정 일자") + private LocalDateTime modDate; + + @Schema(description = "수정 유저 ID", example = "system") + @Comment("수정 유저 ID") + private String modUserId; + + @Schema(description = "수정 유저 이름", example = "시스템") + @Comment("수정 유저 이름") + private String modUserNm; + + @OneToMany + @JoinColumn(name = "refId", referencedColumnName = "id", insertable = false, updatable = false) + private List files = new ArrayList<>(); +} diff --git a/src/main/java/kr/re/etri/autoflow/entity/DatasetAttachmentEntity.java b/src/main/java/kr/re/etri/autoflow/entity/DatasetAttachmentEntity.java index f8d61e2..35cd5b6 100644 --- a/src/main/java/kr/re/etri/autoflow/entity/DatasetAttachmentEntity.java +++ b/src/main/java/kr/re/etri/autoflow/entity/DatasetAttachmentEntity.java @@ -30,6 +30,10 @@ public class DatasetAttachmentEntity { @Comment("첨부파일 ID") private Long id; + @Schema(description = "연관 엔티티 ID", example = "1") + @Column(nullable = false) + private Long refId; + @Schema(description = "원본 파일명", example = "step1.yaml") @Comment("원본 파일명") @Column(nullable = false, length = 255) diff --git a/src/main/java/kr/re/etri/autoflow/entity/DatasetEntity.java b/src/main/java/kr/re/etri/autoflow/entity/DatasetEntity.java index 8a5022e..ae2fa51 100644 --- a/src/main/java/kr/re/etri/autoflow/entity/DatasetEntity.java +++ b/src/main/java/kr/re/etri/autoflow/entity/DatasetEntity.java @@ -65,8 +65,8 @@ public class DatasetEntity { @Schema(description = "수정 유저 이름", example = "시스템") @Comment("수정 유저 이름") private String modUserNm; -// -// @OneToMany -// @JoinColumn(name = "refId", referencedColumnName = "id", insertable = false, updatable = false) -// private List files = new ArrayList<>(); + + @OneToMany + @JoinColumn(name = "refId", referencedColumnName = "id", insertable = false, updatable = false) + private List files = new ArrayList<>(); } diff --git a/src/main/java/kr/re/etri/autoflow/payload/request/DataGroupRequest.java b/src/main/java/kr/re/etri/autoflow/payload/request/DataGroupRequest.java new file mode 100644 index 0000000..c7691ad --- /dev/null +++ b/src/main/java/kr/re/etri/autoflow/payload/request/DataGroupRequest.java @@ -0,0 +1,40 @@ +package kr.re.etri.autoflow.payload.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +@Schema(description = "프로젝트 요청 정보") +public class DataGroupRequest { + + @Schema(description = "데이터셋 이름", example = "배터리 상태 데이터 셋", required = true) + private String dsNm; + + @Schema(description = "데이터셋 설명", example = "EV6 차량의 배터리 상태 모음") + private String dsDesc; + + @Schema(description = "삭제 여부", example = "N") + private String delYn; + + @Schema(description = "등록 유저 ID", example = "system", required = true) + private String regUserId; + + @Schema(description = "등록 유저 이름", example = "시스템") + private String regUserNm; + + @Schema(description = "수정 유저 ID", example = "system") + private String modUserId; + + @Schema(description = "수정 유저 이름", example = "시스템") + private String modUserNm; + + @Schema(description = "등록 일자 (생략 가능, 서버에서 세팅 가능)") + private LocalDateTime regDate; + + @Schema(description = "수정 일자 (생략 가능, 서버에서 세팅 가능)") + private LocalDateTime modDate; +} \ No newline at end of file diff --git a/src/main/java/kr/re/etri/autoflow/repository/DataGroupRepository.java b/src/main/java/kr/re/etri/autoflow/repository/DataGroupRepository.java new file mode 100644 index 0000000..fd10fb0 --- /dev/null +++ b/src/main/java/kr/re/etri/autoflow/repository/DataGroupRepository.java @@ -0,0 +1,12 @@ +package kr.re.etri.autoflow.repository; + +import kr.re.etri.autoflow.entity.DataGroupEntity; +import kr.re.etri.autoflow.entity.ProjectEntity; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface DataGroupRepository extends JpaRepository, JpaSpecificationExecutor { + //Page findBy(String keyword, Pageable pageable); +} diff --git a/src/main/java/kr/re/etri/autoflow/service/DataGroupService.java b/src/main/java/kr/re/etri/autoflow/service/DataGroupService.java new file mode 100644 index 0000000..433bc40 --- /dev/null +++ b/src/main/java/kr/re/etri/autoflow/service/DataGroupService.java @@ -0,0 +1,100 @@ +package kr.re.etri.autoflow.service; + +import kr.re.etri.autoflow.entity.DataGroupEntity; +import kr.re.etri.autoflow.payload.request.BaseSearchRequest; +import kr.re.etri.autoflow.payload.request.ProjectRequest; +import kr.re.etri.autoflow.repository.DataGroupRepository; +import kr.re.etri.autoflow.repository.ProjectRepository; +import kr.re.etri.autoflow.repository.UserProjectMapRepository; +import kr.re.etri.autoflow.repository.UserRepository; +import kr.re.etri.autoflow.specification.DataGroupSpecification; +import kr.re.etri.autoflow.specification.ProjectSpecification; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +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.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class DataGroupService { + + private final DataGroupRepository dataGroupRepository; + + private final DataGroupSpecification dataGroupSpecification; + + private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + public List findAll() { + return dataGroupRepository.findAll(); + } + + public Optional findById(Long id) { + return dataGroupRepository.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 = dataGroupSpecification.searchByConditions( + request.getSearchType(), + request.getKeyword(), + startDate, + endDate + ); + + return dataGroupRepository.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 DataGroupEntity create(DataGroupEntity project) { + return dataGroupRepository.save(project); + } + + @Transactional + public Optional update(Long id, ProjectRequest dto) { + return dataGroupRepository.findById(id) + .map(project -> { + BeanUtils.copyProperties(dto, project); + return dataGroupRepository.save(project); + }); + } + + @Transactional + public boolean delete(Long id) { + if (!dataGroupRepository.existsById(id)) { + return false; + } + dataGroupRepository.deleteById(id); + return true; + } +} diff --git a/src/main/java/kr/re/etri/autoflow/service/DatasetService.java b/src/main/java/kr/re/etri/autoflow/service/DatasetService.java index 1aa9b69..665aa93 100644 --- a/src/main/java/kr/re/etri/autoflow/service/DatasetService.java +++ b/src/main/java/kr/re/etri/autoflow/service/DatasetService.java @@ -102,7 +102,7 @@ public class DatasetService { for (MultipartFile file : files) { DatasetAttachmentEntity attachment = DatasetAttachmentEntity.builder() .originalName(file.getOriginalFilename()) - .storedName(storeFile(file)) // 실제 파일 저장 로직 필요 + .storedName("df") // 실제 파일 저장 로직 필요 .contentType(file.getContentType()) .size(file.getSize()) .regUserId(dataset.getRegUserId()) @@ -117,7 +117,7 @@ public class DatasetService { datasetAttachmentRepository.saveAll(attachments); // 엔티티에 첨부파일 리스트 설정 - //saved.setFiles(attachments); + saved.setFiles(attachments); } return saved; diff --git a/src/main/java/kr/re/etri/autoflow/specification/DataGroupSpecification.java b/src/main/java/kr/re/etri/autoflow/specification/DataGroupSpecification.java new file mode 100644 index 0000000..0e45aab --- /dev/null +++ b/src/main/java/kr/re/etri/autoflow/specification/DataGroupSpecification.java @@ -0,0 +1,80 @@ +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.DataGroupEntity; +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 DataGroupSpecification { + + private final EntityManager entityManager; + + private Set stringFields; + + public DataGroupSpecification(EntityManager entityManager) { + this.entityManager = entityManager; + } + + // 스프링 빈 초기화 후 실행 + @PostConstruct + public void init() { + Metamodel metamodel = entityManager.getMetamodel(); + EntityType entityType = metamodel.entity(DataGroupEntity.class); + + // 문자열 타입 필드명만 추출 + stringFields = entityType.getAttributes().stream() + .filter(attr -> attr.getJavaType().equals(String.class)) + .map(Attribute::getName) + .collect(Collectors.toSet()); + + log.info("DataGroupEntity string fields: {}", stringFields); + } + + public Specification searchByConditions( + String searchType, String keyword, + LocalDate startDate, LocalDate endDate) { + + return (root, query, cb) -> { + Predicate predicate = cb.conjunction(); + + 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("regDate"), startDate.atStartOfDay())); + } + + if (endDate != null) { + predicate = cb.and(predicate, cb.lessThanOrEqualTo(root.get("regDate"), endDate.atTime(23, 59, 59))); + } + + return predicate; + }; + } +}