From 0f7dda261b82f483b808504e84a97f31fd0f07ab Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Wed, 31 Dec 2025 09:10:11 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EB=9D=BC=EB=B2=A8=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=ED=95=A0=EB=8B=B9=20=EB=A1=9C=EC=A7=81=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../label/LabelAllocateApiController.java | 76 ++++++++++++++++ .../kamcoback/label/dto/LabelAllocateDto.java | 48 ++++++++++ .../label/service/LabelAllocateService.java | 90 +++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java diff --git a/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java new file mode 100644 index 00000000..29e5ab8f --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java @@ -0,0 +1,76 @@ +package com.kamco.cd.kamcoback.label; + +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +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.service.LabelAllocateService; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@Tag(name = "라벨링 작업 관리", description = "라벨링 작업 관리") +@RequestMapping({"/api/label/mng"}) +@RequiredArgsConstructor +@RestController +public class LabelAllocateApiController { + + // 라벨링 수량 할당하는 로직 테스트 + @PostMapping("/allocate") + public ApiResponseDto labelAllocate(@RequestBody LabelAllocateDto dto) { + + //도엽별 카운트 쿼리 + List sheets = List.of( + new Sheet("1", 261), + new Sheet("2", 500), + new Sheet("3", 350), + new Sheet("4", 250), + new Sheet("5", 380), + new Sheet("6", 459) + ); + + //사용자별 할당 입력한 값 + List targets = List.of( + new TargetUser("A", 1000), + new TargetUser("B", 500), + new TargetUser("C", 700) + ); + + 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) + * + * [B] 입력한 수 : 500 + * - 도엽: 5 (339) + * - 도엽: 3 (161) + * + * [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); + } + +} diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java new file mode 100644 index 00000000..612e3592 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java @@ -0,0 +1,48 @@ +package com.kamco.cd.kamcoback.label.dto; + +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +public class LabelAllocateDto { + + @Getter + @AllArgsConstructor + public static class Sheet { + + private final String sheetId; + private int count; + + public void decrease(int amount) { + this.count -= amount; + } + } + + @Getter + public static class TargetUser { + + private final String userId; + private final int demand; + private final List assigned = new ArrayList<>(); + private int allocated = 0; + @Setter + private int shortage = 0; + + public TargetUser(String userId, int demand) { + this.userId = userId; + this.demand = demand; + } + + public int getRemainDemand() { + return demand - allocated; + } + + public void assign(String sheetId, int count) { + assigned.add(new Sheet(sheetId, count)); + allocated += count; + } + + } +} 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 new file mode 100644 index 00000000..9336893c --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java @@ -0,0 +1,90 @@ +package com.kamco.cd.kamcoback.label.service; + +import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.Sheet; +import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.TargetUser; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class LabelAllocateService { + + public static void allocate(List sheets, List targetUsers) { + + // 1️⃣ 실제 도엽 기준 할당 + allocateSheets(sheets, targetUsers); + + // 2️⃣ 전체 부족분 비율 계산 + distributeShortage(targetUsers); //항상 마지막에 한 번만 호출해야함 + + } + + public static void allocateSheets( + List sheets, + List targets + ) { + // 도엽 큰 것부터 (선택 사항) + sheets.sort(Comparator.comparingInt(Sheet::getCount).reversed()); + + for (TargetUser target : targets) { + Iterator it = sheets.iterator(); + + while (it.hasNext() && target.getRemainDemand() > 0) { + Sheet sheet = it.next(); + + int assignable = Math.min( + sheet.getCount(), + target.getRemainDemand() + ); + + if (assignable > 0) { + target.assign(sheet.getSheetId(), assignable); + sheet.decrease(assignable); + } + + if (sheet.getCount() == 0) { + it.remove(); + } + } + } + } + + public static void distributeShortage(List targets) { + + int totalDemand = targets.stream() + .mapToInt(TargetUser::getDemand) + .sum(); + + int totalAllocated = targets.stream() + .mapToInt(t -> t.getAllocated()) + .sum(); + + int shortage = totalDemand - totalAllocated; + + if (shortage <= 0) { + return; + } + + int distributed = 0; + + for (int i = 0; i < targets.size(); i++) { + TargetUser t = targets.get(i); + + // 마지막 타겟이 나머지 가져가게 (반올림 오차 방지) + int share; + if (i == targets.size() - 1) { + share = shortage - distributed; + } else { + double ratio = (double) t.getDemand() / totalDemand; + share = (int) Math.round(shortage * ratio); + distributed += share; + } + + t.setShortage(share); + } + } + +} From e7df2e7d86581d7dee220fb22a8ec55dcc979ffa Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 31 Dec 2025 09:25:02 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EA=B0=9C=EB=B0=9C=EC=84=9C=EB=B2=84=20shp?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 4a00ed71..579b7a42 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -74,5 +74,5 @@ mapsheet: upload: skipGdalValidation: true shp: - baseurl: /app/detect/result + baseurl: /app/tmp/detect/result From 0df6151777a0c1c2c3c6149a8a1666e5be53ca28 Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 31 Dec 2025 09:25:30 +0900 Subject: [PATCH 3/3] =?UTF-8?q?spotless=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../label/LabelAllocateApiController.java | 63 ++++++++----------- .../kamcoback/label/dto/LabelAllocateDto.java | 6 +- .../label/service/LabelAllocateService.java | 22 ++----- 3 files changed, 34 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java index 29e5ab8f..5a739715 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java @@ -26,51 +26,42 @@ public class LabelAllocateApiController { @PostMapping("/allocate") public ApiResponseDto labelAllocate(@RequestBody LabelAllocateDto dto) { - //도엽별 카운트 쿼리 - List sheets = List.of( - new Sheet("1", 261), - new Sheet("2", 500), - new Sheet("3", 350), - new Sheet("4", 250), - new Sheet("5", 380), - new Sheet("6", 459) - ); + // 도엽별 카운트 쿼리 + List sheets = + List.of( + new Sheet("1", 261), + new Sheet("2", 500), + new Sheet("3", 350), + new Sheet("4", 250), + new Sheet("5", 380), + new Sheet("6", 459)); - //사용자별 할당 입력한 값 - List targets = List.of( - new TargetUser("A", 1000), - new TargetUser("B", 500), - new TargetUser("C", 700) - ); + // 사용자별 할당 입력한 값 + List targets = + List.of(new TargetUser("A", 1000), new TargetUser("B", 500), new TargetUser("C", 700)); 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() + ")"); - }); - }); + 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) + * [A] 입력한 수 : 1000 - 도엽: 2 (500) - 도엽: 6 (459) - 도엽: 5 (41) * - * [B] 입력한 수 : 500 - * - 도엽: 5 (339) - * - 도엽: 3 (161) + *

[B] 입력한 수 : 500 - 도엽: 5 (339) - 도엽: 3 (161) * - * [C] 입력한 수 : 700 - * - 도엽: 3 (189) - * - 도엽: 1 (261) - * - 도엽: 4 (250) + *

[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 하고 다음 으로 넘어가기 + // 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); } - } diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java index 612e3592..a6802547 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java @@ -27,8 +27,7 @@ public class LabelAllocateDto { private final int demand; private final List assigned = new ArrayList<>(); private int allocated = 0; - @Setter - private int shortage = 0; + @Setter private int shortage = 0; public TargetUser(String userId, int demand) { this.userId = userId; @@ -38,11 +37,10 @@ public class LabelAllocateDto { public int getRemainDemand() { return demand - allocated; } - + public void assign(String sheetId, int count) { assigned.add(new Sheet(sheetId, count)); allocated += count; } - } } 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 9336893c..547284b6 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 @@ -18,14 +18,10 @@ public class LabelAllocateService { allocateSheets(sheets, targetUsers); // 2️⃣ 전체 부족분 비율 계산 - distributeShortage(targetUsers); //항상 마지막에 한 번만 호출해야함 - + distributeShortage(targetUsers); // 항상 마지막에 한 번만 호출해야함 } - public static void allocateSheets( - List sheets, - List targets - ) { + public static void allocateSheets(List sheets, List targets) { // 도엽 큰 것부터 (선택 사항) sheets.sort(Comparator.comparingInt(Sheet::getCount).reversed()); @@ -35,10 +31,7 @@ public class LabelAllocateService { while (it.hasNext() && target.getRemainDemand() > 0) { Sheet sheet = it.next(); - int assignable = Math.min( - sheet.getCount(), - target.getRemainDemand() - ); + int assignable = Math.min(sheet.getCount(), target.getRemainDemand()); if (assignable > 0) { target.assign(sheet.getSheetId(), assignable); @@ -54,13 +47,9 @@ public class LabelAllocateService { public static void distributeShortage(List targets) { - int totalDemand = targets.stream() - .mapToInt(TargetUser::getDemand) - .sum(); + int totalDemand = targets.stream().mapToInt(TargetUser::getDemand).sum(); - int totalAllocated = targets.stream() - .mapToInt(t -> t.getAllocated()) - .sum(); + int totalAllocated = targets.stream().mapToInt(t -> t.getAllocated()).sum(); int shortage = totalDemand - totalAllocated; @@ -86,5 +75,4 @@ public class LabelAllocateService { t.setShortage(share); } } - }