From 154bc11007acdb417c34480c05d3d4ef2be0e3f5 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, 5 Jan 2026 18:01:38 +0900 Subject: [PATCH 1/7] =?UTF-8?q?change=20=EA=B3=B5=EC=9C=A0=ED=8F=B4?= =?UTF-8?q?=EB=8D=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose-dev.yml | 1 + src/main/resources/application.yml | 3 +- src/main/resources/etc/AI_INFERENCE.http | 96 ++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/etc/AI_INFERENCE.http diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 60706853..40b43467 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -19,6 +19,7 @@ services: - /mnt/nfs_share/model_output:/app/model-outputs - /mnt/nfs_share/train_dataset:/app/train-dataset - /mnt/nfs_share/tmp:/app/tmp + - /kamco-nfs:/kamco-nfs networks: - kamco-cds restart: unless-stopped diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a5036d99..ffeb27eb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -67,6 +67,7 @@ management: file: #sync-root-dir: D:/app/original-images/ - sync-root-dir: /app/original-images/ + # sync-root-dir: /app/original-images/ + sync-root-dir: /kamco-nfs/images/ sync-tmp-dir: ${file.sync-root-dir}/tmp sync-file-extention: tfw,tif diff --git a/src/main/resources/etc/AI_INFERENCE.http b/src/main/resources/etc/AI_INFERENCE.http new file mode 100644 index 00000000..3c329430 --- /dev/null +++ b/src/main/resources/etc/AI_INFERENCE.http @@ -0,0 +1,96 @@ +# create job + +POST /jobs HTTP/1.1 +Host: 10.100.0.11:8000 +accept: application/json +Content-Type: application/json +Content-Length: 565 + +{ + "pred_requests_areas": { + "input1_year": 2023, + "input2_year": 2024, + "input1_scene_path": "/kamco-nfs/requests/2023_local.geojson", + "input2_scene_path": "/kamco-nfs/requests/2024_local.geojson" + }, + "model_version": "v1-2-test", + "cd_model_path": "/data/shared-dir/cd-checkpoints/v5/cdv5-model3/best_changed_fscore_epoch_11.pth", + "cd_model_config": "/data/shared-dir/cd-checkpoints/v5/cdv5-model3/rvsa-base-and-large-unet-mae-kamco.py", + "cls_model_path": "", + "cls_model_version": "v1-2-test", + "cd_model_type": "G1", + "priority": 0 +} + + + +//G1 +//{ +// "pred_requests_areas": { +// "input1_year": "2022", +// "input2_year": "2023", +// "areas": ["34602060", "35615072", "35813026"] +// }, +// "model_version": "v1-2-test", +// "cd_model_path": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G1/best_changed_fscore_epoch_53.pth", +// "cd_model_config": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G1/rvsa-base-and-large-unet-mae-kamco.py", +// "cls_model_path": "", +// "cls_model_version": "v1-2-test", +// "cd_model_type": "G1", +// "priority": 0 +//} + +//G2: +//{ +//"pred_requests_areas": { +//"input1_year": "2022", +//"input2_year": "2023", +//"areas": ["34602060", "35615072", "35813026"] +//}, +//"model_version": "v1-2-test", +//"cd_model_path": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G2/best_changed_fscore_epoch_40.pth", +//"cd_model_config": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G2/rvsa-base-and-large-unet-mae-kamco.py", +//"cls_model_path": "", +//"cls_model_version": "v1-2-test", +//"cd_model_type": "G2", +//"priority": 0 +//} +// +//G3: +//{ +//"pred_requests_areas": { +//"input1_year": "2022", +//"input2_year": "2023", +//"areas": ["34602060", "35615072", "35813026"] +//}, +//"model_version": "v1-2-test", +//"cd_model_path": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G3/best_changed_fscore_epoch_13.pth", +//"cd_model_config": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G3/rvsa-base-and-large-unet-mae-kamco.py", +//"cls_model_path": "", +//"cls_model_version": "v1-2-test", +//"cd_model_type": "G3", +//"priority": 0 +//} + +//2. GET BATCH + +GET /batches/188 HTTP/1.1 +Host: 10.100.0.11: 8000 +accept: application/json +Content-Type: application/json + +//3-1. get Detail QUEUED +GET /jobs?status=QUEUED&limit=50 HTTP/1.1 +Host: 10.100.0.11:8000 +//3-2. get Detail PROCESSING +GET /jobs?status=PROCESSING&limit=50 HTTP/1.1 +Host: 10.100.0.11: 8000 +//3-3. get Detail PROCESSING +GET /jobs?status=COMPLETED&limit=50 HTTP/1.1 +Host: 10.100.0.11: 8000 + + + + + + From 89b552a0d6f76f1ec26b9131e7fd9af245cba72e 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, 8 Jan 2026 13:26:40 +0900 Subject: [PATCH 2/7] =?UTF-8?q?change=20=EA=B3=B5=EC=9C=A0=ED=8F=B4?= =?UTF-8?q?=EB=8D=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/etc/AI_INFERENCE.http | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/etc/AI_INFERENCE.http b/src/main/resources/etc/AI_INFERENCE.http index 3c329430..cc8f4c55 100644 --- a/src/main/resources/etc/AI_INFERENCE.http +++ b/src/main/resources/etc/AI_INFERENCE.http @@ -33,6 +33,7 @@ Content-Length: 565 // }, // "model_version": "v1-2-test", // "cd_model_path": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G1/best_changed_fscore_epoch_53.pth", +z// "cd_model_path": "/kamco-nfs/ckpt/cd-checkpoints/sample-checkpoints/G1/best_changed_fscore_epoch_53.pth", // "cd_model_config": "/data/shared-dir/cd-checkpoints/sample-checkpoints/G1/rvsa-base-and-large-unet-mae-kamco.py", // "cls_model_path": "", // "cls_model_version": "v1-2-test", @@ -81,7 +82,7 @@ Content-Type: application/json //3-1. get Detail QUEUED GET /jobs?status=QUEUED&limit=50 HTTP/1.1 -Host: 10.100.0.11:8000 +Host: 10.100.0.11: 8000 //3-2. get Detail PROCESSING GET /jobs?status=PROCESSING&limit=50 HTTP/1.1 Host: 10.100.0.11: 8000 From be69fe274d1045817ed27bbfad1d5ccd4547f032 Mon Sep 17 00:00:00 2001 From: teddy Date: Thu, 8 Jan 2026 17:55:52 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[KC-99]=20=EC=B6=94=EB=A1=A0=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20spotless=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/api/SceneDemoApiController.java | 2 +- .../cd/kamcoback/common/utils/DateRange.java | 20 + ...ommonStringUtils.java => StringUtils.java} | 2 +- .../InferenceResultApiController.java | 170 ++++---- .../InferenceResultApiV2Controller.java | 10 +- .../inference/dto/InferenceDetailDto.java | 394 +++++++++++++++++ .../inference/dto/InferenceResultDto.java | 399 +++--------------- .../inference/dto/InferenceResultMngDto.java | 72 ---- .../service/InferenceResultMngService.java | 10 - .../service/InferenceResultService.java | 29 +- .../members/service/AdminService.java | 4 +- .../members/service/MembersService.java | 4 +- .../core/InferenceResultCoreService.java | 33 +- .../core/InferenceResultMngCoreService.java | 8 - .../postgres/core/MapInkxMngCoreService.java | 2 +- .../postgres/core/MembersCoreService.java | 17 +- .../postgres/entity/MapInkx50kEntity.java | 2 +- .../postgres/entity/MapInkx5kEntity.java | 6 +- .../MapSheetAnalDataInferenceGeomEntity.java | 14 +- .../postgres/entity/MapSheetLearnEntity.java | 39 +- .../InferenceResultMngRepositoryCustom.java | 8 - .../InferenceResultMngRepositoryImpl.java | 18 - ...heetAnalDataInferenceRepositoryCustom.java | 16 +- ...pSheetAnalDataInferenceRepositoryImpl.java | 24 +- ...tory.java => MapSheetLearnRepository.java} | 4 +- .../MapSheetLearnRepositoryCustom.java | 10 + .../MapSheetLearnRepositoryImpl.java | 76 ++++ .../cd/kamcoback/scene/dto/MapInkxMngDto.java | 10 +- .../scene/service/MapInkxMngService.java | 2 +- 29 files changed, 766 insertions(+), 639 deletions(-) create mode 100644 src/main/java/com/kamco/cd/kamcoback/common/utils/DateRange.java rename src/main/java/com/kamco/cd/kamcoback/common/utils/{CommonStringUtils.java => StringUtils.java} (96%) create mode 100644 src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java delete mode 100644 src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultMngDto.java delete mode 100644 src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultMngService.java delete mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultMngCoreService.java delete mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryCustom.java delete mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryImpl.java rename src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/{InferenceResultMngRepository.java => MapSheetLearnRepository.java} (58%) create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java diff --git a/src/main/java/com/kamco/cd/kamcoback/common/api/SceneDemoApiController.java b/src/main/java/com/kamco/cd/kamcoback/common/api/SceneDemoApiController.java index b70289a2..a6607c66 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/api/SceneDemoApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/api/SceneDemoApiController.java @@ -1,7 +1,7 @@ package com.kamco.cd.kamcoback.common.api; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; import com.kamco.cd.kamcoback.inference.dto.LearningModelResultDto.BatchProcessResponse; import com.kamco.cd.kamcoback.inference.service.InferenceResultService; import io.swagger.v3.oas.annotations.Operation; diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/DateRange.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/DateRange.java new file mode 100644 index 00000000..c372ddb2 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/DateRange.java @@ -0,0 +1,20 @@ +package com.kamco.cd.kamcoback.common.utils; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +public class DateRange { + + private static final ZoneId KST = ZoneId.of("Asia/Seoul"); + + private DateRange() {} + + public static ZonedDateTime start(LocalDate date) { + return date == null ? null : date.atStartOfDay(KST); + } + + public static ZonedDateTime end(LocalDate date) { + return date == null ? null : date.plusDays(1).atStartOfDay(KST); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/CommonStringUtils.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/StringUtils.java similarity index 96% rename from src/main/java/com/kamco/cd/kamcoback/common/utils/CommonStringUtils.java rename to src/main/java/com/kamco/cd/kamcoback/common/utils/StringUtils.java index c77bd6aa..8b8a6c82 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/CommonStringUtils.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/StringUtils.java @@ -3,7 +3,7 @@ package com.kamco.cd.kamcoback.common.utils; import java.util.regex.Pattern; import org.mindrot.jbcrypt.BCrypt; -public class CommonStringUtils { +public class StringUtils { private static final int BCRYPT_COST = 10; diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java index bd6440af..a5a82719 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java @@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.inference; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList; import com.kamco.cd.kamcoback.inference.service.InferenceResultService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -10,11 +11,10 @@ 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 java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -27,7 +27,7 @@ public class InferenceResultApiController { private final InferenceResultService inferenceResultService; - @Operation(summary = "추론관리 분석결과 목록 조회", description = "분석상태, 제목으로 분석결과를 조회 합니다.") + @Operation(summary = "추론관리 목록", description = "어드민 홈 > 추론관리 > 추론관리 > 추론관리 목록") @ApiResponses( value = { @ApiResponse( @@ -41,93 +41,95 @@ public class InferenceResultApiController { @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/list") - public ApiResponseDto> getInferenceResultList( - @Parameter(description = "분석상태", example = "0002") @RequestParam(required = false) - String statCode, + public ApiResponseDto> getInferenceResultList( + @Parameter(description = "국유인 반영 여부", example = "Y") @RequestParam(required = false) + String applyYn, + @Parameter(description = "반영일", example = "2025-01-01") @RequestParam(required = false) + LocalDate strtDttm, + @Parameter(description = "반영일", example = "2026-01-01") @RequestParam(required = false) + LocalDate endDttm, @Parameter(description = "제목", example = "변화탐지") @RequestParam(required = false) String title, @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") int size) { - InferenceResultDto.SearchReq searchReq = - new InferenceResultDto.SearchReq(statCode, title, page, size); - Page analResList = - inferenceResultService.getInferenceResultList(searchReq); + InferenceResultDto.SearchListReq req = + new InferenceResultDto.SearchListReq(applyYn, strtDttm, endDttm, title, page, size); + Page analResList = inferenceResultService.getInferenceResultList(req); return ApiResponseDto.ok(analResList); } - @Operation(summary = "추론관리 분석결과 요약정보", description = "분석결과 요약정보를 조회합니다.") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "검색 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = InferenceResultDto.AnalResSummary.class))), - @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/summary/{id}") - public ApiResponseDto getInferenceResultSummary( - @Parameter(description = "목록 id", example = "53") @PathVariable Long id) { - return ApiResponseDto.ok(inferenceResultService.getInferenceResultSummary(id)); - } - - @Operation(summary = "추론관리 분석결과 상세", description = "분석결과 상제 정보 Summary, DashBoard") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "검색 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = InferenceResultDto.Detail.class))), - @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/detail/{id}") - public ApiResponseDto getInferenceDetail( - @Parameter(description = "목록 id", example = "53") @PathVariable Long id) { - return ApiResponseDto.ok(inferenceResultService.getDetail(id)); - } - - @Operation(summary = "추론관리 분석결과 상세 목록", description = "추론관리 분석결과 상세 목록 geojson 데이터 조회") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "검색 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Page.class))), - @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/geom/{id}") - public ApiResponseDto> getInferenceResultGeomList( - @Parameter(description = "분석결과 id", example = "53") @PathVariable Long id, - @Parameter(description = "기준년도 분류", example = "land") @RequestParam(required = false) - String targetClass, - @Parameter(description = "비교년도 분류", example = "waste") @RequestParam(required = false) - String compareClass, - @Parameter(description = "5000:1 도협번호 37801011,37801012") @RequestParam(required = false) - List mapSheetNum, - @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") - int page, - @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") - int size, - @Parameter(description = "정렬 조건 (형식: 필드명,방향)", example = "name,asc") - @RequestParam(required = false) - String sort) { - InferenceResultDto.SearchGeoReq searchGeoReq = - new InferenceResultDto.SearchGeoReq( - targetClass, compareClass, mapSheetNum, page, size, sort); - Page geomList = - inferenceResultService.getInferenceResultGeomList(id, searchGeoReq); - return ApiResponseDto.ok(geomList); - } + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "검색 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = InferenceDetailDto.AnalResSummary.class))), + // @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/summary/{id}") + // public ApiResponseDto getInferenceResultSummary( + // @Parameter(description = "목록 id", example = "53") @PathVariable Long id) { + // return ApiResponseDto.ok(inferenceResultService.getInferenceResultSummary(id)); + // } + // + // @Operation(summary = "추론관리 분석결과 상세", description = "분석결과 상제 정보 Summary, DashBoard") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "검색 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = InferenceDetailDto.Detail.class))), + // @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/detail/{id}") + // public ApiResponseDto getInferenceDetail( + // @Parameter(description = "목록 id", example = "53") @PathVariable Long id) { + // return ApiResponseDto.ok(inferenceResultService.getDetail(id)); + // } + // + // @Operation(summary = "추론관리 분석결과 상세 목록", description = "추론관리 분석결과 상세 목록 geojson 데이터 조회") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "검색 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = Page.class))), + // @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/geom/{id}") + // public ApiResponseDto> getInferenceResultGeomList( + // @Parameter(description = "분석결과 id", example = "53") @PathVariable Long id, + // @Parameter(description = "기준년도 분류", example = "land") @RequestParam(required = false) + // String targetClass, + // @Parameter(description = "비교년도 분류", example = "waste") @RequestParam(required = false) + // String compareClass, + // @Parameter(description = "5000:1 도협번호 37801011,37801012") @RequestParam(required = false) + // List mapSheetNum, + // @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") + // int page, + // @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") + // int size, + // @Parameter(description = "정렬 조건 (형식: 필드명,방향)", example = "name,asc") + // @RequestParam(required = false) + // String sort) { + // InferenceDetailDto.SearchGeoReq searchGeoReq = + // new InferenceDetailDto.SearchGeoReq( + // targetClass, compareClass, mapSheetNum, page, size, sort); + // Page geomList = + // inferenceResultService.getInferenceResultGeomList(id, searchGeoReq); + // return ApiResponseDto.ok(geomList); + // } } diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java index 8b01288e..9f41916c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java @@ -1,7 +1,7 @@ package com.kamco.cd.kamcoback.inference; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; import com.kamco.cd.kamcoback.inference.service.InferenceResultService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -43,7 +43,7 @@ public class InferenceResultApiV2Controller { @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/geom/{id}") - public ApiResponseDto> listInferenceResultWithGeom( + public ApiResponseDto> listInferenceResultWithGeom( @Parameter(description = "분석결과 id", example = "1") @PathVariable Long id, @Parameter(description = "기준년도 분류", example = "land") @RequestParam(required = false) String targetClass, @@ -58,11 +58,11 @@ public class InferenceResultApiV2Controller { @Parameter(description = "정렬 조건 (형식: 필드명,방향)", example = "name,asc") @RequestParam(required = false) String sort) { - InferenceResultDto.SearchGeoReq searchGeoReq = - new InferenceResultDto.SearchGeoReq( + InferenceDetailDto.SearchGeoReq searchGeoReq = + new InferenceDetailDto.SearchGeoReq( targetClass, compareClass, mapSheetNum, page, size, sort); - Page geomList = + Page geomList = inferenceResultService.listInferenceResultWithGeom(id, searchGeoReq); return ApiResponseDto.ok(geomList); } diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java new file mode 100644 index 00000000..4f3167ff --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java @@ -0,0 +1,394 @@ +package com.kamco.cd.kamcoback.inference.dto; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.kamco.cd.kamcoback.common.enums.DetectionClassification; +import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +public class InferenceDetailDto { + + @Schema(name = "InferenceResultBasic", description = "분석결과 기본 정보") + @Getter + public static class Basic { + + private Long id; + private String dataName; + private Long mapSheepNum; + private Long detectingCnt; + @JsonFormatDttm private ZonedDateTime analStrtDttm; + @JsonFormatDttm private ZonedDateTime analEndDttm; + private Long analSec; + private String analState; + + public Basic( + Long id, + String dataName, + Long mapSheepNum, + Long detectingCnt, + ZonedDateTime analStrtDttm, + ZonedDateTime analEndDttm, + Long analSec, + String analState) { + this.id = id; + this.dataName = dataName; + this.mapSheepNum = mapSheepNum; + this.detectingCnt = detectingCnt; + this.analStrtDttm = analStrtDttm; + this.analEndDttm = analEndDttm; + this.analSec = analSec; + this.analState = analState; + } + } + + @Schema(name = "AnalysisResultList", description = "분석결과 목록") + @Getter + public static class AnalResList { + + private Long id; + private String analTitle; + private Long detectingCnt; + @JsonFormatDttm private ZonedDateTime analStrtDttm; + @JsonFormatDttm private ZonedDateTime analEndDttm; + private Long analSec; + private Long analPredSec; + private String analState; + private String analStateNm; + private String gukyuinUsed; + + public AnalResList( + Long id, + String analTitle, + Long detectingCnt, + ZonedDateTime analStrtDttm, + ZonedDateTime analEndDttm, + Long analSec, + Long analPredSec, + String analState, + String analStateNm, + String gukyuinUsed) { + this.id = id; + this.analTitle = analTitle; + this.detectingCnt = detectingCnt; + this.analStrtDttm = analStrtDttm; + this.analEndDttm = analEndDttm; + this.analSec = analSec; + this.analPredSec = analPredSec; + this.analState = analState; + this.analStateNm = analStateNm; + this.gukyuinUsed = gukyuinUsed; + } + } + + @Schema(name = "AnalysisResultSummary", description = "분석결과 요약정보") + @Getter + public static class AnalResSummary { + + private Long id; + private String analTitle; + private String modelInfo; + private Integer targetYyyy; + private Integer compareYyyy; + @JsonFormatDttm private ZonedDateTime analStrtDttm; + @JsonFormatDttm private ZonedDateTime analEndDttm; + private Long analSec; + private Long analPredSec; + private String resultUrl; + private Long detectingCnt; + private Double accuracy; + private String analState; + private String analStateNm; + + public AnalResSummary( + Long id, + String analTitle, + String modelInfo, + Integer targetYyyy, + Integer compareYyyy, + ZonedDateTime analStrtDttm, + ZonedDateTime analEndDttm, + Long analSec, + Long analPredSec, + String resultUrl, + Long detectingCnt, + Double accuracy, + String analState, + String analStateNm) { + this.id = id; + this.analTitle = analTitle; + this.modelInfo = modelInfo; + this.targetYyyy = targetYyyy; + this.compareYyyy = compareYyyy; + this.analStrtDttm = analStrtDttm; + this.analEndDttm = analEndDttm; + this.analSec = analSec; + this.analPredSec = analPredSec; + this.resultUrl = resultUrl; + this.detectingCnt = detectingCnt; + this.accuracy = accuracy; + this.analState = analState; + this.analStateNm = analStateNm; + } + } + + @Getter + public static class Dashboard { + + String classAfterCd; + String classAfterName; + Long classAfterCnt; + + public Dashboard(String classAfterCd, Long classAfterCnt) { + this.classAfterCd = classAfterCd; + this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc(); + this.classAfterCnt = classAfterCnt; + } + } + + @Getter + public static class Detail { + + AnalResSummary summary; + List dashboard; + Long totalCnt; + + public Detail(AnalResSummary summary, List dashboard, Long totalCnt) { + this.summary = summary; + this.dashboard = dashboard; + this.totalCnt = totalCnt; + } + } + + // 분석 상세 ROW + @Getter + @AllArgsConstructor + public static class DetailListEntity { + + private Uid code; + private Double detectionScore; + private Clazzes compare; + private Clazzes target; + private MapSheet mapSheet; + private Coordinate center; + @JsonFormatDttm private ZonedDateTime updatedDttm; + + public DetailListEntity( + UUID uuid, + Double detectionScore, + Clazzes compare, + Clazzes target, + MapSheet mapSheet, + Coordinate center, + ZonedDateTime updatedDttm) { + this.code = new Uid(uuid); + this.detectionScore = detectionScore; + this.compare = compare; + this.target = target; + this.mapSheet = mapSheet; + this.center = center; + this.updatedDttm = updatedDttm; + } + } + + @Getter + @AllArgsConstructor + public static class Uid { + + private String shortCode; + private String code; + + public Uid(UUID uuid) { + if (uuid != null) { + this.shortCode = uuid.toString().substring(0, 8).toUpperCase(); + this.code = uuid.toString(); + } + } + } + + // MAP NO + @Getter + @AllArgsConstructor + public static class MapSheet { + + private String number; + private String name; + } + + // classification info + @Getter + public static class Clazz { + + private String code; + private String name; + @JsonIgnore private Double score; + + public Clazz(String code, Double score) { + this.code = code; + this.score = score; + this.name = DetectionClassification.fromString(code).getDesc(); + } + + public Clazz(String code) { + this.code = code; + this.name = DetectionClassification.fromString(code).getDesc(); + } + } + + // classification info + @Getter + public static class Clazzes { + + private DetectionClassification code; + private String name; + + @JsonInclude(JsonInclude.Include.NON_NULL) + private Double score; + + private Integer order; + + public Clazzes(DetectionClassification classification, Double score) { + this.code = classification; + this.name = classification.getDesc(); + this.order = classification.getOrder(); + this.score = score; + } + + public Clazzes(DetectionClassification classification) { + this.code = classification; + this.name = classification.getDesc(); + this.order = classification.getOrder(); + } + } + + // 좌표 정보 point + @Getter + public static class Coordinate { + + private Double lon; // 경도(Longitude) + private Double lat; // 위도(Latitude) + private String srid; // Spatial Reference ID의 약자로, 데이터베이스에서 좌표계를 식별하는 고유 번호 추후enum으로 + + public Coordinate(Double lon, Double lat) { + this.lon = lon; + this.lat = lat; + this.srid = "EPSG:4326"; + } + } + + @Getter + public static class Geom { + + Integer compareYyyy; + Integer targetYyyy; + String classBeforeCd; + String classBeforeName; + Double classBeforeProb; + String classAfterCd; + String classAfterName; + Double classAfterProb; + Long mapSheetNum; + @JsonIgnore String gemoStr; + @JsonIgnore String geomCenterStr; + JsonNode gemo; + JsonNode geomCenter; + + public Geom( + Integer compareYyyy, + Integer targetYyyy, + String classBeforeCd, + Double classBeforeProb, + String classAfterCd, + Double classAfterProb, + Long mapSheetNum, + String gemoStr, + String geomCenterStr) { + this.compareYyyy = compareYyyy; + this.targetYyyy = targetYyyy; + this.classBeforeCd = classBeforeCd; + this.classBeforeName = DetectionClassification.fromString(classBeforeCd).getDesc(); + this.classBeforeProb = classBeforeProb; + this.classAfterCd = classAfterCd; + this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc(); + this.classAfterProb = classAfterProb; + this.mapSheetNum = mapSheetNum; + this.gemoStr = gemoStr; + this.geomCenterStr = geomCenterStr; + + ObjectMapper mapper = new ObjectMapper(); + JsonNode geomJson; + JsonNode geomCenterJson; + try { + geomJson = mapper.readTree(gemoStr); + geomCenterJson = mapper.readTree(geomCenterStr); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + this.gemo = geomJson; + this.geomCenter = geomCenterJson; + } + } + + @Schema(name = "InferenceResultSearchReq", description = "분석결과 목록 요청 정보") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SearchReq { + + // 검색 조건 + private String statCode; + private String title; + + // 페이징 파라미터 + private int page = 0; + private int size = 20; + + public Pageable toPageable() { + return PageRequest.of(page, size); + } + } + + @Schema(name = "InferenceResultSearchReq", description = "분석결과 목록 요청 정보") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SearchGeoReq { + + // 기준년도 + private String targetClass; + // 비교년도 + private String compareClass; + // 분석도엽 + private List mapSheetNum; + + // 페이징 파라미터 + private int page = 0; + private int size = 20; + private String 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/inference/dto/InferenceResultDto.java b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java index 7f6300ea..133b38cf 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java @@ -1,15 +1,9 @@ package com.kamco.cd.kamcoback.inference.dto; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.kamco.cd.kamcoback.common.enums.DetectionClassification; +import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; -import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDate; import java.time.ZonedDateTime; -import java.util.List; import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Getter; @@ -17,339 +11,37 @@ import lombok.NoArgsConstructor; import lombok.Setter; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; public class InferenceResultDto { - @Schema(name = "InferenceResultBasic", description = "분석결과 기본 정보") - @Getter - public static class Basic { - - private Long id; - private String dataName; - private Long mapSheepNum; - private Long detectingCnt; - @JsonFormatDttm private ZonedDateTime analStrtDttm; - @JsonFormatDttm private ZonedDateTime analEndDttm; - private Long analSec; - private String analState; - - public Basic( - Long id, - String dataName, - Long mapSheepNum, - Long detectingCnt, - ZonedDateTime analStrtDttm, - ZonedDateTime analEndDttm, - Long analSec, - String analState) { - this.id = id; - this.dataName = dataName; - this.mapSheepNum = mapSheepNum; - this.detectingCnt = detectingCnt; - this.analStrtDttm = analStrtDttm; - this.analEndDttm = analEndDttm; - this.analSec = analSec; - this.analState = analState; - } - } - - @Schema(name = "AnalysisResultList", description = "분석결과 목록") - @Getter - public static class AnalResList { - - private Long id; - private String analTitle; - private Long detectingCnt; - @JsonFormatDttm private ZonedDateTime analStrtDttm; - @JsonFormatDttm private ZonedDateTime analEndDttm; - private Long analSec; - private Long analPredSec; - private String analState; - private String analStateNm; - private String gukyuinUsed; - - public AnalResList( - Long id, - String analTitle, - Long detectingCnt, - ZonedDateTime analStrtDttm, - ZonedDateTime analEndDttm, - Long analSec, - Long analPredSec, - String analState, - String analStateNm, - String gukyuinUsed) { - this.id = id; - this.analTitle = analTitle; - this.detectingCnt = detectingCnt; - this.analStrtDttm = analStrtDttm; - this.analEndDttm = analEndDttm; - this.analSec = analSec; - this.analPredSec = analPredSec; - this.analState = analState; - this.analStateNm = analStateNm; - this.gukyuinUsed = gukyuinUsed; - } - } - - @Schema(name = "AnalysisResultSummary", description = "분석결과 요약정보") - @Getter - public static class AnalResSummary { - - private Long id; - private String analTitle; - private String modelInfo; - private Integer targetYyyy; - private Integer compareYyyy; - @JsonFormatDttm private ZonedDateTime analStrtDttm; - @JsonFormatDttm private ZonedDateTime analEndDttm; - private Long analSec; - private Long analPredSec; - private String resultUrl; - private Long detectingCnt; - private Double accuracy; - private String analState; - private String analStateNm; - - public AnalResSummary( - Long id, - String analTitle, - String modelInfo, - Integer targetYyyy, - Integer compareYyyy, - ZonedDateTime analStrtDttm, - ZonedDateTime analEndDttm, - Long analSec, - Long analPredSec, - String resultUrl, - Long detectingCnt, - Double accuracy, - String analState, - String analStateNm) { - this.id = id; - this.analTitle = analTitle; - this.modelInfo = modelInfo; - this.targetYyyy = targetYyyy; - this.compareYyyy = compareYyyy; - this.analStrtDttm = analStrtDttm; - this.analEndDttm = analEndDttm; - this.analSec = analSec; - this.analPredSec = analPredSec; - this.resultUrl = resultUrl; - this.detectingCnt = detectingCnt; - this.accuracy = accuracy; - this.analState = analState; - this.analStateNm = analStateNm; - } - } - - @Getter - public static class Dashboard { - - String classAfterCd; - String classAfterName; - Long classAfterCnt; - - public Dashboard(String classAfterCd, Long classAfterCnt) { - this.classAfterCd = classAfterCd; - this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc(); - this.classAfterCnt = classAfterCnt; - } - } - - @Getter - public static class Detail { - - AnalResSummary summary; - List dashboard; - Long totalCnt; - - public Detail(AnalResSummary summary, List dashboard, Long totalCnt) { - this.summary = summary; - this.dashboard = dashboard; - this.totalCnt = totalCnt; - } - } - - // 분석 상세 ROW @Getter + @Setter @AllArgsConstructor - public static class DetailListEntity { + @NoArgsConstructor + public static class ResultList { - private Uid code; - private Double detectionScore; - private Clazzes compare; - private Clazzes target; - private MapSheet mapSheet; - private Coordinate center; - @JsonFormatDttm private ZonedDateTime updatedDttm; - - public DetailListEntity( - UUID uuid, - Double detectionScore, - Clazzes compare, - Clazzes target, - MapSheet mapSheet, - Coordinate center, - ZonedDateTime updatedDttm) { - this.code = new Uid(uuid); - this.detectionScore = detectionScore; - this.compare = compare; - this.target = target; - this.mapSheet = mapSheet; - this.center = center; - this.updatedDttm = updatedDttm; - } + private UUID uuid; + private String title; + private String status; + private String mapSheetCnt; + private Long detectingCnt; + @JsonFormatDttm private ZonedDateTime startTime; + @JsonFormatDttm private ZonedDateTime endTime; + @JsonFormatDttm private ZonedDateTime elapsedTime; + private Boolean applyYn; + @JsonFormatDttm private ZonedDateTime applyDttm; } - @Getter - @AllArgsConstructor - public static class Uid { - - private String shortCode; - private String code; - - public Uid(UUID uuid) { - if (uuid != null) { - this.shortCode = uuid.toString().substring(0, 8).toUpperCase(); - this.code = uuid.toString(); - } - } - } - - // MAP NO - @Getter - @AllArgsConstructor - public static class MapSheet { - - private String number; - private String name; - } - - // classification info - @Getter - public static class Clazz { - - private String code; - private String name; - @JsonIgnore private Double score; - - public Clazz(String code, Double score) { - this.code = code; - this.score = score; - this.name = DetectionClassification.fromString(code).getDesc(); - } - - public Clazz(String code) { - this.code = code; - this.name = DetectionClassification.fromString(code).getDesc(); - } - } - - // classification info - @Getter - public static class Clazzes { - - private DetectionClassification code; - private String name; - - @JsonInclude(JsonInclude.Include.NON_NULL) - private Double score; - - private Integer order; - - public Clazzes(DetectionClassification classification, Double score) { - this.code = classification; - this.name = classification.getDesc(); - this.order = classification.getOrder(); - this.score = score; - } - - public Clazzes(DetectionClassification classification) { - this.code = classification; - this.name = classification.getDesc(); - this.order = classification.getOrder(); - } - } - - // 좌표 정보 point - @Getter - public static class Coordinate { - - private Double lon; // 경도(Longitude) - private Double lat; // 위도(Latitude) - private String srid; // Spatial Reference ID의 약자로, 데이터베이스에서 좌표계를 식별하는 고유 번호 추후enum으로 - - public Coordinate(Double lon, Double lat) { - this.lon = lon; - this.lat = lat; - this.srid = "EPSG:4326"; - } - } - - @Getter - public static class Geom { - - Integer compareYyyy; - Integer targetYyyy; - String classBeforeCd; - String classBeforeName; - Double classBeforeProb; - String classAfterCd; - String classAfterName; - Double classAfterProb; - Long mapSheetNum; - @JsonIgnore String gemoStr; - @JsonIgnore String geomCenterStr; - JsonNode gemo; - JsonNode geomCenter; - - public Geom( - Integer compareYyyy, - Integer targetYyyy, - String classBeforeCd, - Double classBeforeProb, - String classAfterCd, - Double classAfterProb, - Long mapSheetNum, - String gemoStr, - String geomCenterStr) { - this.compareYyyy = compareYyyy; - this.targetYyyy = targetYyyy; - this.classBeforeCd = classBeforeCd; - this.classBeforeName = DetectionClassification.fromString(classBeforeCd).getDesc(); - this.classBeforeProb = classBeforeProb; - this.classAfterCd = classAfterCd; - this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc(); - this.classAfterProb = classAfterProb; - this.mapSheetNum = mapSheetNum; - this.gemoStr = gemoStr; - this.geomCenterStr = geomCenterStr; - - ObjectMapper mapper = new ObjectMapper(); - JsonNode geomJson; - JsonNode geomCenterJson; - try { - geomJson = mapper.readTree(gemoStr); - geomCenterJson = mapper.readTree(geomCenterStr); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - this.gemo = geomJson; - this.geomCenter = geomCenterJson; - } - } - - @Schema(name = "InferenceResultSearchReq", description = "분석결과 목록 요청 정보") @Getter @Setter @NoArgsConstructor @AllArgsConstructor - public static class SearchReq { + public static class SearchListReq { // 검색 조건 - private String statCode; + private String applyYn; + private LocalDate strtDttm; + private LocalDate endDttm; private String title; // 페이징 파라미터 @@ -361,34 +53,41 @@ public class InferenceResultDto { } } - @Schema(name = "InferenceResultSearchReq", description = "분석결과 목록 요청 정보") @Getter - @Setter - @NoArgsConstructor @AllArgsConstructor - public static class SearchGeoReq { + public enum DetectOption implements EnumType { + ALL("전체"), + PART("부분"), + ; + private final String desc; - // 기준년도 - private String targetClass; - // 비교년도 - private String compareClass; - // 분석도엽 - private List mapSheetNum; + @Override + public String getId() { + return name(); + } - // 페이징 파라미터 - private int page = 0; - private int size = 20; - private String sort; + @Override + public String getText() { + return desc; + } + } - 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); + @Getter + @AllArgsConstructor + public enum MapSheetScope implements EnumType { + EXCL("추론제외"), + PREV("이전 년도 도엽 사용"), + ; + private final String desc; + + @Override + public String getId() { + return name(); + } + + @Override + public String getText() { + return desc; } } } diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultMngDto.java b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultMngDto.java deleted file mode 100644 index dd193c80..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultMngDto.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.kamco.cd.kamcoback.inference.dto; - -import com.kamco.cd.kamcoback.common.utils.enums.EnumType; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; - -public class InferenceResultMngDto { - - @Schema(name = "SearchListReq", description = "분석결과 목록 검색 조건") - @Getter - @Setter - @NoArgsConstructor - @AllArgsConstructor - public static class SearchListReq { - - // 검색 조건 - private String applyYn; - private String strtDttm; - private String endDttm; - - // 페이징 파라미터 - private int page = 0; - private int size = 20; - - public Pageable toPageable() { - return PageRequest.of(page, size); - } - } - - @Getter - @AllArgsConstructor - public enum DetectOption implements EnumType { - ALL("전체"), - PART("부분"), - ; - private final String desc; - - @Override - public String getId() { - return name(); - } - - @Override - public String getText() { - return desc; - } - } - - @Getter - @AllArgsConstructor - public enum MapSheetScope implements EnumType { - EXCL("추론제외"), - PREV("이전 년도 도엽 사용"), - ; - private final String desc; - - @Override - public String getId() { - return name(); - } - - @Override - public String getText() { - return desc; - } - } -} diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultMngService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultMngService.java deleted file mode 100644 index efe66da3..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultMngService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.kamco.cd.kamcoback.inference.service; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class InferenceResultMngService {} diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java index 45a9ea82..285e1527 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java @@ -1,9 +1,11 @@ package com.kamco.cd.kamcoback.inference.service; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Detail; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Detail; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList; import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService; import jakarta.validation.constraints.NotNull; import java.util.List; @@ -20,14 +22,13 @@ public class InferenceResultService { private final InferenceResultCoreService inferenceResultCoreService; /** - * 추론관리 > 분석결과 목록 조회 + * 추론관리 목록 * - * @param searchReq + * @param req * @return */ - public Page getInferenceResultList( - InferenceResultDto.SearchReq searchReq) { - return inferenceResultCoreService.getInferenceResultList(searchReq); + public Page getInferenceResultList(InferenceResultDto.SearchListReq req) { + return inferenceResultCoreService.getInferenceResultList(req); } /** @@ -36,7 +37,7 @@ public class InferenceResultService { * @param id * @return */ - public InferenceResultDto.AnalResSummary getInferenceResultSummary(Long id) { + public InferenceDetailDto.AnalResSummary getInferenceResultSummary(Long id) { return inferenceResultCoreService.getInferenceResultSummary(id); } @@ -56,8 +57,8 @@ public class InferenceResultService { * @param searchGeoReq * @return */ - public Page getInferenceResultGeomList( - Long id, InferenceResultDto.SearchGeoReq searchGeoReq) { + public Page getInferenceResultGeomList( + Long id, InferenceDetailDto.SearchGeoReq searchGeoReq) { return inferenceResultCoreService.getInferenceResultGeomList(id, searchGeoReq); } @@ -67,8 +68,8 @@ public class InferenceResultService { * @param searchReq * @return */ - public Page listInferenceResultWithGeom( - @NotNull Long id, InferenceResultDto.SearchGeoReq searchReq) { + public Page listInferenceResultWithGeom( + @NotNull Long id, InferenceDetailDto.SearchGeoReq searchReq) { return inferenceResultCoreService.listInferenceResultWithGeom(id, searchReq); } @@ -81,7 +82,7 @@ public class InferenceResultService { */ public Detail getDetail(Long id) { // summary - InferenceResultDto.AnalResSummary summary = this.getInferenceResultSummary(id); + InferenceDetailDto.AnalResSummary summary = this.getInferenceResultSummary(id); // Dashboard List dashboards = this.getDashboard(id); diff --git a/src/main/java/com/kamco/cd/kamcoback/members/service/AdminService.java b/src/main/java/com/kamco/cd/kamcoback/members/service/AdminService.java index b00c6118..a6c807a4 100644 --- a/src/main/java/com/kamco/cd/kamcoback/members/service/AdminService.java +++ b/src/main/java/com/kamco/cd/kamcoback/members/service/AdminService.java @@ -1,7 +1,7 @@ package com.kamco.cd.kamcoback.members.service; import com.kamco.cd.kamcoback.common.exception.CustomApiException; -import com.kamco.cd.kamcoback.common.utils.CommonStringUtils; +import com.kamco.cd.kamcoback.common.utils.StringUtils; import com.kamco.cd.kamcoback.members.dto.MembersDto; import com.kamco.cd.kamcoback.postgres.core.MembersCoreService; import java.util.UUID; @@ -25,7 +25,7 @@ public class AdminService { */ @Transactional public Long saveMember(MembersDto.AddReq addReq) { - if (!CommonStringUtils.isValidPassword(addReq.getPassword())) { + if (!StringUtils.isValidPassword(addReq.getPassword())) { throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST); } diff --git a/src/main/java/com/kamco/cd/kamcoback/members/service/MembersService.java b/src/main/java/com/kamco/cd/kamcoback/members/service/MembersService.java index 036d35af..6dcc2122 100644 --- a/src/main/java/com/kamco/cd/kamcoback/members/service/MembersService.java +++ b/src/main/java/com/kamco/cd/kamcoback/members/service/MembersService.java @@ -1,7 +1,7 @@ package com.kamco.cd.kamcoback.members.service; import com.kamco.cd.kamcoback.common.exception.CustomApiException; -import com.kamco.cd.kamcoback.common.utils.CommonStringUtils; +import com.kamco.cd.kamcoback.common.utils.StringUtils; import com.kamco.cd.kamcoback.members.dto.MembersDto; import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic; import com.kamco.cd.kamcoback.postgres.core.MembersCoreService; @@ -37,7 +37,7 @@ public class MembersService { @Transactional public void resetPassword(String id, MembersDto.InitReq initReq) { - if (!CommonStringUtils.isValidPassword(initReq.getNewPassword())) { + if (!StringUtils.isValidPassword(initReq.getNewPassword())) { throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST); } membersCoreService.resetPassword(id, initReq); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java index 927beecc..1b4443d4 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java @@ -1,12 +1,16 @@ package com.kamco.cd.kamcoback.postgres.core; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList; import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetAnalDataInferenceRepository; +import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetLearnRepository; import com.kamco.cd.kamcoback.postgres.repository.scene.MapInkx5kRepository; import jakarta.persistence.EntityNotFoundException; import jakarta.validation.constraints.NotNull; @@ -21,27 +25,30 @@ import org.springframework.transaction.annotation.Transactional; public class InferenceResultCoreService { private final MapSheetAnalDataInferenceRepository mapSheetAnalDataRepository; + private final MapSheetLearnRepository mapSheetLearnRepository; private final MapInkx5kRepository mapInkx5kRepository; /** - * 추론관리 > 분석결과 목록 조회 + * 추론관리 목록 * - * @param searchReq + * @param req * @return */ - public Page getInferenceResultList( - InferenceResultDto.SearchReq searchReq) { - return mapSheetAnalDataRepository.getInferenceResultList(searchReq); + public Page getInferenceResultList(InferenceResultDto.SearchListReq req) { + Page list = mapSheetLearnRepository.getInferenceMgnResultList(req); + return list.map(MapSheetLearnEntity::toDto); } + /****/ + /** * 분석결과 요약정보 * * @param id * @return */ - public InferenceResultDto.AnalResSummary getInferenceResultSummary(Long id) { - InferenceResultDto.AnalResSummary summary = + public InferenceDetailDto.AnalResSummary getInferenceResultSummary(Long id) { + InferenceDetailDto.AnalResSummary summary = mapSheetAnalDataRepository .getInferenceResultSummary(id) .orElseThrow(() -> new EntityNotFoundException("요약정보를 찾을 수 없습니다. " + id)); @@ -64,8 +71,8 @@ public class InferenceResultCoreService { * @param searchGeoReq * @return */ - public Page getInferenceResultGeomList( - Long id, InferenceResultDto.SearchGeoReq searchGeoReq) { + public Page getInferenceResultGeomList( + Long id, InferenceDetailDto.SearchGeoReq searchGeoReq) { return mapSheetAnalDataRepository.getInferenceGeomList(id, searchGeoReq); } @@ -76,8 +83,8 @@ public class InferenceResultCoreService { * @return */ @Transactional(readOnly = true) - public Page listInferenceResultWithGeom( - @NotNull Long analyId, InferenceResultDto.SearchGeoReq searchReq) { + public Page listInferenceResultWithGeom( + @NotNull Long analyId, InferenceDetailDto.SearchGeoReq searchReq) { // 분석 ID 에 해당하는 dataids를 가져온다. List dataIds = mapSheetAnalDataRepository.listAnalyGeom(analyId).stream() diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultMngCoreService.java deleted file mode 100644 index 5235fb06..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultMngCoreService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.kamco.cd.kamcoback.postgres.core; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class InferenceResultMngCoreService {} 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 78aecaa1..07c45557 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 @@ -3,7 +3,7 @@ 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.inference.dto.InferenceDetailDto.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; 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 699b40e6..5662fe66 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 @@ -3,7 +3,7 @@ package com.kamco.cd.kamcoback.postgres.core; import com.kamco.cd.kamcoback.common.enums.StatusType; import com.kamco.cd.kamcoback.common.enums.error.AuthErrorCode; import com.kamco.cd.kamcoback.common.exception.CustomApiException; -import com.kamco.cd.kamcoback.common.utils.CommonStringUtils; +import com.kamco.cd.kamcoback.common.utils.StringUtils; import com.kamco.cd.kamcoback.common.utils.UserUtil; import com.kamco.cd.kamcoback.members.dto.MembersDto; import com.kamco.cd.kamcoback.members.dto.MembersDto.AddReq; @@ -17,7 +17,6 @@ import com.kamco.cd.kamcoback.postgres.repository.members.MembersRepository; import java.time.ZonedDateTime; import java.util.UUID; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; import org.mindrot.jbcrypt.BCrypt; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; @@ -43,7 +42,7 @@ public class MembersCoreService { } // 패스워드 암호화, 초기 패스워드 고정 - String hashedPassword = CommonStringUtils.hashPassword(addReq.getPassword()); + String hashedPassword = StringUtils.hashPassword(addReq.getPassword()); MemberEntity memberEntity = new MemberEntity(); memberEntity.setUserId(addReq.getEmployeeNo()); @@ -67,22 +66,22 @@ public class MembersCoreService { MemberEntity memberEntity = membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new); - if (StringUtils.isNotBlank(updateReq.getName())) { + if (org.apache.commons.lang3.StringUtils.isNotBlank(updateReq.getName())) { memberEntity.setName(updateReq.getName()); } - if (StringUtils.isNotBlank(updateReq.getStatus())) { + if (org.apache.commons.lang3.StringUtils.isNotBlank(updateReq.getStatus())) { memberEntity.changeStatus(updateReq.getStatus()); } - if (StringUtils.isNotBlank(updateReq.getPassword())) { + if (org.apache.commons.lang3.StringUtils.isNotBlank(updateReq.getPassword())) { // 패스워드 유효성 검사 - if (!CommonStringUtils.isValidPassword(updateReq.getPassword())) { + if (!StringUtils.isValidPassword(updateReq.getPassword())) { throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST); } - String password = CommonStringUtils.hashPassword(updateReq.getPassword()); + String password = StringUtils.hashPassword(updateReq.getPassword()); memberEntity.setStatus(StatusType.PENDING.getId()); memberEntity.setLoginFailCount(0); @@ -107,7 +106,7 @@ public class MembersCoreService { throw new CustomApiException(AuthErrorCode.LOGIN_PASSWORD_MISMATCH); } - String password = CommonStringUtils.hashPassword(initReq.getNewPassword()); + String password = StringUtils.hashPassword(initReq.getNewPassword()); memberEntity.setPassword(password); memberEntity.setStatus(StatusType.ACTIVE.getId()); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java index df11dee0..87192736 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java @@ -1,6 +1,6 @@ package com.kamco.cd.kamcoback.postgres.entity; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; import com.kamco.cd.kamcoback.postgres.CommonDateEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; 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 b4d26049..409aa67c 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,8 +1,8 @@ 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.inference.dto.InferenceDetailDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; import com.kamco.cd.kamcoback.postgres.CommonDateEntity; import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapListEntity; import jakarta.persistence.Column; @@ -71,7 +71,7 @@ public class MapInkx5kEntity extends CommonDateEntity { this.useInference = useInference; } - public InferenceResultDto.MapSheet toEntity() { + public InferenceDetailDto.MapSheet toEntity() { return new MapSheet(mapidcdNo, mapidNm); } 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 c079be5f..165f8207 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 @@ -1,8 +1,8 @@ package com.kamco.cd.kamcoback.postgres.entity; import com.kamco.cd.kamcoback.common.enums.DetectionClassification; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Clazzes; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Clazzes; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -160,20 +160,20 @@ public class MapSheetAnalDataInferenceGeomEntity { @JoinColumn(name = "map_5k_id", referencedColumnName = "fid") private MapInkx5kEntity map5k; - public InferenceResultDto.DetailListEntity toEntity() { + public InferenceDetailDto.DetailListEntity toEntity() { DetectionClassification classification = DetectionClassification.fromString(classBeforeCd); Clazzes comparedClazz = new Clazzes(classification, classBeforeProb); DetectionClassification classification1 = DetectionClassification.fromString(classAfterCd); Clazzes targetClazz = new Clazzes(classification1, classAfterProb); - InferenceResultDto.MapSheet mapSheet = map5k != null ? map5k.toEntity() : null; + InferenceDetailDto.MapSheet mapSheet = map5k != null ? map5k.toEntity() : null; - InferenceResultDto.Coordinate coordinate = null; + InferenceDetailDto.Coordinate coordinate = null; if (geomCenter != null) { org.locationtech.jts.geom.Point point = (org.locationtech.jts.geom.Point) geomCenter; - coordinate = new InferenceResultDto.Coordinate(point.getX(), point.getY()); + coordinate = new InferenceDetailDto.Coordinate(point.getX(), point.getY()); } - return new InferenceResultDto.DetailListEntity( + return new InferenceDetailDto.DetailListEntity( uuid, cdProb, comparedClazz, targetClazz, mapSheet, coordinate, createdDttm); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java index 1393d011..062c7d87 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java @@ -1,5 +1,6 @@ package com.kamco.cd.kamcoback.postgres.entity; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -7,6 +8,7 @@ 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; @@ -31,7 +33,16 @@ public class MapSheetLearnEntity { @ColumnDefault("gen_random_uuid()") @Column(name = "uuid") - private UUID uuid = UUID.randomUUID(); + private UUID uuid; + + @Size(max = 200) + @NotNull + @Column(name = "title", nullable = false, length = 200) + private String title; + + @Size(max = 10) + @Column(name = "status", length = 10) + private String status; @Column(name = "m1_model_uid") private Long m1ModelUid; @@ -52,6 +63,10 @@ public class MapSheetLearnEntity { @Column(name = "detect_option", length = 20) private String detectOption; + @Size(max = 100) + @Column(name = "map_sheet_cnt", length = 100) + private String mapSheetCnt; + @Size(max = 20) @Column(name = "map_sheet_scope", length = 20) private String mapSheetScope; @@ -59,6 +74,12 @@ public class MapSheetLearnEntity { @Column(name = "detecting_cnt") private Long detectingCnt; + @Column(name = "infer_start_dttm") + private ZonedDateTime inferStartDttm; + + @Column(name = "infer_end_dttm") + private ZonedDateTime inferEndDttm; + @Column(name = "elapsed_time") private ZonedDateTime elapsedTime; @@ -70,7 +91,7 @@ public class MapSheetLearnEntity { @ColumnDefault("now()") @Column(name = "created_dttm") - private ZonedDateTime createdDttm = ZonedDateTime.now(); + private ZonedDateTime createdDttm; @Column(name = "created_uid") private Long createdUid; @@ -81,4 +102,18 @@ public class MapSheetLearnEntity { @Column(name = "updated_uid") private Long updatedUid; + + public InferenceResultDto.ResultList toDto() { + return new InferenceResultDto.ResultList( + this.uuid, + this.title, + this.status, + this.mapSheetCnt, + this.detectingCnt, + this.inferStartDttm, + this.inferEndDttm, + this.elapsedTime, + this.applyYn, + this.applyDttm); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryCustom.java deleted file mode 100644 index 79f21c82..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryCustom.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.kamco.cd.kamcoback.postgres.repository.Inference; - -import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; - -public interface InferenceResultMngRepositoryCustom { - - MapSheetLearnEntity getInferenceMgnResultList(); -} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryImpl.java deleted file mode 100644 index e45e02ea..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepositoryImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.kamco.cd.kamcoback.postgres.repository.Inference; - -import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; -import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; - -@Repository -@RequiredArgsConstructor -public class InferenceResultMngRepositoryImpl implements InferenceResultMngRepositoryCustom { - - private final JPAQueryFactory queryFactory; - - @Override - public MapSheetLearnEntity getInferenceMgnResultList() { - return null; - } -} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryCustom.java index 20ee8baa..5b8ff100 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryCustom.java @@ -1,10 +1,10 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResList; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResSummary; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResList; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResSummary; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.SearchGeoReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import jakarta.validation.constraints.NotNull; @@ -14,12 +14,12 @@ import org.springframework.data.domain.Page; public interface MapSheetAnalDataInferenceRepositoryCustom { - Page getInferenceResultList(InferenceResultDto.SearchReq searchReq); + Page getInferenceResultList(InferenceDetailDto.SearchReq searchReq); Optional getInferenceResultSummary(Long id); - Page getInferenceGeomList( - Long id, InferenceResultDto.SearchGeoReq searchGeoReq); + Page getInferenceGeomList( + Long id, InferenceDetailDto.SearchGeoReq searchGeoReq); Page listInferenceResultWithGeom( List dataIds, SearchGeoReq searchReq); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java index 0e465402..f6c1190c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java @@ -2,11 +2,11 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResList; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.AnalResSummary; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResList; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResSummary; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.SearchGeoReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceEntity; @@ -58,7 +58,7 @@ public class MapSheetAnalDataInferenceRepositoryImpl * @return */ @Override - public Page getInferenceResultList(InferenceResultDto.SearchReq searchReq) { + public Page getInferenceResultList(InferenceDetailDto.SearchReq searchReq) { Pageable pageable = searchReq.toPageable(); // "0000" 전체조회 BooleanBuilder builder = new BooleanBuilder(); @@ -75,7 +75,7 @@ public class MapSheetAnalDataInferenceRepositoryImpl queryFactory .select( Projections.constructor( - InferenceResultDto.AnalResList.class, + InferenceDetailDto.AnalResList.class, mapSheetAnalInferenceEntity.id, mapSheetAnalInferenceEntity.analTitle, mapSheetAnalInferenceEntity.detectingCnt, @@ -117,12 +117,12 @@ public class MapSheetAnalDataInferenceRepositoryImpl JPQLQuery latestVerUidSub = JPAExpressions.select(tmv.id.max()).from(tmv).where(tmv.modelUid.eq(tmm.id)); - Optional content = + Optional content = Optional.ofNullable( queryFactory .select( Projections.constructor( - InferenceResultDto.AnalResSummary.class, + InferenceDetailDto.AnalResSummary.class, mapSheetAnalInferenceEntity.id, mapSheetAnalInferenceEntity.analTitle, tmm.modelNm.concat(" ").concat(tmv.modelVer).as("modelInfo"), @@ -228,7 +228,7 @@ public class MapSheetAnalDataInferenceRepositoryImpl * @return */ @Override - public Page getInferenceGeomList(Long id, SearchGeoReq searchGeoReq) { + public Page getInferenceGeomList(Long id, SearchGeoReq searchGeoReq) { Pageable pageable = searchGeoReq.toPageable(); BooleanBuilder builder = new BooleanBuilder(); @@ -257,11 +257,11 @@ public class MapSheetAnalDataInferenceRepositoryImpl builder.and(MapSheetAnalDataInferenceGeomEntity.mapSheetNum.in(mapSheetNum)); } - List content = + List content = queryFactory .select( Projections.constructor( - InferenceResultDto.Geom.class, + InferenceDetailDto.Geom.class, MapSheetAnalDataInferenceGeomEntity.compareYyyy, MapSheetAnalDataInferenceGeomEntity.targetYyyy, MapSheetAnalDataInferenceGeomEntity.classBeforeCd, diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepository.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepository.java similarity index 58% rename from src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepository.java rename to src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepository.java index d54bbad3..923c28b0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultMngRepository.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepository.java @@ -3,5 +3,5 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; import org.springframework.data.jpa.repository.JpaRepository; -public interface InferenceResultMngRepository - extends JpaRepository, InferenceResultMngRepositoryCustom {} +public interface MapSheetLearnRepository + extends JpaRepository, MapSheetLearnRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java new file mode 100644 index 00000000..f541f0c9 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java @@ -0,0 +1,10 @@ +package com.kamco.cd.kamcoback.postgres.repository.Inference; + +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; +import org.springframework.data.domain.Page; + +public interface MapSheetLearnRepositoryCustom { + + Page getInferenceMgnResultList(InferenceResultDto.SearchListReq req); +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java new file mode 100644 index 00000000..42231ee4 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java @@ -0,0 +1,76 @@ +package com.kamco.cd.kamcoback.postgres.repository.Inference; + +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity.mapSheetLearnEntity; + +import com.kamco.cd.kamcoback.common.utils.DateRange; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + @Override + public Page getInferenceMgnResultList(InferenceResultDto.SearchListReq req) { + Pageable pageable = req.toPageable(); + BooleanBuilder builder = new BooleanBuilder(); + + NumberExpression statusOrder = + new CaseBuilder().when(mapSheetLearnEntity.status.eq("Y")).then(0).otherwise(1); + + // 국유인 반영 여부 + if (StringUtils.isNotBlank(req.getApplyYn())) { + if ("Y".equalsIgnoreCase(req.getApplyYn())) { + builder.and(mapSheetLearnEntity.applyYn.isTrue()); + } else if ("N".equalsIgnoreCase(req.getApplyYn())) { + builder.and(mapSheetLearnEntity.applyYn.isNull().or(mapSheetLearnEntity.applyYn.isFalse())); + } + } + + // 국유인 반영일 + if (req.getStrtDttm() != null && req.getEndDttm() != null) { + builder.and( + mapSheetLearnEntity + .applyDttm + .goe(DateRange.start(req.getStrtDttm())) + .and(mapSheetLearnEntity.applyDttm.lt(DateRange.end(req.getEndDttm())))); + } + + // 제목 + if (StringUtils.isNotBlank(req.getTitle())) { + builder.and(mapSheetLearnEntity.title.equalsIgnoreCase(req.getTitle())); + } + + List content = + queryFactory + .select(mapSheetLearnEntity) + .from(mapSheetLearnEntity) + .where(builder) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(statusOrder.asc()) + .fetch(); + + Long total = + queryFactory + .select(mapSheetLearnEntity.count()) + .from(mapSheetLearnEntity) + .where(builder) + .fetchOne(); + + return new PageImpl<>(content, pageable, total == null ? 0L : total); + } +} 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 32464f83..03ccc90a 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 @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.JsonNode; import com.kamco.cd.kamcoback.common.enums.ApiConfigEnum.EnumDto; import com.kamco.cd.kamcoback.common.enums.CommonUseStatus; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.persistence.EntityNotFoundException; import java.time.ZoneId; @@ -62,8 +62,8 @@ public class MapInkxMngDto { @Schema(name = "MapListEntity", description = "목록 항목") public static class MapListEntity { - private InferenceResultDto.MapSheet scene50k; - private InferenceResultDto.MapSheet scene5k; + private InferenceDetailDto.MapSheet scene50k; + private InferenceDetailDto.MapSheet scene5k; private CommonUseStatus useInference; @JsonFormat( @@ -85,8 +85,8 @@ public class MapInkxMngDto { @Builder public MapListEntity( - InferenceResultDto.MapSheet scene50k, - InferenceResultDto.MapSheet scene5k, + InferenceDetailDto.MapSheet scene50k, + InferenceDetailDto.MapSheet scene5k, CommonUseStatus useInference, ZonedDateTime createdDttm, ZonedDateTime updatedDttm) { 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 bab97bbf..3c1fe32c 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 @@ -2,7 +2,7 @@ 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.inference.dto.InferenceDetailDto.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; From 8e8c09f2f6780ddcd00712e8f620086c2d4482ef Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Thu, 8 Jan 2026 18:08:09 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[KC-151]=20=EC=9E=AC=ED=95=A0=EB=8B=B9=20?= =?UTF-8?q?=EC=9D=B4=EC=A0=84=20=EB=A1=9C=EC=A7=81=EC=9C=BC=EB=A1=9C=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 --- .../kamcoback/label/dto/LabelAllocateDto.java | 13 ++--- .../label/service/LabelAllocateService.java | 20 +++++--- .../core/LabelAllocateCoreService.java | 11 +---- .../label/LabelAllocateRepositoryCustom.java | 8 +-- .../label/LabelAllocateRepositoryImpl.java | 49 ++++++++++--------- 5 files changed, 48 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java index 6314bfff..db764638 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java @@ -49,8 +49,7 @@ public class LabelAllocateDto { WAIT("대기"), ASSIGNED("배정"), SKIP("스킵"), - DONE("완료"), - COMPLETE("완료"); + DONE("완료"); private String desc; @@ -202,8 +201,6 @@ public class LabelAllocateDto { private Integer stage; private ZonedDateTime gukyuinDttm; private Long count; - private Long labelCnt; - private Long inspectorCnt; } @Getter @@ -235,10 +232,10 @@ public class LabelAllocateDto { @Schema( description = "이관할 라벨러", example = """ - [ - "87654321" - ] - """) + [ + "87654321" + ] + """) private List labelers; @Schema(description = "회차 마스터 key", example = "f97dc186-e6d3-4645-9737-3173dde8dc64") diff --git a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java index a344561e..ac9bd2f3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java @@ -12,9 +12,7 @@ import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.TargetUser; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.UserList; import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkerListResponse; import com.kamco.cd.kamcoback.postgres.core.LabelAllocateCoreService; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -123,7 +121,6 @@ public class LabelAllocateService { public ApiResponseDto.ResponseObj allocateMove( Integer totalCnt, String uuid, List targetUsers, String userId) { - Map result = new LinkedHashMap<>(); int userCount = targetUsers.size(); if (userCount <= 0) { return new ApiResponseDto.ResponseObj(ApiResponseCode.BAD_REQUEST, "재할당할 라벨러를 선택해주세요."); @@ -132,6 +129,11 @@ public class LabelAllocateService { int base = totalCnt / userCount; int remainder = totalCnt % userCount; + Long lastId = null; + List allIds = + labelAllocateCoreService.fetchNextMoveIds(lastId, totalCnt.longValue(), uuid, userId); + + int index = 0; for (int i = 0; i < userCount; i++) { int assignCount = base; @@ -140,11 +142,15 @@ public class LabelAllocateService { assignCount += remainder; } - result.put(targetUsers.get(i), assignCount); - // TODO: 재할당 테이블에 update 까지만 하고 나머지는 배치에서 처리하기? - labelAllocateCoreService.assignOwnerReAllocate( - uuid, userId, targetUsers.get(i), (long) assignCount); + // labelAllocateCoreService.assignOwnerReAllocate( + // uuid, userId, targetUsers.get(i), (long) assignCount); + + int end = index + assignCount; + List sub = allIds.subList(index, end); + + labelAllocateCoreService.assignOwnerMove(sub, targetUsers.get(i)); + index = end; } // Long lastId = null; diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java index 9c2e2612..ff7c00ba 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java @@ -87,15 +87,8 @@ public class LabelAllocateCoreService { return labelAllocateRepository.findInferenceDetail(uuid); } - public List fetchNextMoveIds( - Long lastId, - Long batchSize, - Integer compareYyyy, - Integer targetYyyy, - Integer stage, - String userId) { - return labelAllocateRepository.fetchNextMoveIds( - lastId, batchSize, compareYyyy, targetYyyy, stage, userId); + public List fetchNextMoveIds(Long lastId, Long batchSize, String uuid, String userId) { + return labelAllocateRepository.fetchNextMoveIds(lastId, batchSize, uuid, userId); } public void assignOwnerMove(List sub, String userId) { diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java index a1279830..350b30c2 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java @@ -54,13 +54,7 @@ public interface LabelAllocateRepositoryCustom { InferenceDetail findInferenceDetail(String uuid); - List fetchNextMoveIds( - Long lastId, - Long batchSize, - Integer compareYyyy, - Integer targetYyyy, - Integer stage, - String userId); + List fetchNextMoveIds(Long lastId, Long batchSize, String uuid, String userId); void assignOwnerMove(List sub, String userId); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java index 4ab96086..6d64776a 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java @@ -7,6 +7,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceG import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity; +import com.kamco.cd.kamcoback.common.enums.StatusType; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.AllocateInfoDto; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail; @@ -493,38 +494,35 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto Projections.constructor( InferenceDetail.class, mapSheetAnalInferenceEntity.analTitle, - Expressions.numberTemplate(Integer.class, "{0}", 4), + mapSheetAnalInferenceEntity.stage, mapSheetAnalInferenceEntity.gukyuinApplyDttm, - mapSheetAnalInferenceEntity.detectingCnt, - labelingAssignmentEntity.workerUid.countDistinct(), - labelingAssignmentEntity.inspectorUid.countDistinct())) + mapSheetAnalDataInferenceGeomEntity.geoUid.count())) .from(mapSheetAnalInferenceEntity) - .innerJoin(labelingAssignmentEntity) - .on(mapSheetAnalInferenceEntity.id.eq(labelingAssignmentEntity.analUid)) + .leftJoin(mapSheetAnalDataInferenceGeomEntity) + .on( + mapSheetAnalInferenceEntity.compareYyyy.eq( + mapSheetAnalDataInferenceGeomEntity.compareYyyy), + mapSheetAnalInferenceEntity.targetYyyy.eq( + mapSheetAnalDataInferenceGeomEntity.targetYyyy), + mapSheetAnalInferenceEntity.stage.eq(mapSheetAnalDataInferenceGeomEntity.stage), + mapSheetAnalDataInferenceGeomEntity.pnu.gt(0), + mapSheetAnalDataInferenceGeomEntity.passYn.isFalse()) .where(mapSheetAnalInferenceEntity.id.eq(analEntity.getId())) .groupBy( mapSheetAnalInferenceEntity.analTitle, + mapSheetAnalInferenceEntity.stage, mapSheetAnalInferenceEntity.gukyuinApplyDttm, mapSheetAnalInferenceEntity.detectingCnt) .fetchOne(); } @Override - public List fetchNextMoveIds( - Long lastId, - Long batchSize, - Integer compareYyyy, - Integer targetYyyy, - Integer stage, - String userId) { + public List fetchNextMoveIds(Long lastId, Long batchSize, String uuid, String userId) { MapSheetAnalInferenceEntity analEntity = queryFactory .selectFrom(mapSheetAnalInferenceEntity) - .where( - mapSheetAnalInferenceEntity.compareYyyy.eq(compareYyyy), - mapSheetAnalInferenceEntity.targetYyyy.eq(targetYyyy), - mapSheetAnalInferenceEntity.stage.eq(stage)) + .where(mapSheetAnalInferenceEntity.uuid.eq(UUID.fromString(uuid))) .fetchOne(); if (Objects.isNull(analEntity)) { @@ -539,7 +537,9 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto labelingAssignmentEntity.workState.eq(LabelState.ASSIGNED.getId()), labelingAssignmentEntity.analUid.eq(analEntity.getId()), lastId == null ? null : labelingAssignmentEntity.inferenceGeomUid.gt(lastId)) - .orderBy(labelingAssignmentEntity.inferenceGeomUid.asc()) + .orderBy( + labelingAssignmentEntity.assignGroupId.asc(), + labelingAssignmentEntity.inferenceGeomUid.asc()) .limit(batchSize) .fetch(); } @@ -574,7 +574,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto NumberExpression completeCnt = new CaseBuilder() - .when(labelingAssignmentEntity.workState.eq(LabelState.COMPLETE.getId())) + .when(labelingAssignmentEntity.workState.eq(LabelState.DONE.getId())) .then(1L) .otherwise((Long) null) .count(); @@ -1050,7 +1050,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto .when( labelingAssignmentEntity .workState - .eq(LabelState.COMPLETE.getId()) + .eq(LabelState.DONE.getId()) .or(labelingAssignmentEntity.workState.eq(LabelState.SKIP.getId()))) .then(1L) .otherwise(0L) @@ -1103,7 +1103,9 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto percent)) .from(labelingAssignmentEntity) .innerJoin(memberEntity) - .on(labelingAssignmentEntity.workerUid.eq(memberEntity.employeeNo)) + .on( + labelingAssignmentEntity.workerUid.eq(memberEntity.employeeNo), + memberEntity.status.eq(StatusType.ACTIVE.getId())) .where( labelingAssignmentEntity.analUid.eq(analEntity.getId()), labelingAssignmentEntity.workerUid.ne(userId)) @@ -1112,7 +1114,10 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto completeCnt .multiply(2) .goe(totalCnt)) // 진행률 평균 이상인 것들만 조회 => percent 를 바로 쓰면 having절에 무리가 갈 수 있다고 함 - .orderBy(completeCnt.desc()) // TODO: 도엽번호? PNU? 로 정렬하여 보여주기? + .orderBy( + completeCnt + .desc()) // TODO: 현재는 잔여건수가 제일 적은(=완료건수가 높은) 순서로 desc, 추후 도엽번호? PNU? 로 정렬하여 + // 보여주기? .fetch(); return new MoveInfo(userChargeCnt, list); From 3691a8271796a4ceff2e77d5805af16cf84f137f Mon Sep 17 00:00:00 2001 From: DanielLee <198891672+sanghyeonhd@users.noreply.github.com> Date: Thu, 8 Jan 2026 18:09:52 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=EB=9D=BC=EB=B2=A8=EB=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EA=B4=80=EB=A6=AC=20=EB=AA=A9=EB=A1=9D=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/label/dto/LabelWorkDto.java | 34 ++++++++- .../label/LabelWorkRepositoryImpl.java | 70 +++++++++++++------ 2 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java index cde2b946..d336eed4 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java @@ -37,7 +37,7 @@ public class LabelWorkDto { private UUID uuid; private Integer compareYyyy; private Integer targetYyyy; - private int stage; + private Integer stage; @JsonFormatDttm private ZonedDateTime createdDttm; private Long detectionTotCnt; private Long labelTotCnt; @@ -47,6 +47,15 @@ public class LabelWorkDto { private Long labelCompleteTotCnt; @JsonFormatDttm private ZonedDateTime labelStartDttm; + // tb_map_sheet_anal_inference.anal_state 컬럼 값 + private String analState; + + // tb_labeling_assignment 테이블에서 stagnation_yn = 'N'인 정상 진행 건수 + private Long normalProgressCnt; + + // tb_labeling_assignment 테이블에서 총 배정 건수 + private Long totalAssignmentCnt; + @JsonProperty("detectYear") public String getDetectYear() { if (compareYyyy == null || targetYyyy == null) { @@ -55,8 +64,16 @@ public class LabelWorkDto { return compareYyyy + "-" + targetYyyy; } + /** + * 라벨링 상태 반환 (tb_map_sheet_anal_inference.anal_state 기준) + */ public String getLabelState() { + // anal_state 값이 있으면 해당 값 사용 + if (this.analState != null && !this.analState.isEmpty()) { + return this.analState; + } + // anal_state 값이 없으면 기존 로직으로 폴백 String mngState = "PENDING"; if (this.labelTotCnt == 0) { @@ -79,14 +96,25 @@ public class LabelWorkDto { } LabelMngState type = Enums.fromId(LabelMngState.class, enumId); + // type이 null인 경우 (enum에 정의되지 않은 상태값) 상태값 자체를 반환 + if (type == null) { + return enumId; + } return type.getText(); } + /** + * 작업 진행률 반환 (tb_labeling_assignment.stagnation_yn = 'N'인 정상 진행율 기준) + * 계산식: (정상 진행 건수 / 총 배정 건수) * 100 + */ public double getLabelRate() { - if (this.labelTotCnt == null || this.labelCompleteTotCnt == 0) { + if (this.totalAssignmentCnt == null || this.totalAssignmentCnt == 0) { return 0.0; } - return (double) this.labelTotCnt / this.labelCompleteTotCnt * 100.0; + if (this.normalProgressCnt == null) { + return 0.0; + } + return (double) this.normalProgressCnt / this.totalAssignmentCnt * 100.0; } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java index dbef596a..b1fea3c1 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java @@ -14,6 +14,7 @@ import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity; import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.Expression; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; @@ -24,8 +25,6 @@ import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; import java.time.LocalDate; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -33,29 +32,23 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import org.springframework.stereotype.Repository; @Slf4j @Repository -public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport - implements LabelWorkRepositoryCustom { +@RequiredArgsConstructor +public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { private final JPAQueryFactory queryFactory; private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); - @PersistenceContext private EntityManager em; - - public LabelWorkRepositoryImpl(JPAQueryFactory queryFactory) { - super(MapSheetAnalDataInferenceGeomEntity.class); - this.queryFactory = queryFactory; - } /** * 변화탐지 년도 셀렉트박스 조회 @@ -129,6 +122,34 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport .and(mapSheetAnalDataInferenceGeomEntity.labelStateDttm.lt(end))); } + // labelTotCnt: pnu가 있고 pass_yn = false (부적합)인 건수만 라벨링 대상 + NumberExpression labelTotCntExpr = new CaseBuilder() + .when( + mapSheetAnalDataInferenceGeomEntity.pnu.isNotNull() + .and(mapSheetAnalDataInferenceGeomEntity.pnu.ne(0L)) + .and(mapSheetAnalDataInferenceGeomEntity.passYn.eq(Boolean.FALSE))) + .then(1L) + .otherwise(0L) + .sum(); + + // stagnation_yn = 'N'인 정상 진행 건수 (서브쿼리로 별도 집계) + Expression normalProgressCntSubQuery = + JPAExpressions.select( + new CaseBuilder() + .when(labelingAssignmentEntity.stagnationYn.eq('N')) + .then(1L) + .otherwise(0L) + .sum() + .coalesce(0L)) + .from(labelingAssignmentEntity) + .where(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id)); + + // 총 배정 건수 (서브쿼리로 별도 집계) + Expression totalAssignmentCntSubQuery = + JPAExpressions.select(labelingAssignmentEntity.count().coalesce(0L)) + .from(labelingAssignmentEntity) + .where(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id)); + List foundContent = queryFactory .select( @@ -138,17 +159,11 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport mapSheetAnalInferenceEntity.compareYyyy, mapSheetAnalInferenceEntity.targetYyyy, mapSheetAnalInferenceEntity.stage, - mapSheetAnalDataInferenceEntity.createdDttm.min(), + // createdDttm: tb_map_sheet_anal_inference.created_dttm 사용 + mapSheetAnalInferenceEntity.createdDttm, mapSheetAnalDataInferenceGeomEntity.dataUid.count(), - new CaseBuilder() - .when( - mapSheetAnalDataInferenceGeomEntity - .pnu - .isNotNull() - .and(mapSheetAnalDataInferenceGeomEntity.pnu.ne(0L))) - .then(1L) - .otherwise(0L) - .sum(), + // labelTotCnt: pnu 있고 pass_yn = false인 건수 + labelTotCntExpr, new CaseBuilder() .when(mapSheetAnalDataInferenceGeomEntity.labelState.eq("ASSIGNED")) .then(1L) @@ -169,7 +184,13 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport .then(1L) .otherwise(0L) .sum(), - mapSheetAnalDataInferenceGeomEntity.labelStateDttm.min())) + mapSheetAnalDataInferenceGeomEntity.labelStateDttm.min(), + // analState: tb_map_sheet_anal_inference.anal_state + mapSheetAnalInferenceEntity.analState, + // normalProgressCnt: stagnation_yn = 'N'인 건수 (서브쿼리) + normalProgressCntSubQuery, + // totalAssignmentCnt: 총 배정 건수 (서브쿼리) + totalAssignmentCntSubQuery)) .from(mapSheetAnalInferenceEntity) .innerJoin(mapSheetAnalDataInferenceEntity) .on(whereSubDataBuilder) @@ -180,7 +201,10 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport mapSheetAnalInferenceEntity.uuid, mapSheetAnalInferenceEntity.compareYyyy, mapSheetAnalInferenceEntity.targetYyyy, - mapSheetAnalInferenceEntity.stage) + mapSheetAnalInferenceEntity.stage, + mapSheetAnalInferenceEntity.createdDttm, + mapSheetAnalInferenceEntity.analState, + mapSheetAnalInferenceEntity.id) .orderBy( mapSheetAnalInferenceEntity.targetYyyy.desc(), mapSheetAnalInferenceEntity.compareYyyy.desc(), From 1a85c99ae4393dbf6c3ad71a2ea1de22f9ce6313 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Thu, 8 Jan 2026 18:31:38 +0900 Subject: [PATCH 6/7] spotless --- .../cd/kamcoback/label/dto/LabelWorkDto.java | 8 +++---- .../label/LabelWorkRepositoryImpl.java | 21 ++++++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java index d336eed4..4a695e82 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java @@ -64,9 +64,7 @@ public class LabelWorkDto { return compareYyyy + "-" + targetYyyy; } - /** - * 라벨링 상태 반환 (tb_map_sheet_anal_inference.anal_state 기준) - */ + /** 라벨링 상태 반환 (tb_map_sheet_anal_inference.anal_state 기준) */ public String getLabelState() { // anal_state 값이 있으면 해당 값 사용 if (this.analState != null && !this.analState.isEmpty()) { @@ -104,8 +102,8 @@ public class LabelWorkDto { } /** - * 작업 진행률 반환 (tb_labeling_assignment.stagnation_yn = 'N'인 정상 진행율 기준) - * 계산식: (정상 진행 건수 / 총 배정 건수) * 100 + * 작업 진행률 반환 (tb_labeling_assignment.stagnation_yn = 'N'인 정상 진행율 기준) 계산식: (정상 진행 건수 / 총 배정 건수) * + * 100 */ public double getLabelRate() { if (this.totalAssignmentCnt == null || this.totalAssignmentCnt == 0) { diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java index b1fea3c1..01aa986d 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java @@ -11,7 +11,6 @@ import com.kamco.cd.kamcoback.label.dto.LabelWorkDto; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMng; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMngDetail; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Expression; @@ -49,7 +48,6 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { private final JPAQueryFactory queryFactory; private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); - /** * 변화탐지 년도 셀렉트박스 조회 * @@ -123,14 +121,17 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { } // labelTotCnt: pnu가 있고 pass_yn = false (부적합)인 건수만 라벨링 대상 - NumberExpression labelTotCntExpr = new CaseBuilder() - .when( - mapSheetAnalDataInferenceGeomEntity.pnu.isNotNull() - .and(mapSheetAnalDataInferenceGeomEntity.pnu.ne(0L)) - .and(mapSheetAnalDataInferenceGeomEntity.passYn.eq(Boolean.FALSE))) - .then(1L) - .otherwise(0L) - .sum(); + NumberExpression labelTotCntExpr = + new CaseBuilder() + .when( + mapSheetAnalDataInferenceGeomEntity + .pnu + .isNotNull() + .and(mapSheetAnalDataInferenceGeomEntity.pnu.ne(0L)) + .and(mapSheetAnalDataInferenceGeomEntity.passYn.eq(Boolean.FALSE))) + .then(1L) + .otherwise(0L) + .sum(); // stagnation_yn = 'N'인 정상 진행 건수 (서브쿼리로 별도 집계) Expression normalProgressCntSubQuery = From 3cdfe2d42cd99d3a758cf9b99a55b3273675df62 Mon Sep 17 00:00:00 2001 From: DanielLee <198891672+sanghyeonhd@users.noreply.github.com> Date: Thu, 8 Jan 2026 18:45:46 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=EB=9D=BC=EB=B2=A8=EB=A7=81=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=A1=B0=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/label/dto/LabelWorkDto.java | 6 +- .../label/LabelWorkRepositoryImpl.java | 106 ++++++++++-------- 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java index d336eed4..d7cfce30 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java @@ -196,14 +196,14 @@ public class LabelWorkDto { @Schema(description = "1일전처리개수") private Long day1AgoDoneCnt; - public Long getremindCnt() { + public Long getRemainCnt() { return this.assignedCnt - this.doneCnt; } public double getDoneRate() { - Long dayDoneCnt = this.day3AgoDoneCnt + this.day2AgoDoneCnt + this.day1AgoDoneCnt; + long dayDoneCnt = this.day3AgoDoneCnt + this.day2AgoDoneCnt + this.day1AgoDoneCnt; - if (dayDoneCnt == null || dayDoneCnt == 0) { + if (dayDoneCnt == 0) { return 0.0; } return (double) dayDoneCnt / 3; diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java index b1fea3c1..85da4e69 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java @@ -1,18 +1,16 @@ package com.kamco.cd.kamcoback.postgres.repository.label; -import static com.kamco.cd.kamcoback.postgres.entity.QLabelingAssignmentEntity.labelingAssignmentEntity; -import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceEntity.mapSheetAnalDataInferenceEntity; -import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity.mapSheetAnalDataInferenceGeomEntity; -import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity; -import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity; - import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelState; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMng; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMngDetail; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity; +import com.kamco.cd.kamcoback.postgres.entity.QLabelingAssignmentEntity; +import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceEntity; +import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity; +import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity; +import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Expression; import com.querydsl.core.types.OrderSpecifier; @@ -22,7 +20,6 @@ import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.core.types.dsl.DateTimePath; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.NumberExpression; -import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; import java.time.LocalDate; @@ -31,6 +28,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -47,13 +45,24 @@ import org.springframework.stereotype.Repository; public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { private final JPAQueryFactory queryFactory; - private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); + + // Q클래스 필드 선언 + private final QMapSheetAnalInferenceEntity mapSheetAnalInferenceEntity = + QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity; + private final QMapSheetAnalDataInferenceEntity mapSheetAnalDataInferenceEntity = + QMapSheetAnalDataInferenceEntity.mapSheetAnalDataInferenceEntity; + private final QMapSheetAnalDataInferenceGeomEntity mapSheetAnalDataInferenceGeomEntity = + QMapSheetAnalDataInferenceGeomEntity.mapSheetAnalDataInferenceGeomEntity; + private final QLabelingAssignmentEntity labelingAssignmentEntity = + QLabelingAssignmentEntity.labelingAssignmentEntity; + private final QMemberEntity memberEntity = QMemberEntity.memberEntity; + /** * 변화탐지 년도 셀렉트박스 조회 * - * @return + * @return 변화탐지 년도 목록 (Entity 반환) */ @Override public List findChangeDetectYearList() { @@ -74,9 +83,10 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { /** * 라벨링 작업관리 목록 조회 + * (복잡한 집계 쿼리로 인해 DTO 직접 반환) * - * @param searchReq - * @return + * @param searchReq 검색 조건 + * @return 라벨링 작업관리 목록 페이지 */ @Override public Page labelWorkMngList(LabelWorkDto.LabelWorkMngSearchReq searchReq) { @@ -213,16 +223,19 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { .limit(pageable.getPageSize()) .fetch(); - Long total = - queryFactory - .select(mapSheetAnalInferenceEntity.uuid.countDistinct()) - .from(mapSheetAnalInferenceEntity) - .innerJoin(mapSheetAnalDataInferenceEntity) - .on(whereSubDataBuilder) - .innerJoin(mapSheetAnalDataInferenceGeomEntity) - .on(whereSubBuilder) - .where(whereBuilder) - .fetchOne(); + // Count 쿼리 별도 실행 (null safe handling) + long total = + Optional.ofNullable( + queryFactory + .select(mapSheetAnalInferenceEntity.uuid.countDistinct()) + .from(mapSheetAnalInferenceEntity) + .innerJoin(mapSheetAnalDataInferenceEntity) + .on(whereSubDataBuilder) + .innerJoin(mapSheetAnalDataInferenceGeomEntity) + .on(whereSubBuilder) + .where(whereBuilder) + .fetchOne()) + .orElse(0L); return new PageImpl<>(foundContent, pageable, total); } @@ -319,21 +332,23 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { .limit(pageable.getPageSize()) .fetch(); - Long countQuery = - queryFactory - .select(labelingAssignmentEntity.workerUid.countDistinct()) - .from(labelingAssignmentEntity) - .innerJoin(mapSheetAnalInferenceEntity) - .on( - mapSheetAnalInferenceEntity - .uuid - .eq(uuid) - .and(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id))) - .innerJoin(memberEntity) - .on(whereSubBuilder) - .where(whereBuilder) - // .groupBy(memberEntity.userRole, memberEntity.name, memberEntity.userId) - .fetchOne(); + // Count 쿼리 별도 실행 (null safe handling) + long countQuery = + Optional.ofNullable( + queryFactory + .select(labelingAssignmentEntity.workerUid.countDistinct()) + .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + mapSheetAnalInferenceEntity + .uuid + .eq(uuid) + .and(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id))) + .innerJoin(memberEntity) + .on(whereSubBuilder) + .where(whereBuilder) + .fetchOne()) + .orElse(0L); return new PageImpl<>(foundContent, pageable, countQuery); } @@ -374,9 +389,10 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { /** * 작업배정 상세조회 + * (복잡한 집계 쿼리로 인해 DTO 직접 반환) * - * @param uuid - * @return + * @param uuid 작업배정 UUID + * @return 작업배정 상세 정보 */ @Override public LabelWorkMngDetail findLabelWorkMngDetail(UUID uuid) { @@ -418,19 +434,13 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { } public NumberExpression caseSumExpression(BooleanExpression condition) { - NumberExpression sumExp = new CaseBuilder().when(condition).then(1L).otherwise(0L).sum(); - - return sumExp; + return new CaseBuilder().when(condition).then(1L).otherwise(0L).sum(); } public BooleanExpression fromDateEqExpression(DateTimePath path, int addDayCnt) { - LocalDate threeDaysAgo = LocalDate.now().plusDays(addDayCnt); - String toDate = threeDaysAgo.format(DateTimeFormatter.ofPattern("YYYY-MM-DD")); + String toDate = threeDaysAgo.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); - BooleanExpression condition = - Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", path).eq(toDate); - - return condition; + return Expressions.stringTemplate("to_char({0}, 'yyyy-MM-dd')", path).eq(toDate); } }