Merge pull request 'feat/infer_dev_260107' (#286) from feat/infer_dev_260107 into develop

Reviewed-on: https://kamco.gitea.gs.dabeeo.com/dabeeo/kamco-dabeeo-backoffice/pulls/286
This commit is contained in:
2026-01-20 15:10:09 +09:00
16 changed files with 149 additions and 14 deletions

View File

@@ -318,4 +318,16 @@ public class LabelAllocateApiController {
LabelAllocateDto.searchReq searchReq = new LabelAllocateDto.searchReq(page, size, "");
return ApiResponseDto.ok(labelAllocateService.findWorkHistoryList(searchReq, userId, type));
}
@Operation(summary = "라벨링 작업 중인 회차 있는지 여부", description = "라벨링 작업 중인 회차 있는지 여부")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음"),
@ApiResponse(responseCode = "500", description = "서버 오류")
})
@GetMapping("/ing-process-cnt")
public ApiResponseDto<Long> labelingIngProcessCnt() {
return ApiResponseDto.ok(labelAllocateService.findLabelingIngProcessCnt());
}
}

View File

@@ -5,6 +5,7 @@ import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode;
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;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelerDetail;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelingStatDto;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.MoveInfo;
@@ -80,11 +81,13 @@ public class LabelAllocateService {
labelAllocateCoreService.insertLabelerUser(analUid, target.getUserId(), target.getDemand());
}
// 검수자 할당 테이블에 insert. TODO: 익일 배치로 라벨링 완료된 내역을 검수자에게 할당해야 함
// 검수자 할당 테이블에 insert.
for (String inspector : targetInspectors) {
labelAllocateCoreService.insertInspector(analUid, inspector);
}
labelAllocateCoreService.updateAnalInferenceMngState(uuid, LabelMngState.ASSIGNED.getId());
return new ApiResponseDto.ResponseObj(ApiResponseCode.OK, "배정이 완료되었습니다.");
}
@@ -255,6 +258,8 @@ public class LabelAllocateService {
}
labelAllocateCoreService.updateClosedYnByUuid(targetUuid, closedType, closedYn);
labelAllocateCoreService.updateAnalInferenceMngState(
UUID.fromString(targetUuid), LabelMngState.FINISH.getId());
}
public Page<WorkHistoryDto> findWorkHistoryList(searchReq searchReq, String userId, String type) {
@@ -264,4 +269,8 @@ public class LabelAllocateService {
return labelAllocateCoreService.workReviewerHistoryList(searchReq, userId);
}
}
public Long findLabelingIngProcessCnt() {
return labelAllocateCoreService.findLabelingIngProcessCnt();
}
}

View File

@@ -226,4 +226,12 @@ public class LabelAllocateCoreService {
public Page<WorkHistoryDto> workReviewerHistoryList(searchReq searchReq, String userId) {
return labelAllocateRepository.workReviewerHistoryList(searchReq, userId);
}
public void updateAnalInferenceMngState(UUID uuid, String status) {
labelAllocateRepository.updateAnalInferenceMngState(uuid, status);
}
public Long findLabelingIngProcessCnt() {
return labelAllocateRepository.findLabelingIngProcessCnt();
}
}

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.postgres.repository.trainingdata.TrainingDataLabel
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DefaultPaging;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DetailRes;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelFeatureRequest.LabelProperties;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingGeometryInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingListDto;
@@ -29,7 +30,7 @@ public class TrainingDataLabelCoreService {
return trainingDataLabelRepository.findLabelingAssignedGeom(assignmentUid);
}
public Long findLabelingAssignmentGeoUid(String assignmentUid) {
public InferenceIdInfo findLabelingAssignmentGeoUid(String assignmentUid) {
return trainingDataLabelRepository.findLabelingAssignmentGeoUid(assignmentUid);
}
@@ -89,4 +90,8 @@ public class TrainingDataLabelCoreService {
String mapSheetNum, Integer beforeYear, Integer afterYear) {
return trainingDataLabelRepository.getCogImageUrl(mapSheetNum, beforeYear, afterYear);
}
public void updateAnalInferenceMngState(Long analUid, String status) {
trainingDataLabelRepository.updateAnalInferenceMngState(analUid, status);
}
}

