From 7ea939485f815ba613c7e45b9e299473e75c1167 Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期一, 26 一月 2026 16:48:40 +0800
Subject: [PATCH] 工单流转卡

---
 src/main/resources/mapper/production/ProductWorkOrderMapper.xml                  |   11 ++
 src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java |   82 +++++++++++++++++++-
 src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java     |   20 -----
 src/main/java/com/ruoyi/production/controller/ProductOrderController.java        |   12 ---
 src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java    |   15 ++-
 src/main/java/com/ruoyi/common/utils/MatrixToImageWriter.java                    |   67 ++++++++++++++++
 src/main/java/com/ruoyi/production/service/ProductOrderService.java              |    2 
 src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java          |    4 
 src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java                  |    4 
 src/main/resources/static/work-order-template.docx                               |    0 
 pom.xml                                                                          |    6 +
 11 files changed, 174 insertions(+), 49 deletions(-)

diff --git a/pom.xml b/pom.xml
index 44c9360..790a3e7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -301,6 +301,12 @@
             <artifactId>easyexcel</artifactId>
             <version>4.0.3</version>
         </dependency>
+        
+         <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.3.3</version>
+        </dependency>
 
     </dependencies>
 
diff --git a/src/main/java/com/ruoyi/common/utils/MatrixToImageWriter.java b/src/main/java/com/ruoyi/common/utils/MatrixToImageWriter.java
new file mode 100644
index 0000000..ad9f2aa
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/utils/MatrixToImageWriter.java
@@ -0,0 +1,67 @@
+package com.ruoyi.common.utils;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 閰嶇疆鍥惧儚鍐欏叆鍣�
+ *
+ * @author z1292
+ *
+ */
+public class MatrixToImageWriter {
+    private final int BLACK = 0xFF000000;
+    private final int WHITE = 0xFFFFFFFF;
+
+    private BufferedImage toBufferedImage(BitMatrix matrix) {
+        int width = matrix.getWidth();
+        int height = matrix.getHeight();
+        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        for (int x = 0; x < width; x++) {
+            for (int y = 0; y < height; y++) {
+                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
+            }
+        }
+        return image;
+    }
+
+    private void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
+        BufferedImage image = toBufferedImage(matrix);
+        if (!ImageIO.write(image, format, file)) {
+            throw new RuntimeException("Could not write an image of format " + format + " to " + file);
+        }
+    }
+
+    public String code(String content, String path) {
+        try {
+            String codeName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yy_MM_dd&HH_mm_ss"));// 浜岀淮鐮佺殑鍥剧墖鍚�
+            String imageType = "jpg";// 鍥剧墖绫诲瀷
+            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+            Map<EncodeHintType, Object> hints = new HashMap<>();
+            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+            hints.put(EncodeHintType.MARGIN, 0);
+            BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400, 400, hints);
+            File file1 = new File(path, codeName + "." + imageType);
+            writeToFile(bitMatrix, imageType, file1);
+            return file1.getPath();
+        } catch (WriterException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        throw new RuntimeException("浜岀淮鐮佺敓鎴愬け璐�");
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
index 442528d..4ad17a0 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -62,16 +62,4 @@
     public R listProcessBom(Long orderId) {
         return R.ok(productOrderService.listProcessBom(orderId));
     }
-
-
-    /**
-     * 鐢熶骇璁㈠崟娴佽浆鍗℃樉绀哄唴瀹�
-     */
-    @ApiOperation("鐢熶骇璁㈠崟娴佽浆鍗℃樉绀哄唴瀹�")
-    @GetMapping("/getProductOrderFlowCard")
-    public R getProductOrderFlowCard(Long orderId) {
-        return R.ok(productOrderService.getProductOrderFlowCard(orderId));
-    }
-
-
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
index 001316b..029e457 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
@@ -3,10 +3,14 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.dto.ProductWorkOrderDto;
+import com.ruoyi.production.pojo.ProductWorkOrder;
 import com.ruoyi.production.service.ProductWorkOrderService;
+import com.ruoyi.quality.pojo.QualityInspect;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
 
 @RestController
 @AllArgsConstructor
@@ -44,12 +48,13 @@
     }
 
     /**
-     * 鐢熶骇宸ュ崟娴佽浆鍗℃樉绀哄唴瀹�
+     * 宸ュ崟娴佽浆鍗′笅杞�
+     * @param response
+     * @param productWorkOrder
      */
