Merge remote-tracking branch 'origin/feat/dev_251201' into feat/dev_251201
# Conflicts: # src/main/java/com/kamco/cd/kamcoback/mapsheet/dto/FileDto.java # src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java # src/main/java/com/kamco/cd/kamcoback/postgres/entity/CommonCodeEntity.java
This commit is contained in:
@@ -27,6 +27,10 @@ public class CommonCodeDto {
|
|||||||
private int order;
|
private int order;
|
||||||
private boolean used;
|
private boolean used;
|
||||||
private Long parentId;
|
private Long parentId;
|
||||||
|
|
||||||
|
private String props1;
|
||||||
|
private String props2;
|
||||||
|
private String props3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(name = "CodeModifyReq", description = "공통코드 수정 정보")
|
@Schema(name = "CodeModifyReq", description = "공통코드 수정 정보")
|
||||||
@@ -35,10 +39,15 @@ public class CommonCodeDto {
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class ModifyReq {
|
public static class ModifyReq {
|
||||||
|
@NotEmpty private String code;
|
||||||
@NotEmpty private String name;
|
@NotEmpty private String name;
|
||||||
private String description;
|
private String description;
|
||||||
private int order;
|
private int order;
|
||||||
private boolean used;
|
private boolean used;
|
||||||
|
|
||||||
|
private String props1;
|
||||||
|
private String props2;
|
||||||
|
private String props3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(name = "CodeOrderReq", description = "공통코드 순서 변경 정보")
|
@Schema(name = "CodeOrderReq", description = "공통코드 순서 변경 정보")
|
||||||
@@ -77,6 +86,10 @@ public class CommonCodeDto {
|
|||||||
|
|
||||||
@JsonFormatDttm private ZonedDateTime updatedDttm;
|
@JsonFormatDttm private ZonedDateTime updatedDttm;
|
||||||
|
|
||||||
|
private String props1;
|
||||||
|
private String props2;
|
||||||
|
private String props3;
|
||||||
|
|
||||||
public Basic(
|
public Basic(
|
||||||
Long id,
|
Long id,
|
||||||
String code,
|
String code,
|
||||||
@@ -87,7 +100,11 @@ public class CommonCodeDto {
|
|||||||
Boolean deleted,
|
Boolean deleted,
|
||||||
List<CommonCodeDto.Basic> children,
|
List<CommonCodeDto.Basic> children,
|
||||||
ZonedDateTime createdDttm,
|
ZonedDateTime createdDttm,
|
||||||
ZonedDateTime updatedDttm) {
|
ZonedDateTime updatedDttm,
|
||||||
|
String props1,
|
||||||
|
String props2,
|
||||||
|
String props3
|
||||||
|
) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
@@ -98,6 +115,9 @@ public class CommonCodeDto {
|
|||||||
this.children = children;
|
this.children = children;
|
||||||
this.createdDttm = createdDttm;
|
this.createdDttm = createdDttm;
|
||||||
this.updatedDttm = updatedDttm;
|
this.updatedDttm = updatedDttm;
|
||||||
|
this.props1 = props1;
|
||||||
|
this.props2 = props2;
|
||||||
|
this.props3 = props3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import java.util.stream.Collectors;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||||
@@ -287,6 +288,29 @@ public class GlobalExceptionHandler {
|
|||||||
errorLog.getId());
|
errorLog.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.CONFLICT)
|
||||||
|
@ExceptionHandler(DuplicateKeyException.class)
|
||||||
|
public ApiResponseDto<String> handlerDuplicateKeyException(
|
||||||
|
DuplicateKeyException e, HttpServletRequest request) {
|
||||||
|
log.warn("[DuplicateKeyException] resource :{} ", e.getMessage());
|
||||||
|
|
||||||
|
String codeName = "DUPLICATE_DATA";
|
||||||
|
|
||||||
|
ErrorLogEntity errorLog =
|
||||||
|
saveErrerLogData(
|
||||||
|
request,
|
||||||
|
ApiResponseCode.getCode(codeName),
|
||||||
|
HttpStatus.valueOf("CONFLICT"),
|
||||||
|
ErrorLogDto.LogErrorLevel.WARNING,
|
||||||
|
e.getStackTrace());
|
||||||
|
|
||||||
|
return ApiResponseDto.createException(
|
||||||
|
ApiResponseCode.getCode(codeName),
|
||||||
|
ApiResponseCode.getMessage(codeName),
|
||||||
|
HttpStatus.valueOf("CONFLICT"),
|
||||||
|
errorLog.getId());
|
||||||
|
}
|
||||||
|
|
||||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
@ExceptionHandler(RuntimeException.class)
|
@ExceptionHandler(RuntimeException.class)
|
||||||
public ApiResponseDto<String> handlerRuntimeException(
|
public ApiResponseDto<String> handlerRuntimeException(
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ public class GeoJsonMonitorConfig {
|
|||||||
/** 처리 실패 파일을 이동할 폴더 경로 */
|
/** 처리 실패 파일을 이동할 폴더 경로 */
|
||||||
private String errorDirectory = "~/geojson/error";
|
private String errorDirectory = "~/geojson/error";
|
||||||
|
|
||||||
/** 파일 모니터링 스케줄 (cron 표현식) 기본값: 매 30초마다 실행 */
|
/** 파일 모니터링 스케줄 (cron 표현식) 기본값: 매 1분마다 실행 */
|
||||||
private String cronExpression = "0/30 * * * * *";
|
private String cronExpression = "0 * * * * *";
|
||||||
|
|
||||||
/** 지원하는 압축파일 확장자 */
|
/** 지원하는 압축파일 확장자 */
|
||||||
private String[] supportedExtensions = {"zip", "tar", "tar.gz", "tgz"};
|
private String[] supportedExtensions = {"zip", "tar", "tar.gz", "tgz"};
|
||||||
|
|||||||
@@ -27,32 +27,30 @@ public class GeoJsonDataService {
|
|||||||
private final GeoJsonReader geoJsonReader = new GeoJsonReader();
|
private final GeoJsonReader geoJsonReader = new GeoJsonReader();
|
||||||
|
|
||||||
/** GeoJSON 파일들을 데이터베이스에 저장 */
|
/** GeoJSON 파일들을 데이터베이스에 저장 */
|
||||||
@Transactional
|
|
||||||
public List<Long> processGeoJsonFiles(
|
public List<Long> processGeoJsonFiles(
|
||||||
Map<String, String> geoJsonContents, String archiveFileName) {
|
Map<String, String> geoJsonContents, String archiveFileName) {
|
||||||
List<Long> savedIds = new ArrayList<>();
|
List<Long> savedIds = new ArrayList<>();
|
||||||
|
|
||||||
log.info("GeoJSON 파일 처리 시작: {} ({}개 파일)", archiveFileName, geoJsonContents.size());
|
log.info("GeoJSON 파일 처리 시작: {} ({}개 파일)", archiveFileName, geoJsonContents.size());
|
||||||
|
|
||||||
|
// 개별 파일별로 독립적인 트랜잭션으로 처리
|
||||||
for (Map.Entry<String, String> entry : geoJsonContents.entrySet()) {
|
for (Map.Entry<String, String> entry : geoJsonContents.entrySet()) {
|
||||||
String fileName = entry.getKey();
|
String fileName = entry.getKey();
|
||||||
String geoJsonContent = entry.getValue();
|
String geoJsonContent = entry.getValue();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Long savedId = processGeoJsonFile(fileName, geoJsonContent, archiveFileName);
|
Long savedId = processGeoJsonFileWithTransaction(fileName, geoJsonContent, archiveFileName);
|
||||||
if (savedId != null) {
|
if (savedId != null) {
|
||||||
savedIds.add(savedId);
|
savedIds.add(savedId);
|
||||||
log.debug("GeoJSON 파일 저장 성공: {} (ID: {})", fileName, savedId);
|
log.debug("GeoJSON 파일 저장 성공: {} (ID: {})", fileName, savedId);
|
||||||
|
|
||||||
// 학습 모델 결과 파일인지 확인하여 geometry 데이터 처리
|
|
||||||
if (isLearningModelResult(fileName, geoJsonContent)) {
|
|
||||||
processLearningModelGeometry(savedId, geoJsonContent, fileName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("GeoJSON 파일 처리 실패: {}", fileName, e);
|
log.error("GeoJSON 파일 처리 실패: {}", fileName, e);
|
||||||
// 개별 파일 처리 실패는 전체 처리를 중단시키지 않음
|
// 개별 파일 처리 실패는 전체 처리를 중단시키지 않음
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 메모리 정리
|
||||||
|
System.gc();
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
@@ -64,6 +62,22 @@ public class GeoJsonDataService {
|
|||||||
return savedIds;
|
return savedIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 개별 파일을 별도 트랜잭션으로 처리 */
|
||||||
|
@Transactional
|
||||||
|
public Long processGeoJsonFileWithTransaction(
|
||||||
|
String fileName, String geoJsonContent, String archiveFileName) {
|
||||||
|
try {
|
||||||
|
Long savedId = processGeoJsonFile(fileName, geoJsonContent, archiveFileName);
|
||||||
|
if (savedId != null && isLearningModelResult(fileName, geoJsonContent)) {
|
||||||
|
processLearningModelGeometryOptimized(savedId, geoJsonContent, fileName);
|
||||||
|
}
|
||||||
|
return savedId;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("파일 처리 중 트랜잭션 에러: {}", fileName, e);
|
||||||
|
throw e; // 트랜잭션 롤백을 위해 재throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 개별 GeoJSON 파일을 MapSheetLearnDataEntity로 변환하여 저장 */
|
/** 개별 GeoJSON 파일을 MapSheetLearnDataEntity로 변환하여 저장 */
|
||||||
private Long processGeoJsonFile(String fileName, String geoJsonContent, String archiveFileName) {
|
private Long processGeoJsonFile(String fileName, String geoJsonContent, String archiveFileName) {
|
||||||
try {
|
try {
|
||||||
@@ -285,9 +299,9 @@ public class GeoJsonDataService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 학습 모델 결과의 geometry 데이터 처리 */
|
/** 학습 모델 결과의 geometry 데이터 처리 - 최적화된 배치 처리 */
|
||||||
@Transactional
|
public void processLearningModelGeometryOptimized(
|
||||||
public void processLearningModelGeometry(Long dataUid, String geoJsonContent, String fileName) {
|
Long dataUid, String geoJsonContent, String fileName) {
|
||||||
try {
|
try {
|
||||||
log.info("학습 모델 geometry 데이터 처리 시작: {} (dataUid: {})", fileName, dataUid);
|
log.info("학습 모델 geometry 데이터 처리 시작: {} (dataUid: {})", fileName, dataUid);
|
||||||
|
|
||||||
@@ -318,30 +332,69 @@ public class GeoJsonDataService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MapSheetLearnDataGeomEntity> geomEntities = new ArrayList<>();
|
// 소규모 배치로 나누어 처리
|
||||||
|
int totalFeatures = features.size();
|
||||||
|
int batchSize = 10; // 작은 배치 크기
|
||||||
int processedCount = 0;
|
int processedCount = 0;
|
||||||
|
|
||||||
for (JsonNode feature : features) {
|
log.info("총 {}개 feature를 {}개씩 배치로 나누어 처리", totalFeatures, batchSize);
|
||||||
|
|
||||||
|
for (int i = 0; i < totalFeatures; i += batchSize) {
|
||||||
|
int endIndex = Math.min(i + batchSize, totalFeatures);
|
||||||
|
List<MapSheetLearnDataGeomEntity> batch = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = i; j < endIndex; j++) {
|
||||||
try {
|
try {
|
||||||
|
JsonNode feature = features.get(j);
|
||||||
MapSheetLearnDataGeomEntity geomEntity =
|
MapSheetLearnDataGeomEntity geomEntity =
|
||||||
createGeometryEntity(feature, dataUid, beforeYear, afterYear, mapSheetNum);
|
createGeometryEntity(feature, dataUid, beforeYear, afterYear, mapSheetNum);
|
||||||
if (geomEntity != null) {
|
if (geomEntity != null) {
|
||||||
geomEntities.add(geomEntity);
|
batch.add(geomEntity);
|
||||||
processedCount++;
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Feature geometry 처리 실패 (feature {}): {}", processedCount, e.getMessage());
|
log.warn("Feature geometry 처리 실패 (feature {}): {}", j + 1, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 배치 저장
|
// 배치별 저장
|
||||||
if (!geomEntities.isEmpty()) {
|
if (!batch.isEmpty()) {
|
||||||
mapSheetLearnDataGeomRepository.saveAll(geomEntities);
|
saveBatchGeometry(batch);
|
||||||
log.info("학습 모델 geometry 데이터 저장 완료: {} ({}개 feature)", fileName, geomEntities.size());
|
processedCount += batch.size();
|
||||||
|
log.debug("배치 {}-{} 처리 완료 ({}개)", i + 1, endIndex, batch.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 메모리 정리
|
||||||
|
batch.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("학습 모델 geometry 데이터 저장 완료: {} ({}개 feature)", fileName, processedCount);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("학습 모델 geometry 데이터 처리 실패: {}", fileName, e);
|
log.error("학습 모델 geometry 데이터 처리 실패: {}", fileName, e);
|
||||||
|
throw new RuntimeException("Geometry 처리 실패: " + fileName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 배치별 geometry 저장 - 별도 트랜잭션 */
|
||||||
|
@Transactional(propagation = org.springframework.transaction.annotation.Propagation.REQUIRES_NEW)
|
||||||
|
public void saveBatchGeometry(List<MapSheetLearnDataGeomEntity> batch) {
|
||||||
|
try {
|
||||||
|
if (batch == null || batch.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mapSheetLearnDataGeomRepository.saveAll(batch);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("배치 geometry 저장 실패: {}", e.getMessage());
|
||||||
|
// 개별 저장 시도
|
||||||
|
for (MapSheetLearnDataGeomEntity entity : batch) {
|
||||||
|
try {
|
||||||
|
if (entity != null) {
|
||||||
|
mapSheetLearnDataGeomRepository.save(entity);
|
||||||
|
}
|
||||||
|
} catch (Exception individualError) {
|
||||||
|
log.warn("개별 geometry 저장 실패: {}", individualError.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,27 @@ public class MapSheetMngApiController {
|
|||||||
return ApiResponseDto.createOK(mapSheetMngService.getFilesAll(srchDto));
|
return ApiResponseDto.createOK(mapSheetMngService.getFilesAll(srchDto));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "파일목록 조회", description = "파일목록 조회")
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회 성공",
|
||||||
|
content =
|
||||||
|
@Content(
|
||||||
|
mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = CommonCodeDto.Basic.class))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
})
|
||||||
|
@PostMapping("/file-all-list")
|
||||||
|
public ApiResponseDto<FilesDto> getAllFiles(@RequestBody SrchFilesDto srchDto) {
|
||||||
|
|
||||||
|
return ApiResponseDto.createOK(mapSheetMngService.getFilesDepthAll(srchDto));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 오류데이터 목록 조회
|
* 오류데이터 목록 조회
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -23,10 +23,15 @@ public class FileDto {
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class SrchFilesDto {
|
public static class SrchFilesDto {
|
||||||
|
@Schema(description = "디렉토리경로", example = "/data")
|
||||||
@NotNull private String dirPath;
|
@NotNull private String dirPath;
|
||||||
|
@Schema(description = "전체(*), cpg,dbf,geojson등", example = "*")
|
||||||
@NotNull private String extension;
|
@NotNull private String extension;
|
||||||
|
@Schema(description = "파일명(name), 최종수정일(date)", example = "name")
|
||||||
@NotNull private String sortType;
|
@NotNull private String sortType;
|
||||||
|
@Schema(description = "파일시작위치", example = "1")
|
||||||
@NotNull private Integer startPos;
|
@NotNull private Integer startPos;
|
||||||
|
@Schema(description = "파일종료위치", example = "100")
|
||||||
@NotNull private Integer endPos;
|
@NotNull private Integer endPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,8 +75,7 @@ public class FileDto {
|
|||||||
private final int folderErrTotCnt;
|
private final int folderErrTotCnt;
|
||||||
private final List<FolderDto> folders;
|
private final List<FolderDto> folders;
|
||||||
|
|
||||||
public FoldersDto(
|
public FoldersDto(String dirPath, int folderTotCnt, int folderErrTotCnt, List<FolderDto> folders) {
|
||||||
String dirPath, int folderTotCnt, int folderErrTotCnt, List<FolderDto> folders) {
|
|
||||||
|
|
||||||
this.dirPath = dirPath;
|
this.dirPath = dirPath;
|
||||||
this.folderTotCnt = folderTotCnt;
|
this.folderTotCnt = folderTotCnt;
|
||||||
@@ -80,20 +84,26 @@ public class FileDto {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Schema(name = "File Basic", description = "파일 기본 정보")
|
@Schema(name = "File Basic", description = "파일 기본 정보")
|
||||||
@Getter
|
@Getter
|
||||||
public static class Basic {
|
public static class Basic {
|
||||||
|
|
||||||
private final String fileNm;
|
private final String fileNm;
|
||||||
private final String filePath;
|
private final String parentFolderNm;
|
||||||
|
private final String parentPath;
|
||||||
|
private final String fullPath;
|
||||||
private final String extension;
|
private final String extension;
|
||||||
private final long fileSize;
|
private final long fileSize;
|
||||||
private final String lastModified;
|
private final String lastModified;
|
||||||
|
|
||||||
public Basic(
|
public Basic(
|
||||||
String fileNm, String filePath, String extension, long fileSize, String lastModified) {
|
String fileNm, String parentFolderNm, String parentPath, String fullPath, String extension, long fileSize, String lastModified) {
|
||||||
this.fileNm = fileNm;
|
this.fileNm = fileNm;
|
||||||
this.filePath = filePath;
|
this.parentFolderNm = parentFolderNm;
|
||||||
|
this.parentPath = parentPath;
|
||||||
|
this.fullPath = fullPath;
|
||||||
this.extension = extension;
|
this.extension = extension;
|
||||||
this.fileSize = fileSize;
|
this.fileSize = fileSize;
|
||||||
this.lastModified = lastModified;
|
this.lastModified = lastModified;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class MapSheetMngService {
|
|||||||
|
|
||||||
private final MapSheetMngCoreService mapSheetMngCoreService;
|
private final MapSheetMngCoreService mapSheetMngCoreService;
|
||||||
|
|
||||||
|
|
||||||
public FoldersDto getFolderAll(SrchFoldersDto srchDto) {
|
public FoldersDto getFolderAll(SrchFoldersDto srchDto) {
|
||||||
|
|
||||||
Path startPath = Paths.get(srchDto.getDirPath());
|
Path startPath = Paths.get(srchDto.getDirPath());
|
||||||
@@ -66,11 +67,8 @@ public class MapSheetMngService {
|
|||||||
String parentPath = path.getParent().toString();
|
String parentPath = path.getParent().toString();
|
||||||
String fullPath = path.toAbsolutePath().toString();
|
String fullPath = path.toAbsolutePath().toString();
|
||||||
|
|
||||||
boolean isValid = true;
|
boolean isValid = !NameValidator.containsKorean(folderNm) &&
|
||||||
if (NameValidator.containsKorean(folderNm)
|
!NameValidator.containsWhitespaceRegex(folderNm);
|
||||||
|| NameValidator.containsWhitespaceRegex(folderNm)) {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
File directory = new File(fullPath);
|
File directory = new File(fullPath);
|
||||||
File[] childFolders = directory.listFiles(File::isDirectory);
|
File[] childFolders = directory.listFiles(File::isDirectory);
|
||||||
@@ -81,16 +79,15 @@ public class MapSheetMngService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileTime time = null;
|
FileTime time = null;
|
||||||
|
String lastModified = "";
|
||||||
try {
|
try {
|
||||||
time = Files.getLastModifiedTime(path);
|
time = Files.getLastModifiedTime(path);
|
||||||
|
lastModified = dttmFormat.format(new Date(time.toMillis()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
String lastModified = dttmFormat.format(new Date(time.toMillis()));
|
return new FolderDto(
|
||||||
|
|
||||||
FolderDto folderDto =
|
|
||||||
new FolderDto(
|
|
||||||
folderNm,
|
folderNm,
|
||||||
parentFolderNm,
|
parentFolderNm,
|
||||||
parentPath,
|
parentPath,
|
||||||
@@ -98,9 +95,8 @@ public class MapSheetMngService {
|
|||||||
depth,
|
depth,
|
||||||
childCnt,
|
childCnt,
|
||||||
lastModified,
|
lastModified,
|
||||||
isValid);
|
isValid
|
||||||
|
);
|
||||||
return folderDto;
|
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
@@ -112,9 +108,7 @@ public class MapSheetMngService {
|
|||||||
|
|
||||||
folderTotCnt = folderDtoList.size();
|
folderTotCnt = folderDtoList.size();
|
||||||
|
|
||||||
folderErrTotCnt =
|
folderErrTotCnt = (int)folderDtoList.stream()
|
||||||
(int)
|
|
||||||
folderDtoList.stream()
|
|
||||||
.filter(dto -> dto.getIsValid().toString().equals("false") )
|
.filter(dto -> dto.getIsValid().toString().equals("false") )
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
@@ -122,9 +116,9 @@ public class MapSheetMngService {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
FoldersDto foldersDto = new FoldersDto(dirPath, folderTotCnt, folderErrTotCnt, folderDtoList);
|
// FoldersDto foldersDto = new FoldersDto(dirPath, folderTotCnt, folderErrTotCnt, folderDtoList);
|
||||||
|
|
||||||
return foldersDto;
|
return new FoldersDto(dirPath, folderTotCnt, folderErrTotCnt, folderDtoList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilesDto getFilesAll(SrchFilesDto srchDto) {
|
public FilesDto getFilesAll(SrchFilesDto srchDto) {
|
||||||
@@ -161,12 +155,17 @@ public class MapSheetMngService {
|
|||||||
|
|
||||||
// 생성자를 통해 객체를 만들고 리스트에 추가
|
// 생성자를 통해 객체를 만들고 리스트에 추가
|
||||||
String fileName = file.getName();
|
String fileName = file.getName();
|
||||||
String filePath = file.getAbsolutePath();
|
String parentPath = file.getParent();
|
||||||
|
String fullPath = file.getAbsolutePath();
|
||||||
String ext = FilenameUtils.getExtension(fileName);
|
String ext = FilenameUtils.getExtension(fileName);
|
||||||
|
|
||||||
|
Path path = Paths.get(parentPath);
|
||||||
|
String parentFolderNm = path.getFileName().toString();
|
||||||
|
|
||||||
long fileSize = file.length();
|
long fileSize = file.length();
|
||||||
String lastModified = dttmFormat.format(new Date(file.lastModified()));
|
String lastModified = dttmFormat.format(new Date(file.lastModified()));
|
||||||
|
|
||||||
files.add(new FileDto.Basic(fileName, filePath, ext, fileSize, lastModified));
|
files.add(new FileDto.Basic(fileName, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified));
|
||||||
|
|
||||||
fileTotCnt = fileTotCnt + 1;
|
fileTotCnt = fileTotCnt + 1;
|
||||||
fileTotSize = fileTotSize + fileSize;
|
fileTotSize = fileTotSize + fileSize;
|
||||||
@@ -181,6 +180,61 @@ public class MapSheetMngService {
|
|||||||
return filesDto;
|
return filesDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public FilesDto getFilesDepthAll(SrchFilesDto srchDto) {
|
||||||
|
|
||||||
|
int maxDepth = 20;
|
||||||
|
Path startPath = Paths.get(srchDto.getDirPath());
|
||||||
|
String dirPath = srchDto.getDirPath();
|
||||||
|
String extension = srchDto.getExtension();
|
||||||
|
|
||||||
|
List<FileDto.Basic> fileDtoList = new ArrayList<>();
|
||||||
|
SimpleDateFormat dttmFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
int fileTotCnt = 0;
|
||||||
|
long fileTotSize = 0;
|
||||||
|
|
||||||
|
try (Stream<Path> stream = Files.walk(startPath, maxDepth)) {
|
||||||
|
|
||||||
|
fileDtoList =
|
||||||
|
stream
|
||||||
|
.filter(Files::isRegularFile)
|
||||||
|
.map(
|
||||||
|
path -> {
|
||||||
|
|
||||||
|
int depth = path.getNameCount();
|
||||||
|
|
||||||
|
String fileNm = path.getFileName().toString();
|
||||||
|
String ext = FilenameUtils.getExtension(fileNm);
|
||||||
|
String parentFolderNm = path.getParent().getFileName().toString();
|
||||||
|
String parentPath = path.getParent().toString();
|
||||||
|
String fullPath = path.toAbsolutePath().toString();
|
||||||
|
|
||||||
|
File file = new File(fullPath);
|
||||||
|
long fileSize = file.length();
|
||||||
|
String lastModified = dttmFormat.format(new Date(file.lastModified()));
|
||||||
|
|
||||||
|
return new FileDto.Basic(fileNm, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
fileTotCnt = fileDtoList.size();
|
||||||
|
fileTotSize = fileDtoList.stream()
|
||||||
|
.mapToLong(FileDto.Basic::getFileSize)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("파일 I/O 오류 발생: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FilesDto filesDto = new FilesDto(dirPath, fileTotCnt, fileTotSize, fileDtoList);
|
||||||
|
|
||||||
|
return filesDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(
|
public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(
|
||||||
MapSheetMngDto.@Valid searchReq searchReq) {
|
MapSheetMngDto.@Valid searchReq searchReq) {
|
||||||
return mapSheetMngCoreService.findMapSheetErrorList(searchReq);
|
return mapSheetMngCoreService.findMapSheetErrorList(searchReq);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import jakarta.persistence.EntityNotFoundException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -34,16 +35,21 @@ public class CommonCodeCoreService
|
|||||||
new EntityNotFoundException(
|
new EntityNotFoundException(
|
||||||
"parent id 를 찾을 수 없습니다. id : " + req.getParentId()));
|
"parent id 를 찾을 수 없습니다. id : " + req.getParentId()));
|
||||||
|
|
||||||
|
Long existsCount = commonCodeRepository.findByParentIdCodeExists(req.getParentId(), req.getCode());
|
||||||
|
if (existsCount > 0) {
|
||||||
|
throw new DuplicateKeyException("이미 등록되어 있습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
CommonCodeEntity entity =
|
CommonCodeEntity entity =
|
||||||
new CommonCodeEntity(
|
new CommonCodeEntity(
|
||||||
req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed());
|
req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed(), req.getProps1(), req.getProps2(), req.getProps3());
|
||||||
entity.addParent(parentCommonCodeEntity);
|
entity.addParent(parentCommonCodeEntity);
|
||||||
return commonCodeRepository.save(entity).toDto();
|
return commonCodeRepository.save(entity).toDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonCodeEntity entity =
|
CommonCodeEntity entity =
|
||||||
new CommonCodeEntity(
|
new CommonCodeEntity(
|
||||||
req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed());
|
req.getCode(), req.getName(), req.getDescription(), req.getOrder(), req.isUsed(), req.getProps1(), req.getProps2(), req.getProps3());
|
||||||
return commonCodeRepository.save(entity).toDto();
|
return commonCodeRepository.save(entity).toDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,14 +59,25 @@ public class CommonCodeCoreService
|
|||||||
.findByCodeId(id)
|
.findByCodeId(id)
|
||||||
.orElseThrow(() -> new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + id));
|
.orElseThrow(() -> new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + id));
|
||||||
|
|
||||||
|
Long parentId = found.getParent() == null ? null : found.getParent().getId();
|
||||||
|
Long existsCount = commonCodeRepository.findByParentIdCodeExiststoUpdate(id, parentId, req.getCode());
|
||||||
|
if (existsCount > 0) {
|
||||||
|
throw new DuplicateKeyException("이미 등록되어 있습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
CommonCodeEntity entity =
|
CommonCodeEntity entity =
|
||||||
new CommonCodeEntity(
|
new CommonCodeEntity(
|
||||||
id,
|
id,
|
||||||
|
req.getCode(),
|
||||||
req.getName(),
|
req.getName(),
|
||||||
req.getDescription(),
|
req.getDescription(),
|
||||||
req.getOrder(),
|
req.getOrder(),
|
||||||
req.isUsed(),
|
req.isUsed(),
|
||||||
found.getDeleted());
|
found.getDeleted(),
|
||||||
|
req.getProps1(),
|
||||||
|
req.getProps2(),
|
||||||
|
req.getProps3()
|
||||||
|
);
|
||||||
|
|
||||||
return commonCodeRepository.save(entity).toDto();
|
return commonCodeRepository.save(entity).toDto();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,23 +61,42 @@ public class CommonCodeEntity extends CommonDateEntity {
|
|||||||
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||||
private List<CommonCodeEntity> children = new ArrayList<>();
|
private List<CommonCodeEntity> children = new ArrayList<>();
|
||||||
|
|
||||||
|
@Size(max = 255)
|
||||||
|
@Column(name = "props1")
|
||||||
|
private String props1;
|
||||||
|
|
||||||
|
@Size(max = 255)
|
||||||
|
@Column(name = "props2")
|
||||||
|
private String props2;
|
||||||
|
|
||||||
|
@Size(max = 255)
|
||||||
|
@Column(name = "props3")
|
||||||
|
private String props3;
|
||||||
|
|
||||||
public CommonCodeEntity(
|
public CommonCodeEntity(
|
||||||
String code, String name, String description, Integer order, Boolean used) {
|
String code, String name, String description, Integer order, Boolean used, String props1, String props2, String props3) {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.order = order;
|
this.order = order;
|
||||||
this.used = used;
|
this.used = used;
|
||||||
|
this.props1 = props1;
|
||||||
|
this.props2 = props2;
|
||||||
|
this.props3 = props3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommonCodeEntity(
|
public CommonCodeEntity(
|
||||||
Long id, String name, String description, Integer order, Boolean used, Boolean deleted) {
|
Long id, String code, String name, String description, Integer order, Boolean used, Boolean deleted, String props1, String props2, String props3) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.code = code;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.order = order;
|
this.order = order;
|
||||||
this.used = used;
|
this.used = used;
|
||||||
this.deleted = deleted;
|
this.deleted = deleted;
|
||||||
|
this.props1 = props1;
|
||||||
|
this.props2 = props2;
|
||||||
|
this.props3 = props3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommonCodeDto.Basic toDto() {
|
public CommonCodeDto.Basic toDto() {
|
||||||
@@ -91,7 +110,11 @@ public class CommonCodeEntity extends CommonDateEntity {
|
|||||||
this.deleted,
|
this.deleted,
|
||||||
this.children.stream().map(CommonCodeEntity::toDto).toList(),
|
this.children.stream().map(CommonCodeEntity::toDto).toList(),
|
||||||
super.getCreatedDate(),
|
super.getCreatedDate(),
|
||||||
super.getModifiedDate());
|
super.getModifiedDate(),
|
||||||
|
this.props1,
|
||||||
|
this.props2,
|
||||||
|
this.props3
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addParent(CommonCodeEntity parent) {
|
public void addParent(CommonCodeEntity parent) {
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package com.kamco.cd.kamcoback.postgres.entity;
|
|||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.SequenceGenerator;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
@@ -20,6 +23,11 @@ import org.hibernate.type.SqlTypes;
|
|||||||
public class MapSheetLearnDataEntity {
|
public class MapSheetLearnDataEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_sheet_learn_data_id_gen")
|
||||||
|
@SequenceGenerator(
|
||||||
|
name = "tb_map_sheet_learn_data_id_gen",
|
||||||
|
sequenceName = "tb_map_sheet_learn_data_data_uid",
|
||||||
|
allocationSize = 1)
|
||||||
@Column(name = "data_uid", nullable = false)
|
@Column(name = "data_uid", nullable = false)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package com.kamco.cd.kamcoback.postgres.entity;
|
|||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.SequenceGenerator;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
@@ -17,6 +20,13 @@ import org.locationtech.jts.geom.Geometry;
|
|||||||
public class MapSheetLearnDataGeomEntity {
|
public class MapSheetLearnDataGeomEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@GeneratedValue(
|
||||||
|
strategy = GenerationType.SEQUENCE,
|
||||||
|
generator = "tb_map_sheet_learn_data_geom_id_gen")
|
||||||
|
@SequenceGenerator(
|
||||||
|
name = "tb_map_sheet_learn_data_geom_id_gen",
|
||||||
|
sequenceName = "tb_map_sheet_learn_data_geom_geom_uid",
|
||||||
|
allocationSize = 1)
|
||||||
@Column(name = "geo_uid", nullable = false)
|
@Column(name = "geo_uid", nullable = false)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.kamco.cd.kamcoback.postgres.repository.code;
|
|||||||
|
|
||||||
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
|
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
|
||||||
import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.CommonCodeEntity;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -15,4 +17,8 @@ public interface CommonCodeRepositoryCustom {
|
|||||||
void updateOrder(CommonCodeDto.OrderReq req);
|
void updateOrder(CommonCodeDto.OrderReq req);
|
||||||
|
|
||||||
Optional<String> getCode(String parentCodeCd, String childCodeCd);
|
Optional<String> getCode(String parentCodeCd, String childCodeCd);
|
||||||
|
|
||||||
|
Long findByParentIdCodeExists(Long parentId, @NotEmpty String code);
|
||||||
|
|
||||||
|
Long findByParentIdCodeExiststoUpdate(Long id, Long parentId, @NotEmpty String code);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,31 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom {
|
|||||||
return Optional.ofNullable(result);
|
return Optional.ofNullable(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long findByParentIdCodeExists(Long parentId, String code) {
|
||||||
|
return queryFactory
|
||||||
|
.select(commonCodeEntity.code.count())
|
||||||
|
.from(commonCodeEntity)
|
||||||
|
.where(
|
||||||
|
commonCodeEntity.parent.id.eq(parentId),
|
||||||
|
commonCodeEntity.code.eq(code)
|
||||||
|
)
|
||||||
|
.fetchOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long findByParentIdCodeExiststoUpdate(Long id, Long parentId, String code) {
|
||||||
|
return queryFactory
|
||||||
|
.select(commonCodeEntity.code.count())
|
||||||
|
.from(commonCodeEntity)
|
||||||
|
.where(
|
||||||
|
commonCodeEntity.parent.id.eq(parentId),
|
||||||
|
commonCodeEntity.code.eq(code),
|
||||||
|
commonCodeEntity.id.ne(id)
|
||||||
|
)
|
||||||
|
.fetchOne();
|
||||||
|
}
|
||||||
|
|
||||||
private List<CommonCodeEntity> findAllByIds(Set<Long> ids) {
|
private List<CommonCodeEntity> findAllByIds(Set<Long> ids) {
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.selectFrom(commonCodeEntity)
|
.selectFrom(commonCodeEntity)
|
||||||
|
|||||||
Reference in New Issue
Block a user