From 6248c3f2d94debc1633cfcc66496263cef8b18b3 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期三, 04 二月 2026 14:41:01 +0800
Subject: [PATCH] feat(production): 新增生产订单功能并优化工单号生成逻辑

---
 src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java                   |    2 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java           |   14 +--
 src/main/resources/mapper/production/ProductWorkOrderMapper.xml                         |    8 ++
 src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java         |    6 -
 src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java            |  169 ++++++++++++++++++++++++++++++++++++++++-
 src/main/resources/mapper/production/ProductOrderMapper.xml                             |    7 +
 src/main/java/com/ruoyi/production/controller/ProductOrderController.java               |   11 ++
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java   |    5 +
 src/main/java/com/ruoyi/production/service/ProductOrderService.java                     |    4 +
 src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java |    6 -
 10 files changed, 205 insertions(+), 27 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/controller/ProductOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
index 4beb89f..4cb0c68 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -87,4 +87,15 @@
     }
 
 
+    @ApiOperation("鏂板鐢熶骇璁㈠崟")
+    @PostMapping("addProductOrder")
+    public R addProductOrder(@RequestBody ProductOrder productOrder) {
+        return R.ok(productOrderService.addProductOrder(productOrder));
+    }
+
+    @ApiOperation("鍒犻櫎鐢熶骇璁㈠崟")
+    @DeleteMapping("/{ids}")
+    public R delete(@PathVariable("ids") Long[] ids) {
+        return R.ok(productOrderService.delete(ids));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
index 9d39a77..d637f7d 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -20,4 +20,6 @@
     ProductWorkOrderDto getProductWorkOrderFlowCard(@Param("id") Long id);
 
     List<ProductWorkOrderDto> selectWorkOrderStartStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
+    ProductWorkOrder selectMax(@Param("datePrefix") String datePrefix);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductOrderService.java b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
index 78a3de1..5a714a6 100644
--- a/src/main/java/com/ruoyi/production/service/ProductOrderService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -21,4 +21,8 @@
     List<ProcessRoute> listProcessRoute(Long productModelId);
 
     List<ProductStructureDto> listProcessBom(Long orderId);
+
+    Boolean addProductOrder(ProductOrder productOrder);
+
+    Boolean delete(Long[] id);
 }
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 a6fdd11..33a80c8 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -1,9 +1,14 @@
 package com.ruoyi.production.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
+import com.ruoyi.procurementrecord.utils.StockUtils;
 import com.ruoyi.production.dto.ProductBomDto;
 import com.ruoyi.production.dto.ProductOrderDto;
 import com.ruoyi.production.dto.ProductStructureDto;
@@ -11,12 +16,16 @@
 import com.ruoyi.production.pojo.*;
 import com.ruoyi.production.service.ProcessRouteService;
 import com.ruoyi.production.service.ProductOrderService;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements ProductOrderService {
@@ -39,6 +48,23 @@
     @Autowired
     private ProductWorkOrderMapper productWorkOrderMapper;
 
+    @Autowired
+    private ProductionProductMainMapper productionProductMainMapper;
+
+    @Autowired
+    private ProductionProductOutputMapper productionProductOutputMapper;
+
+    @Autowired
+    private ProductionProductInputMapper productionProductInputMapper;
+
+    @Autowired
+    private QualityInspectMapper qualityInspectMapper;
+
+    @Autowired
+    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+
+    @Autowired
+    private StockUtils stockUtils;
 
     @Override
     public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) {
@@ -69,11 +95,7 @@
             int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
             if (insert > 0) {
                 // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
-                QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
-                queryWrapper.likeRight("work_order_no", datePrefix)
-                        .orderByDesc("work_order_no")
-                        .last("LIMIT 1");
-                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
                 int sequenceNumber = 1; // 榛樿搴忓彿
                 if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                     String lastNo = lastWorkOrder.getWorkOrderNo().toString();
@@ -87,7 +109,7 @@
                     }
                 }
                 // 鐢熸垚瀹屾暣鐨勫伐鍗曞彿
