학습데이터관리 > 현황 > 검수자 목록 추가

This commit is contained in:
2026-01-19 17:45:20 +09:00
parent a586c440fb
commit 1d910a22f9
4 changed files with 129 additions and 4 deletions

View File

@@ -53,7 +53,11 @@ public class LabelWorkService {
public Page<WorkerState> findlabelWorkStateList(LabelWorkDto.WorkerStateSearchReq searchReq) {
if (searchReq.getUserRole().equals("LABELER")) {
return labelWorkCoreService.findlabelWorkStateList(searchReq);
} else {
return labelWorkCoreService.findReviewerWorkStateList(searchReq);
}
}
public UUID findLastLabelWorkState() {

View File

@@ -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<WorkerState> findReviewerWorkStateList(WorkerStateSearchReq searchReq) {
return labelWorkRepository.findReviewerWorkStateList(searchReq);
}
}

View File

@@ -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<WorkerState> findlabelWorkStateList(LabelWorkDto.WorkerStateSearchReq searchReq);
UUID findLastLabelWorkState();
Page<WorkerState> findReviewerWorkStateList(WorkerStateSearchReq searchReq);
}

View File

@@ -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<Long> day3AgoDoneCnt =
this.caseSumExpression(
doneStateCondition.and(
this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -3)));
this.fromDateEqExpression(labelingAssignmentEntity.workStatDttm, -3)));
NumberExpression<Long> day2AgoDoneCnt =
this.caseSumExpression(
doneStateCondition.and(
this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -2)));
this.fromDateEqExpression(labelingAssignmentEntity.workStatDttm, -2)));
NumberExpression<Long> day1AgoDoneCnt =
this.caseSumExpression(
doneStateCondition.and(
this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -1)));
this.fromDateEqExpression(labelingAssignmentEntity.workStatDttm, -1)));
NumberExpression<Long> remainingCnt = assignedCnt.subtract(doneCnt);
@@ -409,6 +410,118 @@ public class LabelWorkRepositoryImpl implements LabelWorkRepositoryCustom {
return uuid;
}
@Override
public Page<WorkerState> findReviewerWorkStateList(WorkerStateSearchReq searchReq) {
Pageable pageable = PageRequest.of(searchReq.getPage(), searchReq.getSize());
BooleanBuilder whereBuilder = new BooleanBuilder();
BooleanBuilder whereSubBuilder = new BooleanBuilder();
List<OrderSpecifier<?>> 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<Long> assignedCnt = labelingAssignmentEntity.inspectorUid.count();
NumberExpression<Long> doneCnt = this.caseSumExpression(doneStateCondition);
NumberExpression<Long> skipCnt =
this.caseSumExpression(
labelingAssignmentEntity.inspectState.eq(InspectState.EXCEPT.name()));
NumberExpression<Long> day3AgoDoneCnt =
this.caseSumExpression(
doneStateCondition.and(
this.fromDateEqExpression(labelingAssignmentEntity.inspectStatDttm, -3)));
NumberExpression<Long> day2AgoDoneCnt =
this.caseSumExpression(
doneStateCondition.and(
this.fromDateEqExpression(labelingAssignmentEntity.inspectStatDttm, -2)));
NumberExpression<Long> day1AgoDoneCnt =
this.caseSumExpression(
doneStateCondition.and(
this.fromDateEqExpression(labelingAssignmentEntity.inspectStatDttm, -1)));
NumberExpression<Long> 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<WorkerState> 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 직접 반환)
*