From 1d910a22f93f7d75a1e815b69815267e9cbc2b6f Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Mon, 19 Jan 2026 17:45:20 +0900 Subject: [PATCH] =?UTF-8?q?=ED=95=99=EC=8A=B5=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20>=20=ED=98=84=ED=99=A9=20>=20=EA=B2=80?= =?UTF-8?q?=EC=88=98=EC=9E=90=20=EB=AA=A9=EB=A1=9D=20=EC=B6=94=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 직접 반환) *