영상데이터관리 > 업로드처리,추론제외 API 추가

This commit is contained in:
2025-12-03 14:47:58 +09:00
parent 3d6393a65f
commit ddf4239a52
7 changed files with 177 additions and 19 deletions

View File

@@ -91,6 +91,7 @@ public class MapSheetMngApiController {
* @param searchReq
* @return
*/
@Operation(summary = "오류데이터 팝업 > 목록 조회", description = "오류데이터 팝업 > 목록 조회")
@PostMapping("/error-list")
public ApiResponseDto<Page<MapSheetMngDto.ErrorDataDto>> findMapSheetErrorList(
@RequestBody
@@ -123,5 +124,25 @@ public class MapSheetMngApiController {
return ApiResponseDto.ok(mapSheetMngService.findMapSheetMngList(searchReq));
}
/**
* @param hstUidList
* @return
*/
@Operation(summary = "오류데이터 팝업 > 업로드 처리", description = "오류데이터 팝업 > 업로드 처리")
@PutMapping("/upload-process")
public ApiResponseDto<MapSheetMngDto.DmlReturn> uploadProcess(
@RequestBody @Valid List<Long> hstUidList) {
return ApiResponseDto.ok(mapSheetMngService.uploadProcess(hstUidList));
}
/**
* @param hstUidList
* @return
*/
@Operation(summary = "오류데이터 팝업 > 추론 제외", description = "오류데이터 팝업 > 추론 제외")
@PutMapping("/except-inference")
public ApiResponseDto<MapSheetMngDto.DmlReturn> updateExceptUseInference(
@RequestBody @Valid List<Long> hstUidList) {
return ApiResponseDto.ok(mapSheetMngService.updateExceptUseInference(hstUidList));
}
}

View File

@@ -82,7 +82,16 @@ public class MapSheetMngDto {
private Long createdUid;
private String updatedDttm;
private Long updatedUid;
}
@Schema(name = "DmlReturn", description = "영상관리 DML 수행 후 리턴")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class DmlReturn {
private String flag;
private String message;
}
@Getter

View File

@@ -167,4 +167,12 @@ public class MapSheetMngService {
public Page<MapSheetMngDto.MngDto> findMapSheetMngList(MapSheetMngDto.@Valid searchReq searchReq) {
return mapSheetMngCoreService.findMapSheetMngList(searchReq);
}
public MapSheetMngDto.DmlReturn uploadProcess(@Valid List<Long> hstUidList) {
return mapSheetMngCoreService.uploadProcess(hstUidList);
}
public MapSheetMngDto.DmlReturn updateExceptUseInference(@Valid List<Long> hstUidList) {
return mapSheetMngCoreService.updateExceptUseInference(hstUidList);
}
}

View File

@@ -1,9 +1,22 @@
package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepository;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.Valid;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@@ -13,6 +26,11 @@ public class MapSheetMngCoreService {
private final MapSheetMngRepository mapSheetMngRepository;
private static final String ORIGINAL_IMAGES_PATH = "/app/original-images";
@Value("{spring.profiles.active}")
private String activeEnv;
public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(
MapSheetMngDto.@Valid searchReq searchReq) {
return mapSheetMngRepository.findMapSheetErrorList(searchReq);
@@ -21,4 +39,86 @@ public class MapSheetMngCoreService {
public Page<MapSheetMngDto.MngDto> findMapSheetMngList(MapSheetMngDto.@Valid searchReq searchReq) {
return mapSheetMngRepository.findMapSheetMngList(searchReq);
}
public MapSheetMngDto.DmlReturn uploadProcess(@Valid List<Long> hstUidList) {
int count = 0;
if (!Objects.isNull(hstUidList) && !hstUidList.isEmpty()) {
for (Long hstUid : hstUidList) {
Optional<MapSheetMngHstEntity> entity =
Optional.ofNullable(
mapSheetMngRepository
.findMapSheetMngHstInfo(hstUid)
.orElseThrow(EntityNotFoundException::new));
// TODO: local TEST 시 각자 경로 수정하기
// TODO: application.yml 에 active profile : local 로 임시 변경하여 테스트
String localPath = "";
// String localPath = "C:\\Users\\gypark\\Desktop\\file";
String rootDir = ORIGINAL_IMAGES_PATH + "/" + entity.get().getMngYyyy();
if (activeEnv.equals("local")) {
rootDir = localPath + rootDir;
}
String filename = entity.get().getMapSheetNum();
String[] extensions = {"tif", "tfw"};
boolean flag = allExtensionsExist(rootDir, filename, extensions);
if (flag) {
count += 1;
}
MapSheetMngDto.DataState dataState =
flag ? MapSheetMngDto.DataState.SUCCESS : MapSheetMngDto.DataState.FAIL;
entity.get().updateDataState(dataState);
}
}
return new MapSheetMngDto.DmlReturn("success", count + "개 업로드 성공하였습니다.");
}
public MapSheetMngDto.DmlReturn updateExceptUseInference(@Valid List<Long> hstUidList) {
if (!Objects.isNull(hstUidList) && !hstUidList.isEmpty()) {
for (Long hstUid : hstUidList) {
Optional<MapSheetMngHstEntity> entity =
Optional.ofNullable(
mapSheetMngRepository
.findMapSheetMngHstInfo(hstUid)
.orElseThrow(EntityNotFoundException::new));
entity.get().updateUseInference(true);
}
}
return new MapSheetMngDto.DmlReturn("success", hstUidList.size() + "개 추론제외 업데이트 하였습니다.");
}
/**
* 특정 파일명 + 여러 확장자가 모두 존재하는지 확인
*
* @param rootDir 검색할 최상위 디렉토리
* @param filename 파일명 (확장자 제외)
* @param extensions 확인할 확장자 배열 (예: {"tif", "tfw"})
* @return 모든 확장자가 존재하면 true, 하나라도 없으면 false
*/
public static boolean allExtensionsExist(String rootDir, String filename, String... extensions) {
try (Stream<Path> paths = Files.walk(Paths.get(rootDir))) {
// 모든 파일명을 Set으로 저장
Set<String> fileNames =
paths
.filter(Files::isRegularFile)
.map(p -> p.getFileName().toString())
.collect(Collectors.toSet());
// 모든 확장자 파일 존재 여부 확인
for (String ext : extensions) {
String target = filename + "." + ext;
if (!fileNames.contains(target)) {
return false; // 하나라도 없으면 false
}
}
return true; // 모두 존재하면 true
} catch (IOException e) {
throw new RuntimeException("File search error", e);
}
}
}

View File

@@ -59,4 +59,14 @@ public class MapSheetMngHstEntity extends CommonDateEntity {
@Column(name = "updated_uid")
private Long updatedUid;
public void updateDataState(MapSheetMngDto.DataState dataState) {
this.dataState = dataState;
this.dataStateDttm = ZonedDateTime.now();
}
public void updateUseInference(Boolean useInference) {
this.useInference = useInference;
this.useInferenceDttm = ZonedDateTime.now();
}
}

View File

@@ -1,7 +1,9 @@
package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import jakarta.validation.Valid;
import java.util.Optional;
import org.springframework.data.domain.Page;
public interface MapSheetMngRepositoryCustom {
@@ -9,4 +11,5 @@ public interface MapSheetMngRepositoryCustom {
Page<MapSheetMngDto.MngDto> findMapSheetMngList(MapSheetMngDto.@Valid searchReq searchReq);
Optional<MapSheetMngHstEntity> findMapSheetMngHstInfo(Long hstUid);
}

View File

@@ -1,10 +1,13 @@
package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity.mapInkx50kEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngEntity.mapSheetMngEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity.mapSheetMngHstEntity;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.members.dto.RoleType;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
@@ -12,21 +15,15 @@ import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.validation.Valid;
import jdk.jfr.Experimental;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity.mapSheetMngHstEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngEntity.mapSheetMngEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity.mapInkx50kEntity;
import java.util.List;
import java.util.Objects;
public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
implements MapSheetMngRepositoryCustom {
@@ -87,7 +84,6 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<MapSheetMngDto.MngDto> findMapSheetMngList(MapSheetMngDto.@Valid searchReq searchReq) {
@@ -132,8 +128,18 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
return new PageImpl<>(foundContent, pageable, countQuery);
}
private NumberExpression<Integer> rowNum(){
return Expressions.numberTemplate(Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate);
@Override
public Optional<MapSheetMngHstEntity> findMapSheetMngHstInfo(Long hstUid) {
return Optional.ofNullable(
queryFactory
.selectFrom(mapSheetMngHstEntity)
.where(mapSheetMngHstEntity.hstUid.eq(hstUid))
.fetchOne());
}
private NumberExpression<Integer> rowNum() {
return Expressions.numberTemplate(
Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate);
}
private BooleanExpression mapSheetErrorSearchValue(MapSheetMngDto.searchReq searchReq) {
@@ -142,10 +148,11 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
}
// 검색어 1개 값이 도엽명 or 도엽번호 like 검색
return Expressions.booleanTemplate("{0} like '%" + searchReq.getSearchValue() + "%'", mapSheetMngHstEntity.mapSheetName)
.or(Expressions.booleanTemplate("{0} like '%" + searchReq.getSearchValue() + "%'", mapSheetMngHstEntity.mapSheetNum));
return Expressions.booleanTemplate(
"{0} like '%" + searchReq.getSearchValue() + "%'", mapSheetMngHstEntity.mapSheetName)
.or(
Expressions.booleanTemplate(
"{0} like '%" + searchReq.getSearchValue() + "%'",
mapSheetMngHstEntity.mapSheetNum));
}
}