From 1d910a22f93f7d75a1e815b69815267e9cbc2b6f Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Mon, 19 Jan 2026 17:45:20 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=ED=95=99=EC=8A=B5=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EA=B4=80=EB=A6=AC=20>=20=ED=98=84=ED=99=A9=20>=20?= =?UTF-8?q?=EA=B2=80=EC=88=98=EC=9E=90=20=EB=AA=A9=EB=A1=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../label/service/LabelWorkService.java | 6 +- .../postgres/core/LabelWorkCoreService.java | 5 + .../label/LabelWorkRepositoryCustom.java | 3 + .../label/LabelWorkRepositoryImpl.java | 119 +++++++++++++++++- 4 files changed, 129 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelWorkService.java b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelWorkService.java index 4640d3e1..3e23b69d 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelWorkService.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelWorkService.java @@ -53,7 +53,11 @@ public class LabelWorkService { public Page findlabelWorkStateList(LabelWorkDto.WorkerStateSearchReq searchReq) { - return labelWorkCoreService.findlabelWorkStateList(searchReq); + if (searchReq.getUserRole().equals("LABELER")) { + return labelWorkCoreService.findlabelWorkStateList(searchReq); + } else { + return labelWorkCoreService.findReviewerWorkStateList(searchReq); + } } public UUID findLastLabelWorkState() { diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelWorkCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelWorkCoreService.java index 00df1cee..c75efbbd 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelWorkCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelWorkCoreService.java @@ -5,6 +5,7 @@ import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.ChangeDetectYear; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMng; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMngDetail; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; +import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerStateSearchReq; import com.kamco.cd.kamcoback.postgres.repository.label.LabelWorkRepository; import java.util.List; import java.util.UUID; @@ -61,4 +62,8 @@ public class LabelWorkCoreService { public UUID findLastLabelWorkState() { return labelWorkRepository.findLastLabelWorkState(); } + + public Page findReviewerWorkStateList(WorkerStateSearchReq searchReq) { + return labelWorkRepository.findReviewerWorkStateList(searchReq); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryCustom.java index 3f9dbe1a..e5c29c6f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryCustom.java @@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.label.dto.LabelWorkDto; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMng; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMngDetail; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; +import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerStateSearchReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity; import java.util.List; import java.util.UUID; @@ -20,4 +21,6 @@ public interface LabelWorkRepositoryCustom { Page findlabelWorkStateList(LabelWorkDto.WorkerStateSearchReq searchReq); UUID findLastLabelWorkState(); + + Page findReviewerWorkStateList(WorkerStateSearchReq searchReq); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java index 2c5e3485..99bcb8ae 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelWorkRepositoryImpl.java @@ -6,6 +6,7 @@ import com.kamco.cd.kamcoback.label.dto.LabelWorkDto; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMng; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.LabelWorkMngDetail; import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; +import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerStateSearchReq; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.QLabelingAssignmentEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceEntity; @@ -300,17 +301,17 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { NumberExpression day3AgoDoneCnt = this.caseSumExpression( doneStateCondition.and( - this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -3))); + this.fromDateEqExpression(labelingAssignmentEntity.workStatDttm, -3))); NumberExpression day2AgoDoneCnt = this.caseSumExpression( doneStateCondition.and( - this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -2))); + this.fromDateEqExpression(labelingAssignmentEntity.workStatDttm, -2))); NumberExpression day1AgoDoneCnt = this.caseSumExpression( doneStateCondition.and( - this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -1))); + this.fromDateEqExpression(labelingAssignmentEntity.workStatDttm, -1))); NumberExpression remainingCnt = assignedCnt.subtract(doneCnt); @@ -409,6 +410,118 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom { return uuid; } + @Override + public Page findReviewerWorkStateList(WorkerStateSearchReq searchReq) { + Pageable pageable = PageRequest.of(searchReq.getPage(), searchReq.getSize()); + BooleanBuilder whereBuilder = new BooleanBuilder(); + BooleanBuilder whereSubBuilder = new BooleanBuilder(); + List> orderSpecifiers = new ArrayList<>(); + + UUID uuid = UUID.fromString(searchReq.getUuid()); + + if (searchReq.getUserRole() != null && !searchReq.getUserRole().isEmpty()) { + whereSubBuilder.and(memberEntity.userRole.eq(searchReq.getUserRole())); + } + + if (searchReq.getSearchVal() != null && !searchReq.getSearchVal().isEmpty()) { + whereSubBuilder.and( + Expressions.stringTemplate("{0}", memberEntity.userId) + .likeIgnoreCase("%" + searchReq.getSearchVal() + "%") + .or( + Expressions.stringTemplate("{0}", memberEntity.name) + .likeIgnoreCase("%" + searchReq.getSearchVal() + "%"))); + } + + whereSubBuilder.and(labelingAssignmentEntity.inspectorUid.eq(memberEntity.userId)); + + // 공통 조건 추출 + BooleanExpression doneStateCondition = + labelingAssignmentEntity.inspectState.eq(InspectState.COMPLETE.name()); + + NumberExpression assignedCnt = labelingAssignmentEntity.inspectorUid.count(); + NumberExpression doneCnt = this.caseSumExpression(doneStateCondition); + NumberExpression skipCnt = + this.caseSumExpression( + labelingAssignmentEntity.inspectState.eq(InspectState.EXCEPT.name())); + + NumberExpression day3AgoDoneCnt = + this.caseSumExpression( + doneStateCondition.and( + this.fromDateEqExpression(labelingAssignmentEntity.inspectStatDttm, -3))); + + NumberExpression day2AgoDoneCnt = + this.caseSumExpression( + doneStateCondition.and( + this.fromDateEqExpression(labelingAssignmentEntity.inspectStatDttm, -2))); + + NumberExpression day1AgoDoneCnt = + this.caseSumExpression( + doneStateCondition.and( + this.fromDateEqExpression(labelingAssignmentEntity.inspectStatDttm, -1))); + + NumberExpression remainingCnt = assignedCnt.subtract(doneCnt); + + if (searchReq.getSort() == null || searchReq.getSort().isEmpty()) { + orderSpecifiers.add(memberEntity.name.asc()); + } else if (searchReq.getSort().equals("doneCnt desc")) { + orderSpecifiers.add(doneCnt.desc()); + } else if (searchReq.getSort().equals("remindCnt desc")) { + orderSpecifiers.add(remainingCnt.desc()); + } + + List foundContent = + queryFactory + .select( + Projections.constructor( + WorkerState.class, + memberEntity.userRole, + memberEntity.name, + memberEntity.userId, + assignedCnt.as("assignedCnt"), + doneCnt.as("doneCnt"), + skipCnt.as("skipCnt"), + day3AgoDoneCnt.as("day3AgoDoneCnt"), + day2AgoDoneCnt.as("day2AgoDoneCnt"), + day1AgoDoneCnt.as("day1AgoDoneCnt"))) + .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + mapSheetAnalInferenceEntity + .uuid + .eq(uuid) + .and(labelingAssignmentEntity.analUid.eq(mapSheetAnalInferenceEntity.id))) + .innerJoin(memberEntity) + .on(whereSubBuilder) + .where(whereBuilder) + .groupBy(memberEntity.userRole, memberEntity.name, memberEntity.userId) + .orderBy(orderSpecifiers.toArray(new OrderSpecifier[0])) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + // Count 쿼리 별도 실행 (null safe handling) + long countQuery = + Optional.ofNullable( + queryFactory + .select(labelingAssignmentEntity.workerUid.countDistinct()) + .from(labelingAssignmentEntity) + .innerJoin(mapSheetAnalInferenceEntity) + .on( + mapSheetAnalInferenceEntity + .uuid + .eq(uuid) + .and( + labelingAssignmentEntity.analUid.eq( + mapSheetAnalInferenceEntity.id))) + .innerJoin(memberEntity) + .on(whereSubBuilder) + .where(whereBuilder) + .fetchOne()) + .orElse(0L); + + return new PageImpl<>(foundContent, pageable, countQuery); + } + /** * 작업배정 상세조회 (복잡한 집계 쿼리로 인해 DTO 직접 반환) * From c8cb64fbeaa21a7010daa3ee9c7b81d0e4753ec3 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Mon, 19 Jan 2026 17:55:50 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EC=B6=94=EB=A1=A0=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20geom-list=20=EB=B6=84=EC=84=9D=EB=8F=84?= =?UTF-8?q?=EC=97=BD=20=EA=B2=80=EC=83=89=20like=20=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inference/InferenceResultApiController.java | 2 +- .../inference/InferenceResultApiV2Controller.java | 3 +-- .../kamcoback/inference/dto/InferenceDetailDto.java | 2 +- .../MapSheetAnalDataInferenceRepositoryImpl.java | 11 ++++++----- .../Inference/MapSheetLearnRepositoryImpl.java | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java index 45133c4c..1357204e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java @@ -386,7 +386,7 @@ public class InferenceResultApiController { @Parameter(description = "비교년도 분류", example = "waste") @RequestParam(required = false) String compareClass, @Parameter(description = "5000:1 도엽번호 37801011,37801012") @RequestParam(required = false) - List mapSheetNum, + Long mapSheetNum, @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java index 9f41916c..832d54c9 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiV2Controller.java @@ -10,7 +10,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -50,7 +49,7 @@ public class InferenceResultApiV2Controller { @Parameter(description = "비교년도 분류", example = "waste") @RequestParam(required = false) String compareClass, @Parameter(description = "5000:1 도협번호 37801011,37801012") @RequestParam(required = false) - List mapSheetNum, + Long mapSheetNum, @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java index 25ce3ec5..b0cbb278 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java @@ -384,7 +384,7 @@ public class InferenceDetailDto { // 비교년도 private String compareClass; // 분석도엽 - private List mapSheetNum; + private Long mapSheetNum; // 페이징 파라미터 private int page = 0; diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java index f6c1190c..9e8d203f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetAnalDataInferenceRepositoryImpl.java @@ -1,5 +1,6 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity.mapSheetAnalDataInferenceGeomEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; @@ -252,9 +253,9 @@ public class MapSheetAnalDataInferenceRepositoryImpl } // 분석도엽 - if (searchGeoReq.getMapSheetNum() != null && !searchGeoReq.getMapSheetNum().isEmpty()) { - List mapSheetNum = searchGeoReq.getMapSheetNum(); - builder.and(MapSheetAnalDataInferenceGeomEntity.mapSheetNum.in(mapSheetNum)); + if (searchGeoReq.getMapSheetNum() != null) { + Long mapSheetNum = searchGeoReq.getMapSheetNum(); + builder.and(mapSheetAnalDataInferenceGeomEntity.mapSheetNum.like("%" + mapSheetNum + "%")); } List content = @@ -368,8 +369,8 @@ public class MapSheetAnalDataInferenceRepositoryImpl } private BooleanExpression containsMapSheetNum( - QMapSheetAnalDataInferenceGeomEntity detectedEntity, List mapSheet) { - if (mapSheet == null || mapSheet.isEmpty()) { + QMapSheetAnalDataInferenceGeomEntity detectedEntity, Long mapSheet) { + if (mapSheet == null) { return null; } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java index 9038d6d5..7c249633 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java @@ -391,9 +391,9 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto } // 분석도엽 - if (searchGeoReq.getMapSheetNum() != null && !searchGeoReq.getMapSheetNum().isEmpty()) { - List mapSheetNum = searchGeoReq.getMapSheetNum(); - builder.and(mapSheetAnalDataInferenceGeomEntity.mapSheetNum.in(mapSheetNum)); + if (searchGeoReq.getMapSheetNum() != null) { + Long mapSheetNum = searchGeoReq.getMapSheetNum(); + builder.and(mapSheetAnalDataInferenceGeomEntity.mapSheetNum.like("%" + mapSheetNum + "%")); } List content =