From 11a94829f7de6489259020db8aaae372951752f3 Mon Sep 17 00:00:00 2001 From: DanielLee <198891672+sanghyeonhd@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:28:35 +0900 Subject: [PATCH] File Delete Add --- .../mapsheet/MapSheetMngApiController.java | 86 ++++++++--------- .../mapsheet/dto/MapSheetMngDto.java | 2 +- .../mapsheet/service/MapSheetMngService.java | 86 ++++++++--------- .../postgres/core/MapSheetMngCoreService.java | 94 +++++++++---------- .../mapsheet/MapSheetMngRepositoryCustom.java | 11 +++ .../mapsheet/MapSheetMngRepositoryImpl.java | 48 +++++----- 6 files changed, 169 insertions(+), 158 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 781c92d7..72cda420 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java @@ -36,61 +36,61 @@ public class MapSheetMngApiController { */ @PostMapping("/error-list") public ApiResponseDto> findMapSheetErrorList( - @RequestBody @Valid MapSheetMngDto.searchReq searchReq) { + @RequestBody @Valid MapSheetMngDto.searchReq searchReq) { return ApiResponseDto.ok(mapSheetMngService.findMapSheetErrorList(searchReq)); } @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) - }) + 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("/mng-list") public ApiResponseDto> findMapSheetMngList( - @RequestBody @Valid MapSheetMngDto.searchReq searchReq) { + @RequestBody @Valid MapSheetMngDto.searchReq searchReq) { return ApiResponseDto.ok(mapSheetMngService.findMapSheetMngList(searchReq)); } @Operation(summary = "영상관리 > 데이터 등록", description = "영상관리 > 데이터 등록") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "데이터 등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Long.class))), - @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), - @ApiResponse(responseCode = "404", description = "데이터를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "데이터 등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Long.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), + @ApiResponse(responseCode = "404", description = "데이터를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PutMapping("/mng-data-save") public ApiResponseDto mngDataSave( - @RequestBody @Valid MapSheetMngDto.AddReq AddReq) { + @RequestBody @Valid MapSheetMngDto.AddReq AddReq) { return ApiResponseDto.ok(mapSheetMngService.mngDataSave(AddReq)); } @Operation(summary = "파일 업로드", description = "파일 업로드") @PostMapping(value = "/file-upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ApiResponseDto uploadFile( - @RequestPart(value = "file") MultipartFile file, - @RequestParam(value = "hstUid") Long hstUid) { + @RequestPart(value = "file") MultipartFile file, + @RequestParam(value = "hstUid") Long hstUid) { return ApiResponseDto.ok(mapSheetMngService.uploadFile(file, hstUid)); } @Operation(summary = "파일 삭제", description = "파일 삭제") @PostMapping("/file-delete") public ApiResponseDto deleteFile( - @RequestBody @Valid MapSheetMngDto.DeleteFileReq req) { + @RequestBody @Valid MapSheetMngDto.DeleteFileReq req) { return ApiResponseDto.ok(mapSheetMngService.deleteFile(req)); } @@ -100,21 +100,21 @@ public class MapSheetMngApiController { */ @Operation(summary = "오류데이터 팝업 > 업로드 처리", description = "오류데이터 팝업 > 업로드 처리") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "공통코드 저장 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Long.class))), - @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "공통코드 저장 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Long.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PutMapping("/upload-process") public ApiResponseDto uploadProcess( - @RequestBody @Valid List hstUidList) { + @RequestBody @Valid List hstUidList) { return ApiResponseDto.ok(mapSheetMngService.uploadProcess(hstUidList)); } @@ -125,7 +125,7 @@ public class MapSheetMngApiController { @Operation(summary = "오류데이터 팝업 > 추론 제외", description = "오류데이터 팝업 > 추론 제외") @PutMapping("/except-inference") public ApiResponseDto updateExceptUseInference( - @RequestBody @Valid List hstUidList) { + @RequestBody @Valid List hstUidList) { return ApiResponseDto.ok(mapSheetMngService.updateExceptUseInference(hstUidList)); } } 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 ad61bbec..f21b9cdc 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 @@ -42,7 +42,7 @@ public class MapSheetMngDto { String[] sortParams = sort.split(","); String property = sortParams[0]; Sort.Direction direction = - sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC; + sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC; return PageRequest.of(page, size, Sort.by(direction, property)); } return PageRequest.of(page, size); 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 34ec4ba0..00ccf072 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 @@ -83,8 +83,8 @@ public class MapSheetMngService { String lastModified = dttmFormat.format(new Date(file.lastModified())); files.add( - new FileDto.Basic( - fileName, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified)); + new FileDto.Basic( + fileName, parentFolderNm, parentPath, fullPath, ext, fileSize, lastModified)); fileTotCnt = fileTotCnt + 1; fileTotSize = fileTotSize + fileSize; @@ -120,35 +120,35 @@ public class MapSheetMngService { try (Stream stream = Files.walk(startPath, maxDepth)) { fileDtoList = - stream - .filter(Files::isRegularFile) - .filter( - p -> - extension == null - || extension.equals("") - || extension.equals("*") - || targetExtensions.contains(extractExtension(p))) - .sorted(getFileComparator(sortType)) - .skip(startPos) - .limit(limit) - .map( - path -> { - int depth = path.getNameCount(); + stream + .filter(Files::isRegularFile) + .filter( + p -> + extension == null + || extension.equals("") + || extension.equals("*") + || targetExtensions.contains(extractExtension(p))) + .sorted(getFileComparator(sortType)) + .skip(startPos) + .limit(limit) + .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(); + 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())); + 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()); + 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(); @@ -167,10 +167,10 @@ public class MapSheetMngService { // "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()); + .map(ext -> ext.trim()) + .filter(ext -> !ext.isEmpty()) + .map(ext -> "." + ext.toLowerCase()) + .collect(Collectors.toSet()); } public String extractExtension(Path path) { @@ -190,17 +190,17 @@ public class MapSheetMngService { // 파일 이름 비교 기본 Comparator (대소문자 무시) Comparator nameComparator = - Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); + Comparator.comparing(path -> path.getFileName().toString(), CASE_INSENSITIVE_ORDER); Comparator dateComparator = - Comparator.comparing( - path -> { - try { - return Files.getLastModifiedTime(path); - } catch (IOException e) { - return FileTime.fromMillis(0); - } - }); + Comparator.comparing( + path -> { + try { + return Files.getLastModifiedTime(path); + } catch (IOException e) { + return FileTime.fromMillis(0); + } + }); if ("name desc".equalsIgnoreCase(sortType)) { return nameComparator.reversed(); @@ -214,12 +214,12 @@ public class MapSheetMngService { } public Page findMapSheetErrorList( - MapSheetMngDto.@Valid searchReq searchReq) { + MapSheetMngDto.@Valid searchReq searchReq) { return mapSheetMngCoreService.findMapSheetErrorList(searchReq); } public Page findMapSheetMngList( - MapSheetMngDto.@Valid searchReq searchReq) { + MapSheetMngDto.@Valid searchReq searchReq) { return mapSheetMngCoreService.findMapSheetMngList(searchReq); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java index d258a1aa..1b708a04 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapSheetMngCoreService.java @@ -12,7 +12,6 @@ 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; @@ -30,24 +29,25 @@ public class MapSheetMngCoreService { private static final String ORIGINAL_IMAGES_PATH = "/app/original-images"; - @Value("{spring.profiles.active}") + // Fix: property placeholder syntax + @Value("${spring.profiles.active}") private String activeEnv; public Page findMapSheetErrorList( - MapSheetMngDto.@Valid searchReq searchReq) { + MapSheetMngDto.@Valid searchReq searchReq) { return mapSheetMngRepository.findMapSheetErrorList(searchReq); } public Page findMapSheetMngList( - MapSheetMngDto.@Valid searchReq searchReq) { + MapSheetMngDto.@Valid searchReq searchReq) { return mapSheetMngRepository.findMapSheetMngList(searchReq); } public MapSheetMngDto.DmlReturn uploadFile(MultipartFile file, Long hstUid) { MapSheetMngHstEntity entity = - mapSheetMngRepository - .findMapSheetMngHstInfo(hstUid) - .orElseThrow(() -> new EntityNotFoundException("해당 이력이 존재하지 않습니다.")); + mapSheetMngRepository + .findMapSheetMngHstInfo(hstUid) + .orElseThrow(() -> new EntityNotFoundException("해당 이력이 존재하지 않습니다.")); String localPath = ""; String rootDir = ORIGINAL_IMAGES_PATH + "/" + entity.getMngYyyy(); @@ -62,7 +62,7 @@ public class MapSheetMngCoreService { } String originalFilename = file.getOriginalFilename(); - if (originalFilename == null) { + if (originalFilename == null || originalFilename.isBlank()) { throw new IllegalArgumentException("파일명이 없습니다."); } Path filePath = uploadPath.resolve(originalFilename); @@ -88,54 +88,48 @@ public class MapSheetMngCoreService { } public MapSheetMngDto.DmlReturn uploadProcess(@Valid List hstUidList) { - int count = 0; - if (!Objects.isNull(hstUidList) && !hstUidList.isEmpty()) { - for (Long hstUid : hstUidList) { - Optional entity = - Optional.ofNullable( - mapSheetMngRepository + if (Objects.isNull(hstUidList) || hstUidList.isEmpty()) { + throw new IllegalArgumentException("처리할 대상이 없습니다."); + } + int successCount = 0; + int failCount = 0; + + for (Long hstUid : hstUidList) { + MapSheetMngHstEntity hst = + mapSheetMngRepository .findMapSheetMngHstInfo(hstUid) - .orElseThrow(EntityNotFoundException::new)); + .orElseThrow(() -> new EntityNotFoundException("해당 이력이 존재하지 않습니다.")); - // 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 localPath = ""; // 필요 시 로컬 테스트 경로 설정 + String rootDir = ORIGINAL_IMAGES_PATH + "/" + hst.getMngYyyy(); + if ("local".equals(activeEnv)) { + rootDir = localPath + rootDir; + } - String filename = entity.get().getMapSheetNum(); - String[] extensions = {"tif", "tfw"}; - boolean flag = allExtensionsExist(rootDir, filename, extensions); - if (flag) { - count += 1; - } + String filename = hst.getMapSheetNum(); + String[] extensions = {"tif", "tfw"}; + boolean existBoth = allExtensionsExist(rootDir, filename, extensions); - /* - MapSheetMngDto.DataState dataState = - flag ? MapSheetMngDto.DataState.SUCCESS : MapSheetMngDto.DataState.FAIL; - entity.get().updateDataState(dataState); - */ + String state = existBoth ? "SUCCESS" : "NOT"; + mapSheetMngRepository.updateUploadProcessResult(hstUid, state); + + if (existBoth) { + successCount++; + } else { + failCount++; } } - return new MapSheetMngDto.DmlReturn("success", count + "개 업로드 성공하였습니다."); + + String msg = String.format("업로드 처리 완료: 성공 %d건, 실패 %d건", successCount, failCount); + return new MapSheetMngDto.DmlReturn("success", msg); } public MapSheetMngDto.DmlReturn updateExceptUseInference(@Valid List hstUidList) { - if (!Objects.isNull(hstUidList) && !hstUidList.isEmpty()) { - for (Long hstUid : hstUidList) { - Optional entity = - Optional.ofNullable( - mapSheetMngRepository - .findMapSheetMngHstInfo(hstUid) - .orElseThrow(EntityNotFoundException::new)); - - // entity.get().updateUseInference(true); - } + if (Objects.isNull(hstUidList) || hstUidList.isEmpty()) { + throw new IllegalArgumentException("처리할 대상이 없습니다."); } - return new MapSheetMngDto.DmlReturn("success", hstUidList.size() + "개 추론제외 업데이트 하였습니다."); + long updated = mapSheetMngRepository.updateExceptUseInference(hstUidList); + return new MapSheetMngDto.DmlReturn("success", updated + "개 추론제외 업데이트 하였습니다."); } /** @@ -151,10 +145,10 @@ public class MapSheetMngCoreService { // 모든 파일명을 Set으로 저장 Set fileNames = - paths - .filter(Files::isRegularFile) - .map(p -> p.getFileName().toString()) - .collect(Collectors.toSet()); + paths + .filter(Files::isRegularFile) + .map(p -> p.getFileName().toString()) + .collect(Collectors.toSet()); // 모든 확장자 파일 존재 여부 확인 for (String ext : extensions) { diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java index 817cca55..94bf57c8 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/mapsheet/MapSheetMngRepositoryCustom.java @@ -3,6 +3,7 @@ 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.List; import java.util.Optional; import org.springframework.data.domain.Page; @@ -14,4 +15,14 @@ public interface MapSheetMngRepositoryCustom { Page findMapSheetMngList(MapSheetMngDto.@Valid searchReq searchReq); Optional findMapSheetMngHstInfo(Long hstUid); + + /** + * hstUid 목록에 대해 추론 사용 여부(use_inference)를 'N'으로 업데이트하고 타임스탬프를 기록합니다. + * + * @return 업데이트된 행 수 + */ + long updateExceptUseInference(List hstUidList); + + /** 업로드 처리 결과에 따라 data_state를 업데이트합니다. 성공 시 'SUCCESS', 실패 시 'NOT' 등으로 설정합니다. */ + long updateUploadProcessResult(Long hstUid, String dataState); } 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 2ca6853f..fb0b7a33 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 @@ -16,6 +16,7 @@ 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 java.time.ZonedDateTime; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -100,27 +101,6 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngEntity.mngYyyy.eq(searchReq.getMngYyyy())); } - /* - QMapSheetMngEntity m = mapSheetMngEntity; - QMapSheetMngHstEntity h = mapSheetMngHstEntity; - - List summaryContent = - queryFactory - .select( - Projections.constructor( - MapSheetSummaryDto.class, - mapSheetMngHstEntity.mngYyyy, - mapSheetMngHstEntity.mngYyyy.count().as("syncTotCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("DONE")).then(1L).otherwise(0L) - .sum().as("syncStateDoneCnt") - )) - .from(mapSheetMngHstEntity) - .groupBy(mapSheetMngHstEntity.mngYyyy) // mng_yyyy 별로 그룹핑 - .fetch(); - - */ - List foundContent = queryFactory .select( @@ -192,6 +172,32 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport .fetchOne()); } + @Override + public long updateExceptUseInference(List hstUidList) { + ZonedDateTime now = ZonedDateTime.now(); + long affected = + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.useInference, "N") + .set(mapSheetMngHstEntity.useInferenceDttm, now) + .where(mapSheetMngHstEntity.hstUid.in(hstUidList)) + .execute(); + return affected; + } + + @Override + public long updateUploadProcessResult(Long hstUid, String dataState) { + ZonedDateTime now = ZonedDateTime.now(); + long affected = + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.dataState, dataState) + .set(mapSheetMngHstEntity.dataStateDttm, now) + .where(mapSheetMngHstEntity.hstUid.eq(hstUid)) + .execute(); + return affected; + } + private NumberExpression rowNum() { return Expressions.numberTemplate( Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate);