From f3453ab499f59b017e47103872d2b695e1c4b45b Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 30 Jan 2026 12:04:11 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=96=B4=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamco/cd/kamcoback/layer/dto/LayerDto.java | 5 +++++ .../postgres/core/MapLayerCoreService.java | 15 ++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/layer/dto/LayerDto.java b/src/main/java/com/kamco/cd/kamcoback/layer/dto/LayerDto.java index 98d18422..4ad12d51 100644 --- a/src/main/java/com/kamco/cd/kamcoback/layer/dto/LayerDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/layer/dto/LayerDto.java @@ -408,4 +408,9 @@ public class LayerDto { @Schema(description = "노출여부 true, false", example = "true") private Boolean isMapYn; } + + public enum MapType { + CHANGE_MAP, + LABELING_MAP + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapLayerCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapLayerCoreService.java index 09af8b01..11368382 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapLayerCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapLayerCoreService.java @@ -147,13 +147,18 @@ public class MapLayerCoreService { .findDetailByUuid(uuid) .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND)); - if ("CHANGE_MAP".equals(isMapYn.getMapType())) { - entity.setIsChangeMap(isMapYn.getIsMapYn()); - } else if ("LABELING_MAP".equals(isMapYn.getMapType())) { - entity.setIsLabelingMap(isMapYn.getIsMapYn()); - } else { + LayerDto.MapType mapType; + + try { + mapType = LayerDto.MapType.valueOf(isMapYn.getMapType()); + } catch (IllegalArgumentException e) { throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST); } + + switch (mapType) { + case CHANGE_MAP -> entity.setIsChangeMap(isMapYn.getIsMapYn()); + case LABELING_MAP -> entity.setIsLabelingMap(isMapYn.getIsMapYn()); + } } /** From df8bac950b6056268c94ccbac2c3ff49cc153ab2 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Fri, 30 Jan 2026 13:30:13 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=EA=B5=AD=EC=9C=A0=EC=9D=B8=20API=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gukyuin/GukYuinApiController.java | 16 +- .../gukyuin/dto/ChngDetectMastDto.java | 56 +++++- .../cd/kamcoback/gukyuin/dto/GukYuinDto.java | 33 +++- .../kamcoback/gukyuin/dto/GukYuinStatus.java | 1 + .../gukyuin/service/GukYuinApiService.java | 167 +++++++++++++++++- .../postgres/core/GukYuinCoreService.java | 13 ++ .../postgres/core/GukYuinJobCoreService.java | 14 +- .../postgres/entity/MapSheetLearnEntity.java | 3 + .../gukyuin/GukYuinRepositoryCustom.java | 16 +- .../gukyuin/GukYuinRepositoryImpl.java | 101 ++++++++++- .../service/GukYuinApiJobService.java | 83 +++++++-- 11 files changed, 453 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java index 2217b939..a7ab2e43 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java @@ -1,6 +1,7 @@ package com.kamco.cd.kamcoback.gukyuin; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ChnDetectMastReqDto; @@ -51,7 +52,7 @@ public class GukYuinApiController { @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @PostMapping("/chn/mast/regist") - public ApiResponseDto regist( + public ApiResponseDto regist( @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { return ApiResponseDto.ok(gukYuinApiService.regist(chnDetectMastReq)); } @@ -133,9 +134,9 @@ public class GukYuinApiController { @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) - public ApiResponseDto selectChangeDetectionList( + public ApiResponseDto selectChangeDetectionDetail( @PathVariable String chnDtctMstId) { - return ApiResponseDto.ok(gukYuinApiService.list(chnDtctMstId)); + return ApiResponseDto.ok(gukYuinApiService.detail(chnDtctMstId)); } @Operation(summary = "국유in연동 가능여부 확인", description = "국유in연동 가능여부 확인") @@ -239,4 +240,13 @@ public class GukYuinApiController { @PathVariable String chnDtctObjtId, @PathVariable String lblYn) { return ApiResponseDto.ok(gukYuinApiService.updateChnDtctObjtLabelingYn(chnDtctObjtId, lblYn)); } + + @Operation(summary = "국유in연동 등록", description = "국유in연동 등록") + @GetMapping("/mast/reg/{uuid}") + public ApiResponseDto connectChnMastRegist( + @Parameter(description = "uuid", example = "7a593d0e-76a8-4b50-8978-9af1fbe871af") + @PathVariable + UUID uuid) { + return ApiResponseDto.ok(gukYuinApiService.connectChnMastRegist(uuid)); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/ChngDetectMastDto.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/ChngDetectMastDto.java index 35d1febe..772448c7 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/ChngDetectMastDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/ChngDetectMastDto.java @@ -66,13 +66,30 @@ public class ChngDetectMastDto { @AllArgsConstructor public static class ChnDetectMastReqDto { - private String cprsYr; // 비교년도 2023 - private String crtrYr; // 기준년도 2024 - private String chnDtctSno; // 차수 (1 | 2 | ...) - private String chnDtctId; // 탐지아이디. UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성 - private String pathNm; // 탐지결과 절대경로명 /kamco_nas/export/{chnDtctId} - private String reqEpno; // 사원번호 - private String reqIp; // 사원아이피 + @Schema(description = "비교년도", example = "2023") + private String cprsYr; + + @Schema(description = "기준년도", example = "2024") + private String crtrYr; + + @Schema(description = "차수", example = "1") + private String chnDtctSno; + + @Schema( + description = "탐지아이디, UUID를 기반으로 '-'를 제거하고 대문자/숫자로 구성", + example = "D5F192EC76D34F6592035BE63A84F591") + private String chnDtctId; + + @Schema( + description = "탐지결과 절대경로명 /kamco_nas/export/{chnDtctId}", + example = "/kamco-nfs/dataset/export/D5F192EC76D34F6592035BE63A84F591") + private String pathNm; + + @Schema(description = "사원번호", example = "123456") + private String reqEpno; + + @Schema(description = "사원아이피", example = "127.0.0.1") + private String reqIp; } @Getter @@ -158,4 +175,29 @@ public class ChngDetectMastDto { private List result; private Boolean success; } + + @Schema(name = "RegistResDto", description = "reg 등록 후 리턴 형태") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class RegistResDto { + + private Integer code; + private String message; + private Basic result; + private Boolean success; + } + + @Schema(name = "LearnKeyDto", description = "learn 엔티티 key 정보") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class LearnKeyDto { + + private Long id; + private String uid; + private String chnDtctMstId; + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinDto.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinDto.java index d236bfb4..652a00fc 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinDto.java @@ -1,21 +1,13 @@ package com.kamco.cd.kamcoback.gukyuin.dto; import com.kamco.cd.kamcoback.common.utils.enums.EnumType; +import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; public class GukYuinDto { - @Getter - @Setter - public static class GukYuinLinkableRes { - - private boolean linkable; - // private GukYuinLinkFailCode code; - private String message; - } - /** 실패 코드 enum */ @Getter @AllArgsConstructor @@ -39,10 +31,33 @@ public class GukYuinDto { } } + @Getter + @Setter + public static class GukYuinLinkableRes { + + private boolean linkable; + // private GukYuinLinkFailCode code; + private String message; + } + // Repository가 반환할 Fact(조회 결과) public record GukYuinLinkFacts( boolean existsLearn, boolean isPartScope, boolean hasRunningInference, boolean hasOtherUnfinishedGukYuin) {} + + @Getter + @Setter + @AllArgsConstructor + public static class LearnInfo { + + private Long id; + private UUID uuid; + private Integer compareYyyy; + private Integer targetYyyy; + private Integer stage; + private String uid; + private String applyStatus; + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinStatus.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinStatus.java index 174e9714..e6472c04 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinStatus.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/dto/GukYuinStatus.java @@ -11,6 +11,7 @@ public enum GukYuinStatus implements EnumType { IN_PROGRESS("진행중"), GUK_COMPLETED("국유인 매핑 완료"), PNU_COMPLETED("PNU 싱크 완료"), + PNU_FAILED("PNU 싱크 중 에러"), CANCELED("취소"); private final String desc; diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java index 82fec220..84b2d172 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java @@ -1,6 +1,10 @@ package com.kamco.cd.kamcoback.gukyuin.service; import com.kamco.cd.kamcoback.common.utils.NetUtils; +import com.kamco.cd.kamcoback.common.utils.UserUtil; +import com.kamco.cd.kamcoback.config.api.ApiLogFunction; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient; import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto; @@ -8,22 +12,31 @@ import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ContBasic; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ResultContDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ResultPnuDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto; +import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ChnDetectMastReqDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ResReturn; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ResultDto; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkFacts; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkFailCode; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkableRes; +import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo; +import com.kamco.cd.kamcoback.log.dto.EventStatus; +import com.kamco.cd.kamcoback.log.dto.EventType; import com.kamco.cd.kamcoback.postgres.core.GukYuinCoreService; +import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity; +import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +@Slf4j @Service -@Transactional(readOnly = true) +@Transactional @RequiredArgsConstructor public class GukYuinApiService { @@ -31,6 +44,9 @@ public class GukYuinApiService { private final ExternalHttpClient externalHttpClient; private final NetUtils netUtils = new NetUtils(); + private final UserUtil userUtil; + private final AuditLogRepository auditLogRepository; + @Value("${spring.profiles.active:local}") private String profile; @@ -41,25 +57,42 @@ public class GukYuinApiService { private String gukyuinCdiUrl; @Transactional - public ChngDetectMastDto.Basic regist(ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { + public ChngDetectMastDto.RegistResDto regist( + ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { String url = gukyuinCdiUrl + "/chn/mast/regist"; String myip = netUtils.getLocalIP(); chnDetectMastReq.setReqIp(myip); - chnDetectMastReq.setReqEpno("1234567"); // TODO + chnDetectMastReq.setReqEpno(userUtil.getEmployeeNo()); - ExternalCallResult result = + ExternalCallResult result = externalHttpClient.call( url, HttpMethod.POST, chnDetectMastReq, netUtils.jsonHeaders(), - ChngDetectMastDto.Basic.class); + ChngDetectMastDto.RegistResDto.class); - ChngDetectMastDto.Basic resultBody = result.body(); - gukyuinCoreService.updateGukYuinMastRegResult(resultBody); + ChngDetectMastDto.RegistResDto resultBody = result.body(); + Boolean success = null; + if (resultBody != null) { + ChngDetectMastDto.Basic registRes = resultBody.getResult(); + // 추론 회차에 applyStatus, applyStatusDttm 업데이트 + gukyuinCoreService.updateGukYuinMastRegResult(registRes); + // anal_inference 에도 국유인 반영여부, applyDttm 업데이트 + gukyuinCoreService.updateAnalInferenceApplyDttm(registRes); + success = resultBody.getSuccess(); + } + + this.insertGukyuinAuditLog( + EventType.ADDED.getId(), + myip, + userUtil.getId(), + url.replace(gukyuinUrl, ""), + chnDetectMastReq, + success); return resultBody; } @@ -69,7 +102,7 @@ public class GukYuinApiService { String myip = netUtils.getLocalIP(); chnDetectMastReq.setReqIp(myip); - chnDetectMastReq.setReqEpno("1234567"); // TODO + chnDetectMastReq.setReqEpno(userUtil.getEmployeeNo()); ExternalCallResult result = externalHttpClient.call( @@ -82,11 +115,18 @@ public class GukYuinApiService { ChngDetectMastDto.Basic resultBody = result.body(); gukyuinCoreService.updateGukYuinMastRegRemove(resultBody); + this.insertGukyuinAuditLog( + EventType.REMOVE.getId(), + myip, + userUtil.getId(), + url.replace(gukyuinUrl, ""), + chnDetectMastReq, + true); // TODO : successFail 여부 return new ResReturn("success", "탐지결과 삭제 되었습니다."); } // 등록목록 1개 확인 - public ChngDetectMastDto.ResultDto list(String chnDtctMstId) { + public ChngDetectMastDto.ResultDto detail(String chnDtctMstId) { String url = gukyuinCdiUrl + "/chn/mast/list/" + chnDtctMstId; @@ -94,6 +134,13 @@ public class GukYuinApiService { externalHttpClient.call( url, HttpMethod.GET, null, netUtils.jsonHeaders(), ChngDetectMastDto.ResultDto.class); + this.insertGukyuinAuditLog( + EventType.DETAIL.getId(), + netUtils.getLocalIP(), + userUtil.getId(), + url.replace(gukyuinUrl, ""), + null, + result.body().getSuccess()); return result.body(); } @@ -108,6 +155,13 @@ public class GukYuinApiService { externalHttpClient.call( url, HttpMethod.GET, null, netUtils.jsonHeaders(), ChngDetectMastDto.ResultDto.class); + this.insertGukyuinAuditLog( + EventType.LIST.getId(), + netUtils.getLocalIP(), + userUtil.getId(), + url.replace(gukyuinUrl, ""), + null, + result.body().getSuccess()); return result.body(); } @@ -188,6 +242,14 @@ public class GukYuinApiService { } } + this.insertGukyuinAuditLog( + EventType.LIST.getId(), + netUtils.getLocalIP(), + userUtil.getId(), + url.replace(gukyuinUrl, ""), + null, + result.body().getSuccess()); + return result.body(); } @@ -202,6 +264,14 @@ public class GukYuinApiService { netUtils.jsonHeaders(), ChngDetectContDto.ResultPnuDto.class); + this.insertGukyuinAuditLog( + EventType.DETAIL.getId(), + netUtils.getLocalIP(), + userUtil.getId(), + url.replace(gukyuinUrl, ""), + null, + result.body().getSuccess()); + return result.body(); } @@ -218,6 +288,14 @@ public class GukYuinApiService { ChngDetectContDto.ResultPnuDto dto = result.body(); + this.insertGukyuinAuditLog( + EventType.MODIFIED.getId(), + netUtils.getLocalIP(), + userUtil.getId(), + url.replace(gukyuinUrl, ""), + null, + result.body().getSuccess()); + return new ResReturn(dto.getCode() > 200000 ? "fail" : "success", dto.getMessage()); } @@ -232,6 +310,13 @@ public class GukYuinApiService { netUtils.jsonHeaders(), ChngDetectContDto.ResultContDto.class); + this.insertGukyuinAuditLog( + EventType.LIST.getId(), + netUtils.getLocalIP(), + userUtil.getId(), + url.replace(gukyuinUrl, ""), + null, + result.body().getSuccess()); return result.body(); } @@ -242,6 +327,70 @@ public class GukYuinApiService { externalHttpClient.call( url, HttpMethod.GET, null, netUtils.jsonHeaders(), ChngDetectMastDto.ResultDto.class); + this.insertGukyuinAuditLog( + EventType.DETAIL.getId(), + netUtils.getLocalIP(), + userUtil.getId(), + url.replace(gukyuinUrl, ""), + null, + result.body().getSuccess()); + return result.body(); } + + @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false) + public void insertGukyuinAuditLog( + String actionType, + String myIp, + Long userUid, + String requestUri, + Object requestBody, + boolean successFail) { + try { + AuditLogEntity log = + new AuditLogEntity( + userUid, + EventType.fromName(actionType), + successFail ? EventStatus.SUCCESS : EventStatus.FAILED, + "GUKYUIN", // 메뉴도 국유인으로 하나 따기 + myIp, + requestUri, + requestBody == null ? null : ApiLogFunction.cutRequestBody(requestBody.toString()), + null, + null, + null); + auditLogRepository.save(log); + + } catch (Exception e) { + log.error(e.getMessage()); + throw e; + } + } + + public ResponseObj connectChnMastRegist(UUID uuid) { + // uuid로 추론 회차 조회 + LearnInfo info = gukyuinCoreService.findMapSheetLearnInfo(uuid); + // if (info.getApplyStatus() != null && + // !info.getApplyStatus().equals(GukYuinStatus.PENDING.getId())) + // { + // return new ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 국유인 연동을 한 추론 회차입니다."); + // } + + // 비교년도,기준년도로 전송한 데이터 있는지 확인 후 회차 번호 생성 + Integer maxStage = + gukyuinCoreService.findMapSheetLearnYearStage(info.getCompareYyyy(), info.getTargetYyyy()); + + // reqDto 셋팅 + ChnDetectMastReqDto reqDto = new ChnDetectMastReqDto(); + reqDto.setCprsYr(String.valueOf(info.getCompareYyyy())); + reqDto.setCrtrYr(String.valueOf(info.getTargetYyyy())); + reqDto.setChnDtctSno(String.valueOf(maxStage + 1)); + reqDto.setChnDtctId(info.getUid()); + reqDto.setPathNm("/kamco-nfs/dataset/export/" + info.getUid()); + + // 국유인 /chn/mast/regist 전송 + this.regist(reqDto); + + return new ResponseObj(ApiResponseCode.OK, ""); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinCoreService.java index 49dab3ac..4a924f01 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinCoreService.java @@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.postgres.core; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.Basic; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.GukYuinLinkFacts; +import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo; import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetLearnRepository; import com.kamco.cd.kamcoback.postgres.repository.gukyuin.GukYuinRepository; import java.util.UUID; @@ -44,4 +45,16 @@ public class GukYuinCoreService { public void insertGeoUidPnuData(Long geoUid, String[] pnuList) { gukYuinRepository.insertGeoUidPnuData(geoUid, pnuList); } + + public LearnInfo findMapSheetLearnInfo(UUID uuid) { + return gukYuinRepository.findMapSheetLearnInfo(uuid); + } + + public Integer findMapSheetLearnYearStage(Integer compareYyyy, Integer targetYyyy) { + return gukYuinRepository.findMapSheetLearnYearStage(compareYyyy, targetYyyy); + } + + public void updateAnalInferenceApplyDttm(Basic registRes) { + gukYuinRepository.updateAnalInferenceApplyDttm(registRes); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinJobCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinJobCoreService.java index d0a32e25..8c234dab 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinJobCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinJobCoreService.java @@ -1,5 +1,7 @@ package com.kamco.cd.kamcoback.postgres.core; +import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LearnKeyDto; +import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinStatus; import com.kamco.cd.kamcoback.postgres.repository.gukyuin.GukYuinRepository; import java.util.List; import org.springframework.stereotype.Service; @@ -13,11 +15,15 @@ public class GukYuinJobCoreService { this.gukYuinRepository = gukYuinRepository; } - public List findGukyuinApplyIngUidList() { - return gukYuinRepository.findGukyuinApplyIngUidList(); + public void updateGukYuinApplyStateComplete(Long id, GukYuinStatus status) { + gukYuinRepository.updateGukYuinApplyStateComplete(id, status); } - public void updateGukYuinApplyStateComplete(String uid) { - gukYuinRepository.updateGukYuinApplyStateComplete(uid); + public List findGukyuinApplyStatusUidList(GukYuinStatus gukYuinStatus) { + return gukYuinRepository.findGukyuinApplyStatusUidList(gukYuinStatus); + } + + public void upsertMapSheetDataAnalGeomPnu(String chnDtctObjtId, String[] pnuList) { + gukYuinRepository.upsertMapSheetDataAnalGeomPnu(chnDtctObjtId, pnuList); } } 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 fa6ab43f..a161c05d 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 @@ -199,6 +199,9 @@ public class MapSheetLearnEntity { @Column(name = "total_jobs") private Long totalJobs; + @Column(name = "chn_dtct_mst_id") + private String chnDtctMstId; + public InferenceResultDto.ResultList toDto() { return new InferenceResultDto.ResultList( this.uuid, diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryCustom.java index ae7763ef..ced7c08c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryCustom.java @@ -1,7 +1,11 @@ package com.kamco.cd.kamcoback.postgres.repository.gukyuin; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.Basic; +import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LearnKeyDto; +import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo; +import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinStatus; import java.util.List; +import java.util.UUID; public interface GukYuinRepositoryCustom { @@ -15,7 +19,15 @@ public interface GukYuinRepositoryCustom { void insertGeoUidPnuData(Long geoUid, String[] pnuList); - List findGukyuinApplyIngUidList(); + void updateGukYuinApplyStateComplete(Long id, GukYuinStatus status); - void updateGukYuinApplyStateComplete(String uid); + List findGukyuinApplyStatusUidList(GukYuinStatus gukYuinStatus); + + void upsertMapSheetDataAnalGeomPnu(String uid, String[] pnuList); + + LearnInfo findMapSheetLearnInfo(UUID uuid); + + Integer findMapSheetLearnYearStage(Integer compareYyyy, Integer targetYyyy); + + void updateAnalInferenceApplyDttm(Basic registRes); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryImpl.java index cf7ba85f..281b5f70 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinRepositoryImpl.java @@ -1,17 +1,24 @@ package com.kamco.cd.kamcoback.postgres.repository.gukyuin; 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.QMapSheetLearnEntity.mapSheetLearnEntity; import static com.kamco.cd.kamcoback.postgres.entity.QPnuEntity.pnuEntity; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.Basic; +import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LearnKeyDto; +import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinDto.LearnInfo; import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinStatus; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.transaction.Transactional; import java.time.ZonedDateTime; import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -37,6 +44,7 @@ public class GukYuinRepositoryImpl implements GukYuinRepositoryCustom { .set(mapSheetLearnEntity.stage, stage) .set(mapSheetLearnEntity.applyStatus, status.getId()) .set(mapSheetLearnEntity.applyStatusDttm, ZonedDateTime.now()) + .set(mapSheetLearnEntity.chnDtctMstId, resultBody.getChnDtctMstId()) .where(mapSheetLearnEntity.uid.eq(resultBody.getChnDtctId())) .execute(); } @@ -81,22 +89,103 @@ public class GukYuinRepositoryImpl implements GukYuinRepositoryCustom { } @Override - public List findGukyuinApplyIngUidList() { + public List findGukyuinApplyStatusUidList(GukYuinStatus status) { return queryFactory - .select(mapSheetLearnEntity.uid) + .select( + Projections.constructor( + LearnKeyDto.class, + mapSheetLearnEntity.id, + mapSheetLearnEntity.uid, + mapSheetLearnEntity.chnDtctMstId)) .from(mapSheetLearnEntity) - .where(mapSheetLearnEntity.applyStatus.eq(GukYuinStatus.IN_PROGRESS.getId())) + .where(mapSheetLearnEntity.applyStatus.eq(status.getId())) .fetch(); } + @Override + public void upsertMapSheetDataAnalGeomPnu(String chnDtctObjtId, String[] pnuList) { + long length = pnuList.length; + queryFactory + .update(mapSheetAnalDataInferenceGeomEntity) + .set(mapSheetAnalDataInferenceGeomEntity.pnu, length) + .where(mapSheetAnalDataInferenceGeomEntity.resultUid.eq(chnDtctObjtId)) + .execute(); + + Long geoUid = + queryFactory + .select(mapSheetAnalDataInferenceGeomEntity.geoUid) + .from(mapSheetAnalDataInferenceGeomEntity) + .where(mapSheetAnalDataInferenceGeomEntity.resultUid.eq(chnDtctObjtId)) + .fetchOne(); + + for (int i = 0; i < length; i++) { + queryFactory + .insert(pnuEntity) + .columns(pnuEntity.geo.geoUid, pnuEntity.pnu, pnuEntity.createdDttm) + .values(geoUid, pnuList[i], ZonedDateTime.now()) + .execute(); + } + } + + @Override + public LearnInfo findMapSheetLearnInfo(UUID uuid) { + return queryFactory + .select( + Projections.constructor( + LearnInfo.class, + mapSheetLearnEntity.id, + mapSheetLearnEntity.uuid, + mapSheetLearnEntity.compareYyyy, + mapSheetLearnEntity.targetYyyy, + mapSheetLearnEntity.stage, + mapSheetLearnEntity.uid, + mapSheetLearnEntity.applyStatus)) + .from(mapSheetLearnEntity) + .where(mapSheetLearnEntity.uuid.eq(uuid)) + .fetchOne(); + } + + @Override + public Integer findMapSheetLearnYearStage(Integer compareYyyy, Integer targetYyyy) { + NumberExpression stageExpr = + Expressions.numberTemplate(Integer.class, "coalesce({0}, 0)", mapSheetLearnEntity.stage); + + return queryFactory + .select(stageExpr.max()) + .from(mapSheetLearnEntity) + .where( + mapSheetLearnEntity.compareYyyy.eq(compareYyyy), + mapSheetLearnEntity.targetYyyy.eq(targetYyyy), + mapSheetLearnEntity.applyStatus.isNotNull(), + mapSheetLearnEntity.applyStatus.ne(GukYuinStatus.PENDING.getId())) + .fetchOne(); + } + + @Override + public void updateAnalInferenceApplyDttm(Basic registRes) { + Long learnId = + queryFactory + .select(mapSheetLearnEntity.id) + .from(mapSheetLearnEntity) + .where(mapSheetLearnEntity.uid.eq(registRes.getChnDtctId())) + .fetchOne(); + + queryFactory + .update(mapSheetAnalInferenceEntity) + .set(mapSheetAnalInferenceEntity.gukyuinUsed, "Y") + .set(mapSheetAnalInferenceEntity.gukyuinApplyDttm, ZonedDateTime.now()) + .where(mapSheetAnalInferenceEntity.learnId.eq(learnId)) + .execute(); + } + @Override @Transactional - public void updateGukYuinApplyStateComplete(String uid) { + public void updateGukYuinApplyStateComplete(Long id, GukYuinStatus status) { queryFactory .update(mapSheetLearnEntity) - .set(mapSheetLearnEntity.applyStatus, GukYuinStatus.PNU_COMPLETED.getId()) + .set(mapSheetLearnEntity.applyStatus, status.getId()) .set(mapSheetLearnEntity.applyStatusDttm, ZonedDateTime.now()) - .where(mapSheetLearnEntity.uid.eq(uid)) + .where(mapSheetLearnEntity.id.eq(id)) .execute(); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/GukYuinApiJobService.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/GukYuinApiJobService.java index 2d7533a8..c537ce90 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/GukYuinApiJobService.java +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/GukYuinApiJobService.java @@ -1,7 +1,11 @@ package com.kamco.cd.kamcoback.scheduler.service; +import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto; +import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectContDto.ResultContDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto; +import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.LearnKeyDto; import com.kamco.cd.kamcoback.gukyuin.dto.ChngDetectMastDto.ResultDto; +import com.kamco.cd.kamcoback.gukyuin.dto.GukYuinStatus; import com.kamco.cd.kamcoback.gukyuin.service.GukYuinApiService; import com.kamco.cd.kamcoback.postgres.core.GukYuinJobCoreService; import java.util.List; @@ -31,23 +35,24 @@ public class GukYuinApiJobService { return "local".equalsIgnoreCase(profile); } - @Scheduled(cron = "0 0/10 * * * *") + @Scheduled(cron = "0 * * * * *") // 0 0/10 * * * * public void findGukYuinMastCompleteYn() { - if (isLocalProfile()) { - return; - } + // if (isLocalProfile()) { + // return; + // } - List list = gukYuinJobCoreService.findGukyuinApplyIngUidList(); + List list = + gukYuinJobCoreService.findGukyuinApplyStatusUidList(GukYuinStatus.IN_PROGRESS); if (list.isEmpty()) { return; } - for (String uid : list) { + for (LearnKeyDto dto : list) { try { - ResultDto result = gukYuinApiService.listChnDtctId(uid); + ResultDto result = gukYuinApiService.detail(dto.getChnDtctMstId()); if (result == null || result.getResult() == null || result.getResult().isEmpty()) { - log.warn("[GUKYUIN] empty result uid={}", uid); + log.warn("[GUKYUIN] empty result chnDtctMstId={}", dto.getChnDtctMstId()); continue; } @@ -56,10 +61,11 @@ public class GukYuinApiJobService { Integer progress = basic.getExcnPgrt() == null ? null : Integer.parseInt(basic.getExcnPgrt().trim()); if (progress != null && progress == 100) { - gukYuinJobCoreService.updateGukYuinApplyStateComplete(uid); + gukYuinJobCoreService.updateGukYuinApplyStateComplete( + dto.getId(), GukYuinStatus.GUK_COMPLETED); } } catch (Exception e) { - log.error("[GUKYUIN] failed uid={}", uid, e); + log.error("[GUKYUIN] failed uid={}", dto.getChnDtctMstId(), e); } } } @@ -69,5 +75,62 @@ public class GukYuinApiJobService { if (isLocalProfile()) { return; } + + List list = + gukYuinJobCoreService.findGukyuinApplyStatusUidList(GukYuinStatus.GUK_COMPLETED); + if (list.isEmpty()) { + return; + } + + for (LearnKeyDto dto : list) { + try { + processUid(dto.getChnDtctMstId(), dto.getUid()); + gukYuinJobCoreService.updateGukYuinApplyStateComplete( + dto.getId(), GukYuinStatus.PNU_COMPLETED); + } catch (Exception e) { + log.error("[GUKYUIN] failed uid={}", dto.getUid(), e); + gukYuinJobCoreService.updateGukYuinApplyStateComplete( + dto.getId(), GukYuinStatus.PNU_FAILED); + } + } + } + + private void processUid(String chnDtctMstId, String uid) { + ResultDto result = gukYuinApiService.detail(chnDtctMstId); + if (result == null || result.getResult() == null || result.getResult().isEmpty()) { + return; + } + + ChngDetectMastDto.Basic basic = result.getResult().get(0); + String chnDtctCnt = basic.getChnDtctCnt(); + if (chnDtctCnt == null || chnDtctCnt.isEmpty()) { + return; + } + + // page 계산 + int pageSize = 100; + int totalCount = Integer.parseInt(chnDtctCnt); + int totalPages = (totalCount + pageSize - 1) / pageSize; + + for (int page = 0; page < totalPages; page++) { + processPage(uid, page, pageSize); + } + } + + private void processPage(String uid, int page, int pageSize) { + ResultContDto cont = gukYuinApiService.findChnContList(uid, page, pageSize); + if (cont == null || cont.getResult().isEmpty()) { + return; // 외부 API 이상 방어 + } + + // pnuList 업데이트 + for (ChngDetectContDto.ContBasic contBasic : cont.getResult()) { + if (contBasic.getPnuList() == null) { + return; + } + + gukYuinJobCoreService.upsertMapSheetDataAnalGeomPnu( + contBasic.getChnDtctObjtId(), contBasic.getPnuList()); + } } } From 29556b6a05a054bcb7e8ddaed8d7340214fd2e30 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Fri, 30 Jan 2026 13:33:00 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=EB=93=B1=EB=A1=9D=20post=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 --- .../gukyuin/GukYuinApiController.java | 270 +++++++++--------- 1 file changed, 136 insertions(+), 134 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java index a7ab2e43..00d81bb0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java @@ -37,63 +37,65 @@ public class GukYuinApiController { private final GukYuinApiService gukYuinApiService; - /** 탐지결과 등록 */ + /** + * 탐지결과 등록 + */ @Operation(summary = "탐지결과 등록", description = "탐지결과 등록") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = DetectMastReq.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = DetectMastReq.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PostMapping("/chn/mast/regist") public ApiResponseDto regist( - @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { + @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { return ApiResponseDto.ok(gukYuinApiService.regist(chnDetectMastReq)); } @Operation(summary = "탐지결과 삭제", description = "탐지결과 삭제") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ChnDetectMastReqDto.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChnDetectMastReqDto.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PostMapping("/chn/mast/remove") public ApiResponseDto remove( - @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { + @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { return ApiResponseDto.ok(gukYuinApiService.remove(chnDetectMastReq)); } @Operation(summary = "탐지결과 등록목록 조회(년도,차수 조회)", description = "탐지결과 등록목록 조회") @GetMapping("/chn/mast") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto selectChangeDetectionList( - @RequestParam(required = false) String cprsYr, - @RequestParam(required = false) String crtrYr, - @RequestParam(required = false) String chnDtctSno) { + @RequestParam(required = false) String cprsYr, + @RequestParam(required = false) String crtrYr, + @RequestParam(required = false) String chnDtctSno) { ChngDetectMastSearchDto searchDto = new ChngDetectMastSearchDto(); searchDto.setCprsYr(cprsYr); searchDto.setCrtrYr(crtrYr); @@ -104,149 +106,149 @@ public class GukYuinApiController { @Operation(summary = "탐지결과 등록목록 조회(회차uid)", description = "탐지결과 등록목록 조회") @GetMapping("/chn/mast/{chnDtctId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto selectChangeDetectionDtctIdList( - @RequestParam(required = false) String chnDtctId) { + @RequestParam(required = false) String chnDtctId) { return ApiResponseDto.ok(gukYuinApiService.listChnDtctId(chnDtctId)); } @Operation(summary = "탐지결과 등록목록 조회(1건 조회)", description = "탐지결과 등록목록 조회") @GetMapping("/chn/mast/list/{chnDtctMstId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto selectChangeDetectionDetail( - @PathVariable String chnDtctMstId) { + @PathVariable String chnDtctMstId) { return ApiResponseDto.ok(gukYuinApiService.detail(chnDtctMstId)); } @Operation(summary = "국유in연동 가능여부 확인", description = "국유in연동 가능여부 확인") @GetMapping("/is-link/{uuid}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = - @Schema( - implementation = GukYuinLinkableRes.class, - description = "TRUE:연동가능, FALSE:연동 불가능"))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = + @Schema( + implementation = GukYuinLinkableRes.class, + description = "TRUE:연동가능, FALSE:연동 불가능"))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto getIsLinkGukYuin( - @Parameter(description = "uuid", example = "5799eb21-4780-48b0-a82e-e58dcbb8806b") - @PathVariable - UUID uuid) { + @Parameter(description = "uuid", example = "5799eb21-4780-48b0-a82e-e58dcbb8806b") + @PathVariable + UUID uuid) { return ApiResponseDto.ok(gukYuinApiService.getIsLinkGukYuin(uuid)); } @Operation(summary = "탐지객체 조회 (탐지객체)", description = "탐지객체 조회 (탐지객체)") @GetMapping("/chn/cont/{chnDtctId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto findChnContList( - @PathVariable String chnDtctId, - @RequestParam(defaultValue = "0") Integer pageIndex, - @RequestParam(defaultValue = "10") Integer pageSize) { + @PathVariable String chnDtctId, + @RequestParam(defaultValue = "0") Integer pageIndex, + @RequestParam(defaultValue = "10") Integer pageSize) { return ApiResponseDto.ok(gukYuinApiService.findChnContList(chnDtctId, pageIndex, pageSize)); } @Operation(summary = "탐지객체 조회 (PNU에 해당하는 탐지객체)", description = "탐지객체 조회 (PNU에 해당하는 탐지객체)") @GetMapping("/chn/cont/{chnDtctId}/pnu/{pnu}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto findChnPnuToContList( - @PathVariable String chnDtctId, @PathVariable String pnu) { + @PathVariable String chnDtctId, @PathVariable String pnu) { return ApiResponseDto.ok(gukYuinApiService.findChnPnuToContList(chnDtctId, pnu)); } @Operation(summary = "탐지객체 조회 (탐지객체와 교차하는 PNU)", description = "탐지객체 조회 (탐지객체와 교차하는 PNU)") @GetMapping("/chn/pnu/{chnDtctId}/objt/{chnDtctObjtId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto findPnuObjMgmtList( - @PathVariable String chnDtctId, @PathVariable String chnDtctObjtId) { + @PathVariable String chnDtctId, @PathVariable String chnDtctObjtId) { return ApiResponseDto.ok(gukYuinApiService.findPnuObjMgmtList(chnDtctId, chnDtctObjtId)); } @Operation(summary = "라벨여부 수정", description = "라벨여부 수정") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = DetectMastReq.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = DetectMastReq.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PostMapping("/rlb/objt/{chnDtctObjtId}/lbl/{lblYn}") public ApiResponseDto updateChnDtctObjtLabelingYn( - @PathVariable String chnDtctObjtId, @PathVariable String lblYn) { + @PathVariable String chnDtctObjtId, @PathVariable String lblYn) { return ApiResponseDto.ok(gukYuinApiService.updateChnDtctObjtLabelingYn(chnDtctObjtId, lblYn)); } @Operation(summary = "국유in연동 등록", description = "국유in연동 등록") - @GetMapping("/mast/reg/{uuid}") + @PostMapping("/mast/reg/{uuid}") public ApiResponseDto connectChnMastRegist( - @Parameter(description = "uuid", example = "7a593d0e-76a8-4b50-8978-9af1fbe871af") - @PathVariable - UUID uuid) { + @Parameter(description = "uuid", example = "7a593d0e-76a8-4b50-8978-9af1fbe871af") + @PathVariable + UUID uuid) { return ApiResponseDto.ok(gukYuinApiService.connectChnMastRegist(uuid)); } } From d95dc364aa51d5de3a5ed2f70520aec0555edf29 Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 30 Jan 2026 14:10:22 +0900 Subject: [PATCH 4/5] =?UTF-8?q?wmts=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gukyuin/GukYuinApiController.java | 268 ++++++------ .../gukyuin/service/GukYuinApiService.java | 2 +- .../cd/kamcoback/layer/dto/WmtsLayerInfo.java | 78 +++- .../kamcoback/layer/service/WmtsService.java | 403 +++++++++++------- 4 files changed, 462 insertions(+), 289 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java index 00d81bb0..dd6efcf7 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/GukYuinApiController.java @@ -37,65 +37,63 @@ public class GukYuinApiController { private final GukYuinApiService gukYuinApiService; - /** - * 탐지결과 등록 - */ + /** 탐지결과 등록 */ @Operation(summary = "탐지결과 등록", description = "탐지결과 등록") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = DetectMastReq.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = DetectMastReq.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PostMapping("/chn/mast/regist") public ApiResponseDto regist( - @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { + @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { return ApiResponseDto.ok(gukYuinApiService.regist(chnDetectMastReq)); } @Operation(summary = "탐지결과 삭제", description = "탐지결과 삭제") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ChnDetectMastReqDto.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChnDetectMastReqDto.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PostMapping("/chn/mast/remove") public ApiResponseDto remove( - @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { + @RequestBody @Valid ChngDetectMastDto.ChnDetectMastReqDto chnDetectMastReq) { return ApiResponseDto.ok(gukYuinApiService.remove(chnDetectMastReq)); } @Operation(summary = "탐지결과 등록목록 조회(년도,차수 조회)", description = "탐지결과 등록목록 조회") @GetMapping("/chn/mast") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto selectChangeDetectionList( - @RequestParam(required = false) String cprsYr, - @RequestParam(required = false) String crtrYr, - @RequestParam(required = false) String chnDtctSno) { + @RequestParam(required = false) String cprsYr, + @RequestParam(required = false) String crtrYr, + @RequestParam(required = false) String chnDtctSno) { ChngDetectMastSearchDto searchDto = new ChngDetectMastSearchDto(); searchDto.setCprsYr(cprsYr); searchDto.setCrtrYr(crtrYr); @@ -106,149 +104,149 @@ public class GukYuinApiController { @Operation(summary = "탐지결과 등록목록 조회(회차uid)", description = "탐지결과 등록목록 조회") @GetMapping("/chn/mast/{chnDtctId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto selectChangeDetectionDtctIdList( - @RequestParam(required = false) String chnDtctId) { + @RequestParam(required = false) String chnDtctId) { return ApiResponseDto.ok(gukYuinApiService.listChnDtctId(chnDtctId)); } @Operation(summary = "탐지결과 등록목록 조회(1건 조회)", description = "탐지결과 등록목록 조회") @GetMapping("/chn/mast/list/{chnDtctMstId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto selectChangeDetectionDetail( - @PathVariable String chnDtctMstId) { + @PathVariable String chnDtctMstId) { return ApiResponseDto.ok(gukYuinApiService.detail(chnDtctMstId)); } @Operation(summary = "국유in연동 가능여부 확인", description = "국유in연동 가능여부 확인") @GetMapping("/is-link/{uuid}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = - @Schema( - implementation = GukYuinLinkableRes.class, - description = "TRUE:연동가능, FALSE:연동 불가능"))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = + @Schema( + implementation = GukYuinLinkableRes.class, + description = "TRUE:연동가능, FALSE:연동 불가능"))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto getIsLinkGukYuin( - @Parameter(description = "uuid", example = "5799eb21-4780-48b0-a82e-e58dcbb8806b") - @PathVariable - UUID uuid) { + @Parameter(description = "uuid", example = "5799eb21-4780-48b0-a82e-e58dcbb8806b") + @PathVariable + UUID uuid) { return ApiResponseDto.ok(gukYuinApiService.getIsLinkGukYuin(uuid)); } @Operation(summary = "탐지객체 조회 (탐지객체)", description = "탐지객체 조회 (탐지객체)") @GetMapping("/chn/cont/{chnDtctId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto findChnContList( - @PathVariable String chnDtctId, - @RequestParam(defaultValue = "0") Integer pageIndex, - @RequestParam(defaultValue = "10") Integer pageSize) { + @PathVariable String chnDtctId, + @RequestParam(defaultValue = "0") Integer pageIndex, + @RequestParam(defaultValue = "10") Integer pageSize) { return ApiResponseDto.ok(gukYuinApiService.findChnContList(chnDtctId, pageIndex, pageSize)); } @Operation(summary = "탐지객체 조회 (PNU에 해당하는 탐지객체)", description = "탐지객체 조회 (PNU에 해당하는 탐지객체)") @GetMapping("/chn/cont/{chnDtctId}/pnu/{pnu}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto findChnPnuToContList( - @PathVariable String chnDtctId, @PathVariable String pnu) { + @PathVariable String chnDtctId, @PathVariable String pnu) { return ApiResponseDto.ok(gukYuinApiService.findChnPnuToContList(chnDtctId, pnu)); } @Operation(summary = "탐지객체 조회 (탐지객체와 교차하는 PNU)", description = "탐지객체 조회 (탐지객체와 교차하는 PNU)") @GetMapping("/chn/pnu/{chnDtctId}/objt/{chnDtctObjtId}") @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "목록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Basic.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "200", + description = "목록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) public ApiResponseDto findPnuObjMgmtList( - @PathVariable String chnDtctId, @PathVariable String chnDtctObjtId) { + @PathVariable String chnDtctId, @PathVariable String chnDtctObjtId) { return ApiResponseDto.ok(gukYuinApiService.findPnuObjMgmtList(chnDtctId, chnDtctObjtId)); } @Operation(summary = "라벨여부 수정", description = "라벨여부 수정") @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "등록 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = DetectMastReq.class))), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "201", + description = "등록 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = DetectMastReq.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @PostMapping("/rlb/objt/{chnDtctObjtId}/lbl/{lblYn}") public ApiResponseDto updateChnDtctObjtLabelingYn( - @PathVariable String chnDtctObjtId, @PathVariable String lblYn) { + @PathVariable String chnDtctObjtId, @PathVariable String lblYn) { return ApiResponseDto.ok(gukYuinApiService.updateChnDtctObjtLabelingYn(chnDtctObjtId, lblYn)); } @Operation(summary = "국유in연동 등록", description = "국유in연동 등록") @PostMapping("/mast/reg/{uuid}") public ApiResponseDto connectChnMastRegist( - @Parameter(description = "uuid", example = "7a593d0e-76a8-4b50-8978-9af1fbe871af") - @PathVariable - UUID uuid) { + @Parameter(description = "uuid", example = "7a593d0e-76a8-4b50-8978-9af1fbe871af") + @PathVariable + UUID uuid) { return ApiResponseDto.ok(gukYuinApiService.connectChnMastRegist(uuid)); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java b/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java index 84b2d172..de37d45e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java +++ b/src/main/java/com/kamco/cd/kamcoback/gukyuin/service/GukYuinApiService.java @@ -75,7 +75,7 @@ public class GukYuinApiService { ChngDetectMastDto.RegistResDto.class); ChngDetectMastDto.RegistResDto resultBody = result.body(); - Boolean success = null; + Boolean success = false; if (resultBody != null) { ChngDetectMastDto.Basic registRes = resultBody.getResult(); // 추론 회차에 applyStatus, applyStatusDttm 업데이트 diff --git a/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java b/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java index beb6e4ea..a4f30c41 100755 --- a/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java +++ b/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java @@ -1,6 +1,5 @@ package com.kamco.cd.kamcoback.layer.dto; -import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.List; @@ -13,9 +12,32 @@ public class WmtsLayerInfo { public List keywords = new ArrayList<>(); public BoundingBox boundingBox; public List formats = new ArrayList<>(); - public List tileMatrixSetLinks = new ArrayList<>(); + public List tileMatrixSetLinks = new ArrayList<>(); public List resourceUrls = new ArrayList<>(); public List