liyong
2026-05-15 0578c6c76f13e367b5dc7d0882efe3c69ca4cb0e
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -9,13 +9,8 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
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.bean.dto.ProductStructureDto;
import com.ruoyi.production.bean.dto.ProductionProductMainDto;
@@ -26,8 +21,7 @@
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.quality.mapper.*;
import com.ruoyi.quality.pojo.*;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.stock.service.StockInventoryService;
import com.ruoyi.technology.mapper.TechnologyOperationMapper;
import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper;
@@ -41,15 +35,7 @@
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.*;
import java.util.stream.Collectors;
@Service
@@ -82,6 +68,7 @@
    @Override
    public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) {
        // 分页查询生产报工主表
        IPage<ProductionProductMainDto> result = productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
        fillOperationParamList(result.getRecords());
        return result;
@@ -89,20 +76,24 @@
    @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)
@@ -112,6 +103,7 @@
            return;
        }
        // 查询并准备业务数据
        List<ProductionOrderRoutingOperationParam> paramList = productionOrderRoutingOperationParamMapper.selectList(
                Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
                        .in(ProductionOrderRoutingOperationParam::getProductionProductMainId, mainIdSet)
@@ -211,6 +203,7 @@
    @Override
    public Boolean addProductMain(ProductionProductMainDto dto) {
        // 新增生产报工主记录
        Long taskId = resolveTaskId(dto);
        if (taskId == null) {
            throw new ServiceException("请传入生产工单ID");
@@ -220,11 +213,13 @@
    @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;
@@ -233,10 +228,10 @@
    }
    private Boolean addProductMainByProductionTask(ProductionProductMainDto dto) {
        // 报工以订单工序快照为准,避免工艺主数据变更后影响历史工单执行。
        // 按生产任务新增报工主记录
        Long taskId = resolveTaskId(dto);
        if (taskId == null) {
            throw new ServiceException("productionOperationTaskId can not be null");
            throw new ServiceException("生产工单ID不能为空");
        }
        SysUser user = userMapper.selectUserById(dto.getUserId());
        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(taskId);
@@ -266,6 +261,7 @@
        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());
@@ -305,45 +301,45 @@
                        .eq(ProductionOrderRoutingOperation::getProductionOrderId, routingOperation.getProductionOrderId()));
        boolean isLastOperation = routingOperation.getDragSort() != null && routingOperation.getDragSort().equals(routingOperationList.size());
        if (productQty.compareTo(BigDecimal.ZERO) > 0) {
            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());
                qualityInspect.setProductName(product.getProductName());
                qualityInspect.setModel(productModel.getModel());
                qualityInspect.setUnit(productModel.getUnit());
                qualityInspect.setQuantity(productQty);
                qualityInspect.setProcess(process);
                qualityInspect.setInspectState(0);
                qualityInspect.setInspectType(inspectType);
                qualityInspect.setProductMainId(productionProductMain.getId());
                qualityInspect.setProductModelId(productModel.getId());
                qualityInspectMapper.insert(qualityInspect);
                List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process);
                if (!qualityTestStandard.isEmpty()) {
                    qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
                    qualityInspectMapper.updateById(qualityInspect);
                    qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
                                    .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId()))
                            .forEach(qualityTestStandardParam -> {
                                QualityInspectParam param = new QualityInspectParam();
                                BeanUtils.copyProperties(qualityTestStandardParam, param);
                                param.setId(null);
                                param.setInspectId(qualityInspect.getId());
                                qualityInspectParamMapper.insert(param);
                            });
                }
            } 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);
            }
//            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());
//                qualityInspect.setProductName(product.getProductName());
//                qualityInspect.setModel(productModel.getModel());
//                qualityInspect.setUnit(productModel.getUnit());
//                qualityInspect.setQuantity(productQty);
//                qualityInspect.setProcess(process);
//                qualityInspect.setInspectState(0);
//                qualityInspect.setInspectType(inspectType);
//                qualityInspect.setProductMainId(productionProductMain.getId());
//                qualityInspect.setProductModelId(productModel.getId());
//                qualityInspectMapper.insert(qualityInspect);
//                List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process);
//                if (!qualityTestStandard.isEmpty()) {
//                    qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
//                    qualityInspectMapper.updateById(qualityInspect);
//                    qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
//                                    .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId()))
//                            .forEach(qualityTestStandardParam -> {
//                                QualityInspectParam param = new QualityInspectParam();
//                                BeanUtils.copyProperties(qualityTestStandardParam, param);
//                                param.setId(null);
//                                param.setInspectId(qualityInspect.getId());
//                                qualityInspectParamMapper.insert(param);
//                            });
//                }
//            } 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);
//            }
            productionOperationTask.setCompleteQuantity(defaultDecimal(productionOperationTask.getCompleteQuantity()).add(productQty));
            if (ObjectUtils.isNull(productionOperationTask.getActualStartTime())) {
@@ -381,8 +377,6 @@
            }
            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);
@@ -391,10 +385,6 @@
            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;
    }
@@ -522,17 +512,19 @@
    }
    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("该条报工已经不合格处理了,不允许删除");
            }
        }
        // 参数与前置条件校验
//        if (!qualityInspects.isEmpty()) {
//            List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList(
//                    Wrappers.<QualityUnqualified>lambdaQuery()
//        // 遍历处理数据并组装结果
//                            .in(QualityUnqualified::getInspectId, qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList())));
//            if (!qualityUnqualifieds.isEmpty() && qualityUnqualifieds.getFirst().getInspectState() == 1) {
//                throw new ServiceException("该条报工已经不合格处理了,不允许删除");
//            }
//        }
        ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(
                Wrappers.<ProductionProductOutput>lambdaQuery()
                        .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId()))
@@ -552,6 +544,7 @@
            } else {
                productionOperationTask.setStatus(3);
            }
        // 持久化或输出处理结果
            productionOperationTaskMapper.updateById(productionOperationTask);
            ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId());
@@ -578,13 +571,13 @@
            }
        }
        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::getProductionProductMainId, productionProductMain.getId()));
        productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
@@ -592,14 +585,15 @@
        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());
//        stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInQualifiedRecordTypeEnum.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);
@@ -622,10 +616,12 @@
    }
    private BigDecimal defaultDecimal(BigDecimal value) {
        // 将空数量兜底为0,避免空指针异常
        return value == null ? BigDecimal.ZERO : value;
    }
    private Long resolveTaskId(ProductionProductMainDto dto) {
        // 从入参中解析生产工单ID并校验
        if (dto == null) {
            return null;
        }
@@ -634,6 +630,7 @@
    @Override
    public ArrayList<Long> listMain(List<Long> idList) {
        // 查询主表ID集合
        return productionProductMainMapper.listMain(idList);
    }
}