From d54fbc9d4f8981fa0f7f613b33a28a8cd4f764ea Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期日, 25 十月 2026 16:29:53 +0800
Subject: [PATCH] feat(system): 优化用户搜索功能并完善ERP和MES模块验证逻辑

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java |   75 +++++++++++++++++++++++++++++++++++++
 1 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java
index 72698b7..e30fe31 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java
@@ -16,8 +16,11 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.pro.route.MesProRouteMapper;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService;
+import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -29,6 +32,10 @@
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Set;
+import java.util.Comparator;
+import java.util.Arrays;
+import java.util.stream.Collectors;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -58,6 +65,10 @@
     @Resource
     @Lazy
     private MesMdItemService itemService;
+    @Resource
+    private MesMdItemTypeService itemTypeService;
+    @Resource
+    private MesWmWarehouseAreaService warehouseAreaService;
 
     @Override
     public Long createRoute(MesProRouteSaveReqVO createReqVO) {
@@ -147,13 +158,75 @@
         // 3. 鎵�鏈変骇鍝佸繀椤婚厤缃簡 BOM 娑堣��
         List<MesProRouteProductDO> productList = routeProductService.getRouteProductListByRouteId(routeId);
         for (MesProRouteProductDO product : productList) {
+            MesMdItemDO item = itemService.validateItemExists(product.getItemId());
+            if (product.getWarehouseId() == null || product.getLocationId() == null || product.getAreaId() == null) {
+                throw exception(PRO_ROUTE_PRODUCT_WAREHOUSE_REQUIRED, item.getName());
+            }
+            warehouseAreaService.validateWarehouseAreaExists(product.getWarehouseId(),
+                    product.getLocationId(), product.getAreaId());
             List<MesProRouteProductBomDO> bomList = routeProductBomService
                     .getRouteProductBomList(routeId, null, product.getItemId());
             if (CollUtil.isEmpty(bomList)) {
-                MesMdItemDO item = itemService.validateItemExists(product.getItemId());
                 throw exception(PRO_ROUTE_ENABLE_PRODUCT_NO_BOM, item.getName());
             }
         }
+        validateProcessOutputs(processList, productList);
+    }
+
+    private void validateProcessOutputs(List<MesProRouteProcessDO> processList,
+                                        List<MesProRouteProductDO> productList) {
+        if (CollUtil.isEmpty(productList)) {
+            throw exception(PRO_ROUTE_LAST_OUTPUT_INVALID, processList.get(processList.size() - 1).getProcessId());
+        }
+        Set<Long> boundItemIds = productList.stream().map(MesProRouteProductDO::getItemId).collect(Collectors.toSet());
+        Set<Long> finishedItemIds = productList.stream()
+                .map(MesProRouteProductDO::getItemId)
+                .filter(itemId -> isItemUnderCategory(itemId, "FG"))
+                .collect(Collectors.toSet());
+        MesProRouteProcessDO lastProcess = processList.stream()
+                .max(Comparator.comparing(MesProRouteProcessDO::getSort)).orElseThrow();
+        for (MesProRouteProcessDO process : processList) {
+            Set<Long> outputIds = parseOutputItemIds(process.getOutputItemId());
+            if (CollUtil.isEmpty(outputIds)) {
+                throw exception(PRO_ROUTE_PROCESS_OUTPUT_REQUIRED, process.getProcessId());
+            }
+            for (Long outputId : outputIds) {
+                if (!boundItemIds.contains(outputId)) {
+                    MesMdItemDO item = itemService.validateItemExists(outputId);
+                    throw exception(PRO_ROUTE_PROCESS_OUTPUT_NOT_BOUND, item.getName());
+                }
+            }
+            if (process.getId().equals(lastProcess.getId())) {
+                if (finishedItemIds.isEmpty() || !outputIds.equals(finishedItemIds)) {
+                    throw exception(PRO_ROUTE_LAST_OUTPUT_INVALID, process.getProcessId());
+                }
+            } else if (outputIds.stream().anyMatch(itemId -> !isItemUnderCategory(itemId, "SF"))) {
+                throw exception(PRO_ROUTE_MIDDLE_OUTPUT_INVALID, process.getProcessId());
+            }
+        }
+    }
+
+    private Set<Long> parseOutputItemIds(String value) {
+        if (StrUtil.isBlank(value)) {
+            return Collections.emptySet();
+        }
+        return Arrays.stream(value.split(",")).map(String::trim).filter(StrUtil::isNotBlank)
+                .map(Long::valueOf).collect(Collectors.toSet());
+    }
+
+    private boolean isItemUnderCategory(Long itemId, String rootCode) {
+        MesMdItemDO item = itemService.validateItemExists(itemId);
+        MesMdItemTypeDO type = itemTypeService.getItemType(item.getItemTypeId());
+        while (type != null) {
+            if (rootCode.equals(type.getCode())) {
+                return true;
+            }
+            if (type.getParentId() == null || MesMdItemTypeDO.PARENT_ID_ROOT.equals(type.getParentId())) {
+                return false;
+            }
+            type = itemTypeService.getItemType(type.getParentId());
+        }
+        return false;
     }
 
     @Override

--
Gitblit v1.9.3