싱크경로 yml에 설정하고 FileConfig 삭제
영상관리 수정
This commit is contained in:
@@ -478,6 +478,21 @@ public class FIleChecker {
|
||||
return fileTotSize;
|
||||
}
|
||||
|
||||
public static boolean multipartSaveTo(MultipartFile mfile, String targetPath)
|
||||
{
|
||||
Path tmpSavePath = Paths.get(targetPath);
|
||||
|
||||
boolean fileUpload = true;
|
||||
try {
|
||||
mfile.transferTo(tmpSavePath);
|
||||
} catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean validationMultipart(MultipartFile mfile)
|
||||
{
|
||||
// 파일 유효성 검증
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.kamco.cd.kamcoback.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/** GeoJSON 파일 모니터링 설정 */
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "file.config")
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileConfig {
|
||||
|
||||
// private String rootSyncDir = "D:\\app\\original-images\\";
|
||||
// private String tmpSyncDir = rootSyncDir + "tmp\\";
|
||||
|
||||
private String rootSyncDir = "/app/original-images/";
|
||||
private String tmpSyncDir = rootSyncDir + "tmp/";
|
||||
|
||||
private String syncFileExt = "tfw,tif";
|
||||
}
|
||||
@@ -3,6 +3,10 @@ package com.kamco.cd.kamcoback.mapsheet;
|
||||
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
|
||||
import com.kamco.cd.kamcoback.code.service.CommonCodeService;
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.service.MapSheetMngService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -222,4 +226,46 @@ public class MapSheetMngApiController {
|
||||
@RequestParam @Valid List<Long> fileUids) {
|
||||
return ApiResponseDto.ok(mapSheetMngService.deleteByFileUidMngFile(fileUids));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Operation(summary = "폴더 조회", description = "폴더 조회 (ROOT:/app/original-images 이하로 경로입력)")
|
||||
@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("/folder-list")
|
||||
public ApiResponseDto<FoldersDto> getDir(@RequestBody SrchFoldersDto srchDto) {
|
||||
|
||||
return ApiResponseDto.createOK(mapSheetMngService.getFolderAll(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-list")
|
||||
public ApiResponseDto<FilesDto> getFiles(@RequestBody SrchFilesDto srchDto) {
|
||||
|
||||
return ApiResponseDto.createOK(mapSheetMngService.getFilesAll(srchDto));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
package com.kamco.cd.kamcoback.mapsheet;
|
||||
|
||||
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
|
||||
import com.kamco.cd.kamcoback.code.service.CommonCodeService;
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.service.MapSheetMngFileCheckerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "영상 관리", description = "영상 관리 API")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping({"/api/mapsheet"})
|
||||
public class MapSheetMngFileCheckerApiController {
|
||||
|
||||
private final CommonCodeService commonCodeService;
|
||||
private final MapSheetMngFileCheckerService mapSheetMngFileCheckerService;
|
||||
|
||||
@Operation(summary = "폴더 조회", description = "폴더 조회 (ROOT:/app/original-images 이하로 경로입력)")
|
||||
@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("/folder-list")
|
||||
public ApiResponseDto<FoldersDto> getDir(@RequestBody SrchFoldersDto srchDto) {
|
||||
|
||||
return ApiResponseDto.createOK(mapSheetMngFileCheckerService.getFolderAll(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-list")
|
||||
public ApiResponseDto<FilesDto> getFiles(@RequestBody SrchFilesDto srchDto) {
|
||||
|
||||
return ApiResponseDto.createOK(mapSheetMngFileCheckerService.getFilesAll(srchDto));
|
||||
}
|
||||
|
||||
/*
|
||||
@Operation(summary = "파일 업로드", description = "파일 업로드 및 TIF 검증")
|
||||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public ApiResponseDto<String> uploadFile(
|
||||
@RequestPart("file") MultipartFile file,
|
||||
@RequestParam("targetPath") String targetPath,
|
||||
@RequestParam(value = "overwrite", required = false, defaultValue = "false")
|
||||
boolean overwrite,
|
||||
@RequestParam(value = "hstUid", required = false) Long hstUid) {
|
||||
return ApiResponseDto.createOK(
|
||||
mapSheetMngFileCheckerService.uploadFile(file, targetPath, overwrite, hstUid));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
@Operation(summary = "파일 삭제", description = "중복 파일 등 파일 삭제")
|
||||
@PostMapping("/delete")
|
||||
public ApiResponseDto<Boolean> deleteFile(@RequestBody SrchFoldersDto dto) {
|
||||
return ApiResponseDto.createOK(mapSheetMngFileCheckerService.deleteFile(dto.getDirPath()));
|
||||
}
|
||||
|
||||
@Operation(summary = "중복 파일 삭제", description = "중복 데이터 발견 시 기존 데이터를 삭제")
|
||||
@PostMapping(value = "/delete-file")
|
||||
public ApiResponseDto<String> deleteDuplicateFile(
|
||||
@RequestParam("filePath") String filePath, @RequestParam("fileName") String fileName) {
|
||||
return ApiResponseDto.createOK(
|
||||
mapSheetMngFileCheckerService.deleteDuplicate(filePath, fileName));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
@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 SrchFilesDepthDto srchDto) {
|
||||
|
||||
return ApiResponseDto.createOK(mapSheetMngFileCheckerService.getFilesDepthAll(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("/sync-process")
|
||||
public ApiResponseDto<ImageryDto.SyncReturn> syncProcess(
|
||||
@RequestBody @Valid ImageryDto.searchReq searchReq) {
|
||||
return ApiResponseDto.ok(mapSheetMngFileCheckerService.syncProcess(searchReq));
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
}
|
||||
@@ -1,530 +0,0 @@
|
||||
package com.kamco.cd.kamcoback.mapsheet.service;
|
||||
|
||||
import static java.lang.String.CASE_INSENSITIVE_ORDER;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.exception.DuplicateFileException;
|
||||
import com.kamco.cd.kamcoback.common.exception.ValidationException;
|
||||
import com.kamco.cd.kamcoback.common.utils.FIleChecker;
|
||||
import com.kamco.cd.kamcoback.config.FileConfig;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDepthDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
|
||||
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngFileCheckerCoreService;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngFileEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngFileRepository;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class MapSheetMngFileCheckerService {
|
||||
|
||||
private final MapSheetMngFileCheckerCoreService mapSheetMngFileCheckerCoreService;
|
||||
private final FileConfig fileConfig;
|
||||
private final MapSheetMngFileRepository mapSheetMngFileRepository;
|
||||
|
||||
// @Value("${mapsheet.upload.skipGdalValidation:false}")
|
||||
// private boolean skipGdalValidation;
|
||||
|
||||
public FoldersDto getFolderAll(SrchFoldersDto srchDto) {
|
||||
|
||||
Path startPath = Paths.get(fileConfig.getRootSyncDir() + srchDto.getDirPath());
|
||||
String dirPath = fileConfig.getRootSyncDir() + srchDto.getDirPath();
|
||||
String sortType = "name desc";
|
||||
|
||||
List<FIleChecker.Folder> folderList = FIleChecker.getFolderAll(dirPath);
|
||||
|
||||
int folderTotCnt = folderList.size();
|
||||
int folderErrTotCnt =
|
||||
(int)
|
||||
folderList.stream().filter(dto -> dto.getIsValid().toString().equals("false")).count();
|
||||
|
||||
return new FoldersDto(dirPath, folderTotCnt, folderErrTotCnt, folderList);
|
||||
}
|
||||
|
||||
public FilesDto getFilesAll(SrchFilesDto srchDto) {
|
||||
|
||||
String dirPath = srchDto.getDirPath();
|
||||
int startPos = srchDto.getStartPos();
|
||||
int endPos = srchDto.getEndPos();
|
||||
|
||||
List<FIleChecker.Basic> files =
|
||||
FIleChecker.getFilesFromAllDepth(
|
||||
srchDto.getDirPath(),
|
||||
"*",
|
||||
srchDto.getExtension(),
|
||||
1,
|
||||
srchDto.getSortType(),
|
||||
startPos,
|
||||
endPos);
|
||||
|
||||
int fileListPos = 0;
|
||||
int fileTotCnt = files.size();
|
||||
long fileTotSize = FIleChecker.getFileTotSize(files);
|
||||
|
||||
return new FilesDto(dirPath, fileTotCnt, fileTotSize, files);
|
||||
}
|
||||
|
||||
public FilesDto getFilesDepthAll(SrchFilesDepthDto srchDto) {
|
||||
|
||||
String dirPath = srchDto.getDirPath();
|
||||
int startPos = srchDto.getStartPos();
|
||||
int endPos = srchDto.getEndPos();
|
||||
|
||||
List<FIleChecker.Basic> files =
|
||||
FIleChecker.getFilesFromAllDepth(
|
||||
srchDto.getDirPath(),
|
||||
"*",
|
||||
srchDto.getExtension(),
|
||||
srchDto.getMaxDepth(),
|
||||
srchDto.getSortType(),
|
||||
startPos,
|
||||
endPos);
|
||||
|
||||
int fileListPos = 0;
|
||||
int fileTotCnt = files.size();
|
||||
long fileTotSize = FIleChecker.getFileTotSize(files);
|
||||
|
||||
return new FilesDto(dirPath, fileTotCnt, fileTotSize, files);
|
||||
}
|
||||
|
||||
public Set<String> createExtensionSet(String extensionString) {
|
||||
if (extensionString == null || extensionString.isBlank()) {
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
// "java, class" -> ["java", " class"] -> [".java", ".class"]
|
||||
return Arrays.stream(extensionString.split(","))
|
||||
.map(ext -> ext.trim())
|
||||
.filter(ext -> !ext.isEmpty())
|
||||
.map(ext -> "." + ext.toLowerCase())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public String extractExtension(Path path) {
|
||||
String filename = path.getFileName().toString();
|
||||
int lastDotIndex = filename.lastIndexOf('.');
|
||||
|
||||
// 확장자가 없거나 파일명이 .으로 끝나는 경우
|
||||
if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) {
|
||||
return ""; // 빈 문자열 반환
|
||||
}
|
||||
|
||||
// 확장자 추출 및 소문자 변환
|
||||
return filename.substring(lastDotIndex).toLowerCase();
|
||||
}
|
||||
|
||||
public Comparator<Path> getFileComparator(String sortType) {
|
||||
|
||||
// 파일 이름 비교 기본 Comparator (대소문자 무시)
|
||||
Comparator<Path> nameComparator =
|
||||
Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER);
|
||||
|
||||
Comparator<Path> dateComparator =
|
||||
Comparator.comparing(
|
||||
path -> {
|
||||
try {
|
||||
return Files.getLastModifiedTime(path);
|
||||
} catch (IOException e) {
|
||||
return FileTime.fromMillis(0);
|
||||
}
|
||||
});
|
||||
|
||||
if ("name desc".equalsIgnoreCase(sortType)) {
|
||||
return nameComparator.reversed();
|
||||
} else if ("date".equalsIgnoreCase(sortType)) {
|
||||
return dateComparator;
|
||||
} else if ("date desc".equalsIgnoreCase(sortType)) {
|
||||
return dateComparator.reversed();
|
||||
} else {
|
||||
return nameComparator;
|
||||
}
|
||||
}
|
||||
|
||||
public ImageryDto.SyncReturn syncProcess(ImageryDto.searchReq searchReq) {
|
||||
return mapSheetMngFileCheckerCoreService.syncProcess(searchReq);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public String uploadFile(MultipartFile file, String targetPath, boolean overwrite, Long hstUid) {
|
||||
try {
|
||||
// 파일 유효성 검증
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new ValidationException("업로드 파일이 비어있습니다.");
|
||||
}
|
||||
if (file.getOriginalFilename() == null || file.getOriginalFilename().isEmpty()) {
|
||||
throw new ValidationException("파일명이 유효하지 않습니다.");
|
||||
}
|
||||
|
||||
Path path = Paths.get(targetPath);
|
||||
|
||||
// targetPath가 존재하지 않으면 파일 경로로 가정하고 부모 디렉토리 생성
|
||||
if (!Files.exists(path)) {
|
||||
// 경로가 확장자로 끝나면 파일로 간주
|
||||
if (targetPath.matches(".*\\.[a-zA-Z]{3,4}$")) {
|
||||
if (path.getParent() != null) {
|
||||
Files.createDirectories(path.getParent());
|
||||
}
|
||||
} else {
|
||||
// 확장자가 없으면 디렉토리로 간주
|
||||
Files.createDirectories(path);
|
||||
path = path.resolve(file.getOriginalFilename());
|
||||
}
|
||||
} else if (Files.isDirectory(path)) {
|
||||
path = path.resolve(file.getOriginalFilename());
|
||||
}
|
||||
|
||||
// 최종 파일의 부모 디렉토리 생성
|
||||
if (path.getParent() != null && !Files.exists(path.getParent())) {
|
||||
Files.createDirectories(path.getParent());
|
||||
}
|
||||
|
||||
String filename = path.getFileName().toString();
|
||||
String ext = FilenameUtils.getExtension(filename).toLowerCase();
|
||||
String baseName = FilenameUtils.getBaseName(filename);
|
||||
Path tfwPath =
|
||||
path.getParent() == null
|
||||
? Paths.get(baseName + ".tfw")
|
||||
: path.getParent().resolve(baseName + ".tfw");
|
||||
Path tifPath =
|
||||
path.getParent() == null
|
||||
? Paths.get(baseName + ".tif")
|
||||
: path.getParent().resolve(baseName + ".tif");
|
||||
|
||||
// DB 중복 체크
|
||||
String parentPathStr = path.getParent() != null ? path.getParent().toString() : "";
|
||||
boolean dbExists =
|
||||
mapSheetMngFileRepository.existsByFileNameAndFilePath(filename, parentPathStr);
|
||||
// boolean fileExists = Files.exists(path); // 파일 시스템 존재 여부는 체크하지 않음 (DB 기준)
|
||||
|
||||
// 이미 존재하는 경우 처리 (DB에만 있는 경우 체크)
|
||||
if (!overwrite && dbExists) {
|
||||
throw new DuplicateFileException("동일한 파일이 이미 존재합니다 (DB): " + path.getFileName());
|
||||
}
|
||||
|
||||
// 덮어쓰기인 경우 기존 DB 데이터 삭제 (새로 저장하기 위함)
|
||||
if (overwrite && dbExists) {
|
||||
mapSheetMngFileRepository.deleteByFileNameAndFilePath(filename, parentPathStr);
|
||||
}
|
||||
|
||||
// 업로드 파일 저장(덮어쓰기 허용 시 replace)
|
||||
file.transferTo(path.toFile());
|
||||
|
||||
if ("tfw".equals(ext)) {
|
||||
// TFW 검증
|
||||
boolean tfwOk = FIleChecker.checkTfw(path.toString());
|
||||
if (!tfwOk) {
|
||||
Files.deleteIfExists(path);
|
||||
throw new ValidationException(
|
||||
"유효하지 않은 TFW 파일입니다 (6줄 숫자 형식 검증 실패): " + path.getFileName());
|
||||
}
|
||||
// 안내: 같은 베이스의 TIF가 없으면 추후 TIF 업로드 필요
|
||||
if (!Files.exists(tifPath)) {
|
||||
// DB 메타 저장은 진행 (향후 쌍 검증 위해)
|
||||
saveUploadMeta(path, hstUid);
|
||||
return "TFW 업로드 성공 (매칭되는 TIF가 아직 없습니다).";
|
||||
}
|
||||
// TIF가 존재하면 쌍 요건 충족
|
||||
saveUploadMeta(path, hstUid);
|
||||
return "TFW 업로드 성공";
|
||||
}
|
||||
|
||||
if ("tif".equals(ext) || "tiff".equals(ext)) {
|
||||
// GDAL 검증 (항상 수행)
|
||||
boolean isValidTif = FIleChecker.cmmndGdalInfo(path.toString());
|
||||
if (!isValidTif) {
|
||||
Files.deleteIfExists(path);
|
||||
throw new ValidationException("유효하지 않은 TIF 파일입니다 (GDAL 검증 실패): " + path.getFileName());
|
||||
}
|
||||
|
||||
// TFW 존재/검증
|
||||
if (!Files.exists(tfwPath)) {
|
||||
Files.deleteIfExists(path);
|
||||
throw new ValidationException("TFW 파일이 존재하지 않습니다: " + tfwPath.getFileName());
|
||||
}
|
||||
boolean tfwOk = FIleChecker.checkTfw(tfwPath.toString());
|
||||
if (!tfwOk) {
|
||||
Files.deleteIfExists(path);
|
||||
throw new ValidationException(
|
||||
"유효하지 않은 TFW 파일입니다 (6줄 숫자 형식 검증 실패): " + tfwPath.getFileName());
|
||||
}
|
||||
saveUploadMeta(path, hstUid);
|
||||
return "TIF 업로드 성공";
|
||||
}
|
||||
|
||||
// 기타 확장자: 저장만 하고 메타 기록
|
||||
saveUploadMeta(path, hstUid);
|
||||
|
||||
return "업로드 성공";
|
||||
} catch (ValidationException | DuplicateFileException e) {
|
||||
// 비즈니스 예외는 그대로 던짐
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("파일 I/O 처리 실패: " + e.getMessage(), e);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("파일 업로드 처리 중 오류 발생: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public String uploadPair(
|
||||
MultipartFile tfwFile,
|
||||
MultipartFile tifFile,
|
||||
String targetPath,
|
||||
boolean overwrite,
|
||||
Long hstUid) {
|
||||
try {
|
||||
log.info(
|
||||
"uploadPair 시작 - targetPath: {}, overwrite: {}, hstUid: {}",
|
||||
targetPath,
|
||||
overwrite,
|
||||
hstUid);
|
||||
|
||||
// 파일 유효성 검증
|
||||
if (tfwFile == null || tfwFile.isEmpty()) {
|
||||
throw new ValidationException("TFW 파일이 비어있습니다.");
|
||||
}
|
||||
if (tifFile == null || tifFile.isEmpty()) {
|
||||
throw new ValidationException("TIF 파일이 비어있습니다.");
|
||||
}
|
||||
if (tfwFile.getOriginalFilename() == null || tfwFile.getOriginalFilename().isEmpty()) {
|
||||
throw new ValidationException("TFW 파일명이 유효하지 않습니다.");
|
||||
}
|
||||
if (tifFile.getOriginalFilename() == null || tifFile.getOriginalFilename().isEmpty()) {
|
||||
throw new ValidationException("TIF 파일명이 유효하지 않습니다.");
|
||||
}
|
||||
|
||||
log.info(
|
||||
"파일명 - TFW: {}, TIF: {}", tfwFile.getOriginalFilename(), tifFile.getOriginalFilename());
|
||||
|
||||
Path basePath = Paths.get(targetPath);
|
||||
|
||||
// targetPath가 존재하지 않으면 디렉토리로 생성
|
||||
if (!Files.exists(basePath)) {
|
||||
log.info("대상 경로가 존재하지 않아 디렉토리 생성: {}", basePath);
|
||||
Files.createDirectories(basePath);
|
||||
}
|
||||
|
||||
// 파일인 경우 부모 디렉토리를 basePath로 사용
|
||||
if (Files.isRegularFile(basePath)) {
|
||||
log.info("대상 경로가 파일이므로 부모 디렉토리 사용");
|
||||
basePath = basePath.getParent();
|
||||
}
|
||||
|
||||
if (Files.isDirectory(basePath)) {
|
||||
log.info("디렉토리 확인됨: {}", basePath);
|
||||
// 디렉토리인 경우 파일명 기준으로 경로 생성
|
||||
Path tfwPath = basePath.resolve(tfwFile.getOriginalFilename());
|
||||
Path tifPath = basePath.resolve(tifFile.getOriginalFilename());
|
||||
// 동일 베이스명 확인
|
||||
String tfwBase = FilenameUtils.getBaseName(tfwPath.getFileName().toString());
|
||||
String tifBase = FilenameUtils.getBaseName(tifPath.getFileName().toString());
|
||||
if (!tfwBase.equalsIgnoreCase(tifBase)) {
|
||||
throw new ValidationException("TFW/TIF 파일명이 동일한 베이스가 아닙니다.");
|
||||
}
|
||||
// 디렉토리는 이미 생성되었으므로 추가 생성 불필요
|
||||
// if (tfwPath.getParent() != null) Files.createDirectories(tfwPath.getParent());
|
||||
// if (tifPath.getParent() != null) Files.createDirectories(tifPath.getParent());
|
||||
|
||||
// DB 중복 체크 및 overwrite 처리 (각 파일별)
|
||||
String parentPathStr = basePath.toString();
|
||||
String tfwName = tfwPath.getFileName().toString();
|
||||
String tifName = tifPath.getFileName().toString();
|
||||
boolean tfwDbExists =
|
||||
mapSheetMngFileRepository.existsByFileNameAndFilePath(tfwName, parentPathStr);
|
||||
boolean tifDbExists =
|
||||
mapSheetMngFileRepository.existsByFileNameAndFilePath(tifName, parentPathStr);
|
||||
if (!overwrite && (tfwDbExists || tifDbExists)) {
|
||||
throw new DuplicateFileException("동일한 파일이 이미 존재합니다 (DB): " + tfwName + ", " + tifName);
|
||||
}
|
||||
if (overwrite) {
|
||||
if (tfwDbExists)
|
||||
mapSheetMngFileRepository.deleteByFileNameAndFilePath(tfwName, parentPathStr);
|
||||
if (tifDbExists)
|
||||
mapSheetMngFileRepository.deleteByFileNameAndFilePath(tifName, parentPathStr);
|
||||
}
|
||||
|
||||
// 파일 저장
|
||||
log.info("파일 저장 시작 - TFW: {}, TIF: {}", tfwPath, tifPath);
|
||||
tfwFile.transferTo(tfwPath.toFile());
|
||||
tifFile.transferTo(tifPath.toFile());
|
||||
log.info("파일 저장 완료");
|
||||
|
||||
// 검증
|
||||
log.info("TFW 파일 검증 시작: {}", tfwPath);
|
||||
boolean tfwOk = FIleChecker.checkTfw(tfwPath.toString());
|
||||
if (!tfwOk) {
|
||||
log.warn("TFW 파일 검증 실패: {}", tfwName);
|
||||
Files.deleteIfExists(tfwPath);
|
||||
Files.deleteIfExists(tifPath);
|
||||
throw new ValidationException("유효하지 않은 TFW 파일입니다 (6줄 숫자 형식 검증 실패): " + tfwName);
|
||||
}
|
||||
log.info("TFW 파일 검증 성공");
|
||||
|
||||
log.info("TIF 파일 검증 시작: {}", tifPath);
|
||||
boolean isValidTif = FIleChecker.cmmndGdalInfo(tifPath.toString());
|
||||
if (!isValidTif) {
|
||||
log.warn("TIF 파일 검증 실패: {}", tifName);
|
||||
Files.deleteIfExists(tfwPath);
|
||||
Files.deleteIfExists(tifPath);
|
||||
throw new ValidationException("유효하지 않은 TIF 파일입니다 (GDAL 검증 실패): " + tifName);
|
||||
}
|
||||
log.info("TIF 파일 검증 성공");
|
||||
|
||||
// 메타 저장 (두 파일 각각 저장)
|
||||
log.info("메타 데이터 저장 시작");
|
||||
saveUploadMeta(tfwPath, hstUid);
|
||||
saveUploadMeta(tifPath, hstUid);
|
||||
log.info("메타 데이터 저장 완료");
|
||||
return "TFW/TIF 페어 업로드 성공";
|
||||
} else {
|
||||
throw new ValidationException("targetPath는 디렉토리여야 합니다.");
|
||||
}
|
||||
} catch (ValidationException | DuplicateFileException e) {
|
||||
// 비즈니스 예외는 그대로 던짐
|
||||
log.warn("업로드 비즈니스 예외 발생: {}", e.getMessage());
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
log.error("파일 I/O 처리 실패: {}", e.getMessage(), e);
|
||||
throw new IllegalArgumentException("파일 I/O 처리 실패: " + e.getMessage(), e);
|
||||
} catch (Exception e) {
|
||||
log.error("파일 업로드 처리 중 예상치 못한 오류 발생: {}", e.getMessage(), e);
|
||||
throw new IllegalArgumentException("파일 업로드 처리 중 오류 발생: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveUploadMeta(Path savedPath, Long hstUid) {
|
||||
String fullPath = savedPath.toAbsolutePath().toString();
|
||||
String fileName = savedPath.getFileName().toString();
|
||||
String ext = FilenameUtils.getExtension(fileName);
|
||||
|
||||
MapSheetMngFileEntity entity = new MapSheetMngFileEntity();
|
||||
|
||||
if (hstUid != null) {
|
||||
// 히스토리에서 메타 가져오기
|
||||
var hstOpt = mapSheetMngFileCheckerCoreService.findHstByUid(hstUid);
|
||||
hstOpt.ifPresent(
|
||||
hst -> {
|
||||
entity.setHstUid(hst.getHstUid());
|
||||
entity.setMngYyyy(hst.getMngYyyy());
|
||||
entity.setMapSheetNum(hst.getMapSheetNum());
|
||||
entity.setRefMapSheetNum(hst.getRefMapSheetNum());
|
||||
});
|
||||
} else {
|
||||
// 기존 추정 로직 유지
|
||||
Integer mngYyyy = extractYearFromPath(fullPath);
|
||||
String mapSheetNum = extractMapSheetNumFromFileName(fileName);
|
||||
String refMapSheetNum = null;
|
||||
if (mapSheetNum != null && !mapSheetNum.isEmpty()) {
|
||||
try {
|
||||
long num = Long.parseLong(mapSheetNum);
|
||||
refMapSheetNum = String.valueOf(num / 1000);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
entity.setMngYyyy(mngYyyy);
|
||||
entity.setMapSheetNum(mapSheetNum);
|
||||
entity.setRefMapSheetNum(refMapSheetNum);
|
||||
}
|
||||
|
||||
entity.setFilePath(savedPath.getParent() != null ? savedPath.getParent().toString() : "");
|
||||
entity.setFileName(fileName);
|
||||
entity.setFileExt(ext);
|
||||
|
||||
// 파일 크기 설정
|
||||
try {
|
||||
long size = Files.size(savedPath);
|
||||
entity.setFileSize(size);
|
||||
} catch (IOException e) {
|
||||
entity.setFileSize(0L);
|
||||
}
|
||||
|
||||
mapSheetMngFileRepository.save(entity);
|
||||
}
|
||||
|
||||
private Integer extractYearFromPath(String fullPath) {
|
||||
// 경로에서 4자리 연도를 찾아 가장 근접한 값을 사용
|
||||
// 예시 경로: /Users/.../original-images/2022/2022_25cm/1/34602
|
||||
String[] parts = fullPath.split("/");
|
||||
for (String p : parts) {
|
||||
if (p.matches("\\d{4}")) {
|
||||
try {
|
||||
return Integer.parseInt(p);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String extractMapSheetNumFromFileName(String fileName) {
|
||||
// 파일명에서 연속된 숫자를 최대한 찾아 사용 (예: 34602027.tif -> 34602027)
|
||||
String base = FilenameUtils.getBaseName(fileName);
|
||||
String digits = base.replaceAll("[^0-9]", "");
|
||||
if (!digits.isEmpty()) {
|
||||
return digits;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Boolean deleteFile(String filePath) {
|
||||
try {
|
||||
Path path = Paths.get(filePath);
|
||||
return Files.deleteIfExists(path);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("파일 삭제 실패: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<MapSheetMngFileEntity> findRecentFiles(int limit) {
|
||||
// 간단히 전체를 불러 정렬/제한 (운영에선 Page 요청으로 변경 권장)
|
||||
List<MapSheetMngFileEntity> all = new ArrayList<>();
|
||||
mapSheetMngFileRepository.findAll().forEach(all::add);
|
||||
all.sort(
|
||||
(a, b) -> {
|
||||
// fileUid 기준 내림차순
|
||||
long av = a.getFileUid() == null ? 0L : a.getFileUid();
|
||||
long bv = b.getFileUid() == null ? 0L : b.getFileUid();
|
||||
return Long.compare(bv, av);
|
||||
});
|
||||
if (all.size() > limit) {
|
||||
return all.subList(0, limit);
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public String deleteDuplicate(String filePath, String fileName) {
|
||||
try {
|
||||
Path path = Paths.get(filePath, fileName);
|
||||
boolean deleted = Files.deleteIfExists(path);
|
||||
// DB에서도 삭제
|
||||
mapSheetMngFileRepository.deleteByFileNameAndFilePath(fileName, filePath);
|
||||
return deleted ? "파일 및 DB 레코드 삭제 완료" : "DB 레코드 삭제 완료 (파일 미존재)";
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("중복 파일 삭제 실패: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.kamco.cd.kamcoback.mapsheet.service;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.utils.FIleChecker;
|
||||
import com.kamco.cd.kamcoback.config.FileConfig;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFoldersDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.AddReq;
|
||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.DmlReturn;
|
||||
@@ -31,8 +34,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
public class MapSheetMngService {
|
||||
|
||||
private final MapSheetMngCoreService mapSheetMngCoreService;
|
||||
private final FileConfig fileConfig;
|
||||
|
||||
|
||||
@Value("${file.sync-root-dir}")
|
||||
private String syncRootDir;
|
||||
@@ -113,37 +114,16 @@ public class MapSheetMngService {
|
||||
|
||||
// 중복체크
|
||||
if( !overwrite ) {
|
||||
|
||||
int tfwCnt = FIleChecker.getFileCountFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw");
|
||||
int tifCnt = FIleChecker.getFileCountFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw");
|
||||
|
||||
if (tfwCnt > 0 || tifCnt > 0) {
|
||||
String tfwtifMsg = "";
|
||||
if (tfwCnt > 0)
|
||||
tfwtifMsg = tfwFile.getOriginalFilename();
|
||||
if (tifCnt > 0) {
|
||||
if (tfwCnt > 0)
|
||||
tfwtifMsg = "," + tifFile.getOriginalFilename();
|
||||
else
|
||||
tfwtifMsg = tifFile.getOriginalFilename();
|
||||
}
|
||||
return new DmlReturn("duplicate", tfwtifMsg);
|
||||
}
|
||||
dmlReturn = this.duplicateFile(errDto.getMngYyyy(), tfwFile.getOriginalFilename(), tifFile.getOriginalFilename());
|
||||
if( dmlReturn.getFlag().equals("duplicate") )return dmlReturn;
|
||||
}
|
||||
|
||||
File directory = new File(tmpPath);
|
||||
//멀티파트 파일 tmp폴더 저장(파일형식 체크를 위해)
|
||||
String tfwTmpPath = tmpPath + tfwFile.getOriginalFilename();
|
||||
Path tfwTmpSavePath = Paths.get(tfwTmpPath);
|
||||
String tifTmpPath = tmpPath + tifFile.getOriginalFilename();
|
||||
Path tifTmpSavePath = Paths.get(tifTmpPath);
|
||||
boolean fileUpload = true;
|
||||
try {
|
||||
tfwFile.transferTo(tfwTmpSavePath);
|
||||
tifFile.transferTo(tifTmpSavePath);
|
||||
} catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
return new DmlReturn("fail", "UPLOAD ERROR");
|
||||
}
|
||||
|
||||
if(!FIleChecker.multipartSaveTo(tfwFile, tfwTmpPath))return new DmlReturn("fail", "UPLOAD ERROR");
|
||||
if(!FIleChecker.multipartSaveTo(tifFile, tifTmpPath))return new DmlReturn("fail", "UPLOAD ERROR");
|
||||
|
||||
if (!FIleChecker.cmmndGdalInfo(tifTmpPath)) return new DmlReturn("fail", "TIF TYPE ERROR");
|
||||
if (!FIleChecker.checkTfw(tfwTmpPath)) return new DmlReturn("fail", "TFW TYPE ERROR");
|
||||
@@ -156,6 +136,9 @@ public class MapSheetMngService {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Path tfwTmpSavePath = Paths.get(tfwTmpPath);
|
||||
Path tifTmpSavePath = Paths.get(tifTmpPath);
|
||||
Path tfwTargetPath = null;
|
||||
Path tifTargetPath = null;
|
||||
|
||||
@@ -214,16 +197,6 @@ public class MapSheetMngService {
|
||||
return new DmlReturn("success", "파일 업로드 완료되었습니다.");
|
||||
}
|
||||
|
||||
public DmlReturn validationFile(MultipartFile tfwFile, MultipartFile tifFile)
|
||||
{
|
||||
if( !FIleChecker.validationMultipart(tfwFile) )return new DmlReturn("fail", "TFW SIZE 오류");
|
||||
else if( !FIleChecker.validationMultipart(tifFile) )return new DmlReturn("fail", "TFW SIZE 오류");
|
||||
else if (!FIleChecker.checkExtensions(tfwFile.getOriginalFilename(), "tfw"))return new DmlReturn("fail", "TFW FILENAME ERROR");
|
||||
else if (!FIleChecker.checkExtensions(tifFile.getOriginalFilename(), "tif"))return new DmlReturn("fail", "TIF FILENAME ERROR");
|
||||
|
||||
return new DmlReturn("success", "파일체크");
|
||||
}
|
||||
|
||||
public List<MngFilesDto> findHstUidToMapSheetFileList(Long hstUid) {
|
||||
return mapSheetMngCoreService.findHstUidToMapSheetFileList(hstUid);
|
||||
}
|
||||
@@ -258,4 +231,80 @@ public class MapSheetMngService {
|
||||
|
||||
return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DmlReturn validationFile(MultipartFile tfwFile, MultipartFile tifFile)
|
||||
{
|
||||
if( !FIleChecker.validationMultipart(tfwFile) )return new DmlReturn("fail", "TFW SIZE 오류");
|
||||
else if( !FIleChecker.validationMultipart(tifFile) )return new DmlReturn("fail", "TFW SIZE 오류");
|
||||
else if (!FIleChecker.checkExtensions(tfwFile.getOriginalFilename(), "tfw"))return new DmlReturn("fail", "TFW FILENAME ERROR");
|
||||
else if (!FIleChecker.checkExtensions(tifFile.getOriginalFilename(), "tif"))return new DmlReturn("fail", "TIF FILENAME ERROR");
|
||||
|
||||
return new DmlReturn("success", "파일체크");
|
||||
}
|
||||
|
||||
public DmlReturn duplicateFile(int mngYyyy, String tfwFileName, String tifFileName)
|
||||
{
|
||||
int tfwCnt = mapSheetMngCoreService.findByYearFileNameFileCount(mngYyyy, tfwFileName);
|
||||
int tifCnt = mapSheetMngCoreService.findByYearFileNameFileCount(mngYyyy, tifFileName);
|
||||
|
||||
System.out.println("tfwCnt ==" + tfwCnt);
|
||||
System.out.println("tifCnt ==" + tifCnt);
|
||||
|
||||
if (tfwCnt > 0 || tifCnt > 0) {
|
||||
String resMsg = "";
|
||||
if (tfwCnt > 0)
|
||||
resMsg = tfwFileName;
|
||||
|
||||
if (tifCnt > 0) {
|
||||
if (tfwCnt > 0)
|
||||
resMsg = resMsg + "," + tifFileName;
|
||||
else
|
||||
resMsg = tifFileName;
|
||||
}
|
||||
return new DmlReturn("duplicate", resMsg);
|
||||
}
|
||||
|
||||
return new DmlReturn("success", "파일체크");
|
||||
}
|
||||
|
||||
public FoldersDto getFolderAll(SrchFoldersDto srchDto) {
|
||||
|
||||
Path startPath = Paths.get(syncRootDir + srchDto.getDirPath());
|
||||
String dirPath = syncRootDir + srchDto.getDirPath();
|
||||
String sortType = "name desc";
|
||||
|
||||
List<FIleChecker.Folder> folderList = FIleChecker.getFolderAll(dirPath);
|
||||
|
||||
int folderTotCnt = folderList.size();
|
||||
int folderErrTotCnt =
|
||||
(int)
|
||||
folderList.stream().filter(dto -> dto.getIsValid().toString().equals("false")).count();
|
||||
|
||||
return new FoldersDto(dirPath, folderTotCnt, folderErrTotCnt, folderList);
|
||||
}
|
||||
|
||||
public FilesDto getFilesAll(SrchFilesDto srchDto) {
|
||||
|
||||
String dirPath = srchDto.getDirPath();
|
||||
int startPos = srchDto.getStartPos();
|
||||
int endPos = srchDto.getEndPos();
|
||||
|
||||
List<FIleChecker.Basic> files =
|
||||
FIleChecker.getFilesFromAllDepth(
|
||||
srchDto.getDirPath(),
|
||||
"*",
|
||||
srchDto.getExtension(),
|
||||
1,
|
||||
srchDto.getSortType(),
|
||||
startPos,
|
||||
endPos);
|
||||
|
||||
int fileListPos = 0;
|
||||
int fileTotCnt = files.size();
|
||||
long fileTotSize = FIleChecker.getFileTotSize(files);
|
||||
|
||||
return new FilesDto(dirPath, fileTotCnt, fileTotSize, files);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ public class MapSheetMngCoreService {
|
||||
mapSheetMngRepository.deleteByHstUidMngFile(hstUid);
|
||||
}
|
||||
|
||||
public int findByYearFileNameFileCount(int mngYyyy, String fileName) {
|
||||
return mapSheetMngRepository.findByYearFileNameFileCount(mngYyyy, fileName);
|
||||
}
|
||||
|
||||
public MapSheetMngDto.DmlReturn mngFileSave(@Valid MapSheetMngDto.MngFileAddReq addReq) {
|
||||
|
||||
mapSheetMngRepository.mngFileSave(addReq);
|
||||
|
||||
@@ -55,4 +55,6 @@ public interface MapSheetMngRepositoryCustom {
|
||||
MapSheetMngDto.MngFilesDto findIdToMapSheetFile(Long fileUid);
|
||||
|
||||
void updateHstFileSizes(Long hstUid, long tifSizeBytes, long tfwSizeBytes, long totalSizeBytes);
|
||||
|
||||
int findByYearFileNameFileCount(int mngYyyy, String fileName);
|
||||
}
|
||||
|
||||
@@ -676,6 +676,18 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findByYearFileNameFileCount(int mngYyyy, String fileName){
|
||||
Long execCount = queryFactory
|
||||
.select(mapSheetMngFileEntity.count())
|
||||
.from(mapSheetMngFileEntity)
|
||||
.where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)
|
||||
.and(mapSheetMngFileEntity.fileName.eq(fileName)))
|
||||
.fetchOne();
|
||||
|
||||
return Math.toIntExact(execCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mngFileSave(@Valid MapSheetMngDto.MngFileAddReq addReq) {
|
||||
long fileCount =
|
||||
|
||||
@@ -25,6 +25,7 @@ public class MapSheetMngFileJobController {
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(0, mngSyncPageSize);
|
||||
}
|
||||
|
||||
|
||||
@Scheduled(fixedDelay = 5000)
|
||||
public void mngFileSyncJob01() {
|
||||
if (!isSchedulerEnabled) return;
|
||||
@@ -97,6 +98,7 @@ public class MapSheetMngFileJobController {
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(9, mngSyncPageSize);
|
||||
}
|
||||
|
||||
|
||||
// 3. 외부에서 플래그를 변경할 수 있는 Setter 메서드
|
||||
public void setSchedulerEnabled(boolean enabled) {
|
||||
this.isSchedulerEnabled = enabled;
|
||||
|
||||
@@ -66,6 +66,6 @@ management:
|
||||
|
||||
|
||||
file:
|
||||
sync-root-dir: /app/original-images/
|
||||
sync-root-dir: D:/app/original-images/
|
||||
sync-tmp-dir: ${file.sync-root-dir}/tmp
|
||||
sync-file-extention: tfw,tif
|
||||
|
||||
Reference in New Issue
Block a user