From 1ca5584d7e3200a9af65a099bd26d3593e2ba702 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期四, 07 五月 2026 14:36:08 +0800
Subject: [PATCH] 迁移pro

---
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java |  743 +++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 517 insertions(+), 226 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
index fa34114..150fc89 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -12,13 +12,14 @@
 import com.ruoyi.basic.pojo.Product;
 import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
-import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.procurementrecord.utils.StockUtils;
-import com.ruoyi.production.dto.ProductStructureDto;
-import com.ruoyi.production.dto.ProductionProductMainDto;
+import com.ruoyi.production.bean.dto.ProductStructureDto;
+import com.ruoyi.production.bean.dto.ProductionProductMainDto;
+import com.ruoyi.production.enums.ProductOrderStatusEnum;
 import com.ruoyi.production.mapper.*;
 import com.ruoyi.production.pojo.*;
 import com.ruoyi.production.service.ProductionProductMainService;
@@ -26,19 +27,29 @@
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.quality.mapper.*;
 import com.ruoyi.quality.pojo.*;
-import com.ruoyi.quality.service.IQualityInspectService;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.service.StockInventoryService;
+import com.ruoyi.technology.mapper.TechnologyOperationMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper;
+import com.ruoyi.technology.pojo.TechnologyOperation;
+import com.ruoyi.technology.pojo.TechnologyRoutingOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import com.ruoyi.production.mapper.ProductionProductMainMapper;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 @Service
@@ -46,140 +57,258 @@
 @Transactional(rollbackFor = Exception.class)
 public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
 
