동물원예제 hidden,모델등록이력 API 커밋

This commit is contained in:
2025-11-25 11:51:36 +09:00
parent 68090382f2
commit fa3b67ab94
11 changed files with 116 additions and 23 deletions

View File

@@ -89,13 +89,14 @@ public class ModelMngApiController {
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size, @RequestParam(defaultValue = "20") int size,
@RequestParam(required = false) String searchVal, @RequestParam(required = false) String searchVal,
@RequestParam String searchColumn @RequestParam(required = false) String searchColumn
) { ) {
ModelMngDto.searchReq searchReq = ModelMngDto.searchReq searchReq =
new ModelMngDto.searchReq(page, size, searchColumn + ",desc"); new ModelMngDto.searchReq(page, size, Optional.ofNullable(searchColumn).orElse("createdDate") + ",desc");
//searchColumn:: Entity 컬럼명칭으로 -> 기본값 = 등록일 createdDate, (선택) 배포일 deployDttm
Page<ModelMngDto.ModelRegHistory> result = Page<ModelMngDto.ModelRegHistory> result =
modelMngService.getRegHistoryList(searchReq, startDate, endDate); modelMngService.getRegHistoryList(searchReq, startDate, endDate, searchVal);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }

View File

@@ -135,6 +135,7 @@ public class ModelMngDto {
private String modelVer; private String modelVer;
private String strCreatedDttm; private String strCreatedDttm;
private String usedState; private String usedState;
private String deployState;
private String strDeployDttm; private String strDeployDttm;
} }
} }

View File

@@ -40,7 +40,7 @@ public class ModelMngService {
return modelMngCoreService.delete(id); return modelMngCoreService.delete(id);
} }
public Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate) { public Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate, String searchVal) {
return modelMngCoreService.getRegHistoryList(searchReq, startDate, endDate); return modelMngCoreService.getRegHistoryList(searchReq, startDate, endDate, searchVal);
} }
} }

View File

@@ -0,0 +1,27 @@
package com.kamco.cd.kamcoback.postgres;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.PathBuilder;
import org.springframework.data.domain.Pageable;
public class QuerydslOrderUtil {
/**
* Pageable의 Sort 정보를 QueryDSL OrderSpecifier 배열로 변환
* @param pageable Spring Pageable
* @param entityClass 엔티티 클래스 (예: User.class)
* @param alias Q 엔티티 alias (예: "user")
*/
public static <T> OrderSpecifier<?>[] getOrderSpecifiers(Pageable pageable, Class<T> entityClass, String alias) {
PathBuilder<T> entityPath = new PathBuilder<>(entityClass, alias);
return pageable.getSort()
.stream()
.map(sort -> {
Order order = sort.isAscending() ? Order.ASC : Order.DESC;
// PathBuilder.get()는 컬럼명(String)을 동적 Path로 반환
return new OrderSpecifier<>(order, entityPath.get(sort.getProperty(), String.class));
})
.toArray(OrderSpecifier[]::new);
}
}

View File

@@ -60,7 +60,7 @@ public class ModelMngCoreService {
return null; return null;
} }
public Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate) { public Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate, String searchVal) {
return modelMngRepository.getRegHistoryList(searchReq, startDate, endDate); return modelMngRepository.getRegHistoryList(searchReq, startDate, endDate, searchVal);
} }
} }

View File

@@ -0,0 +1,41 @@
package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.postgres.CommonDateEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.ZonedDateTime;
@Getter
@Setter
@Entity
@Table(name = "tb_model_deploy_hst")
public class ModelDeployHstEntity extends CommonDateEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_model_deploy_hst_id_gen")
@SequenceGenerator(name = "tb_model_deploy_hst_id_gen", sequenceName = "tb_model_deploy_hst_deploy_uid", allocationSize = 1)
@Column(name = "deploy_uid", nullable = false)
private Long id;
@Column(name = "model_uid")
private Long modelUid;
@Column(name = "server_id")
private Long serverId;
@Column(name = "deploy_state")
private String deployState;
@Column(name = "deploy_dttm", columnDefinition = "TIMESTAMP WITH TIME ZONE")
private ZonedDateTime deployDttm;
@Column(name = "created_uid")
private Long createdUid;
@Column(name = "updated_uid")
private Long updatedUid;
@Column(name = "model_ver_uid")
private Long modelVerUid;
}