-    @ApiOperation("鐢熶骇宸ュ崟娴佽浆鍗℃樉绀哄唴瀹�")
-    @GetMapping("/getProductWorkOrderFlowCard")
-    public R getProductWorkOrderFlowCard(Long id) {
-        return R.ok(productWorkOrderservice.getProductWorkOrderFlowCard(id));
+    @PostMapping("/down")
+    public void down(HttpServletResponse response, @RequestBody ProductWorkOrder productWorkOrder) {
+        productWorkOrderservice.down(response, productWorkOrder);
     }
 
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
index 563260d..50a91f5 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
@@ -38,6 +38,6 @@
     @ApiModelProperty(value = "瀹屾垚杩涘害")
     private BigDecimal completionStatus;
 
-    @ApiModelProperty(value = "闄勪欢璇︽儏")
-    private List<ProductWorkOrderFile> productWorkOrderFiles;
+    @ApiModelProperty(value = "鎶ュ簾鏁伴噺")
+    private BigDecimal scrapQty;
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductOrderService.java b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
index 4babc68..39b92d8 100644
--- a/src/main/java/com/ruoyi/production/service/ProductOrderService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -22,6 +22,4 @@
     List<ProcessRoute> listProcessRoute(Long productModelId);
 
     List<ProductStructureDto> listProcessBom(Long orderId);
-
-    List<ProductWorkOrderDto> getProductOrderFlowCard(Long orderId);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java b/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
index 49b4fcc..8ef28e6 100644
--- a/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
@@ -6,11 +6,13 @@
 import com.ruoyi.production.dto.ProductWorkOrderDto;
 import com.ruoyi.production.pojo.ProductWorkOrder;
 
+import javax.servlet.http.HttpServletResponse;
+
 public interface ProductWorkOrderService extends IService<ProductWorkOrder>{
 
     IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder);
 
     int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto);
 
-    ProductWorkOrderDto getProductWorkOrderFlowCard(Long id);
+    void down(HttpServletResponse response, ProductWorkOrder productWorkOrder);
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
index d2cbd73..794eea1 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -42,9 +42,6 @@
     @Autowired
     private ProductWorkOrderMapper productWorkOrderMapper;
 