-    private IQualityInspectService qualityInspectService;
-    private ProductionProductMainMapper productionProductMainMapper;
-
-
-    private ProductWorkOrderMapper productWorkOrderMapper;
-
-    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
-    private SysUserMapper userMapper;
-
-    private ProductionProductOutputMapper productionProductOutputMapper;
-
-
-    private ProductModelMapper productModelMapper;
-
-    private QualityInspectMapper qualityInspectMapper;
-    private QualityUnqualifiedMapper qualityUnqualifiedMapper;
-
-    private ProductProcessMapper productProcessMapper;
-    private ProductProcessRouteMapper productProcessRouteMapper;
-
-    private ProductMapper productMapper;
-
-
-    private QualityTestStandardParamMapper qualityTestStandardParamMapper;
-    private QualityTestStandardMapper qualityTestStandardMapper;
-
-    private QualityInspectParamMapper qualityInspectParamMapper;
-
-    private ProductStructureMapper productStructureMapper;
-
-    private ProductionProductInputMapper productionProductInputMapper;
-
-    private ProductOrderMapper productOrderMapper;
-
-    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
-
-    private StockUtils stockUtils;
-
+    private final ProductionProductMainMapper productionProductMainMapper;
+    private final SysUserMapper userMapper;
+    private final ProductionProductOutputMapper productionProductOutputMapper;
+    private final ProductModelMapper productModelMapper;
+    private final QualityInspectMapper qualityInspectMapper;
+    private final QualityUnqualifiedMapper qualityUnqualifiedMapper;
+    private final ProductMapper productMapper;
+    private final QualityTestStandardParamMapper qualityTestStandardParamMapper;
+    private final QualityTestStandardMapper qualityTestStandardMapper;
+    private final QualityInspectParamMapper qualityInspectParamMapper;
+    private final ProductionProductInputMapper productionProductInputMapper;
+    private final ProductionAccountMapper productionAccountMapper;
+    private final ProductionOperationTaskMapper productionOperationTaskMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final ProductionOrderBomMapper productionOrderBomMapper;
+    private final ProductionBomStructureMapper productionBomStructureMapper;
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+    private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper;
+    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
+    private final TechnologyOperationMapper technologyOperationMapper;
+    private final StockUtils stockUtils;
+    private final StockInventoryService stockInventoryService;
 
     @Override
     public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) {
-        return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
+        IPage<ProductionProductMainDto> result = productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
+        fillOperationParamList(result.getRecords());
+        return result;
+    }
+
+    @Override
+    public IPage<ProductionProductMainDto> pageProductionProductMain(Page page, ProductionProductMainDto productionProductMainDto) {
+        return listPageProductionProductMainDto(page, productionProductMainDto);
+    }
+
+    @Override
+    public ProductionProductMainDto getProductionProductMainInfo(Long id) {
+        return listPageProductionProductMainDto(new Page<>(1, 1), new ProductionProductMainDto() {{
+            setId(id);
+        }}).getRecords().stream().findFirst().orElse(null);
+    }
+
+    private void fillOperationParamList(List<ProductionProductMainDto> recordList) {
+        if (recordList == null || recordList.isEmpty()) {
+            return;
+        }
+        Set<Long> mainIdSet = recordList.stream()
+                .map(ProductionProductMainDto::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (mainIdSet.isEmpty()) {
+            recordList.forEach(item -> item.setProductionOperationParamList(Collections.emptyList()));
+            return;
+        }
+
+        List<ProductionOrderRoutingOperationParam> paramList = productionOrderRoutingOperationParamMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                        .in(ProductionOrderRoutingOperationParam::getProductionProductMainId, mainIdSet)
+                        .orderByAsc(ProductionOrderRoutingOperationParam::getId));
+        Map<Long, List<ProductionOrderRoutingOperationParam>> paramGroupMap = new HashMap<>();
+        for (ProductionOrderRoutingOperationParam param : paramList) {
+            if (param == null || param.getProductionProductMainId() == null) {
+                continue;
+            }
+            paramGroupMap.computeIfAbsent(param.getProductionProductMainId(), key -> new ArrayList<>()).add(param);
+        }
+
+        Set<Long> missingMainIdSet = new LinkedHashSet<>();
+        for (ProductionProductMainDto item : recordList) {
+            Long mainId = item.getId();
+            if (mainId == null) {
+                item.setProductionOperationParamList(Collections.emptyList());
+                continue;
+            }
+            List<ProductionOrderRoutingOperationParam> params = paramGroupMap.get(mainId);
+            if (params != null && !params.isEmpty()) {
+                item.setProductionOperationParamList(params);
+                continue;
+            }
+            missingMainIdSet.add(mainId);
+        }
+        if (missingMainIdSet.isEmpty()) {
+            return;
+        }
+
+        // 鍏煎鍘嗗彶鏁版嵁锛氭棫鎶ュ伐璁板綍娌℃湁鎸夋姤宸D钀藉弬鏁板揩鐓ф椂锛屽洖閫�灞曠ず宸ュ簭妯℃澘鍙傛暟銆�
+        List<ProductionProductMain> mainList = productionProductMainMapper.selectBatchIds(missingMainIdSet);
+        Map<Long, Long> mainIdToTaskIdMap = mainList.stream()
+                .filter(Objects::nonNull)
+                .filter(item -> item.getId() != null)
+                .collect(Collectors.toMap(ProductionProductMain::getId,
+                        ProductionProductMain::getProductionOperationTaskId, (left, right) -> left));
+        Set<Long> taskIdSet = mainIdToTaskIdMap.values().stream()
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (taskIdSet.isEmpty()) {
+            for (ProductionProductMainDto item : recordList) {
+                if (item.getId() != null && missingMainIdSet.contains(item.getId())) {
+                    item.setProductionOperationParamList(Collections.emptyList());
+                }
+            }
+            return;
+        }
+
+        List<ProductionOperationTask> taskList = productionOperationTaskMapper.selectList(
+                Wrappers.<ProductionOperationTask>lambdaQuery()
+                        .in(ProductionOperationTask::getId, taskIdSet));
+        Map<Long, Long> taskIdToRoutingOperationIdMap = taskList.stream()
+                .filter(Objects::nonNull)
+                .filter(item -> item.getId() != null)
+                .collect(Collectors.toMap(ProductionOperationTask::getId,
+                        ProductionOperationTask::getProductionOrderRoutingOperationId, (left, right) -> left));
+        Set<Long> routingOperationIdSet = taskIdToRoutingOperationIdMap.values().stream()
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (routingOperationIdSet.isEmpty()) {
+            for (ProductionProductMainDto item : recordList) {
+                if (item.getId() != null && missingMainIdSet.contains(item.getId())) {
+                    item.setProductionOperationParamList(Collections.emptyList());
+                }
+            }
+            return;
+        }
+
+        List<ProductionOrderRoutingOperationParam> fallbackParamList = productionOrderRoutingOperationParamMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                        .in(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, routingOperationIdSet)
+                        .isNull(ProductionOrderRoutingOperationParam::getProductionProductMainId)
+                        .orderByAsc(ProductionOrderRoutingOperationParam::getId));
+        Map<Long, List<ProductionOrderRoutingOperationParam>> fallbackGroupMap = new HashMap<>();
+        for (ProductionOrderRoutingOperationParam param : fallbackParamList) {
+            if (param == null || param.getProductionOrderRoutingOperationId() == null) {
+                continue;
+            }
+            fallbackGroupMap.computeIfAbsent(param.getProductionOrderRoutingOperationId(), key -> new ArrayList<>()).add(param);
+        }
+
+        for (ProductionProductMainDto item : recordList) {
+            Long mainId = item.getId();
+            if (mainId == null || !missingMainIdSet.contains(mainId)) {
+                continue;
+            }
+            Long taskId = mainIdToTaskIdMap.get(mainId);
+            Long routingOperationId = taskId == null ? null : taskIdToRoutingOperationIdMap.get(taskId);
+            if (routingOperationId == null) {
+                item.setProductionOperationParamList(Collections.emptyList());
+                continue;
+            }
+            item.setProductionOperationParamList(fallbackGroupMap.getOrDefault(routingOperationId, Collections.emptyList()));
+        }
     }
 
     @Override
     public Boolean addProductMain(ProductionProductMainDto dto) {
+        Long taskId = resolveTaskId(dto);
+        if (taskId == null) {
+            throw new ServiceException("璇蜂紶鍏ョ敓浜у伐鍗旾D");
+        }
+        return addProductMainByProductionTask(dto);
+    }
+
+    @Override
+    public Boolean saveProductionProductMain(ProductionProductMainDto productionProductMainDto) {
+        return addProductMain(productionProductMainDto);
+    }
+
+    @Override
+    public Boolean removeProductMain(Long id) {
+        ProductionProductMain currentMain = productionProductMainMapper.selectById(id);
+        if (currentMain == null) {
+            return true;
+        }
+        return removeProductMainByProductionTask(currentMain);
+    }
+
+    private Boolean addProductMainByProductionTask(ProductionProductMainDto dto) {
+        // 鎶ュ伐浠ヨ鍗曞伐搴忓揩鐓т负鍑嗭紝閬垮厤宸ヨ壓涓绘暟鎹彉鏇村悗褰卞搷鍘嗗彶宸ュ崟鎵ц銆�
+        Long taskId = resolveTaskId(dto);
+        if (taskId == null) {
+            throw new ServiceException("productionOperationTaskId can not be null");
+        }
         SysUser user = userMapper.selectUserById(dto.getUserId());
+        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(taskId);
+        if (productionOperationTask == null) {
+            throw new ServiceException("鐢熶骇宸ュ崟涓嶅瓨鍦�");
+        }
+        ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getProductionOrderRoutingOperationId());
+        if (routingOperation == null) {
+            throw new ServiceException("璁㈠崟宸ヨ壓璺嚎宸ュ簭涓嶅瓨鍦�");
+        }
+        ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId());
+        if (productionOrder == null) {
+            throw new ServiceException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+        }
+        TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId());
+        TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null
+                : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId());
+        ProductModel productModel = productModelMapper.selectById(
+                routingOperation.getProductModelId() != null ? routingOperation.getProductModelId() : productionOrder.getProductModelId());
+        if (productModel == null) {
+            throw new ServiceException("浜у搧瑙勬牸涓嶅瓨鍦�");
+        }
+
         ProductionProductMain productionProductMain = new ProductionProductMain();