View File

@@ -1,6 +1,5 @@
package com.kamco.cd.kamcoback.postgres.entity; package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.model.dto.ModelMngDto;
import com.kamco.cd.kamcoback.model.dto.ModelVerDto; import com.kamco.cd.kamcoback.model.dto.ModelVerDto;
import com.kamco.cd.kamcoback.postgres.CommonDateEntity; import com.kamco.cd.kamcoback.postgres.CommonDateEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
@@ -8,9 +7,6 @@ import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
import java.time.ZonedDateTime;
@Getter @Getter
@Setter @Setter

View File

@@ -14,5 +14,5 @@ public interface ModelMngRepositoryCustom {
Optional<ModelMngDto.FinalModelDto> getFinalModelInfo(); Optional<ModelMngDto.FinalModelDto> getFinalModelInfo();
Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate); Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate, String searchVal);
} }

View File

@@ -1,12 +1,15 @@
package com.kamco.cd.kamcoback.postgres.repository.model; package com.kamco.cd.kamcoback.postgres.repository.model;
import com.kamco.cd.kamcoback.model.dto.ModelMngDto; import com.kamco.cd.kamcoback.model.dto.ModelMngDto;
import com.kamco.cd.kamcoback.postgres.QuerydslOrderUtil;
import com.kamco.cd.kamcoback.postgres.entity.ModelMngEntity; import com.kamco.cd.kamcoback.postgres.entity.ModelMngEntity;
import com.kamco.cd.kamcoback.postgres.entity.ModelVerEntity;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import io.micrometer.common.util.StringUtils;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
@@ -19,6 +22,7 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import static com.kamco.cd.kamcoback.postgres.entity.QModelDeployHstEntity.modelDeployHstEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity.modelMngEntity; import static com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity.modelMngEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QModelVerEntity.modelVerEntity; import static com.kamco.cd.kamcoback.postgres.entity.QModelVerEntity.modelVerEntity;
@@ -43,8 +47,7 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
@Override @Override
public Optional<ModelMngDto.FinalModelDto> getFinalModelInfo(){ public Optional<ModelMngDto.FinalModelDto> getFinalModelInfo(){
return Optional.ofNullable( return queryFactory
queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
ModelMngDto.FinalModelDto.class, ModelMngDto.FinalModelDto.class,
@@ -63,13 +66,14 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
.from(modelMngEntity) .from(modelMngEntity)
.innerJoin(modelVerEntity) .innerJoin(modelVerEntity)
.on(modelMngEntity.id.eq(modelVerEntity.modelUid)) .on(modelMngEntity.id.eq(modelVerEntity.modelUid))
.where(modelVerEntity.usedState.eq("USED")) .where(modelVerEntity.usedState.eq("USED")) //USED 인 것 중에
.fetchOne() .orderBy(modelVerEntity.modelVer.desc()) //Version 높은 것 기준
); .stream()
.findFirst();
} }
@Override @Override
public Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate) { public Page<ModelMngDto.ModelRegHistory> getRegHistoryList(ModelMngDto.searchReq searchReq, LocalDate startDate, LocalDate endDate, String searchVal) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
List<ModelMngDto.ModelRegHistory> foundContent = List<ModelMngDto.ModelRegHistory> foundContent =
@@ -80,18 +84,27 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
modelMngEntity.modelNm, modelMngEntity.modelNm,
modelMngEntity.modelCate, modelMngEntity.modelCate,
modelVerEntity.modelVer, modelVerEntity.modelVer,
Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", modelVerEntity.createdDate).as("strCreatedDttm"), Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", modelVerEntity.createdDate).as("createdDttm"),
modelVerEntity.usedState, modelVerEntity.usedState,
Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", modelVerEntity.createdDate).as("strDeployDttm") //TODO: 배포일자 나오면 다시 modelVerEntity.deployState,
Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", modelDeployHstEntity.deployDttm).as("deployDttm")
) )
) )
.from(modelMngEntity) .from(modelMngEntity)
.innerJoin(modelVerEntity) .innerJoin(modelVerEntity)
.on(modelMngEntity.id.eq(modelVerEntity.modelUid)) .on(modelMngEntity.id.eq(modelVerEntity.modelUid))
.where(eventEndedAtBetween(startDate, endDate)) .leftJoin(modelDeployHstEntity)
.on(
modelVerEntity.id.eq(modelDeployHstEntity.modelVerUid)
.and(modelDeployHstEntity.serverId.eq(1L)) //1건만 조회해야 하기에 1번 서버만 조회하기
)
.where(
eventEndedAtBetween(startDate, endDate),
searchModelVerLike(searchVal)
)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
// .orderBy() //TODO : sort column 으로 desc 하기 .orderBy(QuerydslOrderUtil.getOrderSpecifiers(pageable, ModelVerEntity.class, "modelVerEntity"))
.fetch(); .fetch();
Long countQuery = Long countQuery =
@@ -100,7 +113,10 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
.from(modelMngEntity) .from(modelMngEntity)
.innerJoin(modelVerEntity) .innerJoin(modelVerEntity)
.on(modelMngEntity.id.eq(modelVerEntity.modelUid)) .on(modelMngEntity.id.eq(modelVerEntity.modelUid))
.where(eventEndedAtBetween(startDate, endDate)) .where(
eventEndedAtBetween(startDate, endDate),
searchModelVerLike(searchVal)
)
.fetchOne(); .fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery); return new PageImpl<>(foundContent, pageable, countQuery);
@@ -115,4 +131,11 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
return modelMngEntity.createdDate.goe(ZonedDateTime.from(startDateTime)) return modelMngEntity.createdDate.goe(ZonedDateTime.from(startDateTime))
.and(modelMngEntity.modifiedDate.lt(ZonedDateTime.from(endDateTime))); .and(modelMngEntity.modifiedDate.lt(ZonedDateTime.from(endDateTime)));
} }
private BooleanExpression searchModelVerLike(String searchVal){
if (StringUtils.isBlank(searchVal)) {
return null;
}
return modelVerEntity.modelVer.contains(searchVal);
}
} }

