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/quality/service/impl/QualityUnqualifiedOrderServiceImpl.java |  313 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 313 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedOrderServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedOrderServiceImpl.java
index 1c9d83a..a21682f 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedOrderServiceImpl.java
@@ -1,15 +1,48 @@
 package com.ruoyi.quality.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+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.basic.enums.RecordTypeEnum;
 import com.ruoyi.basic.utils.FileUtil;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
+import com.ruoyi.production.mapper.ProductionOrderMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
+import com.ruoyi.production.mapper.ProductionProductMainMapper;
+import com.ruoyi.production.pojo.ProductionOperationTask;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderRouting;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
+import com.ruoyi.production.pojo.ProductionProductMain;
+import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
 import com.ruoyi.quality.mapper.QualityUnqualifiedOrderMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.quality.pojo.QualityUnqualified;
 import com.ruoyi.quality.pojo.QualityUnqualifiedOrder;
+import com.ruoyi.quality.service.IQualityInspectService;
 import com.ruoyi.quality.service.IQualityUnqualifiedOrderService;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.*;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @AllArgsConstructor
 @Service
@@ -17,6 +50,13 @@
 
     private final QualityUnqualifiedOrderMapper orderMapper;
     private final FileUtil fileUtil;
+    private final QualityUnqualifiedMapper qualityUnqualifiedMapper;
+    private final IQualityInspectService qualityInspectService;
+    private final ProductionProductMainMapper productionProductMainMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final ProductionOrderRoutingMapper productionOrderRoutingMapper;
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+    private final ProductionOperationTaskMapper productionOperationTaskMapper;
 
     @Override
     public IPage<QualityUnqualifiedOrder> listPage(Page page, QualityUnqualifiedOrder query) {
@@ -31,4 +71,277 @@
         }
         return order;
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean save(QualityUnqualifiedOrder order) {
+        boolean result = super.save(order);
+        // 澶勭疆鏂瑰紡鍖呭惈"缁翠慨"锛�2=鍘傚唴缁翠慨, 3=杩斿巶缁翠慨锛夋椂锛岃嚜鍔ㄥ垱寤鸿繑淇敓浜ц鍗�
+        if (order.getDisposalMethod() != null && (order.getDisposalMethod() == 2 || order.getDisposalMethod() == 3)) {
+            createReworkProductionOrder(order);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deal(QualityUnqualifiedOrder order) {
+        QualityUnqualifiedOrder existing = orderMapper.selectById(order.getId());
+        if (existing == null) {
+            return false;
+        }
+        existing.setDisposalMethod(order.getDisposalMethod());
+        existing.setRepairEvaluation(order.getRepairEvaluation());
+        existing.setReasonAnalysis(order.getReasonAnalysis());
+        existing.setCorrectionAction(order.getCorrectionAction());
+        existing.setPreventiveAction(order.getPreventiveAction());
+        existing.setRemark(order.getRemark());
+        existing.setDeptOpinion(order.getDeptOpinion());
+        existing.setCompanyDecision(order.getCompanyDecision());
+        existing.setGeneralManagerOpinion(order.getGeneralManagerOpinion());
+        existing.setStatus(3);
+        boolean result = updateById(existing);
+        if (result && existing.getDisposalMethod() != null
+                && (existing.getDisposalMethod() == 2 || existing.getDisposalMethod() == 3)) {
+            createReworkProductionOrder(existing);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateWithRework(QualityUnqualifiedOrder order) {
+        boolean result = updateById(order);
+        if (result && order.getDisposalMethod() != null
+                && (order.getDisposalMethod() == 2 || order.getDisposalMethod() == 3)) {
+            createReworkProductionOrder(order);
+        }
+        return result;
+    }
+
+    @Override
+    public void export(Long id, HttpServletResponse response) {
+        QualityUnqualifiedOrder order = getDetail(id);
+        if (order == null) {
+            throw new ServiceException("澶勭悊鍗曚笉瀛樺湪");
+        }
+        try (InputStream is = this.getClass().getResourceAsStream("/static/涓嶅悎鏍煎搧澶勭悊鍗�.xls");
+             POIFSFileSystem fs = new POIFSFileSystem(is);
+             HSSFWorkbook wb = new HSSFWorkbook(fs)) {
+            Sheet sheet = wb.getSheetAt(0);
+
+            setCellValue(sheet, 2, 1, order.getProjectName());
+            setCellValue(sheet, 2, 5, order.getProjectNo());
+            setCellValue(sheet, 3, 1, order.getEquipmentName());
+            setCellValue(sheet, 3, 5, order.getEquipmentDrawingNo());
+            setCellValue(sheet, 4, 1, order.getMaterialName());
+            setCellValue(sheet, 4, 5, order.getMaterialDrawingNo());
+            setCellValue(sheet, 5, 1, order.getSpecificationModel());
+            setCellValue(sheet, 5, 3, order.getMaterialQuality());
+            setCellValue(sheet, 5, 5, order.getQuantity());
+            setCellValue(sheet, 5, 7, order.getUnqualifiedQuantity());
+
+            // 涓嶅悎鏍煎伐搴� - 鍙浛鎹㈠搴旂殑鈻′负鈭�
+            if (order.getUnqualifiedProcess() != null) {
+                String origin = "鈻℃潵鏂�    鈻″埗绋�   鈻℃垚鍝�";
+                int idx = order.getUnqualifiedProcess() - 1;
+                if (idx >= 0 && idx < 3) {
+                    origin = origin.replaceFirst("鈻�", "鈭�");
+                    if (idx >= 1) origin = origin.replaceFirst("鈻�", idx == 1 ? "鈭�" : "鈻�");
+                    if (idx >= 2) origin = origin.replaceFirst("鈻�", "鈭�");
+                }
+                // 鎸夌储寮曚緷娆℃浛鎹�
+                StringBuilder sb = new StringBuilder();
+                int found = 0;
+                for (char c : "鈻℃潵鏂�    鈻″埗绋�   鈻℃垚鍝�".toCharArray()) {
+                    if (c == '鈻�') {
+                        sb.append(found == idx ? '鈽�' : '鈻�');
+                        found++;
+                    } else {
+                        sb.append(c);
+                    }
+                }
+                setCellValue(sheet, 6, 1, sb.toString());
+            }
+            setCellValue(sheet, 6, 5, order.getSupplierName());
+
+            setCellValue(sheet, 7, 1, order.getInspectorName());
+            setCellValue(sheet, 7, 3, order.getInspectDate());
+            setCellValue(sheet, 7, 5, order.getResponsiblePerson());
+            setCellValue(sheet, 7, 7, order.getResponsibleDept());
+
+            setCellValue(sheet, 8, 1, order.getProblemDescription());
+            setCellValue(sheet, 9, 1, order.getReasonAnalysis());
+            setCellValue(sheet, 10, 1, order.getCorrectionAction());
+
+            // 澶勭疆鏂瑰紡 - 鍙浛鎹㈠搴旂殑鈻′负鈭�
+            if (order.getDisposalMethod() != null) {
+                String template = "鈻¤姝ユ帴鏀�  鈻″巶鍐呯淮淇�  鈻¤繑鍘傜淮淇�  鈻℃崲璐�  鈻¢��璐�  鈻℃姤搴�";
+                int idx = order.getDisposalMethod() - 1;
+                StringBuilder sb = new StringBuilder();
+                int found = 0;
+                for (char c : template.toCharArray()) {
+                    if (c == '鈻�') {
+                        sb.append(found == idx ? '鈽�' : '鈻�');
+                        found++;
+                    } else {
+                        sb.append(c);
+                    }
+                }
+                setCellValue(sheet, 11, 1, sb.toString());
+            }
+            setCellValue(sheet, 12, 1, order.getRepairEvaluation());
+            setCellValue(sheet, 13, 1, order.getPreventiveAction());
+            setCellValue(sheet, 14, 1, order.getDeptOpinion());
+            setCellValue(sheet, 15, 1, order.getCompanyDecision());
+            setCellValue(sheet, 16, 1, order.getGeneralManagerOpinion());
+
+            response.setContentType("application/vnd.ms-excel");
+            String fileName = URLEncoder.encode("涓嶅悎鏍煎搧澶勭悊鍗昣" + order.getOrderNo(), "UTF-8");
+            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
+            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
+            OutputStream os = response.getOutputStream();
+            wb.write(os);
+            os.flush();
+            os.close();
+        } catch (Exception e) {
+            throw new RuntimeException("瀵煎嚭澶辫触", e);
+        }
+    }
+
+    private void setCellValue(Sheet sheet, int rowIdx, int colIdx, Object value) {
+        if (value == null) return;
+        Row row = sheet.getRow(rowIdx);
+        if (row == null) row = sheet.createRow(rowIdx);
+        Cell cell = row.getCell(colIdx);
+        if (cell == null) cell = row.createCell(colIdx);
+        if (value instanceof Date) {
+            cell.setCellValue((Date) value);
+        } else if (value instanceof Number) {
+            cell.setCellValue(((Number) value).doubleValue());
+        } else {
+            cell.setCellValue(value.toString());
+        }
+    }
+
+    private void createReworkProductionOrder(QualityUnqualifiedOrder order) {
+        if (order.getUnqualifiedId() == null) {
+            return;
+        }
+        QualityUnqualified unqualified = qualityUnqualifiedMapper.selectById(order.getUnqualifiedId());
+        if (unqualified == null || unqualified.getInspectId() == null) {
+            return;
+        }
+        QualityInspect qualityInspect = qualityInspectService.getById(unqualified.getInspectId());
+        if (qualityInspect == null || qualityInspect.getProductMainId() == null) {
+            return;
+        }
+        ProductionProductMain sourceMain = productionProductMainMapper.selectById(qualityInspect.getProductMainId());
+        if (sourceMain == null || sourceMain.getProductionOperationTaskId() == null) {
+            return;
+        }
+        ProductionOperationTask sourceTask = productionOperationTaskMapper.selectById(sourceMain.getProductionOperationTaskId());
+        if (sourceTask == null) {
+            return;
+        }
+        ProductionOrder sourceOrder = productionOrderMapper.selectById(sourceTask.getProductionOrderId());
+        if (sourceOrder == null) {
+            return;
+        }
+
+        BigDecimal reworkQty = order.getUnqualifiedQuantity() != null ? order.getUnqualifiedQuantity()
+                : unqualified.getQuantity() != null ? unqualified.getQuantity() : BigDecimal.ONE;
+
+        ProductionOrder newOrder = new ProductionOrder();
+        BeanUtils.copyProperties(sourceOrder, newOrder);
+        newOrder.setId(null);
+        newOrder.setNpsNo(generateNextProductionOrderNo("FG"));
+        newOrder.setQuantity(reworkQty);
+        newOrder.setCompleteQuantity(BigDecimal.ZERO);
+        newOrder.setStartTime(null);
+        newOrder.setEndTime(null);
+        newOrder.setCreateTime(null);
+        newOrder.setUpdateTime(null);
+        newOrder.setDisposalMethod(order.getDisposalMethod());
+        productionOrderMapper.insert(newOrder);
+
+        Map<Long, Long> routingIdMap = new HashMap<>();
+        List<ProductionOrderRouting> sourceRoutings = productionOrderRoutingMapper.selectList(
+                Wrappers.<ProductionOrderRouting>lambdaQuery()
+                        .eq(ProductionOrderRouting::getProductionOrderId, sourceOrder.getId())
+                        .orderByAsc(ProductionOrderRouting::getId));
+        for (ProductionOrderRouting sourceRouting : sourceRoutings) {
+            ProductionOrderRouting newRouting = new ProductionOrderRouting();
+            BeanUtils.copyProperties(sourceRouting, newRouting);
+            newRouting.setId(null);
+            newRouting.setProductionOrderId(newOrder.getId());
+            newRouting.setCreateTime(null);
+            newRouting.setUpdateTime(null);
+            productionOrderRoutingMapper.insert(newRouting);
+            routingIdMap.put(sourceRouting.getId(), newRouting.getId());
+        }
+
+        List<ProductionOrderRoutingOperation> sourceOperations = productionOrderRoutingOperationMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperation::getProductionOrderId, sourceOrder.getId())
+                        .orderByAsc(ProductionOrderRoutingOperation::getDragSort)
+                        .orderByAsc(ProductionOrderRoutingOperation::getId));
+        for (ProductionOrderRoutingOperation sourceOperation : sourceOperations) {
+            ProductionOrderRoutingOperation newOperation = new ProductionOrderRoutingOperation();
+            BeanUtils.copyProperties(sourceOperation, newOperation);
+            newOperation.setId(null);
+            newOperation.setProductionOrderId(newOrder.getId());
+            newOperation.setOrderRoutingId(routingIdMap.get(sourceOperation.getOrderRoutingId()));
+            newOperation.setCreateTime(null);
+            newOperation.setUpdateTime(null);
+            productionOrderRoutingOperationMapper.insert(newOperation);
+
+            ProductionOperationTask newTask = new ProductionOperationTask();
+            newTask.setProductionOrderRoutingOperationId(newOperation.getId());
+            newTask.setProductionOrderId(newOrder.getId());
+            newTask.setPlanQuantity(newOrder.getQuantity());
+            newTask.setCompleteQuantity(BigDecimal.ZERO);
+            newTask.setWorkOrderNo(generateNextTaskNo("FG"));
+            newTask.setStatus(1);
+            productionOperationTaskMapper.insert(newTask);
+        }
+    }
+
+    private String generateNextProductionOrderNo(String prefix) {
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        String orderPrefix = prefix + datePrefix;
+        ProductionOrder latestOrder = productionOrderMapper.selectOne(
+                Wrappers.<ProductionOrder>lambdaQuery()
+                        .likeRight(ProductionOrder::getNpsNo, orderPrefix)
+                        .orderByDesc(ProductionOrder::getNpsNo)
+                        .last("limit 1"));
+        int sequence = 1;
+        if (latestOrder != null && latestOrder.getNpsNo() != null && latestOrder.getNpsNo().startsWith(orderPrefix)) {
+            try {
+                sequence = Integer.parseInt(latestOrder.getNpsNo().substring(orderPrefix.length())) + 1;
+            } catch (NumberFormatException ignored) {
+                sequence = 1;
+            }
+        }
+        return orderPrefix + String.format("%04d", sequence);
+    }
+
+    private String generateNextTaskNo(String prefix) {
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        String taskPrefix = prefix + datePrefix;
+        ProductionOperationTask latestTask = productionOperationTaskMapper.selectOne(
+                Wrappers.<ProductionOperationTask>lambdaQuery()
+                        .likeRight(ProductionOperationTask::getWorkOrderNo, taskPrefix)
+                        .orderByDesc(ProductionOperationTask::getWorkOrderNo)
+                        .last("limit 1"));
+        int sequence = 1;
+        if (latestTask != null && latestTask.getWorkOrderNo() != null && latestTask.getWorkOrderNo().startsWith(taskPrefix)) {
+            try {
+                sequence = Integer.parseInt(latestTask.getWorkOrderNo().substring(taskPrefix.length())) + 1;
+            } catch (NumberFormatException ignored) {
+                sequence = 1;
+            }
+        }
+        return taskPrefix + String.format("%03d", sequence);
+    }
 }

--
Gitblit v1.9.3