From fa3428b4bb32179a42d5618357c22fe2695716ae Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期三, 22 四月 2026 13:58:23 +0800
Subject: [PATCH] 修改全局的注入方式

---
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java |  313 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 305 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
index 6b1bc0c..8562f46 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -1,20 +1,317 @@
 package com.ruoyi.production.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.production.bean.dto.ProductionOrderDto;
+import com.ruoyi.production.bean.vo.ProductionOrderVo;
+import com.ruoyi.production.mapper.ProductionBomStructureMapper;
+import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
+import com.ruoyi.production.mapper.ProductionOrderBomMapper;
 import com.ruoyi.production.mapper.ProductionOrderMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingOperationParamMapper;
+import com.ruoyi.production.mapper.ProductionProductMainMapper;
+import com.ruoyi.production.pojo.ProductionBomStructure;
+import com.ruoyi.production.pojo.ProductionOperationTask;
 import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderBom;
+import com.ruoyi.production.pojo.ProductionOrderRouting;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
+import com.ruoyi.production.pojo.ProductionProductMain;
 import com.ruoyi.production.service.ProductionOrderService;
+import com.ruoyi.technology.mapper.TechnologyBomMapper;
+import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingOperationParamMapper;
+import com.ruoyi.technology.pojo.TechnologyBom;
+import com.ruoyi.technology.pojo.TechnologyBomStructure;
+import com.ruoyi.technology.pojo.TechnologyRouting;
+import com.ruoyi.technology.pojo.TechnologyRoutingOperation;
+import com.ruoyi.technology.pojo.TechnologyRoutingOperationParam;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟琛� 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
 @Service