-        //褰撳墠宸ヨ壓璺嚎瀵瑰簲鐨勫伐搴忚鎯�
-        ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId());
-        if (productProcessRouteItem == null) {
-            throw new RuntimeException("宸ヨ壓璺嚎椤逛笉瀛樺湪");
-        }
-        //褰撳墠鍏蜂綋宸ュ簭
-        ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId());
-        //宸ヨ壓璺嚎涓綋鍓嶅伐搴忓搴旂殑浜у嚭瑙勬牸鍨嬪彿
-        ProductModel productModel = productModelMapper.selectById(productProcessRouteItem.getProductModelId());
-        //鏌ヨ璇ョ敓浜ц鍗曞搴旂殑bom
-        ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectById(productProcessRouteItem.getProductRouteId());
-        /*鏂板鎶ュ伐涓昏〃*/
-        //鏌ヨ鏈�澶ф姤宸ョ紪鍙�
-        String datePrefix = "BG" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
-        QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>();
-        queryWrapper.select("MAX(product_no) as maxNo")
-                .likeRight("product_no", datePrefix);
-        List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper);
-        int sequenceNumber = 1;
-        if (resultList != null && !resultList.isEmpty()) {
-            Map<String, Object> result = resultList.get(0);
-            if (result != null) {
-                Object maxNoObj = result.get("maxNo");
-                if (maxNoObj != null) {
-                    String lastNo = maxNoObj.toString();
-                    System.out.println("lastNo: " + lastNo);
-                    if (lastNo.startsWith(datePrefix)) {
-                        try {
-                            String seqStr = lastNo.substring(datePrefix.length());
-                            sequenceNumber = Integer.parseInt(seqStr) + 1;
-                        } catch (NumberFormatException e) {
-                            sequenceNumber = 1;
-                        }
-                    }
-                }
-            }
-        }
-        String productNo = String.format("%s%03d", datePrefix, sequenceNumber);
-        productionProductMain.setProductNo(productNo);
-        productionProductMain.setUserId(dto.getUserId());
-        productionProductMain.setUserName(dto.getUserName());
-        productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId());
-        productionProductMain.setWorkOrderId(dto.getWorkOrderId());
+        productionProductMain.setProductNo(generateProductNo());
+        productionProductMain.setUserId(user == null ? dto.getUserId() : user.getUserId());
+        productionProductMain.setUserName(user == null ? dto.getUserName() : user.getNickName());
+        productionProductMain.setProductionOperationTaskId(taskId);
         productionProductMain.setStatus(0);
         productionProductMainMapper.insert(productionProductMain);
-        /*鏂板鎶ュ伐鎶曞叆琛�*/
-        List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId());
-        if (productStructureDtos.size() == 0) {
-            //濡傛灉璇ュ伐搴忔病鏈変骇鍝佺粨鏋勭殑鎶曞叆鍝�,閭h繖涓姇鍏ュ搧鍜屼骇鍑哄搧鏄悓涓�涓�
-            ProductStructureDto productStructureDto = new ProductStructureDto();
-            productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId());
-            productStructureDto.setUnitQuantity(BigDecimal.ONE);
-            productStructureDtos.add(productStructureDto);
-        }
-        for (ProductStructureDto productStructureDto : productStructureDtos) {
+        syncOperationParamInputValue(dto, routingOperation.getId(), productionProductMain.getId());
 
+        List<ProductStructureDto> productStructureDtos = resolveInputStructures(
+                productionOrder.getId(), routingOperation, productModel.getId());
+       // 濡傛灉娌℃湁bom瀛愯妭鐐逛簡锛岄偅涔堟姇鍏ュ氨鏄粬鏈韩
+        if (productStructureDtos.isEmpty()) {
+            ProductStructureDto fallbackInput = new ProductStructureDto();
+            fallbackInput.setProductModelId(productModel.getId());
+            fallbackInput.setUnitQuantity(BigDecimal.ONE);
+            productStructureDtos.add(fallbackInput);
+        }
+        for (ProductStructureDto item : productStructureDtos) {
+            // 褰撳墠瀹炵幇鎸夊伐搴忔垚鍝佺洿鎺ヤ綔涓烘姇鍏ワ紝鍚庣画鑻ユ帴鍏ラ鏂欒褰曞彲鍦ㄨ繖閲屾浛鎹㈡潵婧愩��
             ProductionProductInput productionProductInput = new ProductionProductInput();
-            productionProductInput.setProductModelId(productStructureDto.getProductModelId());
-            productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
+            productionProductInput.setProductionProductMainId(productionProductMain.getId());
             productionProductInput.setProductMainId(productionProductMain.getId());
+            productionProductInput.setProductModelId(item.getProductModelId());
+            productionProductInput.setInputQuantity(item.getUnitQuantity().multiply(defaultDecimal(dto.getQuantity())));
+            productionProductInput.setQuantity(productionProductInput.getInputQuantity());
             productionProductInputMapper.insert(productionProductInput);
-            stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId());
-
         }
-        /*鏂板鎶ュ伐浜у嚭琛�*/
+
         ProductionProductOutput productionProductOutput = new ProductionProductOutput();
+        productionProductOutput.setProductionProductMainId(productionProductMain.getId());
         productionProductOutput.setProductMainId(productionProductMain.getId());
-        productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId());
-        productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
-        productionProductOutput.setScrapQty(dto.getScrapQty() != null ? dto.getScrapQty() : BigDecimal.ZERO);
+        productionProductOutput.setProductModelId(productModel.getId());
+        productionProductOutput.setQuantity(defaultDecimal(dto.getQuantity()));
+        productionProductOutput.setScrapQty(defaultDecimal(dto.getScrapQty()));
         productionProductOutputMapper.insert(productionProductOutput);
-        //鍚堟牸鏁伴噺=鎶ュ伐鏁伴噺-鎶ュ簾鏁伴噺
-        BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty());
-        //鍙湁鍚堟牸鏁伴噺>0鎵嶈兘澧炲姞鐩稿簲鏁版嵁
+        BigDecimal reportQty = defaultDecimal(productionProductOutput.getQuantity());
+        BigDecimal productQty = reportQty;
+
+        List<ProductionOrderRoutingOperation> routingOperationList = productionOrderRoutingOperationMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperation::getOrderRoutingId, routingOperation.getOrderRoutingId())
+                        .eq(ProductionOrderRoutingOperation::getProductionOrderId, routingOperation.getProductionOrderId()));
+        boolean isLastOperation = routingOperation.getDragSort() != null && routingOperation.getDragSort().equals(routingOperationList.size());
         if (productQty.compareTo(BigDecimal.ZERO) > 0) {
-            /*鏂板璐ㄦ*/
-            List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
-            if (productProcessRouteItem.getIsQuality()) {
-                //瀵瑰簲鐨勮繃绋嬫鎴栬�呭嚭鍘傛
-                int inspectType = 1;
-                String process = productProcess.getName();//宸ュ簭
-                if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
-                    //鏈�鍚庝竴閬撳伐搴忕敓鎴愬嚭鍘傛
-                    inspectType = 2;
-                    process = null;
-                }
+            if (Boolean.TRUE.equals(routingOperation.getIsQuality())) {
+                // 璐ㄦ宸ュ簭鍏堢敓鎴愭楠屽崟锛岄潪璐ㄦ宸ュ簭鐩存帴鍏ュ悎鏍煎搧搴撳瓨銆�
+                int inspectType = isLastOperation ? 2 : 1;
+                String process = isLastOperation ? null : technologyOperation == null ? null : technologyOperation.getName();
                 Product product = productMapper.selectById(productModel.getProductId());
                 QualityInspect qualityInspect = new QualityInspect();
                 qualityInspect.setProductId(product.getId());
@@ -194,11 +323,11 @@
                 qualityInspect.setProductModelId(productModel.getId());
                 qualityInspectMapper.insert(qualityInspect);
                 List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process);
-                if (qualityTestStandard.size() > 0) {
+                if (!qualityTestStandard.isEmpty()) {
                     qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
                     qualityInspectMapper.updateById(qualityInspect);
                     qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
-                                    .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId()))//榛樿鑾峰彇鏈�鏂扮殑
+                                    .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId()))
                             .forEach(qualityTestStandardParam -> {
                                 QualityInspectParam param = new QualityInspectParam();
                                 BeanUtils.copyProperties(qualityTestStandardParam, param);
@@ -207,140 +336,302 @@
                                 qualityInspectParamMapper.insert(param);
                             });
                 }
-            }else {
-                //鐩存帴鍏ュ簱
-                stockUtils.addStock(productProcessRouteItem.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
+            } else {
+                StockInventoryDto stockInventoryDto = new StockInventoryDto();
+                stockInventoryDto.setRecordId(productionProductMain.getId());
+                stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode()));
+                stockInventoryDto.setQualitity(productQty);
+                stockInventoryDto.setProductModelId(productModel.getId());
+                stockInventoryService.addStockInRecordOnly(stockInventoryDto);
             }
