From 9cdb4a20fa4e031ac04f40d50b27a684af01c31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Thu, 4 Dec 2025 12:13:18 +0900 Subject: [PATCH 01/28] feat: add gdal --- Dockerfile-dev | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Dockerfile-dev b/Dockerfile-dev index 5219a42c..cc49aad0 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -1,6 +1,12 @@ # Stage 1: Build stage (gradle build는 Jenkins에서 이미 수행) FROM eclipse-temurin:21-jre-jammy +# GDAL 설치 +RUN apt-get update && apt-get install -y \ + gdal-bin \ + libgdal-dev \ + && rm -rf /var/lib/apt/lists/* + # 작업 디렉토리 설정 WORKDIR /app From e2e9f57fb6f0bd1f43b85f7763b8cc6122b990dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 18:37:08 +0900 Subject: [PATCH 02/28] feat: add shared folder --- docker-compose-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 107547b6..035481a7 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -14,6 +14,7 @@ services: - /mnt/nfs_share/images:/app/original-images - /mnt/nfs_share/model_output:/app/model-outputs - /mnt/nfs_share/train_dataset:/app/train-dataset + - /mnt/nfs_share/temp:/app/temp networks: - kamco-cds restart: unless-stopped From d70cbca51099f079c01bbb10850c0d0de132dcbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 18:40:15 +0900 Subject: [PATCH 03/28] feat: add shared folder --- docker-compose-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 035481a7..1ac142e5 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -14,7 +14,7 @@ services: - /mnt/nfs_share/images:/app/original-images - /mnt/nfs_share/model_output:/app/model-outputs - /mnt/nfs_share/train_dataset:/app/train-dataset - - /mnt/nfs_share/temp:/app/temp + - /mnt/nfs_share/tmp:/app/tmp networks: - kamco-cds restart: unless-stopped From b8bc14bb17092ccc863b990b43f402430c49c05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 19:25:48 +0900 Subject: [PATCH 04/28] feat: add add_imagery_data_api_v2 --- .../mapsheet/MapSheetMngApiController.java | 28 +++------- .../mapsheet/MapSheetMngApiV2Controller.java | 54 +++++++++++++++++++ .../mapsheet/dto/MapSheetMngDto.java | 15 ++++++ 3 files changed, 77 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java 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 36e4ea89..c3779d20 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java @@ -16,7 +16,14 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @Tag(name = "영상 관리", description = "영상 관리 API") @@ -105,25 +112,6 @@ public class MapSheetMngApiController { return ApiResponseDto.ok(mapSheetMngService.mngComplete(mngYyyy)); } - @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("/mng-year-list") - public ApiResponseDto> findMapSheetMngYyyyList() { - - return ApiResponseDto.ok(mapSheetMngService.findMapSheetMngYyyyList()); - } - @Operation(summary = "영상 데이터 관리 오류 목록", description = "영상 데이터 관리 오류 목록") @ApiResponses( value = { diff --git a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java new file mode 100644 index 00000000..6fade892 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java @@ -0,0 +1,54 @@ +package com.kamco.cd.kamcoback.mapsheet; + +import com.kamco.cd.kamcoback.code.dto.CommonCodeDto; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.mapsheet.service.MapSheetMngService; +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 java.time.Year; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "영상 관리", description = "영상 관리 API") +@RestController +@RequiredArgsConstructor +@RequestMapping({"/api/v2/mapsheet"}) +public class MapSheetMngApiV2Controller { + + private final MapSheetMngService mapSheetMngService; + + @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("/mng-year-list") + public ApiResponseDto findMapSheetMngYyyyList() { + + List years = mapSheetMngService.findMapSheetMngYyyyList(); + // 현재 년도 가져온다 + int currentYear = Year.now().getValue(); + + // 현재년도와 같거나 큰 년도를 가져온다. + Optional result = years.stream().filter(y -> y >= currentYear).min(Integer::compareTo); + + return ApiResponseDto.ok(new MapSheetMngDto.ResisterYearList(result.orElse(null), years)); + } +} 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 f4ee99b2..1ce5a5a1 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 @@ -6,6 +6,7 @@ import com.kamco.cd.kamcoback.common.utils.enums.Enums; 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 lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -238,6 +239,7 @@ public class MapSheetMngDto { @Getter @Setter public static class SyncCheckStateReqUpdateDto { + private Long hstUid; private String filePath; private String syncCheckTfwFileName; @@ -304,4 +306,17 @@ public class MapSheetMngDto { private Long hstUid; private Long fileSize; } + + @Schema(name = "ResisterYearList", description = "영상파일 등록을 위한 연도 list") + @Getter + public static class ResisterYearList { + + private Integer currnet; + private List years; + + public ResisterYearList(Integer currnet, List years) { + this.currnet = currnet; + this.years = years; + } + } } From acd0a783b546848bc8bea0f5dcebcddaac980c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 19:32:19 +0900 Subject: [PATCH 05/28] api_yearlist_for_bug_image_reg --- .../cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java index 6fade892..ed8a92de 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java @@ -14,7 +14,7 @@ import java.time.Year; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -39,7 +39,7 @@ public class MapSheetMngApiV2Controller { @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) - @PostMapping("/mng-year-list") + @GetMapping("/mng-year-list") public ApiResponseDto findMapSheetMngYyyyList() { List years = mapSheetMngService.findMapSheetMngYyyyList(); From 2a314dac7bc2d508ccaa991eafacf1505af2bd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 19:35:15 +0900 Subject: [PATCH 06/28] api_yearlist_for_bug_image_reg --- .../com/kamco/cd/kamcoback/mapsheet/dto/MapSheetMngDto.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 1ce5a5a1..300243b3 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 @@ -311,11 +311,11 @@ public class MapSheetMngDto { @Getter public static class ResisterYearList { - private Integer currnet; + private Integer current; private List years; - public ResisterYearList(Integer currnet, List years) { - this.currnet = currnet; + public ResisterYearList(Integer current, List years) { + this.current = current; this.years = years; } } From 6d5850d200ed13e6d522552fc9cf72a8750c4616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 20:18:54 +0900 Subject: [PATCH 07/28] api_yearlist_for_bug_image_reg --- docker-compose-dev.yml | 1 + src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 1ac142e5..0c04a8dd 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -5,6 +5,7 @@ services: dockerfile: Dockerfile-dev image: kamco-changedetection-api:${IMAGE_TAG:-latest} container_name: kamco-changedetection-api + user: "1000:1000" ports: - "7100:8080" environment: diff --git a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java index 196fc9aa..dc409389 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java @@ -16,7 +16,7 @@ public class FileConfig { // private String tmpSyncDir = rootSyncDir + "tmp\\"; private String rootSyncDir = "/app/original-images/"; - private String tmpSyncDir = rootSyncDir + "tmp/"; + private String tmpSyncDir = "/api/tmp/"; private String syncFileExt = "tfw,tif"; } From 4e3f65df84706ad0682e1fea22a57e838d06cde6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 20:23:49 +0900 Subject: [PATCH 08/28] api_yearlist_for_bug_image_reg --- Dockerfile-dev | 8 ++++++++ docker-compose-dev.yml | 3 +++ 2 files changed, 11 insertions(+) diff --git a/Dockerfile-dev b/Dockerfile-dev index cc49aad0..994ea58a 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -7,6 +7,14 @@ RUN apt-get update && apt-get install -y \ libgdal-dev \ && rm -rf /var/lib/apt/lists/* +ARG UID=1000 +ARG GID=1000 + +RUN groupadd -g ${GID} manager01 \ + && useradd -u ${UID} -g ${GID} -m manager01 + +USER manager01 + # 작업 디렉토리 설정 WORKDIR /app diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 0c04a8dd..60706853 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -3,6 +3,9 @@ services: build: context: . dockerfile: Dockerfile-dev + args: + UID: 1000 # manager01 UID + GID: 1000 # manager01 GID image: kamco-changedetection-api:${IMAGE_TAG:-latest} container_name: kamco-changedetection-api user: "1000:1000" From 4be112f1de26f287fb1081f6ef771a9f7ac9ccfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 20:29:26 +0900 Subject: [PATCH 09/28] =?UTF-8?q?feat:=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapsheet/service/MapSheetMngService.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) 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 0fcf9706..d243dde5 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 @@ -19,11 +19,13 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +@Slf4j @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -85,6 +87,7 @@ public class MapSheetMngService { } // 파일검증용 임시저장 폴더 확인 + log.info("TmpPath > {}", tmpPath); if (!FIleChecker.mkDir(tmpPath)) { return new DmlReturn("fail", "CREATE TEMP FOLDER ERROR"); } @@ -127,10 +130,15 @@ public class MapSheetMngService { if (tfwCnt > 0 || tifCnt > 0) { String tfwtifMsg = ""; - if (tfwCnt > 0) tfwtifMsg = tfwFile.getOriginalFilename(); + if (tfwCnt > 0) { + tfwtifMsg = tfwFile.getOriginalFilename(); + } if (tifCnt > 0) { - if (tfwCnt > 0) tfwtifMsg = "," + tifFile.getOriginalFilename(); - else tfwtifMsg = tifFile.getOriginalFilename(); + if (tfwCnt > 0) { + tfwtifMsg = "," + tifFile.getOriginalFilename(); + } else { + tfwtifMsg = tifFile.getOriginalFilename(); + } } return new DmlReturn("duplicate", tfwtifMsg); } @@ -149,8 +157,12 @@ public class MapSheetMngService { 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"); + if (!FIleChecker.cmmndGdalInfo(tifTmpPath)) { + return new DmlReturn("fail", "TIF TYPE ERROR"); + } + if (!FIleChecker.checkTfw(tfwTmpPath)) { + return new DmlReturn("fail", "TFW TYPE ERROR"); + } // 싱크파일목록으로 업로드 경로 확인 List mngFiles = mapSheetMngCoreService.findIdToMapSheetFileList(hstUid); @@ -247,7 +259,9 @@ public class MapSheetMngService { } // 중복제거 확인후 처리상태(DONE)변경 - if (hstUid > 0) mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); + if (hstUid > 0) { + mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); + } return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다."); } From 7c50152737ffcdda5f5da34e66520af3559ce04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 22 Dec 2025 20:34:45 +0900 Subject: [PATCH 10/28] =?UTF-8?q?feat:=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java index dc409389..196fc9aa 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/FileConfig.java @@ -16,7 +16,7 @@ public class FileConfig { // private String tmpSyncDir = rootSyncDir + "tmp\\"; private String rootSyncDir = "/app/original-images/"; - private String tmpSyncDir = "/api/tmp/"; + private String tmpSyncDir = rootSyncDir + "tmp/"; private String syncFileExt = "tfw,tif"; } From 540e11a40b1276c612fd28d2200ea213af9a6ba4 Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 24 Dec 2025 11:23:29 +0900 Subject: [PATCH 11/28] =?UTF-8?q?=EC=98=81=EC=83=81=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapsheet/service/MapSheetMngService.java | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) 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 6da4de90..fc7fdac1 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 @@ -19,13 +19,11 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -@Slf4j @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -76,18 +74,19 @@ public class MapSheetMngService { } @Transactional - public DmlReturn uploadPair(MultipartFile tfwFile, MultipartFile tifFile, Long hstUid) { + public DmlReturn uploadPair( + MultipartFile tfwFile, MultipartFile tifFile, Long hstUid, Boolean overwrite) { String rootPath = fileConfig.getRootSyncDir(); String tmpPath = fileConfig.getTmpSyncDir(); ErrorDataDto errDto = mapSheetMngCoreService.findMapSheetError(hstUid); + if (errDto == null) { return new DmlReturn("fail", "NO hstUid Data"); } // 파일검증용 임시저장 폴더 확인 - log.info("TmpPath > {}", tmpPath); if (!FIleChecker.mkDir(tmpPath)) { return new DmlReturn("fail", "CREATE TEMP FOLDER ERROR"); } @@ -111,36 +110,38 @@ public class MapSheetMngService { // 중복체크 List basicTfwList = - FIleChecker.getFilesFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw"); + FIleChecker.getFilesFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw"); List basicTifList = - FIleChecker.getFilesFromAllDepth(targetYearDir, tifFile.getOriginalFilename(), "tif"); + FIleChecker.getFilesFromAllDepth(targetYearDir, tifFile.getOriginalFilename(), "tif"); int tfwCnt = - (int) - basicTfwList.stream() - .filter(dto -> dto.getExtension().toString().equals("tfw")) - .count(); + (int) + basicTfwList.stream() + .filter(dto -> dto.getExtension().toString().equals("tfw")) + .count(); int tifCnt = - (int) - basicTifList.stream() - .filter(dto -> dto.getExtension().toString().equals("tif")) - .count(); + (int) + basicTifList.stream() + .filter(dto -> dto.getExtension().toString().equals("tif")) + .count(); - if (tfwCnt > 0 || tifCnt > 0) { - String tfwtifMsg = ""; - if (tfwCnt > 0) { - tfwtifMsg = tfwFile.getOriginalFilename(); - } - if (tifCnt > 0) { + if (!overwrite) { + if (tfwCnt > 0 || tifCnt > 0) { + String tfwtifMsg = ""; if (tfwCnt > 0) { - tfwtifMsg = "," + tifFile.getOriginalFilename(); - } else { - tfwtifMsg = tifFile.getOriginalFilename(); + tfwtifMsg = tfwFile.getOriginalFilename(); } + if (tifCnt > 0) { + if (tfwCnt > 0) { + tfwtifMsg = "," + tifFile.getOriginalFilename(); + } else { + tfwtifMsg = tifFile.getOriginalFilename(); + } + } + return new DmlReturn("duplicate", tfwtifMsg); } - return new DmlReturn("duplicate", tfwtifMsg); } File directory = new File(tmpPath); @@ -178,7 +179,7 @@ public class MapSheetMngService { // 파일이 존재하지 않을 경우(0개) 해당년도 다른 파일경로로 참조 if (uploadPath.isEmpty()) { MngFilesDto filesDto = - mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy()); + mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy()); String referPath = filesDto.getFilePath(); uploadPath = Paths.get(referPath).getParent().toString() + "/" + errDto.getRefMapSheetNum(); } @@ -200,7 +201,7 @@ public class MapSheetMngService { // hst업데이트 MapSheetMngDto.SyncCheckStateReqUpdateDto updReqSyncCheckState = - new MapSheetMngDto.SyncCheckStateReqUpdateDto(); + new MapSheetMngDto.SyncCheckStateReqUpdateDto(); updReqSyncCheckState.setHstUid(hstUid); updReqSyncCheckState.setFilePath(uploadPath); updReqSyncCheckState.setSyncCheckTfwFileName(tfwFile.getOriginalFilename()); From 77303a3f2cfc8f9ac7399ad8423c1e4773d27e7a Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 24 Dec 2025 11:33:19 +0900 Subject: [PATCH 12/28] =?UTF-8?q?=EC=98=81=EC=83=81=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/mapsheet/service/MapSheetMngService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 fc7fdac1..7f9ce0d2 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 @@ -74,8 +74,7 @@ public class MapSheetMngService { } @Transactional - public DmlReturn uploadPair( - MultipartFile tfwFile, MultipartFile tifFile, Long hstUid, Boolean overwrite) { + public DmlReturn uploadPair(MultipartFile tfwFile, MultipartFile tifFile, Long hstUid, Boolean overwrite) { String rootPath = fileConfig.getRootSyncDir(); String tmpPath = fileConfig.getTmpSyncDir(); From b9cc6059e208fdca66495be8c125d28066026370 Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 24 Dec 2025 11:35:18 +0900 Subject: [PATCH 13/28] =?UTF-8?q?=EC=98=81=EC=83=81=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapsheet/service/MapSheetMngService.java | 269 ------------------ 1 file changed, 269 deletions(-) delete mode 100644 src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java 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 deleted file mode 100644 index 7f9ce0d2..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java +++ /dev/null @@ -1,269 +0,0 @@ -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.MapSheetMngDto; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.AddReq; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.DmlReturn; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorDataDto; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorSearchReq; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngDto; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngFilesDto; -import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService; -import jakarta.validation.Valid; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class MapSheetMngService { - - private final MapSheetMngCoreService mapSheetMngCoreService; - private final FileConfig fileConfig; - - public List findMapSheetMngList() { - return mapSheetMngCoreService.findMapSheetMngList(); - } - - public List findMapSheetMngYyyyList() { - return mapSheetMngCoreService.findMapSheetMngYyyyList(); - } - - public MngDto findMapSheetMng(int mngYyyy) { - return mapSheetMngCoreService.findMapSheetMng(mngYyyy); - } - - @Transactional - public DmlReturn mngComplete(int mngYyyy) { - - mapSheetMngCoreService.MapSheetMngComplete(mngYyyy); - - return new DmlReturn("success", "작업완료 처리되었습니다."); - } - - public Page findMapSheetErrorList(@Valid ErrorSearchReq searchReq) { - return mapSheetMngCoreService.findMapSheetErrorList(searchReq); - } - - public ErrorDataDto findMapSheetError(Long hstUid) { - return mapSheetMngCoreService.findMapSheetError(hstUid); - } - - @Transactional - public DmlReturn mngDataSave(AddReq AddReq) { - return mapSheetMngCoreService.mngDataSave(AddReq); - } - - public DmlReturn uploadProcess(@Valid List hstUidList) { - return mapSheetMngCoreService.uploadProcess(hstUidList); - } - - public DmlReturn updateExceptUseInference(@Valid List hstUidList) { - return mapSheetMngCoreService.updateExceptUseInference(hstUidList); - } - - @Transactional - public DmlReturn uploadPair(MultipartFile tfwFile, MultipartFile tifFile, Long hstUid, Boolean overwrite) { - - String rootPath = fileConfig.getRootSyncDir(); - String tmpPath = fileConfig.getTmpSyncDir(); - - ErrorDataDto errDto = mapSheetMngCoreService.findMapSheetError(hstUid); - - if (errDto == null) { - return new DmlReturn("fail", "NO hstUid Data"); - } - - // 파일검증용 임시저장 폴더 확인 - if (!FIleChecker.mkDir(tmpPath)) { - return new DmlReturn("fail", "CREATE TEMP FOLDER ERROR"); - } - - // 파일 유효성 검증 - if (tfwFile == null || tfwFile.isEmpty() || tfwFile.getSize() == 0) { - return new DmlReturn("fail", "TFW SIZE 오류"); - } else if (tifFile == null || tifFile.isEmpty() || tifFile.getSize() == 0) { - return new DmlReturn("fail", "TIF SIZE 오류"); - } - - // 확장자명 체크 - 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"); - } - - MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy()); - String targetYearDir = mngDto.getMngPath(); - - // 중복체크 - List basicTfwList = - FIleChecker.getFilesFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw"); - - List basicTifList = - FIleChecker.getFilesFromAllDepth(targetYearDir, tifFile.getOriginalFilename(), "tif"); - - int tfwCnt = - (int) - basicTfwList.stream() - .filter(dto -> dto.getExtension().toString().equals("tfw")) - .count(); - - int tifCnt = - (int) - basicTifList.stream() - .filter(dto -> dto.getExtension().toString().equals("tif")) - .count(); - - if (!overwrite) { - 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); - } - } - - File directory = new File(tmpPath); - 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.cmmndGdalInfo(tifTmpPath)) { - return new DmlReturn("fail", "TIF TYPE ERROR"); - } - if (!FIleChecker.checkTfw(tfwTmpPath)) { - return new DmlReturn("fail", "TFW TYPE ERROR"); - } - - // 싱크파일목록으로 업로드 경로 확인 - List mngFiles = mapSheetMngCoreService.findIdToMapSheetFileList(hstUid); - String uploadPath = ""; - for (MngFilesDto dto : mngFiles) { - uploadPath = dto.getFilePath(); - break; - } - - Path tfwTargetPath = null; - Path tifTargetPath = null; - - // 파일이 존재하지 않을 경우(0개) 해당년도 다른 파일경로로 참조 - if (uploadPath.isEmpty()) { - MngFilesDto filesDto = - mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy()); - String referPath = filesDto.getFilePath(); - uploadPath = Paths.get(referPath).getParent().toString() + "/" + errDto.getRefMapSheetNum(); - } - - // 업로드 경로 확인(없으면 생성) - if (!FIleChecker.mkDir(uploadPath)) { - return new DmlReturn("fail", "CREATE FOLDER ERROR"); - } - - tfwTargetPath = Paths.get(uploadPath).resolve(tfwFile.getOriginalFilename()); - tifTargetPath = Paths.get(uploadPath).resolve(tifFile.getOriginalFilename()); - - try { - Files.move(tfwTmpSavePath, tfwTargetPath, StandardCopyOption.REPLACE_EXISTING); - Files.move(tifTmpSavePath, tifTargetPath, StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - throw new RuntimeException(e); - } - - // hst업데이트 - MapSheetMngDto.SyncCheckStateReqUpdateDto updReqSyncCheckState = - new MapSheetMngDto.SyncCheckStateReqUpdateDto(); - updReqSyncCheckState.setHstUid(hstUid); - updReqSyncCheckState.setFilePath(uploadPath); - updReqSyncCheckState.setSyncCheckTfwFileName(tfwFile.getOriginalFilename()); - updReqSyncCheckState.setSyncCheckTifFileName(tifFile.getOriginalFilename()); - updReqSyncCheckState.setSyncCheckState("DONE"); - mapSheetMngCoreService.updateMapSheetMngHstSyncCheckState(updReqSyncCheckState); - // 파일정보 업데이트 - mapSheetMngCoreService.deleteByHstUidMngFile(hstUid); - - MapSheetMngDto.MngFileAddReq addReq = new MapSheetMngDto.MngFileAddReq(); - addReq.setMngYyyy(errDto.getMngYyyy()); - addReq.setMapSheetNum(errDto.getMapSheetNum()); - addReq.setRefMapSheetNum(errDto.getRefMapSheetNum()); - addReq.setFilePath(uploadPath); - addReq.setFileName(tfwFile.getOriginalFilename()); - addReq.setFileExt("tfw"); - addReq.setFileSize(tfwFile.getSize()); - addReq.setHstUid(errDto.getHstUid()); - addReq.setFileState("DONE"); - - mapSheetMngCoreService.mngFileSave(addReq); - - addReq.setFileExt("tif"); - addReq.setFileSize(tifFile.getSize()); - mapSheetMngCoreService.mngFileSave(addReq); - - return new DmlReturn("success", "파일 업로드 완료되었습니다."); - } - - public List findHstUidToMapSheetFileList(Long hstUid) { - return mapSheetMngCoreService.findHstUidToMapSheetFileList(hstUid); - } - - @Transactional - public DmlReturn deleteByFileUidMngFile(List fileUids) { - - long hstUid = 0; - // hstUid = 149049; - - for (Long uid : fileUids) { - MapSheetMngDto.MngFilesDto dto = mapSheetMngCoreService.findIdToMapSheetFile(uid); - hstUid = dto.getHstUid(); - - String filePath = dto.getFilePath() + "/" + dto.getFileName(); - Path path = Paths.get(filePath); - try { - boolean isDeleted = Files.deleteIfExists(path); - if (isDeleted) { - System.out.println("파일 삭제 성공: " + filePath); - } else { - System.out.println("삭제 실패: 파일이 존재하지 않습니다."); - } - } catch (IOException e) { - System.err.println("파일 삭제 중 오류 발생: " + e.getMessage()); - } - DmlReturn dmlReturn = mapSheetMngCoreService.deleteByFileUidMngFile(uid); - } - - // 중복제거 확인후 처리상태(DONE)변경 - if (hstUid > 0) { - mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); - } - - return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다."); - } -} From 4836261dde7cd248d8183acb39e7b751cb989ebb Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 24 Dec 2025 11:38:51 +0900 Subject: [PATCH 14/28] =?UTF-8?q?=EC=98=81=EC=83=81=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapsheet/service/MapSheetMngService.java | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java 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 new file mode 100644 index 00000000..fc7fdac1 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java @@ -0,0 +1,270 @@ +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.MapSheetMngDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.AddReq; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.DmlReturn; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorDataDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorSearchReq; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngFilesDto; +import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService; +import jakarta.validation.Valid; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MapSheetMngService { + + private final MapSheetMngCoreService mapSheetMngCoreService; + private final FileConfig fileConfig; + + public List findMapSheetMngList() { + return mapSheetMngCoreService.findMapSheetMngList(); + } + + public List findMapSheetMngYyyyList() { + return mapSheetMngCoreService.findMapSheetMngYyyyList(); + } + + public MngDto findMapSheetMng(int mngYyyy) { + return mapSheetMngCoreService.findMapSheetMng(mngYyyy); + } + + @Transactional + public DmlReturn mngComplete(int mngYyyy) { + + mapSheetMngCoreService.MapSheetMngComplete(mngYyyy); + + return new DmlReturn("success", "작업완료 처리되었습니다."); + } + + public Page findMapSheetErrorList(@Valid ErrorSearchReq searchReq) { + return mapSheetMngCoreService.findMapSheetErrorList(searchReq); + } + + public ErrorDataDto findMapSheetError(Long hstUid) { + return mapSheetMngCoreService.findMapSheetError(hstUid); + } + + @Transactional + public DmlReturn mngDataSave(AddReq AddReq) { + return mapSheetMngCoreService.mngDataSave(AddReq); + } + + public DmlReturn uploadProcess(@Valid List hstUidList) { + return mapSheetMngCoreService.uploadProcess(hstUidList); + } + + public DmlReturn updateExceptUseInference(@Valid List hstUidList) { + return mapSheetMngCoreService.updateExceptUseInference(hstUidList); + } + + @Transactional + public DmlReturn uploadPair( + MultipartFile tfwFile, MultipartFile tifFile, Long hstUid, Boolean overwrite) { + + String rootPath = fileConfig.getRootSyncDir(); + String tmpPath = fileConfig.getTmpSyncDir(); + + ErrorDataDto errDto = mapSheetMngCoreService.findMapSheetError(hstUid); + + if (errDto == null) { + return new DmlReturn("fail", "NO hstUid Data"); + } + + // 파일검증용 임시저장 폴더 확인 + if (!FIleChecker.mkDir(tmpPath)) { + return new DmlReturn("fail", "CREATE TEMP FOLDER ERROR"); + } + + // 파일 유효성 검증 + if (tfwFile == null || tfwFile.isEmpty() || tfwFile.getSize() == 0) { + return new DmlReturn("fail", "TFW SIZE 오류"); + } else if (tifFile == null || tifFile.isEmpty() || tifFile.getSize() == 0) { + return new DmlReturn("fail", "TIF SIZE 오류"); + } + + // 확장자명 체크 + 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"); + } + + MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy()); + String targetYearDir = mngDto.getMngPath(); + + // 중복체크 + List basicTfwList = + FIleChecker.getFilesFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw"); + + List basicTifList = + FIleChecker.getFilesFromAllDepth(targetYearDir, tifFile.getOriginalFilename(), "tif"); + + int tfwCnt = + (int) + basicTfwList.stream() + .filter(dto -> dto.getExtension().toString().equals("tfw")) + .count(); + + int tifCnt = + (int) + basicTifList.stream() + .filter(dto -> dto.getExtension().toString().equals("tif")) + .count(); + + if (!overwrite) { + 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); + } + } + + File directory = new File(tmpPath); + 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.cmmndGdalInfo(tifTmpPath)) { + return new DmlReturn("fail", "TIF TYPE ERROR"); + } + if (!FIleChecker.checkTfw(tfwTmpPath)) { + return new DmlReturn("fail", "TFW TYPE ERROR"); + } + + // 싱크파일목록으로 업로드 경로 확인 + List mngFiles = mapSheetMngCoreService.findIdToMapSheetFileList(hstUid); + String uploadPath = ""; + for (MngFilesDto dto : mngFiles) { + uploadPath = dto.getFilePath(); + break; + } + + Path tfwTargetPath = null; + Path tifTargetPath = null; + + // 파일이 존재하지 않을 경우(0개) 해당년도 다른 파일경로로 참조 + if (uploadPath.isEmpty()) { + MngFilesDto filesDto = + mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy()); + String referPath = filesDto.getFilePath(); + uploadPath = Paths.get(referPath).getParent().toString() + "/" + errDto.getRefMapSheetNum(); + } + + // 업로드 경로 확인(없으면 생성) + if (!FIleChecker.mkDir(uploadPath)) { + return new DmlReturn("fail", "CREATE FOLDER ERROR"); + } + + tfwTargetPath = Paths.get(uploadPath).resolve(tfwFile.getOriginalFilename()); + tifTargetPath = Paths.get(uploadPath).resolve(tifFile.getOriginalFilename()); + + try { + Files.move(tfwTmpSavePath, tfwTargetPath, StandardCopyOption.REPLACE_EXISTING); + Files.move(tifTmpSavePath, tifTargetPath, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // hst업데이트 + MapSheetMngDto.SyncCheckStateReqUpdateDto updReqSyncCheckState = + new MapSheetMngDto.SyncCheckStateReqUpdateDto(); + updReqSyncCheckState.setHstUid(hstUid); + updReqSyncCheckState.setFilePath(uploadPath); + updReqSyncCheckState.setSyncCheckTfwFileName(tfwFile.getOriginalFilename()); + updReqSyncCheckState.setSyncCheckTifFileName(tifFile.getOriginalFilename()); + updReqSyncCheckState.setSyncCheckState("DONE"); + mapSheetMngCoreService.updateMapSheetMngHstSyncCheckState(updReqSyncCheckState); + // 파일정보 업데이트 + mapSheetMngCoreService.deleteByHstUidMngFile(hstUid); + + MapSheetMngDto.MngFileAddReq addReq = new MapSheetMngDto.MngFileAddReq(); + addReq.setMngYyyy(errDto.getMngYyyy()); + addReq.setMapSheetNum(errDto.getMapSheetNum()); + addReq.setRefMapSheetNum(errDto.getRefMapSheetNum()); + addReq.setFilePath(uploadPath); + addReq.setFileName(tfwFile.getOriginalFilename()); + addReq.setFileExt("tfw"); + addReq.setFileSize(tfwFile.getSize()); + addReq.setHstUid(errDto.getHstUid()); + addReq.setFileState("DONE"); + + mapSheetMngCoreService.mngFileSave(addReq); + + addReq.setFileExt("tif"); + addReq.setFileSize(tifFile.getSize()); + mapSheetMngCoreService.mngFileSave(addReq); + + return new DmlReturn("success", "파일 업로드 완료되었습니다."); + } + + public List findHstUidToMapSheetFileList(Long hstUid) { + return mapSheetMngCoreService.findHstUidToMapSheetFileList(hstUid); + } + + @Transactional + public DmlReturn deleteByFileUidMngFile(List fileUids) { + + long hstUid = 0; + // hstUid = 149049; + + for (Long uid : fileUids) { + MapSheetMngDto.MngFilesDto dto = mapSheetMngCoreService.findIdToMapSheetFile(uid); + hstUid = dto.getHstUid(); + + String filePath = dto.getFilePath() + "/" + dto.getFileName(); + Path path = Paths.get(filePath); + try { + boolean isDeleted = Files.deleteIfExists(path); + if (isDeleted) { + System.out.println("파일 삭제 성공: " + filePath); + } else { + System.out.println("삭제 실패: 파일이 존재하지 않습니다."); + } + } catch (IOException e) { + System.err.println("파일 삭제 중 오류 발생: " + e.getMessage()); + } + DmlReturn dmlReturn = mapSheetMngCoreService.deleteByFileUidMngFile(uid); + } + + // 중복제거 확인후 처리상태(DONE)변경 + if (hstUid > 0) { + mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); + } + + return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다."); + } +} From 3cf45319d3ff8eb09668eb3ecf94a0663819902d Mon Sep 17 00:00:00 2001 From: "teddy.kim" Date: Wed, 24 Dec 2025 11:43:46 +0900 Subject: [PATCH 15/28] =?UTF-8?q?=EC=B6=A9=EB=8F=8C=EB=82=98=EC=84=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapsheet/service/MapSheetMngService.java | 270 ------------------ 1 file changed, 270 deletions(-) delete mode 100644 src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java 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 deleted file mode 100644 index fc7fdac1..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java +++ /dev/null @@ -1,270 +0,0 @@ -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.MapSheetMngDto; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.AddReq; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.DmlReturn; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorDataDto; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorSearchReq; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngDto; -import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngFilesDto; -import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService; -import jakarta.validation.Valid; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class MapSheetMngService { - - private final MapSheetMngCoreService mapSheetMngCoreService; - private final FileConfig fileConfig; - - public List findMapSheetMngList() { - return mapSheetMngCoreService.findMapSheetMngList(); - } - - public List findMapSheetMngYyyyList() { - return mapSheetMngCoreService.findMapSheetMngYyyyList(); - } - - public MngDto findMapSheetMng(int mngYyyy) { - return mapSheetMngCoreService.findMapSheetMng(mngYyyy); - } - - @Transactional - public DmlReturn mngComplete(int mngYyyy) { - - mapSheetMngCoreService.MapSheetMngComplete(mngYyyy); - - return new DmlReturn("success", "작업완료 처리되었습니다."); - } - - public Page findMapSheetErrorList(@Valid ErrorSearchReq searchReq) { - return mapSheetMngCoreService.findMapSheetErrorList(searchReq); - } - - public ErrorDataDto findMapSheetError(Long hstUid) { - return mapSheetMngCoreService.findMapSheetError(hstUid); - } - - @Transactional - public DmlReturn mngDataSave(AddReq AddReq) { - return mapSheetMngCoreService.mngDataSave(AddReq); - } - - public DmlReturn uploadProcess(@Valid List hstUidList) { - return mapSheetMngCoreService.uploadProcess(hstUidList); - } - - public DmlReturn updateExceptUseInference(@Valid List hstUidList) { - return mapSheetMngCoreService.updateExceptUseInference(hstUidList); - } - - @Transactional - public DmlReturn uploadPair( - MultipartFile tfwFile, MultipartFile tifFile, Long hstUid, Boolean overwrite) { - - String rootPath = fileConfig.getRootSyncDir(); - String tmpPath = fileConfig.getTmpSyncDir(); - - ErrorDataDto errDto = mapSheetMngCoreService.findMapSheetError(hstUid); - - if (errDto == null) { - return new DmlReturn("fail", "NO hstUid Data"); - } - - // 파일검증용 임시저장 폴더 확인 - if (!FIleChecker.mkDir(tmpPath)) { - return new DmlReturn("fail", "CREATE TEMP FOLDER ERROR"); - } - - // 파일 유효성 검증 - if (tfwFile == null || tfwFile.isEmpty() || tfwFile.getSize() == 0) { - return new DmlReturn("fail", "TFW SIZE 오류"); - } else if (tifFile == null || tifFile.isEmpty() || tifFile.getSize() == 0) { - return new DmlReturn("fail", "TIF SIZE 오류"); - } - - // 확장자명 체크 - 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"); - } - - MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy()); - String targetYearDir = mngDto.getMngPath(); - - // 중복체크 - List basicTfwList = - FIleChecker.getFilesFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw"); - - List basicTifList = - FIleChecker.getFilesFromAllDepth(targetYearDir, tifFile.getOriginalFilename(), "tif"); - - int tfwCnt = - (int) - basicTfwList.stream() - .filter(dto -> dto.getExtension().toString().equals("tfw")) - .count(); - - int tifCnt = - (int) - basicTifList.stream() - .filter(dto -> dto.getExtension().toString().equals("tif")) - .count(); - - if (!overwrite) { - 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); - } - } - - File directory = new File(tmpPath); - 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.cmmndGdalInfo(tifTmpPath)) { - return new DmlReturn("fail", "TIF TYPE ERROR"); - } - if (!FIleChecker.checkTfw(tfwTmpPath)) { - return new DmlReturn("fail", "TFW TYPE ERROR"); - } - - // 싱크파일목록으로 업로드 경로 확인 - List mngFiles = mapSheetMngCoreService.findIdToMapSheetFileList(hstUid); - String uploadPath = ""; - for (MngFilesDto dto : mngFiles) { - uploadPath = dto.getFilePath(); - break; - } - - Path tfwTargetPath = null; - Path tifTargetPath = null; - - // 파일이 존재하지 않을 경우(0개) 해당년도 다른 파일경로로 참조 - if (uploadPath.isEmpty()) { - MngFilesDto filesDto = - mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy()); - String referPath = filesDto.getFilePath(); - uploadPath = Paths.get(referPath).getParent().toString() + "/" + errDto.getRefMapSheetNum(); - } - - // 업로드 경로 확인(없으면 생성) - if (!FIleChecker.mkDir(uploadPath)) { - return new DmlReturn("fail", "CREATE FOLDER ERROR"); - } - - tfwTargetPath = Paths.get(uploadPath).resolve(tfwFile.getOriginalFilename()); - tifTargetPath = Paths.get(uploadPath).resolve(tifFile.getOriginalFilename()); - - try { - Files.move(tfwTmpSavePath, tfwTargetPath, StandardCopyOption.REPLACE_EXISTING); - Files.move(tifTmpSavePath, tifTargetPath, StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - throw new RuntimeException(e); - } - - // hst업데이트 - MapSheetMngDto.SyncCheckStateReqUpdateDto updReqSyncCheckState = - new MapSheetMngDto.SyncCheckStateReqUpdateDto(); - updReqSyncCheckState.setHstUid(hstUid); - updReqSyncCheckState.setFilePath(uploadPath); - updReqSyncCheckState.setSyncCheckTfwFileName(tfwFile.getOriginalFilename()); - updReqSyncCheckState.setSyncCheckTifFileName(tifFile.getOriginalFilename()); - updReqSyncCheckState.setSyncCheckState("DONE"); - mapSheetMngCoreService.updateMapSheetMngHstSyncCheckState(updReqSyncCheckState); - // 파일정보 업데이트 - mapSheetMngCoreService.deleteByHstUidMngFile(hstUid); - - MapSheetMngDto.MngFileAddReq addReq = new MapSheetMngDto.MngFileAddReq(); - addReq.setMngYyyy(errDto.getMngYyyy()); - addReq.setMapSheetNum(errDto.getMapSheetNum()); - addReq.setRefMapSheetNum(errDto.getRefMapSheetNum()); - addReq.setFilePath(uploadPath); - addReq.setFileName(tfwFile.getOriginalFilename()); - addReq.setFileExt("tfw"); - addReq.setFileSize(tfwFile.getSize()); - addReq.setHstUid(errDto.getHstUid()); - addReq.setFileState("DONE"); - - mapSheetMngCoreService.mngFileSave(addReq); - - addReq.setFileExt("tif"); - addReq.setFileSize(tifFile.getSize()); - mapSheetMngCoreService.mngFileSave(addReq); - - return new DmlReturn("success", "파일 업로드 완료되었습니다."); - } - - public List findHstUidToMapSheetFileList(Long hstUid) { - return mapSheetMngCoreService.findHstUidToMapSheetFileList(hstUid); - } - - @Transactional - public DmlReturn deleteByFileUidMngFile(List fileUids) { - - long hstUid = 0; - // hstUid = 149049; - - for (Long uid : fileUids) { - MapSheetMngDto.MngFilesDto dto = mapSheetMngCoreService.findIdToMapSheetFile(uid); - hstUid = dto.getHstUid(); - - String filePath = dto.getFilePath() + "/" + dto.getFileName(); - Path path = Paths.get(filePath); - try { - boolean isDeleted = Files.deleteIfExists(path); - if (isDeleted) { - System.out.println("파일 삭제 성공: " + filePath); - } else { - System.out.println("삭제 실패: 파일이 존재하지 않습니다."); - } - } catch (IOException e) { - System.err.println("파일 삭제 중 오류 발생: " + e.getMessage()); - } - DmlReturn dmlReturn = mapSheetMngCoreService.deleteByFileUidMngFile(uid); - } - - // 중복제거 확인후 처리상태(DONE)변경 - if (hstUid > 0) { - mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); - } - - return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다."); - } -} From 079774531d4864c9f2ca81f3b59829a5b51b493c Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 24 Dec 2025 11:04:50 +0900 Subject: [PATCH 16/28] =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EB=B0=8F=20spotless=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/MenuAuthorizationManager.java | 101 +++++++ .../auth/RedisAuthorizationManager.java | 188 ------------- .../cd/kamcoback/config/SecurityConfig.java | 2 - .../mapsheet/MapSheetMngApiController.java | 34 ++- .../mapsheet/service/MapSheetMngService.java | 259 ++++++++++++++++++ .../cd/kamcoback/menu/MenuApiController.java | 43 --- .../kamcoback/menu/MyMenuApiController.java | 47 ++++ .../cd/kamcoback/menu/dto/MyMenuDto.java | 29 ++ .../kamcoback/menu/service/MenuService.java | 60 ---- .../kamcoback/menu/service/MyMenuService.java | 26 ++ .../postgres/core/MenuCoreService.java | 46 +++- .../repository/menu/MenuRepositoryCustom.java | 6 +- .../repository/menu/MenuRepositoryImpl.java | 67 ++--- src/main/resources/application-local.yml | 4 +- 14 files changed, 562 insertions(+), 350 deletions(-) create mode 100644 src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java delete mode 100644 src/main/java/com/kamco/cd/kamcoback/auth/RedisAuthorizationManager.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/menu/MyMenuApiController.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/menu/dto/MyMenuDto.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/menu/service/MyMenuService.java diff --git a/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java b/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java new file mode 100644 index 00000000..0cc3db39 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java @@ -0,0 +1,101 @@ +package com.kamco.cd.kamcoback.auth; + +import com.kamco.cd.kamcoback.postgres.entity.MenuEntity; +import com.kamco.cd.kamcoback.postgres.repository.menu.MenuRepository; +import jakarta.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.function.Supplier; +import lombok.RequiredArgsConstructor; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.web.access.intercept.RequestAuthorizationContext; +import org.springframework.stereotype.Component; + +/** + * DB 기반 메뉴 권한 AuthorizationManager + * + *