View File

@@ -1,6 +1,7 @@
package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.postgres.repository.trainingdata.TrainingDataReviewRepository;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.DefaultPaging;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.DetailRes;
@@ -29,7 +30,7 @@ public class TrainingDataReviewCoreService {
return trainingDataReviewRepository.findReviewAssignedGeom(operatorUid);
}
public Long findReviewOperatorGeoUid(String operatorUid) {
public InferenceIdInfo findReviewOperatorGeoUid(String operatorUid) {
return trainingDataReviewRepository.findReviewOperatorGeoUid(operatorUid);
}
@@ -89,4 +90,8 @@ public class TrainingDataReviewCoreService {
String mapSheetNum, Integer beforeYear, Integer afterYear) {
return trainingDataReviewRepository.getCogImageUrl(mapSheetNum, beforeYear, afterYear);
}
public void updateAnalInferenceMngState(Long analUid, String status) {
trainingDataReviewRepository.updateAnalInferenceMngState(analUid, status);
}
}

View File

@@ -52,7 +52,8 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
m1_model_batch_id,
m2_model_batch_id,
m3_model_batch_id,
learn_id
learn_id,
anal_state
)
SELECT
r.stage,
@@ -64,7 +65,8 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
r.m1_model_batch_id,
r.m2_model_batch_id,
r.m3_model_batch_id,
r.id
r.id,
LabelState.PENDING.getId(),
FROM tb_map_sheet_learn r
WHERE r.id = :id
ON CONFLICT (stage, compare_yyyy, target_yyyy)

View File

@@ -397,6 +397,11 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
"%" + searchGeoReq.getMapSheetNum() + "%"));
}
where.and(mapSheetAnalDataInferenceGeomEntity.classAfterCd.isNotNull());
where.and(mapSheetAnalDataInferenceGeomEntity.classAfterProb.isNotNull());
where.and(mapSheetAnalDataInferenceGeomEntity.classBeforeCd.isNotNull());
where.and(mapSheetAnalDataInferenceGeomEntity.classBeforeProb.isNotNull());
// 3) inkx 조인 조건: JPQL/HQL에서 '~' 불가 → function('regexp_match', ...) 사용
BooleanExpression inkxIsNumeric =
Expressions.booleanTemplate(

View File

@@ -100,4 +100,8 @@ public interface LabelAllocateRepositoryCustom {
Page<WorkHistoryDto> workLabelHistoryList(LabelAllocateDto.searchReq searchReq, String userId);
Page<WorkHistoryDto> workReviewerHistoryList(searchReq searchReq, String userId);
void updateAnalInferenceMngState(UUID uuid, String status);
Long findLabelingIngProcessCnt();
}

View File

@@ -13,6 +13,7 @@ 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;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InspectState;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelState;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelerDetail;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelingStatDto;
@@ -1785,4 +1786,23 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
return new PageImpl<>(list, pageable, countQuery != null ? countQuery : 0L);
}
@Override
public void updateAnalInferenceMngState(UUID uuid, String status) {
queryFactory
.update(mapSheetAnalInferenceEntity)
.set(mapSheetAnalInferenceEntity.analState, status)
.set(mapSheetAnalInferenceEntity.updatedDttm, ZonedDateTime.now())
.where(mapSheetAnalInferenceEntity.uuid.eq(uuid))
.execute();
}
@Override
public Long findLabelingIngProcessCnt() {
return queryFactory
.select(mapSheetAnalInferenceEntity.id.count())
.from(mapSheetAnalInferenceEntity)
.where(mapSheetAnalInferenceEntity.analState.eq(LabelMngState.ING.getId()))
.fetchOne();
}
}

View File