-            /*鏇存柊宸ュ崟鍜岀敓浜ц鍗�*/
-            ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
-            productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(productQty));
-            if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) {
-                productWorkOrder.setActualStartTime(LocalDate.now());//瀹為檯寮�濮嬫椂闂�
+
+            productionOperationTask.setCompleteQuantity(defaultDecimal(productionOperationTask.getCompleteQuantity()).add(productQty));
+            if (ObjectUtils.isNull(productionOperationTask.getActualStartTime())) {
+                productionOperationTask.setActualStartTime(LocalDate.now());
             }
-            if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0) {
-                productWorkOrder.setActualEndTime(LocalDate.now());//瀹為檯缁撴潫鏃堕棿
+            // 鎶ュ伐椹卞姩宸ュ崟鐘舵�佹祦杞細鏈変骇鍑哄嵆杩涜涓紝杈惧埌璁″垝閲忓嵆瀹屽伐銆�
+            productionOperationTask.setStatus(3);
+            if (productionOperationTask.getPlanQuantity() != null
+                    && productionOperationTask.getCompleteQuantity().compareTo(productionOperationTask.getPlanQuantity()) >= 0) {
+                productionOperationTask.setActualEndTime(LocalDate.now());
+                productionOperationTask.setStatus(4);
             }
-            productWorkOrderMapper.updateById(productWorkOrder);
-            //鐢熶骇璁㈠崟
-            ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
-            if (ObjectUtils.isNull(productOrder.getStartTime())) {
-                productOrder.setStartTime(LocalDateTime.now());//寮�濮嬫椂闂�
+            productionOperationTaskMapper.updateById(productionOperationTask);
+
+            if (ObjectUtils.isNull(productionOrder.getStartTime())) {
+                productionOrder.setStartTime(LocalDateTime.now());
             }
-            if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
-                //濡傛灉鏄渶鍚庝竴閬撳伐搴忔姤宸ヤ箣鍚庣敓浜ц鍗曞畬鎴愭暟閲�+
-                productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(productQty));
-                if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0) {
-                    productOrder.setEndTime(LocalDateTime.now());//缁撴潫鏃堕棿
+            // 璁㈠崟鐘舵�佺敱鏈�鍚庝竴閬撳伐搴忕殑鍚堟牸浜у嚭鎺ㄥ姩锛岄伩鍏嶄腑闂村伐搴忔彁鍓嶅畬宸ャ��
+            productionOrder.setStatus(ProductOrderStatusEnum.RUNNING.getCode());
+            if (isLastOperation) {
+                productionOrder.setCompleteQuantity(defaultDecimal(productionOrder.getCompleteQuantity()).add(productQty));
+                if (productionOrder.getQuantity() != null
+                        && productionOrder.getCompleteQuantity().compareTo(productionOrder.getQuantity()) >= 0) {
+                    productionOrder.setEndTime(LocalDateTime.now());
+                    productionOrder.setStatus(ProductOrderStatusEnum.FINISHED.getCode());
                 }
             }
-            productOrderMapper.updateById(productOrder);
-            /*娣诲姞鐢熶骇鏍哥畻        鍖哄垎宸ュ簭鏄浠惰繕鏄鏃�*/
-            BigDecimal workHours = (productProcess.getType() == 1)
-                    ? productProcess.getSalaryQuota().multiply(productQty)
-                    : productProcess.getSalaryQuota();
+            productionOrderMapper.updateById(productionOrder);
 
-            SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
-                    .productMainId(productionProductMain.getId())
-                    .schedulingUserId(user.getUserId())
-                    .schedulingUserName(user.getNickName())
-                    .finishedNum(productQty)
-                    .workHours(workHours)
-                    .process(productProcess.getName())
-                    .schedulingDate(LocalDate.now())
-                    .tenantId(dto.getTenantId())
-                    .build();
-            salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
-        }
-        //濡傛灉鎶ュ簾鏁伴噺>0,闇�瑕佽繘鍏ユ姤搴熺殑搴撳瓨
-        if (ObjectUtils.isNotEmpty(dto.getScrapQty())) {
-            if (dto.getScrapQty().compareTo(BigDecimal.ZERO) > 0) {
-                stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId());
+            BigDecimal workHours = BigDecimal.ZERO;
+            if (technologyOperation != null && technologyOperation.getSalaryQuota() != null) {
+                workHours = Integer.valueOf(1).equals(technologyOperation.getType())
+                        ? technologyOperation.getSalaryQuota().multiply(productQty)
+                        : technologyOperation.getSalaryQuota();
             }
+            ProductionAccount productionAccount = new ProductionAccount();
+            productionAccount.setProductionProductMainId(productionProductMain.getId());
+//            productionAccount.setSalesLedgerId(productionOrder.getSalesLedgerId());
+//            productionAccount.setSalesLedgerProductId(productionOrder.getSalesLedgerProductId() == null ? null : productionOrder.getSalesLedgerProductId().longValue());
+            productionAccount.setSchedulingUserId(user == null ? null : user.getUserId());
+            productionAccount.setSchedulingUserName(user == null ? dto.getUserName() : user.getNickName());
+            productionAccount.setFinishedNum(productQty);
+            productionAccount.setWorkHours(workHours);
+            productionAccount.setTechnologyOperationName(technologyOperation == null ? null : technologyOperation.getName());
+            productionAccount.setSchedulingDate(LocalDateTime.now());
+            productionAccountMapper.insert(productionAccount);
         }
+//        if (defaultDecimal(dto.getScrapQty()).compareTo(BigDecimal.ZERO) > 0) {
+//            stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(),
+//                    StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId());
+//        }
         return true;
     }
 
