라벨 자동할당 update 로직 -> 추후 라벨링 할당 테이블로 변경할 예정
This commit is contained in:
@@ -2,11 +2,9 @@ package com.kamco.cd.kamcoback.label;
|
|||||||
|
|
||||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.Sheet;
|
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.TargetUser;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.TargetUser;
|
||||||
import com.kamco.cd.kamcoback.label.service.LabelAllocateService;
|
import com.kamco.cd.kamcoback.label.service.LabelAllocateService;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -17,50 +15,46 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Tag(name = "라벨링 작업 관리", description = "라벨링 작업 관리")
|
@Tag(name = "라벨링 작업 관리", description = "라벨링 작업 관리")
|
||||||
@RequestMapping({"/api/label/mng"})
|
@RequestMapping({"/api/label"})
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
public class LabelAllocateApiController {
|
public class LabelAllocateApiController {
|
||||||
|
|
||||||
|
private final LabelAllocateService labelAllocateService;
|
||||||
|
|
||||||
// 라벨링 수량 할당하는 로직 테스트
|
// 라벨링 수량 할당하는 로직 테스트
|
||||||
@PostMapping("/allocate")
|
@PostMapping("/allocate")
|
||||||
public ApiResponseDto<Void> labelAllocate(@RequestBody LabelAllocateDto dto) {
|
public ApiResponseDto<Void> labelAllocate(@RequestBody LabelAllocateDto dto) {
|
||||||
|
|
||||||
// 도엽별 카운트 쿼리
|
// 도엽별 카운트 쿼리
|
||||||
List<Sheet> sheets =
|
// List<Sheet> sheets =
|
||||||
List.of(
|
// List.of(
|
||||||
new Sheet("1", 261),
|
// new Sheet("1", 261),
|
||||||
new Sheet("2", 500),
|
// new Sheet("2", 500),
|
||||||
new Sheet("3", 350),
|
// new Sheet("3", 350),
|
||||||
new Sheet("4", 250),
|
// new Sheet("4", 250),
|
||||||
new Sheet("5", 380),
|
// new Sheet("5", 380),
|
||||||
new Sheet("6", 459));
|
// new Sheet("6", 459));
|
||||||
|
|
||||||
// 사용자별 할당 입력한 값
|
// 사용자별 할당 입력한 값
|
||||||
|
// List<TargetUser> targets =
|
||||||
|
// List.of(new TargetUser("A", 1000), new TargetUser("B", 500), new TargetUser("C", 700));
|
||||||
|
// LabelAllocateService.allocateSheetCount(new ArrayList<>(sheets), new
|
||||||
|
// ArrayList<>(targets));
|
||||||
|
|
||||||
|
// targets.forEach(
|
||||||
|
// t -> {
|
||||||
|
// log.info("[" + t.getUserId() + "]");
|
||||||
|
// t.getAssigned()
|
||||||
|
// .forEach(
|
||||||
|
// u -> {
|
||||||
|
// log.info(" - 도엽: " + u.getSheetId() + " (" + u.getCount() + ")");
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
List<TargetUser> targets =
|
List<TargetUser> targets =
|
||||||
List.of(new TargetUser("A", 1000), new TargetUser("B", 500), new TargetUser("C", 700));
|
List.of(new TargetUser("1", 1000), new TargetUser("2", 400), new TargetUser("3", 440));
|
||||||
|
labelAllocateService.allocateAsc(targets);
|
||||||
LabelAllocateService.allocate(new ArrayList<>(sheets), new ArrayList<>(targets));
|
|
||||||
|
|
||||||
targets.forEach(
|
|
||||||
t -> {
|
|
||||||
log.info("[" + t.getUserId() + "]");
|
|
||||||
t.getAssigned()
|
|
||||||
.forEach(
|
|
||||||
u -> {
|
|
||||||
log.info(" - 도엽: " + u.getSheetId() + " (" + u.getCount() + ")");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
/**
|
|
||||||
* [A] 입력한 수 : 1000 - 도엽: 2 (500) - 도엽: 6 (459) - 도엽: 5 (41)
|
|
||||||
*
|
|
||||||
* <p>[B] 입력한 수 : 500 - 도엽: 5 (339) - 도엽: 3 (161)
|
|
||||||
*
|
|
||||||
* <p>[C] 입력한 수 : 700 - 도엽: 3 (189) - 도엽: 1 (261) - 도엽: 4 (250)
|
|
||||||
*/
|
|
||||||
// A 에게 도엽 2 asc 해서 500건 할당 -> 도엽 6 asc 해서 459 할당 -> 도엽 5 asc 해서 41건 할당 -> insert
|
|
||||||
// B 에게 도엽 5 위에 41건 할당한 것 빼고 asc 해서 339건 할당 -> 도엽 3 asc 해서 161건 할당 -> insert
|
|
||||||
// .... for문에서 할당한 것 빼고 asc 해서 건수만큼 할당 insert 하고 다음 으로 넘어가기
|
|
||||||
|
|
||||||
return ApiResponseDto.ok(null);
|
return ApiResponseDto.ok(null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.kamco.cd.kamcoback.label.service;
|
|||||||
|
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.Sheet;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.Sheet;
|
||||||
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.TargetUser;
|
import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.TargetUser;
|
||||||
|
import com.kamco.cd.kamcoback.postgres.core.LabelAllocateCoreService;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -12,7 +14,19 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class LabelAllocateService {
|
public class LabelAllocateService {
|
||||||
|
|
||||||
public static void allocate(List<Sheet> sheets, List<TargetUser> targetUsers) {
|
private final LabelAllocateCoreService labelAllocateCoreService;
|
||||||
|
|
||||||
|
public LabelAllocateService(LabelAllocateCoreService labelAllocateCoreService) {
|
||||||
|
this.labelAllocateCoreService = labelAllocateCoreService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 도엽 count 수와 할당된 count 수를 비교해서 많은 수부터 먼저 배정하고 나머지를 분배 배정하는 로직
|
||||||
|
*
|
||||||
|
* @param sheets
|
||||||
|
* @param targetUsers
|
||||||
|
*/
|
||||||
|
public static void allocateSheetCount(List<Sheet> sheets, List<TargetUser> targetUsers) {
|
||||||
|
|
||||||
// 1️⃣ 실제 도엽 기준 할당
|
// 1️⃣ 실제 도엽 기준 할당
|
||||||
allocateSheets(sheets, targetUsers);
|
allocateSheets(sheets, targetUsers);
|
||||||
@@ -75,4 +89,34 @@ public class LabelAllocateService {
|
|||||||
t.setShortage(share);
|
t.setShortage(share);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 도엽 기준 asc sorting 해서 할당 수만큼 배정하는 로직
|
||||||
|
*
|
||||||
|
* @param targetUsers
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public void allocateAsc(List<TargetUser> targetUsers) {
|
||||||
|
Long lastId = null;
|
||||||
|
|
||||||
|
for (TargetUser target : targetUsers) {
|
||||||
|
int remaining = target.getDemand();
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
|
||||||
|
int batchSize = Math.min(remaining, 500);
|
||||||
|
List<Long> ids = labelAllocateCoreService.fetchNextIds(lastId, batchSize);
|
||||||
|
|
||||||
|
if (ids.isEmpty()) {
|
||||||
|
return; // 더이상 할당할 데이터가 없으면 return
|
||||||
|
}
|
||||||
|
|
||||||
|
labelAllocateCoreService.assignOwner(
|
||||||
|
ids, Long.valueOf(target.getUserId())); // TODO : userId를 숫자값을 가져올지 사번을 가져올지 고민
|
||||||
|
|
||||||
|
remaining -= ids.size();
|
||||||
|
lastId = ids.get(ids.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.kamco.cd.kamcoback.postgres.core;
|
||||||
|
|
||||||
|
import com.kamco.cd.kamcoback.postgres.repository.label.LabelAllocateRepository;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class LabelAllocateCoreService {
|
||||||
|
|
||||||
|
private final LabelAllocateRepository labelAllocateRepository;
|
||||||
|
|
||||||
|
public List<Long> fetchNextIds(Long lastId, int batchSize) {
|
||||||
|
return labelAllocateRepository.fetchNextIds(lastId, batchSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long assignOwner(List<Long> ids, Long userId) {
|
||||||
|
return labelAllocateRepository.assignOwner(ids, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.kamco.cd.kamcoback.postgres.repository.label;
|
||||||
|
|
||||||
|
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface LabelAllocateRepository
|
||||||
|
extends JpaRepository<MapSheetAnalDataInferenceGeomEntity, Long>,
|
||||||
|
LabelAllocateRepositoryCustom {}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.kamco.cd.kamcoback.postgres.repository.label;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface LabelAllocateRepositoryCustom {
|
||||||
|
|
||||||
|
List<Long> fetchNextIds(Long lastId, int batchSize);
|
||||||
|
|
||||||
|
Long assignOwner(List<Long> ids, Long userId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.kamco.cd.kamcoback.postgres.repository.label;
|
||||||
|
|
||||||
|
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity.mapSheetAnalDataInferenceGeomEntity;
|
||||||
|
|
||||||
|
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity;
|
||||||
|
import com.querydsl.core.types.dsl.Expressions;
|
||||||
|
import com.querydsl.core.types.dsl.StringExpression;
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Repository
|
||||||
|
public class LabelAllocateRepositoryImpl extends QuerydslRepositorySupport
|
||||||
|
implements LabelAllocateRepositoryCustom {
|
||||||
|
|
||||||
|
private final JPAQueryFactory queryFactory;
|
||||||
|
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
|
||||||
|
|
||||||
|
public LabelAllocateRepositoryImpl(JPAQueryFactory queryFactory) {
|
||||||
|
super(MapSheetAnalDataGeomEntity.class);
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> fetchNextIds(Long lastId, int batchSize) {
|
||||||
|
return queryFactory
|
||||||
|
.select(mapSheetAnalDataInferenceGeomEntity.geoUid)
|
||||||
|
.from(mapSheetAnalDataInferenceGeomEntity)
|
||||||
|
.where(
|
||||||
|
// mapSheetAnalDataGeomEntity.pnu.isNotNull(), //TODO: Mockup 진행 이후 확인하기
|
||||||
|
lastId == null ? null : mapSheetAnalDataInferenceGeomEntity.geoUid.gt(lastId),
|
||||||
|
mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq(2022),
|
||||||
|
mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq(2024),
|
||||||
|
mapSheetAnalDataInferenceGeomEntity.labelerUid.isNull())
|
||||||
|
.orderBy(mapSheetAnalDataInferenceGeomEntity.geoUid.asc())
|
||||||
|
.limit(batchSize)
|
||||||
|
.fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long assignOwner(List<Long> ids, Long userId) {
|
||||||
|
return queryFactory
|
||||||
|
.update(mapSheetAnalDataInferenceGeomEntity)
|
||||||
|
.set(mapSheetAnalDataInferenceGeomEntity.labelerUid, userId)
|
||||||
|
.where(mapSheetAnalDataInferenceGeomEntity.geoUid.in(ids))
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user