-    @Autowired
-    private ProductWorkOrderFileMapper productWorkOrderFileMapper;
-
 
     @Override
     public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) {
@@ -115,22 +112,5 @@
     @Override
     public List<ProductStructureDto> listProcessBom(Long orderId) {
         return productOrderMapper.listProcessBom(orderId);
-    }
-
-    @Override
-    public List<ProductWorkOrderDto> getProductOrderFlowCard(Long orderId) {
-        //鏌ヨ璁㈠崟涓嬬殑鎵�鏈夊伐鍗曞苟鎸夌収宸ュ簭鐨勯『搴�
-        List<ProductWorkOrder> productWorkOrders = productWorkOrderMapper.selectList(Wrappers.<ProductWorkOrder>lambdaQuery()
-                .eq(ProductWorkOrder::getProductOrderId, orderId));
-        if (productWorkOrders.size()==0){
-            return null;
-        }
-        List<ProductWorkOrderDto> productWorkOrderDtos = productWorkOrders.stream().map(productWorkOrder -> {
-            ProductWorkOrderDto productWorkOrderFlowCard = productWorkOrderMapper.getProductWorkOrderFlowCard(productWorkOrder.getId());
-            List<ProductWorkOrderFile> productWorkOrderFiles = productWorkOrderFileMapper.selectList(Wrappers.<ProductWorkOrderFile>lambdaQuery().eq(ProductWorkOrderFile::getWorkOrderId, productWorkOrder.getId()));
-            productWorkOrderFlowCard.setProductWorkOrderFiles(productWorkOrderFiles);
-            return productWorkOrderFlowCard;
-        }).collect(Collectors.toList());
-        return productWorkOrderDtos;
     }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
index ec6b8a9..4a68ce8 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -2,28 +2,49 @@
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 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.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.config.Configure;
+import com.deepoove.poi.data.PictureRenderData;
+import com.deepoove.poi.data.Pictures;
+import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
+import com.ruoyi.common.utils.MatrixToImageWriter;
 import com.ruoyi.production.dto.ProductWorkOrderDto;
 import com.ruoyi.production.mapper.ProductWorkOrderFileMapper;
 import com.ruoyi.production.mapper.ProductWorkOrderMapper;
 import com.ruoyi.production.pojo.ProductWorkOrder;
 import com.ruoyi.production.pojo.ProductWorkOrderFile;
 import com.ruoyi.production.service.ProductWorkOrderService;
+import com.ruoyi.quality.pojo.QualityInspectParam;
 import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @Service
-@AllArgsConstructor
 @Transactional(rollbackFor = Exception.class)
 public class ProductWorkOrderServiceImpl extends ServiceImpl<ProductWorkOrderMapper, ProductWorkOrder> implements ProductWorkOrderService {
 
+    @Autowired
     private ProductWorkOrderMapper productWorkOrdermapper;
+    @Autowired
     private ProductWorkOrderFileMapper productWorkOrderFileMapper;
+
+    @Value("${file.temp-dir}")
+    private String tempDir;
 
     @Override
     public IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
@@ -36,11 +57,60 @@
     }
 
     @Override
-    public ProductWorkOrderDto getProductWorkOrderFlowCard(Long id) {
-        ProductWorkOrderDto productWorkOrderFlowCard = productWorkOrdermapper.getProductWorkOrderFlowCard(id);
-        List<ProductWorkOrderFile> productWorkOrderFiles = productWorkOrderFileMapper.selectList(Wrappers.<ProductWorkOrderFile>lambdaQuery().eq(ProductWorkOrderFile::getWorkOrderId, id));
-        productWorkOrderFlowCard.setProductWorkOrderFiles(productWorkOrderFiles);
-        return productWorkOrderFlowCard;
+    public void down(HttpServletResponse response, ProductWorkOrder productWorkOrder) {
+        ProductWorkOrderDto productWorkOrderDto = productWorkOrdermapper.getProductWorkOrderFlowCard(productWorkOrder.getId());
+        String codePath;
+        try {
+            codePath = new MatrixToImageWriter().code(productWorkOrderDto.getId().toString(), tempDir);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        /*鑾峰彇闄勪欢鍥剧墖绫诲瀷*/
+        List<Map<String, Object>> images = new ArrayList<>();
+        List<ProductWorkOrderFile> productWorkOrderFiles = productWorkOrderFileMapper.selectList(Wrappers.<ProductWorkOrderFile>lambdaQuery().eq(ProductWorkOrderFile::getWorkOrderId, productWorkOrder.getId()));
+        if (CollectionUtils.isNotEmpty(productWorkOrderFiles)) {
+            productWorkOrderFiles.forEach(productWorkOrderFile -> {
+                Map<String, Object> image = new HashMap<>();
+                PictureRenderData pictureRenderData = Pictures.ofLocal( productWorkOrderFile.getUrl()).sizeInCm(17, 20).create();
+                image.put("url", pictureRenderData);
+                images.add(image);
+            });
+        }
+        InputStream inputStream = this.getClass().getResourceAsStream("/static/work-order-template.docx");
+        XWPFTemplate template = XWPFTemplate.compile(inputStream).render(
+                new HashMap<String, Object>() {{
+                    put("process", productWorkOrderDto.getProcessName());
+                    put("workOrderNo", productWorkOrderDto.getWorkOrderNo());
+                    put("productOrderNpsNo", productWorkOrderDto.getProductOrderNpsNo());
+                    put("productName", productWorkOrderDto.getProductName());
+                    put("planQuantity", productWorkOrderDto.getPlanQuantity());
+                    put("model", productWorkOrderDto.getModel());
+                    put("completeQuantity", productWorkOrderDto.getCompleteQuantity());
+                    put("scrapQty", productWorkOrderDto.getScrapQty());
+                    put("planStartTime", productWorkOrderDto.getPlanStartTime());
+                    put("planEndTime", productWorkOrderDto.getPlanEndTime());
+                    put("actualStartTime", productWorkOrderDto.getActualStartTime());
+                    put("actualEndTime", productWorkOrderDto.getActualEndTime());
+                    put("twoCode", Pictures.ofLocal(codePath).create());
+                    put("images", images.isEmpty()?null:images);
+                }});
+
+        try {
+            response.setContentType("application/msword");
+            String fileName = URLEncoder.encode(
+                    "娴佽浆鍗�", "UTF-8");
+            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
+            response.setHeader("Content-disposition",
+                    "attachment;filename=" + fileName + ".docx");
+            OutputStream os = response.getOutputStream();
+            template.write(os);
+            os.flush();
+            os.close();
+            inputStream.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("瀵煎嚭澶辫触");
+        }
     }
 
 }
diff --git a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
index d4bb406..6eea92a 100644
--- a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -53,14 +53,23 @@
         pm.unit,
         p.product_name AS productName,
         po.nps_no AS productOrderNpsNo,
-        ROUND(pwo.complete_quantity / pwo.plan_quantity * 100, 2) AS completionStatus
+        ROUND(pwo.complete_quantity / pwo.plan_quantity * 100, 2) AS completionStatus,
+        sum(ppo.scrap_qty) scrapQty
         FROM
         product_work_order pwo
         LEFT JOIN product_process_route_item ppri ON ppri.id = pwo.product_process_route_item_id
+        LEFT JOIN production_product_main ppm ON ppm.work_order_id = pwo.id
+        LEFT JOIN production_product_output ppo ON ppo.product_main_id = ppm.id
         LEFT JOIN product_order po ON po.id = pwo.product_order_id
         LEFT JOIN product_process pp ON pp.id = ppri.process_id
         LEFT JOIN product_model pm ON pm.id = ppri.product_model_id
         LEFT JOIN product p ON p.id = pm.product_id
         WHERE pwo.id = #{id}
+        GROUP BY pwo.id, pwo.product_process_route_item_id, pwo.create_time, pwo.update_time, pwo.work_order_no, pwo.plan_start_time, pwo.plan_end_time, pwo.actual_start_time, pwo.actual_end_time, pwo.status, pwo.tenant_id, pwo.plan_quantity, pwo.product_order_id, pwo.complete_quantity,
+                 pp.NAME ,
+                pm.model,
+                pm.unit,
+                p.product_name,
+                po.nps_no
     </select>
 </mapper>
diff --git a/src/main/resources/static/work-order-template.docx b/src/main/resources/static/work-order-template.docx
new file mode 100644
index 0000000..1bebe87
--- /dev/null
+++ b/src/main/resources/static/work-order-template.docx
Binary files differ

--
Gitblit v1.9.3