-    @Override
-    public Boolean removeProductMain(Long id) {
-        //鍒ゆ柇璇ユ潯鎶ュ伐鏄惁涓嶅悎鏍煎鐞�,濡傛灉涓嶅悎鏍煎鐞嗕簡锛屽垯涓嶅厑璁稿垹闄�
-        List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(Wrappers.<QualityInspect>lambdaQuery().eq(QualityInspect::getProductMainId, id));
-        if (qualityInspects.size() > 0){
-            List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList(Wrappers.<QualityUnqualified>lambdaQuery()
-                    .in(QualityUnqualified::getInspectId, qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList())));
-            if (qualityUnqualifieds.size() > 0 && qualityUnqualifieds.get(0).getInspectState()==1) {
+    private void syncOperationParamInputValue(ProductionProductMainDto dto,
+                                              Long productionOrderRoutingOperationId,
+                                              Long productionProductMainId) {
+        if (dto == null || productionOrderRoutingOperationId == null || productionProductMainId == null) {
+            return;
+        }
+        List<ProductionOrderRoutingOperationParam> paramList = dto.getProductionOperationParamList();
+        if (paramList == null || paramList.isEmpty()) {
+            return;
+        }
+        Set<Long> sourceParamIdSet = paramList.stream()
+                .filter(Objects::nonNull)
+                .map(ProductionOrderRoutingOperationParam::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (sourceParamIdSet.isEmpty()) {
+            return;
+        }
+
+        List<ProductionOrderRoutingOperationParam> dbParamList = productionOrderRoutingOperationParamMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                        .in(ProductionOrderRoutingOperationParam::getId, sourceParamIdSet)
+                        .eq(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, productionOrderRoutingOperationId));
+        if (dbParamList == null || dbParamList.isEmpty()) {
+            return;
+        }
+
+        Map<Long, ProductionOrderRoutingOperationParam> dbParamMap = dbParamList.stream()
+                .filter(item -> item != null && item.getId() != null)
+                .collect(Collectors.toMap(ProductionOrderRoutingOperationParam::getId, item -> item, (left, right) -> left));
+        for (ProductionOrderRoutingOperationParam param : paramList) {
+            if (param == null || param.getId() == null) {
+                continue;
+            }
+            ProductionOrderRoutingOperationParam dbParam = dbParamMap.get(param.getId());
+            if (dbParam == null) {
+                throw new ServiceException("宸ュ簭鍙傛暟涓嶅瓨鍦ㄦ垨涓嶅睘浜庡綋鍓嶅伐鍗曞伐搴忥紝ID=" + param.getId());
+            }
+            productionOrderRoutingOperationParamMapper.insert(buildReportParamSnapshot(dbParam, param.getInputValue(), productionProductMainId));
+        }
+    }
+
+    private ProductionOrderRoutingOperationParam buildReportParamSnapshot(ProductionOrderRoutingOperationParam source,
+                                                                          String inputValue,
+                                                                          Long productionProductMainId) {
+        ProductionOrderRoutingOperationParam target = new ProductionOrderRoutingOperationParam();
+        target.setProductionOrderId(source.getProductionOrderId());
+        target.setTechnologyRoutingOperationParamId(source.getTechnologyRoutingOperationParamId());
+        target.setParamCode(source.getParamCode());
+        target.setParamName(source.getParamName());
+        target.setParamType(source.getParamType());
+        target.setParamFormat(source.getParamFormat());
+        target.setUnit(source.getUnit());
+        target.setIsRequired(source.getIsRequired());
+        target.setRemark(source.getRemark());
+        target.setParamId(source.getParamId());
+        target.setTechnologyOperationId(source.getTechnologyOperationId());
+        target.setTechnologyOperationParamId(source.getTechnologyOperationParamId());
+        target.setStandardValue(source.getStandardValue());
+        target.setInputValue(inputValue);
+        target.setProductionOrderRoutingOperationId(source.getProductionOrderRoutingOperationId());
+        target.setProductionProductMainId(productionProductMainId);
+        return target;
+    }
+
+    private List<ProductStructureDto> resolveInputStructures(Long productionOrderId,
+                                                             ProductionOrderRoutingOperation routingOperation,
+                                                             Long outputProductModelId) {
+        if (productionOrderId == null || routingOperation == null || routingOperation.getTechnologyOperationId() == null) {
+            return new ArrayList<>();
+        }
+        ProductionOrderBom orderBom = productionOrderBomMapper.selectOne(
+                Wrappers.<ProductionOrderBom>lambdaQuery()
+                        .eq(ProductionOrderBom::getProductionOrderId, productionOrderId)
+                        .orderByDesc(ProductionOrderBom::getId)
+                        .last("limit 1"));
+        if (orderBom == null || orderBom.getId() == null) {
+            return new ArrayList<>();
+        }
+
+        List<ProductionBomStructure> bomNodeList = productionBomStructureMapper.selectList(
+                Wrappers.<ProductionBomStructure>lambdaQuery()
+                        .eq(ProductionBomStructure::getProductionOrderBomId, orderBom.getId())
+                        .orderByAsc(ProductionBomStructure::getId));
+        if (bomNodeList.isEmpty()) {
+            return new ArrayList<>();
+        }
+
+        Map<Long, ProductionBomStructure> nodeMap = bomNodeList.stream()
+                .filter(item -> item != null && item.getId() != null)
+                .collect(Collectors.toMap(ProductionBomStructure::getId, item -> item, (left, right) -> left));
+        Long currentOutputModelId = routingOperation.getProductModelId() != null
+                ? routingOperation.getProductModelId()
+                : outputProductModelId;
+
+        Map<Long, BigDecimal> unitQtyByProductModel = new LinkedHashMap<>();
+        for (ProductionBomStructure node : bomNodeList) {
+            if (node == null || node.getParentId() == null || node.getProductModelId() == null) {
+                continue;
+            }
+            if (!Objects.equals(node.getTechnologyOperationId(), routingOperation.getTechnologyOperationId())) {
+                continue;
+            }
+            ProductionBomStructure parent = nodeMap.get(node.getParentId());
+            if (parent == null || !Objects.equals(parent.getProductModelId(), currentOutputModelId)) {
+                continue;
+            }
+            unitQtyByProductModel.merge(node.getProductModelId(), defaultDecimal(node.getUnitQuantity()), BigDecimal::add);
+        }
+
+        List<ProductStructureDto> result = new ArrayList<>();
+        for (Map.Entry<Long, BigDecimal> entry : unitQtyByProductModel.entrySet()) {
+            if (entry.getValue().compareTo(BigDecimal.ZERO) <= 0) {
+                continue;
+            }
+            ProductStructureDto item = new ProductStructureDto();
+            item.setProductModelId(entry.getKey());
+            item.setUnitQuantity(entry.getValue());
+            result.add(item);
+        }
+        return result;
+    }
+
+    private Boolean removeProductMainByProductionTask(ProductionProductMain productionProductMain) {
+        // 鍒犻櫎鎶ュ伐闇�瑕佸悓姝ュ洖婊氳川妫�銆佸簱瀛樸�佸伐鏃舵牳绠楀拰璁㈠崟/宸ュ崟杩涘害銆�
+        List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
+                Wrappers.<QualityInspect>lambdaQuery().eq(QualityInspect::getProductMainId, productionProductMain.getId()));
+        if (qualityInspects.size() > 0) {
+            List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList(
+                    Wrappers.<QualityUnqualified>lambdaQuery()
+                            .in(QualityUnqualified::getInspectId, qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList())));
+            if (qualityUnqualifieds.size() > 0 && qualityUnqualifieds.get(0).getInspectState() == 1) {
                 throw new ServiceException("璇ユ潯鎶ュ伐宸茬粡涓嶅悎鏍煎鐞嗕簡锛屼笉鍏佽鍒犻櫎");
             }
         }
-        ProductionProductMain productionProductMain = productionProductMainMapper.selectById(id);
-        //璇ユ姤宸ュ搴旂殑宸ヨ壓璺嚎璇︽儏
-        ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId());
-        ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(Wrappers.<ProductionProductOutput>lambdaQuery().eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())).get(0);
-        /*鍒犻櫎鏍哥畻*/
-        salesLedgerProductionAccountingMapper.delete(
-                new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
-                        .eq(SalesLedgerProductionAccounting::getProductMainId, productionProductMain.getId())
-        );
-        /*鏇存柊宸ュ崟鍜岀敓浜ц鍗�*/
-        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId());
-        if (productWorkOrder != null && productionProductOutput != null) {
-            BigDecimal outputQty = productionProductOutput.getQuantity() == null ? BigDecimal.ZERO : productionProductOutput.getQuantity();
-            BigDecimal scrapQty = productionProductOutput.getScrapQty() == null ? BigDecimal.ZERO : productionProductOutput.getScrapQty();
-            BigDecimal completeQty = productWorkOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productWorkOrder.getCompleteQuantity();
+        ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(
+                Wrappers.<ProductionProductOutput>lambdaQuery()
+                        .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId()))
+                .stream().findFirst().orElse(null);
+        productionAccountMapper.delete(new LambdaQueryWrapper<ProductionAccount>()
+                .eq(ProductionAccount::getProductionProductMainId, productionProductMain.getId()));
 