View File

@@ -6,6 +6,7 @@ import com.kamco.cd.kamcoback.zoo.dto.AnimalDto.Basic;
import com.kamco.cd.kamcoback.zoo.dto.AnimalDto.Category; import com.kamco.cd.kamcoback.zoo.dto.AnimalDto.Category;
import com.kamco.cd.kamcoback.zoo.dto.AnimalDto.Species; import com.kamco.cd.kamcoback.zoo.dto.AnimalDto.Species;
import com.kamco.cd.kamcoback.zoo.service.AnimalService; import com.kamco.cd.kamcoback.zoo.service.AnimalService;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@@ -24,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@Hidden
@Tag(name = "Animal", description = "동물 관리 API") @Tag(name = "Animal", description = "동물 관리 API")
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.zoo.dto.ZooDto; import com.kamco.cd.kamcoback.zoo.dto.ZooDto;
import com.kamco.cd.kamcoback.zoo.dto.ZooDto.Detail; import com.kamco.cd.kamcoback.zoo.dto.ZooDto.Detail;
import com.kamco.cd.kamcoback.zoo.service.ZooService; import com.kamco.cd.kamcoback.zoo.service.ZooService;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@Hidden
@Tag(name = "Zoo", description = "동물원 관리 API") @Tag(name = "Zoo", description = "동물원 관리 API")
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController