Merge remote-tracking branch 'origin/feat/dev_251201' into feat/dev_251201
This commit is contained in:
@@ -151,18 +151,25 @@ public class LabelAllocateApiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "작업현황 관리 > 라벨러 상세 정보, 작업이관 팝업 내 라벨러 상세 정보 동일",
|
summary = "작업현황 관리 > 라벨러/검수자 상세 정보, 작업이관 팝업 내 라벨러 상세 정보 동일",
|
||||||
description = "작업현황 관리 > 라벨러 상세 정보, 작업이관 팝업 내 라벨러 상세 정보 동일")
|
description = "작업현황 관리 > 라벨러/검수자 상세 정보, 작업이관 팝업 내 라벨러 상세 정보 동일")
|
||||||
@GetMapping("/labeler-detail")
|
@GetMapping("/user-detail")
|
||||||
public ApiResponseDto<LabelerDetail> findLabelerDetail(
|
public ApiResponseDto<LabelerDetail> findUserDetail(
|
||||||
@RequestParam(defaultValue = "01022223333", required = true) String userId,
|
@RequestParam(defaultValue = "01022223333", required = true) String userId,
|
||||||
@Parameter(
|
@Parameter(
|
||||||
description = "회차 마스터 key",
|
description = "회차 마스터 key",
|
||||||
required = true,
|
required = true,
|
||||||
example = "8584e8d4-53b3-4582-bde2-28a81495a626")
|
example = "8584e8d4-53b3-4582-bde2-28a81495a626")
|
||||||
@RequestParam
|
@RequestParam
|
||||||
String uuid) {
|
String uuid,
|
||||||
return ApiResponseDto.ok(labelAllocateService.findLabelerDetail(userId, uuid));
|
@Schema(
|
||||||
|
allowableValues = {"LABELER", "REVIEWER"},
|
||||||
|
defaultValue = "LABELER")
|
||||||
|
@Parameter(
|
||||||
|
description = "라벨러/검수자(LABELER/REVIEWER)",
|
||||||
|
required = true) @RequestParam String type
|
||||||
|
) {
|
||||||
|
return ApiResponseDto.ok(labelAllocateService.findUserDetail(userId, uuid, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "작업현황 관리 > 상세 > 작업 이관", description = "작업현황 관리 > 상세 > 작업 이관")
|
@Operation(summary = "작업현황 관리 > 상세 > 작업 이관", description = "작업현황 관리 > 상세 > 작업 이관")
|
||||||
@@ -199,4 +206,33 @@ public class LabelAllocateApiController {
|
|||||||
dto.getCompareYyyy(),
|
dto.getCompareYyyy(),
|
||||||
dto.getTargetYyyy()));
|
dto.getTargetYyyy()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "라벨링작업 관리 > 상세 > 라벨러/검수자 일별 작업량 목록",
|
||||||
|
description = "라벨링작업 관리 > 상세 > 라벨러/검수자 일별 작업량 목록")
|
||||||
|
@GetMapping("/daily-list")
|
||||||
|
public ApiResponseDto<Page<LabelingStatDto>> findDaliyList(
|
||||||
|
@RequestParam(defaultValue = "0", required = true) int page,
|
||||||
|
@RequestParam(defaultValue = "20", required = true) int size,
|
||||||
|
@Parameter(
|
||||||
|
description = "회차 마스터 key",
|
||||||
|
required = true,
|
||||||
|
example = "8584e8d4-53b3-4582-bde2-28a81495a626")
|
||||||
|
@RequestParam
|
||||||
|
String uuid,
|
||||||
|
@Parameter(
|
||||||
|
description = "사번",
|
||||||
|
required = true,
|
||||||
|
example = "123456")
|
||||||
|
@RequestParam String userId,
|
||||||
|
@Schema(
|
||||||
|
allowableValues = {"LABELER", "REVIEWER"},
|
||||||
|
defaultValue = "LABELER")
|
||||||
|
@Parameter(
|
||||||
|
description = "라벨러/검수자(LABELER/REVIEWER)",
|
||||||
|
required = true) @RequestParam String type
|
||||||
|
) {
|
||||||
|
LabelAllocateDto.searchReq searchReq = new LabelAllocateDto.searchReq(page, size, "");
|
||||||
|
return ApiResponseDto.ok(labelAllocateService.findDaliyList(searchReq, uuid, userId, type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
|
||||||
public class LabelAllocateDto {
|
public class LabelAllocateDto {
|
||||||
|
|
||||||
@@ -97,9 +101,9 @@ public class LabelAllocateDto {
|
|||||||
private Integer stage;
|
private Integer stage;
|
||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description = "라벨러 할당 목록",
|
description = "라벨러 할당 목록",
|
||||||
example =
|
example =
|
||||||
"""
|
"""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"userId": "123456",
|
"userId": "123456",
|
||||||
@@ -118,9 +122,9 @@ public class LabelAllocateDto {
|
|||||||
private List<TargetUser> labelers;
|
private List<TargetUser> labelers;
|
||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description = "검수자 할당 목록",
|
description = "검수자 할당 목록",
|
||||||
example =
|
example =
|
||||||
"""
|
"""
|
||||||
["K20251216001",
|
["K20251216001",
|
||||||
"01022225555",
|
"01022225555",
|
||||||
"K20251212001"
|
"K20251212001"
|
||||||
@@ -171,6 +175,9 @@ public class LabelAllocateDto {
|
|||||||
private Long analUid;
|
private Long analUid;
|
||||||
private ZonedDateTime createdDttm;
|
private ZonedDateTime createdDttm;
|
||||||
private ZonedDateTime updatedDttm;
|
private ZonedDateTime updatedDttm;
|
||||||
|
private String inspectState;
|
||||||
|
private ZonedDateTime workStatDttm;
|
||||||
|
private ZonedDateTime inspectStatDttm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -210,7 +217,7 @@ public class LabelAllocateDto {
|
|||||||
private Double percent;
|
private Double percent;
|
||||||
private Integer ranking;
|
private Integer ranking;
|
||||||
private ZonedDateTime createdDttm;
|
private ZonedDateTime createdDttm;
|
||||||
private String inspectorName;
|
private String ownerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -225,9 +232,9 @@ public class LabelAllocateDto {
|
|||||||
private Integer stage;
|
private Integer stage;
|
||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description = "라벨러 할당 목록",
|
description = "라벨러 할당 목록",
|
||||||
example =
|
example =
|
||||||
"""
|
"""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"userId": "123456",
|
"userId": "123456",
|
||||||
@@ -256,4 +263,43 @@ public class LabelAllocateDto {
|
|||||||
private Long geoUid;
|
private Long geoUid;
|
||||||
private Long mapSheetNum;
|
private Long mapSheetNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class LabelingStatDto {
|
||||||
|
|
||||||
|
private String workDate;
|
||||||
|
private Long dailyTotalCnt;
|
||||||
|
private Long totalCnt;
|
||||||
|
private Long assignedCnt;
|
||||||
|
private Long skipCnt;
|
||||||
|
private Long completeCnt;
|
||||||
|
private Long remainCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(name = "searchReq", description = "일자별 작업 목록 요청")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class searchReq {
|
||||||
|
|
||||||
|
// 페이징 파라미터
|
||||||
|
private int page = 0;
|
||||||
|
private int size = 20;
|
||||||
|
private String sort;
|
||||||
|
|
||||||
|
public Pageable toPageable() {
|
||||||
|
if (sort != null && !sort.isEmpty()) {
|
||||||
|
String[] sortParams = sort.split(",");
|
||||||
|
String property = sortParams[0];
|
||||||
|
Sort.Direction direction =
|
||||||
|
sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC;
|
||||||
|
return PageRequest.of(page, size, Sort.by(direction, property));
|
||||||
|
}
|
||||||
|
return PageRequest.of(page, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,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.AllocateInfoDto;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelerDetail;
|
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.TargetUser;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.TargetUser;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.UserList;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.UserList;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.DailyHistory;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.DailyHistory;
|
||||||
@@ -16,6 +17,7 @@ import java.time.LocalDate;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -218,7 +220,19 @@ public class LabelAllocateService {
|
|||||||
return new ApiResponseDto.ResponseObj(ApiResponseCode.OK, "이관을 완료하였습니다.");
|
return new ApiResponseDto.ResponseObj(ApiResponseCode.OK, "이관을 완료하였습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public LabelerDetail findLabelerDetail(String userId, String uuid) {
|
public LabelerDetail findUserDetail(String userId, String uuid, String type) {
|
||||||
return labelAllocateCoreService.findLabelerDetail(userId, uuid);
|
if (type.equals("LABELER")) {
|
||||||
|
return labelAllocateCoreService.findLabelerDetail(userId, uuid);
|
||||||
|
} else {
|
||||||
|
return labelAllocateCoreService.findInspectorDetail(userId, uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Page<LabelingStatDto> findDaliyList(LabelAllocateDto.searchReq searchReq, String uuid, String userId, String type) {
|
||||||
|
if (type.equals("LABELER")) {
|
||||||
|
return labelAllocateCoreService.findLabelerDailyStat(searchReq, uuid, userId);
|
||||||
|
} else {
|
||||||
|
return labelAllocateCoreService.findInspectorDailyStat(searchReq, uuid, userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ 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.AllocateInfoDto;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelerDetail;
|
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.UserList;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.UserList;
|
||||||
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.searchReq;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.ProjectInfo;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.ProjectInfo;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkProgressInfo;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkProgressInfo;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkerStatistics;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkerStatistics;
|
||||||
@@ -14,6 +16,7 @@ import java.time.LocalDate;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -96,4 +99,16 @@ public class LabelAllocateCoreService {
|
|||||||
public void insertInspector(Long analUid, String inspector) {
|
public void insertInspector(Long analUid, String inspector) {
|
||||||
labelAllocateRepository.insertInspector(analUid, inspector);
|
labelAllocateRepository.insertInspector(analUid, inspector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Page<LabelingStatDto> findLabelerDailyStat(searchReq searchReq, String uuid, String userId) {
|
||||||
|
return labelAllocateRepository.findLabelerDailyStat(searchReq, uuid, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Page<LabelingStatDto> findInspectorDailyStat(searchReq searchReq, String uuid, String userId) {
|
||||||
|
return labelAllocateRepository.findInspectorDailyStat(searchReq, uuid, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LabelerDetail findInspectorDetail(String userId, String uuid) {
|
||||||
|
return labelAllocateRepository.findInspectorDetail(userId, uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import jakarta.persistence.Column;
|
|||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@@ -40,18 +41,31 @@ public class LabelingAssignmentEntity extends CommonDateEntity {
|
|||||||
@Column(name = "anal_uid")
|
@Column(name = "anal_uid")
|
||||||
private Long analUid;
|
private Long analUid;
|
||||||
|
|
||||||
|
@Column(name = "inspect_state")
|
||||||
|
private String inspectState;
|
||||||
|
|
||||||
|
@Column(name = "work_stat_dttm")
|
||||||
|
private ZonedDateTime workStatDttm;
|
||||||
|
|
||||||
|
@Column(name = "inspect_stat_dttm")
|
||||||
|
private ZonedDateTime inspectStatDttm;
|
||||||
|
|
||||||
public LabelAllocateDto.Basic toDto() {
|
public LabelAllocateDto.Basic toDto() {
|
||||||
return new LabelAllocateDto.Basic(
|
return new LabelAllocateDto.Basic(
|
||||||
this.assignmentUid,
|
this.assignmentUid,
|
||||||
this.inferenceGeomUid,
|
this.inferenceGeomUid,
|
||||||
this.workerUid,
|
this.workerUid,
|
||||||
this.inspectorUid,
|
this.inspectorUid,
|
||||||
this.workState,
|
this.workState,
|
||||||
this.stagnationYn,
|
this.stagnationYn,
|
||||||
this.assignGroupId,
|
this.assignGroupId,
|
||||||
this.learnGeomUid,
|
this.learnGeomUid,
|
||||||
this.analUid,
|
this.analUid,
|
||||||
super.getCreatedDate(),
|
super.getCreatedDate(),
|
||||||
super.getModifiedDate());
|
super.getModifiedDate(),
|
||||||
|
this.inspectState,
|
||||||
|
this.workStatDttm,
|
||||||
|
this.inspectStatDttm
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.kamco.cd.kamcoback.postgres.repository.label;
|
package com.kamco.cd.kamcoback.postgres.repository.label;
|
||||||
|
|
||||||
|
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.AllocateInfoDto;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelerDetail;
|
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.UserList;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.UserList;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.ProjectInfo;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.ProjectInfo;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkProgressInfo;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkProgressInfo;
|
||||||
@@ -11,11 +13,12 @@ import com.kamco.cd.kamcoback.postgres.entity.LabelingAssignmentEntity;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
public interface LabelAllocateRepositoryCustom {
|
public interface LabelAllocateRepositoryCustom {
|
||||||
|
|
||||||
List<AllocateInfoDto> fetchNextIds(
|
List<AllocateInfoDto> fetchNextIds(
|
||||||
Long lastId, Long batchSize, Integer compareYyyy, Integer targetYyyy, Integer stage);
|
Long lastId, Long batchSize, Integer compareYyyy, Integer targetYyyy, Integer stage);
|
||||||
|
|
||||||
void assignOwner(List<AllocateInfoDto> ids, String userId, Long analUid);
|
void assignOwner(List<AllocateInfoDto> ids, String userId, Long analUid);
|
||||||
|
|
||||||
@@ -32,7 +35,7 @@ public interface LabelAllocateRepositoryCustom {
|
|||||||
|
|
||||||
// 작업자 통계 조회
|
// 작업자 통계 조회
|
||||||
List<WorkerStatistics> findWorkerStatistics(
|
List<WorkerStatistics> findWorkerStatistics(
|
||||||
Long analUid, String workerType, String search, String sortType);
|
Long analUid, String workerType, String search, String sortType);
|
||||||
|
|
||||||
// 작업 진행 현황 조회
|
// 작업 진행 현황 조회
|
||||||
WorkProgressInfo findWorkProgressInfo(Long analUid);
|
WorkProgressInfo findWorkProgressInfo(Long analUid);
|
||||||
@@ -45,7 +48,7 @@ public interface LabelAllocateRepositoryCustom {
|
|||||||
InferenceDetail findInferenceDetail(String uuid);
|
InferenceDetail findInferenceDetail(String uuid);
|
||||||
|
|
||||||
List<Long> fetchNextMoveIds(
|
List<Long> fetchNextMoveIds(
|
||||||
Long lastId, Long batchSize, Integer compareYyyy, Integer targetYyyy, Integer stage);
|
Long lastId, Long batchSize, Integer compareYyyy, Integer targetYyyy, Integer stage);
|
||||||
|
|
||||||
void assignOwnerMove(List<Long> sub, String userId);
|
void assignOwnerMove(List<Long> sub, String userId);
|
||||||
|
|
||||||
@@ -54,4 +57,10 @@ public interface LabelAllocateRepositoryCustom {
|
|||||||
Long findMapSheetAnalInferenceUid(Integer compareYyyy, Integer targetYyyy, Integer stage);
|
Long findMapSheetAnalInferenceUid(Integer compareYyyy, Integer targetYyyy, Integer stage);
|
||||||
|
|
||||||
void insertInspector(Long analUid, String inspector);
|
void insertInspector(Long analUid, String inspector);
|
||||||
|
|
||||||
|
Page<LabelingStatDto> findLabelerDailyStat(LabelAllocateDto.searchReq searchReq, String uuid, String userId);
|
||||||
|
|
||||||
|
Page<LabelingStatDto> findInspectorDailyStat(LabelAllocateDto.searchReq searchReq, String uuid, String userId);
|
||||||
|
|
||||||
|
LabelerDetail findInspectorDetail(String userId, String uuid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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.InspectState;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelState;
|
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.LabelerDetail;
|
||||||
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelingStatDto;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.UserList;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.UserList;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.ProjectInfo;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.ProjectInfo;
|
||||||
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkProgressInfo;
|
import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkProgressInfo;
|
||||||
@@ -20,6 +21,7 @@ import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkerStatistics;
|
|||||||
import com.kamco.cd.kamcoback.postgres.entity.LabelingAssignmentEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.LabelingAssignmentEntity;
|
||||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity;
|
||||||
import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity;
|
||||||
|
import com.querydsl.core.types.Expression;
|
||||||
import com.querydsl.core.types.Projections;
|
import com.querydsl.core.types.Projections;
|
||||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||||
import com.querydsl.core.types.dsl.CaseBuilder;
|
import com.querydsl.core.types.dsl.CaseBuilder;
|
||||||
@@ -43,6 +45,9 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageImpl;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -567,29 +572,29 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
QMemberEntity inspector = new QMemberEntity("inspector");
|
QMemberEntity inspector = new QMemberEntity("inspector");
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(
|
.select(
|
||||||
Projections.constructor(
|
Projections.constructor(
|
||||||
LabelerDetail.class,
|
LabelerDetail.class,
|
||||||
worker.userRole,
|
worker.userRole,
|
||||||
worker.name,
|
worker.name,
|
||||||
worker.employeeNo,
|
worker.employeeNo,
|
||||||
assignedCnt,
|
assignedCnt,
|
||||||
skipCnt,
|
skipCnt,
|
||||||
completeCnt,
|
completeCnt,
|
||||||
percent,
|
percent,
|
||||||
Expressions.constant(0), // TODO: 순위, 꼭 해야할지?
|
Expressions.constant(0), // TODO: 순위, 꼭 해야할지?
|
||||||
labelingAssignmentEntity.createdDate.min(),
|
labelingAssignmentEntity.workStatDttm.min(),
|
||||||
inspector.name.min()))
|
inspector.name.min()))
|
||||||
.from(worker)
|
.from(worker)
|
||||||
.innerJoin(labelingAssignmentEntity)
|
.innerJoin(labelingAssignmentEntity)
|
||||||
.on(
|
.on(
|
||||||
worker.employeeNo.eq(labelingAssignmentEntity.workerUid),
|
worker.employeeNo.eq(labelingAssignmentEntity.workerUid),
|
||||||
labelingAssignmentEntity.analUid.eq(analEntity.getId()))
|
labelingAssignmentEntity.analUid.eq(analEntity.getId()))
|
||||||
.leftJoin(inspector)
|
.leftJoin(inspector)
|
||||||
.on(labelingAssignmentEntity.inspectorUid.eq(inspector.employeeNo))
|
.on(labelingAssignmentEntity.inspectorUid.eq(inspector.employeeNo))
|
||||||
.where(worker.employeeNo.eq(userId))
|
.where(worker.employeeNo.eq(userId))
|
||||||
.groupBy(worker.userRole, worker.name, worker.employeeNo)
|
.groupBy(worker.userRole, worker.name, worker.employeeNo)
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -681,4 +686,288 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto
|
|||||||
}
|
}
|
||||||
return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<LabelingStatDto> findLabelerDailyStat(LabelAllocateDto.searchReq searchReq, String uuid, String userId) {
|
||||||
|
// 날짜 포맷
|
||||||
|
Expression<String> workDate =
|
||||||
|
Expressions.stringTemplate(
|
||||||
|
"TO_CHAR({0}, 'YYYY-MM-DD')",
|
||||||
|
labelingAssignmentEntity.workStatDttm
|
||||||
|
);
|
||||||
|
|
||||||
|
// 날짜별 전체 건수
|
||||||
|
Expression<Long> dailyTotalCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*)"
|
||||||
|
);
|
||||||
|
|
||||||
|
// ⭐ 전체 기간 총 건수 (윈도우 함수)
|
||||||
|
Expression<Long> totalCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"SUM(COUNT(*)) OVER ()"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 상태별 카운트 (Postgres FILTER 사용)
|
||||||
|
Expression<Long> assignedCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*) FILTER (WHERE {0} = 'ASSIGNED')",
|
||||||
|
labelingAssignmentEntity.workState
|
||||||
|
);
|
||||||
|
|
||||||
|
Expression<Long> skipCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*) FILTER (WHERE {0} = 'SKIP')",
|
||||||
|
labelingAssignmentEntity.workState
|
||||||
|
);
|
||||||
|
|
||||||
|
Expression<Long> completeCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*) FILTER (WHERE {0} = 'COMPLETE')",
|
||||||
|
labelingAssignmentEntity.workState
|
||||||
|
);
|
||||||
|
|
||||||
|
Expression<Long> remainCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"({0} - {1} - {2})",
|
||||||
|
totalCnt,
|
||||||
|
skipCnt,
|
||||||
|
completeCnt
|
||||||
|
);
|
||||||
|
|
||||||
|
// analUid로 분석 정보 조회
|
||||||
|
MapSheetAnalInferenceEntity analEntity =
|
||||||
|
queryFactory
|
||||||
|
.selectFrom(mapSheetAnalInferenceEntity)
|
||||||
|
.where(mapSheetAnalInferenceEntity.uuid.eq(UUID.fromString(uuid)))
|
||||||
|
.fetchOne();
|
||||||
|
|
||||||
|
if (Objects.isNull(analEntity)) {
|
||||||
|
throw new EntityNotFoundException("MapSheetAnalInferenceEntity not found for analUid: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Pageable pageable = searchReq.toPageable();
|
||||||
|
List<LabelingStatDto> foundContent = queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.constructor(
|
||||||
|
LabelingStatDto.class,
|
||||||
|
workDate,
|
||||||
|
dailyTotalCnt,
|
||||||
|
totalCnt, // ⭐ 전체 일자 배정 건수
|
||||||
|
assignedCnt,
|
||||||
|
skipCnt,
|
||||||
|
completeCnt,
|
||||||
|
remainCnt
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(labelingAssignmentEntity)
|
||||||
|
.where(
|
||||||
|
labelingAssignmentEntity.workerUid.eq(userId),
|
||||||
|
labelingAssignmentEntity.analUid.eq(analEntity.getId())
|
||||||
|
)
|
||||||
|
.groupBy(workDate)
|
||||||
|
.orderBy(labelingAssignmentEntity.workStatDttm.min().asc())
|
||||||
|
.offset(pageable.getOffset())
|
||||||
|
.limit(pageable.getPageSize())
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
Long countQuery = queryFactory
|
||||||
|
.select(workDate)
|
||||||
|
.from(labelingAssignmentEntity)
|
||||||
|
.where(
|
||||||
|
labelingAssignmentEntity.workerUid.eq(userId),
|
||||||
|
labelingAssignmentEntity.analUid.eq(analEntity.getId())
|
||||||
|
)
|
||||||
|
.distinct()
|
||||||
|
.fetch()
|
||||||
|
.stream()
|
||||||
|
.count();
|
||||||
|
|
||||||
|
return new PageImpl<>(foundContent, pageable, countQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<LabelingStatDto> findInspectorDailyStat(searchReq searchReq, String uuid, String userId) {
|
||||||
|
// 날짜 포맷
|
||||||
|
Expression<String> workDate =
|
||||||
|
Expressions.stringTemplate(
|
||||||
|
"TO_CHAR({0}, 'YYYY-MM-DD')",
|
||||||
|
labelingAssignmentEntity.inspectStatDttm
|
||||||
|
);
|
||||||
|
|
||||||
|
// 날짜별 전체 건수
|
||||||
|
Expression<Long> dailyTotalCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*)"
|
||||||
|
);
|
||||||
|
|
||||||
|
// ⭐ 전체 기간 총 건수 (윈도우 함수)
|
||||||
|
Expression<Long> totalCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"SUM(COUNT(*)) OVER ()"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 상태별 카운트 (Postgres FILTER 사용)
|
||||||
|
Expression<Long> assignedCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*) FILTER (WHERE {0} = 'UNCONFIRM')",
|
||||||
|
labelingAssignmentEntity.inspectState
|
||||||
|
);
|
||||||
|
|
||||||
|
Expression<Long> skipCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*) FILTER (WHERE {0} = 'EXCEPT')",
|
||||||
|
labelingAssignmentEntity.inspectState
|
||||||
|
);
|
||||||
|
|
||||||
|
Expression<Long> completeCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"COUNT(*) FILTER (WHERE {0} = 'COMPLETE')",
|
||||||
|
labelingAssignmentEntity.inspectState
|
||||||
|
);
|
||||||
|
|
||||||
|
Expression<Long> remainCnt =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Long.class,
|
||||||
|
"({0} - {1} - {2})",
|
||||||
|
totalCnt,
|
||||||
|
skipCnt,
|
||||||
|
completeCnt
|
||||||
|
);
|
||||||
|
|
||||||
|
// analUid로 분석 정보 조회
|
||||||
|
MapSheetAnalInferenceEntity analEntity =
|
||||||
|
queryFactory
|
||||||
|
.selectFrom(mapSheetAnalInferenceEntity)
|
||||||
|
.where(mapSheetAnalInferenceEntity.uuid.eq(UUID.fromString(uuid)))
|
||||||
|
.fetchOne();
|
||||||
|
|
||||||
|
if (Objects.isNull(analEntity)) {
|
||||||
|
throw new EntityNotFoundException("MapSheetAnalInferenceEntity not found for analUid: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Pageable pageable = searchReq.toPageable();
|
||||||
|
List<LabelingStatDto> foundContent = queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.constructor(
|
||||||
|
LabelingStatDto.class,
|
||||||
|
workDate,
|
||||||
|
dailyTotalCnt,
|
||||||
|
totalCnt, // ⭐ 전체 일자 배정 건수
|
||||||
|
assignedCnt,
|
||||||
|
skipCnt,
|
||||||
|
completeCnt,
|
||||||
|
remainCnt
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(labelingAssignmentEntity)
|
||||||
|
.where(
|
||||||
|
labelingAssignmentEntity.inspectorUid.eq(userId),
|
||||||
|
labelingAssignmentEntity.analUid.eq(analEntity.getId())
|
||||||
|
)
|
||||||
|
.groupBy(workDate)
|
||||||
|
.orderBy(labelingAssignmentEntity.inspectStatDttm.min().asc())
|
||||||
|
.offset(pageable.getOffset())
|
||||||
|
.limit(pageable.getPageSize())
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
Long countQuery = queryFactory
|
||||||
|
.select(workDate)
|
||||||
|
.from(labelingAssignmentEntity)
|
||||||
|
.where(
|
||||||
|
labelingAssignmentEntity.inspectorUid.eq(userId),
|
||||||
|
labelingAssignmentEntity.analUid.eq(analEntity.getId())
|
||||||
|
)
|
||||||
|
.distinct()
|
||||||
|
.fetch()
|
||||||
|
.stream()
|
||||||
|
.count();
|
||||||
|
|
||||||
|
return new PageImpl<>(foundContent, pageable, countQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LabelerDetail findInspectorDetail(String userId, String uuid) {
|
||||||
|
NumberExpression<Long> assignedCnt =
|
||||||
|
new CaseBuilder()
|
||||||
|
.when(labelingAssignmentEntity.inspectState.eq(InspectState.UNCONFIRM.getId()))
|
||||||
|
.then(1L)
|
||||||
|
.otherwise((Long) null)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
NumberExpression<Long> skipCnt =
|
||||||
|
new CaseBuilder()
|
||||||
|
.when(labelingAssignmentEntity.inspectState.eq(InspectState.EXCEPT.getId()))
|
||||||
|
.then(1L)
|
||||||
|
.otherwise((Long) null)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
NumberExpression<Long> completeCnt =
|
||||||
|
new CaseBuilder()
|
||||||
|
.when(labelingAssignmentEntity.inspectState.eq(InspectState.COMPLETE.getId()))
|
||||||
|
.then(1L)
|
||||||
|
.otherwise((Long) null)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
NumberExpression<Double> percent =
|
||||||
|
new CaseBuilder()
|
||||||
|
.when(completeCnt.eq(0L))
|
||||||
|
.then(0.0)
|
||||||
|
.otherwise(
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Double.class,
|
||||||
|
"round({0} / {1}, 2)",
|
||||||
|
labelingAssignmentEntity.count(),
|
||||||
|
completeCnt));
|
||||||
|
|
||||||
|
// analUid로 분석 정보 조회
|
||||||
|
MapSheetAnalInferenceEntity analEntity =
|
||||||
|
queryFactory
|
||||||
|
.selectFrom(mapSheetAnalInferenceEntity)
|
||||||
|
.where(mapSheetAnalInferenceEntity.uuid.eq(UUID.fromString(uuid)))
|
||||||
|
.fetchOne();
|
||||||
|
|
||||||
|
if (Objects.isNull(analEntity)) {
|
||||||
|
throw new EntityNotFoundException("MapSheetAnalInferenceEntity not found for analUid: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
QMemberEntity inspector = QMemberEntity.memberEntity;
|
||||||
|
QMemberEntity worker = new QMemberEntity("worker");
|
||||||
|
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.constructor(
|
||||||
|
LabelerDetail.class,
|
||||||
|
inspector.userRole,
|
||||||
|
inspector.name,
|
||||||
|
inspector.employeeNo,
|
||||||
|
assignedCnt,
|
||||||
|
skipCnt,
|
||||||
|
completeCnt,
|
||||||
|
percent,
|
||||||
|
Expressions.constant(0), // TODO: 순위, 꼭 해야할지?
|
||||||
|
labelingAssignmentEntity.inspectStatDttm.min(),
|
||||||
|
worker.name.min()))
|
||||||
|
.from(inspector)
|
||||||
|
.innerJoin(labelingAssignmentEntity)
|
||||||
|
.on(
|
||||||
|
inspector.employeeNo.eq(labelingAssignmentEntity.inspectorUid),
|
||||||
|
labelingAssignmentEntity.analUid.eq(analEntity.getId()))
|
||||||
|
.leftJoin(worker)
|
||||||
|
.on(labelingAssignmentEntity.workerUid.eq(worker.employeeNo))
|
||||||
|
.where(inspector.employeeNo.eq(userId))
|
||||||
|
.groupBy(inspector.userRole, inspector.name, inspector.employeeNo)
|
||||||
|
.fetchOne();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user