@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.postgres.repository.trainingdata;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DefaultPaging;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DetailRes;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelFeatureRequest.LabelProperties;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingGeometryInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingListDto;
@@ -18,7 +19,7 @@ public interface TrainingDataLabelRepositoryCustom {
LabelingGeometryInfo findLabelingAssignedGeom(String assignmentUid);
Long findLabelingAssignmentGeoUid(String assignmentUid);
InferenceIdInfo findLabelingAssignmentGeoUid(String assignmentUid);
void updateLabelingStateAssignment(String assignmentUid, String status);
@@ -37,4 +38,6 @@ public interface TrainingDataLabelRepositoryCustom {
TrainingDataLabelDto.CogImageResponse getCogImageUrl(
String mapSheetNum, Integer beforeYear, Integer afterYear);
void updateAnalInferenceMngState(Long analUid, String status);
}

View File

@@ -4,6 +4,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QImageryEntity.imageryEntit
import static com.kamco.cd.kamcoback.postgres.entity.QLabelingAssignmentEntity.labelingAssignmentEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity;
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.QMapSheetLearnDataGeomEntity.mapSheetLearnDataGeomEntity;
import com.fasterxml.jackson.databind.JsonNode;
@@ -19,6 +20,7 @@ import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DefaultPagin
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DetailRes;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceDataGeometry;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceDataGeometry.InferenceProperties;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InspectionResultInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelFeatureRequest.LabelProperties;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingGeometryInfo;
@@ -174,9 +176,13 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport
}
@Override
public Long findLabelingAssignmentGeoUid(String assignmentUid) {
public InferenceIdInfo findLabelingAssignmentGeoUid(String assignmentUid) {
return queryFactory
.select(labelingAssignmentEntity.inferenceGeomUid)
.select(
Projections.constructor(
InferenceIdInfo.class,
labelingAssignmentEntity.inferenceGeomUid,
labelingAssignmentEntity.analUid))
.from(labelingAssignmentEntity)
.where(labelingAssignmentEntity.assignmentUid.eq(UUID.fromString(assignmentUid)))
.fetchOne();
@@ -838,6 +844,16 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport
}
}
@Override
public void updateAnalInferenceMngState(Long analUid, String status) {
queryFactory
.update(mapSheetAnalInferenceEntity)
.set(mapSheetAnalInferenceEntity.analState, status)
.set(mapSheetAnalInferenceEntity.updatedDttm, ZonedDateTime.now())
.where(mapSheetAnalInferenceEntity.id.eq(analUid))
.execute();
}
private StringExpression makeCogUrl(NumberPath<Integer> year) {
return new CaseBuilder()
.when(imageryEntity.year.eq(year))

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.postgres.repository.trainingdata;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.DefaultPaging;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.DetailRes;
@@ -18,7 +19,7 @@ public interface TrainingDataReviewRepositoryCustom {
ReviewGeometryInfo findReviewAssignedGeom(String operatorUid);
Long findReviewOperatorGeoUid(String operatorUid);
InferenceIdInfo findReviewOperatorGeoUid(String operatorUid);
void updateReviewStateOperator(String operatorUid, String status);
@@ -37,4 +38,6 @@ public interface TrainingDataReviewRepositoryCustom {
TrainingDataReviewDto.CogImageResponse getCogImageUrl(
String mapSheetNum, Integer beforeYear, Integer afterYear);
void updateAnalInferenceMngState(Long analUid, String status);
}

View File

@@ -4,6 +4,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QImageryEntity.imageryEntit
import static com.kamco.cd.kamcoback.postgres.entity.QLabelingAssignmentEntity.labelingAssignmentEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity;
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.QMapSheetLearnDataGeomEntity.mapSheetLearnDataGeomEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity;
@@ -12,6 +13,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InspectState;
import com.kamco.cd.kamcoback.postgres.entity.LabelingAssignmentEntity;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.ChangeDetectionInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.ClassificationInfo;
@@ -177,9 +179,13 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport
}
@Override
public Long findReviewOperatorGeoUid(String operatorUid) {
public InferenceIdInfo findReviewOperatorGeoUid(String operatorUid) {
return queryFactory
.select(labelingAssignmentEntity.inferenceGeomUid)
.select(
Projections.constructor(
InferenceIdInfo.class,
labelingAssignmentEntity.inferenceGeomUid,
labelingAssignmentEntity.analUid))
.from(labelingAssignmentEntity)
.where(labelingAssignmentEntity.assignmentUid.eq(UUID.fromString(operatorUid)))
.fetchOne();
@@ -868,6 +874,16 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport
}
}
@Override
public void updateAnalInferenceMngState(Long analUid, String status) {
queryFactory
.update(mapSheetAnalInferenceEntity)
.set(mapSheetAnalInferenceEntity.analState, status)
.set(mapSheetAnalInferenceEntity.updatedDttm, ZonedDateTime.now())
.where(mapSheetAnalInferenceEntity.id.eq(analUid))
.execute();
}
private StringExpression makeCogUrl(NumberPath<Integer> year) {
return new CaseBuilder()
.when(imageryEntity.year.eq(year))

View File

@@ -204,6 +204,19 @@ public class TrainingDataLabelDto {
}
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class InferenceIdInfo {
@Schema(description = "inferenceGeomUid")
private Long inferenceGeomUid;
@Schema(description = "analUid")
private Long analUid;
}
@Schema(name = "LearnDataGeometry", description = "LearnDataGeometry")
@Getter
@Setter

View File

@@ -2,11 +2,13 @@ package com.kamco.cd.kamcoback.trainingdata.service;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState;
import com.kamco.cd.kamcoback.postgres.core.TrainingDataLabelCoreService;
import com.kamco.cd.kamcoback.scheduler.service.TrainingDataReviewJobService;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DefaultPaging;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DetailRes;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelFeatureRequest;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingGeometryInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingListDto;
@@ -44,8 +46,8 @@ public class TrainingDataLabelService {
public String saveLabelingFeature(LabelFeatureRequest request) {
String status = "";
String assignmentUid = request.getAssignmentUid();
Long inferenceGeomUid =
trainingDataLabelCoreService.findLabelingAssignmentGeoUid(assignmentUid);
InferenceIdInfo info = trainingDataLabelCoreService.findLabelingAssignmentGeoUid(assignmentUid);
Long inferenceGeomUid = info.getInferenceGeomUid();
if (request.getGeometry() == null || request.getGeometry().isEmpty()) {
// SKIP 상태만 업데이트
status = "SKIP";
@@ -61,6 +63,10 @@ public class TrainingDataLabelService {
// 라벨링 완료하면 실시간 검수 할당 (1건)
trainingDataReviewJobService.assignRealtime(assignmentUid);
// 회차 진행 상태 update
trainingDataLabelCoreService.updateAnalInferenceMngState(
info.getAnalUid(), LabelMngState.ING.getId());
return status;
}

View File

@@ -2,7 +2,9 @@ package com.kamco.cd.kamcoback.trainingdata.service;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj;
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState;
import com.kamco.cd.kamcoback.postgres.core.TrainingDataReviewCoreService;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InferenceIdInfo;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.DefaultPaging;
import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataReviewDto.DetailRes;
@@ -39,7 +41,8 @@ public class TrainingDataReviewService {
public String saveReviewFeature(GeoFeatureRequest request) {
String status = "";
String operatorUid = request.getOperatorUid();
Long inferenceGeomUid = trainingDataReviewCoreService.findReviewOperatorGeoUid(operatorUid);
InferenceIdInfo info = trainingDataReviewCoreService.findReviewOperatorGeoUid(operatorUid);
Long inferenceGeomUid = info.getInferenceGeomUid();
if (request.getGeometry() == null || request.getGeometry().isEmpty()) {
// EXCEPT 상태만 업데이트
@@ -52,6 +55,11 @@ public class TrainingDataReviewService {
trainingDataReviewCoreService.updateReviewPolygonClass(
inferenceGeomUid, request.getGeometry(), request.getProperties(), status);
}
// 회차 진행 상태 update
trainingDataReviewCoreService.updateAnalInferenceMngState(
info.getAnalUid(), LabelMngState.ING.getId());
return status;
}