-                String workOrderNoStr ="GD"+ String.format("%s%03d", datePrefix, sequenceNumber);
+                String workOrderNoStr = "GD" + String.format("%s%03d", datePrefix, sequenceNumber);
                 ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                 productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                 productWorkOrder.setProductOrderId(productOrder.getId());
@@ -110,4 +132,139 @@
     public List<ProductStructureDto> listProcessBom(Long orderId) {
         return productOrderMapper.listProcessBom(orderId);
     }
+
+    @Override
+    public Boolean addProductOrder(ProductOrder productOrder) {
+        String string = generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
+        productOrder.setNpsNo(string);
+        productOrder.setCompleteQuantity(BigDecimal.ZERO);
+        this.save(productOrder);
+        if (ObjectUtils.isNotEmpty(productOrder.getRouteId())) {
+            this.bindingRoute(productOrder);
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean delete(Long[] ids) {
+
+        //鎵归噺鏌ヨproductOrder
+        List<ProductOrder> productOrders = productOrderMapper.selectList(
+                new LambdaQueryWrapper<ProductOrder>()
+                        .in(ProductOrder::getId, ids)
+        );
+        if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) {
+
+
+            // 鎵归噺鏌ヨprocessRouteItems
+            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
+                    new LambdaQueryWrapper<ProductProcessRouteItem>()
+                            .in(ProductProcessRouteItem::getProductOrderId, ids)
+            );
+
+            if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(allRouteItems)) {
+                // 鑾峰彇瑕佸垹闄ょ殑宸ュ簭椤笽D
+                List<Long> routeItemIds = allRouteItems.stream()
+                        .map(ProductProcessRouteItem::getId)
+                        .collect(Collectors.toList());
+
+                // 鏌ヨ鍏宠仈鐨勫伐鍗旾D
+                List<ProductWorkOrder> workOrders = productWorkOrderMapper.selectList(
+                        new LambdaQueryWrapper<ProductWorkOrder>()
+                                .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds)
+                );
+                if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(workOrders)) {
+                    List<Long> workOrderIds = workOrders.stream()
+                            .map(ProductWorkOrder::getId)
+                            .collect(Collectors.toList());
+
+                    // 鏌ヨ鍏宠仈鐨勭敓浜т富琛↖D
+                    List<ProductionProductMain> productMains = productionProductMainMapper.selectList(
+                            new LambdaQueryWrapper<ProductionProductMain>()
+                                    .in(ProductionProductMain::getWorkOrderId, workOrderIds)
+                    );
+                    List<Long> productMainIds = productMains.stream()
+                            .map(ProductionProductMain::getId)
+                            .collect(Collectors.toList());
+
+                    // 鍒犻櫎浜у嚭琛ㄣ�佹姇鍏ヨ〃鏁版嵁
+                    if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(productMainIds)) {
+                        productionProductOutputMapper.deleteByProductMainIds(productMainIds);
+                        productionProductInputMapper.deleteByProductMainIds(productMainIds);
+                        List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
+                                new LambdaQueryWrapper<QualityInspect>()
+                                        .in(QualityInspect::getProductMainId, productMainIds)
+                        );
+                        //鍒犻櫎鍑哄簱璁板綍
+                        for (Long productMainId : productMainIds) {
+                            //鍒犻櫎鐢熶骇鍑哄簱璁板綍
+                            stockUtils.deleteStockOutRecord(productMainId, StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
+                            //鍒犻櫎鎶ュ簾鐨勫叆搴撹褰�
+                            stockUtils.deleteStockInRecord(productMainId, StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
+                        }
+                        qualityInspects.forEach(qualityInspect -> {
+                            //inspectState=1 宸叉彁浜� 涓嶈兘鍒犻櫎
+                            if (qualityInspect.getInspectState() == 1) {
+                                throw new RuntimeException("宸叉彁浜ょ殑妫�楠屽崟涓嶈兘鍒犻櫎");
+                            }
+                        });
+                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
+                        salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
+                                .in(SalesLedgerProductionAccounting::getProductMainId, productMainIds));
+                    }
+
+                    // 鍒犻櫎鐢熶骇涓昏〃鏁版嵁
+                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
+
+                    // 鍒犻櫎宸ュ崟鏁版嵁
+                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
+                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
+                }
+            }
+            // 鎵归噺鍒犻櫎processRouteItem
+            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
+                    .in(ProductProcessRouteItem::getProductOrderId, ids));
+
+            // 鎵归噺鍒犻櫎productProcessRoute
+            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
+                    .in(ProductProcessRoute::getProductOrderId, ids));
+
+            // 鎵归噺鍒犻櫎productOrder
+            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
+                    .in(ProductOrder::getId, ids));
+        }
+        return true;
+    }
+
+    //鑾峰彇褰撳墠鐢熶骇璁㈠崟鍙�
+    public String getMaxOrderNoByDate(String datePrefix) {
+        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
+        // 鍖归厤浠� SC + 鏃ユ湡寮�澶寸殑璁㈠崟鍙�
+        queryWrapper.likeRight("nps_no", "SC" + datePrefix);
+        // 鎸夎鍗曞彿鍊掑簭鎺掑垪
+        queryWrapper.orderByDesc("nps_no");
+        queryWrapper.last("LIMIT 1");
+
+        ProductOrder latestOrder = this.getOne(queryWrapper);
+        return latestOrder != null ? latestOrder.getNpsNo() : null;
+    }
+
+    public String generateNextOrderNo(String datePrefix) {
+        String maxOrderNo = getMaxOrderNoByDate(datePrefix);
+        int sequence = 1; // 榛樿璧峰搴忓彿
+        if (maxOrderNo != null && !maxOrderNo.isEmpty()) {
+            // 鎻愬彇娴佹按鍙烽儴鍒嗭紙鍋囪鏍煎紡涓� SC + 鏃ユ湡 + 娴佹按鍙凤級
+            String sequenceStr = maxOrderNo.substring(("SC" + datePrefix).length());
+            try {
+                sequence = Integer.parseInt(sequenceStr) + 1;
+            } catch (NumberFormatException e) {
+                // 寮傚父鎯呭喌涓嬮噸缃负1
+                sequence = 1;
+            }
+        }
+        // 鐢熸垚鏂拌鍗曞彿
+        return "SC" + datePrefix + String.format("%04d", sequence);
+    }
+
+
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
index bbc4b79..c5fbac0 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
@@ -142,11 +142,7 @@
         String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
         if (insert > 0) {
             // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
-            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
-            queryWrapper.likeRight("work_order_no", datePrefix)
-                    .orderByDesc("work_order_no")
-                    .last("LIMIT 1");
-            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
             int sequenceNumber = 1; // 榛樿搴忓彿
             if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                 String lastNo = lastWorkOrder.getWorkOrderNo().toString();
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 71c8690..aa43ebc 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -24,6 +24,8 @@
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.quality.mapper.*;
 import com.ruoyi.quality.pojo.*;
+import com.ruoyi.quality.service.IQualityInspectService;
+import com.ruoyi.quality.service.impl.QualityInspectFileServiceImpl;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -42,6 +44,7 @@
 @Transactional(rollbackFor = Exception.class)
 public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
 
+    private IQualityInspectService qualityInspectService;
     private ProductionProductMainMapper productionProductMainMapper;
 
 
@@ -283,7 +286,9 @@
                     new LambdaQueryWrapper<QualityInspectParam>()
                             .eq(QualityInspectParam::getInspectId, q.getId()));
             qualityInspectMapper.deleteById(q.getId());