+@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor
 public class ProductionOrderServiceImpl extends ServiceImpl<ProductionOrderMapper, ProductionOrder> implements ProductionOrderService {
 
+    private final ProductionOrderRoutingMapper productionOrderRoutingMapper;
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+    private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper;
+    private final ProductionOperationTaskMapper productionOperationTaskMapper;
+    private final ProductionOrderBomMapper productionOrderBomMapper;
+    private final ProductionBomStructureMapper productionBomStructureMapper;
+    private final ProductionProductMainMapper productionProductMainMapper;
+    private final TechnologyRoutingMapper technologyRoutingMapper;
+    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
+    private final TechnologyRoutingOperationParamMapper technologyRoutingOperationParamMapper;
+    private final TechnologyBomMapper technologyBomMapper;
+    private final TechnologyBomStructureMapper technologyBomStructureMapper;
+
+    @Override
+    public com.baomidou.mybatisplus.core.metadata.IPage<ProductionOrderVo> pageProductionOrder(Page<ProductionOrderDto> page, ProductionOrderDto dto) {
+        Page<ProductionOrder> entityPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
+        return this.page(entityPage, buildQueryWrapper(dto)).convert(item -> BeanUtil.copyProperties(item, ProductionOrderVo.class));
+    }
+
+    @Override
+    public List<ProductionOrderVo> listProductionOrder(ProductionOrderDto dto) {
+        return BeanUtil.copyToList(this.list(buildQueryWrapper(dto)), ProductionOrderVo.class);
+    }
+
+    @Override
+    public ProductionOrderVo getProductionOrderInfo(Long id) {
+        ProductionOrder item = this.getById(id);
+        return item == null ? null : BeanUtil.copyProperties(item, ProductionOrderVo.class);
+    }
+
+    @Override
+    public boolean saveProductionOrder(ProductionOrder productionOrder) {
+        ProductionOrder oldOrder = productionOrder.getId() == null ? null : this.getById(productionOrder.getId());
+        if (productionOrder.getNpsNo() == null || productionOrder.getNpsNo().trim().isEmpty()) {
+            productionOrder.setNpsNo(generateNextOrderNo());
+        }
+        if (productionOrder.getCompleteQuantity() == null) {
+            productionOrder.setCompleteQuantity(BigDecimal.ZERO);
+        }
+        boolean saved = this.saveOrUpdate(productionOrder);
+        if (!saved) {
+            return false;
+        }
+        boolean needSync = productionOrder.getTechnologyRoutingId() != null
+                && (oldOrder == null
+                || !Objects.equals(oldOrder.getTechnologyRoutingId(), productionOrder.getTechnologyRoutingId())
+                || productionOrderRoutingMapper.selectCount(Wrappers.<ProductionOrderRouting>lambdaQuery()
+                        .eq(ProductionOrderRouting::getProductionOrderId, productionOrder.getId())) == 0);
+        if (needSync) {
+            syncProductionOrderSnapshot(productionOrder.getId());
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeProductionOrder(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        for (Long id : ids) {
+            clearProductionSnapshot(id);
+        }
+        return this.removeByIds(ids);
+    }
+
+    @Override
+    public int syncProductionOrderSnapshot(Long productionOrderId) {
+        ProductionOrder productionOrder = this.getById(productionOrderId);
+        if (productionOrder == null) {
+            throw new ServiceException("Production order not found");
+        }
+        if (productionOrder.getTechnologyRoutingId() == null) {
+            throw new ServiceException("technologyRoutingId is required");
+        }
+        TechnologyRouting technologyRouting = technologyRoutingMapper.selectById(productionOrder.getTechnologyRoutingId());
+        if (technologyRouting == null) {
+            throw new ServiceException("Technology routing not found");
+        }
+        clearProductionSnapshot(productionOrderId);
+
+        ProductionOrderRouting orderRouting = new ProductionOrderRouting();
+        orderRouting.setProductionOrderId(productionOrder.getId());
+        orderRouting.setTechnologyRoutingId(technologyRouting.getId());
+        orderRouting.setProductModelId(technologyRouting.getProductModelId());
+        orderRouting.setProcessRouteCode(technologyRouting.getProcessRouteCode());
+        orderRouting.setDescription(technologyRouting.getDescription());
+        orderRouting.setBomId(technologyRouting.getBomId());
+        productionOrderRoutingMapper.insert(orderRouting);
+
+        int syncedParamCount = 0;
+        List<TechnologyRoutingOperation> routingOperations = technologyRoutingOperationMapper.selectList(
+                Wrappers.<TechnologyRoutingOperation>lambdaQuery()
+                        .eq(TechnologyRoutingOperation::getTechnologyRoutingId, technologyRouting.getId())
+                        .orderByAsc(TechnologyRoutingOperation::getDragSort)
+                        .orderByAsc(TechnologyRoutingOperation::getId));
+        for (TechnologyRoutingOperation sourceOperation : routingOperations) {
+            ProductionOrderRoutingOperation targetOperation = new ProductionOrderRoutingOperation();
+            targetOperation.setProductionOrderId(productionOrder.getId());
+            targetOperation.setTechnologyRoutingOperationId(sourceOperation.getId());
+            targetOperation.setTechnologyRoutingId(orderRouting.getId());
+            targetOperation.setProductModelId(sourceOperation.getProductModelId());
+            targetOperation.setDragSort(sourceOperation.getDragSort());
+            targetOperation.setIsQuality(sourceOperation.getIsQuality());
+            productionOrderRoutingOperationMapper.insert(targetOperation);
+
+            ProductionOperationTask task = new ProductionOperationTask();
+            task.setTechnologyRoutingOperationId(targetOperation.getId());
+            task.setProductionOrderId(productionOrder.getId());
+            task.setPlanQuantity(defaultDecimal(productionOrder.getQuantity()));
+            task.setCompleteQuantity(BigDecimal.ZERO);
+            task.setWorkOrderNo(generateNextTaskNo());
+            task.setStatus(1);
+            productionOperationTaskMapper.insert(task);
+
+            List<TechnologyRoutingOperationParam> sourceParams = technologyRoutingOperationParamMapper.selectList(
+                    Wrappers.<TechnologyRoutingOperationParam>lambdaQuery()
+                            .eq(TechnologyRoutingOperationParam::getTechnologyRoutingOperationId, sourceOperation.getId())
+                            .orderByAsc(TechnologyRoutingOperationParam::getId));
+            for (TechnologyRoutingOperationParam sourceParam : sourceParams) {
+                ProductionOrderRoutingOperationParam targetParam = new ProductionOrderRoutingOperationParam();
+                targetParam.setProductionOrderId(productionOrder.getId());
+                targetParam.setTechnologyRoutingOperationId(targetOperation.getId());
+                targetParam.setTechnologyRoutingOperationParamId(sourceParam.getId());
+                targetParam.setParamId(sourceParam.getParamId());
+                targetParam.setTechnologyOperationId(sourceParam.getTechnologyOperationId());
+                targetParam.setTechnologyOperationParamId(sourceParam.getTechnologyOperationParamId());
+                targetParam.setParamCode(sourceParam.getParamCode());
+                targetParam.setParamName(sourceParam.getParamName());
+                targetParam.setParamType(sourceParam.getParamType());
+                targetParam.setParamFormat(sourceParam.getParamFormat());
+                targetParam.setUnit(sourceParam.getUnit());
+                targetParam.setIsRequired(sourceParam.getIsRequired());
+                targetParam.setRemark(sourceParam.getRemark());
+                targetParam.setStandardValue(sourceParam.getStandardValue());
+                productionOrderRoutingOperationParamMapper.insert(targetParam);
+                syncedParamCount++;
+            }
+        }
+
+        syncProductionOrderBomSnapshot(productionOrder, technologyRouting);
+        return syncedParamCount;
+    }
+
+    private void syncProductionOrderBomSnapshot(ProductionOrder productionOrder, TechnologyRouting technologyRouting) {
+        if (technologyRouting.getBomId() == null) {
+            return;
+        }
+        TechnologyBom technologyBom = technologyBomMapper.selectById(technologyRouting.getBomId());
+        if (technologyBom == null) {
+            throw new ServiceException("Technology BOM not found");
+        }
+        List<TechnologyBomStructure> structureList = technologyBomStructureMapper.selectList(
+                Wrappers.<TechnologyBomStructure>lambdaQuery()
+                        .eq(TechnologyBomStructure::getBomId, technologyBom.getId())
+                        .orderByAsc(TechnologyBomStructure::getId));
+        TechnologyBomStructure root = structureList.stream().filter(item -> item.getParentId() == null).findFirst().orElse(null);
+
+        ProductionOrderBom orderBom = new ProductionOrderBom();
+        orderBom.setProductionOrderId(productionOrder.getId());
+        orderBom.setBomId(Long.valueOf(technologyBom.getId()));
+        orderBom.setProductModelId(root != null ? root.getProductModelId() : productionOrder.getProductModelId());
+        orderBom.setTechnologyOperationId(root == null ? null : root.getOperationId());
+        orderBom.setUnitQuantity(root != null && root.getUnitQuantity() != null ? root.getUnitQuantity() : BigDecimal.ONE);
+        orderBom.setDemandedQuantity(root != null && root.getDemandedQuantity() != null ? root.getDemandedQuantity() : defaultDecimal(productionOrder.getQuantity()));
+        orderBom.setUnit(root == null ? null : root.getUnit());
+        productionOrderBomMapper.insert(orderBom);
+
+        Map<Long, Long> idMap = new HashMap<>();
+        for (TechnologyBomStructure source : structureList) {
+            ProductionBomStructure target = new ProductionBomStructure();
+            target.setProductionOrderId(productionOrder.getId());
+            target.setProductionOrderBomId(orderBom.getId());
+            target.setParentId(source.getParentId() == null ? null : idMap.get(source.getParentId()));
+            target.setProductModelId(source.getProductModelId());
+            target.setTechnologyOperationId(source.getOperationId());
+            target.setUnitQuantity(source.getUnitQuantity());
+            target.setDemandedQuantity(source.getDemandedQuantity());
+            target.setUnit(source.getUnit());
+            productionBomStructureMapper.insert(target);
+            idMap.put(source.getId(), target.getId());
+        }
+    }
+
+    private void clearProductionSnapshot(Long productionOrderId) {
+        List<Long> taskIds = productionOperationTaskMapper.selectList(
+                        Wrappers.<ProductionOperationTask>lambdaQuery()
+                                .eq(ProductionOperationTask::getProductionOrderId, productionOrderId))
+                .stream().map(ProductionOperationTask::getId).collect(Collectors.toList());
+        if (!taskIds.isEmpty()) {
+            boolean started = productionProductMainMapper.selectCount(
+                    Wrappers.<ProductionProductMain>lambdaQuery()
+                            .in(ProductionProductMain::getProductionOperationTaskId, taskIds)) > 0;
+            if (started) {
+                throw new ServiceException("Production order already started, snapshot cannot be regenerated");
+            }
+            productionOperationTaskMapper.delete(Wrappers.<ProductionOperationTask>lambdaQuery()
+                    .eq(ProductionOperationTask::getProductionOrderId, productionOrderId));
+        }
+        productionOrderRoutingOperationParamMapper.delete(Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                .eq(ProductionOrderRoutingOperationParam::getProductionOrderId, productionOrderId));
+        productionOrderRoutingOperationMapper.delete(Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                .eq(ProductionOrderRoutingOperation::getProductionOrderId, productionOrderId));
+        productionOrderRoutingMapper.delete(Wrappers.<ProductionOrderRouting>lambdaQuery()
+                .eq(ProductionOrderRouting::getProductionOrderId, productionOrderId));
+        productionBomStructureMapper.delete(Wrappers.<ProductionBomStructure>lambdaQuery()
+                .eq(ProductionBomStructure::getProductionOrderId, productionOrderId));
+        productionOrderBomMapper.delete(Wrappers.<ProductionOrderBom>lambdaQuery()
+                .eq(ProductionOrderBom::getProductionOrderId, productionOrderId));
+    }
+
+    private LambdaQueryWrapper<ProductionOrder> buildQueryWrapper(ProductionOrderDto dto) {
+        ProductionOrder query = dto == null ? new ProductionOrder() : dto;
+        return Wrappers.<ProductionOrder>lambdaQuery()
+                .eq(query.getId() != null, ProductionOrder::getId, query.getId())
+                .eq(query.getSalesLedgerId() != null, ProductionOrder::getSalesLedgerId, query.getSalesLedgerId())
+                .eq(query.getProductModelId() != null, ProductionOrder::getProductModelId, query.getProductModelId())
+                .eq(query.getTechnologyRoutingId() != null, ProductionOrder::getTechnologyRoutingId, query.getTechnologyRoutingId())
+                .like(query.getNpsNo() != null && !query.getNpsNo().trim().isEmpty(), ProductionOrder::getNpsNo, query.getNpsNo())
+                .orderByDesc(ProductionOrder::getId);
+    }
+
+    private String generateNextOrderNo() {
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        String prefix = "SC" + datePrefix;
+        ProductionOrder latestOrder = this.getOne(Wrappers.<ProductionOrder>lambdaQuery()
+                .likeRight(ProductionOrder::getNpsNo, prefix)
+                .orderByDesc(ProductionOrder::getNpsNo)
+                .last("limit 1"));
+        int sequence = 1;
+        if (latestOrder != null && latestOrder.getNpsNo() != null && latestOrder.getNpsNo().startsWith(prefix)) {
+            try {
+                sequence = Integer.parseInt(latestOrder.getNpsNo().substring(prefix.length())) + 1;
+            } catch (NumberFormatException ignored) {
+                sequence = 1;
+            }
+        }
+        return prefix + String.format("%04d", sequence);
+    }
+
+    private String generateNextTaskNo() {
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        String prefix = "GD" + datePrefix;
+        ProductionOperationTask lastTask = productionOperationTaskMapper.selectOne(
+                Wrappers.<ProductionOperationTask>lambdaQuery()
+                        .likeRight(ProductionOperationTask::getWorkOrderNo, prefix)
+                        .orderByDesc(ProductionOperationTask::getWorkOrderNo)
+                        .last("limit 1"));
+        int sequence = 1;
+        if (lastTask != null && lastTask.getWorkOrderNo() != null && lastTask.getWorkOrderNo().startsWith(prefix)) {
+            try {
+                sequence = Integer.parseInt(lastTask.getWorkOrderNo().substring(prefix.length())) + 1;
+            } catch (NumberFormatException ignored) {
+                sequence = 1;
+            }
+        }
+        return prefix + String.format("%03d", sequence);
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
 }

--
Gitblit v1.9.3