From ac2e2b5af3726ee64dc37c3ebf26989a0346f22a Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期六, 07 十一月 2026 19:16:05 +0800
Subject: [PATCH] feat(feedback): 优化报工审批流程并增加报工人校验
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java | 102 +++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 91 insertions(+), 11 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java
index 34cb455..d9520f2 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java
@@ -17,12 +17,15 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -40,6 +43,15 @@
@Service
@Validated
public class MesProRouteProcessServiceImpl implements MesProRouteProcessService {
+
+ /**
+ * 浜у嚭鎺掑簭锛氫富浜у嚭浼樺厛锛屽叾娆℃寜 sort锛屾渶鍚庢寜 id
+ */
+ private static final Comparator<MesProRouteProcessOutputDO> OUTPUT_ORDER = Comparator
+ .comparing((MesProRouteProcessOutputDO o) -> Boolean.TRUE.equals(o.getMainFlag()),
+ Comparator.reverseOrder())
+ .thenComparing(MesProRouteProcessOutputDO::getSort, Comparator.nullsLast(Comparator.naturalOrder()))
+ .thenComparing(MesProRouteProcessOutputDO::getId, Comparator.nullsLast(Comparator.naturalOrder()));
@Resource
private MesProRouteProcessMapper routeProcessMapper;
@@ -232,6 +244,7 @@
}
String filtered = outputs.stream()
.filter(output -> output.getProductId() == null || output.getProductId().equals(productId))
+ .sorted(OUTPUT_ORDER)
.map(MesProRouteProcessOutputDO::getItemId)
.filter(Objects::nonNull)
.distinct()
@@ -251,10 +264,30 @@
}
return outputs.stream()
.filter(output -> output.getProductId() == null || output.getProductId().equals(productId))
+ .sorted(OUTPUT_ORDER)
.map(MesProRouteProcessOutputDO::getItemId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
+ }
+
+ @Override
+ public List<MesProRouteProcessOutputDO> getProcessOutputs(Long routeProcessId, Long productId) {
+ if (routeProcessId == null) {
+ return Collections.emptyList();
+ }
+ List<MesProRouteProcessOutputDO> outputs = routeProcessOutputMapper.selectListByRouteProcessId(routeProcessId);
+ if (CollUtil.isEmpty(outputs)) {
+ return Collections.emptyList();
+ }
+ // 涓讳骇鍑轰紭鍏堟帓搴忥紝骞舵寜 itemId 鍘婚噸
+ Map<Long, MesProRouteProcessOutputDO> distinct = new LinkedHashMap<>();
+ outputs.stream()
+ .filter(output -> output.getProductId() == null || output.getProductId().equals(productId))
+ .filter(output -> output.getItemId() != null)
+ .sorted(OUTPUT_ORDER)
+ .forEach(output -> distinct.putIfAbsent(output.getItemId(), output));
+ return new ArrayList<>(distinct.values());
}
@Override
@@ -275,8 +308,13 @@
if (CollUtil.isNotEmpty(reqVO.getOutputs())) {
itemIds = reqVO.getOutputs().stream()
.filter(Objects::nonNull)
- .sorted(Comparator.comparing(MesProRouteProcessSaveReqVO.OutputItem::getSort,
- Comparator.nullsLast(Comparator.naturalOrder())))
+ .sorted(Comparator
+ .comparing((MesProRouteProcessSaveReqVO.OutputItem o) -> Boolean.TRUE.equals(o.getMainFlag()),
+ Comparator.reverseOrder())
+ .thenComparing(MesProRouteProcessSaveReqVO.OutputItem::getSort,
+ Comparator.nullsLast(Comparator.naturalOrder()))
+ .thenComparing(MesProRouteProcessSaveReqVO.OutputItem::getItemId,
+ Comparator.nullsLast(Comparator.naturalOrder())))
.map(MesProRouteProcessSaveReqVO.OutputItem::getItemId)
.filter(Objects::nonNull)
.distinct()
@@ -307,29 +345,37 @@
Set<String> keys = new HashSet<>();
int index = 0;
if (CollUtil.isNotEmpty(reqVO.getOutputs())) {
- for (MesProRouteProcessSaveReqVO.OutputItem output : reqVO.getOutputs()) {
- if (output == null || output.getItemId() == null) {
- continue;
- }
+ List<MesProRouteProcessSaveReqVO.OutputItem> items = reqVO.getOutputs().stream()
+ .filter(Objects::nonNull)
+ .filter(output -> output.getItemId() != null)
+ .collect(Collectors.toList());
+ // 鏍¢獙锛氬悓涓�褰掑睘浜у搧鍒嗙粍鍐呬富浜у嚭鍞竴銆侀厤姣斿悎娉�
+ validateOutputs(items);
+ for (MesProRouteProcessSaveReqVO.OutputItem output : items) {
index++;
if (!keys.add(output.getProductId() + "_" + output.getItemId())) {
continue;
}
+ boolean main = Boolean.TRUE.equals(output.getMainFlag());
+ BigDecimal quantity = main ? BigDecimal.ONE : output.getQuantity();
outputs.add(buildOutput(routeProcess, output.getProductId(), output.getItemId(),
- output.getSort() != null ? output.getSort() : index, output.getRemark()));
+ output.getSort() != null ? output.getSort() : index, quantity, main, output.getRemark()));
}
} else {
- // 鍏煎鍙紶 outputItemIds 鐨勮皟鐢ㄦ柟锛氫骇鍑烘槸璺嚎浜у搧鏃跺綊灞炲埌鑷韩锛屽惁鍒欒涓洪�氱敤
+ // 鍏煎鍙紶 outputItemIds 鐨勮皟鐢ㄦ柟锛氫骇鍑烘槸璺嚎浜у搧鏃跺綊灞炲埌鑷韩锛屽惁鍒欒涓洪�氱敤锛�
+ // 姣忎釜褰掑睘浜у搧鍒嗙粍鐨勭涓�鏉¢粯璁や綔涓轰富浜у嚭
+ Set<Long> mainAssignedProducts = new HashSet<>();
for (Long itemId : reqVO.getOutputItemIds()) {
if (itemId == null) {
continue;
}
- index++;
Long productId = routeProductIds.contains(itemId) ? itemId : null;
if (!keys.add(productId + "_" + itemId)) {
continue;
}
- outputs.add(buildOutput(routeProcess, productId, itemId, index, null));
+ index++;
+ boolean main = mainAssignedProducts.add(productId);
+ outputs.add(buildOutput(routeProcess, productId, itemId, index, BigDecimal.ONE, main, null));
}
}
if (CollUtil.isNotEmpty(outputs)) {
@@ -337,14 +383,48 @@
}
}
+ /**
+ * 鏍¢獙宸ュ簭浜у嚭閰嶇疆锛氬悓涓�褰掑睘浜у搧鍒嗙粍鍐呮渶澶氫竴涓富浜у嚭銆佸涓骇鍑烘椂蹇呴』鎸囧畾涓讳骇鍑猴紝闈炰富浜у嚭閰嶆瘮蹇呴』澶т簬 0
+ */
+ private void validateOutputs(List<MesProRouteProcessSaveReqVO.OutputItem> items) {
+ if (CollUtil.isEmpty(items)) {
+ return;
+ }
+ Map<Long, List<MesProRouteProcessSaveReqVO.OutputItem>> groupByProduct = new HashMap<>();
+ for (MesProRouteProcessSaveReqVO.OutputItem item : items) {
+ groupByProduct.computeIfAbsent(item.getProductId(), key -> new ArrayList<>()).add(item);
+ }
+ for (List<MesProRouteProcessSaveReqVO.OutputItem> group : groupByProduct.values()) {
+ long mainCount = group.stream().filter(item -> Boolean.TRUE.equals(item.getMainFlag())).count();
+ if (mainCount > 1) {
+ throw exception(PRO_ROUTE_PROCESS_OUTPUT_MAIN_DUPLICATE);
+ }
+ if (mainCount == 0 && group.size() > 1) {
+ throw exception(PRO_ROUTE_PROCESS_OUTPUT_MAIN_REQUIRED);
+ }
+ for (MesProRouteProcessSaveReqVO.OutputItem item : group) {
+ if (Boolean.TRUE.equals(item.getMainFlag())) {
+ continue;
+ }
+ // 鏈~閰嶆瘮榛樿鎸� 1 澶勭悊锛屽~浜嗗垯蹇呴』澶т簬 0
+ if (item.getQuantity() != null && item.getQuantity().compareTo(BigDecimal.ZERO) <= 0) {
+ throw exception(PRO_ROUTE_PROCESS_OUTPUT_RATIO_INVALID);
+ }
+ }
+ }
+ }
+
private MesProRouteProcessOutputDO buildOutput(MesProRouteProcessDO routeProcess, Long productId,
- Long itemId, Integer sort, String remark) {
+ Long itemId, Integer sort, BigDecimal quantity,
+ Boolean mainFlag, String remark) {
return MesProRouteProcessOutputDO.builder()
.routeProcessId(routeProcess.getId())
.routeId(routeProcess.getRouteId())
.processId(routeProcess.getProcessId())
.productId(productId)
.itemId(itemId)
+ .quantity(mainFlag != null && mainFlag ? BigDecimal.ONE : quantity)
+ .mainFlag(Boolean.TRUE.equals(mainFlag))
.sort(sort)
.remark(remark)
.build();
--
Gitblit v1.9.3