-            BigDecimal validQuantity = outputQty.subtract(scrapQty);
-
-            productWorkOrder.setCompleteQuantity(completeQty.subtract(validQuantity));
-            productWorkOrder.setActualEndTime(null);
-            productWorkOrderMapper.updateById(productWorkOrder);
-        } else {
-            throw new ServiceException("鎿嶄綔澶辫触锛氬伐鍗曚俊鎭垨浜у嚭璁板綍涓嶅瓨鍦�");
-        }
-        //鍒ゆ柇鏄惁鏄渶鍚庝竴閬撳伐搴�
-        List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
-        if (productProcessRouteItem.getDragSort() != null && productProcessRouteItems != null && productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
-            ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
-            if (productOrder != null) {
-                BigDecimal orderCompleteQty = productOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productOrder.getCompleteQuantity();
-                BigDecimal totalQty = productionProductOutput.getQuantity() != null ? productionProductOutput.getQuantity() : BigDecimal.ZERO;
-                BigDecimal scrapQty = productionProductOutput.getScrapQty() != null ? productionProductOutput.getScrapQty() : BigDecimal.ZERO;
-                BigDecimal actualQualifiedQty = totalQty.subtract(scrapQty);
-                BigDecimal newCompleteQty = orderCompleteQty.subtract(actualQualifiedQty);
-                productOrder.setCompleteQuantity(newCompleteQty.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : newCompleteQty);
-                productOrder.setEndTime(null);
-                productOrderMapper.updateById(productOrder);
+        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(productionProductMain.getProductionOperationTaskId());
+        if (productionOperationTask != null && productionProductOutput != null) {
+            BigDecimal reportQuantity = defaultDecimal(productionProductOutput.getQuantity());
+            productionOperationTask.setCompleteQuantity(defaultDecimal(productionOperationTask.getCompleteQuantity()).subtract(reportQuantity));
+            productionOperationTask.setActualEndTime(null);
+            if (defaultDecimal(productionOperationTask.getCompleteQuantity()).compareTo(BigDecimal.ZERO) <= 0) {
+                productionOperationTask.setCompleteQuantity(BigDecimal.ZERO);
+                productionOperationTask.setActualStartTime(null);
+                productionOperationTask.setStatus(2);
             } else {
-                throw new ServiceException("鍏宠仈鐨勭敓浜ц鍗曚笉瀛樺湪");
+                productionOperationTask.setStatus(3);
+            }
+            productionOperationTaskMapper.updateById(productionOperationTask);
+
+            ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId());
+            ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getProductionOrderRoutingOperationId());
+            if (productionOrder != null && routingOperation != null) {
+                // 鍙湁鏈�鍚庝竴閬撳伐搴忕殑鎶ュ伐鎵嶄細褰卞搷鐢熶骇璁㈠崟瀹屽伐鏁伴噺銆�
+                List<ProductionOrderRoutingOperation> routingOperationList = productionOrderRoutingOperationMapper.selectList(
+                        Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                                .eq(ProductionOrderRoutingOperation::getOrderRoutingId, routingOperation.getOrderRoutingId())
+                                .eq(ProductionOrderRoutingOperation::getProductionOrderId, routingOperation.getProductionOrderId()));
+                boolean isLastOperation = routingOperation.getDragSort() != null && routingOperation.getDragSort().equals(routingOperationList.size());
+                if (isLastOperation) {
+                    BigDecimal newCompleteQty = defaultDecimal(productionOrder.getCompleteQuantity()).subtract(reportQuantity);
+                    productionOrder.setCompleteQuantity(newCompleteQty.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : newCompleteQty);
+                    productionOrder.setEndTime(null);
+                }
+                if (defaultDecimal(productionOrder.getCompleteQuantity()).compareTo(BigDecimal.ZERO) <= 0) {
+                    productionOrder.setStartTime(null);
+                    productionOrder.setStatus(ProductOrderStatusEnum.WAIT.getCode());
+                } else {
+                    productionOrder.setStatus(ProductOrderStatusEnum.RUNNING.getCode());
+                }
+                productionOrderMapper.updateById(productionOrder);
             }
         }
-        //鍒犻櫎璐ㄦ
-        qualityInspectMapper.selectList(
-                new LambdaQueryWrapper<QualityInspect>()
-                        .eq(QualityInspect::getProductMainId, productionProductMain.getId())
-        ).forEach(q -> {
-            qualityInspectParamMapper.delete(
-                    new LambdaQueryWrapper<QualityInspectParam>()
-                            .eq(QualityInspectParam::getInspectId, q.getId()));
-            qualityInspectMapper.deleteById(q.getId());
-                stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
-        });
 
-        // 鍒犻櫎浜у嚭璁板綍
+        qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>()
+                .eq(QualityInspect::getProductMainId, productionProductMain.getId())).forEach(q -> {
+            qualityInspectParamMapper.delete(new LambdaQueryWrapper<QualityInspectParam>()
+                    .eq(QualityInspectParam::getInspectId, q.getId()));
+            qualityInspectMapper.deleteById(q.getId());
+            stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
+        });
         productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
-                .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()));
-        //鍒犻櫎鎶曞叆璁板綍
+                .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId()));
         productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
-                .eq(ProductionProductInput::getProductMainId, productionProductMain.getId()));
-        //鍒犻櫎鎶ュ簾鐨勫叆搴撹褰�
+                .eq(ProductionProductInput::getProductionProductMainId, productionProductMain.getId()));
+        productionOrderRoutingOperationParamMapper.delete(
+                Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperationParam::getProductionProductMainId, productionProductMain.getId()));
         stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
-        //鍒犻櫎涓嶉渶瑕佽川妫�鐨勫悎鏍煎叆搴�
         stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode());
-        //鍒犻櫎鎶曞叆瀵瑰簲鐨勫嚭搴撹褰�
         stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
-        // 鍒犻櫎涓昏〃
         productionProductMainMapper.deleteById(productionProductMain.getId());
         return true;
     }
 
+    private String generateProductNo() {
+        String datePrefix = "BG" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
+        QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("MAX(product_no) as maxNo").likeRight("product_no", datePrefix);
+        List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper);
+        int sequenceNumber = 1;
+        if (resultList != null && !resultList.isEmpty()) {
+            Map<String, Object> result = resultList.get(0);
+            if (result != null && result.get("maxNo") != null) {
+                String lastNo = result.get("maxNo").toString();
+                if (lastNo.startsWith(datePrefix)) {
+                    try {
+                        sequenceNumber = Integer.parseInt(lastNo.substring(datePrefix.length())) + 1;
+                    } catch (NumberFormatException e) {
+                        sequenceNumber = 1;
+                    }
+                }
+            }
+        }
+        return String.format("%s%03d", datePrefix, sequenceNumber);
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
+
+    private Long resolveTaskId(ProductionProductMainDto dto) {
+        if (dto == null) {
+            return null;
+        }
+        return dto.getProductionOperationTaskId();
+    }
+
     @Override
     public ArrayList<Long> listMain(List<Long> idList) {
         return productionProductMainMapper.listMain(idList);

--
Gitblit v1.9.3