+                stockUtils.deleteStockInRecord(q.getId(), StockQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
         });
+
         // 鍒犻櫎浜у嚭璁板綍
         productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
                 .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()));
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
index 68c819c..f70321b 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -98,11 +98,7 @@
                             int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                             if (insert > 0) {
                                 // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
-                                QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
-                                queryWrapper.likeRight("work_order_no", datePrefix)
-                                        .orderByDesc("work_order_no")
-                                        .last("LIMIT 1");
-                                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+                                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
                                 int sequenceNumber = 1; // 榛樿搴忓彿
                                 if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                                     String lastNo = lastWorkOrder.getWorkOrderNo().toString();
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
index f6d6b27..f44d766 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -15,6 +15,7 @@
 import com.ruoyi.production.dto.ProductStructureDto;
 import com.ruoyi.production.mapper.*;
 import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.impl.ProductOrderServiceImpl;
 import com.ruoyi.production.service.impl.SalesLedgerProductionAccountingServiceImpl;
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
@@ -94,7 +95,7 @@
     @Autowired
     private StockInventoryMapper stockInventoryMapper;
     @Autowired
-    private SalesLedgerProductionAccountingServiceImpl salesLedgerProductionAccountingServiceImpl;
+    private ProductOrderServiceImpl productOrderServiceImpl;
 
     @Override
     public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -273,7 +274,8 @@
         productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
         productOrder.setProductModelId(salesLedgerProduct.getProductModelId());
         productOrder.setSaleLedgerProductId(salesLedgerProduct.getId());
-        productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
+        String string = productOrderServiceImpl.generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
+        productOrder.setNpsNo(string);
         productOrder.setQuantity(salesLedgerProduct.getQuantity());//闇�姹傛暟閲�
         productOrder.setCompleteQuantity(BigDecimal.ZERO);//瀹屾垚鏁伴噺
         productOrderMapper.insert(productOrder);
@@ -304,13 +306,7 @@
                 int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                 if (insert > 0) {
                     // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
-                    QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
-                    queryWrapper.likeRight("work_order_no", datePrefix)
-                            .orderByDesc("work_order_no")
-                            .last("LIMIT 1");
-
-                    ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
-
+                    ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
                     int sequenceNumber = 1; // 榛樿搴忓彿
                     if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                         String lastNo = lastWorkOrder.getWorkOrderNo().toString();
diff --git a/src/main/resources/mapper/production/ProductOrderMapper.xml b/src/main/resources/mapper/production/ProductOrderMapper.xml
index ff4b68f..fdcb54e 100644
--- a/src/main/resources/mapper/production/ProductOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -17,8 +17,9 @@
         select po.*,
         sl.sales_contract_no,
         sl.customer_name,
-        slp.product_category,
-        slp.specification_model,
+        p.product_name as product_category,
+        pm.model as specification_model,
+        pm.unit,
         ppr.process_route_code,
         pb.bom_no,
         ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus,
@@ -38,6 +39,8 @@
         FROM shipping_info
         GROUP BY sales_ledger_id
         ) shipping_status_counts ON sl.id = shipping_status_counts.sales_ledger_id
+            left join product_model pm on po.product_model_id = pm.id
+            left join product p on pm.product_id = p.id
         left join sales_ledger_product slp on po.sale_ledger_product_id = slp.id
         left join product_process_route ppr on po.id = ppr.product_order_id
         left join product_bom pb on pb.id = ppr.bom_id
diff --git a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
index fef6bef..14b883e 100644
--- a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -87,4 +87,12 @@
             actual_start_time &gt;= #{startDate}
             AND actual_start_time &lt;= #{endDate}
     </select>
+    <select id="selectMax" resultType="com.ruoyi.production.pojo.ProductWorkOrder">
+        SELECT SUBSTRING(work_order_no, 3) as work_order_no
+        FROM product_work_order
+        WHERE SUBSTRING(work_order_no, 3) like concat(#{datePrefix},'%')
+        order by work_order_no  desc
+        limit 1
+        ;
+    </select>
 </mapper>

--
Gitblit v1.9.3