From 341b1c8f2e545ff7190d7641d086c1ce92781dbf Mon Sep 17 00:00:00 2001 From: Moon Date: Tue, 6 Jan 2026 12:02:37 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EC=9E=91=EC=97=85=ED=98=84=ED=99=A9=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../label/LabelWorkerApiController.java | 7 + .../cd/kamcoback/label/dto/LabelWorkDto.java | 3 + .../label/LabelWorkRepositoryImpl.java | 139 ++++++++++-------- 3 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java b/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java index 5cccb20f..275305fe 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java @@ -126,6 +126,12 @@ public class LabelWorkerApiController { String userRole, @Parameter(description = "검색어", example = "20261201") @RequestParam(required = false) String searchVal, + @Parameter( + description = "정렬", + example = "", + schema = @Schema(allowableValues = {"remindCnt desc", "doneCnt desc"})) + @RequestParam(required = false) + String sort, @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") @@ -139,6 +145,7 @@ public class LabelWorkerApiController { searchReq.setUserRole(userRole); searchReq.setSearchVal(searchVal); searchReq.setUuid(uuid); + searchReq.setSort(sort); searchReq.setPage(page); searchReq.setSize(size); return ApiResponseDto.ok(labelWorkService.findlabelWorkStateList(searchReq)); diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java index f4afbf7f..7ab01364 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java @@ -211,6 +211,9 @@ public class LabelWorkDto { @Schema(description = "종료일", example = "20261201") private String uuid; + @Schema(description = "정렬(remindCnt desc, doneCnt desc)", example = "remindCnt desc") + private String sort; + public Pageable toPageable() { return PageRequest.of(page, size); 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 910aa3d6..8f01bed8 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 static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceG import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity; +import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelState; 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; @@ -13,8 +14,11 @@ import com.kamco.cd.kamcoback.label.dto.LabelWorkDto.WorkerState; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity; import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.DateTimePath; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.core.types.dsl.StringExpression; @@ -26,6 +30,7 @@ import java.time.LocalDate; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import lombok.extern.slf4j.Slf4j; @@ -208,21 +213,14 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport @Override public Page findlabelWorkStateList(LabelWorkDto.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()); - LocalDate threeDaysAgo = LocalDate.now().minusDays(3); - String s3 = threeDaysAgo.format(DateTimeFormatter.ofPattern("YYYY-MM-DD")); - - LocalDate twoDaysAgo = LocalDate.now().minusDays(2); - String s2 = twoDaysAgo.format(DateTimeFormatter.ofPattern("YYYY-MM-DD")); - - LocalDate oneDaysAgo = LocalDate.now().minusDays(1); - String s1 = oneDaysAgo.format(DateTimeFormatter.ofPattern("YYYY-MM-DD")); - if (searchReq.getUserRole() != null && !searchReq.getUserRole().isEmpty()) { whereSubBuilder.and(memberEntity.userRole.eq(searchReq.getUserRole())); } @@ -238,6 +236,43 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport whereSubBuilder.and(labelingAssignmentEntity.workerUid.eq(memberEntity.userId)); + NumberExpression assignedCnt = labelingAssignmentEntity.workerUid.count(); + NumberExpression doneCnt = + this.caseSumExpression(labelingAssignmentEntity.workState.eq(LabelState.DONE.name())); + NumberExpression skipCnt = + this.caseSumExpression(labelingAssignmentEntity.workState.eq(LabelState.SKIP.name())); + + NumberExpression day3AgoDoneCnt = + this.caseSumExpression( + labelingAssignmentEntity + .workState + .eq(LabelState.DONE.name()) + .and(this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -3))); + + NumberExpression day2AgoDoneCnt = + this.caseSumExpression( + labelingAssignmentEntity + .workState + .eq(LabelState.DONE.name()) + .and(this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -2))); + + NumberExpression day1AgoDoneCnt = + this.caseSumExpression( + labelingAssignmentEntity + .workState + .eq(LabelState.DONE.name()) + .and(this.fromDateEqExpression(labelingAssignmentEntity.modifiedDate, -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( @@ -246,61 +281,12 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport memberEntity.userRole, memberEntity.name, memberEntity.userId, - labelingAssignmentEntity.workerUid.count().as("assignedCnt"), - new CaseBuilder() - .when(labelingAssignmentEntity.workState.eq("DONE")) - .then(1L) - .otherwise(0L) - .sum() - .as("doneCnt"), - new CaseBuilder() - .when(labelingAssignmentEntity.workState.eq("SKIP")) - .then(1L) - .otherwise(0L) - .sum() - .as("skipCnt"), - new CaseBuilder() - .when( - labelingAssignmentEntity - .workState - .eq("DONE") - .and( - Expressions.stringTemplate( - "to_char({0}, 'YYYY-MM-DD')", - labelingAssignmentEntity.modifiedDate) - .eq(s3))) - .then(1L) - .otherwise(0L) - .sum() - .as("day3AgoDoneCnt"), - new CaseBuilder() - .when( - labelingAssignmentEntity - .workState - .eq("DONE") - .and( - Expressions.stringTemplate( - "to_char({0}, 'YYYY-MM-DD')", - labelingAssignmentEntity.modifiedDate) - .eq(s2))) - .then(1L) - .otherwise(0L) - .sum() - .as("day2AgoDoneCnt"), - new CaseBuilder() - .when( - labelingAssignmentEntity - .workState - .eq("DONE") - .and( - Expressions.stringTemplate( - "to_char({0}, 'YYYY-MM-DD')", - labelingAssignmentEntity.modifiedDate) - .eq(s1))) - .then(1L) - .otherwise(0L) - .sum() - .as("day1AgoDoneCnt"))) + assignedCnt.as("assignedCnt"), + doneCnt.as("doneCnt"), + skipCnt.as("skipCnt"), + day3AgoDoneCnt.as("day3AgoDoneCnt"), + day2AgoDoneCnt.as("day2AgoDoneCnt"), + day1AgoDoneCnt.as("day1AgoDoneCnt"))) .from(labelingAssignmentEntity) .innerJoin(mapSheetAnalInferenceEntity) .on( @@ -312,6 +298,7 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport .on(whereSubBuilder) .where(whereBuilder) .groupBy(memberEntity.userRole, memberEntity.name, memberEntity.userId) + .orderBy(orderSpecifiers.toArray(new OrderSpecifier[0])) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); @@ -413,4 +400,28 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport mapSheetAnalInferenceEntity.createdDttm) .fetchOne(); } + + public NumberExpression caseSumExpression(BooleanExpression condition) { + NumberExpression sumExp = + new CaseBuilder() + .when(labelingAssignmentEntity.workState.eq("DONE")) + .then(1L) + .otherwise(0L) + .sum(); + + return sumExp; + } + + public BooleanExpression fromDateEqExpression(DateTimePath path, int addDayCnt) { + + LocalDate threeDaysAgo = LocalDate.now().plusDays(addDayCnt); + String toDate = threeDaysAgo.format(DateTimeFormatter.ofPattern("YYYY-MM-DD")); + + // System.out.println("toDate == " + toDate); + + BooleanExpression condition = + Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", path).eq(toDate); + + return condition; + } } From bb920c6ca863daded35c42738b8dbd4be88a9b42 Mon Sep 17 00:00:00 2001 From: Moon Date: Tue, 6 Jan 2026 12:05:27 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EC=9E=91=EC=97=85=ED=98=84=ED=99=A9=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../postgres/repository/label/LabelWorkRepositoryImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 8f01bed8..bee35325 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 @@ -404,7 +404,7 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport public NumberExpression caseSumExpression(BooleanExpression condition) { NumberExpression sumExp = new CaseBuilder() - .when(labelingAssignmentEntity.workState.eq("DONE")) + .when(condition) .then(1L) .otherwise(0L) .sum(); @@ -417,8 +417,6 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport LocalDate threeDaysAgo = LocalDate.now().plusDays(addDayCnt); String toDate = threeDaysAgo.format(DateTimeFormatter.ofPattern("YYYY-MM-DD")); - // System.out.println("toDate == " + toDate); - BooleanExpression condition = Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", path).eq(toDate); From 91ebcc9551042740d946c0ac050389abd9b14769 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Tue, 6 Jan 2026 12:12:35 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=EB=9D=BC=EB=B2=A8=EC=9E=91=EC=97=85?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EB=AA=A9=EB=A1=9D=20API=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=20=EC=88=98=EC=A0=95,=20=EC=97=90=EB=9F=AC=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EB=82=A0=EC=A7=9C=20=EB=B3=80=ED=99=98=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 --- .../label/LabelWorkerApiController.java | 9 ++++---- .../cd/kamcoback/label/dto/LabelWorkDto.java | 9 ++++---- .../label/service/LabelAllocateService.java | 22 +------------------ .../label/LabelWorkRepositoryImpl.java | 21 ++++-------------- .../log/ErrorLogRepositoryImpl.java | 12 +++++----- 5 files changed, 22 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java b/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java index 275305fe..e8bef564 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/LabelWorkerApiController.java @@ -16,6 +16,7 @@ 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.time.LocalDate; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -71,10 +72,10 @@ public class LabelWorkerApiController { public ApiResponseDto> labelWorkMngList( @Parameter(description = "변화탐지년도", example = "2022-2024") @RequestParam(required = false) String detectYear, - @Parameter(description = "시작일", example = "20220101") @RequestParam(required = false) - String strtDttm, - @Parameter(description = "종료일", example = "20261201") @RequestParam(required = false) - String endDttm, + @Parameter(description = "시작일", example = "2022-01-01") @RequestParam(required = false) + LocalDate strtDttm, + @Parameter(description = "종료일", example = "2026-12-01") @RequestParam(required = false) + LocalDate endDttm, @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/label/dto/LabelWorkDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java index 7ab01364..cde2b946 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelWorkDto.java @@ -5,6 +5,7 @@ import com.kamco.cd.kamcoback.common.utils.enums.Enums; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState; import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDate; import java.time.ZonedDateTime; import java.util.UUID; import lombok.AllArgsConstructor; @@ -120,11 +121,11 @@ public class LabelWorkDto { @Schema(description = "변화탐지년도", example = "2024") private String detectYear; - @Schema(description = "시작일", example = "20260101") - private String strtDttm; + @Schema(description = "시작일", example = "2026-01-01") + private LocalDate strtDttm; - @Schema(description = "종료일", example = "20261201") - private String endDttm; + @Schema(description = "종료일", example = "2026-12-01") + private LocalDate endDttm; public Pageable toPageable() { diff --git a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java index 8b6b82b9..a0dfadf2 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java @@ -74,31 +74,11 @@ public class LabelAllocateService { index = end; } - // 검수자에게 userCount명 만큼 할당 - List list = labelAllocateCoreService.findAssignedLabelerList(analUid); - + // 검수자 할당 테이블에 insert. TODO: 익일 배치로 라벨링 완료된 내역을 검수자에게 할당해야 함 for (String inspector : targetInspectors) { labelAllocateCoreService.insertInspector(analUid, inspector); } - // int from = 0; - // for (TargetInspector inspector : targetInspectors) { - // int to = Math.min(from + inspector.getUserCount(), list.size()); - // - // if (from >= to) { - // break; - // } - // - // List assignmentUids = - // list.subList(from, - // to).stream().map(LabelAllocateDto.Basic::getAssignmentUid).toList(); - // - // labelAllocateCoreService.assignInspectorBulk(assignmentUids, - // inspector.getInspectorUid()); - // - // from = to; - // } - return new ApiResponseDto.ResponseObj(ApiResponseCode.OK, "배정이 완료되었습니다."); } 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 bee35325..8979cebe 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 @@ -114,21 +114,13 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport whereSubBuilder.and( mapSheetAnalDataInferenceGeomEntity.dataUid.eq(mapSheetAnalDataInferenceEntity.id)); - if (searchReq.getStrtDttm() != null - && !searchReq.getStrtDttm().isEmpty() - && searchReq.getEndDttm() != null - && !searchReq.getEndDttm().isEmpty()) { + if (searchReq.getStrtDttm() != null && searchReq.getEndDttm() != null) { ZoneId zoneId = ZoneId.of("Asia/Seoul"); - ZonedDateTime start = - LocalDate.parse(searchReq.getStrtDttm(), DateTimeFormatter.BASIC_ISO_DATE) - .atStartOfDay(zoneId); + ZonedDateTime start = searchReq.getStrtDttm().atStartOfDay(zoneId); - ZonedDateTime end = - LocalDate.parse(searchReq.getEndDttm(), DateTimeFormatter.BASIC_ISO_DATE) - .plusDays(1) - .atStartOfDay(zoneId); + ZonedDateTime end = searchReq.getEndDttm().plusDays(1).atStartOfDay(zoneId); whereSubBuilder.and( mapSheetAnalDataInferenceGeomEntity @@ -402,12 +394,7 @@ public class LabelWorkRepositoryImpl extends QuerydslRepositorySupport } public NumberExpression caseSumExpression(BooleanExpression condition) { - NumberExpression sumExp = - new CaseBuilder() - .when(condition) - .then(1L) - .otherwise(0L) - .sum(); + NumberExpression sumExp = new CaseBuilder().when(condition).then(1L).otherwise(0L).sum(); return sumExp; } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/log/ErrorLogRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/log/ErrorLogRepositoryImpl.java index de42f7c9..03cc0869 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/log/ErrorLogRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/log/ErrorLogRepositoryImpl.java @@ -15,7 +15,7 @@ import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.time.LocalDate; -import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; import java.util.Objects; @@ -98,12 +98,14 @@ public class ErrorLogRepositoryImpl extends QuerydslRepositorySupport if (Objects.isNull(startDate) || Objects.isNull(endDate)) { return null; } - LocalDateTime startDateTime = startDate.atStartOfDay(); - LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay(); + + ZoneId zoneId = ZoneId.of("Asia/Seoul"); + ZonedDateTime startDateTime = startDate.atStartOfDay(zoneId); + ZonedDateTime endDateTime = endDate.plusDays(1).atStartOfDay(zoneId); return auditLogEntity .createdDate - .goe(ZonedDateTime.from(startDateTime)) - .and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime))); + .goe(startDateTime) + .and(auditLogEntity.createdDate.lt(endDateTime)); } private BooleanExpression eventStatusEqFailed() {