From bbc87071fb163666d422c33b73ce7e7c409573b4 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Mon, 26 Jan 2026 18:20:39 +0900 Subject: [PATCH] =?UTF-8?q?=EC=98=81=EC=83=81=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20>=20tif=20=EB=8C=80=EC=9A=A9=EB=9F=89=20?= =?UTF-8?q?=EB=B6=84=ED=95=A0=EC=A0=84=EC=86=A1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapsheet/MapSheetMngApiController.java | 42 +++++++++++++ .../mapsheet/dto/MapSheetMngDto.java | 7 ++- .../mapsheet/service/MapSheetMngService.java | 63 ++++++++++++++++--- .../postgres/entity/MapSheetMngHstEntity.java | 4 ++ .../mapsheet/MapSheetMngRepositoryImpl.java | 12 ++-- 5 files changed, 112 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java index 5f021d9f..c613f2ad 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java @@ -10,6 +10,8 @@ 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.MngYyyyDto; import com.kamco.cd.kamcoback.mapsheet.service.MapSheetMngService; +import com.kamco.cd.kamcoback.model.dto.ModelMngDto.ModelUploadResDto; +import com.kamco.cd.kamcoback.upload.dto.UploadDto; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -19,6 +21,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; @@ -40,6 +43,12 @@ public class MapSheetMngApiController { private final CommonCodeService commonCodeService; private final MapSheetMngService mapSheetMngService; + @Value("${file.sync-root-dir}") + private String syncRootDir; + + @Value("${file.sync-tmp-dir}") + private String syncRootTmpDir; + @Operation(summary = "영상 데이터 관리 목록 조회", description = "영상 데이터 관리 목록 조회") @ApiResponses( value = { @@ -300,4 +309,37 @@ public class MapSheetMngApiController { return ApiResponseDto.ok(mapSheetMngService.findMapSheetMngDoneYyyyList()); } + + @Operation(summary = "영상 tif 대용량 파일 분할 전송", description = "영상 tif 파일 대용량 파일을 청크 단위로 전송합니다.") + @ApiResponses( + value = { + @ApiResponse(responseCode = "200", description = "청크 업로드 성공", content = @Content), + @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), + @ApiResponse(responseCode = "404", description = "업로드 세션을 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @PostMapping(value = "/file-chunk-upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ApiResponseDto fileChunkUpload( + @RequestParam("hstUid") Long hstUid, + @RequestParam("fileName") String fileName, + @RequestParam("fileSize") long fileSize, + @RequestParam("chunkIndex") Integer chunkIndex, + @RequestParam("chunkTotalIndex") Integer chunkTotalIndex, + @RequestPart("chunkFile") MultipartFile chunkFile) { + + String uploadDivi = "mapsheet"; + + UploadDto.UploadAddReq upAddReqDto = new UploadDto.UploadAddReq(); + upAddReqDto.setDatasetId(0L); + upAddReqDto.setFileName(fileName); + upAddReqDto.setFileSize(fileSize); + upAddReqDto.setChunkIndex(chunkIndex); + upAddReqDto.setChunkTotalIndex(chunkTotalIndex); + upAddReqDto.setUploadDivi(uploadDivi); + upAddReqDto.setFinalPath(syncRootDir); + upAddReqDto.setTempPath(syncRootTmpDir); + + return ApiResponseDto.ok( + mapSheetMngService.uploadChunkMapSheetFile(hstUid, upAddReqDto, chunkFile)); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/mapsheet/dto/MapSheetMngDto.java b/src/main/java/com/kamco/cd/kamcoback/mapsheet/dto/MapSheetMngDto.java index eb4ee0c2..9285815e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/dto/MapSheetMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/dto/MapSheetMngDto.java @@ -9,6 +9,7 @@ import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import io.swagger.v3.oas.annotations.media.Schema; import java.time.ZonedDateTime; import java.util.List; +import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -256,6 +257,8 @@ public class MapSheetMngDto { private String errorCheckTifFileName; private String mapSheetPath; + private UUID uuid; + // private List fileArray; public ErrorDataDto( @@ -274,7 +277,8 @@ public class MapSheetMngDto { String errorCheckState, String errorCheckTfwFileName, String errorCheckTifFileName, - String mapSheetPath) { + String mapSheetPath, + UUID uuid) { this.hstUid = hstUid; this.mngYyyy = mngYyyy; this.mapSheetNum = mapSheetNum; @@ -293,6 +297,7 @@ public class MapSheetMngDto { this.errorCheckTfwFileName = errorCheckTfwFileName; this.errorCheckTifFileName = errorCheckTifFileName; this.mapSheetPath = mapSheetPath; + this.uuid = uuid; } private String getSyncStateName(String enumId) { diff --git a/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java b/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java index 15d57ae6..e2ab15e0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java @@ -15,8 +15,12 @@ import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngFilesDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngYyyyDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq; +import com.kamco.cd.kamcoback.model.dto.ModelMngDto.ModelUploadResDto; import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService; import com.kamco.cd.kamcoback.postgres.entity.YearEntity; +import com.kamco.cd.kamcoback.upload.dto.UploadDto; +import com.kamco.cd.kamcoback.upload.dto.UploadDto.UploadAddReq; +import com.kamco.cd.kamcoback.upload.service.UploadService; import jakarta.validation.Valid; import java.io.IOException; import java.nio.file.Files; @@ -38,6 +42,7 @@ import org.springframework.web.multipart.MultipartFile; public class MapSheetMngService { private final MapSheetMngCoreService mapSheetMngCoreService; + private final UploadService uploadService; private final UserUtil userUtil = new UserUtil(); @Value("${file.sync-root-dir}") @@ -129,15 +134,15 @@ public class MapSheetMngService { MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy()); String targetYearDir = mngDto.getMngPath(); - // 중복체크 - if (!overwrite) { - dmlReturn = - this.duplicateFile( - errDto.getMngYyyy(), tfwFile.getOriginalFilename(), tifFile.getOriginalFilename()); - if (dmlReturn.getFlag().equals("duplicate")) { - return dmlReturn; - } - } + // 중복체크 -> 도엽/uuid_yyyyMMddhhmmss 경로에 업로드 할 거라 overwrite 되지 않음 + // if (!overwrite) { + // dmlReturn = + // this.duplicateFile( + // errDto.getMngYyyy(), tfwFile.getOriginalFilename(), tifFile.getOriginalFilename()); + // if (dmlReturn.getFlag().equals("duplicate")) { + // return dmlReturn; + // } + // } // 멀티파트 파일 tmp폴더 저장(파일형식 체크를 위해) String tfwTmpPath = tmpPath + tfwFile.getOriginalFilename(); @@ -357,4 +362,44 @@ public class MapSheetMngService { return yearList; } + + @Transactional + public ModelUploadResDto uploadChunkMapSheetFile( + Long hstUid, UploadAddReq upAddReqDto, MultipartFile chunkFile) { + + // String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); + ErrorDataDto errDto = mapSheetMngCoreService.findMapSheetError(hstUid); + + // 싱크파일목록으로 업로드 경로 확인 + List mngFiles = mapSheetMngCoreService.findByHstUidMapSheetFileList(hstUid); + String uploadPath = ""; + for (MngFilesDto dto : mngFiles) { + uploadPath = dto.getFilePath(); + break; + } + + if (uploadPath.isEmpty()) { + MngFilesDto filesDto = + mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy()); + String referPath = filesDto.getFilePath(); + uploadPath = Paths.get(referPath).getParent().toString() + "/" + errDto.getRefMapSheetNum(); + } + + upAddReqDto.setUuid(errDto.getUuid()); + upAddReqDto.setFinalPath(uploadPath + "/"); + upAddReqDto.setTempPath(upAddReqDto.getTempPath() + "/"); + + UploadDto.UploadRes upRes = uploadService.uploadChunk(upAddReqDto, chunkFile); + + ModelUploadResDto modelUploadResDto = new ModelUploadResDto(); + modelUploadResDto.setRes(upRes.getRes()); + modelUploadResDto.setResMsg(upRes.getResMsg()); + modelUploadResDto.setUuid(upRes.getUuid()); + modelUploadResDto.setFilePath(upRes.getFilePath()); + modelUploadResDto.setFileName(upRes.getFileName()); + modelUploadResDto.setChunkIndex(upRes.getChunkIndex()); + modelUploadResDto.setChunkTotalIndex(upRes.getChunkTotalIndex()); + + return modelUploadResDto; + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java index 2cf1f359..a08e6ca3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetMngHstEntity.java @@ -12,6 +12,7 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.validation.constraints.Size; import java.time.ZonedDateTime; +import java.util.UUID; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -159,6 +160,9 @@ public class MapSheetMngHstEntity extends CommonDateEntity { @Column(name = "sync_check_tfw_file_name", length = 100) private String syncCheckTfwFileName; + @Column(name = "uuid") + private UUID uuid; + // 파일정보 업데이트 public void updateFileInfos(Long tifSizeBytes, Long tfwSizeBytes) { tifSizeBytes = tifSizeBytes == null ? 0L : tifSizeBytes; diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java index d87fe15e..9730282b 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryImpl.java @@ -387,7 +387,8 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport mapSheetMngHstEntity.syncCheckState, mapSheetMngHstEntity.syncCheckTfwFileName, mapSheetMngHstEntity.syncCheckTifFileName, - mapSheetMngHstEntity.mapSheetPath)) + mapSheetMngHstEntity.mapSheetPath, + mapSheetMngHstEntity.uuid)) .from(mapSheetMngHstEntity) .innerJoin(mapInkx5kEntity) .on( @@ -435,7 +436,6 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport Expressions.stringTemplate( "concat({0}, substring({1}, 1, 5))", mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - // 튜플 방지: concat으로 문자열 생성 Expressions.stringTemplate( "concat('(', {0}, ',', {1}, ')')", @@ -443,18 +443,18 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport Expressions.stringTemplate( "concat({0}, substring({1}, 6, 3))", mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - // fid 타입 주의 (Long이면 DTO도 Long으로 맞추는 걸 추천) mapInkx5kEntity.fid, // 또는 mapInkx5kEntity.fid.intValue() - // createdDate 말고 ZonedDateTime으로 매핑된 필드로 - mapSheetMngHstEntity.createdDate, // (예시) + mapSheetMngHstEntity.createdDate, // (예시) //createdDttm mapSheetMngHstEntity.syncState, mapSheetMngHstEntity.syncTfwFileName, mapSheetMngHstEntity.syncTifFileName, mapSheetMngHstEntity.syncCheckState, mapSheetMngHstEntity.syncCheckTfwFileName, - mapSheetMngHstEntity.syncCheckTifFileName)) + mapSheetMngHstEntity.syncCheckTifFileName, + mapSheetMngHstEntity.mapSheetPath, + mapSheetMngHstEntity.uuid)) .from(mapSheetMngHstEntity) .innerJoin(mapInkx5kEntity) .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo))