From 741918a903e17b2ec7522556d2c043b8d35dd8a1 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 15 六月 2026 17:42:58 +0800
Subject: [PATCH] 生产取消bom,不合格管理定制化

---
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java |  393 ++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 227 insertions(+), 166 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 c52892a..3514da3 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -1,5 +1,6 @@
 package com.ruoyi.production.service.impl;
 
+import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -14,9 +15,9 @@
 import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
 import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.procurementrecord.utils.StockUtils;
-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.*;
@@ -39,13 +40,14 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.Duration;
 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;
@@ -72,8 +74,6 @@
     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;
@@ -219,106 +219,179 @@
 
     @Override
     public Boolean addProductMain(ProductionProductMainDto dto) {
-        // 鏂板鐢熶骇鎶ュ伐涓昏褰�
+        // 鍏煎鏃ф祦绋嬶細濡傛灉娌℃湁寮�濮嬫姤宸ヨ褰旾D锛岃蛋涓�姝ユ姤宸ワ紙鑷姩鍒涘缓+缁撴潫锛�
+        Long startRecordId = dto.resolveStartRecordId();
+        if (startRecordId == null) {
+            return oneStepWork(dto);
+        }
+        dto.setId(startRecordId);
+        return finishWork(dto);
+    }
+
+    @Override
+    public Boolean startWork(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("鐢熶骇宸ュ崟ID涓嶈兘涓虹┖");
-        }
-        SysUser user = userMapper.selectUserById(dto.getUserId());
-        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(taskId);
-        if (productionOperationTask == null) {
+        ProductionOperationTask task = productionOperationTaskMapper.selectById(taskId);
+        if (task == null) {
             throw new ServiceException("鐢熶骇宸ュ崟涓嶅瓨鍦�");
         }
-        ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getProductionOrderRoutingOperationId());
-        if (routingOperation == null) {
-            throw new ServiceException("璁㈠崟宸ヨ壓璺嚎宸ュ簭涓嶅瓨鍦�");
+        // 鏉冮檺鏍¢獙锛氬凡鎸囨淳鏃朵粎琚寚娲句汉鍙搷浣�
+        validateWorkerPermission(task);
+
+        if (task.getStatus() != null && task.getStatus() != 2 && task.getStatus() != 3) {
+            throw new ServiceException("褰撳墠宸ュ崟鐘舵�佷笉鍏佽寮�濮嬫姤宸ワ紝浠呭緟鐢熶骇鎴栫敓浜т腑鐘舵�佺殑宸ュ崟鍙搷浣�");
         }
-        ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId());
-        if (productionOrder == null) {
-            throw new ServiceException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+        SysUser user = userMapper.selectUserById(dto.getUserId());
+        ProductionProductMain main = new ProductionProductMain();
+        main.setProductNo(generateProductNo());
+        main.setUserId(user == null ? dto.getUserId() : user.getUserId());
+        main.setUserName(user == null ? dto.getUserName() : user.getNickName());
+        main.setProductionOperationTaskId(taskId);
+        main.setStatus(0);
+        main.setActualStartTime(LocalDateTime.now());
+        productionProductMainMapper.insert(main);
+
+        // 宸ュ崟鐘舵�� -> 鐢熶骇涓�
+        task.setStatus(3);
+        if (task.getActualStartTime() == null) {
+            task.setActualStartTime(LocalDateTime.now());
         }
-        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());
+        productionOperationTaskMapper.updateById(task);
+
+        // 鐢熶骇璁㈠崟 -> 鐢熶骇杩涜涓�
+        ProductionOrder productionOrder = productionOrderMapper.selectById(task.getProductionOrderId());
+        if (productionOrder != null && productionOrder.getStartTime() == null) {
+            productionOrder.setStartTime(LocalDateTime.now());
+            productionOrder.setStatus(ProductOrderStatusEnum.RUNNING.getCode());
+            productionOrderMapper.updateById(productionOrder);
+        }
+        return true;
+    }
+
+    private Boolean oneStepWork(ProductionProductMainDto dto) {
+        // 鍏煎鏃т竴姝ユ姤宸ユ祦绋嬶細鑷姩鍒涘缓寮�濮嬭褰曞苟绔嬪嵆缁撴潫
+        Long taskId = resolveTaskId(dto);
+        if (taskId == null) {
+            throw new ServiceException("璇蜂紶鍏ョ敓浜у伐鍗旾D");
+        }
+        ProductionOperationTask task = productionOperationTaskMapper.selectById(taskId);
+        if (task == null) {
+            throw new ServiceException("鐢熶骇宸ュ崟涓嶅瓨鍦�");
+        }
+        validateWorkerPermission(task);
+        if (task.getStatus() != null && task.getStatus() != 2 && task.getStatus() != 3) {
+            throw new ServiceException("褰撳墠宸ュ崟鐘舵�佷笉鍏佽鎶ュ伐");
+        }
+        SysUser user = userMapper.selectUserById(dto.getUserId());
+        ProductionProductMain main = new ProductionProductMain();
+        main.setProductNo(generateProductNo());
+        main.setUserId(user == null ? dto.getUserId() : user.getUserId());
+        main.setUserName(user == null ? dto.getUserName() : user.getNickName());
+        main.setProductionOperationTaskId(taskId);
+        main.setStatus(0);
+        main.setActualStartTime(LocalDateTime.now());
+        productionProductMainMapper.insert(main);
+
+        if (task.getActualStartTime() == null) {
+            task.setActualStartTime(LocalDateTime.now());
+        }
+        task.setStatus(3);
+        productionOperationTaskMapper.updateById(task);
+
+        ProductionOrder productionOrder = productionOrderMapper.selectById(task.getProductionOrderId());
+        if (productionOrder != null && productionOrder.getStartTime() == null) {
+            productionOrder.setStartTime(LocalDateTime.now());
+            productionOrder.setStatus(ProductOrderStatusEnum.RUNNING.getCode());
+            productionOrderMapper.updateById(productionOrder);
+        }
+
+        dto.setId(main.getId());
+        return finishWork(dto);
+    }
+
+    private Boolean finishWork(ProductionProductMainDto dto) {
+        // 缁撴潫鎶ュ伐锛氭洿鏂板紑濮嬫姤宸ヨ褰曪紝鍒涘缓浜у嚭銆佹姇鍏ュ搧銆佹牳绠楄褰�
+        ProductionProductMain currentMain = productionProductMainMapper.selectById(dto.getId());
+        if (currentMain == null) {
+            throw new ServiceException("寮�濮嬫姤宸ヨ褰曚笉瀛樺湪");
+        }
+        if (currentMain.getStatus() == null || currentMain.getStatus() != 0) {
+            throw new ServiceException("璇ユ姤宸ヨ褰曞凡缁撴潫鎴栫姸鎬佸紓甯�");
+        }
+        Long taskId = currentMain.getProductionOperationTaskId();
+        ProductionOperationTask task = productionOperationTaskMapper.selectById(taskId);
+        if (task == null) {
+            throw new ServiceException("鐢熶骇宸ュ崟涓嶅瓨鍦�");
+        }
+        validateWorkerPermission(task);
+
+        // 鏇存柊鎶ュ伐璁板綍涓哄凡缁撴潫锛岃褰曠粨鏉熸椂闂�
+        currentMain.setActualEndTime(LocalDateTime.now());
+        currentMain.setStatus(1);
+        if (dto.getWorkHour() != null) {
+            currentMain.setWorkHour(dto.getWorkHour());
+        } else if (currentMain.getActualStartTime() != null) {
+            // 鏍规嵁寮�濮�/缁撴潫鏃堕棿璁$畻瀹為檯宸ユ椂锛堝皬鏃讹級
+            long seconds = Duration.between(currentMain.getActualStartTime(), currentMain.getActualEndTime()).getSeconds();
+            currentMain.setWorkHour(BigDecimal.valueOf(seconds).divide(BigDecimal.valueOf(3600), 4, RoundingMode.HALF_UP));
+        }
+        productionProductMainMapper.updateById(currentMain);
+
+        // 鍚屾宸ュ簭鍙傛暟
+        ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(task.getProductionOrderRoutingOperationId());
+        if (routingOperation != null) {
+            syncOperationParamInputValue(dto, routingOperation.getId(), currentMain.getId());
+        }
+
+        // 鑾峰彇浜у搧瑙勬牸
+        ProductModel productModel = null;
+        if (routingOperation != null) {
+            productModel = productModelMapper.selectById(
+                    routingOperation.getProductModelId() != null ? routingOperation.getProductModelId() : getProductionOrderProductModelId(task));
+        }
         if (productModel == null) {
             throw new ServiceException("浜у搧瑙勬牸涓嶅瓨鍦�");
         }
 
-        ProductionProductMain productionProductMain = new ProductionProductMain();
-        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);
-        productionProductMain.setWorkHour(dto.getWorkHour());
-        productionProductMainMapper.insert(productionProductMain);
-        syncOperationParamInputValue(dto, routingOperation.getId(), productionProductMain.getId());
+        // 鎶曞叆鍝�
+        ProductionProductInput productionProductInput = new ProductionProductInput();
+        productionProductInput.setProductionProductMainId(currentMain.getId());
+        productionProductInput.setProductModelId(productModel.getId());
+        productionProductInput.setInputQuantity(defaultDecimal(dto.getQuantity()));
+        productionProductInput.setQuantity(productionProductInput.getInputQuantity());
+        productionProductInputMapper.insert(productionProductInput);
 
-        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.setProductionProductMainId(productionProductMain.getId());
-            productionProductInput.setProductModelId(item.getProductModelId());
-            productionProductInput.setInputQuantity(item.getUnitQuantity().multiply(defaultDecimal(dto.getQuantity())));
-            productionProductInput.setQuantity(productionProductInput.getInputQuantity());
-            productionProductInputMapper.insert(productionProductInput);
-        }
-
+        // 浜у嚭鍝�
         ProductionProductOutput productionProductOutput = new ProductionProductOutput();
-        productionProductOutput.setProductionProductMainId(productionProductMain.getId());
+        productionProductOutput.setProductionProductMainId(currentMain.getId());
         productionProductOutput.setProductModelId(productModel.getId());
         productionProductOutput.setQuantity(defaultDecimal(dto.getQuantity()));
         productionProductOutput.setScrapQty(defaultDecimal(dto.getScrapQty()));
         productionProductOutputMapper.insert(productionProductOutput);
+
         BigDecimal reportQty = defaultDecimal(productionProductOutput.getQuantity());
         BigDecimal scrapQty = defaultDecimal(productionProductOutput.getScrapQty());
         BigDecimal productQty = reportQty;
         String qualifiedBatchNo = null;
 
-        List<ProductionOrderRoutingOperation> routingOperationList = productionOrderRoutingOperationMapper.selectList(
+        TechnologyRoutingOperation technologyRoutingOperation = routingOperation != null
+                ? technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId()) : null;
+        TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null
+                : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId());
+
+        List<ProductionOrderRoutingOperation> routingOperationList = routingOperation != null ? 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());
+                        .eq(ProductionOrderRoutingOperation::getProductionOrderId, routingOperation.getProductionOrderId())) : new ArrayList<>();
+        boolean isLastOperation = routingOperation != null && routingOperation.getDragSort() != null
+                && routingOperation.getDragSort().equals(routingOperationList.size());
+
         if (productQty.compareTo(BigDecimal.ZERO) > 0) {
-            if (Boolean.TRUE.equals(routingOperation.getIsQuality())) {
-                // 璐ㄦ宸ュ簭鍏堢敓鎴愭楠屽崟锛岄潪璐ㄦ宸ュ簭鐩存帴鍏ュ悎鏍煎搧搴撳瓨銆�
+            if (routingOperation != null && 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());
@@ -331,7 +404,7 @@
                 qualityInspect.setProcess(process);
                 qualityInspect.setInspectState(0);
                 qualityInspect.setInspectType(inspectType);
-                qualityInspect.setProductMainId(productionProductMain.getId());
+                qualityInspect.setProductMainId(currentMain.getId());
                 qualityInspect.setProductModelId(productModel.getId());
                 qualityInspectMapper.insert(qualityInspect);
                 List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process);
@@ -350,45 +423,46 @@
                 }
             } else {
                 StockInventoryDto stockInventoryDto = new StockInventoryDto();
-                stockInventoryDto.setRecordId(productionProductMain.getId());
+                stockInventoryDto.setRecordId(currentMain.getId());
                 stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode()));
                 stockInventoryDto.setQualitity(productQty);
                 stockInventoryDto.setProductModelId(productModel.getId());
                 stockInventoryService.addStockInRecordOnly(stockInventoryDto);
                 qualifiedBatchNo = resolveLatestStockInBatchNo(
-                        productionProductMain.getId(),
+                        currentMain.getId(),
                         StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(),
                         productModel.getId(),
                         "0");
             }
 
-            productionOperationTask.setCompleteQuantity(defaultDecimal(productionOperationTask.getCompleteQuantity()).add(productQty));
-            if (ObjectUtils.isNull(productionOperationTask.getActualStartTime())) {
-                productionOperationTask.setActualStartTime(LocalDate.now());
+            task.setCompleteQuantity(defaultDecimal(task.getCompleteQuantity()).add(productQty));
+            if (task.getActualStartTime() == null) {
+                task.setActualStartTime(LocalDateTime.now());
             }
-            // 鎶ュ伐椹卞姩宸ュ崟鐘舵�佹祦杞細鏈変骇鍑哄嵆杩涜涓紝杈惧埌璁″垝閲忓嵆瀹屽伐銆�
-            productionOperationTask.setStatus(3);
-            if (productionOperationTask.getPlanQuantity() != null
-                    && productionOperationTask.getCompleteQuantity().compareTo(productionOperationTask.getPlanQuantity()) >= 0) {
-                productionOperationTask.setActualEndTime(LocalDate.now());
-                productionOperationTask.setStatus(4);
+            task.setStatus(3);
+            if (task.getPlanQuantity() != null
+                    && task.getCompleteQuantity().compareTo(task.getPlanQuantity()) >= 0) {
+                task.setActualEndTime(LocalDateTime.now());
+                task.setStatus(4);
             }
-            productionOperationTaskMapper.updateById(productionOperationTask);
+            productionOperationTaskMapper.updateById(task);
 
-            if (ObjectUtils.isNull(productionOrder.getStartTime())) {
-                productionOrder.setStartTime(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());
+            ProductionOrder productionOrder = productionOrderMapper.selectById(task.getProductionOrderId());
+            if (productionOrder != null) {
+                if (productionOrder.getStartTime() == null) {
+                    productionOrder.setStartTime(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());
+                    }
+                }
+                productionOrderMapper.updateById(productionOrder);
             }
-            productionOrderMapper.updateById(productionOrder);
 
             BigDecimal workHours = BigDecimal.ZERO;
             if (technologyOperation != null && technologyOperation.getSalaryQuota() != null) {
@@ -397,13 +471,14 @@
                         : technologyOperation.getSalaryQuota();
             }
             ProductionAccount productionAccount = new ProductionAccount();
-            productionAccount.setProductionProductMainId(productionProductMain.getId());
-            productionAccount.setSchedulingUserId(user == null ? null : user.getUserId());
-            productionAccount.setSchedulingUserName(user == null ? dto.getUserName() : user.getNickName());
+            productionAccount.setProductionProductMainId(currentMain.getId());
+            SysUser user = userMapper.selectUserById(dto.getUserId());
+            productionAccount.setSchedulingUserId(user == null ? currentMain.getUserId() : user.getUserId());
+            productionAccount.setSchedulingUserName(user == null ? currentMain.getUserName() : user.getNickName());
             productionAccount.setFinishedNum(productQty);
             productionAccount.setWorkHours(technologyOperation != null ? technologyOperation.getSalaryQuota() : null);
             productionAccount.setTechnologyOperationName(technologyOperation == null ? null : technologyOperation.getName());
-            productionAccount.setSchedulingDate(LocalDateTime.now());
+            productionAccount.setSchedulingDate(currentMain.getActualEndTime() != null ? currentMain.getActualEndTime() : LocalDateTime.now());
             productionAccountMapper.insert(productionAccount);
         }
         if (scrapQty.compareTo(BigDecimal.ZERO) > 0) {
@@ -411,10 +486,54 @@
                     productModel.getId(),
                     scrapQty,
                     StockInQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(),
-                    productionProductMain.getId(),
+                    currentMain.getId(),
                     qualifiedBatchNo);
         }
         return true;
+    }
+
+    private Long getProductionOrderProductModelId(ProductionOperationTask task) {
+        // 浠庣敓浜ц鍗曡幏鍙栦骇鍝佽鏍糏D
+        if (task == null || task.getProductionOrderId() == null) {
+            return null;
+        }
+        ProductionOrder order = productionOrderMapper.selectById(task.getProductionOrderId());
+        return order == null ? null : order.getProductModelId();
+    }
+
+    private void validateWorkerPermission(ProductionOperationTask task) {
+        // 鏍¢獙褰撳墠鐢ㄦ埛鏄惁鏈夋潈鎿嶄綔姝ゅ伐鍗曪細鏈寚娲炬椂浜轰汉鍙搷浣滐紝宸叉寚娲炬椂浠呰鎸囨淳浜哄彲鎿嶄綔
+        if (task == null) {
+            return;
+        }
+        String userIds = task.getUserIds();
+        if (userIds == null || userIds.isEmpty() || "[]".equals(userIds.trim())) {
+            return;
+        }
+        Long currentUserId = SecurityUtils.getUserId();
+        if (currentUserId == null) {
+            return;
+        }
+        List<Long> assignedIds = JSON.parseArray(userIds, Long.class);
+        if (assignedIds == null || !assignedIds.contains(currentUserId)) {
+            throw new ServiceException("鎮ㄦ湭琚寚娲惧埌姝ゅ伐鍗曪紝鏃犳硶鎿嶄綔");
+        }
+    }
+
+    @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 String resolveLatestStockInBatchNo(Long recordId,
@@ -502,64 +621,6 @@
         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) {

--
Gitblit v1.9.3