- Redis 사용 안 함 - ADMIN 예외 없음 (DB 매핑 기준) - 한 계정 = role 1개 - menu_url(prefix) 기반 API 접근 제어 + */ +@Component +@RequiredArgsConstructor +public class MenuAuthorizationManager implements AuthorizationManager { + + private static final Logger log = LogManager.getLogger(MenuAuthorizationManager.class); + + private final MenuRepository menuAuthQueryRepository; + + @Override + public AuthorizationDecision check( + Supplier authenticationSupplier, RequestAuthorizationContext context) { + + HttpServletRequest request = context.getRequest(); + String requestPath = normalizePath(request.getRequestURI()); + + Authentication authentication = authenticationSupplier.get(); + if (authentication == null || !authentication.isAuthenticated()) { + return new AuthorizationDecision(false); + } + + String role = extractSingleRole(authentication); + if (role == null) { + return new AuthorizationDecision(false); + } + + // DB에서 role에 허용된 메뉴 조회 + List allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role); + + if (allowedMenus == null || allowedMenus.isEmpty()) { + return new AuthorizationDecision(false); + } + + // menu_url(prefix) 기반 접근 허용 판단 + for (MenuEntity menu : allowedMenus) { + String baseUri = menu.getMenuUrl(); + if (baseUri == null || baseUri.isBlank()) { + continue; + } + if (matchUri(baseUri, requestPath)) { + return new AuthorizationDecision(true); + } + } + + return new AuthorizationDecision(false); + } + + /* ========================= + * role 추출 + * ========================= */ + private String extractSingleRole(Authentication authentication) { + GrantedAuthority ga = authentication.getAuthorities().stream().findFirst().orElse(null); + + if (ga == null || ga.getAuthority() == null || ga.getAuthority().isBlank()) { + return null; + } + + String auth = ga.getAuthority(); + return auth.startsWith("ROLE_") ? auth.substring(5) : auth; + } + + /* ========================= + * URI prefix 매칭 + * ========================= */ + private boolean matchUri(String baseUri, String requestPath) { + String base = normalizePath(baseUri); + String req = normalizePath(requestPath); + return req.equals(base) || req.startsWith(base + "/"); + } + + /* ========================= + * URI 정규화 + * ========================= */ + private String normalizePath(String path) { + if (path == null || path.isBlank()) { + return "/"; + } + return path.replaceAll("//+", "/"); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/auth/RedisAuthorizationManager.java b/src/main/java/com/kamco/cd/kamcoback/auth/RedisAuthorizationManager.java deleted file mode 100644 index 9fcb3b16..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/auth/RedisAuthorizationManager.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.kamco.cd.kamcoback.auth; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.kamco.cd.kamcoback.common.enums.RoleType; -import com.kamco.cd.kamcoback.menu.dto.MenuDto; -import jakarta.servlet.http.HttpServletRequest; -import java.util.Collections; -import java.util.List; -import java.util.function.Supplier; -import lombok.RequiredArgsConstructor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.security.authorization.AuthorizationDecision; -import org.springframework.security.authorization.AuthorizationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.web.access.intercept.RequestAuthorizationContext; -import org.springframework.stereotype.Component; - -/** redis에 등록된 메뉴별 권한 확인 */ -@Component -@RequiredArgsConstructor -public class RedisAuthorizationManager - implements AuthorizationManager { - - private static final Logger log = LogManager.getLogger(RedisAuthorizationManager.class); - private static final String REDIS_KEY = "auth:api:role"; - - private final StringRedisTemplate redisTemplate; - private final ObjectMapper objectMapper; - - @Override - public AuthorizationDecision check( - Supplier authenticationSupplier, RequestAuthorizationContext context) { - - HttpServletRequest request = context.getRequest(); - String requestPath = normalizePath(request.getRequestURI()); - - Authentication authentication = authenticationSupplier.get(); - if (authentication == null || !authentication.isAuthenticated()) { - return new AuthorizationDecision(false); - } - - // ADMIN 은 무조건 허용 - if (hasAdmin(authentication)) { - return new AuthorizationDecision(true); - } - - // 사용자 role 목록 - List userRoles = extractRoles(authentication); - if (userRoles.isEmpty()) { - return new AuthorizationDecision(false); - } - - // Redis 조회 (1회) - String json = redisTemplate.opsForValue().get(REDIS_KEY); - if (json == null || json.isBlank()) { - return new AuthorizationDecision(false); - } - - // JSON 파싱 (1회) - List menus = parseMenus(json); - if (menus.isEmpty()) { - return new AuthorizationDecision(false); - } - - // role + prefix URI 매칭 - for (String role : userRoles) { - if (isAllowed(menus, role, requestPath)) { - return new AuthorizationDecision(true); - } - } - - return new AuthorizationDecision(false); - } - - /* ========================= - * 핵심 권한 판별 로직 - * ========================= */ - private boolean isAllowed(List menus, String role, String requestPath) { - - for (MenuDto.MenuWithRolesDto menu : menus) { - if (menu == null) { - continue; - } - - String baseUri = menu.getMenuApiUri(); - if (baseUri == null || baseUri.isBlank()) { - continue; - } - - // role 포함 여부 - if (!hasRole(menu.getRoles(), role)) { - continue; - } - - // prefix URI 허용 - if (matchUri(baseUri, requestPath)) { - return true; - } - } - return false; - } - - /* ========================= - * URI prefix 매칭 - * ========================= */ - private boolean matchUri(String baseUri, String requestPath) { - String base = normalizePath(baseUri); - String req = normalizePath(requestPath); - - // /api/log/audit → /api/log/audit/** - return req.equals(base) || req.startsWith(base + "/"); - } - - /* ========================= - * role 문자열 처리 - * ========================= */ - private boolean hasRole(String rolesCsv, String targetRole) { - if (rolesCsv == null || rolesCsv.isBlank()) { - return false; - } - if (targetRole == null || targetRole.isBlank()) { - return false; - } - - for (String r : rolesCsv.split(",")) { - if (targetRole.equalsIgnoreCase(r.trim())) { - return true; - } - } - return false; - } - - /* ========================= - * Redis JSON 파싱 - * ========================= */ - private List parseMenus(String json) { - try { - return objectMapper.readValue(json, new TypeReference>() {}); - } catch (Exception e) { - log.warn("Failed to parse redis menu json. key={}", REDIS_KEY, e); - return Collections.emptyList(); - } - } - - /* ========================= - * ADMIN 판별 - * ========================= */ - private boolean hasAdmin(Authentication authentication) { - for (GrantedAuthority ga : authentication.getAuthorities()) { - if (ga == null || ga.getAuthority() == null) { - continue; - } - - String auth = ga.getAuthority(); - String admin = RoleType.ADMIN.getId(); - - if (auth.equals(admin) || auth.equals("ROLE_" + admin)) { - return true; - } - } - return false; - } - - /* ========================= - * ROLE 목록 추출 - * ========================= */ - private List extractRoles(Authentication authentication) { - return authentication.getAuthorities().stream() - .map(GrantedAuthority::getAuthority) - .filter(a -> a != null && !a.isBlank()) - .map(a -> a.startsWith("ROLE_") ? a.substring(5) : a) - .toList(); - } - - /* ========================= - * URI 정규화 - * ========================= */ - private String normalizePath(String path) { - if (path == null || path.isBlank()) { - return "/"; - } - return path.replaceAll("//+", "/"); - } -} diff --git a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java index a2be68ad..fe1ab0cf 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java @@ -2,7 +2,6 @@ package com.kamco.cd.kamcoback.config; import com.kamco.cd.kamcoback.auth.CustomAuthenticationProvider; import com.kamco.cd.kamcoback.auth.JwtAuthenticationFilter; -import com.kamco.cd.kamcoback.auth.RedisAuthorizationManager; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; @@ -29,7 +28,6 @@ public class SecurityConfig { private final JwtAuthenticationFilter jwtAuthenticationFilter; private final CustomAuthenticationProvider customAuthenticationProvider; - private final RedisAuthorizationManager redisAuthorizationManager; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 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 c3779d20..32c8520f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiController.java @@ -16,14 +16,7 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @Tag(name = "영상 관리", description = "영상 관리 API") @@ -112,6 +105,25 @@ public class MapSheetMngApiController { return ApiResponseDto.ok(mapSheetMngService.mngComplete(mngYyyy)); } + @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("/mng-year-list") + public ApiResponseDto> findMapSheetMngYyyyList() { + + return ApiResponseDto.ok(mapSheetMngService.findMapSheetMngYyyyList()); + } + @Operation(summary = "영상 데이터 관리 오류 목록", description = "영상 데이터 관리 오류 목록") @ApiResponses( value = { @@ -163,8 +175,10 @@ public class MapSheetMngApiController { public ApiResponseDto uploadPair( @RequestPart("tfw") MultipartFile tfwFile, @RequestPart("tif") MultipartFile tifFile, - @RequestParam(value = "hstUid", required = false) Long hstUid) { - return ApiResponseDto.createOK(mapSheetMngService.uploadPair(tfwFile, tifFile, hstUid)); + @RequestParam(value = "hstUid", required = false) Long hstUid, + @RequestParam(value = "overwrite", required = false) boolean overwrite) { + return ApiResponseDto.createOK( + mapSheetMngService.uploadPair(tfwFile, tifFile, hstUid, overwrite)); } @Operation(summary = "영상관리 > 파일조회", description = "영상관리 > 파일조회") 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 new file mode 100644 index 00000000..ffa25353 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/service/MapSheetMngService.java @@ -0,0 +1,259 @@ +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.MapSheetMngDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.AddReq; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.DmlReturn; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorDataDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorSearchReq; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.MngFilesDto; +import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService; +import jakarta.validation.Valid; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MapSheetMngService { + + private final MapSheetMngCoreService mapSheetMngCoreService; + private final FileConfig fileConfig; + + public List findMapSheetMngList() { + return mapSheetMngCoreService.findMapSheetMngList(); + } + + public List findMapSheetMngYyyyList() { + return mapSheetMngCoreService.findMapSheetMngYyyyList(); + } + + public MngDto findMapSheetMng(int mngYyyy) { + return mapSheetMngCoreService.findMapSheetMng(mngYyyy); + } + + @Transactional + public DmlReturn mngComplete(int mngYyyy) { + + mapSheetMngCoreService.MapSheetMngComplete(mngYyyy); + + return new DmlReturn("success", "작업완료 처리되었습니다."); + } + + public Page findMapSheetErrorList(@Valid ErrorSearchReq searchReq) { + return mapSheetMngCoreService.findMapSheetErrorList(searchReq); + } + + public ErrorDataDto findMapSheetError(Long hstUid) { + return mapSheetMngCoreService.findMapSheetError(hstUid); + } + + @Transactional + public DmlReturn mngDataSave(AddReq AddReq) { + return mapSheetMngCoreService.mngDataSave(AddReq); + } + + public DmlReturn uploadProcess(@Valid List hstUidList) { + return mapSheetMngCoreService.uploadProcess(hstUidList); + } + + public DmlReturn updateExceptUseInference(@Valid List hstUidList) { + return mapSheetMngCoreService.updateExceptUseInference(hstUidList); + } + + @Transactional + public DmlReturn uploadPair( + MultipartFile tfwFile, MultipartFile tifFile, Long hstUid, Boolean overwrite) { + + String rootPath = fileConfig.getRootSyncDir(); + String tmpPath = fileConfig.getTmpSyncDir(); + + ErrorDataDto errDto = mapSheetMngCoreService.findMapSheetError(hstUid); + + if (errDto == null) { + return new DmlReturn("fail", "NO hstUid Data"); + } + + // 파일검증용 임시저장 폴더 확인 + if (!FIleChecker.mkDir(tmpPath)) { + return new DmlReturn("fail", "CREATE TEMP FOLDER ERROR"); + } + + // 파일 유효성 검증 + if (tfwFile == null || tfwFile.isEmpty() || tfwFile.getSize() == 0) { + return new DmlReturn("fail", "TFW SIZE 오류"); + } else if (tifFile == null || tifFile.isEmpty() || tifFile.getSize() == 0) { + return new DmlReturn("fail", "TIF SIZE 오류"); + } + + // 확장자명 체크 + 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"); + } + + MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy()); + String targetYearDir = mngDto.getMngPath(); + + // 중복체크 + List basicTfwList = + FIleChecker.getFilesFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw"); + + List basicTifList = + FIleChecker.getFilesFromAllDepth(targetYearDir, tifFile.getOriginalFilename(), "tif"); + + int tfwCnt = + (int) + basicTfwList.stream() + .filter(dto -> dto.getExtension().toString().equals("tfw")) + .count(); + + int tifCnt = + (int) + basicTifList.stream() + .filter(dto -> dto.getExtension().toString().equals("tif")) + .count(); + + if (!overwrite) { + 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); + } + } + + File directory = new File(tmpPath); + 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.cmmndGdalInfo(tifTmpPath)) return new DmlReturn("fail", "TIF TYPE ERROR"); + if (!FIleChecker.checkTfw(tfwTmpPath)) return new DmlReturn("fail", "TFW TYPE ERROR"); + + // 싱크파일목록으로 업로드 경로 확인 + List mngFiles = mapSheetMngCoreService.findIdToMapSheetFileList(hstUid); + String uploadPath = ""; + for (MngFilesDto dto : mngFiles) { + uploadPath = dto.getFilePath(); + break; + } + + Path tfwTargetPath = null; + Path tifTargetPath = null; + + // 파일이 존재하지 않을 경우(0개) 해당년도 다른 파일경로로 참조 + if (uploadPath.isEmpty()) { + MngFilesDto filesDto = + mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy()); + String referPath = filesDto.getFilePath(); + uploadPath = Paths.get(referPath).getParent().toString() + "/" + errDto.getRefMapSheetNum(); + } + + // 업로드 경로 확인(없으면 생성) + if (!FIleChecker.mkDir(uploadPath)) { + return new DmlReturn("fail", "CREATE FOLDER ERROR"); + } + + tfwTargetPath = Paths.get(uploadPath).resolve(tfwFile.getOriginalFilename()); + tifTargetPath = Paths.get(uploadPath).resolve(tifFile.getOriginalFilename()); + + try { + Files.move(tfwTmpSavePath, tfwTargetPath, StandardCopyOption.REPLACE_EXISTING); + Files.move(tifTmpSavePath, tifTargetPath, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // hst업데이트 + MapSheetMngDto.SyncCheckStateReqUpdateDto updReqSyncCheckState = + new MapSheetMngDto.SyncCheckStateReqUpdateDto(); + updReqSyncCheckState.setHstUid(hstUid); + updReqSyncCheckState.setFilePath(uploadPath); + updReqSyncCheckState.setSyncCheckTfwFileName(tfwFile.getOriginalFilename()); + updReqSyncCheckState.setSyncCheckTifFileName(tifFile.getOriginalFilename()); + updReqSyncCheckState.setSyncCheckState("DONE"); + mapSheetMngCoreService.updateMapSheetMngHstSyncCheckState(updReqSyncCheckState); + // 파일정보 업데이트 + mapSheetMngCoreService.deleteByHstUidMngFile(hstUid); + + MapSheetMngDto.MngFileAddReq addReq = new MapSheetMngDto.MngFileAddReq(); + addReq.setMngYyyy(errDto.getMngYyyy()); + addReq.setMapSheetNum(errDto.getMapSheetNum()); + addReq.setRefMapSheetNum(errDto.getRefMapSheetNum()); + addReq.setFilePath(uploadPath); + addReq.setFileName(tfwFile.getOriginalFilename()); + addReq.setFileExt("tfw"); + addReq.setFileSize(tfwFile.getSize()); + addReq.setHstUid(errDto.getHstUid()); + addReq.setFileState("DONE"); + + mapSheetMngCoreService.mngFileSave(addReq); + + addReq.setFileExt("tif"); + addReq.setFileSize(tifFile.getSize()); + mapSheetMngCoreService.mngFileSave(addReq); + + return new DmlReturn("success", "파일 업로드 완료되었습니다."); + } + + public List findHstUidToMapSheetFileList(Long hstUid) { + return mapSheetMngCoreService.findHstUidToMapSheetFileList(hstUid); + } + + @Transactional + public DmlReturn deleteByFileUidMngFile(List fileUids) { + + long hstUid = 0; + // hstUid = 149049; + + for (Long uid : fileUids) { + MapSheetMngDto.MngFilesDto dto = mapSheetMngCoreService.findIdToMapSheetFile(uid); + hstUid = dto.getHstUid(); + + String filePath = dto.getFilePath() + "/" + dto.getFileName(); + Path path = Paths.get(filePath); + try { + boolean isDeleted = Files.deleteIfExists(path); + if (isDeleted) { + System.out.println("파일 삭제 성공: " + filePath); + } else { + System.out.println("삭제 실패: 파일이 존재하지 않습니다."); + } + } catch (IOException e) { + System.err.println("파일 삭제 중 오류 발생: " + e.getMessage()); + } + DmlReturn dmlReturn = mapSheetMngCoreService.deleteByFileUidMngFile(uid); + } + + // 중복제거 확인후 처리상태(DONE)변경 + if (hstUid > 0) mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); + + return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다."); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/menu/MenuApiController.java b/src/main/java/com/kamco/cd/kamcoback/menu/MenuApiController.java index 3d8f2710..72435eda 100644 --- a/src/main/java/com/kamco/cd/kamcoback/menu/MenuApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/menu/MenuApiController.java @@ -1,7 +1,6 @@ package com.kamco.cd.kamcoback.menu; import com.fasterxml.jackson.databind.ObjectMapper; -import com.kamco.cd.kamcoback.common.utils.UserUtil; import com.kamco.cd.kamcoback.config.api.ApiLogFunction; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.menu.dto.MenuDto; @@ -11,17 +10,14 @@ 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 java.util.LinkedHashMap; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -@Tag(name = "메뉴 관리", description = "메뉴 관리 API") @RestController @RequiredArgsConstructor @RequestMapping("/api/menu") @@ -68,43 +64,4 @@ public class MenuApiController { return ApiResponseDto.ok(ApiLogFunction.getUriMenuInfo(result, apiUri)); } - - @Operation(summary = "권한별 메뉴 레디스 저장", description = "권한별 메뉴 레디스 저장") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = MenuDto.Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @PostMapping("/auth") - public ApiResponseDto getFindByRoleRedis() { - menuService.getFindByRoleRedis(); - return ApiResponseDto.createOK("ok"); - } - - @Operation(summary = "권한별 메뉴 조회", description = "로그인 권한별 메뉴 목록") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = MenuDto.Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/auth") - public ApiResponseDto> getFindAllByRole() { - UserUtil userUtil = new UserUtil(); - String role = userUtil.getRole(); - return ApiResponseDto.ok(menuService.getFindByRole(role)); - } } diff --git a/src/main/java/com/kamco/cd/kamcoback/menu/MyMenuApiController.java b/src/main/java/com/kamco/cd/kamcoback/menu/MyMenuApiController.java new file mode 100644 index 00000000..ade26a80 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/menu/MyMenuApiController.java @@ -0,0 +1,47 @@ +package com.kamco.cd.kamcoback.menu; + +import com.kamco.cd.kamcoback.common.utils.UserUtil; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.menu.dto.MenuDto; +import com.kamco.cd.kamcoback.menu.dto.MyMenuDto; +import com.kamco.cd.kamcoback.menu.service.MyMenuService; +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 java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "메뉴 조회", description = "메뉴 조회 API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/my/menus") +public class MyMenuApiController { + + private final MyMenuService myMenuService; + + @Operation(summary = "사용자별 메뉴 조회", description = "로그인 사용자별 권한 메뉴 목록") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "조회 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = MenuDto.Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping + public ApiResponseDto> getFindAllByRole() { + UserUtil userUtil = new UserUtil(); + String role = userUtil.getRole(); + return ApiResponseDto.ok(myMenuService.getFindByRole(role)); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/menu/dto/MyMenuDto.java b/src/main/java/com/kamco/cd/kamcoback/menu/dto/MyMenuDto.java new file mode 100644 index 00000000..16ccda3b --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/menu/dto/MyMenuDto.java @@ -0,0 +1,29 @@ +package com.kamco.cd.kamcoback.menu.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class MyMenuDto { + + @Schema(name = "My Menu Basic", description = "사용자별 권한 메뉴 목록") + @Getter + @NoArgsConstructor + public static class Basic { + + private String id; + private String name; + private String menuUrl; + private Long order; + private List children = new ArrayList<>(); + + public Basic(String menuUid, String menuNm, String menuUrl, Long menuOrder) { + this.id = menuUid; + this.name = menuNm; + this.menuUrl = menuUrl; + this.order = menuOrder; + } + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/menu/service/MenuService.java b/src/main/java/com/kamco/cd/kamcoback/menu/service/MenuService.java index bee0a81f..bf2db12f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/menu/service/MenuService.java +++ b/src/main/java/com/kamco/cd/kamcoback/menu/service/MenuService.java @@ -1,13 +1,9 @@ package com.kamco.cd.kamcoback.menu.service; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; -import com.kamco.cd.kamcoback.common.enums.RoleType; import com.kamco.cd.kamcoback.common.utils.UserUtil; import com.kamco.cd.kamcoback.menu.dto.MenuDto; import com.kamco.cd.kamcoback.postgres.core.MenuCoreService; -import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; @@ -27,60 +23,4 @@ public class MenuService { public List getFindAll() { return menuCoreService.getFindAll(); } - - /** - * 권한별 메뉴 목록 redis 등록 - * - * @return - */ - public void getFindByRoleRedis() { - - for (RoleType role : RoleType.values()) { - List menus = menuCoreService.getFindByRole(role.name()); - - try { - String key = "menu:role:" + role.name(); - String value = objectMapper.writeValueAsString(menus); - redisTemplate.opsForValue().set(key, value); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - List menusWithRoles = menuCoreService.getMenuWithRoles(); - - try { - String key = "auth:api:role"; - String value = objectMapper.writeValueAsString(menusWithRoles); - redisTemplate.opsForValue().set(key, value); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - /** - * 권한별 메뉴 목록 조회 - * - * @param role - * @return - */ - public List getFindByRole(String role) { - String key = "menu:role:" + role; - String json = redisTemplate.opsForValue().get(key); - if (json == null) { - return new ArrayList<>(); - } - - JavaType type = - objectMapper.getTypeFactory().constructCollectionType(List.class, MenuDto.Basic.class); - - List cached; - - try { - cached = objectMapper.readValue(json, type); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - return cached; - } } diff --git a/src/main/java/com/kamco/cd/kamcoback/menu/service/MyMenuService.java b/src/main/java/com/kamco/cd/kamcoback/menu/service/MyMenuService.java new file mode 100644 index 00000000..9adad491 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/menu/service/MyMenuService.java @@ -0,0 +1,26 @@ +package com.kamco.cd.kamcoback.menu.service; + +import com.kamco.cd.kamcoback.menu.dto.MyMenuDto; +import com.kamco.cd.kamcoback.postgres.core.MenuCoreService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MyMenuService { + + private final MenuCoreService menuCoreService; + + /** + * 권한별 메뉴 목록 조회 + * + * @param role + * @return + */ + public List getFindByRole(String role) { + return menuCoreService.getFindByRole(role); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MenuCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MenuCoreService.java index d01054e0..3e9041fe 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MenuCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MenuCoreService.java @@ -1,8 +1,10 @@ package com.kamco.cd.kamcoback.postgres.core; import com.kamco.cd.kamcoback.menu.dto.MenuDto; +import com.kamco.cd.kamcoback.menu.dto.MyMenuDto; import com.kamco.cd.kamcoback.postgres.entity.MenuEntity; import com.kamco.cd.kamcoback.postgres.repository.menu.MenuRepository; +import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -23,16 +25,50 @@ public class MenuCoreService { * @param role * @return */ - public List getFindByRole(String role) { - return menuRepository.getFindByRole(role).stream().map(MenuEntity::toDto).toList(); + public List getFindByRole(String role) { + List entities = menuRepository.getFindByRole(role); + + return entities.stream() + .map( + parent -> { + MyMenuDto.Basic p = + new MyMenuDto.Basic( + parent.getMenuUid(), + parent.getMenuNm(), + parent.getMenuUrl(), + parent.getMenuOrder()); + + parent.getChildren().stream() + .filter( + c -> + Boolean.TRUE.equals(c.getIsUse()) && Boolean.FALSE.equals(c.getDeleted())) + .sorted( + Comparator.comparing( + MenuEntity::getMenuOrder, Comparator.nullsLast(Long::compareTo))) + .map( + c -> + new MyMenuDto.Basic( + c.getMenuUid(), c.getMenuNm(), c.getMenuUrl(), c.getMenuOrder())) + .forEach(childDto -> p.getChildren().add(childDto)); + + return p; + }) + .sorted( + Comparator.comparing(MyMenuDto.Basic::getOrder, Comparator.nullsLast(Long::compareTo))) + .toList(); } /** - * 메뉴별 권한 조회 + * 사용자 role 기준으로 접근 가능한 메뉴 URL 목록 조회 * + * @param role * @return */ - public List getMenuWithRoles() { - return menuRepository.getFindByMenuWithRoles(); + public List findAllowedMenuUrlsByRole(String role) { + return menuRepository.findAllowedMenuUrlsByRole(role).stream() + .map(MenuEntity::getMenuUrl) + .filter(url -> url != null && !url.isBlank()) + .distinct() + .toList(); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java index d0f8a9b7..775ff647 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java @@ -1,6 +1,5 @@ package com.kamco.cd.kamcoback.postgres.repository.menu; -import com.kamco.cd.kamcoback.menu.dto.MenuDto.MenuWithRolesDto; import com.kamco.cd.kamcoback.postgres.entity.MenuEntity; import java.util.List; @@ -17,9 +16,10 @@ public interface MenuRepositoryCustom { List getFindByRole(String role); /** - * 메뉴별 권한 조회 + * 사용자 role 기준으로 접근 가능한 메뉴 URL 목록 조회 * + * @param role * @return */ - List getFindByMenuWithRoles(); + List findAllowedMenuUrlsByRole(String role); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java index a995e7d7..62a91213 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java @@ -3,13 +3,8 @@ package com.kamco.cd.kamcoback.postgres.repository.menu; import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMenuMappEntity.menuMappEntity; -import com.kamco.cd.kamcoback.menu.dto.MenuDto.MenuWithRolesDto; import com.kamco.cd.kamcoback.postgres.entity.MenuEntity; import com.kamco.cd.kamcoback.postgres.entity.QMenuEntity; -import com.kamco.cd.kamcoback.postgres.entity.QMenuMappEntity; -import com.querydsl.core.types.Expression; -import com.querydsl.core.types.Projections; -import com.querydsl.core.types.dsl.Expressions; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; import lombok.RequiredArgsConstructor; @@ -34,12 +29,14 @@ public class MenuRepositoryImpl implements MenuRepositoryCustom { @Override public List getFindByRole(String role) { + QMenuEntity parent = QMenuEntity.menuEntity; QMenuEntity child = new QMenuEntity("child"); + List content = queryFactory - .selectDistinct(menuEntity) - .from(menuEntity) - .leftJoin(menuEntity.children, child) + .selectDistinct(parent) + .from(parent) + .leftJoin(parent.children, child) .fetchJoin() .leftJoin(menuMappEntity) .on( @@ -47,43 +44,39 @@ public class MenuRepositoryImpl implements MenuRepositoryCustom { .roleCode .eq(role) .and(menuMappEntity.deleted.isFalse()) - .and( - menuMappEntity.menuUid.eq(menuEntity).or(menuMappEntity.menuUid.eq(child)))) + .and(menuMappEntity.menuUid.eq(child))) .where( - menuEntity.parent.isNull(), - menuEntity.deleted.isFalse(), - menuEntity.isUse.isTrue(), + parent.parent.isNull(), + parent.deleted.isFalse(), + parent.isUse.isTrue(), menuMappEntity.id.isNotNull()) - .orderBy(menuEntity.menuOrder.asc().nullsLast(), child.menuOrder.asc().nullsLast()) + .orderBy(parent.menuOrder.asc().nullsLast(), child.menuOrder.asc().nullsLast()) .fetch(); return content; } + /** + * 사용자 role 기준으로 접근 가능한 메뉴 URL 목록 조회 + * + * @param role + * @return + */ @Override - public List getFindByMenuWithRoles() { - QMenuEntity tm = menuEntity; - QMenuMappEntity tmm = menuMappEntity; + public List findAllowedMenuUrlsByRole(String role) { - Expression roleAgg = - Expressions.stringTemplate("string_agg({0}, {1})", tmm.roleCode, Expressions.constant(",")); - - List content = - queryFactory - .select( - Projections.constructor( - MenuWithRolesDto.class, - tm.menuUid, - tm.menuNm, - tm.menuUrl, - tm.menuApiUri, - roleAgg)) - .from(tm) - .leftJoin(tmm) - .on(tmm.menuUid.eq(tm).and(tmm.deleted.isFalse())) - .where(tm.deleted.isFalse()) - .groupBy(tm.menuUid, tm.menuNm, tm.menuUrl, tm.menuApiUri) - .fetch(); - return content; + return queryFactory + .selectDistinct(menuEntity) + .from(menuMappEntity) + .join(menuMappEntity.menuUid, menuEntity) + .where( + menuMappEntity.roleCode.eq(role), + menuMappEntity.deleted.isFalse(), + menuEntity.deleted.isFalse(), + menuEntity.isUse.isTrue(), + menuEntity.menuUrl.isNotNull(), + menuEntity.menuUrl.isNotEmpty()) + .orderBy(menuEntity.menuOrder.asc().nullsLast()) + .fetch(); } } diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 054d08ac..0889d7ff 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -25,9 +25,9 @@ spring: data: redis: - host: localhost + host: 192.168.2.109 port: 6379 - password: 1234 + password: kamco servlet: multipart: From 5d297ba4568a67bfdb658f737a00bb6adf973ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Wed, 24 Dec 2025 12:37:32 +0900 Subject: [PATCH 17/28] feat: myinfo --- .../cd/kamcoback/config/SecurityConfig.java | 4 + .../cd/kamcoback/members/dto/MembersDto.java | 81 +++++++++++++++++++ .../postgres/core/MembersCoreService.java | 15 ++++ .../postgres/entity/MemberEntity.java | 19 +++++ .../cd/kamcoback/user/UserApiController.java | 53 ++++++++++++ .../user/service/UserInfoService.java | 26 ++++++ 6 files changed, 198 insertions(+) create mode 100644 src/main/java/com/kamco/cd/kamcoback/user/UserApiController.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/user/service/UserInfoService.java diff --git a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java index fe1ab0cf..bf45341b 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java @@ -77,8 +77,12 @@ public class SecurityConfig { "/api/members/*/password", "/v3/api-docs/**") .permitAll() + // 로그인한 사용자만 가능 + .requestMatchers("/api/user/**") + .authenticated() .anyRequest() // .access(redisAuthorizationManager) + .authenticated()) .addFilterBefore( jwtAuthenticationFilter, diff --git a/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java b/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java index b03b08cd..8af2bb91 100644 --- a/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java @@ -1,5 +1,6 @@ package com.kamco.cd.kamcoback.members.dto; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.kamco.cd.kamcoback.common.enums.RoleType; import com.kamco.cd.kamcoback.common.enums.StatusType; import com.kamco.cd.kamcoback.common.utils.enums.Enums; @@ -181,4 +182,84 @@ public class MembersDto { private String employeeNo; private String role; } + + @Getter + public static class RoleEntity { + + private final RoleType type; + private final String name; + + public RoleEntity(RoleType status) { + this.type = status; + this.name = status.getText(); + } + } + + @Getter + public static class StatusEntity { + + private final StatusType type; + private final String name; + + public StatusEntity(StatusType status) { + this.type = status; + this.name = status.getText(); + } + } + + @Getter + public static class EntityData { + + @JsonIgnore private Long id; + private UUID uuid; + private String name; + private String employeeNo; + private RoleEntity role; + private StatusEntity status; + @JsonFormatDttm private ZonedDateTime createdDttm; + @JsonFormatDttm private ZonedDateTime firstLoginDttm; + @JsonFormatDttm private ZonedDateTime lastLoginDttm; + @JsonFormatDttm private ZonedDateTime statusChgDttm; + + private Boolean isReset; + + public EntityData( + Long id, + UUID uuid, + RoleType role, + String name, + String employeeNo, + StatusType status, + ZonedDateTime createdDttm, + ZonedDateTime firstLoginDttm, + ZonedDateTime lastLoginDttm, + ZonedDateTime statusChgDttm, + Boolean isReset) { + this.id = id; + this.uuid = uuid; + this.name = name; + this.employeeNo = employeeNo; + this.status = new StatusEntity(status); + this.createdDttm = createdDttm; + this.firstLoginDttm = firstLoginDttm; + this.lastLoginDttm = lastLoginDttm; + this.statusChgDttm = statusChgDttm; + this.isReset = isReset; + this.role = new RoleEntity(role); + } + + private String getUserRoleName(String roleId) { + RoleType type = Enums.fromId(RoleType.class, roleId); + return type.getText(); + } + + private String getStatusName(String status, Boolean pwdResetYn) { + StatusType type = Enums.fromId(StatusType.class, status); + pwdResetYn = pwdResetYn != null && pwdResetYn; + if (type.equals(StatusType.PENDING) && pwdResetYn) { + type = StatusType.ACTIVE; + } + return type.getText(); + } + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java index cb040aa6..1aa36339 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MembersCoreService.java @@ -23,6 +23,7 @@ import org.mindrot.jbcrypt.BCrypt; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -173,4 +174,18 @@ public class MembersCoreService { public boolean existsByEmployeeNo(String employeeNo) { return membersRepository.existsByEmployeeNo(employeeNo); } + + /** + * 회원정보 조회 (단건 ) by uuid + * + * @param uuid + */ + @Transactional(readOnly = true) + public MembersDto.EntityData getUserInfoByUuid(String memberUuid) { + MemberEntity member = + membersRepository + .findByUUID(UUID.fromString(memberUuid)) + .orElseThrow(MemberNotFoundException::new); + return member.toEntity(); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java index d2088ad9..1d97dd2c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MemberEntity.java @@ -1,6 +1,8 @@ package com.kamco.cd.kamcoback.postgres.entity; +import com.kamco.cd.kamcoback.common.enums.RoleType; import com.kamco.cd.kamcoback.common.enums.StatusType; +import com.kamco.cd.kamcoback.members.dto.MembersDto.EntityData; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -14,8 +16,10 @@ import java.util.Objects; import java.util.UUID; import lombok.Getter; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import org.hibernate.annotations.ColumnDefault; +@Slf4j @Getter @Setter @Entity @@ -100,4 +104,19 @@ public class MemberEntity { this.status = newStatus; this.statusChgDttm = ZonedDateTime.now(); } + + public EntityData toEntity() { + return new EntityData( + id, + uuid, + RoleType.valueOf(userRole), + name, + employeeNo, + StatusType.valueOf(status), + createdDttm, + firstLoginDttm, + lastLoginDttm, + statusChgDttm, + pwdResetYn); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/user/UserApiController.java b/src/main/java/com/kamco/cd/kamcoback/user/UserApiController.java new file mode 100644 index 00000000..c9d30696 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/user/UserApiController.java @@ -0,0 +1,53 @@ +package com.kamco.cd.kamcoback.user; + +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.members.dto.MembersDto; +import com.kamco.cd.kamcoback.user.service.UserInfoService; +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.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "사용자 정보", description = "사용자 정보 조회 API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/user") +public class UserApiController { + + private final UserInfoService userInfoService; + + @Operation( + summary = "현재 로그인 사용자 정보 조회", + description = "JWT 토큰에서 사용자 ID를 추출하여 현재 로그인한 사용자의 정보를 조회합니다.") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "조회 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = MembersDto.EntityData.class))), + @ApiResponse( + responseCode = "401", + description = "인증 실패 (토큰 없음 또는 유효하지 않음)", + content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping("/iam") + public ApiResponseDto iam() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String memberUuid = authentication.getName(); // JWT의 sub 값 (사용자 ID) + + // Member의 정보를 조회해서 리턴한다. + return ApiResponseDto.createOK(userInfoService.getUserInfoByUuid(memberUuid)); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/user/service/UserInfoService.java b/src/main/java/com/kamco/cd/kamcoback/user/service/UserInfoService.java new file mode 100644 index 00000000..2d93153a --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/user/service/UserInfoService.java @@ -0,0 +1,26 @@ +package com.kamco.cd.kamcoback.user.service; + +import com.kamco.cd.kamcoback.members.dto.MembersDto; +import com.kamco.cd.kamcoback.postgres.core.MembersCoreService; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +@Transactional(readOnly = true) +public class UserInfoService { + + private final MembersCoreService membersCoreService; + + /** + * 회원정보 조회 (단건 ) by uuid + * + * @param uuid + * @return + */ + public MembersDto.EntityData getUserInfoByUuid(@NotNull String uuid) { + return membersCoreService.getUserInfoByUuid(uuid); + } +} From 701192ecd2e7ffc7db140df528c9889d70f59e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 29 Dec 2025 14:47:54 +0900 Subject: [PATCH 18/28] feat: polishing --- .../mapsheet/MapSheetMngApiV2Controller.java | 4 +- .../mapsheet/dto/MapSheetMngDto.java | 56 +++++++++++++ .../mapsheet/service/MapSheetMngService.java | 36 +++++++-- .../postgres/core/MapSheetMngCoreService.java | 38 ++++++--- .../postgres/entity/MapSheetMngHstEntity.java | 80 +++++++++++++++++-- .../mapsheet/MapSheetMngRepositoryCustom.java | 4 + .../mapsheet/MapSheetMngRepositoryImpl.java | 53 +++++++----- 7 files changed, 227 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java index ed8a92de..9ddf3888 100644 --- a/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java +++ b/src/main/java/com/kamco/cd/kamcoback/mapsheet/MapSheetMngApiV2Controller.java @@ -40,9 +40,9 @@ public class MapSheetMngApiV2Controller { @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/mng-year-list") - public ApiResponseDto findMapSheetMngYyyyList() { + public ApiResponseDto getListMapListYYYYLimit10() { - List years = mapSheetMngService.findMapSheetMngYyyyList(); + List years = mapSheetMngService.getListMapListYYYYLimit10(); // 현재 년도 가져온다 int currentYear = Year.now().getValue(); 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 300243b3..3e102248 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 @@ -2,12 +2,14 @@ package com.kamco.cd.kamcoback.mapsheet.dto; import com.kamco.cd.kamcoback.common.enums.MngStateType; import com.kamco.cd.kamcoback.common.enums.SyncStateType; +import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.enums.Enums; 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 lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -319,4 +321,58 @@ public class MapSheetMngDto { this.years = years; } } + + @Getter + @AllArgsConstructor + public enum MapSheetState implements EnumType { + // @formatter:off + DONE("완료"), + NOTYET("처리대기"); + // @formatter:on + + private final String message; + + @Override + public String getId() { + return name(); + } + + @Override + public String getText() { + return message; + } + } + + // 연도리스틀 조회시 사용하는 request Dto + @Getter + @Setter + @NoArgsConstructor + public static class YearSearchReq { + + private String status; + + // 페이징 파라미터 + private int page = 0; + private int size = 20; + private String sort; + + @Builder + public YearSearchReq(String status, int page, int size, String sort) { + this.status = status; + this.page = page; + this.size = size; + this.sort = sort; + } + + public Pageable toPageable() { + if (sort != null && !sort.isEmpty()) { + String[] sortParams = sort.split(","); + String property = sortParams[0]; + Sort.Direction direction = + 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 ffa25353..9b58855b 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 @@ -9,7 +9,9 @@ import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorDataDto; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.ErrorSearchReq; 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.YearSearchReq; import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService; +import com.kamco.cd.kamcoback.postgres.entity.YearEntity; import jakarta.validation.Valid; import java.io.File; import java.io.IOException; @@ -17,6 +19,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -40,6 +43,16 @@ public class MapSheetMngService { return mapSheetMngCoreService.findMapSheetMngYyyyList(); } + public List getListMapListYYYYLimit10() { + + YearSearchReq req = YearSearchReq.builder().status("NOTYET").page(0).size(10).build(); + // List조회 + Page years = mapSheetMngCoreService.getListMapListYYYYWithPaging(req); + return years.map(YearEntity::getYyyy).getContent().stream() + .sorted(Comparator.reverseOrder()) + .toList(); + } + public MngDto findMapSheetMng(int mngYyyy) { return mapSheetMngCoreService.findMapSheetMng(mngYyyy); } @@ -130,10 +143,15 @@ public class MapSheetMngService { if (!overwrite) { if (tfwCnt > 0 || tifCnt > 0) { String tfwtifMsg = ""; - if (tfwCnt > 0) tfwtifMsg = tfwFile.getOriginalFilename(); + if (tfwCnt > 0) { + tfwtifMsg = tfwFile.getOriginalFilename(); + } if (tifCnt > 0) { - if (tfwCnt > 0) tfwtifMsg = "," + tifFile.getOriginalFilename(); - else tfwtifMsg = tifFile.getOriginalFilename(); + if (tfwCnt > 0) { + tfwtifMsg = "," + tifFile.getOriginalFilename(); + } else { + tfwtifMsg = tifFile.getOriginalFilename(); + } } return new DmlReturn("duplicate", tfwtifMsg); } @@ -153,8 +171,12 @@ public class MapSheetMngService { 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"); + if (!FIleChecker.cmmndGdalInfo(tifTmpPath)) { + return new DmlReturn("fail", "TIF TYPE ERROR"); + } + if (!FIleChecker.checkTfw(tfwTmpPath)) { + return new DmlReturn("fail", "TFW TYPE ERROR"); + } // 싱크파일목록으로 업로드 경로 확인 List mngFiles = mapSheetMngCoreService.findIdToMapSheetFileList(hstUid); @@ -252,7 +274,9 @@ public class MapSheetMngService { } // 중복제거 확인후 처리상태(DONE)변경 - if (hstUid > 0) mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); + if (hstUid > 0) { + mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid); + } return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다."); } 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 047b5231..e11a7d68 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 @@ -1,8 +1,10 @@ package com.kamco.cd.kamcoback.postgres.core; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; +import com.kamco.cd.kamcoback.postgres.entity.YearEntity; import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepository; import jakarta.persistence.EntityNotFoundException; import jakarta.validation.Valid; @@ -20,6 +22,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -40,6 +43,18 @@ public class MapSheetMngCoreService { return mapSheetMngRepository.findMapSheetMngYyyyList(); } + /** + * 영상등록이 가능한 연도리스트 + * + * @param req + * @return + */ + @Transactional(readOnly = true) + public Page getListMapListYYYYWithPaging(YearSearchReq req) { + + return mapSheetMngRepository.getYears(req); + } + public MapSheetMngDto.MngDto findMapSheetMng(int mngYyyy) { return mapSheetMngRepository.findMapSheetMng(mngYyyy); } @@ -146,18 +161,18 @@ public class MapSheetMngCoreService { }) .sum(); - entity.get().setTifSizeBytes(tifSize); - entity.get().setTfwSizeBytes(tfwSize); - entity.get().setTotalSizeBytes(tifSize + tfwSize); + MapSheetMngHstEntity mapSheetMngHst = entity.get(); + + mapSheetMngHst.updateFileInfos(tifSize, tfwSize); // 엔터티 저장 -> 커스텀 업데이트로 변경 mapSheetMngRepository.updateHstFileSizes( entity.get().getHstUid(), tifSize, tfwSize, tifSize + tfwSize); } catch (IOException e) { // 크기 계산 실패 시 0으로 저장 - entity.get().setTifSizeBytes(0L); - entity.get().setTfwSizeBytes(0L); - entity.get().setTotalSizeBytes(0L); + MapSheetMngHstEntity mapSheetMng = entity.get(); + mapSheetMng.updateFileInfos(0L, 0L); + mapSheetMngRepository.updateHstFileSizes(entity.get().getHstUid(), 0L, 0L, 0L); } @@ -254,13 +269,18 @@ public class MapSheetMngCoreService { List filesDto = mapSheetMngRepository.findHstUidToMapSheetFileList(hstUid); for (MapSheetMngDto.MngFilesDto dto : filesDto) { - if (dto.getFileExt().equals("tif")) reqDto.setSyncCheckTifFileName(dto.getFileName()); - else if (dto.getFileExt().equals("tfw")) reqDto.setSyncCheckTfwFileName(dto.getFileName()); + if (dto.getFileExt().equals("tif")) { + reqDto.setSyncCheckTifFileName(dto.getFileName()); + } else if (dto.getFileExt().equals("tfw")) { + reqDto.setSyncCheckTfwFileName(dto.getFileName()); + } reqDto.setFilePath(dto.getFilePath()); } String fileState = "DONE"; - if (filesDto.size() > 2) fileState = "DONE"; + if (filesDto.size() > 2) { + fileState = "DONE"; + } reqDto.setSyncCheckState(fileState); 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 ad81fbc7..2cf1f359 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 @@ -1,37 +1,92 @@ package com.kamco.cd.kamcoback.postgres.entity; import com.kamco.cd.kamcoback.postgres.CommonDateEntity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import jakarta.validation.constraints.Size; import java.time.ZonedDateTime; +import lombok.AccessLevel; import lombok.Getter; -import lombok.Setter; +import lombok.NoArgsConstructor; +/** + * This class represents the entity for managing the history of map sheets. It is mapped to the + * database table "tb_map_sheet_mng_hst" and contains various properties related to the 1:5k map + * sheet information, as well as metadata for file synchronization and management. + * + *

This entity: - Includes a primary key (hstUid) for unique identification. - Maintains + * information associated with map sheets such as code, name, scale ratio, and paths. - Tracks + * states, timestamps, and data synchronization details. - Maintains relationships with the + * `MapInkx5kEntity` entity through a many-to-one association. - Provides functionality to update + * file information and sizes (`tifSizeBytes`, `tfwSizeBytes`, and `totalSizeBytes`). + * + *

It extends the `CommonDateEntity` class to include common date management fields, such as + * creation and modification timestamps. + * + *

The `@Getter` annotation generates getter methods for all fields, while the access to setters + * is restricted to enforce controlled modifications. The entity uses `@NoArgsConstructor` with + * `AccessLevel.PROTECTED` to restrict direct instantiation. The `updateFileInfos` method allows + * dynamic updates of specific file information. + * + *

Fields include: - hstUid: Unique identifier for the history record. - mngYyyy: Year associated + * with the management record. - mapInkx5kByCode: Reference to the related `MapInkx5kEntity` object. + * - mapSheetNum: Map sheet number identifying specific map. - mapSheetName: Name of the map sheet. + * - mapSheetCodeSrc: Source code of the map sheet. - scaleRatio: Scale ratio of the map. - + * dataState: State/status of the map sheet data. - dataStateDttm: Timestamp of the data state. - + * useInference: Indicator or metadata for inference usage. - useInferenceDttm: Timestamp for + * inference-related use. - mapSheetPath: Path or location of the map sheet file. - refMapSheetNum: + * Reference to a related map sheet number. - createdUid: User ID of the record creator. - + * updatedUid: User ID of the last updater. - syncState and related fields: Fields to manage + * synchronization states and processes. - tifSizeBytes, tfwSizeBytes, totalSizeBytes: Fields to + * track file size details. - sync file name fields: Stores names of files relevant for + * synchronization and verification. + * + *

This entity is essential for tracking and managing map sheet revisions, status, and usage in a + * system leveraging 1:5k map data. + */ @Getter -@Setter +// entity의 접근제어를 위해 @setter를 사용 x +// @Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity +// 영상관리이력 @Table(name = "tb_map_sheet_mng_hst") public class MapSheetMngHstEntity extends CommonDateEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "hst_uid") - private Long hstUid; + private Long hstUid; // id @Column(name = "mng_yyyy") - private Integer mngYyyy; + private Integer mngYyyy; // 년도 - @Column(name = "map_sheet_code") - private Integer mapSheetCode; + // JPA 연관관계: MapInkx5k 참조 (PK 기반) 소속도엽번호 1:5k + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "map_sheet_code", referencedColumnName = "fid") + private MapInkx5kEntity mapInkx5kByCode; + // TODO 1:5k 관련 정보 추후 제거 필요 @Column(name = "map_sheet_num") - private String mapSheetNum; + private String mapSheetNum; // 도엽번호 @Column(name = "map_sheet_name") private String mapSheetName; + // TODO END + + // 도엽파일이 저장된 경로 @Column(name = "map_sheet_code_src") private Integer mapSheetCodeSrc; + // 도엽비율? @Column(name = "scale_ratio") private Integer scaleRatio; @@ -103,4 +158,13 @@ public class MapSheetMngHstEntity extends CommonDateEntity { @Size(max = 100) @Column(name = "sync_check_tfw_file_name", length = 100) private String syncCheckTfwFileName; + + // 파일정보 업데이트 + public void updateFileInfos(Long tifSizeBytes, Long tfwSizeBytes) { + tifSizeBytes = tifSizeBytes == null ? 0L : tifSizeBytes; + tfwSizeBytes = tfwSizeBytes == null ? 0L : tfwSizeBytes; + this.tifSizeBytes = tifSizeBytes; + this.tfwSizeBytes = tfwSizeBytes; + this.totalSizeBytes = tifSizeBytes + tfwSizeBytes; + } } 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 b26508da..4c070e95 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 @@ -1,7 +1,9 @@ package com.kamco.cd.kamcoback.postgres.repository.mapsheet; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; +import com.kamco.cd.kamcoback.postgres.entity.YearEntity; import jakarta.validation.Valid; import java.util.List; import java.util.Optional; @@ -55,4 +57,6 @@ public interface MapSheetMngRepositoryCustom { MapSheetMngDto.MngFilesDto findIdToMapSheetFile(Long fileUid); void updateHstFileSizes(Long hstUid, long tifSizeBytes, long tfwSizeBytes, long totalSizeBytes); + + Page getYears(YearSearchReq yearSearchReq); } 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 add560c9..7e970baa 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 @@ -8,7 +8,10 @@ import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity.mapSh import static com.kamco.cd.kamcoback.postgres.entity.QYearEntity.yearEntity; import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto; +import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity; +import com.kamco.cd.kamcoback.postgres.entity.QYearEntity; +import com.kamco.cd.kamcoback.postgres.entity.YearEntity; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; @@ -295,23 +298,7 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport mapSheetMngHstEntity.syncState.ne("DONE").and(mapSheetMngHstEntity.syncState.ne("NOTYET"))); if (searchReq.getSyncState() != null && !searchReq.getSyncState().isEmpty()) { - /* - if (searchReq.getSyncState().equals("NOTPAIR")) { - whereBuilder.and( - mapSheetMngHstEntity - .syncState - .eq("NOTPAIR") - .or(mapSheetMngHstEntity.syncState.eq("NOFILE"))); - } else if (searchReq.getSyncState().equals("FAULT")) { - whereBuilder.and( - mapSheetMngHstEntity - .syncState - .eq("SIZEERROR") - .or(mapSheetMngHstEntity.syncState.eq("TYPEERROR"))); - } else { - whereBuilder.and(mapSheetMngHstEntity.syncState.eq(searchReq.getSyncState())); - } - */ + whereBuilder.and(mapSheetMngHstEntity.syncState.eq(searchReq.getSyncState())); } @@ -379,8 +366,7 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport queryFactory .select(mapSheetMngHstEntity.hstUid.count()) .from(mapSheetMngHstEntity) - .innerJoin(mapInkx5kEntity) - .on(mapSheetMngHstEntity.mapSheetCode.eq(mapInkx5kEntity.fid)) + .innerJoin(mapSheetMngHstEntity.mapInkx5kByCode, mapInkx5kEntity) .leftJoin(mapInkx50kEntity) .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid.longValue())) .where(whereBuilder) @@ -737,6 +723,35 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport query.executeUpdate(); } + @Override + public Page getYears(YearSearchReq req) { + Pageable pageable = req.toPageable(); + // LISTS + List content = + queryFactory + .selectFrom(yearEntity) + .where(eqYearStatus(yearEntity, req.getStatus())) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(yearEntity.yyyy.asc()) + .fetch(); + // count 쿼리 + Long total = + queryFactory + .select(yearEntity.yyyy.count()) + .from(yearEntity) + .where(eqYearStatus(yearEntity, req.getStatus())) + .fetchOne(); + return new PageImpl<>(content, pageable, total); + } + + private BooleanExpression eqYearStatus(QYearEntity years, String status) { + if (status == null) { + return null; + } + return years.status.eq(status); + } + private NumberExpression rowNum() { return Expressions.numberTemplate( Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate); From 3158f5344e1556caf88d189230b673d90a09801c Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 30 Dec 2025 09:41:23 +0900 Subject: [PATCH 19/28] =?UTF-8?q?shp=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EA=B2=BD=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inference/service/InferenceResultShpService.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java index 326519aa..52d9195c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java @@ -16,7 +16,9 @@ public class InferenceResultShpService { private final InferenceResultShpCoreService coreService; private final ShpWriter shpWriter; - /** inference_results 테이블을 기준으로 분석 결과 테이블과 도형 테이블을 최신 상태로 반영한다. */ + /** + * inference_results 테이블을 기준으로 분석 결과 테이블과 도형 테이블을 최신 상태로 반영한다. + */ @Transactional public InferenceResultShpDto.InferenceCntDto saveInferenceResultData() { return coreService.buildInferenceData(); @@ -34,7 +36,7 @@ public class InferenceResultShpService { public InferenceResultShpDto.FileCntDto createShpFile() { // TODO 파일 경로는 정해지면 수정, properties 사용 - String baseDir = System.getProperty("user.home") + "/detect/result"; + String baseDir = "/app/detect/result"; // TODO 배치 실행으로 변경 필요 int batchSize = 100; @@ -58,9 +60,9 @@ public class InferenceResultShpService { // 파일명 생성 (stage_mapSheet_compare_target) InferenceResultShpDto.Basic first = dtoList.get(0); String baseName = - String.format( - "%d_%d_%d_%d", - first.getStage(), first.getMapId(), first.getInput1(), first.getInput2()); + String.format( + "%d_%d_%d_%d", + first.getStage(), first.getMapId(), first.getInput1(), first.getInput2()); String baseDir2 = "/" + first.getInput1() + "_" + first.getInput2() + "/" + first.getStage(); String shpBasePath = baseDir + baseDir2 + "/shp/" + baseName; From cbbc934f987623ec0e86f6ae5f7ecf187c6b70ce Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 30 Dec 2025 09:46:33 +0900 Subject: [PATCH 20/28] =?UTF-8?q?shp=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EA=B2=BD=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inference/service/InferenceResultShpService.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java index 52d9195c..6a578e32 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java @@ -16,9 +16,7 @@ public class InferenceResultShpService { private final InferenceResultShpCoreService coreService; private final ShpWriter shpWriter; - /** - * inference_results 테이블을 기준으로 분석 결과 테이블과 도형 테이블을 최신 상태로 반영한다. - */ + /** inference_results 테이블을 기준으로 분석 결과 테이블과 도형 테이블을 최신 상태로 반영한다. */ @Transactional public InferenceResultShpDto.InferenceCntDto saveInferenceResultData() { return coreService.buildInferenceData(); @@ -60,9 +58,9 @@ public class InferenceResultShpService { // 파일명 생성 (stage_mapSheet_compare_target) InferenceResultShpDto.Basic first = dtoList.get(0); String baseName = - String.format( - "%d_%d_%d_%d", - first.getStage(), first.getMapId(), first.getInput1(), first.getInput2()); + String.format( + "%d_%d_%d_%d", + first.getStage(), first.getMapId(), first.getInput1(), first.getInput2()); String baseDir2 = "/" + first.getInput1() + "_" + first.getInput2() + "/" + first.getStage(); String shpBasePath = baseDir + baseDir2 + "/shp/" + baseName; From 7e4f3476b3ff4fb551f5a6e67e27ca54e93b3744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Tue, 30 Dec 2025 10:00:32 +0900 Subject: [PATCH 21/28] polishing --- .../kamcoback/common/enums/ApiConfigEnum.java | 22 +++++++++ .../common/enums/CommonUseStatus.java | 40 ++++++++++++++++ .../postgres/core/MapInkxMngCoreService.java | 46 +++++++++++++++++-- .../postgres/entity/MapInkx5kEntity.java | 20 ++++---- .../scene/MapInkx5kRepositoryCustom.java | 3 +- .../scene/MapInkx5kRepositoryImpl.java | 5 +- .../scene/MapInkxMngApiController.java | 8 +++- .../cd/kamcoback/scene/dto/MapInkxMngDto.java | 16 ++++++- .../scene/service/MapInkxMngService.java | 12 +++-- 9 files changed, 151 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/kamco/cd/kamcoback/common/enums/ApiConfigEnum.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/common/enums/CommonUseStatus.java diff --git a/src/main/java/com/kamco/cd/kamcoback/common/enums/ApiConfigEnum.java b/src/main/java/com/kamco/cd/kamcoback/common/enums/ApiConfigEnum.java new file mode 100644 index 00000000..30d8ea27 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/common/enums/ApiConfigEnum.java @@ -0,0 +1,22 @@ +package com.kamco.cd.kamcoback.common.enums; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +public class ApiConfigEnum { + + @Getter + @EqualsAndHashCode(of = "enumValue") + public static class EnumDto { + + private final T enumValue; + private final String id; + private final String text; + + public EnumDto(T enumValue, String id, String text) { + this.enumValue = enumValue; + this.id = id; + this.text = text; + } + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/common/enums/CommonUseStatus.java b/src/main/java/com/kamco/cd/kamcoback/common/enums/CommonUseStatus.java new file mode 100644 index 00000000..c099d74f --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/common/enums/CommonUseStatus.java @@ -0,0 +1,40 @@ +package com.kamco.cd.kamcoback.common.enums; + +import com.kamco.cd.kamcoback.common.utils.enums.EnumType; +import java.util.Arrays; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Common usage status used across the system. + * + *

This enum represents whether a resource is active, excluded from processing, or inactive. It + * is commonly used for filtering, business rules, and status management. + */ +@Getter +@AllArgsConstructor +public enum CommonUseStatus implements EnumType { + + // @formatter:off + USE("USE", "Active", 100) + /** Actively used and available */ + , + EXCEPT("EXCEPT", "Excluded", 200) + /** Explicitly excluded from use or processing */ + , + NOT_USE("NOT_USE", "Inactive", 999) +/** Not used or disabled */ +; + // @formatter:on + + private String id; + private String text; + private int ordering; + + public static CommonUseStatus getEnumById(String id) { + return Arrays.stream(CommonUseStatus.values()) + .filter(x -> x.getId().equals(id)) + .findFirst() + .orElse(CommonUseStatus.NOT_USE); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java index 37a5af02..67e2dfa3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java @@ -1,7 +1,9 @@ package com.kamco.cd.kamcoback.postgres.core; +import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode; import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; import com.kamco.cd.kamcoback.postgres.entity.MapInkx50kEntity; import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; import com.kamco.cd.kamcoback.postgres.repository.scene.MapInkx50kRepository; @@ -10,12 +12,16 @@ import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.UseInferReq; import jakarta.persistence.EntityNotFoundException; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import java.util.Optional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.locationtech.jts.geom.Polygon; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +@Slf4j @Service @RequiredArgsConstructor public class MapInkxMngCoreService { @@ -25,7 +31,7 @@ public class MapInkxMngCoreService { // 목록 public Page findMapInkxMngList( - MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { + MapInkxMngDto.searchReq searchReq, CommonUseStatus useInference, String searchVal) { return mapInkx5kRepository.findMapInkxMngList(searchReq, useInference, searchVal); } @@ -44,15 +50,14 @@ public class MapInkxMngCoreService { } MapInkx5kEntity entity = - new MapInkx5kEntity( - req.getMapidcdNo(), req.getMapidNm(), map_polygon, mapInkx50k, "USE" // 기본은 USE로 - ); + new MapInkx5kEntity(req.getMapidcdNo(), req.getMapidNm(), map_polygon, mapInkx50k); mapInkx5kRepository.save(entity); return new ResponseObj(ApiResponseCode.OK, ""); } + // 도엽의 사용여부를 변경한다. public ResponseObj updateUseInference(@Valid UseInferReq useInferReq) { Optional entity = Optional.ofNullable( @@ -63,4 +68,37 @@ public class MapInkxMngCoreService { entity.get().updateUseInference(useInferReq.getUseInference()); return new ResponseObj(ApiResponseCode.OK, ""); } + + /** + * Updates the inference usage status of a given map sheet (도엽) based on the provided scene ID and + * usage status. 도엽의 사용여부를 변경한다. + * + * @param sceneId5k the unique identifier for the map sheet whose usage status is being updated + * @param useStatus the new usage status to be set for the specified map sheet + * @return a ResponseObj indicating the outcome of the operation, including a response code and + * message + * @throws EntityNotFoundException if no map sheet is found for the provided scene ID + */ + @Transactional + public MapSheet updateUseInference( + @NotNull String sceneId5k, @NotNull CommonUseStatus useStatus) { + + log.debug("[updateUseInference]CHANGE_SCENE STATUS start: {}", sceneId5k); + + // 5k도엽 정보를 가져온다. + MapInkx5kEntity getScene5k = + mapInkx5kRepository + .findByMapidCdNoInfo(sceneId5k) + .orElseThrow(() -> new EntityNotFoundException("도엽정보를 찾을 수 없습니다.")); + + log.debug( + "[updateUseInference]CHANGE_SCENE STATUS: {} |BEFORE {} |AFTER {}", + sceneId5k, + getScene5k.getUseInference(), + useStatus); + // 상태를 업데이트한다. + getScene5k.updateUseInference(useStatus); + + return getScene5k.toEntity(); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java index 3fbe840e..80247365 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java @@ -1,10 +1,13 @@ package com.kamco.cd.kamcoback.postgres.entity; +import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; import com.kamco.cd.kamcoback.postgres.CommonDateEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -46,23 +49,24 @@ public class MapInkx5kEntity extends CommonDateEntity { @JoinColumn(name = "fid_k50", referencedColumnName = "fid") private MapInkx50kEntity mapInkx50k; + // 사용상태 USE, @Column(name = "use_inference") - private String useInference; + @Enumerated(EnumType.STRING) + private CommonUseStatus useInference; + // Constructor public MapInkx5kEntity( - String mapidcdNo, - String mapidNm, - Geometry geom, - MapInkx50kEntity mapInkx50k, - String useInference) { + String mapidcdNo, String mapidNm, Geometry geom, MapInkx50kEntity mapInkx50k) { this.mapidcdNo = mapidcdNo; this.mapidNm = mapidNm; this.geom = geom; this.mapInkx50k = mapInkx50k; - this.useInference = useInference; + // 생성시 default 사용함 (사용,제외,사용안함) + this.useInference = CommonUseStatus.USE; } - public void updateUseInference(String useInference) { + // 변경 사용상태 (추론사용여부) + public void updateUseInference(CommonUseStatus useInference) { this.useInference = useInference; } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java index b1c642cb..50bdf94f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java @@ -1,5 +1,6 @@ package com.kamco.cd.kamcoback.postgres.repository.scene; +import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapList; @@ -12,7 +13,7 @@ public interface MapInkx5kRepositoryCustom { List listGetScenes5k(List codes); Page findMapInkxMngList( - MapInkxMngDto.searchReq searchReq, String useInference, String searchVal); + MapInkxMngDto.searchReq searchReq, CommonUseStatus useInference, String searchVal); Long findByMapidCdNoExists(String mapidcdNo); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java index af85b892..9e34a467 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java @@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.postgres.repository.scene; import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity.mapInkx50kEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity; +import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; @@ -42,7 +43,7 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport @Override public Page findMapInkxMngList( - searchReq searchReq, String useInference, String searchVal) { + searchReq searchReq, CommonUseStatus useInference, String searchVal) { Pageable pageable = searchReq.toPageable(); List foundContent = @@ -103,7 +104,7 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport .fetchOne()); } - private BooleanExpression searchUseInference(String useInference) { + private BooleanExpression searchUseInference(CommonUseStatus useInference) { if (Objects.isNull(useInference)) { return null; } diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java b/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java index 3bb3b361..d1018323 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java @@ -1,7 +1,10 @@ package com.kamco.cd.kamcoback.scene; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto; +import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; import com.kamco.cd.kamcoback.scene.service.MapInkxMngService; import io.swagger.v3.oas.annotations.Operation; @@ -46,7 +49,7 @@ public class MapInkxMngApiController { public ApiResponseDto> findMapInkxMngList( @RequestParam int page, @RequestParam(defaultValue = "20") int size, - @RequestParam(required = false) String useInference, + @RequestParam(required = false) CommonUseStatus useInference, @RequestParam(required = false) String searchVal) { MapInkxMngDto.searchReq searchReq = new MapInkxMngDto.searchReq(page, size, ""); return ApiResponseDto.ok( @@ -108,6 +111,7 @@ public class MapInkxMngApiController { @RequestBody @Valid MapInkxMngDto.UseInferReq useInferReq) { - return ApiResponseDto.okObject(mapInkxMngService.updateUseInference(useInferReq)); + mapInkxMngService.updateUseInference(useInferReq); + return ApiResponseDto.okObject(new ResponseObj(ApiResponseCode.OK, "")); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java index 47298e0f..533fbc19 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java @@ -1,9 +1,11 @@ package com.kamco.cd.kamcoback.scene.dto; import com.fasterxml.jackson.databind.JsonNode; +import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose; import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.persistence.EntityNotFoundException; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -151,6 +153,18 @@ public class MapInkxMngDto { public static class UseInferReq { private String mapidcdNo; - private String useInference; + private CommonUseStatus useInference; // 변경하고자하는 상태 + + public void valid() { + if (mapidcdNo == null || mapidcdNo.isEmpty()) { + throw new IllegalArgumentException("도엽번호는 필수 입력값입니다."); + } + // 공백제거 + mapidcdNo = mapidcdNo.trim(); + + if (!mapidcdNo.matches("^\\d{8}$")) { + throw new EntityNotFoundException("도엽번호는 8자리 숫자로 구성되어야 합니다."); + } + } } } diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java b/src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java index b39bc323..5cd06c7c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java +++ b/src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java @@ -1,6 +1,8 @@ package com.kamco.cd.kamcoback.scene.service; +import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; import com.kamco.cd.kamcoback.postgres.core.MapInkxMngCoreService; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapList; @@ -15,6 +17,7 @@ import org.locationtech.jts.geom.LinearRing; import org.locationtech.jts.geom.PrecisionModel; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -23,7 +26,7 @@ public class MapInkxMngService { private final MapInkxMngCoreService mapInkxMngCoreService; public Page findMapInkxMngList( - MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { + MapInkxMngDto.searchReq searchReq, CommonUseStatus useInference, String searchVal) { return mapInkxMngCoreService.findMapInkxMngList(searchReq, useInference, searchVal); } @@ -52,7 +55,10 @@ public class MapInkxMngService { return mapInkxMngCoreService.saveMapInkx5k(req, GEOMETRY_FACTORY.createPolygon(shell)); } - public ResponseObj updateUseInference(@Valid UseInferReq useInferReq) { - return mapInkxMngCoreService.updateUseInference(useInferReq); + // 도엽의 상태를 업데이트한다. + @Transactional + public MapSheet updateUseInference(@Valid UseInferReq useInferReq) { + return mapInkxMngCoreService.updateUseInference( + useInferReq.getMapidcdNo(), useInferReq.getUseInference()); } } From 34ee60b9082d7793dcb42b77b60c5457ad114585 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Tue, 30 Dec 2025 10:07:56 +0900 Subject: [PATCH 22/28] =?UTF-8?q?=EB=8F=84=EC=97=BD=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EC=BB=AC=EB=9F=BC=20=EC=88=98=EC=A0=95=EB=90=9C=20?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=A7=9E=EC=B6=94=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../postgres/core/MapInkxMngCoreService.java | 16 +- .../postgres/entity/MapInkx5kEntity.java | 10 +- .../mapsheet/MapSheetMngRepositoryImpl.java | 997 +++++++++--------- .../scene/MapInkx5kRepositoryImpl.java | 100 +- .../cd/kamcoback/scene/dto/MapInkxMngDto.java | 38 +- 5 files changed, 581 insertions(+), 580 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java index cdcba289..5e69bec3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java @@ -24,7 +24,7 @@ public class MapInkxMngCoreService { // 목록 public Page findMapInkxMngList( - MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { + MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { return mapInkx5kRepository.findMapInkxMngList(searchReq, useInference, searchVal); } @@ -43,9 +43,9 @@ public class MapInkxMngCoreService { } MapInkx5kEntity entity = - new MapInkx5kEntity( - req.getMapidcdNo(), req.getMapidNm(), map_polygon, fid50k.longValue(), "USE" // 기본은 USE로 - ); + new MapInkx5kEntity( + req.getMapidcdNo(), req.getMapidNm(), map_polygon, fid50k, "USE" // 기본은 USE로 + ); mapInkx5kRepository.save(entity); @@ -54,10 +54,10 @@ public class MapInkxMngCoreService { public ResponseObj updateUseInference(@Valid UseInferReq useInferReq) { Optional entity = - Optional.ofNullable( - mapInkx5kRepository - .findByMapidCdNoInfo(useInferReq.getMapidcdNo()) - .orElseThrow(() -> new EntityNotFoundException("도엽정보를 찾을 수 없습니다."))); + Optional.ofNullable( + mapInkx5kRepository + .findByMapidCdNoInfo(useInferReq.getMapidcdNo()) + .orElseThrow(() -> new EntityNotFoundException("도엽정보를 찾을 수 없습니다."))); entity.get().updateUseInference(useInferReq.getUseInference()); return new ResponseObj(ApiResponseCode.OK, ""); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java index d2d7fdb5..c6e3ca87 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java @@ -25,9 +25,9 @@ public class MapInkx5kEntity extends CommonDateEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_inkx_5k_fid_seq_gen") @SequenceGenerator( - name = "tb_map_inkx_5k_fid_seq_gen", - sequenceName = "tb_map_inkx_5k_fid_seq", - allocationSize = 1) + name = "tb_map_inkx_5k_fid_seq_gen", + sequenceName = "tb_map_inkx_5k_fid_seq", + allocationSize = 1) private Integer fid; @Column(name = "mapidcd_no") @@ -40,13 +40,13 @@ public class MapInkx5kEntity extends CommonDateEntity { private Geometry geom; @Column(name = "fid_k50") - private Long fidK50; + private Integer fidK50; @Column(name = "use_inference") private String useInference; public MapInkx5kEntity( - String mapidcdNo, String mapidNm, Geometry geom, Long fidK50, String useInference) { + String mapidcdNo, String mapidNm, Geometry geom, Integer fidK50, String useInference) { this.mapidcdNo = mapidcdNo; this.mapidNm = mapidNm; this.geom = geom; 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 1226813b..6c214497 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 @@ -33,12 +33,13 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport - implements MapSheetMngRepositoryCustom { + implements MapSheetMngRepositoryCustom { private final JPAQueryFactory queryFactory; private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); - @PersistenceContext private EntityManager em; + @PersistenceContext + private EntityManager em; public MapSheetMngRepositoryImpl(JPAQueryFactory queryFactory) { super(MapSheetMngHstEntity.class); @@ -58,121 +59,121 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport NumberExpression totalCount = mapSheetMngHstEntity.count().as("syncTotCnt"); NumberExpression doneCount = - new CaseBuilder() - .when(mapSheetMngHstEntity.dataState.eq("DONE")) - .then(1L) - .otherwise(0L) - .sum() - .as("syncStateDoneCnt"); + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum() + .as("syncStateDoneCnt"); List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngDto.class, - Expressions.numberTemplate( - Integer.class, - "row_number() over(order by {0} desc)", - mapSheetMngEntity.createdDttm), - mapSheetMngEntity.mngYyyy, - mapSheetMngEntity.mngPath, - mapSheetMngEntity.mngState, - mapSheetMngEntity.syncState, - mapSheetMngEntity.syncCheckState, - mapSheetMngHstEntity.count().as("syncTotalCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.dataState.eq("DONE")) - .then(1L) - .otherwise(0L) - .sum() - .as("syncStateDoneCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) - .then(1L) - .otherwise(0L) - .sum(), - mapSheetMngEntity.createdDttm, - mapSheetMngHstEntity.syncEndDttm.max())) - .from(mapSheetMngEntity) - .leftJoin(mapSheetMngHstEntity) - .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) - .where(whereBuilder) - // .offset(pageable.getOffset()) - // .limit(pageable.getPageSize()) - .orderBy(mapSheetMngEntity.mngYyyy.desc()) - .groupBy(mapSheetMngEntity.mngYyyy) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngDto.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} desc)", + mapSheetMngEntity.createdDttm), + mapSheetMngEntity.mngYyyy, + mapSheetMngEntity.mngPath, + mapSheetMngEntity.mngState, + mapSheetMngEntity.syncState, + mapSheetMngEntity.syncCheckState, + mapSheetMngHstEntity.count().as("syncTotalCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum() + .as("syncStateDoneCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) + .then(1L) + .otherwise(0L) + .sum(), + mapSheetMngEntity.createdDttm, + mapSheetMngHstEntity.syncEndDttm.max())) + .from(mapSheetMngEntity) + .leftJoin(mapSheetMngHstEntity) + .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) + .where(whereBuilder) + // .offset(pageable.getOffset()) + // .limit(pageable.getPageSize()) + .orderBy(mapSheetMngEntity.mngYyyy.desc()) + .groupBy(mapSheetMngEntity.mngYyyy) + .fetch(); Long countQuery = - queryFactory - .select(mapSheetMngEntity.mngYyyy.count()) - .from(mapSheetMngEntity) - .where(whereBuilder) - .fetchOne(); + queryFactory + .select(mapSheetMngEntity.mngYyyy.count()) + .from(mapSheetMngEntity) + .where(whereBuilder) + .fetchOne(); return foundContent; } @@ -180,15 +181,15 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport public List findMapSheetMngYyyyList() { List foundContent = - queryFactory - .select(yearEntity.yyyy) - .from(yearEntity) - .leftJoin(mapSheetMngEntity) - .on(mapSheetMngEntity.mngYyyy.eq(yearEntity.yyyy)) - .where(yearEntity.status.eq("NOTYET")) - .orderBy(yearEntity.yyyy.asc()) - .limit(10) - .fetch(); + queryFactory + .select(yearEntity.yyyy) + .from(yearEntity) + .leftJoin(mapSheetMngEntity) + .on(mapSheetMngEntity.mngYyyy.eq(yearEntity.yyyy)) + .where(yearEntity.status.eq("NOTYET")) + .orderBy(yearEntity.yyyy.asc()) + .limit(10) + .fetch(); foundContent.sort(Comparator.reverseOrder()); @@ -197,11 +198,11 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport public void updateYearState(int yyyy, String status) { long execCount = - queryFactory - .update(yearEntity) - .set(yearEntity.status, status) - .where(yearEntity.yyyy.eq(yyyy)) - .execute(); + queryFactory + .update(yearEntity) + .set(yearEntity.status, status) + .where(yearEntity.yyyy.eq(yyyy)) + .execute(); } public MapSheetMngDto.MngDto findMapSheetMng(int mngYyyy) { @@ -210,117 +211,117 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngEntity.mngYyyy.eq(mngYyyy)); MapSheetMngDto.MngDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngDto.class, - Expressions.numberTemplate( - Integer.class, - "row_number() over(order by {0} desc)", - mapSheetMngEntity.createdDttm), - mapSheetMngEntity.mngYyyy, - mapSheetMngEntity.mngPath, - mapSheetMngEntity.mngState, - mapSheetMngEntity.syncState, - mapSheetMngEntity.syncCheckState, - mapSheetMngHstEntity.count().as("syncTotalCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.dataState.eq("DONE")) - .then(1L) - .otherwise(0L) - .sum() - .as("syncStateDoneCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) - .then(1L) - .otherwise(0L) - .sum(), - mapSheetMngEntity.createdDttm, - mapSheetMngHstEntity.syncEndDttm.max())) - .from(mapSheetMngEntity) - .leftJoin(mapSheetMngHstEntity) - .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) - .where(whereBuilder) - .groupBy(mapSheetMngEntity.mngYyyy) - .fetchOne(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngDto.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} desc)", + mapSheetMngEntity.createdDttm), + mapSheetMngEntity.mngYyyy, + mapSheetMngEntity.mngPath, + mapSheetMngEntity.mngState, + mapSheetMngEntity.syncState, + mapSheetMngEntity.syncCheckState, + mapSheetMngHstEntity.count().as("syncTotalCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum() + .as("syncStateDoneCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) + .then(1L) + .otherwise(0L) + .sum(), + mapSheetMngEntity.createdDttm, + mapSheetMngHstEntity.syncEndDttm.max())) + .from(mapSheetMngEntity) + .leftJoin(mapSheetMngHstEntity) + .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) + .where(whereBuilder) + .groupBy(mapSheetMngEntity.mngYyyy) + .fetchOne(); return foundContent; } @Override public Page findMapSheetErrorList( - MapSheetMngDto.@Valid ErrorSearchReq searchReq) { + MapSheetMngDto.@Valid ErrorSearchReq searchReq) { Pageable pageable = PageRequest.of(searchReq.getPage(), searchReq.getSize()); BooleanBuilder whereBuilder = new BooleanBuilder(); whereBuilder.and(mapSheetMngHstEntity.mngYyyy.eq(searchReq.getMngYyyy())); whereBuilder.and( - mapSheetMngHstEntity.syncState.ne("DONE").and(mapSheetMngHstEntity.syncState.ne("NOTYET"))); + mapSheetMngHstEntity.syncState.ne("DONE").and(mapSheetMngHstEntity.syncState.ne("NOTYET"))); if (searchReq.getSyncState() != null && !searchReq.getSyncState().isEmpty()) { whereBuilder.and(mapSheetMngHstEntity.syncState.eq(searchReq.getSyncState())); @@ -332,70 +333,70 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport if (searchReq.getSearchValue() != null && !searchReq.getSearchValue().isEmpty()) { whereBuilder.and( - mapSheetMngHstEntity - .mapSheetNum - .eq(searchReq.getSearchValue()) - .or(mapSheetMngHstEntity.refMapSheetNum.eq(searchReq.getSearchValue())) - .or( - Expressions.stringTemplate( - "concat({0},substring({1}, 0, 6))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .likeIgnoreCase("%" + searchReq.getSearchValue() + "%")) - .or( - Expressions.stringTemplate( - "concat({0},substring({1}, 6, 8))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .likeIgnoreCase("%" + searchReq.getSearchValue() + "%"))); + mapSheetMngHstEntity + .mapSheetNum + .eq(searchReq.getSearchValue()) + .or(mapSheetMngHstEntity.refMapSheetNum.eq(searchReq.getSearchValue())) + .or( + Expressions.stringTemplate( + "concat({0},substring({1}, 0, 6))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .likeIgnoreCase("%" + searchReq.getSearchValue() + "%")) + .or( + Expressions.stringTemplate( + "concat({0},substring({1}, 6, 8))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .likeIgnoreCase("%" + searchReq.getSearchValue() + "%"))); } List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.ErrorDataDto.class, - mapSheetMngHstEntity.hstUid, - mapSheetMngHstEntity.mngYyyy, - mapSheetMngHstEntity.mapSheetNum, - mapSheetMngHstEntity.refMapSheetNum, - Expressions.stringTemplate( - "concat({0},substring({1}, 0, 6))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .as("map50kName"), - Expressions.stringTemplate( - "concat({0},{1})", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .as("map5kName"), - Expressions.stringTemplate( - "concat({0},substring({1}, 6, 8))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .as("mapSrcName"), - mapInkx5kEntity.fid, - mapSheetMngHstEntity.createdDate, - mapSheetMngHstEntity.syncState, - mapSheetMngHstEntity.syncTfwFileName, - mapSheetMngHstEntity.syncTifFileName, - mapSheetMngHstEntity.syncCheckState, - mapSheetMngHstEntity.syncCheckTfwFileName, - mapSheetMngHstEntity.syncCheckTifFileName)) - .from(mapSheetMngHstEntity) - .innerJoin(mapInkx5kEntity) - .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) - .where(whereBuilder) - .orderBy(mapSheetMngHstEntity.createdDate.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.ErrorDataDto.class, + mapSheetMngHstEntity.hstUid, + mapSheetMngHstEntity.mngYyyy, + mapSheetMngHstEntity.mapSheetNum, + mapSheetMngHstEntity.refMapSheetNum, + Expressions.stringTemplate( + "concat({0},substring({1}, 0, 6))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .as("map50kName"), + Expressions.stringTemplate( + "concat({0},{1})", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .as("map5kName"), + Expressions.stringTemplate( + "concat({0},substring({1}, 6, 8))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .as("mapSrcName"), + mapInkx5kEntity.fid, + mapSheetMngHstEntity.createdDate, + mapSheetMngHstEntity.syncState, + mapSheetMngHstEntity.syncTfwFileName, + mapSheetMngHstEntity.syncTifFileName, + mapSheetMngHstEntity.syncCheckState, + mapSheetMngHstEntity.syncCheckTfwFileName, + mapSheetMngHstEntity.syncCheckTifFileName)) + .from(mapSheetMngHstEntity) + .innerJoin(mapInkx5kEntity) + .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) + .where(whereBuilder) + .orderBy(mapSheetMngHstEntity.createdDate.desc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); Long countQuery = - queryFactory - .select(mapSheetMngHstEntity.hstUid.count()) - .from(mapSheetMngHstEntity) - .innerJoin(mapInkx5kEntity) - .on(mapSheetMngHstEntity.mapSheetCode.eq(mapInkx5kEntity.fid)) - .leftJoin(mapInkx50kEntity) - .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid.longValue())) - .where(whereBuilder) - .fetchOne(); + queryFactory + .select(mapSheetMngHstEntity.hstUid.count()) + .from(mapSheetMngHstEntity) + .innerJoin(mapInkx5kEntity) + .on(mapSheetMngHstEntity.mapSheetCode.eq(mapInkx5kEntity.fid)) + .leftJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid)) + .where(whereBuilder) + .fetchOne(); return new PageImpl<>(foundContent, pageable, countQuery); } @@ -407,42 +408,42 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngHstEntity.hstUid.eq(hstUid)); MapSheetMngDto.ErrorDataDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.ErrorDataDto.class, - mapSheetMngHstEntity.hstUid, - mapSheetMngHstEntity.mngYyyy, - mapSheetMngHstEntity.mapSheetNum, - mapSheetMngHstEntity.refMapSheetNum, - Expressions.stringTemplate( - "concat({0}, substring({1}, 1, 5))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.ErrorDataDto.class, + mapSheetMngHstEntity.hstUid, + mapSheetMngHstEntity.mngYyyy, + mapSheetMngHstEntity.mapSheetNum, + mapSheetMngHstEntity.refMapSheetNum, + Expressions.stringTemplate( + "concat({0}, substring({1}, 1, 5))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - // ✅ 튜플 방지: concat으로 문자열 생성 - Expressions.stringTemplate( - "concat('(', {0}, ',', {1}, ')')", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - Expressions.stringTemplate( - "concat({0}, substring({1}, 6, 3))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), + // ✅ 튜플 방지: concat으로 문자열 생성 + Expressions.stringTemplate( + "concat('(', {0}, ',', {1}, ')')", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), + Expressions.stringTemplate( + "concat({0}, substring({1}, 6, 3))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - // fid 타입 주의 (Long이면 DTO도 Long으로 맞추는 걸 추천) - mapInkx5kEntity.fid, // 또는 mapInkx5kEntity.fid.intValue() + // fid 타입 주의 (Long이면 DTO도 Long으로 맞추는 걸 추천) + mapInkx5kEntity.fid, // 또는 mapInkx5kEntity.fid.intValue() - // ✅ createdDate 말고 ZonedDateTime으로 매핑된 필드로 - mapSheetMngHstEntity.createdDate, // (예시) - mapSheetMngHstEntity.syncState, - mapSheetMngHstEntity.syncTfwFileName, - mapSheetMngHstEntity.syncTifFileName, - mapSheetMngHstEntity.syncCheckState, - mapSheetMngHstEntity.syncCheckTfwFileName, - mapSheetMngHstEntity.syncCheckTifFileName)) - .from(mapSheetMngHstEntity) - .innerJoin(mapInkx5kEntity) - .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) - .where(whereBuilder) - .fetchOne(); + // ✅ createdDate 말고 ZonedDateTime으로 매핑된 필드로 + mapSheetMngHstEntity.createdDate, // (예시) + mapSheetMngHstEntity.syncState, + mapSheetMngHstEntity.syncTfwFileName, + mapSheetMngHstEntity.syncTifFileName, + mapSheetMngHstEntity.syncCheckState, + mapSheetMngHstEntity.syncCheckTfwFileName, + mapSheetMngHstEntity.syncCheckTifFileName)) + .from(mapSheetMngHstEntity) + .innerJoin(mapInkx5kEntity) + .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) + .where(whereBuilder) + .fetchOne(); return foundContent; } @@ -455,22 +456,22 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngFileEntity.fileDel.eq(false)); List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(whereBuilder) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(whereBuilder) + .fetch(); return foundContent; } @@ -482,23 +483,23 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngFileEntity.fileDel.eq(false)); List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(whereBuilder) - .orderBy(mapSheetMngFileEntity.filePath.asc()) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(whereBuilder) + .orderBy(mapSheetMngFileEntity.filePath.asc()) + .fetch(); return foundContent; } @@ -510,24 +511,24 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)); MapSheetMngDto.MngFilesDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(whereBuilder) - .orderBy(mapSheetMngFileEntity.fileUid.desc()) - .limit(1) - .fetchOne(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(whereBuilder) + .orderBy(mapSheetMngFileEntity.fileUid.desc()) + .limit(1) + .fetchOne(); return foundContent; } @@ -536,22 +537,22 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport public MapSheetMngDto.MngFilesDto findByFileUidMapSheetFile(Long fileUid) { MapSheetMngDto.MngFilesDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) - .fetchOne(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) + .fetchOne(); return foundContent; } @@ -559,147 +560,147 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport @Override public void MapSheetMngComplete(int mngYyyy) { long execCount = - queryFactory - .update(mapSheetMngEntity) - .set(mapSheetMngEntity.mngState, "COMPLETE") - .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .update(mapSheetMngEntity) + .set(mapSheetMngEntity.mngState, "COMPLETE") + .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void updateMapSheetMngHstSyncCheckState(MapSheetMngDto.SyncCheckStateReqUpdateDto updReq) { long execCount = - queryFactory - .update(mapSheetMngHstEntity) - .set(mapSheetMngHstEntity.syncCheckState, updReq.getSyncCheckState()) - .set(mapSheetMngHstEntity.mapSheetPath, updReq.getFilePath()) - .set(mapSheetMngHstEntity.syncCheckTfwFileName, updReq.getSyncCheckTfwFileName()) - .set(mapSheetMngHstEntity.syncCheckTifFileName, updReq.getSyncCheckTifFileName()) - .set(mapSheetMngHstEntity.syncCheckStrtDttm, ZonedDateTime.now()) - .set(mapSheetMngHstEntity.syncCheckEndDttm, ZonedDateTime.now()) - .where(mapSheetMngHstEntity.hstUid.eq(updReq.getHstUid())) - .execute(); + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.syncCheckState, updReq.getSyncCheckState()) + .set(mapSheetMngHstEntity.mapSheetPath, updReq.getFilePath()) + .set(mapSheetMngHstEntity.syncCheckTfwFileName, updReq.getSyncCheckTfwFileName()) + .set(mapSheetMngHstEntity.syncCheckTifFileName, updReq.getSyncCheckTifFileName()) + .set(mapSheetMngHstEntity.syncCheckStrtDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncCheckEndDttm, ZonedDateTime.now()) + .where(mapSheetMngHstEntity.hstUid.eq(updReq.getHstUid())) + .execute(); } @Override public void deleteByMngYyyyMngAll(int mngYyyy) { long deletedFileCount = - queryFactory - .delete(mapSheetMngFileEntity) - .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngFileEntity) + .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) + .execute(); long deletedHisCount = - queryFactory - .delete(mapSheetMngHstEntity) - .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngHstEntity) + .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) + .execute(); long deletedMngCount = - queryFactory - .delete(mapSheetMngEntity) - .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngEntity) + .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByMngYyyyMng(int mngYyyy) { long deletedMngCount = - queryFactory - .delete(mapSheetMngEntity) - .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngEntity) + .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByMngYyyyMngHst(int mngYyyy) { long deletedHisCount = - queryFactory - .delete(mapSheetMngHstEntity) - .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngHstEntity) + .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByMngYyyyMngFile(int mngYyyy) { long deletedFileCount = - queryFactory - .delete(mapSheetMngFileEntity) - .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngFileEntity) + .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByHstUidMngFile(Long hstUid) { long deletedFileCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileDel, true) - .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileDel, true) + .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) + .execute(); } @Override public void deleteByFileUidMngFile(Long fileUid) { long fileCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileDel, true) - .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileDel, true) + .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) + .execute(); } @Override public void updateByHstUidMngFileState(Long hstUid, String fileState) { long execCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileState, fileState) - .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileState, fileState) + .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) + .execute(); } @Override public void deleteByNotInFileUidMngFile(Long hstUid, List fileUids) { long execCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileDel, true) - .where( - mapSheetMngFileEntity - .hstUid - .eq(hstUid) - .and(mapSheetMngFileEntity.fileUid.notIn(fileUids))) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileDel, true) + .where( + mapSheetMngFileEntity + .hstUid + .eq(hstUid) + .and(mapSheetMngFileEntity.fileUid.notIn(fileUids))) + .execute(); } @Override public void updateByFileUidMngFileState(Long fileUid, String fileState) { long execCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileState, fileState) - .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileState, fileState) + .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) + .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(); + queryFactory + .select(mapSheetMngFileEntity.count()) + .from(mapSheetMngFileEntity) + .where( + mapSheetMngFileEntity + .mngYyyy + .eq(mngYyyy) + .and(mapSheetMngFileEntity.fileName.eq(fileName))) + .fetchOne(); return Math.toIntExact(execCount); } @@ -707,36 +708,36 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport @Override public void mngFileSave(@Valid MapSheetMngDto.MngFileAddReq addReq) { long fileCount = - queryFactory - .insert(mapSheetMngFileEntity) - .columns( - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize, - mapSheetMngFileEntity.fileState) - .values( - addReq.getMngYyyy(), - addReq.getMapSheetNum(), - addReq.getRefMapSheetNum(), - addReq.getFilePath(), - addReq.getFileName(), - addReq.getFileExt(), - addReq.getHstUid(), - addReq.getFileSize(), - addReq.getFileState()) - .execute(); + queryFactory + .insert(mapSheetMngFileEntity) + .columns( + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize, + mapSheetMngFileEntity.fileState) + .values( + addReq.getMngYyyy(), + addReq.getMapSheetNum(), + addReq.getRefMapSheetNum(), + addReq.getFilePath(), + addReq.getFileName(), + addReq.getFileExt(), + addReq.getHstUid(), + addReq.getFileSize(), + addReq.getFileState()) + .execute(); } @Override public int insertMapSheetOrgDataToMapSheetMngHst(int mngYyyy, String mngPath) { String sql = - """ + """ INSERT INTO tb_map_sheet_mng_hst ( mng_yyyy @@ -776,17 +777,17 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport @Override public Optional findMapSheetMngHstInfo(Long hstUid) { return Optional.ofNullable( - queryFactory - .selectFrom(mapSheetMngHstEntity) - .where(mapSheetMngHstEntity.hstUid.eq(hstUid)) - .fetchOne()); + queryFactory + .selectFrom(mapSheetMngHstEntity) + .where(mapSheetMngHstEntity.hstUid.eq(hstUid)) + .fetchOne()); } @Override public void updateHstFileSizes( - Long hstUid, long tifSizeBytes, long tfwSizeBytes, long totalSizeBytes) { + Long hstUid, long tifSizeBytes, long tfwSizeBytes, long totalSizeBytes) { String sql = - "UPDATE tb_map_sheet_mng_hst SET tif_size_bytes = :tif, tfw_size_bytes = :tfw, total_size_bytes = :tot WHERE hst_uid = :uid"; + "UPDATE tb_map_sheet_mng_hst SET tif_size_bytes = :tif, tfw_size_bytes = :tfw, total_size_bytes = :tot WHERE hst_uid = :uid"; Query query = (Query) em.createNativeQuery(sql); query.setParameter("tif", tifSizeBytes); query.setParameter("tfw", tfwSizeBytes); @@ -797,7 +798,7 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport private NumberExpression rowNum() { return Expressions.numberTemplate( - Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate); + Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate); } private BooleanExpression mapSheetErrorSearchValue(MapSheetMngDto.ErrorSearchReq searchReq) { @@ -807,10 +808,10 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport // 검색어 1개 값이 도엽명 or 도엽번호 like 검색 return Expressions.booleanTemplate( - "{0} like '%" + searchReq.getSearchValue() + "%'", mapSheetMngHstEntity.mapSheetName) - .or( - Expressions.booleanTemplate( - "{0} like '%" + searchReq.getSearchValue() + "%'", - mapSheetMngHstEntity.mapSheetNum)); + "{0} like '%" + searchReq.getSearchValue() + "%'", mapSheetMngHstEntity.mapSheetName) + .or( + Expressions.booleanTemplate( + "{0} like '%" + searchReq.getSearchValue() + "%'", + mapSheetMngHstEntity.mapSheetNum)); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java index 2f957b8a..5412d4ef 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java @@ -21,7 +21,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport - implements MapInkx5kRepositoryCustom { + implements MapInkx5kRepositoryCustom { private final JPAQueryFactory queryFactory; @@ -34,53 +34,53 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport QMapInkx5kEntity map5k = QMapInkx5kEntity.mapInkx5kEntity; return queryFactory - .selectFrom(map5k) - .where(map5k.mapidcdNo.in(codes)) - .orderBy(map5k.mapidcdNo.asc()) - .fetch(); + .selectFrom(map5k) + .where(map5k.mapidcdNo.in(codes)) + .orderBy(map5k.mapidcdNo.asc()) + .fetch(); } @Override public Page findMapInkxMngList( - searchReq searchReq, String useInference, String searchVal) { + searchReq searchReq, String useInference, String searchVal) { Pageable pageable = searchReq.toPageable(); List foundContent = - queryFactory - .select( - Projections.constructor( - MapInkxMngDto.MapList.class, - Expressions.numberTemplate( - Integer.class, - "row_number() over(order by {0} asc)", - mapInkx5kEntity.mapidcdNo), - mapInkx5kEntity.mapidcdNo, - mapInkx50kEntity.mapidcdNo, - mapInkx5kEntity.mapidNm, - mapInkx5kEntity.createdDate, - mapInkx5kEntity.modifiedDate, - // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", - // mapInkx5kEntity.createdDate), - // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", - // mapInkx5kEntity.modifiedDate), - mapInkx5kEntity.useInference)) - .from(mapInkx5kEntity) - .innerJoin(mapInkx50kEntity) - .on(mapInkx5kEntity.fidK50.intValue().eq(mapInkx50kEntity.fid)) - .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .orderBy(mapInkx5kEntity.mapidcdNo.asc()) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapInkxMngDto.MapList.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} asc)", + mapInkx5kEntity.mapidcdNo), + mapInkx5kEntity.mapidcdNo, + mapInkx50kEntity.mapidcdNo, + mapInkx5kEntity.mapidNm, + mapInkx5kEntity.createdDate, + mapInkx5kEntity.modifiedDate, + // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", + // mapInkx5kEntity.createdDate), + // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", + // mapInkx5kEntity.modifiedDate), + mapInkx5kEntity.useInference)) + .from(mapInkx5kEntity) + .innerJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid)) + .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(mapInkx5kEntity.mapidcdNo.asc()) + .fetch(); Long countQuery = - queryFactory - .select(mapInkx5kEntity.count()) - .from(mapInkx5kEntity) - .innerJoin(mapInkx50kEntity) - .on(mapInkx5kEntity.fidK50.intValue().eq(mapInkx50kEntity.fid)) - .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) - .fetchOne(); + queryFactory + .select(mapInkx5kEntity.count()) + .from(mapInkx5kEntity) + .innerJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.intValue().eq(mapInkx50kEntity.fid)) + .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) + .fetchOne(); return new PageImpl<>(foundContent, pageable, countQuery); } @@ -88,19 +88,19 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport @Override public Long findByMapidCdNoExists(String mapidcdNo) { return queryFactory - .select(mapInkx5kEntity.count()) - .from(mapInkx5kEntity) - .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) - .fetchOne(); + .select(mapInkx5kEntity.count()) + .from(mapInkx5kEntity) + .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) + .fetchOne(); } @Override public Optional findByMapidCdNoInfo(String mapidcdNo) { return Optional.ofNullable( - queryFactory - .selectFrom(mapInkx5kEntity) - .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) - .fetchOne()); + queryFactory + .selectFrom(mapInkx5kEntity) + .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) + .fetchOne()); } private BooleanExpression searchUseInference(String useInference) { @@ -115,8 +115,8 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport return null; } return mapInkx5kEntity - .mapidcdNo - .like("%" + searchVal + "%") - .or(mapInkx5kEntity.mapidNm.like("%" + searchVal + "%")); + .mapidcdNo + .like("%" + searchVal + "%") + .or(mapInkx5kEntity.mapidNm.like("%" + searchVal + "%")); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java index 5c8baf05..992cf071 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java @@ -48,7 +48,7 @@ public class MapInkxMngDto { private String mapidcdNo; private String mapidNm; private JsonNode geom; - private Long fidK50; + private Integer fidK50; private String useInference; private ZonedDateTime createdDttm; private ZonedDateTime updatedDttm; @@ -72,28 +72,28 @@ public class MapInkxMngDto { // 목록 Querydsl 에서 리턴 받는 건 생성자 기준임 -> 쿼리 컬럼 그대로 받고 여기서 Java 형변환 해서 return 하기 public MapList( - Integer rowNum, - String mapidcdNo5k, - String mapidcdNo50k, - String mapidNm, - ZonedDateTime createdDttmTime, - ZonedDateTime updatedDttmTime, - String useInference) { + Integer rowNum, + String mapidcdNo5k, + String mapidcdNo50k, + String mapidNm, + ZonedDateTime createdDttmTime, + ZonedDateTime updatedDttmTime, + String useInference) { this.rowNum = rowNum; this.mapidcdNo5k = mapidcdNo5k; this.mapidcdNo50k = mapidcdNo50k; this.mapidNm = mapidNm; DateTimeFormatter fmt = - DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Seoul")); + DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Seoul")); this.createdDttm = fmt.format(createdDttmTime); this.updatedDttm = fmt.format(updatedDttmTime); this.createdDttmTime = createdDttmTime; this.updatedDttmTime = updatedDttmTime; this.useInference = - useInference.equals("USE") - ? UseInferenceType.USE.getDesc() - : UseInferenceType.EXCEPT.getDesc(); + useInference.equals("USE") + ? UseInferenceType.USE.getDesc() + : UseInferenceType.EXCEPT.getDesc(); } } @@ -114,7 +114,7 @@ public class MapInkxMngDto { 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); @@ -135,12 +135,12 @@ public class MapInkxMngDto { private String mapidNm; @Schema( - description = "좌표 목록 (한 줄에 한 점, '경도 위도' 형식)", - example = - "127.17500001632317 36.17499998262991\n" - + "127.14999995475043 36.17500002877932\n" - + "127.15000004313612 36.199999984012415\n" - + "127.1750000466954 36.20000001863179") + description = "좌표 목록 (한 줄에 한 점, '경도 위도' 형식)", + example = + "127.17500001632317 36.17499998262991\n" + + "127.14999995475043 36.17500002877932\n" + + "127.15000004313612 36.199999984012415\n" + + "127.1750000466954 36.20000001863179") private String coordinates; } From ded9fa4b225f1d05b191f8ec08fd577c33284cfc Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Tue, 30 Dec 2025 10:08:23 +0900 Subject: [PATCH 23/28] =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../postgres/core/MapInkxMngCoreService.java | 16 +- .../postgres/entity/MapInkx5kEntity.java | 8 +- .../mapsheet/MapSheetMngRepositoryImpl.java | 997 +++++++++--------- .../scene/MapInkx5kRepositoryImpl.java | 100 +- .../cd/kamcoback/scene/dto/MapInkxMngDto.java | 36 +- 5 files changed, 578 insertions(+), 579 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java index 5e69bec3..a3beac7e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java @@ -24,7 +24,7 @@ public class MapInkxMngCoreService { // 목록 public Page findMapInkxMngList( - MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { + MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { return mapInkx5kRepository.findMapInkxMngList(searchReq, useInference, searchVal); } @@ -43,9 +43,9 @@ public class MapInkxMngCoreService { } MapInkx5kEntity entity = - new MapInkx5kEntity( - req.getMapidcdNo(), req.getMapidNm(), map_polygon, fid50k, "USE" // 기본은 USE로 - ); + new MapInkx5kEntity( + req.getMapidcdNo(), req.getMapidNm(), map_polygon, fid50k, "USE" // 기본은 USE로 + ); mapInkx5kRepository.save(entity); @@ -54,10 +54,10 @@ public class MapInkxMngCoreService { public ResponseObj updateUseInference(@Valid UseInferReq useInferReq) { Optional entity = - Optional.ofNullable( - mapInkx5kRepository - .findByMapidCdNoInfo(useInferReq.getMapidcdNo()) - .orElseThrow(() -> new EntityNotFoundException("도엽정보를 찾을 수 없습니다."))); + Optional.ofNullable( + mapInkx5kRepository + .findByMapidCdNoInfo(useInferReq.getMapidcdNo()) + .orElseThrow(() -> new EntityNotFoundException("도엽정보를 찾을 수 없습니다."))); entity.get().updateUseInference(useInferReq.getUseInference()); return new ResponseObj(ApiResponseCode.OK, ""); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java index c6e3ca87..981b0818 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java @@ -25,9 +25,9 @@ public class MapInkx5kEntity extends CommonDateEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_inkx_5k_fid_seq_gen") @SequenceGenerator( - name = "tb_map_inkx_5k_fid_seq_gen", - sequenceName = "tb_map_inkx_5k_fid_seq", - allocationSize = 1) + name = "tb_map_inkx_5k_fid_seq_gen", + sequenceName = "tb_map_inkx_5k_fid_seq", + allocationSize = 1) private Integer fid; @Column(name = "mapidcd_no") @@ -46,7 +46,7 @@ public class MapInkx5kEntity extends CommonDateEntity { private String useInference; public MapInkx5kEntity( - String mapidcdNo, String mapidNm, Geometry geom, Integer fidK50, String useInference) { + String mapidcdNo, String mapidNm, Geometry geom, Integer fidK50, String useInference) { this.mapidcdNo = mapidcdNo; this.mapidNm = mapidNm; this.geom = geom; 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 6c214497..dd0bcb4c 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 @@ -33,13 +33,12 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport - implements MapSheetMngRepositoryCustom { + implements MapSheetMngRepositoryCustom { private final JPAQueryFactory queryFactory; private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); - @PersistenceContext - private EntityManager em; + @PersistenceContext private EntityManager em; public MapSheetMngRepositoryImpl(JPAQueryFactory queryFactory) { super(MapSheetMngHstEntity.class); @@ -59,121 +58,121 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport NumberExpression totalCount = mapSheetMngHstEntity.count().as("syncTotCnt"); NumberExpression doneCount = - new CaseBuilder() - .when(mapSheetMngHstEntity.dataState.eq("DONE")) - .then(1L) - .otherwise(0L) - .sum() - .as("syncStateDoneCnt"); + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum() + .as("syncStateDoneCnt"); List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngDto.class, - Expressions.numberTemplate( - Integer.class, - "row_number() over(order by {0} desc)", - mapSheetMngEntity.createdDttm), - mapSheetMngEntity.mngYyyy, - mapSheetMngEntity.mngPath, - mapSheetMngEntity.mngState, - mapSheetMngEntity.syncState, - mapSheetMngEntity.syncCheckState, - mapSheetMngHstEntity.count().as("syncTotalCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.dataState.eq("DONE")) - .then(1L) - .otherwise(0L) - .sum() - .as("syncStateDoneCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) - .then(1L) - .otherwise(0L) - .sum(), - mapSheetMngEntity.createdDttm, - mapSheetMngHstEntity.syncEndDttm.max())) - .from(mapSheetMngEntity) - .leftJoin(mapSheetMngHstEntity) - .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) - .where(whereBuilder) - // .offset(pageable.getOffset()) - // .limit(pageable.getPageSize()) - .orderBy(mapSheetMngEntity.mngYyyy.desc()) - .groupBy(mapSheetMngEntity.mngYyyy) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngDto.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} desc)", + mapSheetMngEntity.createdDttm), + mapSheetMngEntity.mngYyyy, + mapSheetMngEntity.mngPath, + mapSheetMngEntity.mngState, + mapSheetMngEntity.syncState, + mapSheetMngEntity.syncCheckState, + mapSheetMngHstEntity.count().as("syncTotalCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum() + .as("syncStateDoneCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) + .then(1L) + .otherwise(0L) + .sum(), + mapSheetMngEntity.createdDttm, + mapSheetMngHstEntity.syncEndDttm.max())) + .from(mapSheetMngEntity) + .leftJoin(mapSheetMngHstEntity) + .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) + .where(whereBuilder) + // .offset(pageable.getOffset()) + // .limit(pageable.getPageSize()) + .orderBy(mapSheetMngEntity.mngYyyy.desc()) + .groupBy(mapSheetMngEntity.mngYyyy) + .fetch(); Long countQuery = - queryFactory - .select(mapSheetMngEntity.mngYyyy.count()) - .from(mapSheetMngEntity) - .where(whereBuilder) - .fetchOne(); + queryFactory + .select(mapSheetMngEntity.mngYyyy.count()) + .from(mapSheetMngEntity) + .where(whereBuilder) + .fetchOne(); return foundContent; } @@ -181,15 +180,15 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport public List findMapSheetMngYyyyList() { List foundContent = - queryFactory - .select(yearEntity.yyyy) - .from(yearEntity) - .leftJoin(mapSheetMngEntity) - .on(mapSheetMngEntity.mngYyyy.eq(yearEntity.yyyy)) - .where(yearEntity.status.eq("NOTYET")) - .orderBy(yearEntity.yyyy.asc()) - .limit(10) - .fetch(); + queryFactory + .select(yearEntity.yyyy) + .from(yearEntity) + .leftJoin(mapSheetMngEntity) + .on(mapSheetMngEntity.mngYyyy.eq(yearEntity.yyyy)) + .where(yearEntity.status.eq("NOTYET")) + .orderBy(yearEntity.yyyy.asc()) + .limit(10) + .fetch(); foundContent.sort(Comparator.reverseOrder()); @@ -198,11 +197,11 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport public void updateYearState(int yyyy, String status) { long execCount = - queryFactory - .update(yearEntity) - .set(yearEntity.status, status) - .where(yearEntity.yyyy.eq(yyyy)) - .execute(); + queryFactory + .update(yearEntity) + .set(yearEntity.status, status) + .where(yearEntity.yyyy.eq(yyyy)) + .execute(); } public MapSheetMngDto.MngDto findMapSheetMng(int mngYyyy) { @@ -211,117 +210,117 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngEntity.mngYyyy.eq(mngYyyy)); MapSheetMngDto.MngDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngDto.class, - Expressions.numberTemplate( - Integer.class, - "row_number() over(order by {0} desc)", - mapSheetMngEntity.createdDttm), - mapSheetMngEntity.mngYyyy, - mapSheetMngEntity.mngPath, - mapSheetMngEntity.mngState, - mapSheetMngEntity.syncState, - mapSheetMngEntity.syncCheckState, - mapSheetMngHstEntity.count().as("syncTotalCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.dataState.eq("DONE")) - .then(1L) - .otherwise(0L) - .sum() - .as("syncStateDoneCnt"), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and( - mapSheetMngHstEntity - .syncState - .eq("TYPEERROR") - .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) - .then(1L) - .otherwise(0L) - .sum(), - new CaseBuilder() - .when( - mapSheetMngHstEntity - .syncCheckState - .eq("DONE") - .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) - .then(1L) - .otherwise(0L) - .sum(), - mapSheetMngEntity.createdDttm, - mapSheetMngHstEntity.syncEndDttm.max())) - .from(mapSheetMngEntity) - .leftJoin(mapSheetMngHstEntity) - .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) - .where(whereBuilder) - .groupBy(mapSheetMngEntity.mngYyyy) - .fetchOne(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngDto.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} desc)", + mapSheetMngEntity.createdDttm), + mapSheetMngEntity.mngYyyy, + mapSheetMngEntity.mngPath, + mapSheetMngEntity.mngState, + mapSheetMngEntity.syncState, + mapSheetMngEntity.syncCheckState, + mapSheetMngHstEntity.count().as("syncTotalCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.dataState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum() + .as("syncStateDoneCnt"), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.ne("NOTYET")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOTPAIR")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOTPAIR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("DUPLICATE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("DUPLICATE"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR"))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and( + mapSheetMngHstEntity + .syncState + .eq("TYPEERROR") + .or(mapSheetMngHstEntity.syncState.eq("SIZEERROR")))) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when(mapSheetMngHstEntity.syncState.eq("NOFILE")) + .then(1L) + .otherwise(0L) + .sum(), + new CaseBuilder() + .when( + mapSheetMngHstEntity + .syncCheckState + .eq("DONE") + .and(mapSheetMngHstEntity.syncState.eq("NOFILE"))) + .then(1L) + .otherwise(0L) + .sum(), + mapSheetMngEntity.createdDttm, + mapSheetMngHstEntity.syncEndDttm.max())) + .from(mapSheetMngEntity) + .leftJoin(mapSheetMngHstEntity) + .on(mapSheetMngEntity.mngYyyy.eq(mapSheetMngHstEntity.mngYyyy)) + .where(whereBuilder) + .groupBy(mapSheetMngEntity.mngYyyy) + .fetchOne(); return foundContent; } @Override public Page findMapSheetErrorList( - MapSheetMngDto.@Valid ErrorSearchReq searchReq) { + MapSheetMngDto.@Valid ErrorSearchReq searchReq) { Pageable pageable = PageRequest.of(searchReq.getPage(), searchReq.getSize()); BooleanBuilder whereBuilder = new BooleanBuilder(); whereBuilder.and(mapSheetMngHstEntity.mngYyyy.eq(searchReq.getMngYyyy())); whereBuilder.and( - mapSheetMngHstEntity.syncState.ne("DONE").and(mapSheetMngHstEntity.syncState.ne("NOTYET"))); + mapSheetMngHstEntity.syncState.ne("DONE").and(mapSheetMngHstEntity.syncState.ne("NOTYET"))); if (searchReq.getSyncState() != null && !searchReq.getSyncState().isEmpty()) { whereBuilder.and(mapSheetMngHstEntity.syncState.eq(searchReq.getSyncState())); @@ -333,70 +332,70 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport if (searchReq.getSearchValue() != null && !searchReq.getSearchValue().isEmpty()) { whereBuilder.and( - mapSheetMngHstEntity - .mapSheetNum - .eq(searchReq.getSearchValue()) - .or(mapSheetMngHstEntity.refMapSheetNum.eq(searchReq.getSearchValue())) - .or( - Expressions.stringTemplate( - "concat({0},substring({1}, 0, 6))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .likeIgnoreCase("%" + searchReq.getSearchValue() + "%")) - .or( - Expressions.stringTemplate( - "concat({0},substring({1}, 6, 8))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .likeIgnoreCase("%" + searchReq.getSearchValue() + "%"))); + mapSheetMngHstEntity + .mapSheetNum + .eq(searchReq.getSearchValue()) + .or(mapSheetMngHstEntity.refMapSheetNum.eq(searchReq.getSearchValue())) + .or( + Expressions.stringTemplate( + "concat({0},substring({1}, 0, 6))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .likeIgnoreCase("%" + searchReq.getSearchValue() + "%")) + .or( + Expressions.stringTemplate( + "concat({0},substring({1}, 6, 8))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .likeIgnoreCase("%" + searchReq.getSearchValue() + "%"))); } List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.ErrorDataDto.class, - mapSheetMngHstEntity.hstUid, - mapSheetMngHstEntity.mngYyyy, - mapSheetMngHstEntity.mapSheetNum, - mapSheetMngHstEntity.refMapSheetNum, - Expressions.stringTemplate( - "concat({0},substring({1}, 0, 6))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .as("map50kName"), - Expressions.stringTemplate( - "concat({0},{1})", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .as("map5kName"), - Expressions.stringTemplate( - "concat({0},substring({1}, 6, 8))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) - .as("mapSrcName"), - mapInkx5kEntity.fid, - mapSheetMngHstEntity.createdDate, - mapSheetMngHstEntity.syncState, - mapSheetMngHstEntity.syncTfwFileName, - mapSheetMngHstEntity.syncTifFileName, - mapSheetMngHstEntity.syncCheckState, - mapSheetMngHstEntity.syncCheckTfwFileName, - mapSheetMngHstEntity.syncCheckTifFileName)) - .from(mapSheetMngHstEntity) - .innerJoin(mapInkx5kEntity) - .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) - .where(whereBuilder) - .orderBy(mapSheetMngHstEntity.createdDate.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.ErrorDataDto.class, + mapSheetMngHstEntity.hstUid, + mapSheetMngHstEntity.mngYyyy, + mapSheetMngHstEntity.mapSheetNum, + mapSheetMngHstEntity.refMapSheetNum, + Expressions.stringTemplate( + "concat({0},substring({1}, 0, 6))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .as("map50kName"), + Expressions.stringTemplate( + "concat({0},{1})", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .as("map5kName"), + Expressions.stringTemplate( + "concat({0},substring({1}, 6, 8))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum) + .as("mapSrcName"), + mapInkx5kEntity.fid, + mapSheetMngHstEntity.createdDate, + mapSheetMngHstEntity.syncState, + mapSheetMngHstEntity.syncTfwFileName, + mapSheetMngHstEntity.syncTifFileName, + mapSheetMngHstEntity.syncCheckState, + mapSheetMngHstEntity.syncCheckTfwFileName, + mapSheetMngHstEntity.syncCheckTifFileName)) + .from(mapSheetMngHstEntity) + .innerJoin(mapInkx5kEntity) + .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) + .where(whereBuilder) + .orderBy(mapSheetMngHstEntity.createdDate.desc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); Long countQuery = - queryFactory - .select(mapSheetMngHstEntity.hstUid.count()) - .from(mapSheetMngHstEntity) - .innerJoin(mapInkx5kEntity) - .on(mapSheetMngHstEntity.mapSheetCode.eq(mapInkx5kEntity.fid)) - .leftJoin(mapInkx50kEntity) - .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid)) - .where(whereBuilder) - .fetchOne(); + queryFactory + .select(mapSheetMngHstEntity.hstUid.count()) + .from(mapSheetMngHstEntity) + .innerJoin(mapInkx5kEntity) + .on(mapSheetMngHstEntity.mapSheetCode.eq(mapInkx5kEntity.fid)) + .leftJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid)) + .where(whereBuilder) + .fetchOne(); return new PageImpl<>(foundContent, pageable, countQuery); } @@ -408,42 +407,42 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngHstEntity.hstUid.eq(hstUid)); MapSheetMngDto.ErrorDataDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.ErrorDataDto.class, - mapSheetMngHstEntity.hstUid, - mapSheetMngHstEntity.mngYyyy, - mapSheetMngHstEntity.mapSheetNum, - mapSheetMngHstEntity.refMapSheetNum, - Expressions.stringTemplate( - "concat({0}, substring({1}, 1, 5))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.ErrorDataDto.class, + mapSheetMngHstEntity.hstUid, + mapSheetMngHstEntity.mngYyyy, + mapSheetMngHstEntity.mapSheetNum, + mapSheetMngHstEntity.refMapSheetNum, + Expressions.stringTemplate( + "concat({0}, substring({1}, 1, 5))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - // ✅ 튜플 방지: concat으로 문자열 생성 - Expressions.stringTemplate( - "concat('(', {0}, ',', {1}, ')')", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - Expressions.stringTemplate( - "concat({0}, substring({1}, 6, 3))", - mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), + // ✅ 튜플 방지: concat으로 문자열 생성 + Expressions.stringTemplate( + "concat('(', {0}, ',', {1}, ')')", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), + Expressions.stringTemplate( + "concat({0}, substring({1}, 6, 3))", + mapInkx5kEntity.mapidNm, mapSheetMngHstEntity.mapSheetNum), - // fid 타입 주의 (Long이면 DTO도 Long으로 맞추는 걸 추천) - mapInkx5kEntity.fid, // 또는 mapInkx5kEntity.fid.intValue() + // fid 타입 주의 (Long이면 DTO도 Long으로 맞추는 걸 추천) + mapInkx5kEntity.fid, // 또는 mapInkx5kEntity.fid.intValue() - // ✅ createdDate 말고 ZonedDateTime으로 매핑된 필드로 - mapSheetMngHstEntity.createdDate, // (예시) - mapSheetMngHstEntity.syncState, - mapSheetMngHstEntity.syncTfwFileName, - mapSheetMngHstEntity.syncTifFileName, - mapSheetMngHstEntity.syncCheckState, - mapSheetMngHstEntity.syncCheckTfwFileName, - mapSheetMngHstEntity.syncCheckTifFileName)) - .from(mapSheetMngHstEntity) - .innerJoin(mapInkx5kEntity) - .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) - .where(whereBuilder) - .fetchOne(); + // ✅ createdDate 말고 ZonedDateTime으로 매핑된 필드로 + mapSheetMngHstEntity.createdDate, // (예시) + mapSheetMngHstEntity.syncState, + mapSheetMngHstEntity.syncTfwFileName, + mapSheetMngHstEntity.syncTifFileName, + mapSheetMngHstEntity.syncCheckState, + mapSheetMngHstEntity.syncCheckTfwFileName, + mapSheetMngHstEntity.syncCheckTifFileName)) + .from(mapSheetMngHstEntity) + .innerJoin(mapInkx5kEntity) + .on(mapSheetMngHstEntity.mapSheetNum.eq(mapInkx5kEntity.mapidcdNo)) + .where(whereBuilder) + .fetchOne(); return foundContent; } @@ -456,22 +455,22 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngFileEntity.fileDel.eq(false)); List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(whereBuilder) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(whereBuilder) + .fetch(); return foundContent; } @@ -483,23 +482,23 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngFileEntity.fileDel.eq(false)); List foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(whereBuilder) - .orderBy(mapSheetMngFileEntity.filePath.asc()) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(whereBuilder) + .orderBy(mapSheetMngFileEntity.filePath.asc()) + .fetch(); return foundContent; } @@ -511,24 +510,24 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport whereBuilder.and(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)); MapSheetMngDto.MngFilesDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(whereBuilder) - .orderBy(mapSheetMngFileEntity.fileUid.desc()) - .limit(1) - .fetchOne(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(whereBuilder) + .orderBy(mapSheetMngFileEntity.fileUid.desc()) + .limit(1) + .fetchOne(); return foundContent; } @@ -537,22 +536,22 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport public MapSheetMngDto.MngFilesDto findByFileUidMapSheetFile(Long fileUid) { MapSheetMngDto.MngFilesDto foundContent = - queryFactory - .select( - Projections.constructor( - MapSheetMngDto.MngFilesDto.class, - mapSheetMngFileEntity.fileUid, - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize)) - .from(mapSheetMngFileEntity) - .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) - .fetchOne(); + queryFactory + .select( + Projections.constructor( + MapSheetMngDto.MngFilesDto.class, + mapSheetMngFileEntity.fileUid, + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize)) + .from(mapSheetMngFileEntity) + .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) + .fetchOne(); return foundContent; } @@ -560,147 +559,147 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport @Override public void MapSheetMngComplete(int mngYyyy) { long execCount = - queryFactory - .update(mapSheetMngEntity) - .set(mapSheetMngEntity.mngState, "COMPLETE") - .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .update(mapSheetMngEntity) + .set(mapSheetMngEntity.mngState, "COMPLETE") + .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void updateMapSheetMngHstSyncCheckState(MapSheetMngDto.SyncCheckStateReqUpdateDto updReq) { long execCount = - queryFactory - .update(mapSheetMngHstEntity) - .set(mapSheetMngHstEntity.syncCheckState, updReq.getSyncCheckState()) - .set(mapSheetMngHstEntity.mapSheetPath, updReq.getFilePath()) - .set(mapSheetMngHstEntity.syncCheckTfwFileName, updReq.getSyncCheckTfwFileName()) - .set(mapSheetMngHstEntity.syncCheckTifFileName, updReq.getSyncCheckTifFileName()) - .set(mapSheetMngHstEntity.syncCheckStrtDttm, ZonedDateTime.now()) - .set(mapSheetMngHstEntity.syncCheckEndDttm, ZonedDateTime.now()) - .where(mapSheetMngHstEntity.hstUid.eq(updReq.getHstUid())) - .execute(); + queryFactory + .update(mapSheetMngHstEntity) + .set(mapSheetMngHstEntity.syncCheckState, updReq.getSyncCheckState()) + .set(mapSheetMngHstEntity.mapSheetPath, updReq.getFilePath()) + .set(mapSheetMngHstEntity.syncCheckTfwFileName, updReq.getSyncCheckTfwFileName()) + .set(mapSheetMngHstEntity.syncCheckTifFileName, updReq.getSyncCheckTifFileName()) + .set(mapSheetMngHstEntity.syncCheckStrtDttm, ZonedDateTime.now()) + .set(mapSheetMngHstEntity.syncCheckEndDttm, ZonedDateTime.now()) + .where(mapSheetMngHstEntity.hstUid.eq(updReq.getHstUid())) + .execute(); } @Override public void deleteByMngYyyyMngAll(int mngYyyy) { long deletedFileCount = - queryFactory - .delete(mapSheetMngFileEntity) - .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngFileEntity) + .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) + .execute(); long deletedHisCount = - queryFactory - .delete(mapSheetMngHstEntity) - .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngHstEntity) + .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) + .execute(); long deletedMngCount = - queryFactory - .delete(mapSheetMngEntity) - .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngEntity) + .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByMngYyyyMng(int mngYyyy) { long deletedMngCount = - queryFactory - .delete(mapSheetMngEntity) - .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngEntity) + .where(mapSheetMngEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByMngYyyyMngHst(int mngYyyy) { long deletedHisCount = - queryFactory - .delete(mapSheetMngHstEntity) - .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngHstEntity) + .where(mapSheetMngHstEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByMngYyyyMngFile(int mngYyyy) { long deletedFileCount = - queryFactory - .delete(mapSheetMngFileEntity) - .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) - .execute(); + queryFactory + .delete(mapSheetMngFileEntity) + .where(mapSheetMngFileEntity.mngYyyy.eq(mngYyyy)) + .execute(); } @Override public void deleteByHstUidMngFile(Long hstUid) { long deletedFileCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileDel, true) - .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileDel, true) + .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) + .execute(); } @Override public void deleteByFileUidMngFile(Long fileUid) { long fileCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileDel, true) - .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileDel, true) + .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) + .execute(); } @Override public void updateByHstUidMngFileState(Long hstUid, String fileState) { long execCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileState, fileState) - .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileState, fileState) + .where(mapSheetMngFileEntity.hstUid.eq(hstUid)) + .execute(); } @Override public void deleteByNotInFileUidMngFile(Long hstUid, List fileUids) { long execCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileDel, true) - .where( - mapSheetMngFileEntity - .hstUid - .eq(hstUid) - .and(mapSheetMngFileEntity.fileUid.notIn(fileUids))) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileDel, true) + .where( + mapSheetMngFileEntity + .hstUid + .eq(hstUid) + .and(mapSheetMngFileEntity.fileUid.notIn(fileUids))) + .execute(); } @Override public void updateByFileUidMngFileState(Long fileUid, String fileState) { long execCount = - queryFactory - .update(mapSheetMngFileEntity) - .set(mapSheetMngFileEntity.fileState, fileState) - .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) - .execute(); + queryFactory + .update(mapSheetMngFileEntity) + .set(mapSheetMngFileEntity.fileState, fileState) + .where(mapSheetMngFileEntity.fileUid.eq(fileUid)) + .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(); + queryFactory + .select(mapSheetMngFileEntity.count()) + .from(mapSheetMngFileEntity) + .where( + mapSheetMngFileEntity + .mngYyyy + .eq(mngYyyy) + .and(mapSheetMngFileEntity.fileName.eq(fileName))) + .fetchOne(); return Math.toIntExact(execCount); } @@ -708,36 +707,36 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport @Override public void mngFileSave(@Valid MapSheetMngDto.MngFileAddReq addReq) { long fileCount = - queryFactory - .insert(mapSheetMngFileEntity) - .columns( - mapSheetMngFileEntity.mngYyyy, - mapSheetMngFileEntity.mapSheetNum, - mapSheetMngFileEntity.refMapSheetNum, - mapSheetMngFileEntity.filePath, - mapSheetMngFileEntity.fileName, - mapSheetMngFileEntity.fileExt, - mapSheetMngFileEntity.hstUid, - mapSheetMngFileEntity.fileSize, - mapSheetMngFileEntity.fileState) - .values( - addReq.getMngYyyy(), - addReq.getMapSheetNum(), - addReq.getRefMapSheetNum(), - addReq.getFilePath(), - addReq.getFileName(), - addReq.getFileExt(), - addReq.getHstUid(), - addReq.getFileSize(), - addReq.getFileState()) - .execute(); + queryFactory + .insert(mapSheetMngFileEntity) + .columns( + mapSheetMngFileEntity.mngYyyy, + mapSheetMngFileEntity.mapSheetNum, + mapSheetMngFileEntity.refMapSheetNum, + mapSheetMngFileEntity.filePath, + mapSheetMngFileEntity.fileName, + mapSheetMngFileEntity.fileExt, + mapSheetMngFileEntity.hstUid, + mapSheetMngFileEntity.fileSize, + mapSheetMngFileEntity.fileState) + .values( + addReq.getMngYyyy(), + addReq.getMapSheetNum(), + addReq.getRefMapSheetNum(), + addReq.getFilePath(), + addReq.getFileName(), + addReq.getFileExt(), + addReq.getHstUid(), + addReq.getFileSize(), + addReq.getFileState()) + .execute(); } @Override public int insertMapSheetOrgDataToMapSheetMngHst(int mngYyyy, String mngPath) { String sql = - """ + """ INSERT INTO tb_map_sheet_mng_hst ( mng_yyyy @@ -777,17 +776,17 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport @Override public Optional findMapSheetMngHstInfo(Long hstUid) { return Optional.ofNullable( - queryFactory - .selectFrom(mapSheetMngHstEntity) - .where(mapSheetMngHstEntity.hstUid.eq(hstUid)) - .fetchOne()); + queryFactory + .selectFrom(mapSheetMngHstEntity) + .where(mapSheetMngHstEntity.hstUid.eq(hstUid)) + .fetchOne()); } @Override public void updateHstFileSizes( - Long hstUid, long tifSizeBytes, long tfwSizeBytes, long totalSizeBytes) { + Long hstUid, long tifSizeBytes, long tfwSizeBytes, long totalSizeBytes) { String sql = - "UPDATE tb_map_sheet_mng_hst SET tif_size_bytes = :tif, tfw_size_bytes = :tfw, total_size_bytes = :tot WHERE hst_uid = :uid"; + "UPDATE tb_map_sheet_mng_hst SET tif_size_bytes = :tif, tfw_size_bytes = :tfw, total_size_bytes = :tot WHERE hst_uid = :uid"; Query query = (Query) em.createNativeQuery(sql); query.setParameter("tif", tifSizeBytes); query.setParameter("tfw", tfwSizeBytes); @@ -798,7 +797,7 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport private NumberExpression rowNum() { return Expressions.numberTemplate( - Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate); + Integer.class, "row_number() over(order by {0} desc)", mapSheetMngHstEntity.createdDate); } private BooleanExpression mapSheetErrorSearchValue(MapSheetMngDto.ErrorSearchReq searchReq) { @@ -808,10 +807,10 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport // 검색어 1개 값이 도엽명 or 도엽번호 like 검색 return Expressions.booleanTemplate( - "{0} like '%" + searchReq.getSearchValue() + "%'", mapSheetMngHstEntity.mapSheetName) - .or( - Expressions.booleanTemplate( - "{0} like '%" + searchReq.getSearchValue() + "%'", - mapSheetMngHstEntity.mapSheetNum)); + "{0} like '%" + searchReq.getSearchValue() + "%'", mapSheetMngHstEntity.mapSheetName) + .or( + Expressions.booleanTemplate( + "{0} like '%" + searchReq.getSearchValue() + "%'", + mapSheetMngHstEntity.mapSheetNum)); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java index 5412d4ef..88531ad1 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java @@ -21,7 +21,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport - implements MapInkx5kRepositoryCustom { + implements MapInkx5kRepositoryCustom { private final JPAQueryFactory queryFactory; @@ -34,53 +34,53 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport QMapInkx5kEntity map5k = QMapInkx5kEntity.mapInkx5kEntity; return queryFactory - .selectFrom(map5k) - .where(map5k.mapidcdNo.in(codes)) - .orderBy(map5k.mapidcdNo.asc()) - .fetch(); + .selectFrom(map5k) + .where(map5k.mapidcdNo.in(codes)) + .orderBy(map5k.mapidcdNo.asc()) + .fetch(); } @Override public Page findMapInkxMngList( - searchReq searchReq, String useInference, String searchVal) { + searchReq searchReq, String useInference, String searchVal) { Pageable pageable = searchReq.toPageable(); List foundContent = - queryFactory - .select( - Projections.constructor( - MapInkxMngDto.MapList.class, - Expressions.numberTemplate( - Integer.class, - "row_number() over(order by {0} asc)", - mapInkx5kEntity.mapidcdNo), - mapInkx5kEntity.mapidcdNo, - mapInkx50kEntity.mapidcdNo, - mapInkx5kEntity.mapidNm, - mapInkx5kEntity.createdDate, - mapInkx5kEntity.modifiedDate, - // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", - // mapInkx5kEntity.createdDate), - // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", - // mapInkx5kEntity.modifiedDate), - mapInkx5kEntity.useInference)) - .from(mapInkx5kEntity) - .innerJoin(mapInkx50kEntity) - .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid)) - .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .orderBy(mapInkx5kEntity.mapidcdNo.asc()) - .fetch(); + queryFactory + .select( + Projections.constructor( + MapInkxMngDto.MapList.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} asc)", + mapInkx5kEntity.mapidcdNo), + mapInkx5kEntity.mapidcdNo, + mapInkx50kEntity.mapidcdNo, + mapInkx5kEntity.mapidNm, + mapInkx5kEntity.createdDate, + mapInkx5kEntity.modifiedDate, + // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", + // mapInkx5kEntity.createdDate), + // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", + // mapInkx5kEntity.modifiedDate), + mapInkx5kEntity.useInference)) + .from(mapInkx5kEntity) + .innerJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.eq(mapInkx50kEntity.fid)) + .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(mapInkx5kEntity.mapidcdNo.asc()) + .fetch(); Long countQuery = - queryFactory - .select(mapInkx5kEntity.count()) - .from(mapInkx5kEntity) - .innerJoin(mapInkx50kEntity) - .on(mapInkx5kEntity.fidK50.intValue().eq(mapInkx50kEntity.fid)) - .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) - .fetchOne(); + queryFactory + .select(mapInkx5kEntity.count()) + .from(mapInkx5kEntity) + .innerJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.intValue().eq(mapInkx50kEntity.fid)) + .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) + .fetchOne(); return new PageImpl<>(foundContent, pageable, countQuery); } @@ -88,19 +88,19 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport @Override public Long findByMapidCdNoExists(String mapidcdNo) { return queryFactory - .select(mapInkx5kEntity.count()) - .from(mapInkx5kEntity) - .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) - .fetchOne(); + .select(mapInkx5kEntity.count()) + .from(mapInkx5kEntity) + .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) + .fetchOne(); } @Override public Optional findByMapidCdNoInfo(String mapidcdNo) { return Optional.ofNullable( - queryFactory - .selectFrom(mapInkx5kEntity) - .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) - .fetchOne()); + queryFactory + .selectFrom(mapInkx5kEntity) + .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) + .fetchOne()); } private BooleanExpression searchUseInference(String useInference) { @@ -115,8 +115,8 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport return null; } return mapInkx5kEntity - .mapidcdNo - .like("%" + searchVal + "%") - .or(mapInkx5kEntity.mapidNm.like("%" + searchVal + "%")); + .mapidcdNo + .like("%" + searchVal + "%") + .or(mapInkx5kEntity.mapidNm.like("%" + searchVal + "%")); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java index 992cf071..635943f1 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java @@ -72,28 +72,28 @@ public class MapInkxMngDto { // 목록 Querydsl 에서 리턴 받는 건 생성자 기준임 -> 쿼리 컬럼 그대로 받고 여기서 Java 형변환 해서 return 하기 public MapList( - Integer rowNum, - String mapidcdNo5k, - String mapidcdNo50k, - String mapidNm, - ZonedDateTime createdDttmTime, - ZonedDateTime updatedDttmTime, - String useInference) { + Integer rowNum, + String mapidcdNo5k, + String mapidcdNo50k, + String mapidNm, + ZonedDateTime createdDttmTime, + ZonedDateTime updatedDttmTime, + String useInference) { this.rowNum = rowNum; this.mapidcdNo5k = mapidcdNo5k; this.mapidcdNo50k = mapidcdNo50k; this.mapidNm = mapidNm; DateTimeFormatter fmt = - DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Seoul")); + DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Seoul")); this.createdDttm = fmt.format(createdDttmTime); this.updatedDttm = fmt.format(updatedDttmTime); this.createdDttmTime = createdDttmTime; this.updatedDttmTime = updatedDttmTime; this.useInference = - useInference.equals("USE") - ? UseInferenceType.USE.getDesc() - : UseInferenceType.EXCEPT.getDesc(); + useInference.equals("USE") + ? UseInferenceType.USE.getDesc() + : UseInferenceType.EXCEPT.getDesc(); } } @@ -114,7 +114,7 @@ public class MapInkxMngDto { 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); @@ -135,12 +135,12 @@ public class MapInkxMngDto { private String mapidNm; @Schema( - description = "좌표 목록 (한 줄에 한 점, '경도 위도' 형식)", - example = - "127.17500001632317 36.17499998262991\n" - + "127.14999995475043 36.17500002877932\n" - + "127.15000004313612 36.199999984012415\n" - + "127.1750000466954 36.20000001863179") + description = "좌표 목록 (한 줄에 한 점, '경도 위도' 형식)", + example = + "127.17500001632317 36.17499998262991\n" + + "127.14999995475043 36.17500002877932\n" + + "127.15000004313612 36.199999984012415\n" + + "127.1750000466954 36.20000001863179") private String coordinates; } From 770f28647e73ef944c9b24cd391d52890164a43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Tue, 30 Dec 2025 10:27:52 +0900 Subject: [PATCH 24/28] feat: polishing --- .../com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java index 533fbc19..caa995a6 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java @@ -79,7 +79,7 @@ public class MapInkxMngDto { String mapidNm, ZonedDateTime createdDttmTime, ZonedDateTime updatedDttmTime, - String useInference) { + CommonUseStatus useInference) { this.rowNum = rowNum; this.mapidcdNo5k = mapidcdNo5k; this.mapidcdNo50k = mapidcdNo50k; @@ -91,10 +91,7 @@ public class MapInkxMngDto { this.updatedDttm = fmt.format(updatedDttmTime); this.createdDttmTime = createdDttmTime; this.updatedDttmTime = updatedDttmTime; - this.useInference = - useInference.equals("USE") - ? UseInferenceType.USE.getDesc() - : UseInferenceType.EXCEPT.getDesc(); + this.useInference = useInference.getId(); } } From 98f5a6fa8400011e8b9b4f75e8b2e925028fb03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Tue, 30 Dec 2025 11:07:04 +0900 Subject: [PATCH 25/28] fix: sceneapi error remove fetchjoin --- .../postgres/repository/scene/MapInkx5kRepositoryImpl.java | 2 -- .../com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java index 9e34a467..6485e9c1 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java @@ -67,7 +67,6 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport mapInkx5kEntity.useInference)) .from(mapInkx5kEntity) .innerJoin(mapInkx5kEntity.mapInkx50k, mapInkx50kEntity) - .fetchJoin() .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -79,7 +78,6 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport .select(mapInkx5kEntity.count()) .from(mapInkx5kEntity) .innerJoin(mapInkx5kEntity.mapInkx50k, mapInkx50kEntity) - .fetchJoin() .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) .fetchOne(); diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java b/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java index d1018323..3648e707 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java @@ -47,7 +47,7 @@ public class MapInkxMngApiController { }) @GetMapping public ApiResponseDto> findMapInkxMngList( - @RequestParam int page, + @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size, @RequestParam(required = false) CommonUseStatus useInference, @RequestParam(required = false) String searchVal) { From 412f4a0d5e2682b627d1727aa05e3a8b95ec36ff Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 30 Dec 2025 11:28:52 +0900 Subject: [PATCH 26/28] =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/MenuAuthorizationManager.java | 37 +++++++++++++++++-- .../cd/kamcoback/config/SecurityConfig.java | 5 ++- .../repository/menu/MenuRepositoryCustom.java | 8 ++++ .../repository/menu/MenuRepositoryImpl.java | 17 +++++++++ 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java b/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java index 0cc3db39..021332e9 100644 --- a/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java +++ b/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java @@ -45,19 +45,50 @@ public class MenuAuthorizationManager implements AuthorizationManager allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role); + boolean isAdmin = "ADMIN".equalsIgnoreCase(role); + // URL별 권한 조회 + List matchedMenus = menuAuthQueryRepository.findMenusByRequestPath(requestPath); + + boolean isProtectedUrl = matchedMenus != null && !matchedMenus.isEmpty(); + + // URL별 권한에 라벨러, 검수자 권한이 있으면 , ADMIN도 false + if (isProtectedUrl) { + List allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role); + if (allowedMenus == null || allowedMenus.isEmpty()) { + return new AuthorizationDecision(false); + } + + for (MenuEntity menu : allowedMenus) { + String baseUri = menu.getMenuUrl(); + if (baseUri == null || baseUri.isBlank()) { + continue; + } + + if (matchUri(baseUri, requestPath)) { + return new AuthorizationDecision(true); + } + } + return new AuthorizationDecision(false); + } + + // ✅ 3) 보호 URL이 아니면 ADMIN은 전부 허용 + if (isAdmin) { + return new AuthorizationDecision(true); + } + + // ✅ 4) 일반 role은 기존대로 매핑 기반 + List allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role); if (allowedMenus == null || allowedMenus.isEmpty()) { return new AuthorizationDecision(false); } - // menu_url(prefix) 기반 접근 허용 판단 for (MenuEntity menu : allowedMenus) { String baseUri = menu.getMenuUrl(); if (baseUri == null || baseUri.isBlank()) { continue; } + if (matchUri(baseUri, requestPath)) { return new AuthorizationDecision(true); } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java index 1acaf5f4..dca50109 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java @@ -83,9 +83,10 @@ public class SecurityConfig { .requestMatchers("/api/user/**") .authenticated() .anyRequest() - // .access(redisAuthorizationManager) + .access(menuAuthorizationManager) - .authenticated()) + // .authenticated() + ) .addFilterBefore( jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java index 775ff647..c1e7db63 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryCustom.java @@ -22,4 +22,12 @@ public interface MenuRepositoryCustom { * @return */ List findAllowedMenuUrlsByRole(String role); + + /** + * url별 역할 + * + * @param requestPath + * @return + */ + List findMenusByRequestPath(String requestPath); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java index 62a91213..b4919fd4 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/menu/MenuRepositoryImpl.java @@ -79,4 +79,21 @@ public class MenuRepositoryImpl implements MenuRepositoryCustom { .orderBy(menuEntity.menuOrder.asc().nullsLast()) .fetch(); } + + @Override + public List findMenusByRequestPath(String requestPath) { + return queryFactory + .selectDistinct(menuEntity) + .from(menuMappEntity) + .join(menuMappEntity.menuUid, menuEntity) + .where( + menuMappEntity.deleted.isFalse(), + menuEntity.deleted.isFalse(), + menuEntity.isUse.isTrue(), + menuEntity.menuUrl.isNotNull(), + menuEntity.menuUrl.isNotEmpty(), + menuEntity.menuUrl.eq(requestPath)) + .orderBy(menuEntity.menuOrder.asc().nullsLast()) + .fetch(); + } } From 03231775fddf8dae5dea6cfc4ca1ff5cf3840efa Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 30 Dec 2025 15:12:10 +0900 Subject: [PATCH 27/28] =?UTF-8?q?shp=20=ED=8C=8C=EC=9D=BC=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20baseurl=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20=EC=B6=94=EB=A1=A0=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/auth/MenuAuthorizationManager.java | 11 ++++------- .../inference/service/InferenceResultShpService.java | 7 ++++--- .../entity/MapSheetAnalDataInferenceGeomEntity.java | 6 ++++++ src/main/resources/application-dev.yml | 2 ++ src/main/resources/application-local.yml | 6 ++++++ src/main/resources/application-prod.yml | 6 +++++- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java b/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java index 021332e9..a9e8b11c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java +++ b/src/main/java/com/kamco/cd/kamcoback/auth/MenuAuthorizationManager.java @@ -1,13 +1,12 @@ package com.kamco.cd.kamcoback.auth; +import com.kamco.cd.kamcoback.common.enums.RoleType; import com.kamco.cd.kamcoback.postgres.entity.MenuEntity; import com.kamco.cd.kamcoback.postgres.repository.menu.MenuRepository; import jakarta.servlet.http.HttpServletRequest; import java.util.List; import java.util.function.Supplier; import lombok.RequiredArgsConstructor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.core.Authentication; @@ -24,8 +23,6 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class MenuAuthorizationManager implements AuthorizationManager { - private static final Logger log = LogManager.getLogger(MenuAuthorizationManager.class); - private final MenuRepository menuAuthQueryRepository; @Override @@ -45,7 +42,7 @@ public class MenuAuthorizationManager implements AuthorizationManager matchedMenus = menuAuthQueryRepository.findMenusByRequestPath(requestPath); @@ -72,12 +69,12 @@ public class MenuAuthorizationManager implements AuthorizationManager allowedMenus = menuAuthQueryRepository.findAllowedMenuUrlsByRole(role); if (allowedMenus == null || allowedMenus.isEmpty()) { return new AuthorizationDecision(false); diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java index 6a578e32..980a5a22 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java @@ -5,6 +5,7 @@ import com.kamco.cd.kamcoback.inference.dto.WriteCnt; import com.kamco.cd.kamcoback.postgres.core.InferenceResultShpCoreService; import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,6 +17,9 @@ public class InferenceResultShpService { private final InferenceResultShpCoreService coreService; private final ShpWriter shpWriter; + @Value("${mapsheet.shp.baseurl}") + private String baseDir; + /** inference_results 테이블을 기준으로 분석 결과 테이블과 도형 테이블을 최신 상태로 반영한다. */ @Transactional public InferenceResultShpDto.InferenceCntDto saveInferenceResultData() { @@ -33,9 +37,6 @@ public class InferenceResultShpService { @Transactional public InferenceResultShpDto.FileCntDto createShpFile() { - // TODO 파일 경로는 정해지면 수정, properties 사용 - String baseDir = "/app/detect/result"; - // TODO 배치 실행으로 변경 필요 int batchSize = 100; int geomLimit = 500_000; diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetAnalDataInferenceGeomEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetAnalDataInferenceGeomEntity.java index 7ce986d6..f41d8191 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetAnalDataInferenceGeomEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetAnalDataInferenceGeomEntity.java @@ -146,4 +146,10 @@ public class MapSheetAnalDataInferenceGeomEntity { @Column(name = "file_created_dttm") private ZonedDateTime fileCreatedDttm; + + @Column(name = "pass_yn") + private Boolean passYn; + + @Column(name = "pass_yn_dttm") + private ZonedDateTime passYnDttm; } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 6c7b17f0..4a00ed71 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -73,4 +73,6 @@ logging: mapsheet: upload: skipGdalValidation: true + shp: + baseurl: /app/detect/result diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 0889d7ff..37250f1e 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -53,3 +53,9 @@ token: springdoc: swagger-ui: persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장 + +mapsheet: + upload: + skipGdalValidation: true + shp: + baseurl: /Users/bokmin/detect/result diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index e989c2b4..7c633ecd 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -30,5 +30,9 @@ token: refresh-cookie-name: kamco # 개발용 쿠키 이름 refresh-cookie-secure: true # 로컬 http 테스트면 false - +mapsheet: + upload: + skipGdalValidation: true + shp: + baseurl: /app/detect/result From ff2c54d38e117f9071ad7d64ab90a7f796d51e74 Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 30 Dec 2025 18:32:21 +0900 Subject: [PATCH 28/28] =?UTF-8?q?=EC=9D=B4=EB=85=B8=ED=8E=A8=20=EB=AA=A9?= =?UTF-8?q?=EC=97=85=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Innopam/InnopamApiController.java | 145 ++++++++++++++++++ .../kamcoback/Innopam/dto/DetectMastDto.java | 91 +++++++++++ .../postgres/core/DetectMastCoreService.java | 62 ++++++++ .../postgres/entity/DetectMastEntity.java | 85 ++++++++++ .../repository/DetectMastRepository.java | 7 + .../DetectMastRepositoryCustom.java | 12 ++ .../repository/DetectMastRepositoryImpl.java | 59 +++++++ .../Innopam/service/DetectMastService.java | 59 +++++++ 8 files changed, 520 insertions(+) create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/InnopamApiController.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/dto/DetectMastDto.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/core/DetectMastCoreService.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/entity/DetectMastEntity.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepository.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryCustom.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryImpl.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/Innopam/service/DetectMastService.java diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/InnopamApiController.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/InnopamApiController.java new file mode 100644 index 00000000..13bd6456 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/InnopamApiController.java @@ -0,0 +1,145 @@ +package com.kamco.cd.kamcoback.Innopam; + +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.Basic; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastReq; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch; +import com.kamco.cd.kamcoback.Innopam.service.DetectMastService; +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 jakarta.validation.Valid; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "이노펨 mockup API", description = "이노펨 mockup API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/kcd/cdi/detect") +public class InnopamApiController { + + private final DetectMastService detectMastService; + + /** 탐지결과 등록 */ + @Operation(summary = "탐지결과 등록", description = "탐지결과 등록") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = DetectMastReq.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @PostMapping("/mast/regist") + public DetectMastReq setChangeDetection( + @RequestBody @Valid DetectMastDto.DetectMastReq detectMast) { + detectMastService.saveDetectMast(detectMast); + return detectMast; + } + + @Operation(summary = "탐지결과 삭제", description = "탐지결과 삭제") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = DetectMastReq.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @PostMapping("/mast/remove") + public String deleteChangeDetection(@RequestBody DetectMastReq detectMast) { + return "OK"; + } + + @Operation(summary = "탐지결과 등록목록 조회", description = "탐지결과 등록목록 조회") + @GetMapping("/mast/list") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + public List selectChangeDetectionList( + @RequestParam(required = false) String cprsBfYr, + @RequestParam(required = false) String cprsAdYr, + @RequestParam(required = false) Integer dtctSno) { + DetectMastSearch detectMastSearch = new DetectMastSearch(); + detectMastSearch.setCprsAdYr(cprsAdYr); + detectMastSearch.setCprsBfYr(cprsBfYr); + detectMastSearch.setDtctSno(dtctSno); + return detectMastService.selectDetectMast(detectMastSearch); + } + + @Operation(summary = "탐지결과 등록목록 상세 조회", description = "탐지결과 등록목록 상세 조회") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping("/mast/list/{dtctMstId}") + public Basic selectChangeDetectionDetail(@PathVariable Long dtctMstId) { + return detectMastService.selectDetectMast(dtctMstId); + } + + @Operation(summary = "탐지객체 PNU 리스트 조회", description = "탐지객체 PNU 리스트 조회") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}") + public void selectPnuList( + @PathVariable String cprsBfYr, @PathVariable String cprsAfYr, @PathVariable String dtctSno) { + DetectMastSearch detectMastSearch = new DetectMastSearch(); + detectMastSearch.setCprsAdYr(cprsAfYr); + detectMastSearch.setCprsBfYr(cprsBfYr); + detectMastSearch.setDtctSno(Integer.parseInt(dtctSno)); + detectMastService.findPnuData(detectMastSearch); + } + + /** + * 탐지객체 PNU 단건 조회 + * + * @param detectMast + */ + @GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}/{featureId}") + public void selectPnuDetail(@RequestBody DetectMastDto detectMast) {} +} diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/dto/DetectMastDto.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/dto/DetectMastDto.java new file mode 100644 index 00000000..77ef145e --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/dto/DetectMastDto.java @@ -0,0 +1,91 @@ +package com.kamco.cd.kamcoback.Innopam.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class DetectMastDto { + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class Basic { + + private Long dtctMstId; + private String cprsBfYr; + private String cprsAdYr; + private Integer dtctSno; + private String pathNm; + private String crtEpno; + private String crtIp; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class DetectMastReq { + + @NotBlank + @Schema(description = "before 연도", example = "2023") + private String cprsBfYr; + + @NotBlank + @Schema(description = "after 연도", example = "2024") + private String cprsAdYr; + + @NotBlank + @Schema(description = "차수(회차)", example = "4") + private Integer dtctSno; + + @NotBlank + @Schema(description = "파일경로", example = "/app/detect/result/2023_2024/4") + private String pathNm; + + @NotBlank + @Schema(description = "사원번호", example = "1234567") + private String crtEpno; + + @NotBlank + @Schema(description = "아이피", example = "0.0.0.0") + private String crtIp; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class DetectMastSearch { + + private String cprsBfYr; + private String cprsAdYr; + private Integer dtctSno; + private String featureId; + } + + /** before 연도 */ + private String cprsBfYr; + + /** after 연도 */ + private String cprsAdYr; + + /** 차수 */ + private Integer dtctSno; + + /** shp 파일경로 */ + private String pathNm; + + /** 등록한 사람 사번 */ + private String crtEpno; + + /** 등록한 사람 ip */ + private String crtIp; +} diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/core/DetectMastCoreService.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/core/DetectMastCoreService.java new file mode 100644 index 00000000..6125209b --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/core/DetectMastCoreService.java @@ -0,0 +1,62 @@ +package com.kamco.cd.kamcoback.Innopam.postgres.core; + +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.Basic; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastReq; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch; +import com.kamco.cd.kamcoback.Innopam.postgres.entity.DetectMastEntity; +import com.kamco.cd.kamcoback.Innopam.postgres.repository.DetectMastRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class DetectMastCoreService { + + private final DetectMastRepository detectMastRepository; + + public void saveDetectMast(DetectMastReq detectMast) { + DetectMastEntity detectMastEntity = new DetectMastEntity(); + detectMastEntity.setCprsBfYr(detectMast.getCprsBfYr()); + detectMastEntity.setCprsAdYr(detectMast.getCprsAdYr()); + detectMastEntity.setDtctSno(detectMast.getDtctSno()); + detectMastEntity.setPathNm(detectMast.getPathNm()); + detectMastEntity.setCrtEpno(detectMast.getCrtEpno()); + detectMastEntity.setCrtIp(detectMast.getCrtIp()); + detectMastRepository.save(detectMastEntity); + } + + public List selectDetectMast(DetectMastSearch detectMast) { + return detectMastRepository.findDetectMastList(detectMast).stream() + .map( + e -> + new DetectMastDto.Basic( + e.getId(), + e.getCprsBfYr(), + e.getCprsAdYr(), + e.getDtctSno(), + e.getPathNm(), + e.getCrtEpno(), + e.getCrtIp())) + .toList(); + } + + public Basic selectDetectMast(Long id) { + DetectMastEntity e = + detectMastRepository.findById(id).orElseThrow(() -> new RuntimeException("등록 데이터가 없습니다.")); + return new DetectMastDto.Basic( + e.getId(), + e.getCprsBfYr(), + e.getCprsAdYr(), + e.getDtctSno(), + e.getPathNm(), + e.getCrtEpno(), + e.getCrtIp()); + } + + public String findPnuData(DetectMastSearch detectMast) { + DetectMastEntity detectMastEntity = detectMastRepository.findPnuData(detectMast); + return detectMastEntity.getPathNm(); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/entity/DetectMastEntity.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/entity/DetectMastEntity.java new file mode 100644 index 00000000..5d326b83 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/entity/DetectMastEntity.java @@ -0,0 +1,85 @@ +package com.kamco.cd.kamcoback.Innopam.postgres.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.ZonedDateTime; +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.ColumnDefault; + +@Getter +@Setter +@Entity +@Table(name = "detect_mast") +public class DetectMastEntity { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "detect_mast_id_gen") + @SequenceGenerator( + name = "detect_mast_id_gen", + sequenceName = "seq_detect_mast_id", + allocationSize = 1) + @Column(name = "dtct_mst_id", nullable = false) + private Long id; + + @NotNull + @ColumnDefault("gen_random_uuid()") + @Column(name = "dtct_mst_uuid", nullable = false) + private UUID dtctMstUuid = UUID.randomUUID(); + + @Size(max = 4) + @NotNull + @Column(name = "cprs_bf_yr", nullable = false, length = 4) + private String cprsBfYr; + + @Size(max = 4) + @NotNull + @Column(name = "cprs_ad_yr", nullable = false, length = 4) + private String cprsAdYr; + + @NotNull + @Column(name = "dtct_sno", nullable = false) + private Integer dtctSno; + + @NotNull + @Column(name = "path_nm", nullable = false, length = Integer.MAX_VALUE) + private String pathNm; + + @Size(max = 50) + @Column(name = "feature_id", length = 50) + private String featureId; + + @Size(max = 30) + @NotNull + @Column(name = "crt_epno", nullable = false, length = 30) + private String crtEpno; + + @Size(max = 45) + @NotNull + @Column(name = "crt_ip", nullable = false, length = 45) + private String crtIp; + + @NotNull + @ColumnDefault("now()") + @Column(name = "crt_dttm", nullable = false) + private ZonedDateTime crtDttm = ZonedDateTime.now(); + + @Size(max = 30) + @Column(name = "chg_epno", length = 30) + private String chgEpno; + + @Size(max = 45) + @Column(name = "chg_ip", length = 45) + private String chgIp; + + @Column(name = "chg_dttm") + private ZonedDateTime chgDttm; +} diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepository.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepository.java new file mode 100644 index 00000000..c6aa24f3 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepository.java @@ -0,0 +1,7 @@ +package com.kamco.cd.kamcoback.Innopam.postgres.repository; + +import com.kamco.cd.kamcoback.Innopam.postgres.entity.DetectMastEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DetectMastRepository + extends JpaRepository, DetectMastRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryCustom.java new file mode 100644 index 00000000..93ce4fb4 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryCustom.java @@ -0,0 +1,12 @@ +package com.kamco.cd.kamcoback.Innopam.postgres.repository; + +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch; +import com.kamco.cd.kamcoback.Innopam.postgres.entity.DetectMastEntity; +import java.util.List; + +public interface DetectMastRepositoryCustom { + + public List findDetectMastList(DetectMastSearch detectMast); + + public DetectMastEntity findPnuData(DetectMastSearch detectMast); +} diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryImpl.java new file mode 100644 index 00000000..c2c658e2 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/postgres/repository/DetectMastRepositoryImpl.java @@ -0,0 +1,59 @@ +package com.kamco.cd.kamcoback.Innopam.postgres.repository; + +import static com.kamco.cd.kamcoback.Innopam.postgres.entity.QDetectMastEntity.detectMastEntity; + +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch; +import com.kamco.cd.kamcoback.Innopam.postgres.entity.DetectMastEntity; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class DetectMastRepositoryImpl implements DetectMastRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + @Override + public List findDetectMastList(DetectMastSearch detectMast) { + + BooleanBuilder whereBuilder = new BooleanBuilder(); + + if (StringUtils.isNotBlank(detectMast.getCprsAdYr())) { + whereBuilder.and(detectMastEntity.cprsAdYr.eq(detectMast.getCprsAdYr())); + } + + if (StringUtils.isNotBlank(detectMast.getCprsBfYr())) { + whereBuilder.and(detectMastEntity.cprsBfYr.eq(detectMast.getCprsBfYr())); + } + + if (detectMast.getDtctSno() != null) { + whereBuilder.and(detectMastEntity.dtctSno.eq(detectMast.getDtctSno())); + } + + return queryFactory.select(detectMastEntity).from(detectMastEntity).where(whereBuilder).fetch(); + } + + @Override + public DetectMastEntity findPnuData(DetectMastSearch detectMast) { + + BooleanBuilder whereBuilder = new BooleanBuilder(); + + whereBuilder.and(detectMastEntity.cprsAdYr.eq(detectMast.getCprsAdYr())); + whereBuilder.and(detectMastEntity.cprsBfYr.eq(detectMast.getCprsBfYr())); + whereBuilder.and(detectMastEntity.dtctSno.eq(detectMast.getDtctSno())); + + if (detectMast.getFeatureId() != null) { + whereBuilder.and(detectMastEntity.featureId.eq(detectMast.getFeatureId())); + } + + return queryFactory + .select(detectMastEntity) + .from(detectMastEntity) + .where(whereBuilder) + .fetchOne(); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/Innopam/service/DetectMastService.java b/src/main/java/com/kamco/cd/kamcoback/Innopam/service/DetectMastService.java new file mode 100644 index 00000000..9b1c9d08 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/Innopam/service/DetectMastService.java @@ -0,0 +1,59 @@ +package com.kamco.cd.kamcoback.Innopam.service; + +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.Basic; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastReq; +import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch; +import com.kamco.cd.kamcoback.Innopam.postgres.core.DetectMastCoreService; +import java.io.File; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class DetectMastService { + + private final DetectMastCoreService detectMastCoreService; + + @Transactional + public void saveDetectMast(DetectMastReq detectMast) { + detectMastCoreService.saveDetectMast(detectMast); + } + + public List selectDetectMast(DetectMastSearch detectMast) { + return detectMastCoreService.selectDetectMast(detectMast); + } + + public Basic selectDetectMast(Long id) { + return detectMastCoreService.selectDetectMast(id); + } + + public void findPnuData(DetectMastSearch detectMast) { + String pathNm = detectMastCoreService.findPnuData(detectMast); + + File dir = new File(pathNm); + if (dir.exists() && dir.isDirectory()) { + File[] files = dir.listFiles(); + + if (files != null) { + for (File file : files) { + System.out.println(file.getName()); + } + } + } + } + + public static String randomPnu() { + ThreadLocalRandom r = ThreadLocalRandom.current(); + + String lawCode = String.valueOf(r.nextLong(1000000000L, 9999999999L)); // 10자리 + String sanFlag = r.nextBoolean() ? "1" : "2"; // 산/대지 + String bon = String.format("%04d", r.nextInt(1, 10000)); // 본번 + String bu = String.format("%04d", r.nextInt(0, 10000)); // 부번 + + return lawCode + sanFlag + bon + bu; + } +}