feat/infer_dev_260211 #126
@@ -281,6 +281,7 @@ public class GukYuinApiService {
|
||||
+ "&reqEpno="
|
||||
+ ("Y".equals(batchYn) ? "BATCH" : userUtil.getEmployeeNo());
|
||||
|
||||
log.info("##### API 호출 URL : {}", url);
|
||||
ExternalCallResult<ChngDetectContDto.ResultContDto> result =
|
||||
externalHttpClient.call(
|
||||
url,
|
||||
@@ -289,6 +290,7 @@ public class GukYuinApiService {
|
||||
netUtils.jsonHeaders(),
|
||||
ChngDetectContDto.ResultContDto.class);
|
||||
|
||||
log.info("##### API 호출 완료 : {}", result.toString());
|
||||
List<ContBasic> contList = result.body().getResult();
|
||||
if (contList == null || contList.isEmpty()) {
|
||||
return new ResultContDto(
|
||||
@@ -348,6 +350,7 @@ public class GukYuinApiService {
|
||||
info.setReqIp(myip);
|
||||
info.setReqEpno("Y".equals(batchYn) ? "BATCH" : userUtil.getEmployeeNo());
|
||||
|
||||
log.info("##### API 호출 URL : {}", url);
|
||||
ExternalCallResult<ChngDetectContDto.ResultLabelDto> result =
|
||||
externalHttpClient.call(
|
||||
url,
|
||||
@@ -355,6 +358,7 @@ public class GukYuinApiService {
|
||||
info,
|
||||
netUtils.jsonHeaders(),
|
||||
ChngDetectContDto.ResultLabelDto.class);
|
||||
log.info("##### API 호출 완료 : {}", result.toString());
|
||||
|
||||
this.insertGukyuinAuditLog(
|
||||
EventType.MODIFIED.getId(),
|
||||
@@ -408,10 +412,12 @@ public class GukYuinApiService {
|
||||
+ "&reqEpno="
|
||||
+ ("Y".equals(batchYn) ? "BATCH" : userUtil.getEmployeeNo());
|
||||
|
||||
log.info("##### API 호출 URL : {}", url);
|
||||
ExternalCallResult<ChngDetectMastDto.ResultDto> result =
|
||||
externalHttpClient.call(
|
||||
url, HttpMethod.GET, null, netUtils.jsonHeaders(), ChngDetectMastDto.ResultDto.class);
|
||||
|
||||
log.info("##### API 호출 완료 : {}", result.toString());
|
||||
this.insertGukyuinAuditLog(
|
||||
EventType.DETAIL.getId(),
|
||||
netUtils.getLocalIP(),
|
||||
|
||||
@@ -458,6 +458,7 @@ public class InferenceDetailDto {
|
||||
private String bboxGeom;
|
||||
private String bboxCenterPoint;
|
||||
private UUID inferenceUuid;
|
||||
private String status;
|
||||
|
||||
public AnalResultInfo(
|
||||
String analTitle,
|
||||
@@ -474,7 +475,8 @@ public class InferenceDetailDto {
|
||||
String subUid,
|
||||
Boolean applyYn,
|
||||
ZonedDateTime applyDttm,
|
||||
UUID inferenceUuid) {
|
||||
UUID inferenceUuid,
|
||||
String status) {
|
||||
this.analTitle = analTitle;
|
||||
this.modelVer1 = modelVer1;
|
||||
this.modelVer2 = modelVer2;
|
||||
@@ -489,6 +491,7 @@ public class InferenceDetailDto {
|
||||
this.subUid = subUid;
|
||||
this.applyYn = applyYn;
|
||||
this.applyDttm = applyDttm;
|
||||
this.status = status;
|
||||
Duration elapsed =
|
||||
(inferStartDttm != null && inferEndDttm != null)
|
||||
? Duration.between(inferStartDttm, inferEndDttm)
|
||||
@@ -538,6 +541,10 @@ public class InferenceDetailDto {
|
||||
public Boolean getApplyYn() {
|
||||
return this.applyYn != null && this.applyYn;
|
||||
}
|
||||
|
||||
public String getStatusNm() {
|
||||
return InferenceResultDto.Status.getDescByCode(this.status);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
||||
@@ -315,7 +315,8 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
|
||||
Expressions.stringTemplate("substring({0} from 1 for 8)", mapSheetLearnEntity.uid),
|
||||
mapSheetLearnEntity.applyYn,
|
||||
mapSheetLearnEntity.applyDttm,
|
||||
mapSheetAnalInferenceEntity.uuid))
|
||||
mapSheetAnalInferenceEntity.uuid,
|
||||
mapSheetLearnEntity.status))
|
||||
.from(mapSheetLearnEntity)
|
||||
.leftJoin(m1)
|
||||
.on(mapSheetLearnEntity.m1ModelUuid.eq(m1.uuid))
|
||||
|
||||
@@ -31,26 +31,33 @@ public class GukYuinApiLabelJobService {
|
||||
return "local".equalsIgnoreCase(profile);
|
||||
}
|
||||
|
||||
// @Scheduled(cron = "0 0 2 * * *")
|
||||
public void runTask() {
|
||||
findLabelingCompleteSend(null);
|
||||
}
|
||||
|
||||
/** 어제 라벨링 검수 완료된 것 -> 국유인에 전송 */
|
||||
public void findLabelingCompleteSend(LocalDate baseDate) {
|
||||
// if (isLocalProfile()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
log.info("[Step 1-1] 어제 검수완료된 라벨링을 검색한다.");
|
||||
log.info("=== baseDate : {}", baseDate);
|
||||
log.info("=== baseDate 있으면 해당 일자, 없으면 어제일자로 조회");
|
||||
|
||||
List<GeomUidDto> list = gukYuinLabelJobCoreService.findYesterdayLabelingCompleteList(baseDate);
|
||||
log.info("[Step 1-2] 검수완료된 폴리곤 객체 수 : {}", list == null ? 0 : list.size());
|
||||
if (list.isEmpty()) {
|
||||
log.info("[Step 1-3] 객체 없어서 return : 스케줄링 종료");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("[Step 2-1] 객체 목록으로 라벨링 전송 API 호출 시작");
|
||||
for (GeomUidDto gto : list) {
|
||||
log.info("[Step 2-2] 객체ID 확인 gto.getResultUid(): {}", gto.getResultUid());
|
||||
ChngDetectContDto.ResultLabelDto dto =
|
||||
gukYuinApiService.updateChnDtctObjtLabelingYn(gto.getResultUid(), "Y", "Y");
|
||||
log.info("[Step 2-3] 결과 dto.getSuccess(): {}", dto.getSuccess());
|
||||
if (dto.getSuccess()) {
|
||||
log.info("[Step 2-4] 결과가 성공일 때 inference_geom에 label_send_dttm 업데이트 하기");
|
||||
log.info("==== 업데이트 하는 객체 gto.getGeoUid(): {}", gto.getGeoUid());
|
||||
// inference_geom 에 label_send_dttm 업데이트 하기
|
||||
gukYuinLabelJobCoreService.updateAnalDataInferenceGeomSendDttm(gto.getGeoUid());
|
||||
}
|
||||
|
||||
@@ -41,16 +41,24 @@ public class GukYuinApiPnuJobService {
|
||||
// return;
|
||||
// }
|
||||
|
||||
log.info("[Step 1-1] 국유인 연동까지 완료된 추론 목록 가져오기");
|
||||
log.info("=== apply_status -> 100% 다운 완료: GUK_COMPLETED, PNU매핑 실패: PNU_FAILED");
|
||||
List<LearnKeyDto> list =
|
||||
gukYuinPnuJobCoreService.findGukyuinApplyStatusUidList(
|
||||
List.of(GukYuinStatus.GUK_COMPLETED.getId(), GukYuinStatus.PNU_FAILED.getId()));
|
||||
|
||||
log.info("[Step 1-2] 매핑할 추론 회차 갯수 : {}", list == null ? 0 : list.size());
|
||||
if (list.isEmpty()) {
|
||||
log.info("[Step 1-3] 매핑할 추론 회차 갯수 없어서 리턴하고 끝남");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("[Step 2-1] 추론 회차별 pnu 매핑 for문 시작 ");
|
||||
for (LearnKeyDto dto : list) {
|
||||
try {
|
||||
processUid(dto.getUid(), dto.getUid());
|
||||
log.info("[Step 2-2] 진행하는 추론 Uid: {}", dto.getUid());
|
||||
processUid(dto.getUid());
|
||||
|
||||
gukYuinPnuJobCoreService.updateGukYuinApplyStateComplete(
|
||||
dto.getId(), GukYuinStatus.PNU_COMPLETED);
|
||||
} catch (Exception e) {
|
||||
@@ -61,15 +69,21 @@ public class GukYuinApiPnuJobService {
|
||||
}
|
||||
}
|
||||
|
||||
private void processUid(String chnDtctId, String uid) {
|
||||
ResultDto result = gukYuinApiService.listChnDtctId(chnDtctId, "Y");
|
||||
private void processUid(String uid) {
|
||||
log.info("[Step 2-4] 탐지 등록목록 상세 API 호출 시작");
|
||||
ResultDto result = gukYuinApiService.listChnDtctId(uid, "Y");
|
||||
|
||||
if (result == null || result.getResult() == null || result.getResult().isEmpty()) {
|
||||
log.info("[Step 2-5] 결과값 없어서 return");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("[Step 2-5] 결과값 첫번째 값 가져오기");
|
||||
ChngDetectMastDto.Basic basic = result.getResult().get(0);
|
||||
String chnDtctCnt = basic.getChnDtctCnt();
|
||||
log.info("[Step 2-6] 탐지 객체 전체 갯수 chnDtctCnt = {}", chnDtctCnt);
|
||||
if (chnDtctCnt == null || chnDtctCnt.isEmpty()) {
|
||||
log.info("[Step 2-76] 탐지 객체 전체 갯수 없어서 return");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -78,29 +92,44 @@ public class GukYuinApiPnuJobService {
|
||||
int totalCount = Integer.parseInt(chnDtctCnt);
|
||||
int totalPages = (totalCount + pageSize - 1) / pageSize;
|
||||
|
||||
log.info("[Step 3-1] 탐지 객체 전체 수로 페이지 계산 : {}", totalPages);
|
||||
for (int page = 0; page < totalPages; page++) {
|
||||
log.info("[Step 3-2] 페이지 별 호출 : {}", page);
|
||||
processPage(uid, page, pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
private void processPage(String uid, int page, int pageSize) {
|
||||
log.info("[Step 4-1] 탐지객체 목록 API 호출 시작");
|
||||
ResultContDto resContList = gukYuinApiService.findChnContList(uid, page, pageSize, "Y");
|
||||
|
||||
if (resContList.getResult() == null || resContList.getResult().isEmpty()) {
|
||||
log.info("[Step 4-2] 탐지객체 목록 결과 없어서 return");
|
||||
return; // 외부 API 이상 방어
|
||||
}
|
||||
|
||||
List<ContBasic> contList = resContList.getResult();
|
||||
log.info("[Step 4-3] 탐지객체 목록 결과 contList.size : {}", contList == null ? 0 : contList.size());
|
||||
for (ContBasic cont : contList) {
|
||||
String[] pnuList = cont.getPnuList();
|
||||
long pnuCnt = pnuList == null ? 0 : pnuList.length;
|
||||
log.info("[Step 4-4] 객체에 연결된 pnuCnt : {}", pnuCnt);
|
||||
if (cont.getChnDtctObjtId() != null) {
|
||||
log.info(
|
||||
"[Step 4-5] inference_geom 에 pnu 갯수 update : cont.getChnDtctObjtId = {}",
|
||||
cont.getChnDtctObjtId());
|
||||
log.info(" === cont.getChnDtctObjtId : {}", cont.getChnDtctObjtId());
|
||||
log.info(" === pnuCnt : {}", pnuCnt);
|
||||
gukYuinPnuJobCoreService.updateInferenceGeomDataPnuCnt(cont.getChnDtctObjtId(), pnuCnt);
|
||||
|
||||
if (pnuCnt > 0) {
|
||||
log.info("[Step 4-6] 객체 ID로 geoUid 검색 = {}", cont.getChnDtctObjtId());
|
||||
Long geoUid =
|
||||
gukYuinPnuJobCoreService.findMapSheetAnalDataInferenceGeomUid(
|
||||
cont.getChnDtctObjtId());
|
||||
|
||||
log.info("[Step 4-7] tb_pnu 에 데이터 upsert 수행");
|
||||
log.info("===== geoUid = {}", geoUid);
|
||||
gukYuinPnuJobCoreService.insertGeoUidPnuData(geoUid, pnuList, cont.getChnDtctObjtId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class GukYuinApiStbltJobService {
|
||||
gukYuinStbltJobCoreService.findGukYuinEligibleForSurveyList(
|
||||
GukYuinStatus.PNU_COMPLETED.getId());
|
||||
|
||||
log.info("[Step 1-2] 국유인 연동 PNU 완료된 추론 회차 갯수 : {}", list.size());
|
||||
log.info("[Step 1-2] 국유인 연동 PNU 완료된 추론 회차 갯수 : {}", list == null ? 0 : list.size());
|
||||
if (list.isEmpty()) {
|
||||
log.info("[Step 1-3] 국유인 연동 PNU 완료된 추론 회차 갯수 없어서 return");
|
||||
return;
|
||||
@@ -83,7 +83,7 @@ public class GukYuinApiStbltJobService {
|
||||
}
|
||||
|
||||
log.info("[Step 4-1] 국유인 실태조사 적합여부 result 값으로 데이터 업데이트");
|
||||
log.info(" === 데이터 갯수 : {}", result.getResult().size());
|
||||
log.info(" === 데이터 갯수 : {}", result.getResult() == null ? 0 : result.getResult().size());
|
||||
|
||||
for (RlbDtctMastDto stbltDto : result.getResult()) {
|
||||
log.info("[Step 4-2] 국유인 실태조사 적합여부 결과 가져오기");
|
||||
|
||||
@@ -32,7 +32,6 @@ public class TrainingDataLabelJobService {
|
||||
return "local".equalsIgnoreCase(profile);
|
||||
}
|
||||
|
||||
// @Scheduled(cron = "0 0 0 * * *")
|
||||
public void runTask() {
|
||||
// 프록시를 통해 호출해야 @Transactional이 적용됨
|
||||
applicationContext
|
||||
@@ -43,55 +42,72 @@ public class TrainingDataLabelJobService {
|
||||
@Transactional
|
||||
public void assignReviewerYesterdayLabelComplete(LocalDate baseDate) {
|
||||
|
||||
// if (isLocalProfile()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
try {
|
||||
log.info("[Step 1-1] 라벨링 완료된 데이터 목록 조회한다.");
|
||||
log.info("=== baseDate : {}", baseDate);
|
||||
log.info("=== baseDate 있으면 해당 일자, 없으면 어제일자로 조회");
|
||||
List<Tasks> tasks =
|
||||
trainingDataLabelJobCoreService.findCompletedYesterdayUnassigned(baseDate);
|
||||
|
||||
log.info("[Step 1-2] 목록 객체 건수 count : {}", tasks == null ? 0 : tasks.size());
|
||||
if (tasks.isEmpty()) {
|
||||
log.info("[Step 1-3] 조회된 것 없어 return");
|
||||
return;
|
||||
}
|
||||
|
||||
// 회차별로 그룹핑
|
||||
log.info("[Step 2-1] 회차별로 그룹핑 시작");
|
||||
Map<Long, List<Tasks>> taskByRound =
|
||||
tasks.stream().collect(Collectors.groupingBy(Tasks::getAnalUid));
|
||||
|
||||
// 회차별 분배
|
||||
log.info("[Step 3-1] 회차별로 분배 시작");
|
||||
for (Map.Entry<Long, List<Tasks>> entry : taskByRound.entrySet()) {
|
||||
Long analUid = entry.getKey();
|
||||
List<Tasks> analTasks = entry.getValue();
|
||||
|
||||
// pending 계산
|
||||
log.info("[Step 3-2] 수행하는 회차 analUid: {}", analUid);
|
||||
log.info("해당 회차에 라벨링 할당받은 검수자별 완료 건수 count(), 완료한 게 적은 순으로 해야 일이 한 사람에게 몰리지 않음");
|
||||
List<InspectorPendingDto> pendings =
|
||||
trainingDataLabelJobCoreService.findInspectorPendingByRound(analUid);
|
||||
|
||||
log.info("검수자 수: {}", pendings == null ? 0 : pendings.size());
|
||||
if (pendings.isEmpty()) {
|
||||
log.info("[Step 3-3] 할당된 검수자가 없으면 return");
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("[Step 4-1] 검수자 사번 List 생성");
|
||||
List<String> reviewerIds =
|
||||
pendings.stream().map(InspectorPendingDto::getInspectorUid).toList();
|
||||
|
||||
// Lock 걸릴 수 있기 때문에 엔티티 조회하는 Repository 에서 구현
|
||||
log.info("[Step 4-2] 검수자 테이블 lock 걸리지 않게 처리");
|
||||
trainingDataLabelJobCoreService.lockInspectors(analUid, reviewerIds);
|
||||
|
||||
// 균등 분배
|
||||
log.info("[Step 5-1] 검수자에게 라벨 작업 균등분배 시작");
|
||||
Map<String, List<Tasks>> assignMap = distributeByLeastPending(analTasks, reviewerIds);
|
||||
log.info("[Step 5-2] 검수자에게 라벨 작업 균등분배 완료");
|
||||
|
||||
// reviewer별 batch update
|
||||
log.info("[Step 5-3] 검수자별 할당 데이터를 batch update 시작");
|
||||
assignMap.forEach(
|
||||
(reviewerId, assignedTasks) -> {
|
||||
if (assignedTasks.isEmpty()) {
|
||||
log.info("[Step 5-4] 할당된 데이터 없으면 return");
|
||||
return;
|
||||
}
|
||||
|
||||
List<UUID> assignmentUids =
|
||||
assignedTasks.stream().map(Tasks::getAssignmentUid).toList();
|
||||
log.info("[Step 6-1] 할당 작업에 검수자 아이디 update");
|
||||
log.info("==== 검수자 사번: {}", reviewerId);
|
||||
log.info("==== 할당 갯수: {}", assignmentUids == null ? 0 : assignmentUids.size());
|
||||
trainingDataLabelJobCoreService.assignReviewerBatch(assignmentUids, reviewerId);
|
||||
|
||||
log.info("[Step 7-1] geom 테이블에 검수 상태 update");
|
||||
List<Long> geomUids = assignedTasks.stream().map(Tasks::getInferenceUid).toList();
|
||||
trainingDataLabelJobCoreService.updateGeomUidTestState(geomUids);
|
||||
});
|
||||
|
||||
@@ -39,52 +39,68 @@ public class TrainingDataReviewJobService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
// @Scheduled(cron = "0 0 2 * * *")
|
||||
public void runTask() {
|
||||
exportGeojsonLabelingGeom(null);
|
||||
}
|
||||
|
||||
public void exportGeojsonLabelingGeom(LocalDate baseDate) {
|
||||
|
||||
// if (isLocalProfile()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 1) 경로/파일명 결정
|
||||
String targetDir =
|
||||
"local".equals(profile) ? System.getProperty("user.home") + "/geojson" : trainingDataDir;
|
||||
log.info("[Step 1-1] geojson 파일 생성할 경로: {}", targetDir);
|
||||
|
||||
// 2) 진행중인 회차 중, complete_cnt 가 존재하는 회차 목록 가져오기
|
||||
log.info("[Step 1-2] 진행중인 회차 중, complete_cnt 가 존재하는 회차 목록 가져오기");
|
||||
List<AnalCntInfo> analList = trainingDataReviewJobCoreService.findAnalCntInfoList();
|
||||
log.info("[Step 1-3] 회차 리스트 건수: {}", analList == null ? 0 : analList.size());
|
||||
|
||||
if (analList.isEmpty()) {
|
||||
log.info("[Step 1-4] 회차 리스트 없어 return 하고 종료");
|
||||
return;
|
||||
}
|
||||
|
||||
for (AnalCntInfo info : analList) {
|
||||
log.info("[Step 2-1] 회차 폴리곤 전체 건수 == 파일 생성 건수 같은지 확인");
|
||||
log.info("=== info.getAllCnt(): {}", info.getAllCnt());
|
||||
log.info("=== info.getFileCnt(): {}", info.getFileCnt());
|
||||
|
||||
if (Objects.equals(info.getAllCnt(), info.getFileCnt())) {
|
||||
log.info("[Step 2-2] 회차 폴리곤 전체 건수 == 파일 생성 건수 같아서 파일 생성 진행하지 않음 continue");
|
||||
continue;
|
||||
}
|
||||
|
||||
String resultUid = info.getResultUid(); // 회차의 대문자 uid (폴더명으로 사용)
|
||||
|
||||
// 3) 회차 + 어제까지 검수 완료된 총 데이터의 도엽별 목록 가져오기
|
||||
log.info("[Step 3-1] 회차 + 어제까지 검수 완료된 총 데이터의 도엽별 목록 가져오기");
|
||||
List<AnalMapSheetList> analMapList =
|
||||
trainingDataReviewJobCoreService.findCompletedAnalMapSheetList(
|
||||
info.getAnalUid(), baseDate);
|
||||
|
||||
log.info("=== analMapList cnt: {}", analMapList == null ? 0 : analMapList.size());
|
||||
if (analMapList.isEmpty()) {
|
||||
log.info("[Step 3-2] 도엽 목록 조회되지 않아 continue");
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("[Step 4-1] 도엽별 geom 데이터 가지고 와서 geojson 만들기 시작");
|
||||
for (AnalMapSheetList mapSheet : analMapList) {
|
||||
// 4) 도엽별 geom 데이터 가지고 와서 geojson 만들기
|
||||
log.info("[Step 4-2] 도엽별 검수완료된 폴리곤 데이터 목록 조회");
|
||||
List<CompleteLabelData> completeList =
|
||||
trainingDataReviewJobCoreService.findCompletedYesterdayLabelingList(
|
||||
info.getAnalUid(), mapSheet.getMapSheetNum(), baseDate);
|
||||
|
||||
log.info("=== completeList size: {}", completeList == null ? 0 : completeList.size());
|
||||
if (!completeList.isEmpty()) {
|
||||
|
||||
log.info("[Step 4-3] 목록에서 filter로 geoUid List 생성, 폴리곤 feature별 리스트 생성");
|
||||
List<Long> geoUids = completeList.stream().map(CompleteLabelData::getGeoUid).toList();
|
||||
List<GeoJsonFeature> features = completeList.stream().map(GeoJsonFeature::from).toList();
|
||||
|
||||
// 5) 파일서버에 uid 폴더 생성 후 업로드 하기
|
||||
log.info("[Step 5-1] 파일서버에 uid 폴더 생성 후 업로드 하기 시작");
|
||||
FeatureCollection collection = new FeatureCollection(features);
|
||||
String filename =
|
||||
String.format(
|
||||
@@ -94,15 +110,21 @@ public class TrainingDataReviewJobService {
|
||||
mapSheet.getTargetYyyy(),
|
||||
mapSheet.getMapSheetNum());
|
||||
|
||||
log.info("=== filename: {}", filename);
|
||||
log.info("=== 회차의 uid: {}", resultUid);
|
||||
Path outputPath = Paths.get(targetDir + "/" + resultUid, filename);
|
||||
log.info("=== outputPath: {}", outputPath);
|
||||
try {
|
||||
log.info("[Step 6-1] Uid로 폴더 생성");
|
||||
Files.createDirectories(outputPath.getParent());
|
||||
|
||||
log.info("[Step 6-2] geoJson 파일 생성");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
objectMapper.writeValue(outputPath.toFile(), collection);
|
||||
|
||||
// geoUids : file_create_yn = true 로 업데이트
|
||||
log.info("[Step 6-3] learn_data_geom 에 file_create_yn = true 로 업데이트");
|
||||
trainingDataReviewJobCoreService.updateLearnDataGeomFileCreateYn(geoUids);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
Reference in New Issue
Block a user