작업현황관리 수정
This commit is contained in:
@@ -63,7 +63,7 @@ public class LabelAllocateApiController {
|
|||||||
})
|
})
|
||||||
@GetMapping("/admin/workers")
|
@GetMapping("/admin/workers")
|
||||||
public ApiResponseDto<WorkerListResponse> getWorkerStatistics(
|
public ApiResponseDto<WorkerListResponse> getWorkerStatistics(
|
||||||
@Parameter(description = "분석 ID (필수)", required = true, example = "3") @RequestParam
|
@Parameter(description = "분석 ID (선택)", example = "3") @RequestParam(required = false)
|
||||||
Long analUid,
|
Long analUid,
|
||||||
@Parameter(
|
@Parameter(
|
||||||
description = "작업자 유형 (선택) - 미입력 시 LABELER로 조회",
|
description = "작업자 유형 (선택) - 미입력 시 LABELER로 조회",
|
||||||
@@ -74,11 +74,9 @@ public class LabelAllocateApiController {
|
|||||||
defaultValue = "LABELER"))
|
defaultValue = "LABELER"))
|
||||||
@RequestParam(required = false)
|
@RequestParam(required = false)
|
||||||
String type,
|
String type,
|
||||||
@Parameter(description = "작업자 이름 검색 (부분 일치)", example = "김라벨") @RequestParam(required = false)
|
@Parameter(description = "검색어 (작업자 이름 또는 사번으로 검색, 부분 일치)", example = "김라벨")
|
||||||
String searchName,
|
|
||||||
@Parameter(description = "작업자 사번 검색 (부분 일치)", example = "1234567")
|
|
||||||
@RequestParam(required = false)
|
@RequestParam(required = false)
|
||||||
String searchEmployeeNo,
|
String search,
|
||||||
@Parameter(
|
@Parameter(
|
||||||
description = "정렬 조건 (선택) - 미입력 시 이름 오름차순",
|
description = "정렬 조건 (선택) - 미입력 시 이름 오름차순",
|
||||||
example = "REMAINING_DESC",
|
example = "REMAINING_DESC",
|
||||||
@@ -92,14 +90,20 @@ public class LabelAllocateApiController {
|
|||||||
},
|
},
|
||||||
defaultValue = "NAME_ASC"))
|
defaultValue = "NAME_ASC"))
|
||||||
@RequestParam(required = false)
|
@RequestParam(required = false)
|
||||||
String sort) {
|
String sort,
|
||||||
|
@Parameter(description = "페이지 번호 (0부터 시작)", example = "0")
|
||||||
|
@RequestParam(defaultValue = "0")
|
||||||
|
Integer page,
|
||||||
|
@Parameter(description = "페이지 크기", example = "20")
|
||||||
|
@RequestParam(defaultValue = "20")
|
||||||
|
Integer size) {
|
||||||
|
|
||||||
// type이 null이면 기본값으로 LABELER 설정
|
// type이 null이면 기본값으로 LABELER 설정
|
||||||
String workerType = (type == null || type.isEmpty()) ? RoleType.LABELER.name() : type;
|
String workerType = (type == null || type.isEmpty()) ? RoleType.LABELER.name() : type;
|
||||||
|
|
||||||
return ApiResponseDto.ok(
|
return ApiResponseDto.ok(
|
||||||
labelAllocateService.getWorkerStatistics(
|
labelAllocateService.getWorkerStatistics(
|
||||||
analUid, workerType, searchName, searchEmployeeNo, sort));
|
analUid, workerType, search, sort, page, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "라벨링작업 관리 > 작업 배정", description = "라벨링작업 관리 > 작업 배정")
|
@Operation(summary = "라벨링작업 관리 > 작업 배정", description = "라벨링작업 관리 > 작업 배정")
|
||||||
|
|||||||
@@ -113,5 +113,17 @@ public class WorkerStatsDto {
|
|||||||
|
|
||||||
@Schema(description = "작업자 목록")
|
@Schema(description = "작업자 목록")
|
||||||
private List<WorkerStatistics> workers;
|
private List<WorkerStatistics> workers;
|
||||||
|
|
||||||
|
@Schema(description = "현재 페이지 번호 (0부터 시작)")
|
||||||
|
private Integer currentPage;
|
||||||
|
|
||||||
|
@Schema(description = "페이지 크기")
|
||||||
|
private Integer pageSize;
|
||||||
|
|
||||||
|
@Schema(description = "전체 데이터 수")
|
||||||
|
private Long totalElements;
|
||||||
|
|
||||||
|
@Schema(description = "전체 페이지 수")
|
||||||
|
private Integer totalPages;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,21 +107,23 @@ public class LabelAllocateService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 작업자 목록 및 3일치 통계 조회
|
* 작업자 통계 조회
|
||||||
*
|
*
|
||||||
* @param analUid 분석 ID
|
* @param analUid 분석 ID
|
||||||
* @param workerType 작업자 유형 (LABELER/INSPECTOR)
|
* @param workerType 작업자 유형 (LABELER/INSPECTOR)
|
||||||
* @param searchName 이름 검색
|
* @param search 검색어 (이름 또는 사번)
|
||||||
* @param searchEmployeeNo 사번 검색
|
|
||||||
* @param sortType 정렬 조건
|
* @param sortType 정렬 조건
|
||||||
|
* @param page 페이지 번호 (0부터 시작)
|
||||||
|
* @param size 페이지 크기
|
||||||
* @return 작업자 목록 및 통계
|
* @return 작업자 목록 및 통계
|
||||||
*/
|
*/
|
||||||
public WorkerListResponse getWorkerStatistics(
|
public WorkerListResponse getWorkerStatistics(
|
||||||
Long analUid,
|
Long analUid,
|
||||||
String workerType,
|
String workerType,
|
||||||
String searchName,
|
String search,
|
||||||
String searchEmployeeNo,
|
String sortType,
|
||||||
String sortType) {
|
Integer page,
|
||||||
|
Integer size) {
|
||||||
|
|
||||||
// 작업 진행 현황 조회
|
// 작업 진행 현황 조회
|
||||||
var progressInfo = labelAllocateCoreService.findWorkProgressInfo(analUid);
|
var progressInfo = labelAllocateCoreService.findWorkProgressInfo(analUid);
|
||||||
@@ -129,7 +131,7 @@ public class LabelAllocateService {
|
|||||||
// 작업자 통계 조회
|
// 작업자 통계 조회
|
||||||
List<WorkerStatistics> workers =
|
List<WorkerStatistics> workers =
|
||||||
labelAllocateCoreService.findWorkerStatistics(
|
labelAllocateCoreService.findWorkerStatistics(
|
||||||
analUid, workerType, searchName, searchEmployeeNo, sortType);
|
analUid, workerType, search, sortType);
|
||||||
|
|
||||||
// 각 작업자별 3일치 처리량 조회
|
// 각 작업자별 3일치 처리량 조회
|
||||||
LocalDate today = LocalDate.now();
|
LocalDate today = LocalDate.now();
|
||||||
@@ -162,7 +164,23 @@ public class LabelAllocateService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return WorkerListResponse.builder().progressInfo(progressInfo).workers(workers).build();
|
// 페이징 처리
|
||||||
|
long totalElements = workers.size();
|
||||||
|
int totalPages = (int) Math.ceil((double) totalElements / size);
|
||||||
|
int fromIndex = page * size;
|
||||||
|
int toIndex = Math.min(fromIndex + size, workers.size());
|
||||||
|
|
||||||
|
List<WorkerStatistics> pagedWorkers =
|
||||||
|
(fromIndex < workers.size()) ? workers.subList(fromIndex, toIndex) : List.of();
|
||||||
|
|
||||||
|
return WorkerListResponse.builder()
|
||||||
|
.progressInfo(progressInfo)
|
||||||
|
.workers(pagedWorkers)
|
||||||
|
.currentPage(page)
|
||||||
|
.pageSize(size)
|
||||||
|
.totalElements(totalElements)
|
||||||
|
.totalPages(totalPages)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InferenceDetail findInferenceDetail(
|
public InferenceDetail findInferenceDetail(
|
||||||
|
|||||||
@@ -57,11 +57,10 @@ public class LabelAllocateCoreService {
|
|||||||
public List<WorkerStatistics> findWorkerStatistics(
|
public List<WorkerStatistics> findWorkerStatistics(
|
||||||
Long analUid,
|
Long analUid,
|
||||||
String workerType,
|
String workerType,
|
||||||
String searchName,
|
String search,
|
||||||
String searchEmployeeNo,
|
|
||||||
String sortType) {
|
String sortType) {
|
||||||
return labelAllocateRepository.findWorkerStatistics(
|
return labelAllocateRepository.findWorkerStatistics(
|
||||||
analUid, workerType, searchName, searchEmployeeNo, sortType);
|
analUid, workerType, search, sortType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorkProgressInfo findWorkProgressInfo(Long analUid) {
|
public WorkProgressInfo findWorkProgressInfo(Long analUid) {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public interface LabelAllocateRepositoryCustom {
|
|||||||
|
|
||||||
// 작업자 통계 조회
|
// 작업자 통계 조회
|
||||||
List<WorkerStatistics> findWorkerStatistics(
|
List<WorkerStatistics> findWorkerStatistics(
|
||||||
Long analUid, String workerType, String searchName, String searchEmployeeNo, String sortType);
|
Long analUid, String workerType, String search, String sortType);
|
||||||
|
|
||||||
// 작업 진행 현황 조회
|
// 작업 진행 현황 조회
|
||||||
WorkProgressInfo findWorkProgressInfo(Long analUid);
|
WorkProgressInfo findWorkProgressInfo(Long analUid);
|
||||||
|
|||||||
@@ -206,8 +206,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
public List<WorkerStatistics> findWorkerStatistics(
|
public List<WorkerStatistics> findWorkerStatistics(
|
||||||
Long analUid,
|
Long analUid,
|
||||||
String workerType,
|
String workerType,
|
||||||
String searchName,
|
String search,
|
||||||
String searchEmployeeNo,
|
|
||||||
String sortType) {
|
String sortType) {
|
||||||
|
|
||||||
// 작업자 유형에 따른 필드 선택
|
// 작업자 유형에 따른 필드 선택
|
||||||
@@ -221,14 +220,11 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
? labelingAssignmentEntity.inspectorUid.isNotNull()
|
? labelingAssignmentEntity.inspectorUid.isNotNull()
|
||||||
: labelingAssignmentEntity.workerUid.isNotNull();
|
: labelingAssignmentEntity.workerUid.isNotNull();
|
||||||
|
|
||||||
// 검색 조건
|
// 검색 조건 (이름 또는 사번으로 검색)
|
||||||
BooleanExpression searchCondition = null;
|
BooleanExpression searchCondition = null;
|
||||||
if (searchName != null && !searchName.isEmpty()) {
|
if (search != null && !search.isEmpty()) {
|
||||||
searchCondition = memberEntity.name.contains(searchName);
|
searchCondition = memberEntity.name.contains(search)
|
||||||
}
|
.or(memberEntity.employeeNo.contains(search));
|
||||||
if (searchEmployeeNo != null && !searchEmployeeNo.isEmpty()) {
|
|
||||||
BooleanExpression empCondition = memberEntity.employeeNo.contains(searchEmployeeNo);
|
|
||||||
searchCondition = searchCondition == null ? empCondition : searchCondition.and(empCondition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 완료, 스킵, 남은 작업 계산
|
// 완료, 스킵, 남은 작업 계산
|
||||||
@@ -258,6 +254,8 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
.sum();
|
.sum();
|
||||||
|
|
||||||
// 기본 통계 조회 쿼리
|
// 기본 통계 조회 쿼리
|
||||||
|
BooleanExpression analUidCondition = analUid != null ? labelingAssignmentEntity.analUid.eq(analUid) : null;
|
||||||
|
|
||||||
var baseQuery =
|
var baseQuery =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(
|
.select(
|
||||||
@@ -274,7 +272,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
"REVIEWER".equals(workerType)
|
"REVIEWER".equals(workerType)
|
||||||
? memberEntity.employeeNo.eq(labelingAssignmentEntity.inspectorUid)
|
? memberEntity.employeeNo.eq(labelingAssignmentEntity.inspectorUid)
|
||||||
: memberEntity.employeeNo.eq(labelingAssignmentEntity.workerUid))
|
: memberEntity.employeeNo.eq(labelingAssignmentEntity.workerUid))
|
||||||
.where(labelingAssignmentEntity.analUid.eq(analUid), workerCondition, searchCondition)
|
.where(analUidCondition, workerCondition, searchCondition)
|
||||||
.groupBy(workerIdField, memberEntity.name);
|
.groupBy(workerIdField, memberEntity.name);
|
||||||
|
|
||||||
// 정렬 조건 적용
|
// 정렬 조건 적용
|
||||||
@@ -321,12 +319,14 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorkProgressInfo findWorkProgressInfo(Long analUid) {
|
public WorkProgressInfo findWorkProgressInfo(Long analUid) {
|
||||||
|
BooleanExpression analUidCondition = analUid != null ? labelingAssignmentEntity.analUid.eq(analUid) : null;
|
||||||
|
|
||||||
// 전체 배정 건수
|
// 전체 배정 건수
|
||||||
Long totalAssigned =
|
Long totalAssigned =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(labelingAssignmentEntity.count())
|
.select(labelingAssignmentEntity.count())
|
||||||
.from(labelingAssignmentEntity)
|
.from(labelingAssignmentEntity)
|
||||||
.where(labelingAssignmentEntity.analUid.eq(analUid))
|
.where(analUidCondition)
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|
||||||
// 완료 + 스킵 건수
|
// 완료 + 스킵 건수
|
||||||
@@ -335,7 +335,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
.select(labelingAssignmentEntity.count())
|
.select(labelingAssignmentEntity.count())
|
||||||
.from(labelingAssignmentEntity)
|
.from(labelingAssignmentEntity)
|
||||||
.where(
|
.where(
|
||||||
labelingAssignmentEntity.analUid.eq(analUid),
|
analUidCondition,
|
||||||
labelingAssignmentEntity.workState.in("DONE", "SKIP"))
|
labelingAssignmentEntity.workState.in("DONE", "SKIP"))
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
.select(labelingAssignmentEntity.workerUid.countDistinct())
|
.select(labelingAssignmentEntity.workerUid.countDistinct())
|
||||||
.from(labelingAssignmentEntity)
|
.from(labelingAssignmentEntity)
|
||||||
.where(
|
.where(
|
||||||
labelingAssignmentEntity.analUid.eq(analUid),
|
analUidCondition,
|
||||||
labelingAssignmentEntity.workerUid.isNotNull())
|
labelingAssignmentEntity.workerUid.isNotNull())
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
.select(labelingAssignmentEntity.count())
|
.select(labelingAssignmentEntity.count())
|
||||||
.from(labelingAssignmentEntity)
|
.from(labelingAssignmentEntity)
|
||||||
.where(
|
.where(
|
||||||
labelingAssignmentEntity.analUid.eq(analUid),
|
analUidCondition,
|
||||||
labelingAssignmentEntity.workerUid.isNotNull(),
|
labelingAssignmentEntity.workerUid.isNotNull(),
|
||||||
labelingAssignmentEntity.workState.notIn("DONE", "SKIP"))
|
labelingAssignmentEntity.workState.notIn("DONE", "SKIP"))
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
@@ -366,7 +366,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
.select(labelingAssignmentEntity.inspectorUid.countDistinct())
|
.select(labelingAssignmentEntity.inspectorUid.countDistinct())
|
||||||
.from(labelingAssignmentEntity)
|
.from(labelingAssignmentEntity)
|
||||||
.where(
|
.where(
|
||||||
labelingAssignmentEntity.analUid.eq(analUid),
|
analUidCondition,
|
||||||
labelingAssignmentEntity.inspectorUid.isNotNull())
|
labelingAssignmentEntity.inspectorUid.isNotNull())
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
.select(labelingAssignmentEntity.count())
|
.select(labelingAssignmentEntity.count())
|
||||||
.from(labelingAssignmentEntity)
|
.from(labelingAssignmentEntity)
|
||||||
.where(
|
.where(
|
||||||
labelingAssignmentEntity.analUid.eq(analUid),
|
analUidCondition,
|
||||||
labelingAssignmentEntity.inspectorUid.isNotNull(),
|
labelingAssignmentEntity.inspectorUid.isNotNull(),
|
||||||
labelingAssignmentEntity.workState.notIn("DONE"))
|
labelingAssignmentEntity.workState.notIn("DONE"))
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
@@ -416,12 +416,14 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
? labelingAssignmentEntity.inspectorUid.eq(workerId)
|
? labelingAssignmentEntity.inspectorUid.eq(workerId)
|
||||||
: labelingAssignmentEntity.workerUid.eq(workerId);
|
: labelingAssignmentEntity.workerUid.eq(workerId);
|
||||||
|
|
||||||
|
BooleanExpression analUidCondition = analUid != null ? labelingAssignmentEntity.analUid.eq(analUid) : null;
|
||||||
|
|
||||||
Long count =
|
Long count =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(labelingAssignmentEntity.count())
|
.select(labelingAssignmentEntity.count())
|
||||||
.from(labelingAssignmentEntity)
|
.from(labelingAssignmentEntity)
|
||||||
.where(
|
.where(
|
||||||
labelingAssignmentEntity.analUid.eq(analUid),
|
analUidCondition,
|
||||||
workerCondition,
|
workerCondition,
|
||||||
labelingAssignmentEntity.workState.in(
|
labelingAssignmentEntity.workState.in(
|
||||||
LabelState.DONE.getId(), LabelState.SKIP.getId()),
|
LabelState.DONE.getId(), LabelState.SKIP.getId()),
|
||||||
|
|||||||
Reference in New Issue
Block a user