From 2ab6b6860e4f7bee67a0f66831b9b1fb0f420710 Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期三, 22 四月 2026 10:45:01 +0800
Subject: [PATCH] Merge branch 'dev_New_pro' of http://114.132.189.42:9002/r/product-inventory-management-after into dev_New_pro

---
 src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java                                  |   63 
 src/main/java/com/ruoyi/production/controller/ProductionOperationTaskController.java                 |   64 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java              |   20 
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingServiceImpl.java               |   35 
 src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java                  |   25 
 src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java                               |    8 
 src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingOperationParamController.java    |   70 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java               |   20 
 src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java              |   64 
 src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java                                       |  120 
 src/main/java/com/ruoyi/production/service/ProductionProductMainService.java                         |   28 
 src/main/java/com/ruoyi/production/service/impl/SalesLedgerProductionAccountingServiceImpl.java      |   24 
 src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamDto.java                  |   12 
 src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java                       |  623 -------
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java      |  140 +
 src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java                  |   58 
 src/main/resources/mapper/production/ProductionAccountMapper.xml                                     |   20 
 src/main/java/com/ruoyi/production/bean/dto/ProductStructureDto.java                                 |   21 
 src/main/java/com/ruoyi/production/service/ProductionProductInputService.java                        |   13 
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java                      |  313 ++++
 src/main/java/com/ruoyi/production/service/ProductionOrderService.java                               |   25 
 src/main/java/com/ruoyi/safe/controller/SafeCertificationFileController.java                         |    5 
 src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java                     |   17 
 src/main/java/com/ruoyi/production/controller/ProductionOrderController.java                         |   70 
 src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationParamService.java          |   19 
 src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java                                 |   65 
 src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java                                 |   67 
 src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamSyncDto.java              |   16 
 src/main/java/com/ruoyi/home/dto/ProductionProgressOrderDto.java                                     |   57 
 src/main/java/com/ruoyi/production/bean/vo/ProductionOrderRoutingOperationParamVo.java               |    8 
 src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java |  208 ++
 src/main/java/com/ruoyi/production/service/ProductionOrderRoutingService.java                        |   14 
 src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java                           |   34 
 src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java                       |   13 
 src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java                                 |   14 
 src/main/java/com/ruoyi/production/service/SalesLedgerProductionAccountingService.java               |    8 
 src/main/java/com/ruoyi/technology/controller/TechnologyBomController.java                           |    6 
 src/main/resources/mapper/production/ProductionOperationTaskMapper.xml                               |   64 
 src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java                      |  221 +-
 src/main/java/com/ruoyi/production/controller/ProductionPlanController.java                          |    2 
 src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java                                   |   87 
 src/main/java/com/ruoyi/production/service/ProductionPlanService.java                                |    4 
 src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java                          |    8 
 src/main/java/com/ruoyi/production/service/ProductionOperationTaskService.java                       |   24 
 src/main/resources/mapper/production/ProductionPlanMapper.xml                                        |   98 +
 src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamSyncDto.java         |   11 
 src/main/java/com/ruoyi/production/bean/vo/ProductionOperationTaskVo.java                            |    8 
 src/main/java/com/ruoyi/production/bean/dto/ProductionOrderDto.java                                  |    8 
 src/main/java/com/ruoyi/production/bean/dto/ProductionPlanDto.java                                   |    7 
 src/main/resources/mapper/production/ProductionProductInputMapper.xml                                |   26 
 src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java                            |   39 
 src/main/java/com/ruoyi/production/bean/vo/ProductionOrderVo.java                                    |    8 
 src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java                   |   96 +
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java                        |  293 +--
 src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java                           |    3 
 src/main/java/com/ruoyi/home/dto/ProductionProgressDto.java                                          |    5 
 src/main/resources/mapper/production/ProductionProductOutputMapper.xml                               |   43 
 src/main/java/com/ruoyi/production/pojo/ProductionPlan.java                                          |    2 
 src/main/java/com/ruoyi/basic/dto/ProductModelDto.java                                               |    2 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java                               |   13 
 src/main/java/com/ruoyi/production/bean/dto/BomImportDto.java                                        |   30 
 src/main/java/com/ruoyi/technology/service/TechnologyBomService.java                                 |    4 
 src/main/java/com/ruoyi/home/dto/ProductionTurnoverDto.java                                          |    2 
 src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamDto.java             |    8 
 src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java                         |   24 
 src/main/java/com/ruoyi/production/bean/dto/SalesLedgerProductionAccountingDto.java                  |   14 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java                |  345 ++++
 src/main/java/com/ruoyi/production/bean/dto/ProductionProductInputDto.java                           |   27 
 src/main/resources/mapper/production/ProductionOrderMapper.xml                                       |   48 
 src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java                        |   21 
 src/main/java/com/ruoyi/home/dto/ProductionTaskStatisticsDto.java                                    |   50 
 src/main/java/com/ruoyi/technology/bean/vo/TechnologyRoutingOperationParamVo.java                    |   12 
 src/main/java/com/ruoyi/production/bean/dto/ProductionProductOutputDto.java                          |   25 
 /dev/null                                                                                            |   59 
 src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java               |   14 
 src/main/java/com/ruoyi/safe/controller/SafeCertificationController.java                             |    5 
 src/main/java/com/ruoyi/production/bean/dto/UserAccountDto.java                                      |   11 
 src/main/java/com/ruoyi/production/mapper/ProductionPlanMapper.java                                  |   12 
 src/main/java/com/ruoyi/technology/bean/dto/BomImportDto.java                                        |   37 
 src/main/resources/mapper/production/ProductionProductMainMapper.xml                                 |   93 +
 src/main/java/com/ruoyi/production/bean/dto/UserProductionAccountingDto.java                         |    9 
 src/main/java/com/ruoyi/production/pojo/ProductionOrder.java                                         |   14 
 src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java                          |   22 
 src/main/java/com/ruoyi/production/mapper/ProductionOperationTaskMapper.java                         |   18 
 src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java                 |   25 
 src/main/resources/application.yml                                                                   |    2 
 src/main/java/com/ruoyi/production/mapper/ProductionAccountMapper.java                               |    8 
 87 files changed, 3,037 insertions(+), 1,361 deletions(-)

diff --git a/src/main/java/com/ruoyi/basic/dto/ProductModelDto.java b/src/main/java/com/ruoyi/basic/dto/ProductModelDto.java
index 53b3b5d..4a88508 100644
--- a/src/main/java/com/ruoyi/basic/dto/ProductModelDto.java
+++ b/src/main/java/com/ruoyi/basic/dto/ProductModelDto.java
@@ -1,7 +1,7 @@
 package com.ruoyi.basic.dto;
 
 import com.ruoyi.basic.pojo.ProductModel;
-import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.bean.dto.ProductStructureDto;
 import lombok.Data;
 
 import java.util.List;
diff --git a/src/main/java/com/ruoyi/home/dto/ProductionProgressDto.java b/src/main/java/com/ruoyi/home/dto/ProductionProgressDto.java
index 88fe4b6..46373b2 100644
--- a/src/main/java/com/ruoyi/home/dto/ProductionProgressDto.java
+++ b/src/main/java/com/ruoyi/home/dto/ProductionProgressDto.java
@@ -1,11 +1,8 @@
 package com.ruoyi.home.dto;
-
-import com.ruoyi.production.dto.ProductOrderDto;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
-import java.math.BigDecimal;
 import java.util.List;
 
 @Data
@@ -21,5 +18,5 @@
     @ApiModelProperty("閮ㄥ垎瀹屾垚璁㈠崟鏁�")
     private Long partialCompletedOrderCount;
     @ApiModelProperty("璁㈠崟璇︽儏")
-    private List<ProductOrderDto> completedOrderDetails;
+    private List<ProductionProgressOrderDto> completedOrderDetails;
 }
diff --git a/src/main/java/com/ruoyi/home/dto/ProductionProgressOrderDto.java b/src/main/java/com/ruoyi/home/dto/ProductionProgressOrderDto.java
new file mode 100644
index 0000000..a219e3d
--- /dev/null
+++ b/src/main/java/com/ruoyi/home/dto/ProductionProgressOrderDto.java
@@ -0,0 +1,57 @@
+package com.ruoyi.home.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@Data
+public class ProductionProgressOrderDto {
+
+    @ApiModelProperty("鐢熶骇璁㈠崟鍙�")
+    private String npsNo;
+
+    @ApiModelProperty("閿�鍞悎鍚屽彿")
+    private String salesContractNo;
+
+    @ApiModelProperty("椤圭洰鍚嶇О")
+    private String projectName;
+
+    @ApiModelProperty("瀹㈡埛鍚嶇О")
+    private String customerName;
+
+    @ApiModelProperty("浜у搧鍚嶇О")
+    private String productCategory;
+
+    @ApiModelProperty("瑙勬牸鍨嬪彿")
+    private String specificationModel;
+
+    @ApiModelProperty("宸ヨ壓璺嚎缂栧彿")
+    private String processRouteCode;
+
+    @ApiModelProperty("闇�姹傛暟閲�")
+    private BigDecimal quantity;
+
+    @ApiModelProperty("瀹屾垚鏁伴噺")
+    private BigDecimal completeQuantity;
+
+    @ApiModelProperty("瀹屾垚杩涘害")
+    private BigDecimal completionStatus;
+
+    @ApiModelProperty("BOM缂栧彿")
+    private String bomNo;
+
+    @ApiModelProperty("浜ゆ湡鍋忓樊")
+    private Integer deliveryDaysDiff;
+
+    @ApiModelProperty("浜ゆ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate deliveryDate;
+
+    @ApiModelProperty("鏄惁鍙戣揣")
+    private Boolean isFh;
+}
diff --git a/src/main/java/com/ruoyi/home/dto/ProductionTaskStatisticsDto.java b/src/main/java/com/ruoyi/home/dto/ProductionTaskStatisticsDto.java
new file mode 100644
index 0000000..dcde43f
--- /dev/null
+++ b/src/main/java/com/ruoyi/home/dto/ProductionTaskStatisticsDto.java
@@ -0,0 +1,50 @@
+package com.ruoyi.home.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@Data
+public class ProductionTaskStatisticsDto {
+
+    @ApiModelProperty("宸ュ崟ID")
+    private Long id;
+
+    @ApiModelProperty("宸ュ崟缂栧彿")
+    private String workOrderNo;
+
+    @ApiModelProperty("璁″垝寮�濮嬫椂闂�")
+    private LocalDate planStartTime;
+
+    @ApiModelProperty("璁″垝缁撴潫鏃堕棿")
+    private LocalDate planEndTime;
+
+    @ApiModelProperty("瀹為檯寮�濮嬫椂闂�")
+    private LocalDate actualStartTime;
+
+    @ApiModelProperty("瀹為檯缁撴潫鏃堕棿")
+    private LocalDate actualEndTime;
+
+    @ApiModelProperty("璁″垝鏁伴噺")
+    private BigDecimal planQuantity;
+
+    @ApiModelProperty("瀹屾垚鏁伴噺")
+    private BigDecimal completeQuantity;
+
+    @ApiModelProperty("宸ュ簭鍚嶇О")
+    private String processName;
+
+    @ApiModelProperty("浜у搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty("瑙勬牸鍨嬪彿")
+    private String model;
+
+    @ApiModelProperty("鍗曚綅")
+    private String unit;
+
+    @ApiModelProperty("鐢熶骇璁㈠崟鍙�")
+    private String productOrderNpsNo;
+}
diff --git a/src/main/java/com/ruoyi/home/dto/ProductionTurnoverDto.java b/src/main/java/com/ruoyi/home/dto/ProductionTurnoverDto.java
index 41ad82b..80af148 100644
--- a/src/main/java/com/ruoyi/home/dto/ProductionTurnoverDto.java
+++ b/src/main/java/com/ruoyi/home/dto/ProductionTurnoverDto.java
@@ -1,6 +1,4 @@
 package com.ruoyi.home.dto;
-
-import com.ruoyi.production.dto.ProductOrderDto;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
diff --git a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
index 2d3e608..628dfd5 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3,16 +3,13 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.mapper.AccountExpenseMapper;
 import com.ruoyi.account.mapper.AccountIncomeMapper;
 import com.ruoyi.account.pojo.AccountExpense;
-import com.ruoyi.home.mapper.HomeMapper;
-import com.ruoyi.account.mapper.AccountExpenseMapper;
 import com.ruoyi.approve.mapper.ApproveProcessMapper;
 import com.ruoyi.approve.pojo.ApproveProcess;
 import com.ruoyi.basic.mapper.CustomerMapper;
 import com.ruoyi.basic.mapper.ProductMapper;
-import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.mapper.SupplierManageMapper;
 import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.basic.pojo.Product;
@@ -27,20 +24,10 @@
 import com.ruoyi.dto.MapDto;
 import com.ruoyi.framework.security.LoginUser;
 import com.ruoyi.home.dto.*;
+import com.ruoyi.home.mapper.HomeMapper;
 import com.ruoyi.home.service.HomeService;
-import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
-import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
-import com.ruoyi.procurementrecord.utils.StockUtils;
-import com.ruoyi.production.dto.ProductOrderDto;
-import com.ruoyi.production.dto.ProductWorkOrderDto;
-import com.ruoyi.production.mapper.ProductOrderMapper;
-import com.ruoyi.production.mapper.ProductProcessMapper;
-import com.ruoyi.production.mapper.ProductWorkOrderMapper;
-import com.ruoyi.production.mapper.ProductionProductInputMapper;
-import com.ruoyi.production.mapper.ProductionProductOutputMapper;
-import com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper;
-import com.ruoyi.production.pojo.ProductProcess;
-import com.ruoyi.production.pojo.ProductWorkOrder;
+import com.ruoyi.production.bean.dto.ProductionProductOutputDto;
+import com.ruoyi.production.mapper.*;
 import com.ruoyi.project.system.domain.SysDept;
 import com.ruoyi.project.system.mapper.SysDeptMapper;
 import com.ruoyi.purchase.mapper.PaymentRegistrationMapper;
@@ -114,10 +101,7 @@
     private NoticeMapper noticeMapper;
 
     @Autowired
-    private ProductOrderMapper productOrderMapper;
-
-    @Autowired
-    private ProductWorkOrderMapper productWorkOrderMapper;
+    private ProductionOrderMapper productionOrderMapper;
 
     @Autowired
     private ProductMapper productMapper;
@@ -144,7 +128,7 @@
     private QualityUnqualifiedMapper qualityUnqualifiedMapper;
 
     @Autowired
-    private ProductProcessMapper productProcessMapper;
+    private ProductionOperationTaskMapper productionOperationTaskMapper;
     
     @Autowired
     private AccountExpenseMapper accountExpenseMapper;
@@ -560,18 +544,15 @@
     @Override
     public ProductionProgressDto productionProgress() {
         ProductionProgressDto productionProgressDto = new ProductionProgressDto();
-        ProductOrderDto orderDto = new ProductOrderDto();
-        orderDto.setStartTime(LocalDateTime.now().minusMonths(1));
-        orderDto.setEndTime(LocalDateTime.now());
-        List<ProductOrderDto> productOrderDtos = productOrderMapper.pageProductOrder(new Page<>(1, -1), orderDto)
-                .getRecords();
-        productionProgressDto.setCompletedOrderDetails(productOrderDtos);
-        long totalCount = productOrderDtos.size();
-        long count = productOrderDtos.stream().filter(
-                        productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(productOrderDto.getQuantity()) >= 0)
+        List<ProductionProgressOrderDto> orderDetails = productionOrderMapper.selectProgressOrders(
+                LocalDateTime.now().minusMonths(1), LocalDateTime.now());
+        productionProgressDto.setCompletedOrderDetails(orderDetails);
+        long totalCount = orderDetails.size();
+        long count = orderDetails.stream().filter(
+                        item -> defaultDecimal(item.getCompleteQuantity()).compareTo(defaultDecimal(item.getQuantity())) >= 0)
                 .count();
-        long count2 = productOrderDtos.stream()
-                .filter(productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(BigDecimal.ZERO) == 0)
+        long count2 = orderDetails.stream()
+                .filter(item -> defaultDecimal(item.getCompleteQuantity()).compareTo(BigDecimal.ZERO) == 0)
                 .count();
         productionProgressDto.setTotalOrderCount(totalCount);
         productionProgressDto.setCompletedOrderCount(count);
@@ -583,15 +564,11 @@
     @Override
     public ProductionTurnoverDto workInProcessTurnover() {
         ProductionTurnoverDto productionTurnoverDto = new ProductionTurnoverDto();
-        ProductWorkOrderDto workOrder = new ProductWorkOrderDto();
-        workOrder.setPlanStartTime(LocalDate.now().minusMonths(1));
-        workOrder.setPlanEndTime(LocalDate.now());
-        List<ProductWorkOrderDto> productWorkOrders = productWorkOrderMapper
-                .pageProductWorkOrder(new Page<>(1, -1), workOrder).getRecords();
-        long sum = productWorkOrders.stream()
-                .filter(productWorkOrder -> productWorkOrder.getPlanQuantity()
-                        .compareTo(productWorkOrder.getCompleteQuantity()) > 0)
-                .map(ProductWorkOrder::getPlanQuantity)
+        List<ProductionTaskStatisticsDto> taskList = productionOperationTaskMapper
+                .selectTaskStatisticsByDate(LocalDate.now().minusMonths(1), LocalDate.now());
+        long sum = taskList.stream()
+                .filter(task -> defaultDecimal(task.getPlanQuantity()).compareTo(defaultDecimal(task.getCompleteQuantity())) > 0)
+                .map(ProductionTaskStatisticsDto::getPlanQuantity)
                 .mapToLong(BigDecimal::longValue)
                 .sum();
         if (sum == 0)
@@ -600,23 +577,21 @@
         productionTurnoverDto.setAverageTurnoverDays(BigDecimal.valueOf(sum).divide(
                 BigDecimal.valueOf(ChronoUnit.DAYS.between(LocalDateTime.now().minusMonths(1), LocalDateTime.now())), 2,
                 RoundingMode.HALF_UP));
-        long completeQuantity = productWorkOrders.stream()
-                .filter(productWorkOrder -> productWorkOrder.getCompleteQuantity()
-                        .compareTo(productWorkOrder.getPlanQuantity()) >= 0)
-                .map(ProductWorkOrder::getCompleteQuantity)
+        long completeQuantity = taskList.stream()
+                .filter(task -> defaultDecimal(task.getCompleteQuantity()).compareTo(defaultDecimal(task.getPlanQuantity())) >= 0)
+                .map(ProductionTaskStatisticsDto::getCompleteQuantity)
                 .mapToLong(BigDecimal::longValue)
                 .sum();
         productionTurnoverDto.setTurnoverEfficiency(
                 BigDecimal.valueOf(completeQuantity).divide(BigDecimal.valueOf(sum), 2, RoundingMode.HALF_UP));
-        Map<String, List<ProductWorkOrderDto>> map = productWorkOrders.stream()
-                .filter(productWorkOrder -> productWorkOrder.getPlanQuantity()
-                        .compareTo(productWorkOrder.getCompleteQuantity()) > 0)
-                .collect(Collectors.groupingBy(ProductWorkOrderDto::getProcessName));
+        Map<String, List<ProductionTaskStatisticsDto>> map = taskList.stream()
+                .filter(task -> defaultDecimal(task.getPlanQuantity()).compareTo(defaultDecimal(task.getCompleteQuantity())) > 0)
+                .collect(Collectors.groupingBy(ProductionTaskStatisticsDto::getProcessName));
         List<String> strings = new ArrayList<>();
         List<Long> processQuantityDetails = new ArrayList<>();
         map.entrySet().stream().forEach(entry -> {
             String key = entry.getKey();
-            long completeSum = entry.getValue().stream().map(ProductWorkOrderDto::getCompleteQuantity)
+            long completeSum = entry.getValue().stream().map(ProductionTaskStatisticsDto::getCompleteQuantity)
                     .mapToLong(BigDecimal::longValue).sum();
             strings.add(key);
             processQuantityDetails.add(completeSum);
@@ -1610,12 +1585,7 @@
                 break;
         }
 
-        ProductWorkOrderDto queryDto = new ProductWorkOrderDto();
-        queryDto.setPlanStartTime(startDate);
-        queryDto.setPlanEndTime(endDate);
-
-        List<ProductWorkOrderDto> list = productWorkOrderMapper.pageProductWorkOrder(new Page<>(1, -1), queryDto)
-                .getRecords();
+        List<ProductionTaskStatisticsDto> list = productionOperationTaskMapper.selectTaskStatisticsByDate(startDate, endDate);
 
         if (CollectionUtils.isEmpty(list)) {
             return new ArrayList<>();
@@ -1624,9 +1594,9 @@
         Map<String, BigDecimal> processOutputMap = list.stream()
                 .filter(item -> item.getProcessName() != null && item.getCompleteQuantity() != null)
                 .collect(Collectors.groupingBy(
-                        ProductWorkOrderDto::getProcessName,
+                        ProductionTaskStatisticsDto::getProcessName,
                         Collectors.reducing(BigDecimal.ZERO,
-                                ProductWorkOrderDto::getCompleteQuantity,
+                                ProductionTaskStatisticsDto::getCompleteQuantity,
                                 BigDecimal::add)));
 
         BigDecimal total = processOutputMap.values().stream()
@@ -1680,17 +1650,17 @@
         String startStr = startDate.atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         String endStr = endDate.atTime(LocalTime.MAX).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
 
-        List<ProductWorkOrderDto> startList = productWorkOrderMapper.selectWorkOrderStartStats(startStr, endStr);
+        List<ProductionTaskStatisticsDto> startList = productionOperationTaskMapper.selectTaskStartStats(startStr, endStr);
 
-        List<com.ruoyi.production.dto.ProductionProductOutputDto> outputList = productionProductOutputMapper
+        List<ProductionProductOutputDto> outputList = productionProductOutputMapper
                 .selectOutputStats(startStr, endStr);
 
         Map<String, WorkOrderEfficiencyDto> dateMap = new HashMap<>();
 
         if (!CollectionUtils.isEmpty(startList)) {
-            for (ProductWorkOrderDto item : startList) {
-                if (item.getPlanStartTime() != null) {
-                    String date = item.getPlanStartTime().toString();
+            for (ProductionTaskStatisticsDto item : startList) {
+                if (item.getActualStartTime() != null) {
+                    String date = item.getActualStartTime().toString();
                     WorkOrderEfficiencyDto dto = dateMap.getOrDefault(date, new WorkOrderEfficiencyDto());
                     dto.setDate(date);
                     BigDecimal qty = item.getPlanQuantity() != null ? item.getPlanQuantity() : BigDecimal.ZERO;
@@ -1702,7 +1672,7 @@
 
         // 瀹屽伐鏁伴噺鍜岃壇鍝佺巼
         if (!CollectionUtils.isEmpty(outputList)) {
-            for (com.ruoyi.production.dto.ProductionProductOutputDto item : outputList) {
+            for (ProductionProductOutputDto item : outputList) {
                 if (item.getCreateTime() != null) {
                     String date = item.getCreateTime().toLocalDate().toString();
                     WorkOrderEfficiencyDto dto = dateMap.getOrDefault(date, new WorkOrderEfficiencyDto());
@@ -1776,7 +1746,7 @@
     }
 
     @Autowired
-    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+    private ProductionAccountMapper salesLedgerProductionAccountingMapper;
 
     @Override
     public List<ProductionAccountingDto> productionAccountingAnalysis(Integer type) {
@@ -1841,16 +1811,16 @@
         String lastEnd = lastMonthDate.withDayOfMonth(lastMonthDate.lengthOfMonth()).atTime(LocalTime.MAX)
                 .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
 
-        int currentCreated = productOrderMapper.countCreated(currentStart, currentEnd);
-        int lastCreated = productOrderMapper.countCreated(lastStart, lastEnd);
+        int currentCreated = productionOrderMapper.countCreated(currentStart, currentEnd);
+        int lastCreated = productionOrderMapper.countCreated(lastStart, lastEnd);
         MapDto createdDto = createOrderCountDto("鐢熶骇璁㈠崟鏁�", currentCreated, lastCreated);
 
-        int currentCompleted = productOrderMapper.countCompleted(currentStart, currentEnd);
-        int lastCompleted = productOrderMapper.countCompleted(lastStart, lastEnd);
+        int currentCompleted = productionOrderMapper.countCompleted(currentStart, currentEnd);
+        int lastCompleted = productionOrderMapper.countCompleted(lastStart, lastEnd);
         MapDto completedDto = createOrderCountDto("宸插畬鎴愯鍗曟暟", currentCompleted, lastCompleted);
 
-        int currentPending = productOrderMapper.countPending(currentStart, currentEnd);
-        int lastPending = productOrderMapper.countPending(lastStart, lastEnd);
+        int currentPending = productionOrderMapper.countPending(currentStart, currentEnd);
+        int lastPending = productionOrderMapper.countPending(lastStart, lastEnd);
         MapDto pendingDto = createOrderCountDto("寰呯敓浜ц鍗曟暟", currentPending, lastPending);
 
         return Arrays.asList(createdDto, completedDto, pendingDto);
@@ -2510,6 +2480,10 @@
         LocalDateTime startDateTime = startDate.atStartOfDay();
         LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);
 
-        return productProcessMapper.calculateProductionStatistics(startDateTime, endDateTime, userId, processIds);
+        return productionOperationTaskMapper.calculateProductionStatistics(startDateTime, endDateTime, userId, processIds);
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
     }
 }
diff --git a/src/main/java/com/ruoyi/production/bean/dto/BomImportDto.java b/src/main/java/com/ruoyi/production/bean/dto/BomImportDto.java
new file mode 100644
index 0000000..4557cf7
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/BomImportDto.java
@@ -0,0 +1,30 @@
+package com.ruoyi.production.bean.dto;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class BomImportDto {
+    @Excel(name = "鐖朵骇鍝佸悕绉�")
+    private String parentName;
+
+    @Excel(name = "鐖朵骇鍝佽鏍�")
+    private String parentSpec;
+
+    @Excel(name = "瀛愪骇鍝佸悕绉�")
+    private String childName;
+
+    @Excel(name = "瀛愪骇鍝佽鏍�")
+    private String childSpec;
+
+    @Excel(name = "鍗曚綅鐢ㄩ噺")
+    private BigDecimal unitQty;
+
+    @Excel(name = "宸ュ簭")
+    private String process;
+
+    @Excel(name = "澶囨敞")
+    private String remark;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductStructureDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductStructureDto.java
new file mode 100644
index 0000000..0bb4230
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductStructureDto.java
@@ -0,0 +1,21 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class ProductStructureDto {
+    private Long id;
+    private Long bomId;
+    private Long parentId;
+    private Long productModelId;
+    private BigDecimal unitQuantity;
+    private String unit;
+    private Long processId;
+    private String processName;
+    private String productName;
+    private String model;
+    private List<ProductStructureDto> children;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java
new file mode 100644
index 0000000..906d1f6
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionOperationTaskDto.java
@@ -0,0 +1,8 @@
+package com.ruoyi.production.bean.dto;
+
+import com.ruoyi.production.pojo.ProductionOperationTask;
+import lombok.Data;
+
+@Data
+public class ProductionOperationTaskDto extends ProductionOperationTask {
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderDto.java
new file mode 100644
index 0000000..c99a633
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderDto.java
@@ -0,0 +1,8 @@
+package com.ruoyi.production.bean.dto;
+
+import com.ruoyi.production.pojo.ProductionOrder;
+import lombok.Data;
+
+@Data
+public class ProductionOrderDto extends ProductionOrder {
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamDto.java
new file mode 100644
index 0000000..e89cc1a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamDto.java
@@ -0,0 +1,8 @@
+package com.ruoyi.production.bean.dto;
+
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
+import lombok.Data;
+
+@Data
+public class ProductionOrderRoutingOperationParamDto extends ProductionOrderRoutingOperationParam {
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamSyncDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamSyncDto.java
new file mode 100644
index 0000000..044ae7f
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionOrderRoutingOperationParamSyncDto.java
@@ -0,0 +1,11 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+@Data
+public class ProductionOrderRoutingOperationParamSyncDto {
+
+    private Long productionOrderRoutingOperationId;
+
+    private Boolean replaceExisting;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanDto.java
index 78802c1..5e0074f 100644
--- a/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanDto.java
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionPlanDto.java
@@ -58,4 +58,11 @@
     @ApiModelProperty("鍏宠仈鐗╂枡淇℃伅琛↖D")
     private Long productMaterialId;
 
+    /**
+     * 寮哄害
+     */
+    @ApiModelProperty("寮哄害")
+    @Excel(name = "寮哄害")
+    private String strength;
+
 }
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionProductInputDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionProductInputDto.java
new file mode 100644
index 0000000..f1435d8
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionProductInputDto.java
@@ -0,0 +1,27 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+public class ProductionProductInputDto {
+    private Long id;
+    private Long productMainId;
+    private Long productionProductMainId;
+    private Long productModelId;
+    private BigDecimal quantity;
+    private BigDecimal inputQuantity;
+    private LocalDateTime createTime;
+    private LocalDateTime updateTime;
+    private Long tenantId;
+    private Integer createUser;
+    private Integer updateUser;
+    private Long deptId;
+
+    private String productNo;
+    private String model;
+    private String productName;
+    private String unit;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java
new file mode 100644
index 0000000..1712d72
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java
@@ -0,0 +1,39 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
+public class ProductionProductMainDto {
+    private Long id;
+    private String productNo;
+    private Long userId;
+    private String userName;
+    private Long productProcessRouteItemId;
+    private Long workOrderId;
+    private Long productionOperationTaskId;
+    private Integer status;
+    private LocalDateTime createTime;
+    private LocalDateTime updateTime;
+    private Long tenantId;
+    private Integer createUser;
+    private Integer updateUser;
+    private Long deptId;
+
+    private String workOrderNo;
+    private String workOrderStatus;
+    private String nickName;
+    private BigDecimal quantity;
+    private BigDecimal scrapQty;
+    private String productName;
+    private String productModelName;
+    private String unit;
+    private String salesContractNo;
+    private LocalDate schedulingDate;
+    private String schedulingUserName;
+    private String customerName;
+    private String process;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/ProductionProductOutputDto.java b/src/main/java/com/ruoyi/production/bean/dto/ProductionProductOutputDto.java
new file mode 100644
index 0000000..0363ea9
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/ProductionProductOutputDto.java
@@ -0,0 +1,25 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+public class ProductionProductOutputDto {
+    private Long id;
+    private Long productMainId;
+    private Long productionProductMainId;
+    private Long productModelId;
+    private BigDecimal quantity;
+    private BigDecimal scrapQty;
+    private LocalDateTime createTime;
+    private LocalDateTime updateTime;
+    private Long tenantId;
+    private Integer createUser;
+    private Integer updateUser;
+    private Long deptId;
+
+    private String productNo;
+    private String model;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/SalesLedgerProductionAccountingDto.java b/src/main/java/com/ruoyi/production/bean/dto/SalesLedgerProductionAccountingDto.java
new file mode 100644
index 0000000..2270368
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/SalesLedgerProductionAccountingDto.java
@@ -0,0 +1,14 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+
+@Data
+public class SalesLedgerProductionAccountingDto {
+    private Long userId;
+    private String userName;
+    private String process;
+    private LocalDate startDate;
+    private LocalDate endDate;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/UserAccountDto.java b/src/main/java/com/ruoyi/production/bean/dto/UserAccountDto.java
new file mode 100644
index 0000000..5ac89c7
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/UserAccountDto.java
@@ -0,0 +1,11 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class UserAccountDto {
+    private BigDecimal account = BigDecimal.ZERO;
+    private BigDecimal accountBalance = BigDecimal.ZERO;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/dto/UserProductionAccountingDto.java b/src/main/java/com/ruoyi/production/bean/dto/UserProductionAccountingDto.java
new file mode 100644
index 0000000..3541487
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/dto/UserProductionAccountingDto.java
@@ -0,0 +1,9 @@
+package com.ruoyi.production.bean.dto;
+
+import lombok.Data;
+
+@Data
+public class UserProductionAccountingDto {
+    private Long userId;
+    private String date;
+}
diff --git a/src/main/java/com/ruoyi/production/bean/vo/ProductionOperationTaskVo.java b/src/main/java/com/ruoyi/production/bean/vo/ProductionOperationTaskVo.java
new file mode 100644
index 0000000..eed3a31
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/vo/ProductionOperationTaskVo.java
@@ -0,0 +1,8 @@
+package com.ruoyi.production.bean.vo;
+
+import com.ruoyi.production.pojo.ProductionOperationTask;
+import lombok.Data;
+
+@Data
+public class ProductionOperationTaskVo extends ProductionOperationTask {
+}
diff --git a/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderRoutingOperationParamVo.java b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderRoutingOperationParamVo.java
new file mode 100644
index 0000000..e0819da
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderRoutingOperationParamVo.java
@@ -0,0 +1,8 @@
+package com.ruoyi.production.bean.vo;
+
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
+import lombok.Data;
+
+@Data
+public class ProductionOrderRoutingOperationParamVo extends ProductionOrderRoutingOperationParam {
+}
diff --git a/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderVo.java b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderVo.java
new file mode 100644
index 0000000..d8820d0
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/bean/vo/ProductionOrderVo.java
@@ -0,0 +1,8 @@
+package com.ruoyi.production.bean.vo;
+
+import com.ruoyi.production.pojo.ProductionOrder;
+import lombok.Data;
+
+@Data
+public class ProductionOrderVo extends ProductionOrder {
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionOperationTaskController.java b/src/main/java/com/ruoyi/production/controller/ProductionOperationTaskController.java
index 1c9922f..f03f46b 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionOperationTaskController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionOperationTaskController.java
@@ -1,18 +1,66 @@
 package com.ruoyi.production.controller;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.bean.dto.ProductionOperationTaskDto;
+import com.ruoyi.production.bean.vo.ProductionOperationTaskVo;
+import com.ruoyi.production.pojo.ProductionOperationTask;
+import com.ruoyi.production.service.ProductionOperationTaskService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-/**
- * <p>
- * 鐢熶骇宸ュ崟琛� 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
 @RestController
 @RequestMapping("/productionOperationTask")
+@Api(tags = "鐢熶骇宸ュ崟")
+@RequiredArgsConstructor
 public class ProductionOperationTaskController {
 
+    private final ProductionOperationTaskService productionOperationTaskService;
+
+    @GetMapping("/page")
+    @ApiOperation("鍒嗛〉鏌ヨ")
+    public R page(Page<ProductionOperationTaskDto> page, ProductionOperationTaskDto dto) {
+        return R.ok(productionOperationTaskService.pageProductionOperationTask(page, dto));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("宸ュ崟鍒楄〃")
+    public R<List<ProductionOperationTaskVo>> list(ProductionOperationTaskDto dto) {
+        return R.ok(productionOperationTaskService.listProductionOperationTask(dto));
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation("宸ュ崟璇︽儏")
+    public R<ProductionOperationTaskVo> getInfo(@PathVariable("id") Long id) {
+        return R.ok(productionOperationTaskService.getProductionOperationTaskInfo(id));
+    }
+
+    @PostMapping
+    @ApiOperation("鏂板宸ュ崟")
+    public R<Boolean> add(@RequestBody ProductionOperationTask productionOperationTask) {
+        return R.ok(productionOperationTaskService.saveProductionOperationTask(productionOperationTask));
+    }
+
+    @PutMapping
+    @ApiOperation("淇敼宸ュ崟")
+    public R<Boolean> edit(@RequestBody ProductionOperationTask productionOperationTask) {
+        return R.ok(productionOperationTaskService.saveProductionOperationTask(productionOperationTask));
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("鍒犻櫎宸ュ崟")
+    public R<Boolean> remove(@RequestBody List<Long> ids) {
+        return R.ok(productionOperationTaskService.removeProductionOperationTask(ids));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
index 00dcabe..9558c8d 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionOrderController.java
@@ -1,18 +1,72 @@
 package com.ruoyi.production.controller;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.bean.dto.ProductionOrderDto;
+import com.ruoyi.production.bean.vo.ProductionOrderVo;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.service.ProductionOrderService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟琛� 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
 @RestController
 @RequestMapping("/productionOrder")
+@Api(tags = "鐢熶骇璁㈠崟")
+@RequiredArgsConstructor
 public class ProductionOrderController {
 
+    private final ProductionOrderService productionOrderService;
+
+    @GetMapping("/page")
+    @ApiOperation("鍒嗛〉鏌ヨ")
+    public R page(ProductionOrderDto dto, Page<ProductionOrderDto> page) {
+        return R.ok(productionOrderService.pageProductionOrder(page, dto));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("鐢熶骇璁㈠崟鍒楄〃")
+    public R<List<ProductionOrderVo>> list(ProductionOrderDto dto) {
+        return R.ok(productionOrderService.listProductionOrder(dto));
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation("鐢熶骇璁㈠崟璇︽儏")
+    public R<ProductionOrderVo> getInfo(@PathVariable("id") Long id) {
+        return R.ok(productionOrderService.getProductionOrderInfo(id));
+    }
+
+    @PostMapping
+    @ApiOperation("鏂板鐢熶骇璁㈠崟")
+    public R<Boolean> add(@RequestBody ProductionOrder productionOrder) {
+        return R.ok(productionOrderService.saveProductionOrder(productionOrder));
+    }
+
+    @PutMapping
+    @ApiOperation("淇敼鐢熶骇璁㈠崟")
+    public R<Boolean> edit(@RequestBody ProductionOrder productionOrder) {
+        return R.ok(productionOrderService.saveProductionOrder(productionOrder));
+    }
+
+    @PostMapping("/syncSnapshot/{id}")
+    @ApiOperation("鍚屾鐢熶骇璁㈠崟宸ヨ壓/BOM蹇収")
+    public R<Integer> syncSnapshot(@PathVariable("id") Long id) {
+        return R.ok(productionOrderService.syncProductionOrderSnapshot(id));
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("鍒犻櫎鐢熶骇璁㈠崟")
+    public R<Boolean> remove(@RequestBody List<Long> ids) {
+        return R.ok(productionOrderService.removeProductionOrder(ids));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java b/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java
index 5d76958..cb79e85 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingController.java
@@ -1,18 +1,56 @@
 package com.ruoyi.production.controller;
 
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
+import com.ruoyi.production.service.ProductionOrderRoutingOperationService;
+import com.ruoyi.production.service.ProductionOrderRoutingService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟宸ヨ壓璺嚎琛� 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
 @RestController
 @RequestMapping("/productionOrderRouting")
+@Api(tags = "鐢熶骇璁㈠崟宸ヨ壓璺嚎")
+@RequiredArgsConstructor
 public class ProductionOrderRoutingController {
 
+    private final ProductionOrderRoutingService productionOrderRoutingService;
+    private final ProductionOrderRoutingOperationService productionOrderRoutingOperationService;
+
+    @GetMapping("list")
+    @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓璺嚎瀛愯〃")
+    public R list(Long orderId) {
+        return R.ok(productionOrderRoutingService.listItem(orderId));
+    }
+
+    @GetMapping("listMain")
+    @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓璺嚎涓昏〃")
+    public R listMain(Long orderId) {
+        return R.ok(productionOrderRoutingService.listMain(orderId));
+    }
+
+    @PostMapping("/addRouteItem")
+    @ApiOperation("鏂板鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾胯鎯�")
+    public R addRouteItem(@RequestBody ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        return productionOrderRoutingOperationService.addRouteItem(productionOrderRoutingOperation);
+    }
+
+    @PostMapping("/updateRouteItem")
+    @ApiOperation("淇敼鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾胯鎯�")
+    public R updateRouteItem(@RequestBody ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        return R.ok(productionOrderRoutingOperationService.updateById(productionOrderRoutingOperation));
+    }
+
+    @DeleteMapping("/deleteRouteItem/{id}")
+    @ApiOperation("鍒犻櫎鐢熶骇宸ヨ壓璺嚎")
+    public R deleteRouteItem(@PathVariable("id") Long id) {
+        return productionOrderRoutingOperationService.deleteRouteItem(id);
+    }
+
+    @PostMapping("/sortRouteItem")
+    @ApiOperation("鎺掑簭")
+    public R sortRouteItem(@RequestBody ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        return R.ok(productionOrderRoutingOperationService.sortRouteItem(productionOrderRoutingOperation));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingOperationParamController.java b/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingOperationParamController.java
index 2828729..f84ae83 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingOperationParamController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionOrderRoutingOperationParamController.java
@@ -1,18 +1,68 @@
 package com.ruoyi.production.controller;
 
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.bean.dto.ProductionOrderRoutingOperationParamDto;
+import com.ruoyi.production.bean.dto.ProductionOrderRoutingOperationParamSyncDto;
+import com.ruoyi.production.bean.vo.ProductionOrderRoutingOperationParamVo;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
+import com.ruoyi.production.service.ProductionOrderRoutingOperationParamService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟琛� 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
 @RestController
 @RequestMapping("/productionOrderRoutingOperationParam")
+@Api(tags = "鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟")
+@RequiredArgsConstructor
 public class ProductionOrderRoutingOperationParamController {
 
+    private final ProductionOrderRoutingOperationParamService productionOrderRoutingOperationParamService;
+
+    @GetMapping("/page")
+    @ApiOperation("鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟鍒嗛〉鏌ヨ")
+    public R<IPage<ProductionOrderRoutingOperationParamVo>> page(Page<ProductionOrderRoutingOperationParamDto> page,
+                                                                 ProductionOrderRoutingOperationParamDto dto) {
+        return R.ok(productionOrderRoutingOperationParamService.pageProductionOrderRoutingOperationParam(page, dto));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟鍒楄〃")
+    public R<List<ProductionOrderRoutingOperationParamVo>> list(ProductionOrderRoutingOperationParamDto dto) {
+        return R.ok(productionOrderRoutingOperationParamService.listProductionOrderRoutingOperationParam(dto));
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation("鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟璇︽儏")
+    public R<ProductionOrderRoutingOperationParamVo> getInfo(@PathVariable("id") Long id) {
+        return R.ok(productionOrderRoutingOperationParamService.getProductionOrderRoutingOperationParamInfo(id));
+    }
+
+    @PostMapping
+    @ApiOperation("鏂板鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟")
+    public R<Boolean> add(@RequestBody ProductionOrderRoutingOperationParam item) {
+        return R.ok(productionOrderRoutingOperationParamService.saveProductionOrderRoutingOperationParam(item));
+    }
+
+    @PutMapping
+    @ApiOperation("淇敼鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟")
+    public R<Boolean> edit(@RequestBody ProductionOrderRoutingOperationParam item) {
+        return R.ok(productionOrderRoutingOperationParamService.saveProductionOrderRoutingOperationParam(item));
+    }
+
+    @DeleteMapping("/{id}")
+    @ApiOperation("鍒犻櫎鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭鍙傛暟")
+    public R<Boolean> remove(@PathVariable("id") Long id) {
+        return R.ok(productionOrderRoutingOperationParamService.removeProductionOrderRoutingOperationParam(id));
+    }
+
+    @PostMapping("/sync")
+    @ApiOperation("鎸夎鍗曞伐鑹鸿矾绾垮伐搴忓悓姝ュ伐搴忓弬鏁�")
+    public R<Integer> sync(@RequestBody ProductionOrderRoutingOperationParamSyncDto syncDto) {
+        return R.ok(productionOrderRoutingOperationParamService.syncProductionOrderRoutingOperationParam(syncDto));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionPlanController.java b/src/main/java/com/ruoyi/production/controller/ProductionPlanController.java
index df8a6fd..29ec05b 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionPlanController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionPlanController.java
@@ -12,11 +12,11 @@
 import com.ruoyi.production.service.ProductionPlanService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
 import java.util.List;
 
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
index 758e699..278fd1d 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
@@ -1,18 +1,25 @@
 package com.ruoyi.production.controller;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.bean.dto.ProductionProductInputDto;
+import com.ruoyi.production.service.ProductionProductInputService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐鎶曞叆琛� 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+@RequestMapping("productionProductInput")
 @RestController
-@RequestMapping("/productionProductInput")
+@Api(value = "鐢熶骇鎶曞叆")
 public class ProductionProductInputController {
 
+    @Autowired
+    private ProductionProductInputService productionProductInputService;
+
+    @GetMapping("listPage")
+    public R page(Page<ProductionProductInputDto> page, ProductionProductInputDto productionProductInputDto) {
+        return R.ok(productionProductInputService.listPageProductionProductInputDto(page, productionProductInputDto));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
index 6b755bc..935dec0 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
@@ -1,18 +1,92 @@
 package com.ruoyi.production.controller;
 
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.bean.dto.ProductionProductMainDto;
+import com.ruoyi.production.service.ProductionProductMainService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐琛� 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
+@RequestMapping("productionProductMain")
 @RestController
-@RequestMapping("/productionProductMain")
+@Api(value = "鐢熶骇鎶ュ伐")
 public class ProductionProductMainController {
 
+    @Autowired
+    private ProductionProductMainService productionProductMainService;
+
+    /**
+     * 鎶ュ伐鏌ヨ
+     * @param page
+     * @param productionProductMainDto
+     * @return
+     */
+    @GetMapping("listPage")
+    public R page(Page<ProductionProductMainDto> page, ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.listPageProductionProductMainDto(page, productionProductMainDto));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("鐢熶骇鎶ュ伐鍒嗛〉鏌ヨ")
+    public R pageProductionProductMain(Page<ProductionProductMainDto> page, ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.pageProductionProductMain(page, productionProductMainDto));
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation("鐢熶骇鎶ュ伐璇︽儏")
+    public R getInfo(@PathVariable("id") Long id) {
+        return R.ok(productionProductMainService.getProductionProductMainInfo(id));
+    }
+
+    /**
+     * 鎶ュ伐鏂板鏇存柊
+     * @param productionProductMainDto
+     * @return
+     */
+    @PostMapping("addProductMain")
+    public R addProductMain(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.addProductMain(productionProductMainDto));
+    }
+
+    @PostMapping
+    @ApiOperation("鏂板鐢熶骇鎶ュ伐")
+    public R add(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.saveProductionProductMain(productionProductMainDto));
+    }
+
+    @PutMapping
+    @ApiOperation("淇敼鐢熶骇鎶ュ伐")
+    public R edit(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.saveProductionProductMain(productionProductMainDto));
+    }
+
+    @ApiOperation("鍒犻櫎鎶ュ伐")
+    @DeleteMapping("/delete")
+    public R delete(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.removeProductMain(productionProductMainDto.getId()));
+    }
+
+    @DeleteMapping("/{id}")
+    @ApiOperation("鍒犻櫎鐢熶骇鎶ュ伐")
+    public R remove(@PathVariable("id") Long id) {
+        return R.ok(productionProductMainService.removeProductMain(id));
+    }
+
+
+    /**
+     * 瀵煎嚭
+     */
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, ProductionProductMainDto productionProductMainDto) {
+        List<ProductionProductMainDto> list;
+        list = productionProductMainService.listPageProductionProductMainDto(new Page<>(1, -1), productionProductMainDto).getRecords();
+        ExcelUtil<ProductionProductMainDto> util = new ExcelUtil<ProductionProductMainDto>(ProductionProductMainDto.class);
+        util.exportExcel(response, list, "鐢熶骇鎶ュ伐鏁版嵁");
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
index 64963d1..8944282 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
@@ -1,18 +1,25 @@
 package com.ruoyi.production.controller;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.bean.dto.ProductionProductOutputDto;
+import com.ruoyi.production.service.ProductionProductOutputService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐浜у嚭琛� 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+@RequestMapping("productionProductOutput")
 @RestController
-@RequestMapping("/productionProductOutput")
+@Api(value = "鐢熶骇浜у嚭")
 public class ProductionProductOutputController {
 
+    @Autowired
+    private ProductionProductOutputService productionProductOutputService;
+
+    @GetMapping("listPage")
+    public R page(Page<ProductionProductOutputDto> page, ProductionProductOutputDto productionProductOutputDto) {
+        return R.ok(productionProductOutputService.listPageProductionProductOutputDto(page, productionProductOutputDto));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java b/src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java
new file mode 100644
index 0000000..5ad55c3
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java
@@ -0,0 +1,65 @@
+package com.ruoyi.production.enums;
+
+import lombok.Getter;
+
+/**
+ * <br>
+ * 鐢熶骇璁㈠崟鐘舵�佹灇涓剧被
+ * </br>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/03/18 14:18
+ */
+@Getter
+public enum ProductOrderStatusEnum {
+
+    WAIT(1, "寰呭紑濮�"),
+    RUNNING(2, "杩涜涓�"),
+    FINISHED(3, "宸插畬鎴�"),
+    CANCEL(4, "宸插彇娑�");
+
+    private final Integer code;
+    private final String desc;
+
+    ProductOrderStatusEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    /**
+     * 鏍规嵁code鑾峰彇鏋氫妇
+     */
+    public static ProductOrderStatusEnum getByCode(Integer code) {
+        if (code == null) {
+            return null;
+        }
+        for (ProductOrderStatusEnum item : values()) {
+            if (item.getCode().equals(code)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁鍏佽鍒犻櫎锛�4锛�
+     */
+    public static boolean canDelete(Integer code) {
+        return WAIT.getCode().equals(code) || CANCEL.getCode().equals(code);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁鍏佽鎾ゅ洖锛�1锛�
+     */
+    public static boolean canRevoke(Integer code) {
+        return WAIT.getCode().equals(code);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁宸插紑濮嬬敓浜э紙2銆�3锛�
+     */
+    public static boolean isStarted(Integer code) {
+        return RUNNING.getCode().equals(code) || FINISHED.getCode().equals(code);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionAccountMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionAccountMapper.java
index f8d4fee..e1ae36b 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionAccountMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionAccountMapper.java
@@ -1,8 +1,13 @@
 package com.ruoyi.production.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.production.bean.dto.UserAccountDto;
 import com.ruoyi.production.pojo.ProductionAccount;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -14,5 +19,8 @@
  */
 @Mapper
 public interface ProductionAccountMapper extends BaseMapper<ProductionAccount> {
+    UserAccountDto selectUserAccount(@Param("userId") Long userId, @Param("date") String date);
+
+    List<Map<String, Object>> selectDailyWagesStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
 
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionOperationTaskMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionOperationTaskMapper.java
index ee7e406..c3c6d3b 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionOperationTaskMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionOperationTaskMapper.java
@@ -1,8 +1,15 @@
 package com.ruoyi.production.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.home.dto.ProductionTaskStatisticsDto;
+import com.ruoyi.home.dto.processDataProductionStatisticsDto;
 import com.ruoyi.production.pojo.ProductionOperationTask;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * <p>
@@ -15,4 +22,15 @@
 @Mapper
 public interface ProductionOperationTaskMapper extends BaseMapper<ProductionOperationTask> {
 
+    List<ProductionTaskStatisticsDto> selectTaskStatisticsByDate(@Param("startDate") LocalDate startDate,
+                                                                 @Param("endDate") LocalDate endDate);
+
+    List<ProductionTaskStatisticsDto> selectTaskStartStats(@Param("startDateTime") String startDateTime,
+                                                           @Param("endDateTime") String endDateTime);
+
+    List<processDataProductionStatisticsDto> calculateProductionStatistics(@Param("startDateTime") LocalDateTime startDateTime,
+                                                                           @Param("endDateTime") LocalDateTime endDateTime,
+                                                                           @Param("userId") Long userId,
+                                                                           @Param("processIds") List<Long> processIds);
+
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java
index ab6d5f7..e66e768 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionOrderMapper.java
@@ -1,8 +1,13 @@
 package com.ruoyi.production.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.home.dto.ProductionProgressOrderDto;
 import com.ruoyi.production.pojo.ProductionOrder;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * <p>
@@ -15,4 +20,13 @@
 @Mapper
 public interface ProductionOrderMapper extends BaseMapper<ProductionOrder> {
 
+    List<ProductionProgressOrderDto> selectProgressOrders(@Param("startTime") LocalDateTime startTime,
+                                                          @Param("endTime") LocalDateTime endTime);
+
+    Integer countCreated(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
+    Integer countCompleted(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
+    Integer countPending(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionPlanMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionPlanMapper.java
index 5459f5b..892c633 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionPlanMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionPlanMapper.java
@@ -1,8 +1,14 @@
 package com.ruoyi.production.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.bean.dto.ProductionPlanDto;
 import com.ruoyi.production.pojo.ProductionPlan;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -15,4 +21,10 @@
 @Mapper
 public interface ProductionPlanMapper extends BaseMapper<ProductionPlan> {
 
+    IPage<ProductionPlanDto> listPage(Page page, @Param("c") ProductionPlanDto productionPlanDto);
+
+    List<ProductionPlanDto> selectWithMaterialByIds(@Param("ids") List<Long> ids);
+
+    ProductionPlanDto selectProductionPlanDtoById(@Param("productionPlanId") Long productionPlanId);
+
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
index 854b238..cbd6998 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
@@ -1,18 +1,24 @@
 package com.ruoyi.production.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.bean.dto.ProductionProductInputDto;
 import com.ruoyi.production.pojo.ProductionProductInput;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐鎶曞叆琛� Mapper 鎺ュ彛
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+import java.util.Map;
+
 @Mapper
 public interface ProductionProductInputMapper extends BaseMapper<ProductionProductInput> {
+    IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, @Param("c") ProductionProductInputDto productionProductInputDto);
 
+    /**
+     * 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎鎶曞叆琛ㄦ暟鎹�
+     */
+    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
+
+    List<Map<String, Object>> selectInputStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
index 3c4ccdc..c637caf 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -1,18 +1,36 @@
 package com.ruoyi.production.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.bean.dto.ProductionProductMainDto;
+import com.ruoyi.production.bean.dto.SalesLedgerProductionAccountingDto;
+import com.ruoyi.production.pojo.ProductionOrder;
 import com.ruoyi.production.pojo.ProductionProductMain;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐琛� Mapper 鎺ュ彛
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.ArrayList;
+import java.util.List;
+
 @Mapper
 public interface ProductionProductMainMapper extends BaseMapper<ProductionProductMain> {
 
+    IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, @Param("c") ProductionProductMainDto productionProductMainDto);
+
+    /**
+     * 鏍规嵁宸ュ崟ID鎵归噺鍒犻櫎鐢熶骇涓昏〃鏁版嵁
+     */
+    int deleteByWorkOrderIds(@Param("workOrderIds") List<Long> workOrderIds);
+
+    /**
+     * 鏍规嵁鎶ュ伐id鏌ヨ鐢熶骇璁㈠崟
+     * @param productMainId
+     * @return
+     */
+    ProductionOrder getOrderByMainId(@Param("productMainId") Long productMainId);
+
+    IPage<ProductionProductMainDto> listProductionDetails(@Param("ew") SalesLedgerProductionAccountingDto salesLedgerProductionAccountingDto, Page page);
+
+    ArrayList<Long> listMain(List<Long> idList);
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
index 46f3f95..06a87de 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
@@ -1,18 +1,26 @@
 package com.ruoyi.production.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.bean.dto.ProductionProductOutputDto;
 import com.ruoyi.production.pojo.ProductionProductOutput;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐浜у嚭琛� Mapper 鎺ュ彛
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+import java.util.Map;
+
 @Mapper
 public interface ProductionProductOutputMapper extends BaseMapper<ProductionProductOutput> {
+    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, @Param("c") ProductionProductOutputDto productionProductOutputDto);
 
+    /**
+     * 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎浜у嚭琛ㄦ暟鎹�
+     */
+    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
+
+    List<ProductionProductOutputDto> selectOutputStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
+    List<Map<String, Object>> selectDailyOutputStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionOrder.java b/src/main/java/com/ruoyi/production/pojo/ProductionOrder.java
index 5fcab22..c07b320 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionOrder.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionOrder.java
@@ -1,13 +1,16 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 /**
@@ -74,4 +77,15 @@
     @ApiModelProperty("閮ㄩ棬ID")
     @TableField(fill = FieldFill.INSERT)
     private Long deptId;
+
+    @ApiModelProperty(value = "璁″垝瀹屾垚鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate planCompleteTime;
+
+    @ApiModelProperty(value = "鐘舵�侊紙1.寰呭紑濮嬨��2.杩涜涓��3.宸插畬鎴愩��4.宸插彇娑堬級")
+    private Integer status;
+
+    @ApiModelProperty("寮哄害")
+    private String strength;
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionPlan.java b/src/main/java/com/ruoyi/production/pojo/ProductionPlan.java
index 6ffa6db..44dcaa7 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionPlan.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionPlan.java
@@ -6,6 +6,7 @@
 import lombok.Getter;
 import lombok.Setter;
 
+import java.io.Serial;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
@@ -24,6 +25,7 @@
 @ApiModel(value = "ProductionPlan瀵硅薄", description = "鐢熶骇璁″垝琛�")
 public class ProductionPlan implements Serializable {
 
+    @Serial
     private static final long serialVersionUID = 1L;
 
     @ApiModelProperty("id")
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
index 3d8285a..8554767 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
@@ -1,57 +1,54 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.Data;
 
-import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐鎶曞叆琛�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
-@Getter
-@Setter
+@Data
 @TableName("production_product_input")
-@ApiModel(value = "ProductionProductInput瀵硅薄", description = "鐢熶骇鎶ュ伐鎶曞叆琛�")
-public class ProductionProductInput implements Serializable {
+public class ProductionProductInput {
 
-    private static final long serialVersionUID = 1L;
-
-    @ApiModelProperty("id")
-    @TableId(value = "id", type = IdType.AUTO)
+    @TableId(type = IdType.AUTO)
     private Long id;
 
-    @ApiModelProperty("鎶曞叆鏁伴噺")
-    private BigDecimal inputQuantity;
+    @ApiModelProperty(value = "鎶ュ伐id")
+    private Long productMainId;
 
-    @ApiModelProperty("鎶ュ伐琛╥d")
+    @ApiModelProperty(value = "鐢熶骇鎶ュ伐涓昏〃id")
     private Long productionProductMainId;
 
-    @ApiModelProperty("浜у搧鍨嬪彿id")
+    @ApiModelProperty(value = "浜у搧id")
     private Long productModelId;
 
-    @ApiModelProperty("鏇存柊鏃堕棿")
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private LocalDateTime updateTime;
+    @ApiModelProperty(value = "鏁伴噺")
+    private BigDecimal quantity;
 
-    @ApiModelProperty("鍒涘缓浜篒D")
-    @TableField(fill = FieldFill.INSERT)
-    private Long createUser;
+    @ApiModelProperty(value = "鎶曞叆鏁伴噺")
+    private BigDecimal inputQuantity;
 
-    @ApiModelProperty("褰曞叆鏃堕棿")
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
     @TableField(fill = FieldFill.INSERT)
     private LocalDateTime createTime;
 
-    @ApiModelProperty("鏇存柊鐢ㄦ埛")
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
     @TableField(fill = FieldFill.INSERT_UPDATE)
-    private Long updateUser;
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty(value = "鏇存柊鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
index 449c15f..f38764f 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
@@ -1,57 +1,68 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
-import io.swagger.annotations.ApiModel;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
-import java.io.Serializable;
 import java.time.LocalDateTime;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐琛�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
-@Getter
-@Setter
+@Data
 @TableName("production_product_main")
-@ApiModel(value = "ProductionProductMain瀵硅薄", description = "鐢熶骇鎶ュ伐琛�")
-public class ProductionProductMain implements Serializable {
+public class ProductionProductMain {
 
-    private static final long serialVersionUID = 1L;
-
-    @ApiModelProperty("id")
-    @TableId(value = "id", type = IdType.AUTO)
+    @TableId(type = IdType.AUTO)
     private Long id;
 
-    @ApiModelProperty("鎶ュ伐鍗曞彿")
+    @ApiModelProperty(value = "鎶ュ伐鍗曞彿")
+    @Excel(name = "鎶ュ伐鍗曞彿")
     private String productNo;
 
-    @ApiModelProperty("宸ュ崟id")
+    @ApiModelProperty(value = "鎶ュ伐浜哄憳id")
+    private Long userId;
+
+    @ApiModelProperty(value = "鎶ュ伐浜哄憳")
+    private String userName;
+
+    @ApiModelProperty(value = "鐢熶骇椤圭洰id")
+    private Long productProcessRouteItemId;
+
+    @ApiModelProperty(value = "宸ュ崟id")
+    private Long workOrderId;
+
+    @ApiModelProperty(value = "鐢熶骇宸ュ簭宸ュ崟id")
     private Long productionOperationTaskId;
 
-    @ApiModelProperty("閮ㄩ棬ID")
+    @ApiModelProperty(value = "鎶ュ伐鐘舵��")
+    private Integer status;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty(value = "鏇存柊鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
     @TableField(fill = FieldFill.INSERT)
     private Long deptId;
 
-    @ApiModelProperty("鏇存柊鏃堕棿")
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private LocalDateTime updateTime;
-
-    @ApiModelProperty("鍒涘缓浜篒D")
-    @TableField(fill = FieldFill.INSERT)
-    private Long createUser;
-
-    @ApiModelProperty("褰曞叆鏃堕棿")
-    @TableField(fill = FieldFill.INSERT)
-    private LocalDateTime createTime;
-
-    @ApiModelProperty("鏇存柊鐢ㄦ埛")
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private Long updateUser;
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
index 32cc976..31cf274 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -1,59 +1,54 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.Data;
 
-import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐浜у嚭琛�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
-@Getter
-@Setter
+@Data
 @TableName("production_product_output")
-@ApiModel(value = "ProductionProductOutput瀵硅薄", description = "鐢熶骇鎶ュ伐浜у嚭琛�")
-public class ProductionProductOutput implements Serializable {
+public class ProductionProductOutput {
 
-    private static final long serialVersionUID = 1L;
-
-    @TableId(value = "id", type = IdType.AUTO)
+    @TableId(type = IdType.AUTO)
     private Long id;
 
-    @ApiModelProperty("鎶ュ伐鍗昳d")
+    @ApiModelProperty(value = "鎶ュ伐id")
+    private Long productMainId;
+
+    @ApiModelProperty(value = "鐢熶骇鎶ュ伐涓昏〃id")
     private Long productionProductMainId;
 
-    @ApiModelProperty("浜у搧瑙勬牸id")
+    @ApiModelProperty(value = "浜у搧id")
     private Long productModelId;
 
-    @ApiModelProperty("鎶ュ伐鏁伴噺")
+    @ApiModelProperty(value = "鎶ュ伐鏁伴噺(鎬绘暟閲�)")
     private BigDecimal quantity;
 
-    @ApiModelProperty("鎶ュ簾鏁伴噺")
-    private BigDecimal scrapQty;
-
-    @ApiModelProperty("鏇存柊鏃堕棿")
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private LocalDateTime updateTime;
-
-    @ApiModelProperty("鍒涘缓浜篒D")
-    @TableField(fill = FieldFill.INSERT)
-    private Long createUser;
-
-    @ApiModelProperty("褰曞叆鏃堕棿")
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
     @TableField(fill = FieldFill.INSERT)
     private LocalDateTime createTime;
 
-    @ApiModelProperty("鏇存柊鐢ㄦ埛")
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
     @TableField(fill = FieldFill.INSERT_UPDATE)
-    private Long updateUser;
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty(value = "鎶ュ簾鏁伴噺")
+    private BigDecimal scrapQty;
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty(value = "鏇存柊鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOperationTaskService.java b/src/main/java/com/ruoyi/production/service/ProductionOperationTaskService.java
index 90570be..8897c4e 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOperationTaskService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOperationTaskService.java
@@ -1,16 +1,24 @@
 package com.ruoyi.production.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.bean.dto.ProductionOperationTaskDto;
+import com.ruoyi.production.bean.vo.ProductionOperationTaskVo;
 import com.ruoyi.production.pojo.ProductionOperationTask;
 
-/**
- * <p>
- * 鐢熶骇宸ュ崟琛� 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
 public interface ProductionOperationTaskService extends IService<ProductionOperationTask> {
 
+    IPage<ProductionOperationTaskVo> pageProductionOperationTask(Page<ProductionOperationTaskDto> page,
+                                                                 ProductionOperationTaskDto productionOperationTaskDto);
+
+    List<ProductionOperationTaskVo> listProductionOperationTask(ProductionOperationTaskDto productionOperationTaskDto);
+
+    ProductionOperationTaskVo getProductionOperationTaskInfo(Long id);
+
+    boolean saveProductionOperationTask(ProductionOperationTask productionOperationTask);
+
+    boolean removeProductionOperationTask(List<Long> ids);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationParamService.java b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationParamService.java
index 1ff0e5b..0376c7a 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationParamService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationParamService.java
@@ -1,7 +1,14 @@
 package com.ruoyi.production.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.bean.dto.ProductionOrderRoutingOperationParamDto;
+import com.ruoyi.production.bean.dto.ProductionOrderRoutingOperationParamSyncDto;
+import com.ruoyi.production.bean.vo.ProductionOrderRoutingOperationParamVo;
 import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
+
+import java.util.List;
 
 /**
  * <p>
@@ -13,4 +20,16 @@
  */
 public interface ProductionOrderRoutingOperationParamService extends IService<ProductionOrderRoutingOperationParam> {
 
+    IPage<ProductionOrderRoutingOperationParamVo> pageProductionOrderRoutingOperationParam(Page<ProductionOrderRoutingOperationParamDto> page,
+                                                                                           ProductionOrderRoutingOperationParamDto dto);
+
+    List<ProductionOrderRoutingOperationParamVo> listProductionOrderRoutingOperationParam(ProductionOrderRoutingOperationParamDto dto);
+
+    ProductionOrderRoutingOperationParamVo getProductionOrderRoutingOperationParamInfo(Long id);
+
+    boolean saveProductionOrderRoutingOperationParam(ProductionOrderRoutingOperationParam item);
+
+    boolean removeProductionOrderRoutingOperationParam(Long id);
+
+    int syncProductionOrderRoutingOperationParam(ProductionOrderRoutingOperationParamSyncDto syncDto);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java
index ed64948..2377dc3 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingOperationService.java
@@ -1,16 +1,14 @@
 package com.ruoyi.production.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭琛� 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
 public interface ProductionOrderRoutingOperationService extends IService<ProductionOrderRoutingOperation> {
 
+    R addRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation);
+
+    R deleteRouteItem(Long id);
+
+    int sortRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingService.java b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingService.java
index 54668a4..42144b3 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOrderRoutingService.java
@@ -2,15 +2,13 @@
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.production.pojo.ProductionOrderRouting;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟宸ヨ壓璺嚎琛� 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
 public interface ProductionOrderRoutingService extends IService<ProductionOrderRouting> {
 
+    ProductionOrderRouting listMain(Long orderId);
+
+    List<ProductionOrderRoutingOperation> listItem(Long orderId);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionOrderService.java b/src/main/java/com/ruoyi/production/service/ProductionOrderService.java
index a3e7fd5..56779bf 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionOrderService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionOrderService.java
@@ -1,16 +1,25 @@
 package com.ruoyi.production.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.bean.dto.ProductionOrderDto;
+import com.ruoyi.production.bean.vo.ProductionOrderVo;
 import com.ruoyi.production.pojo.ProductionOrder;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟琛� 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
 public interface ProductionOrderService extends IService<ProductionOrder> {
 
+    IPage<ProductionOrderVo> pageProductionOrder(Page<ProductionOrderDto> page, ProductionOrderDto productionOrderDto);
+
+    List<ProductionOrderVo> listProductionOrder(ProductionOrderDto productionOrderDto);
+
+    ProductionOrderVo getProductionOrderInfo(Long id);
+
+    boolean saveProductionOrder(ProductionOrder productionOrder);
+
+    boolean removeProductionOrder(List<Long> ids);
+
+    int syncProductionOrderSnapshot(Long productionOrderId);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionPlanService.java b/src/main/java/com/ruoyi/production/service/ProductionPlanService.java
index f4b871d..370a7c6 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionPlanService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionPlanService.java
@@ -6,9 +6,9 @@
 import com.ruoyi.production.bean.dto.ProductionPlanDto;
 import com.ruoyi.production.bean.vo.ProductionPlanVo;
 import com.ruoyi.production.pojo.ProductionPlan;
+import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -21,7 +21,7 @@
  */
 public interface ProductionPlanService extends IService<ProductionPlan> {
 
-    IPage<ProductionPlanVo> listPage(Page page, ProductionPlanDto productionPlanDto);
+    IPage<ProductionPlanVo> listPage(Page<ProductionPlanDto> page, ProductionPlanDto productionPlanDto);
 
     /**
      * 鎵嬪姩鍚屾
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java b/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
index 7ce4410..42afd89 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
@@ -1,16 +1,11 @@
 package com.ruoyi.production.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.bean.dto.ProductionProductInputDto;
 import com.ruoyi.production.pojo.ProductionProductInput;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐鎶曞叆琛� 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
 public interface ProductionProductInputService extends IService<ProductionProductInput> {
-
+    IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, ProductionProductInputDto productionProductInputDto);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java b/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
index 9a4adbf..6a07d2b 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
@@ -1,16 +1,26 @@
 package com.ruoyi.production.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.bean.dto.ProductionProductMainDto;
 import com.ruoyi.production.pojo.ProductionProductMain;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐琛� 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
-public interface ProductionProductMainService extends IService<ProductionProductMain> {
+import java.util.ArrayList;
+import java.util.List;
 
+public interface ProductionProductMainService extends IService<ProductionProductMain> {
+    IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto);
+
+    IPage<ProductionProductMainDto> pageProductionProductMain(Page page, ProductionProductMainDto productionProductMainDto);
+
+    ProductionProductMainDto getProductionProductMainInfo(Long id);
+
+    Boolean addProductMain(ProductionProductMainDto productionProductMainDto);
+
+    Boolean saveProductionProductMain(ProductionProductMainDto productionProductMainDto);
+
+    Boolean removeProductMain(Long id);
+
+    ArrayList<Long> listMain(List<Long> idList);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java b/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
index 2a51d2e..b01ae0d 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
@@ -1,16 +1,11 @@
 package com.ruoyi.production.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.bean.dto.ProductionProductOutputDto;
 import com.ruoyi.production.pojo.ProductionProductOutput;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐浜у嚭琛� 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
 public interface ProductionProductOutputService extends IService<ProductionProductOutput> {
-
+    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, ProductionProductOutputDto productionProductOutputDto);
 }
diff --git a/src/main/java/com/ruoyi/production/service/SalesLedgerProductionAccountingService.java b/src/main/java/com/ruoyi/production/service/SalesLedgerProductionAccountingService.java
new file mode 100644
index 0000000..9f844f1
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/SalesLedgerProductionAccountingService.java
@@ -0,0 +1,8 @@
+package com.ruoyi.production.service;
+
+import com.ruoyi.production.bean.dto.UserAccountDto;
+import com.ruoyi.production.bean.dto.UserProductionAccountingDto;
+
+public interface SalesLedgerProductionAccountingService {
+    UserAccountDto getByUserId(UserProductionAccountingDto dto);
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java
index ee245d6..66e1aaa 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOperationTaskServiceImpl.java
@@ -1,20 +1,64 @@
 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.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.production.bean.dto.ProductionOperationTaskDto;
+import com.ruoyi.production.bean.vo.ProductionOperationTaskVo;
 import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
 import com.ruoyi.production.pojo.ProductionOperationTask;
 import com.ruoyi.production.service.ProductionOperationTaskService;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
-/**
- * <p>
- * 鐢熶骇宸ュ崟琛� 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
-@Service
-public class ProductionOperationTaskServiceImpl extends ServiceImpl<ProductionOperationTaskMapper, ProductionOperationTask> implements ProductionOperationTaskService {
+import java.util.List;
 
+@Service
+@RequiredArgsConstructor
+public class ProductionOperationTaskServiceImpl extends ServiceImpl<ProductionOperationTaskMapper, ProductionOperationTask>
+        implements ProductionOperationTaskService {
+
+    @Override
+    public IPage<ProductionOperationTaskVo> pageProductionOperationTask(Page<ProductionOperationTaskDto> page,
+                                                                         ProductionOperationTaskDto dto) {
+        Page<ProductionOperationTask> entityPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
+        return this.page(entityPage, buildQueryWrapper(dto)).convert(item -> BeanUtil.copyProperties(item, ProductionOperationTaskVo.class));
+    }
+
+    @Override
+    public List<ProductionOperationTaskVo> listProductionOperationTask(ProductionOperationTaskDto dto) {
+        return BeanUtil.copyToList(this.list(buildQueryWrapper(dto)), ProductionOperationTaskVo.class);
+    }
+
+    @Override
+    public ProductionOperationTaskVo getProductionOperationTaskInfo(Long id) {
+        ProductionOperationTask item = this.getById(id);
+        return item == null ? null : BeanUtil.copyProperties(item, ProductionOperationTaskVo.class);
+    }
+
+    @Override
+    public boolean saveProductionOperationTask(ProductionOperationTask productionOperationTask) {
+        return this.saveOrUpdate(productionOperationTask);
+    }
+
+    @Override
+    public boolean removeProductionOperationTask(List<Long> ids) {
+        return ids != null && !ids.isEmpty() && this.removeByIds(ids);
+    }
+
+    private LambdaQueryWrapper<ProductionOperationTask> buildQueryWrapper(ProductionOperationTaskDto dto) {
+        ProductionOperationTask query = dto == null ? new ProductionOperationTask() : dto;
+        return Wrappers.<ProductionOperationTask>lambdaQuery()
+                .eq(query.getId() != null, ProductionOperationTask::getId, query.getId())
+                .eq(query.getProductionOrderId() != null, ProductionOperationTask::getProductionOrderId, query.getProductionOrderId())
+                .eq(query.getTechnologyRoutingOperationId() != null,
+                        ProductionOperationTask::getTechnologyRoutingOperationId, query.getTechnologyRoutingOperationId())
+                .eq(query.getStatus() != null, ProductionOperationTask::getStatus, query.getStatus())
+                .like(query.getWorkOrderNo() != null && !query.getWorkOrderNo().trim().isEmpty(),
+                        ProductionOperationTask::getWorkOrderNo, query.getWorkOrderNo())
+                .orderByDesc(ProductionOperationTask::getId);
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java
index d6eab7c..048519b 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationParamServiceImpl.java
@@ -1,20 +1,210 @@
 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.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.common.exception.ServiceException;
+import com.ruoyi.production.bean.dto.ProductionOrderRoutingOperationParamDto;
+import com.ruoyi.production.bean.dto.ProductionOrderRoutingOperationParamSyncDto;
+import com.ruoyi.production.bean.vo.ProductionOrderRoutingOperationParamVo;
+import com.ruoyi.production.mapper.ProductionOrderMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
 import com.ruoyi.production.mapper.ProductionOrderRoutingOperationParamMapper;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
 import com.ruoyi.production.pojo.ProductionOrderRoutingOperationParam;
 import com.ruoyi.production.service.ProductionOrderRoutingOperationParamService;
+import com.ruoyi.technology.mapper.TechnologyRoutingOperationParamMapper;
+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.util.List;
+
 @Service
-public class ProductionOrderRoutingOperationParamServiceImpl extends ServiceImpl<ProductionOrderRoutingOperationParamMapper, ProductionOrderRoutingOperationParam> implements ProductionOrderRoutingOperationParamService {
+@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor
+public class ProductionOrderRoutingOperationParamServiceImpl extends ServiceImpl<ProductionOrderRoutingOperationParamMapper, ProductionOrderRoutingOperationParam>
+        implements ProductionOrderRoutingOperationParamService {
 
+    private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper;
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final TechnologyRoutingOperationParamMapper technologyRoutingOperationParamMapper;
+
+    @Override
+    public IPage<ProductionOrderRoutingOperationParamVo> pageProductionOrderRoutingOperationParam(Page<ProductionOrderRoutingOperationParamDto> page,
+                                                                                                  ProductionOrderRoutingOperationParamDto dto) {
+        Page<ProductionOrderRoutingOperationParam> entityPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
+        return this.page(entityPage, buildQueryWrapper(dto))
+                .convert(item -> BeanUtil.copyProperties(item, ProductionOrderRoutingOperationParamVo.class));
+    }
+
+    @Override
+    public List<ProductionOrderRoutingOperationParamVo> listProductionOrderRoutingOperationParam(ProductionOrderRoutingOperationParamDto dto) {
+        return BeanUtil.copyToList(this.list(buildQueryWrapper(dto)), ProductionOrderRoutingOperationParamVo.class);
+    }
+
+    @Override
+    public ProductionOrderRoutingOperationParamVo getProductionOrderRoutingOperationParamInfo(Long id) {
+        ProductionOrderRoutingOperationParam item = this.getById(id);
+        return item == null ? null : BeanUtil.copyProperties(item, ProductionOrderRoutingOperationParamVo.class);
+    }
+
+    @Override
+    public boolean saveProductionOrderRoutingOperationParam(ProductionOrderRoutingOperationParam item) {
+        ProductionOrderRoutingOperation routingOperation = getRoutingOperation(item.getTechnologyRoutingOperationId());
+        fillFromSourceParam(item, routingOperation);
+        validateManualFields(item);
+        checkDuplicate(item);
+        return this.saveOrUpdate(item);
+    }
+
+    @Override
+    public boolean removeProductionOrderRoutingOperationParam(Long id) {
+        return this.removeById(id);
+    }
+
+    @Override
+    public int syncProductionOrderRoutingOperationParam(ProductionOrderRoutingOperationParamSyncDto syncDto) {
+        if (syncDto == null || syncDto.getProductionOrderRoutingOperationId() == null) {
+            throw new ServiceException("productionOrderRoutingOperationId is required");
+        }
+        ProductionOrderRoutingOperation routingOperation = getRoutingOperation(syncDto.getProductionOrderRoutingOperationId());
+        List<TechnologyRoutingOperationParam> sourceParamList = technologyRoutingOperationParamMapper.selectList(
+                Wrappers.<TechnologyRoutingOperationParam>lambdaQuery()
+                        .eq(TechnologyRoutingOperationParam::getTechnologyRoutingOperationId, routingOperation.getTechnologyRoutingOperationId())
+                        .orderByAsc(TechnologyRoutingOperationParam::getId)
+        );
+        boolean replaceExisting = syncDto.getReplaceExisting() == null || syncDto.getReplaceExisting();
+        if (replaceExisting) {
+            productionOrderRoutingOperationParamMapper.delete(
+                    Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                            .eq(ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationId, routingOperation.getId())
+            );
+        }
+        int successCount = 0;
+        for (TechnologyRoutingOperationParam sourceParam : sourceParamList) {
+            boolean exists = productionOrderRoutingOperationParamMapper.selectCount(
+                    Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                            .eq(ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationId, routingOperation.getId())
+                            .eq(ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationParamId, sourceParam.getId())
+            ) > 0;
+            if (!replaceExisting && exists) {
+                continue;
+            }
+            ProductionOrderRoutingOperationParam target = new ProductionOrderRoutingOperationParam();
+            target.setTechnologyRoutingOperationId(routingOperation.getId());
+            target.setTechnologyRoutingOperationParamId(sourceParam.getId());
+            target.setProductionOrderId(routingOperation.getProductionOrderId());
+            target.setTechnologyOperationId(sourceParam.getTechnologyOperationId());
+            target.setTechnologyOperationParamId(sourceParam.getTechnologyOperationParamId());
+            target.setParamId(sourceParam.getParamId());
+            target.setParamCode(sourceParam.getParamCode());
+            target.setParamName(sourceParam.getParamName());
+            target.setParamType(sourceParam.getParamType());
+            target.setParamFormat(sourceParam.getParamFormat());
+            target.setUnit(sourceParam.getUnit());
+            target.setIsRequired(sourceParam.getIsRequired());
+            target.setRemark(sourceParam.getRemark());
+            target.setStandardValue(sourceParam.getStandardValue());
+            productionOrderRoutingOperationParamMapper.insert(target);
+            successCount++;
+        }
+        return successCount;
+    }
+
+    private LambdaQueryWrapper<ProductionOrderRoutingOperationParam> buildQueryWrapper(ProductionOrderRoutingOperationParamDto dto) {
+        ProductionOrderRoutingOperationParam query = dto == null ? new ProductionOrderRoutingOperationParam() : dto;
+        return Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                .eq(query.getId() != null, ProductionOrderRoutingOperationParam::getId, query.getId())
+                .eq(query.getProductionOrderId() != null, ProductionOrderRoutingOperationParam::getProductionOrderId, query.getProductionOrderId())
+                .eq(query.getTechnologyRoutingOperationId() != null,
+                        ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationId, query.getTechnologyRoutingOperationId())
+                .eq(query.getTechnologyOperationId() != null,
+                        ProductionOrderRoutingOperationParam::getTechnologyOperationId, query.getTechnologyOperationId())
+                .eq(query.getTechnologyRoutingOperationParamId() != null,
+                        ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationParamId, query.getTechnologyRoutingOperationParamId())
+                .eq(query.getTechnologyOperationParamId() != null,
+                        ProductionOrderRoutingOperationParam::getTechnologyOperationParamId, query.getTechnologyOperationParamId())
+                .like(query.getParamCode() != null && !query.getParamCode().trim().isEmpty(),
+                        ProductionOrderRoutingOperationParam::getParamCode, query.getParamCode())
+                .like(query.getParamName() != null && !query.getParamName().trim().isEmpty(),
+                        ProductionOrderRoutingOperationParam::getParamName, query.getParamName())
+                .orderByAsc(ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationId)
+                .orderByAsc(ProductionOrderRoutingOperationParam::getId);
+    }
+
+    private ProductionOrderRoutingOperation getRoutingOperation(Long productionOrderRoutingOperationId) {
+        if (productionOrderRoutingOperationId == null) {
+            throw new ServiceException("productionOrderRoutingOperationId is required");
+        }
+        ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOrderRoutingOperationId);
+        if (routingOperation == null) {
+            throw new ServiceException("Production order routing operation not found");
+        }
+        return routingOperation;
+    }
+
+    private void fillFromSourceParam(ProductionOrderRoutingOperationParam item, ProductionOrderRoutingOperation routingOperation) {
+        item.setTechnologyRoutingOperationId(routingOperation.getId());
+        item.setProductionOrderId(routingOperation.getProductionOrderId());
+        ProductionOrder productionOrder = productionOrderMapper.selectById(routingOperation.getProductionOrderId());
+        if (productionOrder == null) {
+            throw new ServiceException("Production order not found");
+        }
+        if (item.getTechnologyRoutingOperationParamId() == null) {
+            return;
+        }
+        TechnologyRoutingOperationParam sourceParam = technologyRoutingOperationParamMapper.selectById(item.getTechnologyRoutingOperationParamId());
+        if (sourceParam == null) {
+            throw new ServiceException("Technology routing operation param not found");
+        }
+        if (!routingOperation.getTechnologyRoutingOperationId().equals(sourceParam.getTechnologyRoutingOperationId())) {
+            throw new ServiceException("Source param does not belong to routing operation");
+        }
+        item.setTechnologyOperationId(sourceParam.getTechnologyOperationId());
+        item.setTechnologyOperationParamId(sourceParam.getTechnologyOperationParamId());
+        item.setParamId(sourceParam.getParamId());
+        item.setParamCode(sourceParam.getParamCode());
+        item.setParamName(sourceParam.getParamName());
+        item.setParamType(sourceParam.getParamType());
+        item.setParamFormat(sourceParam.getParamFormat());
+        item.setUnit(sourceParam.getUnit());
+        item.setIsRequired(sourceParam.getIsRequired());
+        if (item.getRemark() == null || item.getRemark().trim().isEmpty()) {
+            item.setRemark(sourceParam.getRemark());
+        }
+        if (item.getStandardValue() == null) {
+            item.setStandardValue(sourceParam.getStandardValue());
+        }
+    }
+
+    private void validateManualFields(ProductionOrderRoutingOperationParam item) {
+        if (item.getParamCode() == null || item.getParamCode().trim().isEmpty()) {
+            throw new ServiceException("paramCode is required");
+        }
+        if (item.getParamName() == null || item.getParamName().trim().isEmpty()) {
+            throw new ServiceException("paramName is required");
+        }
+    }
+
+    private void checkDuplicate(ProductionOrderRoutingOperationParam item) {
+        boolean duplicate = productionOrderRoutingOperationParamMapper.selectCount(
+                Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationId, item.getTechnologyRoutingOperationId())
+                        .eq(item.getTechnologyRoutingOperationParamId() != null,
+                                ProductionOrderRoutingOperationParam::getTechnologyRoutingOperationParamId, item.getTechnologyRoutingOperationParamId())
+                        .eq(item.getTechnologyRoutingOperationParamId() == null && item.getParamCode() != null,
+                                ProductionOrderRoutingOperationParam::getParamCode, item.getParamCode())
+                        .ne(item.getId() != null, ProductionOrderRoutingOperationParam::getId, item.getId())
+        ) > 0;
+        if (duplicate) {
+            throw new ServiceException("Duplicate production order routing operation param");
+        }
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
index 90b1ba1..3895608 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
@@ -1,20 +1,142 @@
 package com.ruoyi.production.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
 import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
+import com.ruoyi.production.mapper.ProductionProductMainMapper;
+import com.ruoyi.production.pojo.ProductionOperationTask;
 import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
+import com.ruoyi.production.pojo.ProductionProductMain;
 import com.ruoyi.production.service.ProductionOrderRoutingOperationService;
+import com.ruoyi.production.service.ProductionProductMainService;
+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.List;
+
 @Service
-public class ProductionOrderRoutingOperationServiceImpl extends ServiceImpl<ProductionOrderRoutingOperationMapper, ProductionOrderRoutingOperation> implements ProductionOrderRoutingOperationService {
+@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor
+public class ProductionOrderRoutingOperationServiceImpl extends ServiceImpl<ProductionOrderRoutingOperationMapper, ProductionOrderRoutingOperation>
+        implements ProductionOrderRoutingOperationService {
 
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+    private final ProductionOperationTaskMapper productionOperationTaskMapper;
+    private final ProductionProductMainMapper productionProductMainMapper;
+    private final ProductionProductMainService productionProductMainService;
+
+    @Override
+    public R addRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        int insert = productionOrderRoutingOperationMapper.insert(productionOrderRoutingOperation);
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        if (insert > 0) {
+            ProductionOperationTask lastTask = productionOperationTaskMapper.selectOne(
+                    Wrappers.<ProductionOperationTask>lambdaQuery()
+                            .likeRight(ProductionOperationTask::getWorkOrderNo, "GD" + datePrefix)
+                            .orderByDesc(ProductionOperationTask::getWorkOrderNo)
+                            .last("limit 1"));
+            int sequenceNumber = 1;
+            if (lastTask != null && lastTask.getWorkOrderNo() != null) {
+                String lastNo = lastTask.getWorkOrderNo();
+                if (lastNo.startsWith("GD" + datePrefix)) {
+                    String seqStr = lastNo.substring(("GD" + datePrefix).length());
+                    try {
+                        sequenceNumber = Integer.parseInt(seqStr) + 1;
+                    } catch (NumberFormatException e) {
+                        sequenceNumber = 1;
+                    }
+                }
+            }
+            String workOrderNoStr = "GD" + String.format("%s%03d", datePrefix, sequenceNumber);
+            ProductionOperationTask productionOperationTask = new ProductionOperationTask();
+            productionOperationTask.setTechnologyRoutingOperationId(productionOrderRoutingOperation.getId());
+            productionOperationTask.setProductionOrderId(productionOrderRoutingOperation.getProductionOrderId());
+            productionOperationTask.setPlanQuantity(BigDecimal.ZERO);
+            productionOperationTask.setCompleteQuantity(BigDecimal.ZERO);
+            productionOperationTask.setWorkOrderNo(workOrderNoStr);
+            productionOperationTask.setStatus(1);
+            productionOperationTaskMapper.insert(productionOperationTask);
+        }
+        return R.ok();
+    }
+
+    @Override
+    public R deleteRouteItem(Long id) {
+        try {
+            ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectOne(
+                    new LambdaQueryWrapper<ProductionOperationTask>()
+                            .eq(ProductionOperationTask::getTechnologyRoutingOperationId, id)
+                            .last("limit 1"));
+            if (productionOperationTask == null) {
+                throw new RuntimeException("鍒犻櫎澶辫触锛氭湭鎵惧埌鍏宠仈鐨勭敓浜у伐鍗�");
+            }
+            if (productionOperationTask.getCompleteQuantity() != null
+                    && BigDecimal.ZERO.compareTo(productionOperationTask.getCompleteQuantity()) < 0) {
+                throw new RuntimeException("鍒犻櫎澶辫触锛氳宸ュ崟宸插紑濮嬬敓浜э紝璇峰厛鍒犻櫎鐢熶骇鎶ュ伐");
+            }
+            List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(
+                    new LambdaQueryWrapper<ProductionProductMain>()
+                            .eq(ProductionProductMain::getProductionOperationTaskId, productionOperationTask.getId()));
+            for (ProductionProductMain main : productionProductMains) {
+                productionProductMainService.removeProductMain(main.getId());
+            }
+            Long productionOrderId = productionOperationTask.getProductionOrderId();
+            Long routingId = null;
+            ProductionOrderRoutingOperation deleteItem = productionOrderRoutingOperationMapper.selectById(id);
+            if (deleteItem != null) {
+                routingId = deleteItem.getTechnologyRoutingId();
+            }
+            productionOperationTaskMapper.delete(new LambdaQueryWrapper<ProductionOperationTask>()
+                    .eq(ProductionOperationTask::getTechnologyRoutingOperationId, id));
+            productionOrderRoutingOperationMapper.deleteById(id);
+            if (routingId != null) {
+                List<ProductionOrderRoutingOperation> operationList = productionOrderRoutingOperationMapper.selectList(
+                        Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                                .eq(ProductionOrderRoutingOperation::getTechnologyRoutingId, routingId)
+                                .eq(ProductionOrderRoutingOperation::getProductionOrderId, productionOrderId)
+                                .orderByAsc(ProductionOrderRoutingOperation::getDragSort));
+                for (int i = 0; i < operationList.size(); i++) {
+                    ProductionOrderRoutingOperation item = operationList.get(i);
+                    if (!Integer.valueOf(i + 1).equals(item.getDragSort())) {
+                        item.setDragSort(i + 1);
+                        productionOrderRoutingOperationMapper.updateById(item);
+                    }
+                }
+            }
+            return R.ok();
+        } catch (Exception e) {
+            throw new RuntimeException("鍒犻櫎鐢熶骇宸ヨ壓璺嚎澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @Override
+    public int sortRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+        ProductionOrderRoutingOperation oldItem = productionOrderRoutingOperationMapper.selectById(productionOrderRoutingOperation.getId());
+        List<ProductionOrderRoutingOperation> operationList = productionOrderRoutingOperationMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperation::getTechnologyRoutingId, oldItem.getTechnologyRoutingId())
+                        .orderByAsc(ProductionOrderRoutingOperation::getDragSort));
+        Integer targetPosition = productionOrderRoutingOperation.getDragSort();
+        if (targetPosition != null && targetPosition >= 1) {
+            operationList.removeIf(item -> item.getId().equals(oldItem.getId()));
+            operationList.add(targetPosition - 1, oldItem);
+            for (int i = 0; i < operationList.size(); i++) {
+                ProductionOrderRoutingOperation item = operationList.get(i);
+                int dragSort = i + 1;
+                if (!Integer.valueOf(dragSort).equals(item.getDragSort())) {
+                    item.setDragSort(dragSort);
+                    productionOrderRoutingOperationMapper.updateById(item);
+                }
+            }
+            return 1;
+        }
+        return 0;
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingServiceImpl.java
index 393ebe0..41b091b 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingServiceImpl.java
@@ -1,20 +1,39 @@
 package com.ruoyi.production.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.production.mapper.ProductionOrderRoutingMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
 import com.ruoyi.production.pojo.ProductionOrderRouting;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
 import com.ruoyi.production.service.ProductionOrderRoutingService;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
-/**
- * <p>
- * 鐢熶骇璁㈠崟宸ヨ壓璺嚎琛� 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.util.List;
+
 @Service
+@RequiredArgsConstructor
 public class ProductionOrderRoutingServiceImpl extends ServiceImpl<ProductionOrderRoutingMapper, ProductionOrderRouting> implements ProductionOrderRoutingService {
 
+    private final ProductionOrderRoutingMapper productionOrderRoutingMapper;
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+
+    @Override
+    public ProductionOrderRouting listMain(Long orderId) {
+        return productionOrderRoutingMapper.selectOne(
+                Wrappers.<ProductionOrderRouting>lambdaQuery()
+                        .eq(ProductionOrderRouting::getProductionOrderId, orderId)
+                        .orderByDesc(ProductionOrderRouting::getId)
+                        .last("limit 1"));
+    }
+
+    @Override
+    public List<ProductionOrderRoutingOperation> listItem(Long orderId) {
+        return productionOrderRoutingOperationMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperation::getProductionOrderId, orderId)
+                        .orderByAsc(ProductionOrderRoutingOperation::getDragSort)
+                        .orderByAsc(ProductionOrderRoutingOperation::getId));
+    }
 }
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;
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
index 852bfca..6113736 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
@@ -1,558 +1,65 @@
-//package com.ruoyi.production.service.impl;
-//
-//import com.alibaba.fastjson2.JSONArray;
-//import com.alibaba.fastjson2.JSONObject;
-//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-//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.common.exception.ServiceException;
-//import com.ruoyi.common.exception.base.BaseException;
-//import com.ruoyi.common.utils.StringUtils;
-//import com.ruoyi.common.utils.bean.BeanUtils;
-//import com.ruoyi.common.utils.poi.ExcelUtil;
-//import com.ruoyi.production.bean.dto.ProductionPlanDto;
-//import com.ruoyi.production.bean.dto.ProductionPlanImportDto;
-//import com.ruoyi.production.bean.vo.ProductionPlanVo;
-//import com.ruoyi.production.mapper.ProductionPlanMapper;
-//import com.ruoyi.production.pojo.ProductionPlan;
-//import com.ruoyi.production.service.ProductionPlanService;
-//import lombok.RequiredArgsConstructor;
-//import org.springframework.stereotype.Service;
-//import org.springframework.transaction.annotation.Transactional;
-//import org.springframework.web.multipart.MultipartFile;
-//
-//import javax.servlet.http.HttpServletResponse;
-//import java.math.BigDecimal;
-//import java.time.Instant;
-//import java.time.LocalDateTime;
-//import java.time.ZoneId;
-//import java.util.*;
-//import java.util.concurrent.locks.ReentrantLock;
-//import java.util.stream.Collectors;
-//
-///**
-// * <p>
-// * 鐢熶骇璁″垝琛� 鏈嶅姟瀹炵幇绫�
-// * </p>
-// *
-// * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
-// * @since 2026-04-21 02:11:10
-// */
-//@Service
-//@RequiredArgsConstructor
-//public class ProductionPlanServiceImpl extends ServiceImpl<ProductionPlanMapper, ProductionPlan> implements ProductionPlanService {
-//
-//    private ProductionPlanMapper productionPlanMapper;
-//
-//
-//    /**
-//     * 鍚屾閿侊紝纭繚鎵嬪姩鍜屽畾鏃朵换鍔′笉鍚屾椂鎵ц
-//     */
-//    private final ReentrantLock syncLock = new ReentrantLock();
-//
-//    @Override
-//    public IPage<ProductionPlanVo> listPage(Page<ProductionPlanDto> page, ProductionPlanDto productionPlanDto) {
-//
-//        return productionPlanMapper.selectPage(page, null);
-//    }
-//
-//    /**
-//     * 椤甸潰鎵嬪姩鍚屾
-//     */
-//    @Override
-//    public void loadProdData() {
-//        syncProdData(1);
-//    }
-//
-//    /**
-//     * 瀹氭椂浠诲姟鍚屾
-//     */
-//    @Override
-//    public void syncProdDataJob() {
-//        syncProdData(2);
-//    }
-//
-//    /**
-//     * 鍚堝苟鐢熶骇璁″垝
-//     */
-//    @Override
-//    @Transactional(rollbackFor = Exception.class)
-//    public boolean combine(ProductionPlanDto productionPlanDto) {
-//        if (productionPlanDto.getIds() == null || productionPlanDto.getIds().isEmpty()) {
-//            return false;
-//        }
-//
-//        //  鏌ヨ涓荤敓浜ц鍒�
-//        List<ProductionPlanDto> plans = productionPlanMapper.selectWithMaterialByIds(productionPlanDto.getIds());
-//
-//        if (plans == null || plans.isEmpty()) {
-//            throw new ServiceException("涓嬪彂澶辫触,鐢熶骇璁″垝涓嶅瓨鍦�");
-//        }
-//
-//        //  鏍¢獙鏄惁瀛樺湪涓嶅悓鐨勪骇鍝佸悕绉�
-//        String firstProductName = plans.get(0).getProductName();
-//        if (plans.stream().anyMatch(p -> p.getProductName() == null || !p.getProductName().equals(firstProductName))) {
-//            throw new BaseException("鍚堝苟澶辫触锛屽瓨鍦ㄤ笉鍚岀殑浜у搧鍚嶇О");
-//        }
-//
-//        // 鏍¢獙鏄惁瀛樺湪涓嶅悓鐨勪骇鍝佽鏍�
-//        String firstProductSpec = plans.get(0).getModel();
-//        if (plans.stream().anyMatch(p -> p.getModel() == null || !p.getModel().equals(firstProductSpec))) {
-//            throw new BaseException("鍚堝苟澶辫触锛屽瓨鍦ㄤ笉鍚岀殑浜у搧瑙勬牸");
-//        }
-//
-//        // 鍙犲姞鍓╀綑鏂规暟
-//        BigDecimal totalRemainingVolume = plans.stream()
-//                .map(ProductionPlan::getRemainingVolume)
-//                .filter(Objects::nonNull)
-//                .reduce(BigDecimal.ZERO, BigDecimal::add);
-//        // 鍒ゆ柇涓嬪彂鏁伴噺鏄惁澶т簬绛変簬鍓╀綑鏂规暟
-//        if (productionPlanDto.getTotalAssignedQuantity().compareTo(totalRemainingVolume) > 0) {
-//            throw new BaseException("鎿嶄綔澶辫触锛屼笅鍙戞暟閲忎笉鑳藉ぇ浜庡墿浣欐柟鏁�");
-//        }
-//
-//        // 鍒涘缓鐢熶骇璁㈠崟
-//        ProductOrder productOrder = new ProductOrder();
-//        productOrder.setQuantity(productionPlanDto.getTotalAssignedQuantity());
-//        productOrder.setPlanCompleteTime(productionPlanDto.getPlanCompleteTime());
-//        productOrder.setStatus(ProductOrderStatusEnum.WAIT.getCode());
-//        productOrder.setStrength(productionPlanDto.getStrength());
-//        productOrder.setProductMaterialSkuId(plans.get(0).getProductMaterialSkuId());
-//
-//        Long orderId = productOrderService.insertProductOrder(productOrder);
-//
-//        //  褰撲笅鍙戠殑浜у搧涓虹爩鍧楁垨鏉挎潗锛屽氨鎷夊彇BOM瀛愰泦涓庡伐鑹鸿矾绾垮瓙闆嗘暟鎹瓨鍏ュ埌闄勮〃涓�
-//        if ("鐮屽潡".equals(productionPlanDto.getProductName())) {
-//            productOrder.setRouteId(productionOrderAppendixService.populateBlocks(orderId, productionPlanDto));
-//        }
-//        if ("鏉挎潗".equals(productionPlanDto.getProductName())) {
-//            productOrder.setRouteId(productionOrderAppendixService.populatePlates(orderId, productionPlanDto));
-//        }
-//        //  鏇存柊缁戝畾鐨勫伐鑹鸿矾绾�
-//        productOrderService.updateById(productOrder);
-//
-//        // 鏍规嵁涓嬪彂鏁伴噺锛屼粠绗竴涓敓浜ц鍒掑紑濮嬪垎閰嶆柟鏁�
-//        BigDecimal assignedVolume = BigDecimal.ZERO;
-//        for (ProductionPlan plan : plans) {
-//            BigDecimal volume = plan.getVolume();
-//            if (volume == null) {
-//                continue;
-//            }
-//            // 璁$畻鍓╀綑鏂规暟
-//            BigDecimal remainingVolume = plan.getRemainingVolume();
-//            if (remainingVolume.compareTo(BigDecimal.ZERO) <= 0) {
-//                continue;
-//            }
-//
-//            ProductOrderPlan productOrderPlan = new ProductOrderPlan();
-//            productOrderPlan.setProductOrderId(productOrder.getId());
-//            productOrderPlan.setProductionPlanId(plan.getId());
-//
-//            if (assignedVolume.add(remainingVolume).compareTo(productionPlanDto.getTotalAssignedQuantity()) >= 0) {
-//                // 鏈�鍚庝竴涓鍒掞紝鍒嗛厤鍓╀綑鏂规暟
-//                BigDecimal lastRemainingVolume = productionPlanDto.getTotalAssignedQuantity().subtract(assignedVolume);
-//                BigDecimal assignedQuantity = Optional.ofNullable(plan.getAssignedQuantity()).orElse(BigDecimal.ZERO).add(lastRemainingVolume);
-//                plan.setAssignedQuantity(assignedQuantity);
-//                plan.setStatus(assignedQuantity.compareTo(plan.getVolume()) >= 0 ? 2 : 1);
-//                productOrderPlan.setAssignedQuantity(lastRemainingVolume);
-//                productionPlanMapper.updateById(plan);
-//                productOrderPlanMapper.insert(productOrderPlan);
-//                break;
-//            }
-//
-//            // 鍒嗛厤褰撳墠璁″垝鏂规暟
-//            BigDecimal assignedQuantity = Optional.ofNullable(plan.getAssignedQuantity()).orElse(BigDecimal.ZERO).add(remainingVolume);
-//            plan.setAssignedQuantity(assignedQuantity);
-//            plan.setStatus(assignedQuantity.compareTo(plan.getVolume()) >= 0 ? 2 : 1);
-//            productOrderPlan.setAssignedQuantity(remainingVolume);
-//            // 鏇存柊鐢熶骇璁″垝
-//            productionPlanMapper.updateById(plan);
-//            // 鍒涘缓鍏宠仈鍏崇郴
-//            productOrderPlanMapper.insert(productOrderPlan);
-//            assignedVolume = assignedVolume.add(remainingVolume);
-//        }
-//
-//        for (ProductionPlan plan : plans) {
-//            BigDecimal assignedQuantity = Optional.ofNullable(plan.getAssignedQuantity()).orElse(BigDecimal.ZERO);
-//            BigDecimal volume = Optional.ofNullable(plan.getVolume()).orElse(BigDecimal.ZERO);
-//            if (assignedQuantity.compareTo(BigDecimal.ZERO) <= 0) {
-//                plan.setStatus(0);
-//            } else if (assignedQuantity.compareTo(volume) >= 0) {
-//                plan.setStatus(2);
-//            } else {
-//                plan.setStatus(1);
-//            }
-//            productionPlanMapper.updateById(plan);
-//        }
-//        return true;
-//    }
-//
-//    @Override
-//    @Transactional(rollbackFor = Exception.class)
-//    public boolean add(ProductionPlanDto productionPlanDto) {
-//        if (StringUtils.isEmpty(productionPlanDto.getApplyNo())) {
-//            throw new ServiceException("鏂板澶辫触锛岀敵璇峰崟缂栧彿涓嶈兘涓虹┖");
-//        }
-//        Long count = productionPlanMapper.selectCount(Wrappers.<ProductionPlan>lambdaQuery()
-//                .eq(ProductionPlan::getApplyNo, productionPlanDto.getApplyNo()));
-//        if (count > 0) {
-//            throw new ServiceException("鏂板澶辫触锛岀敵璇峰崟缂栧彿 " + productionPlanDto.getApplyNo() + " 宸插瓨鍦�");
-//        }
-//        productionPlanDto.setDataSourceType(DataSourceTypeEnum.MANUAL.getCode());
-//        productionPlanDto.setStatus(0);
-//        productionPlanMapper.insert(productionPlanDto);
-//        return true;
-//    }
-//
-//    @Override
-//    @Transactional(rollbackFor = Exception.class)
-//    public boolean update(ProductionPlanDto productionPlanDto) {
-//        if (productionPlanDto == null || productionPlanDto.getId() == null) {
-//            throw new ServiceException("缂栬緫澶辫触,鏁版嵁涓嶈兘涓虹┖");
-//        }
-//        ProductionPlan productionPlan = getById(productionPlanDto.getId());
-//        if (productionPlan == null) {
-//            throw new ServiceException("缂栬緫澶辫触,涓荤敓浜ц鍒掍笉瀛樺湪");
-//        }
-//
-//        if (StringUtils.isNotEmpty(productionPlanDto.getApplyNo())
-//                && !productionPlanDto.getApplyNo().equals(productionPlan.getApplyNo())) {
-//
-//            Long count = productionPlanMapper.selectCount(Wrappers.<ProductionPlan>lambdaQuery()
-//                    .eq(ProductionPlan::getApplyNo, productionPlanDto.getApplyNo())
-//                    .ne(ProductionPlan::getId, productionPlanDto.getId())); // 鎺掗櫎鑷韩
-//
-//            if (count > 0) {
-//                throw new ServiceException("缂栬緫澶辫触锛岀敵璇峰崟缂栧彿 " + productionPlanDto.getApplyNo() + " 宸茶鍗犵敤");
-//            }
-//        }
-//        // 宸蹭笅鍙戠姸鎬侊紝涓嶈兘缂栬緫
-//        if (productionPlan.getStatus() != 0) {
-//            throw new BaseException("缂栬緫澶辫触,璇ョ敓浜ц鍒掑凡涓嬪彂鎴栭儴鍒嗕笅鍙戠姸鎬�,绂佹缂栬緫");
-//        }
-//
-//        // 鏌ヨ鏄惁鏈夊叧鑱旇鍗�
-//        boolean hasProductOrderPlan = productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery()
-//                        .eq(ProductOrderPlan::getProductionPlanId, productionPlanDto.getId()))
-//                .stream().anyMatch(p -> p.getProductOrderId() != null);
-//
-//        if (hasProductOrderPlan) {
-//            if (productionPlanDto.getVolume().compareTo(productionPlan.getVolume()) < 0) {
-//                throw new BaseException("鏂规暟涓嶈兘閫掑噺");
-//            }
-//        }
-//
-//        return productionPlanMapper.updateById(productionPlanDto) > 0;
-//    }
-//
-//    @Override
-//    @Transactional(rollbackFor = Exception.class)
-//    public boolean delete(List<Long> ids) {
-//        // 濡傛灉瀛樺湪宸蹭笅鍙戠殑璁″垝锛屽垯涓嶈兘鍒犻櫎
-//        if (productionPlanMapper.selectList(Wrappers.<ProductionPlan>lambdaQuery().in(ProductionPlan::getId, ids)).stream().anyMatch(p -> p.getStatus() == 1 || p.getStatus() == 2)) {
-//            throw new BaseException("鍒犻櫎澶辫触锛屽瓨鍦ㄥ凡涓嬪彂鎴栭儴鍒嗕笅鍙戠殑璁″垝");
-//        }
-//        // 濡傛灉鏈夊叧鑱旇鍗曪紝鍒欎笉鑳藉垹闄�
-//        if (productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductionPlanId, ids)).stream().anyMatch(p -> p.getProductOrderId() != null)) {
-//            throw new BaseException("鍒犻櫎澶辫触锛屽瓨鍦ㄥ叧鑱旇鍗�");
-//        }
-//
-//        return productionPlanMapper.deleteBatchIds(ids) > 0;
-//    }
-//
-//    /**
-//     * 鍚屾鏁版嵁
-//     */
-//    @Transactional(rollbackFor = Exception.class)
-//    public void syncProdData(Integer dataSyncType) {
-//        if (!syncLock.tryLock()) {
-//            log.warn("鍚屾姝e湪杩涜涓紝鏈 {} 鍚屾璇锋眰琚烦杩�", dataSyncType == 1 ? "鎵嬪姩鍚屾" : "瀹氭椂浠诲姟鍚屾");
-//            return;
-//        }
-//
-//        try {
-//            JSONArray searchConditions = new JSONArray();
-//            JSONObject condition = new JSONObject();
-//            condition.put("key", "processApprovedResult");
-//            JSONArray valueArray = new JSONArray();
-//            valueArray.add("agree");
-//
-//            condition.put("value", valueArray);
-//            condition.put("type", "ARRAY");
-//            condition.put("operator", "in");
-//            condition.put("componentName", "SelectField");
-//            searchConditions.add(condition);
-//
-//            String searchFieldJson = searchConditions.toJSONString();
-//
-//            JSONArray dataArr = AliDingUtils.getFormDataList(aliDingConfig, aliDingConfig.getProducePlanFormUuid(), searchFieldJson, this, ProductionPlan::getFormModifiedTime);
-//
-//            if (dataArr.isEmpty()) {
-//                log.info("娌℃湁鏇村鏂版暟鎹渶瑕佸悓姝�");
-//                return;
-//            }
-//
-//            //  瑙f瀽骞朵繚瀛樻暟鎹�
-//            List<ProductionPlan> list = parseProductionPlans(dataArr, dataSyncType, dataArr.size());
-//            if (!list.isEmpty()) {
-//                //  澶勭悊鏇存柊鎴栨柊澧�
-//                int affected = processSaveOrUpdate(list);
-//                log.info("鏁版嵁鍚屾瀹屾垚锛屽叡鍚屾 {} 鏉℃暟鎹�", affected);
-//            }
-//
-//        } catch (Exception e) {
-//            log.error("鍚屾鐢熶骇璁″垝寮傚父", e);
-//        } finally {
-//            // 閲婃斁閿�
-//            syncLock.unlock();
-//        }
-//    }
-//
-//    private List<ProductionPlan> parseProductionPlans(JSONArray dataArr, Integer dataSyncType, Integer totalCount) {
-//        List<ProductionPlan> list = new ArrayList<>();
-//        LocalDateTime now = LocalDateTime.now();
-//
-//        for (int i = 0; i < dataArr.size(); i++) {
-//            JSONObject item = dataArr.getJSONObject(i);
-//            String formInstanceId = item.getString("formInstanceId");
-//            String serialNo = item.getString("serialNo");
-//
-//            JSONObject originator = item.getJSONObject("originator");
-//            String originatorName = originator != null && originator.containsKey("userName")
-//                    ? originator.getJSONObject("userName").getString("nameInChinese") : "鏈煡";
-//
-//            JSONObject formData = item.getJSONObject("formData");
-//            JSONArray tableArr = formData.getJSONArray("tableField_l7fytfcn");
-//            if (tableArr == null || tableArr.isEmpty()) {
-//                continue;
-//            }
-//
-//            for (int j = 0; j < tableArr.size(); j++) {
-//                JSONObject row = tableArr.getJSONObject(j);
-//                ProductionPlan plan = new ProductionPlan();
-//
-//                plan.setFormInstanceId(formInstanceId);
-//                plan.setSerialNo(serialNo);
-//                plan.setApplyNo(formData.getString("textField_l7fytfco"));
-//                plan.setCustomerName(formData.getString("textField_lbkozohg"));
-//
-//                String materialCode = row.getString("textField_l9xo62q5");
-//                // 鏍规嵁鐗╂枡缂栫爜鏌ヨ鐗╂枡淇℃伅琛紝鍏宠仈鐗╂枡ID
-//                if (StringUtils.isNotEmpty(materialCode)) {
-//                    LambdaQueryWrapper<ProductMaterialSku> skuQueryWrapper = new LambdaQueryWrapper<>();
-//                    skuQueryWrapper.eq(ProductMaterialSku::getMaterialCode, materialCode);
-//                    ProductMaterialSku sku = productMaterialSkuService.getOne(skuQueryWrapper);
-//                    if (sku != null) {
-//                        plan.setProductMaterialSkuId(sku.getId());
-//                    }
-//                }
-//
-//                plan.setLength(row.getInteger("numberField_lb7lgatg_value"));
-//                plan.setWidth(row.getInteger("numberField_lb7lgath_value"));
-//                plan.setHeight(row.getInteger("numberField_lb7lgati_value"));
-//                plan.setQuantity(row.getInteger("numberField_lb7lgatj_value"));
-//                plan.setVolume(row.getBigDecimal("numberField_l7fytfd3_value"));
-//                plan.setStrength(row.getString("radioField_m9urarr2_id"));
-//
-//                JSONArray dateArr = row.getJSONArray("cascadeDateField_lfxqqluw");
-//                if (dateArr != null && dateArr.size() == 2) {
-//                    try {
-//                        long start = Long.parseLong(dateArr.getString(0));
-//                        long end = Long.parseLong(dateArr.getString(1));
-//
-//                        Date startDate = Date.from(Instant.ofEpochMilli(start)
-//                                .atZone(ZoneId.systemDefault())
-//                                .toLocalDate()
-//                                .atStartOfDay(ZoneId.systemDefault())
-//                                .toInstant());
-//                        Date endDate = Date.from(Instant.ofEpochMilli(end)
-//                                .atZone(ZoneId.systemDefault())
-//                                .toLocalDate()
-//                                .atStartOfDay(ZoneId.systemDefault())
-//                                .toInstant());
-//
-//                        plan.setStartDate(startDate);
-//                        plan.setEndDate(endDate);
-//                    } catch (Exception e) {
-//                        log.warn("瑙f瀽鏃ユ湡澶辫触: {}", dateArr);
-//                    }
-//                }
-//
-//                plan.setSubmitter(originatorName);
-//                plan.setSubmitOrg("瀹佸涓垱缁胯兘瀹炰笟闆嗗洟鏈夐檺鍏徃");
-//                plan.setRemarkOne(formData.getString("textareaField_l7fytfcy"));
-//                plan.setRemarkTwo(formData.getString("textField_l7fytfcx"));
-//                plan.setCreatorName(originatorName);
-//
-//                JSONObject modifyUser = item.getJSONObject("modifyUser");
-//                if (modifyUser != null && modifyUser.containsKey("userName")) {
-//                    plan.setModifierName(modifyUser.getJSONObject("userName").getString("nameInChinese"));
-//                }
-//
-//                plan.setFormCreatedTime(AliDingUtils.parseUtcTime(item.getString("createdTimeGMT")));
-//                plan.setFormModifiedTime(AliDingUtils.parseUtcTime(item.getString("modifiedTimeGMT")));
-//                plan.setDataSourceType(DataSourceTypeEnum.DING_TALK.getCode());
-//                plan.setCreateTime(now);
-//                plan.setUpdateTime(now);
-//                plan.setTotalCount(totalCount);
-//
-//                list.add(plan);
-//            }
-//        }
-//        return list;
-//    }
-//
-//    private int processSaveOrUpdate(List<ProductionPlan> list) {
-//        if (list == null || list.isEmpty()) {
-//            return 0;
-//        }
-//        int affected = 0;
-//
-//        //  鍘婚噸 formInstanceId
-//        Set<String> formIds = list.stream()
-//                .map(ProductionPlan::getFormInstanceId)
-//                .collect(Collectors.toSet());
-//
-//        //  鏌ヨ鏁版嵁搴撳凡鏈夋暟鎹�
-//        List<ProductionPlan> existList = this.list(new LambdaQueryWrapper<ProductionPlan>().in(ProductionPlan::getFormInstanceId, formIds));
-//
-//        //  Map (formInstanceId + materialCode)
-//        Map<String, ProductionPlan> existMap = new HashMap<>();
-//        for (ProductionPlan p : existList) {
-//            String key = p.getFormInstanceId() + "_" + p.getProductMaterialSkuId();
-//            existMap.put(key, p);
-//        }
-//
-//        //  閬嶅巻鍚屾鏁版嵁
-//        for (ProductionPlan plan : list) {
-//            String key = plan.getFormInstanceId() + "_" + plan.getProductMaterialSkuId();
-//            ProductionPlan exist = existMap.get(key);
-//            if (exist == null) {
-//                // 鏂板
-//                this.save(plan);
-//                affected++;
-//                log.info("鏂板鏁版嵁 formInstanceId={}, materialCode={}", plan.getFormInstanceId(), plan.getProductMaterialSkuId());
-//            } else {
-//                // 鍒ゆ柇鏄惁闇�瑕佹洿鏂�
-//                if (exist.getFormModifiedTime() == null || !exist.getFormModifiedTime().equals(plan.getFormModifiedTime())) {
-//                    plan.setId(exist.getId());
-//                    plan.setCreateTime(exist.getCreateTime());
-//                    this.updateById(plan);
-//                    affected++;
-//                    log.info("鏇存柊鏁版嵁 formInstanceId={}, materialCode={}", plan.getFormInstanceId(), plan.getProductMaterialSkuId());
-//                }
-//            }
-//        }
-//        return affected;
-//    }
-//
-//    @Override
-//    public List<ProductionPlanSummaryDto> summaryByProductType(ProductionPlanSummaryDto query) {
-//        return baseMapper.selectSummaryByProductType(query);
-//    }
-//
-//    @Override
-//    @Transactional(rollbackFor = Exception.class)
-//    public void importProdData(MultipartFile file) {
-//        if (file == null || file.isEmpty()) {
-//            throw new ServiceException("瀵煎叆鏁版嵁涓嶈兘涓虹┖");
-//        }
-//        ExcelUtil<ProductionPlanImportDto> excelUtil = new ExcelUtil<>(ProductionPlanImportDto.class);
-//        List<ProductionPlanImportDto> list;
-//        try {
-//            list = excelUtil.importExcel(file.getInputStream());
-//        } catch (Exception e) {
-//            log.error("鐢熶骇闇�姹侲xcel瀵煎叆澶辫触", e);
-//            throw new ServiceException("Excel瑙f瀽澶辫触");
-//        }
-//
-//        if (list == null || list.isEmpty()) {
-//            throw new ServiceException("Excel娌℃湁鏁版嵁");
-//        }
-//
-//        Set<String> applyNos = new HashSet<>();
-//        Set<String> materialCodes = new HashSet<>();
-//        for (int i = 0; i < list.size(); i++) {
-//            ProductionPlanImportDto dto = list.get(i);
-//            String applyNo = dto.getApplyNo();
-//            String materialCode = dto.getMaterialCode();
-//
-//            if (StringUtils.isEmpty(applyNo)) {
-//                throw new ServiceException("瀵煎叆澶辫触锛氱 " + (i + 2) + " 琛岀敵璇峰崟缂栧彿涓嶈兘涓虹┖");
-//            }
-//            if (!applyNos.add(applyNo)) {
-//                throw new ServiceException("瀵煎叆澶辫触锛欵xcel 涓瓨鍦ㄩ噸澶嶇殑鐢宠鍗曠紪鍙�: " + applyNo);
-//            }
-//            if (StringUtils.isEmpty(materialCode)) {
-//                throw new ServiceException("瀵煎叆澶辫触锛氱 " + (i + 2) + " 琛岀墿鏂欑紪鐮佷笉鑳戒负绌�");
-//            }
-//
-//            String strength = dto.getStrength();
-//            if (StringUtils.isNotEmpty(strength)) {
-//                if (!"A3.5".equals(strength) && !"A5.0".equals(strength)) {
-//                    throw new ServiceException("瀵煎叆澶辫触锛氱 " + (i + 2) + " 琛屽己搴﹀彧鑳芥槸 A3.5 鎴� A5.0");
-//                }
-//            }
-//
-//            materialCodes.add(materialCode);
-//        }
-//
-//        //  鐢宠鍗曠紪鍙锋槸鍚﹀凡瀛樺湪
-//        Long existApplyNoCount = baseMapper.selectCount(Wrappers.<ProductionPlan>lambdaQuery()
-//                .in(ProductionPlan::getApplyNo, applyNos));
-//        if (existApplyNoCount > 0) {
-//            List<String> existApplyNos = baseMapper.selectList(Wrappers.<ProductionPlan>lambdaQuery()
-//                            .in(ProductionPlan::getApplyNo, applyNos))
-//                    .stream().map(ProductionPlan::getApplyNo).collect(Collectors.toList());
-//            throw new ServiceException("瀵煎叆澶辫触锛岀敵璇峰崟缂栧彿宸插瓨鍦�: " + String.join(", ", existApplyNos));
-//        }
-//
-//        Map<String, Long> skuMap = productMaterialSkuService.list(Wrappers.<ProductMaterialSku>lambdaQuery()
-//                        .in(ProductMaterialSku::getMaterialCode, materialCodes))
-//                .stream().collect(Collectors.toMap(ProductMaterialSku::getMaterialCode, ProductMaterialSku::getId, (k1, k2) -> k1));
-//
-//        List<String> missingCodes = materialCodes.stream()
-//                .filter(code -> !skuMap.containsKey(code))
-//                .collect(Collectors.toList());
-//        if (!missingCodes.isEmpty()) {
-//            throw new ServiceException("瀵煎叆澶辫触锛屼互涓嬬墿鏂欑紪鐮佷笉瀛樺湪: " + String.join(", ", missingCodes));
-//        }
-//
-//        LocalDateTime now = LocalDateTime.now();
-//        List<ProductionPlan> entityList = list.stream().map(dto -> {
-//            ProductionPlan entity = new ProductionPlan();
-//            BeanUtils.copyProperties(dto, entity);
-//            entity.setProductMaterialSkuId(skuMap.get(dto.getMaterialCode()));
-//            entity.setAssignedQuantity(BigDecimal.ZERO);
-//            entity.setDataSourceType(DataSourceTypeEnum.MANUAL.getCode());
-//            entity.setStatus(0);
-//            entity.setCreateTime(now);
-//            entity.setUpdateTime(now);
-//            return entity;
-//        }).collect(Collectors.toList());
-//
-//        this.saveBatch(entityList);
-//    }
-//
-//    @Override
-//    public void exportProdData(HttpServletResponse response, List<Long> ids) {
-//        List<ProductionPlan> list;
-//        if (ids != null && !ids.isEmpty()) {
-//            list = baseMapper.selectBatchIds(ids);
-//        } else {
-//            list = baseMapper.selectList(null);
-//        }
-//
-//        List<ProductionPlanImportDto> exportList = new ArrayList<>();
-//        for (ProductionPlan entity : list) {
-//            ProductionPlanImportDto dto = new ProductionPlanImportDto();
-//            BeanUtils.copyProperties(entity, dto);
-//            exportList.add(dto);
-//        }
-//        ExcelUtil<ProductionPlanImportDto> util = new ExcelUtil<>(ProductionPlanImportDto.class);
-//        util.exportExcel(response, exportList, "閿�鍞敓浜ч渶姹傛暟鎹�");
-//    }
-//
-//}
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.bean.dto.ProductionPlanDto;
+import com.ruoyi.production.bean.vo.ProductionPlanVo;
+import com.ruoyi.production.mapper.ProductionPlanMapper;
+import com.ruoyi.production.pojo.ProductionPlan;
+import com.ruoyi.production.service.ProductionPlanService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class ProductionPlanServiceImpl extends ServiceImpl<ProductionPlanMapper, ProductionPlan> implements ProductionPlanService {
+    @Override
+    public IPage<ProductionPlanVo> listPage(Page<ProductionPlanDto> page, ProductionPlanDto productionPlanDto) {
+        return null;
+    }
+
+    @Override
+    public void loadProdData() {
+
+    }
+
+    @Override
+    public void syncProdDataJob() {
+
+    }
+
+    @Override
+    public boolean combine(ProductionPlanDto productionPlanDto) {
+        return false;
+    }
+
+    @Override
+    public boolean add(ProductionPlanDto productionPlanDto) {
+        return false;
+    }
+
+    @Override
+    public boolean update(ProductionPlanDto productionPlanDto) {
+        return false;
+    }
+
+    @Override
+    public boolean delete(List<Long> ids) {
+        return false;
+    }
+
+    @Override
+    public void importProdData(MultipartFile file) {
+
+    }
+
+    @Override
+    public void exportProdData(HttpServletResponse response, List<Long> ids) {
+
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
index 252e408..d46c317 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
@@ -1,20 +1,24 @@
 package com.ruoyi.production.service.impl;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.bean.dto.ProductionProductInputDto;
 import com.ruoyi.production.mapper.ProductionProductInputMapper;
 import com.ruoyi.production.pojo.ProductionProductInput;
 import com.ruoyi.production.service.ProductionProductInputService;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐鎶曞叆琛� 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
 @Service
+@AllArgsConstructor
 public class ProductionProductInputServiceImpl extends ServiceImpl<ProductionProductInputMapper, ProductionProductInput> implements ProductionProductInputService {
+    @Autowired
+    private ProductionProductInputMapper productionProductInputMapper;
 
+    @Override
+    public IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, ProductionProductInputDto productionProductInputDto) {
+        return productionProductInputMapper.listPageProductionProductInputDto(page, productionProductInputDto);
+    }
 }
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 9ec1e06..92fd9f2 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -1,20 +1,345 @@
 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.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.production.mapper.ProductionProductMainMapper;
-import com.ruoyi.production.pojo.ProductionProductMain;
+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;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
 import com.ruoyi.production.service.ProductionProductMainService;
+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.technology.mapper.TechnologyOperationMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper;
+import com.ruoyi.technology.pojo.TechnologyOperation;
+import com.ruoyi.technology.pojo.TechnologyRoutingOperation;
+import lombok.AllArgsConstructor;
 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.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
 @Service
+@AllArgsConstructor
+@Transactional(rollbackFor = Exception.class)
 public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
 
+    private final ProductionProductMainMapper productionProductMainMapper;
+    private final SysUserMapper userMapper;
+    private final ProductionProductOutputMapper productionProductOutputMapper;
+    private final ProductModelMapper productModelMapper;
+    private final QualityInspectMapper qualityInspectMapper;
+    private final QualityUnqualifiedMapper qualityUnqualifiedMapper;
+    private final ProductMapper productMapper;
+    private final QualityTestStandardParamMapper qualityTestStandardParamMapper;
+    private final QualityTestStandardMapper qualityTestStandardMapper;
+    private final QualityInspectParamMapper qualityInspectParamMapper;
+    private final ProductionProductInputMapper productionProductInputMapper;
+    private final ProductionAccountMapper productionAccountMapper;
+    private final ProductionOperationTaskMapper productionOperationTaskMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
+    private final TechnologyOperationMapper technologyOperationMapper;
+    private final StockUtils stockUtils;
+
+    @Override
+    public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) {
+        return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
+    }
+
+    @Override
+    public IPage<ProductionProductMainDto> pageProductionProductMain(Page page, ProductionProductMainDto productionProductMainDto) {
+        return listPageProductionProductMainDto(page, productionProductMainDto);
+    }
+
+    @Override
+    public ProductionProductMainDto getProductionProductMainInfo(Long id) {
+        return productionProductMainMapper.listPageProductionProductMainDto(new Page<>(1, 1), new ProductionProductMainDto() {{
+            setId(id);
+        }}).getRecords().stream().findFirst().orElse(null);
+    }
+
+    @Override
+    public Boolean addProductMain(ProductionProductMainDto dto) {
+        if (dto.getProductionOperationTaskId() == null) {
+            throw new ServiceException("璇蜂紶鍏ョ敓浜у伐鍗旾D");
+        }
+        return addProductMainByProductionTask(dto);
+    }
+
+    @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;
+        }
+        return removeProductMainByProductionTask(currentMain);
+    }
+
+    private Boolean addProductMainByProductionTask(ProductionProductMainDto dto) {
+        SysUser user = userMapper.selectUserById(dto.getUserId());
+        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(dto.getProductionOperationTaskId());
+        if (productionOperationTask == null) {
+            throw new ServiceException("鐢熶骇宸ュ崟涓嶅瓨鍦�");
+        }
+        ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getTechnologyRoutingOperationId());
+        if (routingOperation == null) {
+            throw new ServiceException("璁㈠崟宸ヨ壓璺嚎宸ュ簭涓嶅瓨鍦�");
+        }
+        ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId());
+        if (productionOrder == null) {
+            throw new ServiceException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+        }
+        TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId());
+        TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null
+                : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId());
+        ProductModel productModel = productModelMapper.selectById(
+                routingOperation.getProductModelId() != null ? routingOperation.getProductModelId() : productionOrder.getProductModelId());
+        if (productModel == null) {
+            throw new ServiceException("浜у搧瑙勬牸涓嶅瓨鍦�");
+        }
+
+        ProductionProductMain productionProductMain = new ProductionProductMain();
+        productionProductMain.setProductNo(generateProductNo());
+        productionProductMain.setUserId(dto.getUserId());
+        productionProductMain.setUserName(dto.getUserName());
+        productionProductMain.setProductionOperationTaskId(productionOperationTask.getId());
+        productionProductMain.setWorkOrderId(productionOperationTask.getId());
+        productionProductMain.setStatus(0);
+        productionProductMainMapper.insert(productionProductMain);
+
+        List<ProductStructureDto> productStructureDtos = new ArrayList<>();
+        ProductStructureDto productStructureDto = new ProductStructureDto();
+        productStructureDto.setProductModelId(productModel.getId());
+        productStructureDto.setUnitQuantity(BigDecimal.ONE);
+        productStructureDtos.add(productStructureDto);
+        for (ProductStructureDto item : productStructureDtos) {
+            ProductionProductInput productionProductInput = new ProductionProductInput();
+            productionProductInput.setProductionProductMainId(productionProductMain.getId());
+            productionProductInput.setProductMainId(productionProductMain.getId());
+            productionProductInput.setProductModelId(item.getProductModelId());
+            productionProductInput.setInputQuantity(item.getUnitQuantity().multiply(defaultDecimal(dto.getQuantity())));
+            productionProductInput.setQuantity(productionProductInput.getInputQuantity());
+            productionProductInputMapper.insert(productionProductInput);
+            stockUtils.substractStock(item.getProductModelId(), productionProductInput.getInputQuantity(),
+                    StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId());
+        }
+
+        ProductionProductOutput productionProductOutput = new ProductionProductOutput();
+        productionProductOutput.setProductionProductMainId(productionProductMain.getId());
+        productionProductOutput.setProductMainId(productionProductMain.getId());
+        productionProductOutput.setProductModelId(productModel.getId());
+        productionProductOutput.setQuantity(defaultDecimal(dto.getQuantity()));
+        productionProductOutput.setScrapQty(defaultDecimal(dto.getScrapQty()));
+        productionProductOutputMapper.insert(productionProductOutput);
+        BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty());
+
+        List<ProductionOrderRoutingOperation> routingOperationList = productionOrderRoutingOperationMapper.selectList(
+                Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                        .eq(ProductionOrderRoutingOperation::getTechnologyRoutingId, routingOperation.getTechnologyRoutingId())
+                        .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.size() > 0) {
+                    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 {
+                stockUtils.addStock(productModel.getId(), productQty,
+                        StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
+            }
+
+            productionOperationTask.setCompleteQuantity(defaultDecimal(productionOperationTask.getCompleteQuantity()).add(productQty));
+            if (ObjectUtils.isNull(productionOperationTask.getActualStartTime())) {
+                productionOperationTask.setActualStartTime(LocalDate.now());
+            }
+            if (productionOperationTask.getPlanQuantity() != null
+                    && productionOperationTask.getCompleteQuantity().compareTo(productionOperationTask.getPlanQuantity()) >= 0) {
+                productionOperationTask.setActualEndTime(LocalDate.now());
+            }
+            productionOperationTaskMapper.updateById(productionOperationTask);
+
+            if (ObjectUtils.isNull(productionOrder.getStartTime())) {
+                productionOrder.setStartTime(LocalDateTime.now());
+            }
+            if (isLastOperation) {
+                productionOrder.setCompleteQuantity(defaultDecimal(productionOrder.getCompleteQuantity()).add(productQty));
+                if (productionOrder.getQuantity() != null
+                        && productionOrder.getCompleteQuantity().compareTo(productionOrder.getQuantity()) >= 0) {
+                    productionOrder.setEndTime(LocalDateTime.now());
+                }
+            }
+            productionOrderMapper.updateById(productionOrder);
+
+            BigDecimal workHours = BigDecimal.ZERO;
+            if (technologyOperation != null && technologyOperation.getSalaryQuota() != null) {
+                workHours = Integer.valueOf(1).equals(technologyOperation.getType())
+                        ? technologyOperation.getSalaryQuota().multiply(productQty)
+                        : technologyOperation.getSalaryQuota();
+            }
+            ProductionAccount productionAccount = new ProductionAccount();
+            productionAccount.setProductionProductMainId(productionProductMain.getId());
+            productionAccount.setSalesLedgerId(productionOrder.getSalesLedgerId());
+            productionAccount.setSalesLedgerProductId(productionOrder.getSaleLedgerProductId() == null ? null : productionOrder.getSaleLedgerProductId().longValue());
+            productionAccount.setSchedulingUserId(user == null ? null : user.getUserId());
+            productionAccount.setSchedulingUserName(user == null ? dto.getUserName() : user.getNickName());
+            productionAccount.setFinishedNum(productQty);
+            productionAccount.setWorkHours(workHours);
+            productionAccount.setTechnologyOperationName(technologyOperation == null ? null : technologyOperation.getName());
+            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;
+    }
+
+    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("璇ユ潯鎶ュ伐宸茬粡涓嶅悎鏍煎鐞嗕簡锛屼笉鍏佽鍒犻櫎");
+            }
+        }
+        ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(
+                Wrappers.<ProductionProductOutput>lambdaQuery()
+                        .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId()))
+                .stream().findFirst().orElse(null);
+        productionAccountMapper.delete(new LambdaQueryWrapper<ProductionAccount>()
+                .eq(ProductionAccount::getProductionProductMainId, productionProductMain.getId()));
+
+        ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectById(productionProductMain.getProductionOperationTaskId());
+        if (productionOperationTask != null && productionProductOutput != null) {
+            BigDecimal validQuantity = defaultDecimal(productionProductOutput.getQuantity()).subtract(defaultDecimal(productionProductOutput.getScrapQty()));
+            productionOperationTask.setCompleteQuantity(defaultDecimal(productionOperationTask.getCompleteQuantity()).subtract(validQuantity));
+            productionOperationTask.setActualEndTime(null);
+            productionOperationTaskMapper.updateById(productionOperationTask);
+
+            ProductionOrder productionOrder = productionOrderMapper.selectById(productionOperationTask.getProductionOrderId());
+            ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(productionOperationTask.getTechnologyRoutingOperationId());
+            if (productionOrder != null && routingOperation != null) {
+                List<ProductionOrderRoutingOperation> routingOperationList = productionOrderRoutingOperationMapper.selectList(
+                        Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+                                .eq(ProductionOrderRoutingOperation::getTechnologyRoutingId, routingOperation.getTechnologyRoutingId())
+                                .eq(ProductionOrderRoutingOperation::getProductionOrderId, routingOperation.getProductionOrderId()));
+                boolean isLastOperation = routingOperation.getDragSort() != null && routingOperation.getDragSort().equals(routingOperationList.size());
+                if (isLastOperation) {
+                    BigDecimal newCompleteQty = defaultDecimal(productionOrder.getCompleteQuantity()).subtract(validQuantity);
+                    productionOrder.setCompleteQuantity(newCompleteQty.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : newCompleteQty);
+                    productionOrder.setEndTime(null);
+                    productionOrderMapper.updateById(productionOrder);
+                }
+            }
+        }
+
+        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>()
+                .eq(ProductionProductInput::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());
+        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);
+        List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper);
+        int sequenceNumber = 1;
+        if (resultList != null && !resultList.isEmpty()) {
+            Map<String, Object> result = resultList.get(0);
+            if (result != null && result.get("maxNo") != null) {
+                String lastNo = result.get("maxNo").toString();
+                if (lastNo.startsWith(datePrefix)) {
+                    try {
+                        sequenceNumber = Integer.parseInt(lastNo.substring(datePrefix.length())) + 1;
+                    } catch (NumberFormatException e) {
+                        sequenceNumber = 1;
+                    }
+                }
+            }
+        }
+        return String.format("%s%03d", datePrefix, sequenceNumber);
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
+
+    @Override
+    public ArrayList<Long> listMain(List<Long> idList) {
+        return productionProductMainMapper.listMain(idList);
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
index cb8e224..49518c0 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
@@ -1,20 +1,24 @@
 package com.ruoyi.production.service.impl;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.bean.dto.ProductionProductOutputDto;
 import com.ruoyi.production.mapper.ProductionProductOutputMapper;
 import com.ruoyi.production.pojo.ProductionProductOutput;
 import com.ruoyi.production.service.ProductionProductOutputService;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-/**
- * <p>
- * 鐢熶骇鎶ュ伐浜у嚭琛� 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
 @Service
+@AllArgsConstructor
 public class ProductionProductOutputServiceImpl extends ServiceImpl<ProductionProductOutputMapper, ProductionProductOutput> implements ProductionProductOutputService {
+    @Autowired
+    private ProductionProductOutputMapper productionProductOutputMapper;
 
+    @Override
+    public IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, ProductionProductOutputDto productionProductOutputDto) {
+        return productionProductOutputMapper.listPageProductionProductOutputDto(page, productionProductOutputDto);
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/SalesLedgerProductionAccountingServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/SalesLedgerProductionAccountingServiceImpl.java
new file mode 100644
index 0000000..f06284d
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/SalesLedgerProductionAccountingServiceImpl.java
@@ -0,0 +1,24 @@
+package com.ruoyi.production.service.impl;
+
+import com.ruoyi.production.bean.dto.UserAccountDto;
+import com.ruoyi.production.bean.dto.UserProductionAccountingDto;
+import com.ruoyi.production.mapper.ProductionAccountMapper;
+import com.ruoyi.production.service.SalesLedgerProductionAccountingService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class SalesLedgerProductionAccountingServiceImpl implements SalesLedgerProductionAccountingService {
+
+    private final ProductionAccountMapper productionAccountMapper;
+
+    @Override
+    public UserAccountDto getByUserId(UserProductionAccountingDto dto) {
+        if (dto == null || dto.getUserId() == null || dto.getDate() == null || dto.getDate().trim().isEmpty()) {
+            return new UserAccountDto();
+        }
+        UserAccountDto result = productionAccountMapper.selectUserAccount(dto.getUserId(), dto.getDate());
+        return result == null ? new UserAccountDto() : result;
+    }
+}
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java
index f01f315..cd2aee6 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java
@@ -1,9 +1,6 @@
 package com.ruoyi.quality.service.impl;
 
-import com.ruoyi.basic.service.IProductModelService;
-import com.ruoyi.basic.service.IProductService;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.production.service.ProductOrderService;
 import com.ruoyi.quality.dto.*;
 import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.quality.service.QualityReportService;
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 ffb9ed1..876d68e 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -1,24 +1,26 @@
 package com.ruoyi.quality.service.impl;
 
-
-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.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
-import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.procurementrecord.utils.StockUtils;
-import com.ruoyi.production.mapper.ProductProcessRouteItemMapper;
-import com.ruoyi.production.mapper.ProductProcessRouteMapper;
-import com.ruoyi.production.mapper.ProductWorkOrderMapper;
+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.*;
-import com.ruoyi.production.service.ProductOrderService;
+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.pojo.QualityInspect;
 import com.ruoyi.quality.pojo.QualityUnqualified;
@@ -32,21 +34,23 @@
 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;
 
 @AllArgsConstructor
 @Service
 public class QualityUnqualifiedServiceImpl extends ServiceImpl<QualityUnqualifiedMapper, QualityUnqualified> implements IQualityUnqualifiedService {
 
     private final StockUtils stockUtils;
-    private QualityUnqualifiedMapper qualityUnqualifiedMapper;
-    private IQualityInspectService qualityInspectService;
-    private ProductOrderService productOrderService;
-    private ProductionProductMainMapper productionProductMainMapper;
-    private ProductProcessRouteMapper productProcessRouteMapper;
-    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
-    private ProductWorkOrderMapper productWorkOrderMapper;
-    private StockUninventoryService stockUninventoryService;
+    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;
+    private final StockUninventoryService stockUninventoryService;
 
     @Override
     public IPage<QualityUnqualified> qualityUnqualifiedListPage(Page page, QualityUnqualified qualityUnqualified) {
@@ -56,7 +60,7 @@
     @Override
     public void qualityUnqualifiedExport(HttpServletResponse response, QualityUnqualified qualityUnqualified) {
         List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.qualityUnqualifiedExport(qualityUnqualified);
-        ExcelUtil<QualityUnqualified> util = new ExcelUtil<QualityUnqualified>(QualityUnqualified.class);
+        ExcelUtil<QualityUnqualified> util = new ExcelUtil<>(QualityUnqualified.class);
         util.exportExcel(response, qualityUnqualifieds, "涓嶅悎鏍肩鐞嗗鍑�");
     }
 
@@ -68,92 +72,41 @@
             switch (qualityUnqualified.getDealResult()) {
                 case "杩斾慨":
                 case "杩斿伐":
-                    //鍒ゆ柇璐ㄦ琛ㄦ槸鍚︽湁鐩稿叧鐨勬姤宸d,濡傛灉鏈夋姤宸d,閭d箞杩斿伐闇�瑕侀噸鏂板垱寤虹敓浜ц鍗曢噸鏂扮敓浜�
                     if (ObjectUtils.isNotNull(qualityInspect.getProductMainId())) {
-                        //杩斿伐闇�瑕侀噸鏂板垱寤虹敓浜ц鍗曢噸鏂扮敓浜�
-                        ProductOrder productOrder = productionProductMainMapper.getOrderByMainId(qualityInspect.getProductMainId());
-                        ProductOrder order = new ProductOrder();
-                        BeanUtils.copyProperties(productOrder, order);
-                        order.setId(null);
-                        order.setQuantity(unqualified.getQuantity());
-                        order.setCompleteQuantity(BigDecimal.ZERO);
-                        order.setStartTime(null);
-                        order.setEndTime(null);
-                        productOrderService.save(order);
-                        //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎涓昏〃
-                        ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectList(Wrappers.<ProductProcessRoute>lambdaQuery().eq(ProductProcessRoute::getProductOrderId, productOrder.getId()).orderByDesc(ProductProcessRoute::getId)).get(0);
-                        ProductProcessRoute newProcessRoute = new ProductProcessRoute();
-                        BeanUtils.copyProperties(productProcessRoute, newProcessRoute);
-                        newProcessRoute.setId(null);
-                        newProcessRoute.setProductOrderId(order.getId());
-                        productProcessRouteMapper.insert(newProcessRoute);
-                        //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎瀛愯〃
-                        List<ProductProcessRouteItem> processRouteItems = productProcessRouteItemMapper.selectList(new QueryWrapper<ProductProcessRouteItem>().lambda().eq(ProductProcessRouteItem::getProductRouteId, productProcessRoute.getId()));
-                        // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
-                        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
-                        for (ProductProcessRouteItem processRouteItem : processRouteItems) {
-                            ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
-                            BeanUtils.copyProperties(processRouteItem, productProcessRouteItem);
-                            productProcessRouteItem.setId(null);
-                            productProcessRouteItem.setProductRouteId(newProcessRoute.getId());
-                            int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
-                            if (insert > 0) {
-                                // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
-                                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
-                                int sequenceNumber = 1; // 榛樿搴忓彿
-                                if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
-                                    String lastNo = lastWorkOrder.getWorkOrderNo().toString();
-                                    if (lastNo.startsWith(datePrefix)) {
-                                        String seqStr = lastNo.substring(datePrefix.length());
-                                        try {
-                                            sequenceNumber = Integer.parseInt(seqStr) + 1;
-                                        } catch (NumberFormatException e) {
-                                            sequenceNumber = 1;
-                                        }
-                                    }
-                                }
-                                // 鐢熸垚瀹屾暣鐨勫伐鍗曞彿
-                                String workOrderNoStr = "FG" + String.format("%s%03d", datePrefix, sequenceNumber);
-                                ProductWorkOrder productWorkOrder = new ProductWorkOrder();
-                                productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
-                                productWorkOrder.setProductOrderId(order.getId());
-                                productWorkOrder.setPlanQuantity(order.getQuantity());
-                                productWorkOrder.setWorkOrderNo(workOrderNoStr);
-                                productWorkOrder.setStatus(1);
-                                productWorkOrderMapper.insert(productWorkOrder);
-                            }
+                        ProductionProductMain sourceMain = productionProductMainMapper.selectById(qualityInspect.getProductMainId());
+                        if (sourceMain == null || sourceMain.getProductionOperationTaskId() == null) {
+                            throw new ServiceException("鍘嗗彶鎶ュ伐鏈粦瀹氱敓浜у伐鍗曪紝鏃犳硶鎸夋柊妯″瀷杩斾慨/杩斿伐");
                         }
+                        createReworkProductionByNewModel(sourceMain, unqualified.getQuantity());
                     }
                     break;
                 case "鎶ュ簾":
-                    //璋冪敤涓嶅悎鏍煎簱瀛樻帴鍙� 鍏ヤ笉鍚堟牸搴�
-                    stockUtils.addUnStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId());
+                    stockUtils.addUnStock(qualityInspect.getProductModelId(), unqualified.getQuantity(),
+                            StockInUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId());
                     break;
                 case "璁╂鏀捐":
-                    //璋冪敤鎻愪氦鍚堟牸鐨勬帴鍙�
-                    stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId());
+                    stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(),
+                            StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId());
                     break;
                 default:
                     break;
             }
         } else {
-            //鏌ヨ瀵瑰簲鐨勮鏍煎瀷鍙穒d
             Long modelId = qualityUnqualifiedMapper.getModelId(qualityUnqualified.getProductName(), qualityUnqualified.getModel());
             switch (qualityUnqualified.getDealResult()) {
                 case "鎶ュ簾":
-                    //璋冪敤涓嶅悎鏍煎簱瀛樻帴鍙� 鍏ヤ笉鍚堟牸搴�
-                    stockUtils.addUnStock(modelId, unqualified.getQuantity(), StockInUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId());
+                    stockUtils.addUnStock(modelId, unqualified.getQuantity(),
+                            StockInUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId());
                     break;
                 case "璁╂鏀捐":
-                    //璋冪敤鎻愪氦鍚堟牸鐨勬帴鍙�
-                    stockUtils.addStock(modelId, unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId());
+                    stockUtils.addStock(modelId, unqualified.getQuantity(),
+                            StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId());
                     break;
                 default:
                     break;
             }
-
         }
-        qualityUnqualified.setInspectState(1);//宸插鐞�
+        qualityUnqualified.setInspectState(1);
         return qualityUnqualifiedMapper.updateById(qualityUnqualified);
     }
 
@@ -161,4 +114,110 @@
     public QualityUnqualified getUnqualified(Integer id) {
         return qualityUnqualifiedMapper.getUnqualified(id);
     }
+
+    private void createReworkProductionByNewModel(ProductionProductMain sourceMain, BigDecimal quantity) {
+        ProductionOperationTask sourceTask = productionOperationTaskMapper.selectById(sourceMain.getProductionOperationTaskId());
+        if (sourceTask == null) {
+            throw new ServiceException("鍏宠仈鐨勭敓浜у伐鍗曚笉瀛樺湪");
+        }
+        ProductionOrder sourceOrder = productionOrderMapper.selectById(sourceTask.getProductionOrderId());
+        if (sourceOrder == null) {
+            throw new ServiceException("鍏宠仈鐨勭敓浜ц鍗曚笉瀛樺湪");
+        }
+
+        ProductionOrder newOrder = new ProductionOrder();
+        BeanUtils.copyProperties(sourceOrder, newOrder);
+        newOrder.setId(null);
+        newOrder.setNpsNo(generateNextProductionOrderNo("FG"));
+        newOrder.setQuantity(defaultDecimal(quantity));
+        newOrder.setCompleteQuantity(BigDecimal.ZERO);
+        newOrder.setStartTime(null);
+        newOrder.setEndTime(null);
+        newOrder.setCreateTime(null);
+        newOrder.setUpdateTime(null);
+        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.setTechnologyRoutingId(routingIdMap.get(sourceOperation.getTechnologyRoutingId()));
+            newOperation.setCreateTime(null);
+            newOperation.setUpdateTime(null);
+            productionOrderRoutingOperationMapper.insert(newOperation);
+
+            ProductionOperationTask newTask = new ProductionOperationTask();
+            newTask.setTechnologyRoutingOperationId(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);
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
 }
diff --git a/src/main/java/com/ruoyi/safe/controller/SafeCertificationController.java b/src/main/java/com/ruoyi/safe/controller/SafeCertificationController.java
index 7e13eb8..cc59428 100644
--- a/src/main/java/com/ruoyi/safe/controller/SafeCertificationController.java
+++ b/src/main/java/com/ruoyi/safe/controller/SafeCertificationController.java
@@ -1,19 +1,14 @@
 package com.ruoyi.safe.controller;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.dto.ProcessRouteDto;
-import com.ruoyi.production.pojo.ProcessRoute;
 import com.ruoyi.safe.pojo.SafeCertification;
 import com.ruoyi.safe.service.SafeCertificationService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.Arrays;
 import java.util.List;
 
 /**
diff --git a/src/main/java/com/ruoyi/safe/controller/SafeCertificationFileController.java b/src/main/java/com/ruoyi/safe/controller/SafeCertificationFileController.java
index d60b479..cce9272 100644
--- a/src/main/java/com/ruoyi/safe/controller/SafeCertificationFileController.java
+++ b/src/main/java/com/ruoyi/safe/controller/SafeCertificationFileController.java
@@ -2,18 +2,15 @@
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.pojo.ProductWorkOrderFile;
-import com.ruoyi.production.service.ProductWorkOrderFileService;
 import com.ruoyi.safe.pojo.SafeCertificationFile;
 import com.ruoyi.safe.service.SafeCertificationFileService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import jakarta.annotation.Resource;
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
-import jakarta.annotation.Resource;
 import java.util.List;
 
 /**
diff --git a/src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java b/src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java
index 7d8e017..2f528f2 100644
--- a/src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java
+++ b/src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java
@@ -8,9 +8,6 @@
 import com.deepoove.poi.XWPFTemplate;
 import com.deepoove.poi.config.Configure;
 import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
-import com.ruoyi.production.pojo.ProductOrder;
-import com.ruoyi.production.pojo.ProductWorkOrder;
-import com.ruoyi.project.system.domain.SysNotice;
 import com.ruoyi.safe.dto.SafeTrainingDetailsDto;
 import com.ruoyi.safe.dto.SafeTrainingDto;
 import com.ruoyi.safe.mapper.SafeTrainingDetailsMapper;
@@ -22,20 +19,15 @@
 import com.ruoyi.safe.service.SafeTrainingService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import jakarta.servlet.http.HttpServletResponse;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URLEncoder;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 
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 68b52cb..965f07a 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -10,10 +10,9 @@
 import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.procurementrecord.utils.StockUtils;
-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.ProductionOrderService;
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.quality.mapper.QualityInspectMapper;
@@ -30,6 +29,10 @@
 import com.ruoyi.sales.service.ISalesLedgerProductService;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.pojo.StockInventory;
+import com.ruoyi.technology.bean.vo.TechnologyBomStructureVo;
+import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
+import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
+import com.ruoyi.technology.pojo.TechnologyRouting;
 import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -57,24 +60,19 @@
 public class SalesLedgerProductServiceImpl extends ServiceImpl<SalesLedgerProductMapper, SalesLedgerProduct> implements ISalesLedgerProductService {
 
     private SalesLedgerProductMapper salesLedgerProductMapper;
-    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+    private ProductionAccountMapper productionAccountMapper;
 
     private SalesLedgerMapper salesLedgerMapper;
 
     private PurchaseLedgerMapper purchaseLedgerMapper;
 
-    private ProductOrderMapper productOrderMapper;
-
-    private ProcessRouteItemMapper processRouteItemMapper;
-
-    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+    private ProductionOrderMapper productionOrderMapper;
+    private ProductionOperationTaskMapper productionOperationTaskMapper;
+    private ProductionOrderService productionOrderService;
+    private TechnologyRoutingMapper technologyRoutingMapper;
+    private TechnologyBomStructureMapper technologyBomStructureMapper;
 
     private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
-
-    private ProcessRouteMapper processRouteMapper;
-    private ProductProcessRouteMapper productProcessRouteMapper;
-
-    private ProductWorkOrderMapper productWorkOrderMapper;
     private ProductionProductMainMapper productionProductMainMapper;
     private ProductionProductOutputMapper productionProductOutputMapper;
     private ProductionProductInputMapper productionProductInputMapper;
@@ -87,12 +85,7 @@
 
 
     @Autowired
-    private ProductStructureMapper productStructureMapper;
-    @Autowired
     private StockInventoryMapper stockInventoryMapper;
-    @Autowired
-    private ProductOrderServiceImpl productOrderServiceImpl;
-
     @Override
     public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
         return salesLedgerProductMapper.selectById(id);
@@ -266,70 +259,25 @@
      * 鏂板鐢熶骇鏁版嵁
      */
     public void addProductionData(SalesLedgerProduct salesLedgerProduct) {
-        ProductOrder productOrder = new ProductOrder();
-        productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
-        productOrder.setProductModelId(salesLedgerProduct.getProductModelId());
-        productOrder.setSaleLedgerProductId(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);
+        ProductionOrder productionOrder = new ProductionOrder();
+        productionOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
+        productionOrder.setProductModelId(salesLedgerProduct.getProductModelId());
+        productionOrder.setSaleLedgerProductId(salesLedgerProduct.getId().intValue());
+        productionOrder.setNpsNo(generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
+        productionOrder.setQuantity(salesLedgerProduct.getQuantity());
+        productionOrder.setCompleteQuantity(BigDecimal.ZERO);
 
-        List<ProcessRoute> processRoutes = processRouteMapper.selectList(new QueryWrapper<ProcessRoute>().lambda()
-                .eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId())
-                .orderByDesc(ProcessRoute::getCreateTime));
-        if (processRoutes.size()>0){
-            ProcessRoute processRoute = processRoutes.get(0);
-            //鏂板鐢熶骇璁㈠崟宸ヨ壓璺嚎涓昏〃
-            ProductProcessRoute productProcessRoute = new ProductProcessRoute();
-            productProcessRoute.setProductModelId(processRoute.getProductModelId());
-            productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
-            productProcessRoute.setProductOrderId(productOrder.getId());
-            productProcessRoute.setBomId(processRoute.getBomId());
-            productProcessRouteMapper.insert(productProcessRoute);
-            //鏂板鐢熶骇璁㈠崟宸ヨ壓璺嚎瀛愯〃
-            List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
-            // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
-            String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
-            for (ProcessRouteItem processRouteItem : processRouteItems) {
-                ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
-                productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
-                productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
-                productProcessRouteItem.setProductOrderId(productOrder.getId());
-                productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
-                productProcessRouteItem.setDragSort(processRouteItem.getDragSort());
-                int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
-                if (insert > 0) {
-                    // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
-                    ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
-                    int sequenceNumber = 1; // 榛樿搴忓彿
-                    if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
-                        String lastNo = lastWorkOrder.getWorkOrderNo().toString();
-                        if (lastNo.startsWith(datePrefix)) {
-                            String seqStr = lastNo.substring(datePrefix.length());
-                            try {
-                                sequenceNumber = Integer.parseInt(seqStr) + 1;
-                            } catch (NumberFormatException e) {
-                                sequenceNumber = 1;
-                            }
-                        }
-                    }
-                    // 鐢熸垚瀹屾暣鐨勫伐鍗曞彿
-                    String workOrderNoStr ="GD"+ String.format("%s%03d", datePrefix, sequenceNumber);
-                    ProductWorkOrder productWorkOrder = new ProductWorkOrder();
-                    productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
-                    productWorkOrder.setProductOrderId(productOrder.getId());
-                    productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
-                    productWorkOrder.setWorkOrderNo(workOrderNoStr);
-                    productWorkOrder.setStatus(1);
-
-                    productWorkOrderMapper.insert(productWorkOrder);
-                }
-
-            }
-            productOrder.setRouteId(processRoute.getId());
-            productOrderMapper.updateById(productOrder);
+        TechnologyRouting routing = technologyRoutingMapper.selectOne(
+                new QueryWrapper<TechnologyRouting>().lambda()
+                        .eq(TechnologyRouting::getProductModelId, salesLedgerProduct.getProductModelId())
+                        .orderByDesc(TechnologyRouting::getCreateTime)
+                        .last("LIMIT 1"));
+        if (routing != null) {
+            productionOrder.setTechnologyRoutingId(routing.getId());
+        }
+        productionOrderMapper.insert(productionOrder);
+        if (productionOrder.getTechnologyRoutingId() != null) {
+            productionOrderService.syncProductionOrderSnapshot(productionOrder.getId());
         }
     }
 
@@ -337,93 +285,44 @@
      * 鍒犻櫎鐢熶骇鏁版嵁
      */
     public void deleteProductionData(List<Long> productIds) {
-        //鎵归噺鏌ヨproductOrder
-        List<ProductOrder> productOrders = productOrderMapper.selectList(
-                new LambdaQueryWrapper<ProductOrder>()
-                        .in(ProductOrder::getSaleLedgerProductId, productIds)
-        );
-        if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) {
-            List<Long> orderIds = productOrders.stream()
-                    .map(ProductOrder::getId)
-                    .collect(Collectors.toList());
-
-            // 鎵归噺鏌ヨprocessRouteItems
-            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
-                    new LambdaQueryWrapper<ProductProcessRouteItem>()
-                            .in(ProductProcessRouteItem::getProductOrderId, orderIds)
-            );
-
-            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, StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
-                            //鍒犻櫎鎶ュ簾鐨勫叆搴撹褰�
-                            stockUtils.deleteStockInRecord(productMainId, StockInUnQualifiedRecordTypeEnum.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));
+        List<ProductionOrder> productionOrders = productionOrderMapper.selectList(
+                new LambdaQueryWrapper<ProductionOrder>()
+                        .in(ProductionOrder::getSaleLedgerProductId, productIds.stream().map(Long::intValue).collect(Collectors.toList())));
+        if (org.springframework.util.CollectionUtils.isEmpty(productionOrders)) {
+            return;
+        }
+        List<Long> orderIds = productionOrders.stream().map(ProductionOrder::getId).collect(Collectors.toList());
+        List<Long> taskIds = productionOperationTaskMapper.selectList(
+                        new LambdaQueryWrapper<ProductionOperationTask>()
+                                .in(ProductionOperationTask::getProductionOrderId, orderIds))
+                .stream().map(ProductionOperationTask::getId).collect(Collectors.toList());
+        if (!taskIds.isEmpty()) {
+            List<ProductionProductMain> productMains = productionProductMainMapper.selectList(
+                    new LambdaQueryWrapper<ProductionProductMain>()
+                            .in(ProductionProductMain::getProductionOperationTaskId, taskIds));
+            List<Long> productMainIds = productMains.stream().map(ProductionProductMain::getId).collect(Collectors.toList());
+            if (!productMainIds.isEmpty()) {
+                List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
+                        new LambdaQueryWrapper<QualityInspect>().in(QualityInspect::getProductMainId, productMainIds));
+                qualityInspects.forEach(qualityInspect -> {
+                    if (qualityInspect.getInspectState() == 1) {
+                        throw new RuntimeException("宸叉彁浜ょ殑妫�楠屽崟涓嶈兘鍒犻櫎");
                     }
-
-                    // 鍒犻櫎鐢熶骇涓昏〃鏁版嵁
-                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
-
-                    // 鍒犻櫎宸ュ崟鏁版嵁
-                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
-                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
+                });
+                productionProductOutputMapper.deleteByProductMainIds(productMainIds);
+                productionProductInputMapper.deleteByProductMainIds(productMainIds);
+                qualityInspectMapper.deleteByProductMainIds(productMainIds);
+                productionAccountMapper.delete(new LambdaQueryWrapper<ProductionAccount>()
+                        .in(ProductionAccount::getProductionProductMainId, productMainIds));
+                for (Long productMainId : productMainIds) {
+                    stockUtils.deleteStockOutRecord(productMainId, StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
+                    stockUtils.deleteStockInRecord(productMainId, StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
                 }
             }
-            // 鎵归噺鍒犻櫎processRouteItem
-            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
-                    .in(ProductProcessRouteItem::getProductOrderId, orderIds));
-
-            // 鎵归噺鍒犻櫎productProcessRoute
-            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
-                    .in(ProductProcessRoute::getProductOrderId, orderIds));
-
-            // 鎵归噺鍒犻櫎productOrder
-            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
-                    .in(ProductOrder::getSaleLedgerProductId, productIds));
+            productionProductMainMapper.delete(new LambdaQueryWrapper<ProductionProductMain>()
+                    .in(ProductionProductMain::getProductionOperationTaskId, taskIds));
         }
+        productionOrderService.removeProductionOrder(orderIds);
     }
 
     @Override
@@ -490,37 +389,67 @@
     }
     @Override
     public R judgmentInventory(SalesLedgerProduct salesLedgerProduct) {
-        //鑾峰彇浜у搧鏈�鏂扮殑宸ヨ壓璺嚎
-        ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()).orderByDesc(ProcessRoute::getCreateTime).last("LIMIT 1"));
-        if (processRoute == null) {
+        TechnologyRouting routing = technologyRoutingMapper.selectOne(
+                new QueryWrapper<TechnologyRouting>().lambda()
+                        .eq(TechnologyRouting::getProductModelId, salesLedgerProduct.getProductModelId())
+                        .orderByDesc(TechnologyRouting::getCreateTime)
+                        .last("LIMIT 1"));
+        if (routing == null) {
             return R.fail("璇峰厛璁剧疆宸ヨ壓璺嚎");
         }
-        List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomId(processRoute.getBomId());
-        if (productStructureDtos.isEmpty()) {
+        List<TechnologyBomStructureVo> structureList = technologyBomStructureMapper.listByBomId(routing.getBomId().longValue());
+        if (structureList == null || structureList.isEmpty()) {
             return R.fail("璇峰厛璁剧疆浜у搧缁撴瀯");
         }
         int count = 0;
         StringBuilder stringBuffer = new StringBuilder();
-        for (ProductStructureDto productStructureDto : productStructureDtos) {
-            StockInventory stockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, productStructureDto.getProductModelId()));
-
-            //鎵�闇�鏁伴噺
-            BigDecimal multiply = salesLedgerProduct.getQuantity().multiply(productStructureDto.getUnitQuantity());
-            BigDecimal subtract =stockInventory.getQualitity().subtract(stockInventory.getLockedQuantity()).subtract(multiply).divide(BigDecimal.ONE, 2, RoundingMode.CEILING);
-            if (subtract.compareTo(BigDecimal.ZERO) <= 0) {
+        for (TechnologyBomStructureVo structure : structureList) {
+            if (structure.getParentId() == null) {
+                continue;
+            }
+            StockInventory stockInventory = stockInventoryMapper.selectOne(
+                    new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, structure.getProductModelId()));
+            if (stockInventory == null) {
                 count++;
-                stringBuffer.append(productStructureDto.getProductName())
+                stringBuffer.append(structure.getProductName()).append("-").append(structure.getModel()).append("搴撳瓨涓嶈冻").append(System.lineSeparator());
+                continue;
+            }
+            BigDecimal required = salesLedgerProduct.getQuantity().multiply(structure.getUnitQuantity() == null ? BigDecimal.ZERO : structure.getUnitQuantity());
+            BigDecimal remain = stockInventory.getQualitity()
+                    .subtract(stockInventory.getLockedQuantity())
+                    .subtract(required)
+                    .divide(BigDecimal.ONE, 2, RoundingMode.CEILING);
+            if (remain.compareTo(BigDecimal.ZERO) < 0) {
+                count++;
+                stringBuffer.append(structure.getProductName())
                         .append("-")
-                        .append(productStructureDto.getModel())
+                        .append(structure.getModel())
                         .append("搴撳瓨涓嶈冻锛屽皯")
-                        .append(subtract)
+                        .append(remain.abs())
                         .append(System.lineSeparator());
             }
         }
-        if (count>0) {
+        if (count > 0) {
             return R.fail(stringBuffer.toString());
-        }else {
-            return R.ok();
         }
+        return R.ok();
+    }
+
+    private String generateNextOrderNo(String datePrefix) {
+        QueryWrapper<ProductionOrder> queryWrapper = new QueryWrapper<>();
+        queryWrapper.likeRight("nps_no", "SC" + datePrefix);
+        queryWrapper.orderByDesc("nps_no");
+        queryWrapper.last("LIMIT 1");
+        ProductionOrder latestOrder = productionOrderMapper.selectOne(queryWrapper);
+        int sequence = 1;
+        if (latestOrder != null && latestOrder.getNpsNo() != null && !latestOrder.getNpsNo().isEmpty()) {
+            String sequenceStr = latestOrder.getNpsNo().substring(("SC" + datePrefix).length());
+            try {
+                sequence = Integer.parseInt(sequenceStr) + 1;
+            } catch (NumberFormatException e) {
+                sequence = 1;
+            }
+        }
+        return "SC" + datePrefix + String.format("%04d", sequence);
     }
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index e2c11cf..0ee10b7 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -15,7 +15,6 @@
 import com.ruoyi.basic.mapper.ProductMapper;
 import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.pojo.Customer;
-import com.ruoyi.basic.pojo.CustomerPrivatePool;
 import com.ruoyi.common.enums.FileNameType;
 import com.ruoyi.common.enums.SaleEnum;
 import com.ruoyi.common.exception.base.BaseException;
@@ -97,17 +96,8 @@
     private final CommonFileServiceImpl commonFileService;
     private final ShippingInfoMapper shippingInfoMapper;
     private final InvoiceLedgerMapper invoiceLedgerMapper;
-    private final SalesLedgerSchedulingMapper salesLedgerSchedulingMapper;
-    private final SalesLedgerWorkMapper salesLedgerWorkMapper;
-    private final SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
     private final InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
     private final InvoiceRegistrationMapper invoiceRegistrationMapper;
-    private final ProductOrderMapper productOrderMapper;
-    private final ProcessRouteMapper processRouteMapper;
-    private final ProductProcessRouteMapper productProcessRouteMapper;
-    private final ProcessRouteItemMapper processRouteItemMapper;
-    private final ProductProcessRouteItemMapper productProcessRouteItemMapper;
-    private final ProductWorkOrderMapper productWorkOrderMapper;
     private final ProductionProductMainMapper productionProductMainMapper;
     private final ProductionProductOutputMapper productionProductOutputMapper;
     private final ProductionProductInputMapper productionProductInputMapper;
@@ -123,12 +113,9 @@
     @Autowired
     private ProductMapper productMapper;
     @Autowired
-    private ProductStructureMapper productStructureMapper;
-    @Autowired
     private ProductionProductMainService productionProductMainService;
     @Autowired
     private PurchaseReturnOrderProductsMapper purchaseReturnOrderProductsMapper;
-    ;
     @Autowired
     private SysUserMapper sysUserMapper;
     @Autowired
diff --git a/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
index 3043aad..0dac4b9 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
@@ -2,35 +2,34 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.framework.web.domain.AjaxResult;
-import com.ruoyi.production.dto.UserAccountDto;
-import com.ruoyi.production.dto.UserProductionAccountingDto;
+import com.ruoyi.production.bean.dto.UserAccountDto;
+import com.ruoyi.production.bean.dto.UserProductionAccountingDto;
 import com.ruoyi.production.service.SalesLedgerProductionAccountingService;
 import com.ruoyi.project.system.domain.SysDept;
 import com.ruoyi.project.system.domain.SysUser;
-import com.ruoyi.project.system.domain.SysUserDept;
 import com.ruoyi.project.system.mapper.SysDeptMapper;
 import com.ruoyi.project.system.mapper.SysUserDeptMapper;
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.staff.controller.TaxCalculator;
-import com.ruoyi.staff.dto.StaffOnJobDto;
+import com.ruoyi.staff.mapper.SchemeApplicableStaffMapper;
 import com.ruoyi.staff.mapper.SchemeInsuranceDetailMapper;
 import com.ruoyi.staff.mapper.StaffOnJobMapper;
 import com.ruoyi.staff.pojo.SchemeApplicableStaff;
-import com.ruoyi.staff.mapper.SchemeApplicableStaffMapper;
 import com.ruoyi.staff.pojo.SchemeInsuranceDetail;
 import com.ruoyi.staff.pojo.StaffOnJob;
-import com.ruoyi.staff.service.IStaffOnJobService;
 import com.ruoyi.staff.service.SchemeApplicableStaffService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import jakarta.annotation.Resource;
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 /**
diff --git a/src/main/java/com/ruoyi/technology/bean/dto/BomImportDto.java b/src/main/java/com/ruoyi/technology/bean/dto/BomImportDto.java
new file mode 100644
index 0000000..865a612
--- /dev/null
+++ b/src/main/java/com/ruoyi/technology/bean/dto/BomImportDto.java
@@ -0,0 +1,37 @@
+package com.ruoyi.technology.bean.dto;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class BomImportDto {
+
+    @Excel(name = "鐖堕」浜у搧缂栧彿")
+    private String parentCode;
+
+    @Excel(name = "鐖堕」浜у搧鍚嶇О")
+    private String parentName;
+
+    @Excel(name = "鐖堕」浜у搧瑙勬牸")
+    private String parentSpec;
+
+    @Excel(name = "瀛愰」浜у搧缂栧彿")
+    private String childCode;
+
+    @Excel(name = "瀛愰」浜у搧鍚嶇О")
+    private String childName;
+
+    @Excel(name = "瀛愰」浜у搧瑙勬牸")
+    private String childSpec;
+
+    @Excel(name = "鍗曚綅鐢ㄩ噺")
+    private BigDecimal unitQty;
+
+    @Excel(name = "鎶曟枡宸ュ簭")
+    private String process;
+
+    @Excel(name = "澶囨敞")
+    private String remark;
+}
diff --git a/src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamDto.java b/src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamDto.java
new file mode 100644
index 0000000..dbaabe3
--- /dev/null
+++ b/src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamDto.java
@@ -0,0 +1,12 @@
+package com.ruoyi.technology.bean.dto;
+
+import com.ruoyi.technology.pojo.TechnologyRoutingOperationParam;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "TechnologyRoutingOperationParamDto瀵硅薄", description = "宸ヨ壓璺嚎宸ュ簭鍙傛暟鏌ヨ鍙傛暟")
+public class TechnologyRoutingOperationParamDto extends TechnologyRoutingOperationParam {
+}
diff --git a/src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamSyncDto.java b/src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamSyncDto.java
new file mode 100644
index 0000000..3432738
--- /dev/null
+++ b/src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingOperationParamSyncDto.java
@@ -0,0 +1,16 @@
+package com.ruoyi.technology.bean.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "TechnologyRoutingOperationParamSyncDto瀵硅薄", description = "宸ヨ壓璺嚎宸ュ簭鍙傛暟鍚屾鍙傛暟")
+public class TechnologyRoutingOperationParamSyncDto {
+
+    @ApiModelProperty("宸ヨ壓璺嚎宸ュ簭id")
+    private Long technologyRoutingOperationId;
+
+    @ApiModelProperty("鏄惁瑕嗙洊褰撳墠宸ュ簭宸插瓨鍦ㄥ弬鏁帮紝榛樿true")
+    private Boolean replaceExisting;
+}
diff --git a/src/main/java/com/ruoyi/technology/bean/vo/TechnologyRoutingOperationParamVo.java b/src/main/java/com/ruoyi/technology/bean/vo/TechnologyRoutingOperationParamVo.java
new file mode 100644
index 0000000..9f60e38
--- /dev/null
+++ b/src/main/java/com/ruoyi/technology/bean/vo/TechnologyRoutingOperationParamVo.java
@@ -0,0 +1,12 @@
+package com.ruoyi.technology.bean.vo;
+
+import com.ruoyi.technology.pojo.TechnologyRoutingOperationParam;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "TechnologyRoutingOperationParamVo瀵硅薄", description = "宸ヨ壓璺嚎宸ュ簭鍙傛暟杩斿洖瀵硅薄")
+public class TechnologyRoutingOperationParamVo extends TechnologyRoutingOperationParam {
+}
diff --git a/src/main/java/com/ruoyi/technology/controller/TechnologyBomController.java b/src/main/java/com/ruoyi/technology/controller/TechnologyBomController.java
index b642c8f..08dfcf4 100644
--- a/src/main/java/com/ruoyi/technology/controller/TechnologyBomController.java
+++ b/src/main/java/com/ruoyi/technology/controller/TechnologyBomController.java
@@ -6,19 +6,19 @@
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.dto.BomImportDto;
+import com.ruoyi.technology.bean.dto.BomImportDto;
 import com.ruoyi.technology.bean.dto.TechnologyBomDto;
 import com.ruoyi.technology.bean.vo.TechnologyBomVo;
 import com.ruoyi.technology.pojo.TechnologyBom;
 import com.ruoyi.technology.service.TechnologyBomService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
-import jakarta.servlet.http.HttpServletResponse;
 import java.util.List;
 
 @RestController
@@ -53,7 +53,7 @@
     @DeleteMapping("/batchDelete")
     @Log(title = "Delete technology BOM", businessType = BusinessType.DELETE)
     @ApiOperation("鎵归噺鍒犻櫎BOM")
-    public R batchDelete(@RequestBody List<Integer> ids) {
+    public R batchDelete(@RequestBody List<Long> ids) {
         return R.ok(technologyBomService.batchDelete(ids));
     }
 
diff --git a/src/main/java/com/ruoyi/technology/service/TechnologyBomService.java b/src/main/java/com/ruoyi/technology/service/TechnologyBomService.java
index 84ded9a..c80e304 100644
--- a/src/main/java/com/ruoyi/technology/service/TechnologyBomService.java
+++ b/src/main/java/com/ruoyi/technology/service/TechnologyBomService.java
@@ -7,9 +7,9 @@
 import com.ruoyi.technology.bean.dto.TechnologyBomDto;
 import com.ruoyi.technology.bean.vo.TechnologyBomVo;
 import com.ruoyi.technology.pojo.TechnologyBom;
+import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.web.multipart.MultipartFile;
 
-import jakarta.servlet.http.HttpServletResponse;
 import java.util.List;
 
 public interface TechnologyBomService extends IService<TechnologyBom> {
@@ -22,7 +22,7 @@
 
     R update(TechnologyBom technologyBom);
 
-    boolean batchDelete(List<Integer> ids);
+    boolean batchDelete(List<Long> ids);
 
     R uploadBom(MultipartFile file);
 
diff --git a/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java b/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java
index 807374f..4eba028 100644
--- a/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java
+++ b/src/main/java/com/ruoyi/technology/service/impl/TechnologyBomServiceImpl.java
@@ -13,9 +13,8 @@
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.dto.BomImportDto;
-import com.ruoyi.production.dto.ProductStructureDto;
-import com.ruoyi.production.pojo.ProductStructure;
+import com.ruoyi.production.bean.dto.BomImportDto;
+import com.ruoyi.production.bean.dto.ProductStructureDto;
 import com.ruoyi.technology.bean.dto.TechnologyBomDto;
 import com.ruoyi.technology.bean.vo.TechnologyBomVo;
 import com.ruoyi.technology.mapper.TechnologyBomMapper;
@@ -25,12 +24,12 @@
 import com.ruoyi.technology.pojo.TechnologyRouting;
 import com.ruoyi.technology.service.TechnologyBomService;
 import com.ruoyi.technology.service.TechnologyBomStructureService;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
-import jakarta.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -127,7 +126,7 @@
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean batchDelete(List<Integer> ids) {
+    public boolean batchDelete(List<Long> ids) {
         if (ids == null || ids.isEmpty()) {
             throw new ServiceException("Select at least one BOM");
         }
@@ -212,13 +211,13 @@
 
             //澶勭悊鏍硅妭鐐�,绗竴琛屼笖瀛愰」涓虹┖
             if (i == 0 && StringUtils.isBlank(dto.getChildName())) {
-                ProductStructure rootNode = new ProductStructure();
-                rootNode.setBomId(bom.getId());
+                TechnologyBomStructure rootNode = new TechnologyBomStructure();
+                rootNode.setBomId(bom.getId().longValue());
                 rootNode.setParentId(null); // 椤跺眰娌℃湁鐖惰妭鐐�
                 rootNode.setProductModelId(rootModel.getId());
                 rootNode.setUnitQuantity(BigDecimal.ONE);
                 rootNode.setUnit(rootModel.getUnit());
-//                productStructureService.save(rootNode);
+                technologyBomStructureService.save(rootNode);
 
                 treePathMap.put(parentKey, rootNode.getId());
                 continue;
@@ -236,8 +235,8 @@
             ProductModel childModel = findModel(dto.getChildName(), dto.getChildSpec());
 
             //  鎻掑叆缁撴瀯琛�
-            ProductStructure node = new ProductStructure();
-            node.setBomId(bom.getId());
+            TechnologyBomStructure node = new TechnologyBomStructure();
+            node.setBomId(bom.getId().longValue());
             node.setParentId(parentStructureId); // 鐖惰妭鐐笽D
             node.setProductModelId(childModel.getId());
             node.setUnitQuantity(dto.getUnitQty());
@@ -245,7 +244,7 @@
 //            if (processMap.containsKey(dto.getProcess())) {
 //                node.setProcessId(processMap.get(dto.getProcess()));
 //            }
-//            productStructureService.save(node);
+            technologyBomStructureService.save(node);
 
             //  鎶婂綋鍓嶅瓙椤硅褰曞埌 Map,浣滀负浠ュ悗鏇存繁灞傜骇鐨勭埗椤规煡鎵句緷鎹�
             //  鍚屼竴鐖堕」涓嬬殑鍚屽悕瀛愰」涓嶉渶瑕侀噸澶嶈褰�
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index c79d967..533d7c7 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,4 +1,6 @@
 # Spring閰嶇疆
 spring:
+  main:
+    allow-circular-references: true
   profiles:
     active: dev
diff --git a/src/main/resources/mapper/production/ProcessRouteItemMapper.xml b/src/main/resources/mapper/production/ProcessRouteItemMapper.xml
deleted file mode 100644
index e060f4e..0000000
--- a/src/main/resources/mapper/production/ProcessRouteItemMapper.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProcessRouteItemMapper">
-
-    <resultMap id="basicMap" type="com.ruoyi.production2.pojo.ProcessRouteItem">
-        <id property="id" column="id"/>
-        <result property="routeId" column="route_id"/>
-        <result property="processId" column="process_id"/>
-        <result property="productModelId" column="product_model_id"/>
-        <result property="tenantId" column="tenant_id"/>
-        <result property="createTime" column="create_time"/>
-        <result property="updateTime" column="update_time"/>
-        <result property="dragSort" column="drag_sort"/>
-    </resultMap>
-
-    <select id="listProcessRouteItemDto" resultType="com.ruoyi.production2.dto.ProcessRouteItemDto">
-        select pri.*,
-               pr.description ,
-               pp.name as process_name,
-               pp.is_inbound as inbound,
-               pp.is_report_work as reportWork,
-               pm.speculative_trading_name,
-               pm.product_id,
-               pm.model,
-               p.product_name,
-               pm.unit
-        from
-            process_route_item pri
-                left join product_model pm on pri.product_model_id = pm.id
-                left join product_process pp on pp.id = pri.process_id
-                left join product p on p.id = pm.product_id
-                left join process_route pr on pr.id = pri.route_id
-        where
-            pri.route_id = #{c.routeId}
-        order by pri.drag_sort
-    </select>
-</mapper>
diff --git a/src/main/resources/mapper/production/ProcessRouteMapper.xml b/src/main/resources/mapper/production/ProcessRouteMapper.xml
deleted file mode 100644
index 86a4862..0000000
--- a/src/main/resources/mapper/production/ProcessRouteMapper.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProcessRouteMapper">
-
-
-    <resultMap id="basicMap" type="com.ruoyi.production2.pojo.ProcessRoute">
-            <id property="id" column="id"/>
-            <result property="productModelId" column="product_model_id"/>
-            <result property="description" column="description"/>
-            <result property="tenantId" column="tenant_id"/>
-            <result property="createTime" column="create_time"/>
-            <result property="updateTime" column="update_time"/>
-    </resultMap>
-
-    <select id="pageProcessRouteDto" resultType="com.ruoyi.production2.dto.ProcessRouteDto">
-        select ps.*, p.product_name,pm.product_id,pm.model,pb.bom_no
-        from process_route ps
-        left join product_bom pb on ps.bom_id = pb.id
-        left join product_model pm on ps.product_model_id = pm.id
-        left join product p on pm.product_id = p.id
-        <where>
-            <if test="c.model != null and c.model != ''">
-                and pm.model like concat('%',#{c.model},'%')
-            </if>
-        </where>
-        order by ps.id asc
-    </select>
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductBomMapper.xml b/src/main/resources/mapper/production/ProductBomMapper.xml
deleted file mode 100644
index dbc4a16..0000000
--- a/src/main/resources/mapper/production/ProductBomMapper.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductBomMapper">
-
-    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
-    <resultMap id="BaseResultMap" type="com.ruoyi.production2.pojo.ProductBom">
-        <id column="id" property="id"/>
-        <result column="product_model_id" property="productModelId"/>
-        <result column="bom_no" property="bomNo"/>
-        <result column="remark" property="remark"/>
-        <result column="version" property="version"/>
-        <result column="create_time" property="createTime"/>
-        <result column="update_time" property="updateTime"/>
-        <result column="create_user" property="createUser"/>
-        <result column="update_user" property="updateUser"/>
-        <result column="tenant_id" property="tenantId"/>
-    </resultMap>
-    <select id="listPage" resultType="com.ruoyi.production2.dto.ProductBomDto">
-        select * from (select pb.*,
-        pm.model productModelName,
-        p.product_name productName
-        from product_bom pb
-        left join product_model pm on pb.product_model_id = pm.id
-        left join product p on pm.product_id = p.id)A
-        where 1=1
-        <if test="c.productModelName != null">
-            and productModelName = #{c.productModelName}
-        </if>
-        <if test="c.productName != null">
-            and productName = #{c.productName}
-        </if>
-        <if test="c.bomNo != null">
-            and bom_no = #{c.bomNo}
-        </if>
-        <if test="c.version != null">
-            and version = #{c.version}
-        </if>
-    </select>
-    <select id="getById" resultType="com.ruoyi.production2.dto.ProductBomDto">
-        select pb.*,
-               pm.model productModelName,
-               p.product_name productName
-        from product_bom pb
-                 left join product_model pm on pb.product_model_id = pm.id
-                 left join product p on pm.product_id = p.id
-    </select>
-
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductOrderMapper.xml b/src/main/resources/mapper/production/ProductOrderMapper.xml
deleted file mode 100644
index 452758e..0000000
--- a/src/main/resources/mapper/production/ProductOrderMapper.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductOrderMapper">
-
-
-    <resultMap id="basicMap" type="com.ruoyi.production2.pojo.ProductOrder">
-        <id property="id" column="id"/>
-        <result property="productModelId" column="product_model_id"/>
-        <result property="tenantId" column="tenant_id"/>
-        <result property="salesLedgerId" column="sales_ledger_id"/>
-        <result property="routeId" column="route_id"/>
-        <result property="npsNo" column="nps_no"/>
-        <result property="createTime" column="create_time"/>
-        <result property="updateTime" column="update_time"/>
-    </resultMap>
-    <select id="pageProductOrder" resultType="com.ruoyi.production2.dto.ProductOrderDto">
-        select po.*,
-        sl.sales_contract_no,
-        sl.customer_name,
-        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,
-        DATEDIFF(sl.delivery_date, CURDATE()) AS delivery_days_diff,
-        sl.delivery_date,
-        CASE
-        WHEN shipping_status_counts.total_count = 0 THEN false
-        WHEN shipping_status_counts.unshipped_count = 0 THEN true
-        ELSE false
-        END AS is_fh
-        from product_order po
-        left join sales_ledger sl on po.sales_ledger_id = sl.id
-        LEFT JOIN (
-        SELECT sales_ledger_id,
-        COUNT(*) as total_count,
-        SUM(CASE WHEN status != '宸插彂璐�' THEN 1 ELSE 0 END) as unshipped_count
-        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 and slp.type = 1
-        left join product_process_route ppr on po.id = ppr.product_order_id
-        left join product_bom pb on pb.id = ppr.bom_id
-        <where>
-            <if test="c.npsNo != null and c.npsNo != ''">
-                and po.nps_no like concat('%',#{c.npsNo},'%')
-            </if>
-            <if test="c.salesContractNo != null and c.salesContractNo != ''">
-                and sl.sales_contract_no like concat('%',#{c.salesContractNo},'%')
-            </if>
-            <if test="c.customerName != null and c.customerName != ''">
-                and sl.customer_name like concat('%',#{c.customerName},'%')
-            </if>
-            <if test="c.productCategory != null and c.productCategory != ''">
-                and slp.product_category like concat('%',#{c.productCategory},'%')
-            </if>
-            <if test="c.specificationModel != null and c.specificationModel != ''">
-                and slp.specification_model like concat('%',#{c.specificationModel},'%')
-            </if>
-            <if test="c.startTime != null and c.endTime != null">
-                and po.create_time between #{c.startTime} and #{c.endTime}
-            </if>
-        </where>
-    </select>
-    <select id="listProcessRoute" resultType="com.ruoyi.production2.pojo.ProcessRoute">
-        select pr.*
-        from process_route pr
-                 left join product_model pm on pr.product_model_id = pm.id
-        where pm.id = #{productModelId}
-    </select>
-    <select id="listProcessBom" resultType="com.ruoyi.production2.dto.ProductStructureDto">
-        select ps.id,
-               ps.product_model_id,
-               ps.process_id,
-               ps.unit_quantity,
-               ps.unit_quantity * po.quantity as demandedQuantity,
-               ps.unit,
-               p.product_name,
-               pp.name as  process_name,
-               pm.product_id,
-               pm.model
-        from
-            product_structure ps
-                left join product_model pm on ps.product_model_id = pm.id
-                left join product p on pm.product_id = p.id
-                left join product_process pp on ps.process_id = pp.id
-                left join product_process_route ppr on ps.bom_id = ppr.bom_id
-                left join product_order po on po.id = ppr.product_order_id
-        where ppr.product_order_id = #{orderId}
-        order by ps.id
-    </select>
-
-
-    <select id="countCreated" resultType="java.lang.Integer">
-        SELECT count(1) FROM product_order
-        WHERE create_time &gt;= #{startDate} AND create_time &lt;= #{endDate}
-    </select>
-
-    <select id="countCompleted" resultType="java.lang.Integer">
-        SELECT count(1) FROM product_order
-        WHERE end_time &gt;= #{startDate} AND end_time &lt;= #{endDate}
-          AND complete_quantity &gt;= quantity
-    </select>
-
-    <select id="countPending" resultType="java.lang.Integer">
-        SELECT count(1) FROM product_order
-        WHERE create_time &gt;= #{startDate} AND create_time &lt;= #{endDate}
-          AND complete_quantity &lt; quantity
-    </select>
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductOrderMaterialMapper.xml b/src/main/resources/mapper/production/ProductOrderMaterialMapper.xml
deleted file mode 100644
index 52b0952..0000000
--- a/src/main/resources/mapper/production/ProductOrderMaterialMapper.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductOrderMaterialMapper">
-    <resultMap id="BaseResultMap" type="com.ruoyi.production2.pojo.ProductOrderMaterial">
-        <id column="id" property="id" />
-                <result column="tenant_id" property="tenantId" />
-                <result column="process_name" property="processName" />
-                <result column="material_name" property="materialName" />
-                <result column="material_model" property="materialModel" />
-                <result column="required_qty" property="requiredQty" />
-                <result column="unit" property="unit" />
-                <result column="pick_qty" property="pickQty" />
-                <result column="supplement_qty" property="supplementQty" />
-                <result column="return_qty" property="returnQty" />
-                <result column="actual_qty" property="actualQty" />
-                <result column="create_time" property="createTime" />
-                <result column="update_time" property="updateTime" />
-                <result column="create_user" property="createUser" />
-                <result column="update_user" property="updateUser" />
-
-    </resultMap>
-        <select id="pickMaterial" resultType="com.ruoyi.production2.pojo.ProductOrderMaterial">
-            SELECT
-            si.id,
-            si.qualitity,
-            COALESCE(si.locked_quantity, 0) AS locked_quantity,
-            si.product_model_id,
-            si.create_time,
-            si.update_time,
-            COALESCE(si.warn_num, 0) AS warn_num,
-            si.version,
-            (si.qualitity - COALESCE(si.locked_quantity, 0)) AS un_locked_quantity,
-            pm.model,
-            si.remark,
-            pm.unit,
-            pm.uid_no AS uidNo,
-            p.product_name,
-            p1.product_name AS parentName,
-            si.batch_no,
-            si.customer
-            FROM
-            stock_inventory si
-            LEFT JOIN product_model pm ON si.product_model_id = pm.id
-            LEFT JOIN product p ON pm.product_id = p.id
-            LEFT JOIN product p1 ON p1.id = p.parent_id
-        </select>
-
-    <select id="selectLeafNode" resultType="com.ruoyi.production2.dto.ProductStructureDto">
-        SELECT
-            ps.*,
-            p.product_name,
-            pp.NAME AS process_name,
-            pm.product_id,
-            pm.model
-        FROM
-            product_structure ps
-                LEFT JOIN product_model pm ON ps.product_model_id = pm.id
-                LEFT JOIN product p ON pm.product_id = p.id
-                LEFT JOIN product_process pp ON ps.process_id = pp.id
-        WHERE
-            ps.bom_id = #{bomId}
-          AND NOT EXISTS (SELECT 1 FROM product_structure ps_child WHERE ps_child.parent_id = ps.id AND ps_child.bom_id = 30)
-        ORDER BY
-            ps.id
-    </select>
-
-    <select id="selectByProductModelIds" resultType="com.ruoyi.production2.dto.ProductOrderMaterialDto">
-        SELECT
-            si.id,
-            si.qualitity,
-            COALESCE(si.locked_quantity, 0) AS locked_quantity,
-            si.product_model_id,
-            si.create_time,
-            si.update_time,
-            COALESCE(si.warn_num, 0) AS warn_num,
-            si.version,
-            (si.qualitity - COALESCE(si.locked_quantity, 0)) AS un_locked_quantity,
-            pm.model as materialModel,
-            si.remark,
-            pm.unit,
-            pm.uid_no AS uidNo,
-            p.product_name as materialName,
-            p1.product_name AS parentName,
-            leaf.process_name,
-            leaf.id AS structure_id
-            FROM stock_inventory si
-            LEFT JOIN product_model pm ON si.product_model_id = pm.id
-            LEFT JOIN product p ON pm.product_id = p.id
-            LEFT JOIN product p1 ON p1.id = p.parent_id
-            INNER JOIN (
-            SELECT
-            ps.product_model_id,
-            pp.name AS process_name,
-            ps.id
-        FROM product_structure ps
-        LEFT JOIN product_process pp ON ps.process_id = pp.id
-        WHERE ps.product_model_id IN
-        <foreach collection="ids" item="id" open="(" separator="," close=")">
-            #{id}
-        </foreach>
-        AND ps.id NOT IN (
-        SELECT DISTINCT parent_id
-        FROM product_structure
-        WHERE parent_id IS NOT NULL
-        AND parent_id != 0
-        AND product_model_id IN
-        <foreach collection="ids" item="id" open="(" separator="," close=")">
-            #{id}
-        </foreach>
-        ))
-        leaf ON leaf.product_model_id = si.product_model_id
-        ORDER BY si.id
-    </select>
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductProcessMapper.xml b/src/main/resources/mapper/production/ProductProcessMapper.xml
deleted file mode 100644
index 7bd596c..0000000
--- a/src/main/resources/mapper/production/ProductProcessMapper.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductProcessMapper">
-
-    <select id="listPage" resultType="com.ruoyi.production2.dto.ProductProcessDto">
-        SELECT
-        *
-        FROM
-        product_process p
-        <where>
-            <if test="productProcessDto.name != null and productProcessDto.name != '' ">
-                AND  p.name LIKE CONCAT('%',#{productProcessDto.name},'%')
-            </if>
-            <if test="productProcessDto.no != null and productProcessDto.no != '' ">
-                AND  p.no LIKE CONCAT('%',#{productProcessDto.no},'%')
-            </if>
-        </where>
-        order by p.id asc
-    </select>
-
-    <select id="calculateProductionStatistics" resultType="com.ruoyi.home.dto.processDataProductionStatisticsDto">
-        SELECT
-        pp.name AS processName,
-        SUM(pi.quantity) AS totalInput,
-        SUM(distinct ppo.scrap_qty) AS totalScrap,
-        SUM(distinct (ppo.quantity - ppo.scrap_qty)) AS totalOutput
-        FROM
-        production_product_output ppo
-        INNER JOIN production_product_main ppm ON ppo.product_main_id = ppm.id
-        INNER JOIN product_process_route_item ppri ON ppm.product_process_route_item_id = ppri.id
-        INNER JOIN product_process pp ON ppri.process_id = pp.id
-        INNER JOIN production_product_input pi ON pi.product_main_id = ppm.id
-        <where>
-            <if test="startDateTime != null">
-                AND ppo.create_time &gt;= #{startDateTime}
-            </if>
-            <if test="endDateTime != null">
-                AND ppo.create_time &lt;= #{endDateTime}
-            </if>
-            <if test="userId != null">
-                AND ppm.user_id = #{userId}
-            </if>
-            <if test="processIds != null and processIds.size() > 0">
-                AND pp.id IN
-                <foreach collection="processIds" item="id" open="(" separator="," close=")">
-                    #{id}
-                </foreach>
-            </if>
-        </where>
-        GROUP BY
-        pp.id,
-        pp.name
-    </select>
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml b/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
deleted file mode 100644
index ec8554b..0000000
--- a/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductProcessRouteItemMapper">
-
-
-    <resultMap id="basicMap" type="com.ruoyi.production2.pojo.ProductProcessRouteItem">
-        <id property="id" column="id"/>
-        <result property="productModelId" column="product_model_id"/>
-        <result property="tenantId" column="tenant_id"/>
-        <result property="createTime" column="create_time"/>
-        <result property="updateTime" column="update_time"/>
-    </resultMap>
-    <select id="listItem" resultType="com.ruoyi.production2.dto.ProductProcessRouteItemDto">
-        select ppri.*,
-               pp.name as process_name,
-               pp.is_inbound as inbound,
-               pp.is_report_work as reportWork,
-               pm.model,
-               pm.unit,
-               p.product_name,
-               case when pwo.complete_quantity>0 then true else false end as is_complete
-        from product_process_route_item ppri
-                 left join product_model pm on ppri.product_model_id = pm.id
-                 left join product p on pm.product_id = p.id
-                 left join product_process pp on pp.id = ppri.process_id
-                 left join product_work_order pwo on pwo.product_process_route_item_id = ppri.id
-        where ppri.product_order_id = #{orderId}
-        order by ppri.drag_sort
-    </select>
-
-
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductProcessRouteMapper.xml b/src/main/resources/mapper/production/ProductProcessRouteMapper.xml
deleted file mode 100644
index c58823e..0000000
--- a/src/main/resources/mapper/production/ProductProcessRouteMapper.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductProcessRouteMapper">
-
-    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
-    <resultMap id="BaseResultMap" type="com.ruoyi.production2.pojo.ProductProcessRoute">
-        <id column="id" property="id"/>
-        <result column="product_model_id" property="productModelId"/>
-        <result column="description" property="description"/>
-        <result column="tenant_id" property="tenantId"/>
-        <result column="create_time" property="createTime"/>
-        <result column="update_time" property="updateTime"/>
-        <result column="bom_id" property="bomId"/>
-        <result column="process_route_code" property="processRouteCode"/>
-        <result column="product_order_id" property="productOrderId"/>
-    </resultMap>
-    <select id="listMain" resultType="com.ruoyi.production2.dto.ProcessRouteDto">
-        select ppr.*, p.product_name, pm.product_id, pm.model, pb.bom_no
-        from product_process_route ppr
-                 left join product_bom pb on ppr.bom_id = pb.id
-                 left join product_model pm on ppr.product_model_id = pm.id
-                 left join product p on pm.product_id = p.id
-        where ppr.product_order_id = #{orderId}
-    </select>
-
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductStructureMapper.xml b/src/main/resources/mapper/production/ProductStructureMapper.xml
deleted file mode 100644
index 920db52..0000000
--- a/src/main/resources/mapper/production/ProductStructureMapper.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductStructureMapper">
-
-    <resultMap id="basicMap" type="com.ruoyi.production2.pojo.ProductStructure">
-        <id property="id" column="id"/>
-        <result property="productModelId" column="product_model_id"/>
-        <result property="processId" column="process_id"/>
-        <result property="unitQuantity" column="unit_quantity"/>
-        <result property="demandedQuantity" column="demanded_quantity"/>
-        <result property="unit" column="unit"/>
-        <result property="tenantId" column="tenant_id"/>
-    </resultMap>
-    <select id="listBybomId" resultType="com.ruoyi.production2.dto.ProductStructureDto">
-        select ps.*,
-               p.product_name,
-               pp.name as  process_name,
-               pm.product_id,
-               pm.model
-        from
-            product_structure ps
-                left join product_model pm on ps.product_model_id = pm.id
-                left join product p on pm.product_id = p.id
-                left join product_process pp on ps.process_id = pp.id
-        where ps.bom_id = #{bomId}
-        order by ps.id
-    </select>
-    <select id="listBybomAndProcess" resultType="com.ruoyi.production2.dto.ProductStructureDto">
-        select ps.*,
-               p.product_name,
-               pp.name as  process_name,
-               pm.product_id,
-               pm.model
-        from
-            product_structure ps
-                left join product_model pm on ps.product_model_id = pm.id
-                left join product p on pm.product_id = p.id
-                left join product_process pp on ps.process_id = pp.id
-        where ps.bom_id = #{bomId}
-        and ps.process_id=#{processId}
-        order by ps.id
-    </select>
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductWorkOrderFileMapper.xml b/src/main/resources/mapper/production/ProductWorkOrderFileMapper.xml
deleted file mode 100644
index d46d848..0000000
--- a/src/main/resources/mapper/production/ProductWorkOrderFileMapper.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductWorkOrderFileMapper">
-
-    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
-    <resultMap id="BaseResultMap" type="com.ruoyi.production2.pojo.ProductWorkOrderFile">
-        <id column="id" property="id" />
-        <result column="work_order_id" property="workOrderId" />
-        <result column="name" property="name" />
-        <result column="url" property="url" />
-        <result column="file_size" property="fileSize" />
-        <result column="create_time" property="createTime" />
-        <result column="create_user" property="createUser" />
-        <result column="update_time" property="updateTime" />
-        <result column="update_user" property="updateUser" />
-        <result column="tenant_id" property="tenantId" />
-    </resultMap>
-
-</mapper>
diff --git a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
deleted file mode 100644
index 15466a0..0000000
--- a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.ProductWorkOrderMapper">
-
-    <resultMap id="BaseResultMap" type="com.ruoyi.production2.pojo.ProductWorkOrder">
-        <result column="id" property="id"/>
-        <result column="product_process_route_item_id" property="productProcessRouteItemId"/>
-        <result column="create_time" property="createTime"/>
-        <result column="update_time" property="updateTime"/>
-        <result column="work_order_no" property="workOrderNo"/>
-        <result column="status" property="status"/>
-        <result column="tenant_id" property="tenantId"/>
-        <result column="actual_end_time" property="planStartTime"/>
-        <result column="plan_end_time" property="planEndTime"/>
-        <result column="actual_start_time" property="actualStartTime"/>
-        <result column="actualEndTime" property="actualEndTime"/>
-    </resultMap>
-
-    <select id="pageProductWorkOrder" resultType="com.ruoyi.production2.dto.ProductWorkOrderDto">
-        SELECT
-        pwo.*,
-        pp.NAME as processName,
-        pm.model,
-        pm.unit,
-        p.product_name AS productName,
-        po.nps_no AS productOrderNpsNo,
-        ROUND(pwo.complete_quantity / pwo.plan_quantity * 100, 2) AS completionStatus,
-        CASE
-        WHEN pwo.work_order_no LIKE 'FG%' THEN '杩斿伐杩斾慨'
-        ELSE '姝e父'
-        END AS work_order_type
-        FROM
-        product_work_order pwo
-        LEFT JOIN product_process_route_item ppri ON ppri.id = pwo.product_process_route_item_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 1=1
-            <if test="c.workOrderNo != null and c.workOrderNo != ''">
-               and pwo.work_order_no like concat('%',#{c.workOrderNo},'%')
-            </if>
-            <if test="c.planStartTime != null and c.planEndTime != null">
-                and DATE(pwo.create_time) between #{c.planStartTime} and #{c.planEndTime}
-            </if>
-            <if test="c.productOrderNpsNo != null and c.productOrderNpsNo != ''">
-               and po.nps_no like concat('%',#{c.productOrderNpsNo},'%')
-            </if>
-    </select>
-    <select id="getProductWorkOrderFlowCard" resultType="com.ruoyi.production2.dto.ProductWorkOrderDto">
-        SELECT
-        pwo.*,
-        pp.NAME as processName,
-        pm.model,
-        pm.unit,
-        p.product_name AS productName,
-        po.nps_no AS productOrderNpsNo,
-        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>
-    <select id="selectWorkOrderStartStats" resultType="com.ruoyi.production2.dto.ProductWorkOrderDto">
-        SELECT
-            id,
-            actual_start_time AS planStartTime,
-            plan_quantity
-        FROM
-            product_work_order
-        WHERE
-            actual_start_time &gt;= #{startDate}
-            AND actual_start_time &lt;= #{endDate}
-    </select>
-    <select id="selectMax" resultType="com.ruoyi.production2.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>
diff --git a/src/main/resources/mapper/production/ProductionAccountMapper.xml b/src/main/resources/mapper/production/ProductionAccountMapper.xml
index b1c01e6..8b669e9 100644
--- a/src/main/resources/mapper/production/ProductionAccountMapper.xml
+++ b/src/main/resources/mapper/production/ProductionAccountMapper.xml
@@ -21,4 +21,24 @@
         <result column="dept_id" property="deptId" />
     </resultMap>
 
+    <select id="selectUserAccount" resultType="com.ruoyi.production.bean.dto.UserAccountDto">
+        select ifnull(sum(finished_num), 0) as accountBalance,
+               ifnull(sum(work_hours), 0) as account
+        from production_account
+        where scheduling_user_id = #{userId}
+          and date_format(scheduling_date, '%Y-%m') = #{date}
+    </select>
+
+    <select id="selectDailyWagesStats" resultType="java.util.Map">
+        select date_format(scheduling_date, '%m-%d') as dateStr,
+               cast(ifnull(sum(finished_num), 0) as decimal(18,2)) as numberOfCompleted,
+               cast(ifnull(sum(work_hours), 0) as decimal(18,2)) as amount,
+               cast(0 as decimal(18,2)) as passRate
+        from production_account
+        where scheduling_date &gt;= #{startDate}
+          and scheduling_date &lt;= #{endDate}
+        group by date_format(scheduling_date, '%m-%d')
+        order by date_format(scheduling_date, '%m-%d')
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml b/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
index 5b67bf6..5a40417 100644
--- a/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
+++ b/src/main/resources/mapper/production/ProductionOperationTaskMapper.xml
@@ -21,4 +21,68 @@
         <result column="dept_id" property="deptId" />
     </resultMap>
 
+    <select id="selectTaskStatisticsByDate" resultType="com.ruoyi.home.dto.ProductionTaskStatisticsDto">
+        select pot.id,
+               pot.work_order_no,
+               pot.plan_start_time as planStartTime,
+               pot.plan_end_time as planEndTime,
+               pot.actual_start_time as actualStartTime,
+               pot.actual_end_time as actualEndTime,
+               pot.plan_quantity as planQuantity,
+               ifnull(pot.complete_quantity, 0) as completeQuantity,
+               top2.name as processName,
+               p.product_name as productName,
+               pm.model,
+               pm.unit,
+               po.nps_no as productOrderNpsNo
+        from production_operation_task pot
+                 left join production_order po on pot.production_order_id = po.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 technology_routing_operation tro on pot.technology_routing_operation_id = tro.id
+                 left join technology_operation top2 on tro.technology_operation_id = top2.id
+        where date(pot.create_time) between #{startDate} and #{endDate}
+        order by pot.create_time desc
+    </select>
+
+    <select id="selectTaskStartStats" resultType="com.ruoyi.home.dto.ProductionTaskStatisticsDto">
+        select id,
+               actual_start_time as actualStartTime,
+               plan_quantity as planQuantity
+        from production_operation_task
+        where actual_start_time &gt;= #{startDateTime}
+          and actual_start_time &lt;= #{endDateTime}
+    </select>
+
+    <select id="calculateProductionStatistics" resultType="com.ruoyi.home.dto.processDataProductionStatisticsDto">
+        select top2.name as processName,
+               sum(ifnull(ppi.input_quantity, 0)) as totalInput,
+               sum(ifnull(ppo.scrap_qty, 0)) as totalScrap,
+               sum(ifnull(ppo.quantity, 0) - ifnull(ppo.scrap_qty, 0)) as totalOutput
+        from production_product_output ppo
+                 inner join production_product_main ppm on ppo.production_product_main_id = ppm.id
+                 inner join production_operation_task pot on ppm.production_operation_task_id = pot.id
+                 inner join technology_routing_operation tro on pot.technology_routing_operation_id = tro.id
+                 inner join technology_operation top2 on tro.technology_operation_id = top2.id
+                 left join production_product_input ppi on ppi.production_product_main_id = ppm.id
+        <where>
+            <if test="startDateTime != null">
+                and ppo.create_time &gt;= #{startDateTime}
+            </if>
+            <if test="endDateTime != null">
+                and ppo.create_time &lt;= #{endDateTime}
+            </if>
+            <if test="userId != null">
+                and ppm.create_user = #{userId}
+            </if>
+            <if test="processIds != null and processIds.size() > 0">
+                and top2.id in
+                <foreach collection="processIds" item="id" open="(" separator="," close=")">
+                    #{id}
+                </foreach>
+            </if>
+        </where>
+        group by top2.id, top2.name
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionOrderMapper.xml b/src/main/resources/mapper/production/ProductionOrderMapper.xml
index c52e291..3c26d4e 100644
--- a/src/main/resources/mapper/production/ProductionOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductionOrderMapper.xml
@@ -21,4 +21,52 @@
         <result column="dept_id" property="deptId" />
     </resultMap>
 
+    <select id="selectProgressOrders" resultType="com.ruoyi.home.dto.ProductionProgressOrderDto">
+        select po.nps_no,
+               sl.sales_contract_no,
+               sl.project_name,
+               sl.customer_name,
+               p.product_name as productCategory,
+               pm.model as specificationModel,
+               tr.process_route_code as processRouteCode,
+               po.quantity,
+               ifnull(po.complete_quantity, 0) as completeQuantity,
+               round(ifnull(po.complete_quantity, 0) / nullif(po.quantity, 0) * 100, 2) as completionStatus,
+               tb.bom_no,
+               datediff(sl.delivery_date, curdate()) as deliveryDaysDiff,
+               sl.delivery_date,
+               false as isFh
+        from production_order po
+                 left join sales_ledger sl on po.sales_ledger_id = sl.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 technology_routing tr on po.technology_routing_id = tr.id
+                 left join technology_bom tb on tr.bom_id = tb.id
+        where po.create_time between #{startTime} and #{endTime}
+        order by po.create_time desc
+    </select>
+
+    <select id="countCreated" resultType="java.lang.Integer">
+        select count(1)
+        from production_order
+        where create_time &gt;= #{startDate}
+          and create_time &lt;= #{endDate}
+    </select>
+
+    <select id="countCompleted" resultType="java.lang.Integer">
+        select count(1)
+        from production_order
+        where end_time &gt;= #{startDate}
+          and end_time &lt;= #{endDate}
+          and ifnull(complete_quantity, 0) &gt;= quantity
+    </select>
+
+    <select id="countPending" resultType="java.lang.Integer">
+        select count(1)
+        from production_order
+        where create_time &gt;= #{startDate}
+          and create_time &lt;= #{endDate}
+          and ifnull(complete_quantity, 0) &lt; quantity
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionPlanMapper.xml b/src/main/resources/mapper/production/ProductionPlanMapper.xml
index 3e3a683..fee9fcc 100644
--- a/src/main/resources/mapper/production/ProductionPlanMapper.xml
+++ b/src/main/resources/mapper/production/ProductionPlanMapper.xml
@@ -4,21 +4,89 @@
 
     <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
     <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductionPlan">
-        <id column="id" property="id" />
-        <result column="mps_no" property="mpsNo" />
-        <result column="required_date" property="requiredDate" />
-        <result column="remark" property="remark" />
-        <result column="create_time" property="createTime" />
-        <result column="update_time" property="updateTime" />
-        <result column="create_user" property="createUser" />
-        <result column="update_user" property="updateUser" />
-        <result column="product_model_id" property="productModelId" />
-        <result column="qty_required" property="qtyRequired" />
-        <result column="state" property="state" />
-        <result column="issued" property="issued" />
-        <result column="source" property="source" />
-        <result column="is_audit" property="isAudit" />
-        <result column="promised_delivery_date" property="promisedDeliveryDate" />
+        <id column="id" property="id"/>
+        <result column="mps_no" property="mpsNo"/>
+        <result column="required_date" property="requiredDate"/>
+        <result column="remark" property="remark"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="create_user" property="createUser"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="product_model_id" property="productModelId"/>
+        <result column="qty_required" property="qtyRequired"/>
+        <result column="state" property="state"/>
+        <result column="issued" property="issued"/>
+        <result column="source" property="source"/>
+        <result column="is_audit" property="isAudit"/>
+        <result column="promised_delivery_date" property="promisedDeliveryDate"/>
     </resultMap>
 
+    <select id="listPage" resultType="com.ruoyi.production.bean.dto.ProductionPlanDto">
+        SELECT
+        pp.*,
+        pms.material_code AS materialCode,
+        pms.model,
+        pms.product_id AS productMaterialId,
+        pm.product_name AS productName,
+        pm.unit
+        FROM production_plan pp
+        left join product_material_sku pms on pp.product_material_sku_id = pms.id
+        left join product_material pm on pms.product_id = pm.id
+        WHERE 1 = 1
+        <if test="c.customerName != null and c.customerName != '' ">
+            AND pp.customer_name LIKE CONCAT('%',#{c.customerName},'%')
+        </if>
+        <if test="c.productName != null and c.productName != '' ">
+            AND pm.product_name LIKE CONCAT('%',#{c.productName},'%')
+        </if>
+        <if test="c.materialCode != null and c.materialCode != '' ">
+            AND pms.material_code LIKE CONCAT('%',#{c.materialCode},'%')
+        </if>
+        <if test="c.model != null and c.model != '' ">
+            AND pms.model LIKE CONCAT('%',#{c.model},'%')
+        </if>
+        <if test="c.status != null">
+            AND pp.status =#{c.status}
+        </if>
+        <if test="c.applyNo != null and c.applyNo != '' ">
+            AND pp.apply_no LIKE CONCAT('%',#{c.applyNo},'%')
+        </if>
+        <if test="c.startDate != null">
+            AND pp.start_date &gt;= DATE_FORMAT(#{c.startDate},'%Y-%m-%d')
+        </if>
+        <if test="c.endDate != null">
+            AND pp.end_date &lt;= DATE_FORMAT(#{c.endDate},'%Y-%m-%d')
+        </if>
+        ORDER BY COALESCE(pp.form_modified_time, pp.id) DESC
+    </select>
+
+    <select id="selectWithMaterialByIds" resultType="com.ruoyi.production.bean.dto.ProductionPlanDto">
+        SELECT
+        pp.*,
+        pms.material_code AS materialCode,
+        pms.model,
+        pm.product_name AS productName,
+        pm.unit
+        FROM production_plan pp
+        LEFT JOIN product_material_sku pms ON pp.product_material_sku_id = pms.id
+        LEFT JOIN product_material pm ON pms.product_id = pm.id
+        WHERE pp.id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        ORDER BY pp.id ASC
+    </select>
+    <select id="selectProductionPlanDtoById" resultType="com.ruoyi.production.bean.dto.ProductionPlanDto">
+        SELECT
+        pp.*,
+        pms.material_code AS materialCode,
+        pms.model,
+        pms.product_id AS productMaterialId,
+        pm.product_name AS productName,
+        pm.unit
+        FROM production_plan pp
+        left join product_material_sku pms on pp.product_material_sku_id = pms.id
+        left join product_material pm on pms.product_id = pm.id
+        WHERE pp.id = #{productionPlanId}
+    </select>
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductInputMapper.xml b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
index 236aa2b..506ec70 100644
--- a/src/main/resources/mapper/production/ProductionProductInputMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -14,4 +14,30 @@
         <result column="update_user" property="updateUser" />
     </resultMap>
 
+    <select id="listPageProductionProductInputDto" resultType="com.ruoyi.production.bean.dto.ProductionProductInputDto">
+        select ppi.*,
+               ppm.product_no as productNo,
+               pm.model,
+               p.product_name as productName,
+               pm.unit
+        from production_product_input ppi
+                 left join production_product_main ppm on ppi.production_product_main_id = ppm.id
+                 left join production_operation_task pot on ppm.production_operation_task_id = pot.id
+                 left join production_order po on pot.production_order_id = po.id
+                 left join product_model pm on po.product_model_id = pm.id
+                 left join product p on pm.product_id = p.id
+        <where>
+            <if test="c.productNo != null and c.productNo != ''">
+                and ppm.product_no like concat('%', #{c.productNo}, '%')
+            </if>
+            <if test="c.model != null and c.model != ''">
+                and pm.model like concat('%', #{c.model}, '%')
+            </if>
+            <if test="c.productName != null and c.productName != ''">
+                and p.product_name like concat('%', #{c.productName}, '%')
+            </if>
+        </where>
+        order by ppi.create_time desc
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductMainMapper.xml b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
index d108498..e9200b9 100644
--- a/src/main/resources/mapper/production/ProductionProductMainMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -14,4 +14,97 @@
         <result column="update_user" property="updateUser" />
     </resultMap>
 
+    <select id="listPageProductionProductMainDto" resultType="com.ruoyi.production.bean.dto.ProductionProductMainDto">
+        select ppm.*,
+               pot.work_order_no as workOrderNo,
+               case pot.status
+                   when 1 then '寰呯‘璁�'
+                   when 2 then '寰呯敓浜�'
+                   when 3 then '鐢熶骇涓�'
+                   when 4 then '宸茬敓浜�'
+                   else '鏈煡'
+                   end as workOrderStatus,
+               su.nick_name as nickName,
+               ifnull(ppo.quantity, 0) as quantity,
+               ifnull(ppo.scrap_qty, 0) as scrapQty,
+               p.product_name as productName,
+               pm.model as productModelName,
+               pm.unit,
+               sl.sales_contract_no as salesContractNo,
+               date(ppm.create_time) as schedulingDate,
+               su.nick_name as schedulingUserName,
+               sl.customer_name as customerName,
+               top2.name as process
+        from production_product_main ppm
+                 left join production_operation_task pot on ppm.production_operation_task_id = pot.id
+                 left join production_order po on pot.production_order_id = po.id
+                 left join sales_ledger sl on po.sales_ledger_id = sl.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 technology_routing_operation tro on pot.technology_routing_operation_id = tro.id
+                 left join technology_operation top2 on tro.technology_operation_id = top2.id
+                 left join sys_user su on ppm.create_user = su.user_id
+                 left join production_product_output ppo on ppo.production_product_main_id = ppm.id
+        <where>
+            <if test="c.productNo != null and c.productNo != ''">
+                and ppm.product_no like concat('%', #{c.productNo}, '%')
+            </if>
+            <if test="c.workOrderNo != null and c.workOrderNo != ''">
+                and pot.work_order_no like concat('%', #{c.workOrderNo}, '%')
+            </if>
+            <if test="c.salesContractNo != null and c.salesContractNo != ''">
+                and sl.sales_contract_no like concat('%', #{c.salesContractNo}, '%')
+            </if>
+            <if test="c.customerName != null and c.customerName != ''">
+                and sl.customer_name like concat('%', #{c.customerName}, '%')
+            </if>
+            <if test="c.productName != null and c.productName != ''">
+                and p.product_name like concat('%', #{c.productName}, '%')
+            </if>
+            <if test="c.productModelName != null and c.productModelName != ''">
+                and pm.model like concat('%', #{c.productModelName}, '%')
+            </if>
+            <if test="c.process != null and c.process != ''">
+                and top2.name like concat('%', #{c.process}, '%')
+            </if>
+            <if test="c.schedulingDate != null">
+                and date(ppm.create_time) = #{c.schedulingDate}
+            </if>
+        </where>
+        order by ppm.create_time desc
+    </select>
+
+    <select id="getOrderByMainId" resultType="com.ruoyi.production.pojo.ProductionOrder">
+        select null
+    </select>
+
+    <select id="listProductionDetails" resultType="com.ruoyi.production.bean.dto.ProductionProductMainDto">
+        select ppm.*,
+               pot.work_order_no as workOrderNo,
+               p.product_name as productName,
+               pm.model as productModelName,
+               pm.unit,
+               top2.name as process,
+               ifnull(ppo.quantity, 0) as quantity,
+               ifnull(ppo.scrap_qty, 0) as scrapQty
+        from production_product_main ppm
+                 left join production_operation_task pot on ppm.production_operation_task_id = pot.id
+                 left join production_order po on pot.production_order_id = po.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 technology_routing_operation tro on pot.technology_routing_operation_id = tro.id
+                 left join technology_operation top2 on tro.technology_operation_id = top2.id
+                 left join production_product_output ppo on ppo.production_product_main_id = ppm.id
+        order by ppm.create_time desc
+    </select>
+
+    <select id="listMain" resultType="java.lang.Long">
+        select id
+        from production_product_main
+        where production_operation_task_id in
+        <foreach collection="list" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductOutputMapper.xml b/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
index 0656e91..6dc9682 100644
--- a/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
@@ -15,4 +15,47 @@
         <result column="update_user" property="updateUser" />
     </resultMap>
 
+    <select id="listPageProductionProductOutputDto" resultType="com.ruoyi.production.bean.dto.ProductionProductOutputDto">
+        select ppo.*,
+               ppm.product_no as productNo,
+               pm.model
+        from production_product_output ppo
+                 left join production_product_main ppm on ppo.production_product_main_id = ppm.id
+                 left join production_operation_task pot on ppm.production_operation_task_id = pot.id
+                 left join production_order po on pot.production_order_id = po.id
+                 left join product_model pm on po.product_model_id = pm.id
+        <where>
+            <if test="c.productNo != null and c.productNo != ''">
+                and ppm.product_no like concat('%', #{c.productNo}, '%')
+            </if>
+            <if test="c.model != null and c.model != ''">
+                and pm.model like concat('%', #{c.model}, '%')
+            </if>
+        </where>
+        order by ppo.create_time desc
+    </select>
+
+    <select id="selectOutputStats" resultType="com.ruoyi.production.bean.dto.ProductionProductOutputDto">
+        select id,
+               production_product_main_id as productionProductMainId,
+               product_model_id as productModelId,
+               quantity,
+               scrap_qty as scrapQty,
+               create_time as createTime
+        from production_product_output
+        where create_time &gt;= #{startDate}
+          and create_time &lt;= #{endDate}
+    </select>
+
+    <select id="selectDailyOutputStats" resultType="java.util.Map">
+        select date(create_time) as statDate,
+               sum(ifnull(quantity, 0)) as quantity,
+               sum(ifnull(scrap_qty, 0)) as scrapQty
+        from production_product_output
+        where create_time &gt;= #{startDate}
+          and create_time &lt;= #{endDate}
+        group by date(create_time)
+        order by statDate asc
+    </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml b/src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml
deleted file mode 100644
index f2e460a..0000000
--- a/src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper">
-
-    <select id="listPage" resultType="com.ruoyi.production2.dto.SalesLedgerProductionAccountingDto">
-        SELECT
-        t4.id,
-        t4.finished_num * t4.work_hours as wages,
-        t4.scheduling_user_id,
-        t4.scheduling_user_name,
-        t4.scheduling_date,
-        t4.finished_num,
-        t4.work_hours,
-        t4.process,
-        T1.sales_contract_no,
-        T1.customer_contract_no,
-        T1.project_name,
-        T1.customer_name,
-        t3.product_category,
-        t3.specification_model,
-        t3.unit
-        FROM
-        sales_ledger_production_accounting t4
-        LEFT JOIN sales_ledger T1 ON T1.id = t4.sales_ledger_id
-        left join sales_ledger_product t3 on t4.sales_ledger_product_id = t3.id and slp.type = 1
-        <where>
-            t3.type = 1
-            <if test="salesLedgerDto.schedulingUserName != null and salesLedgerDto.schedulingUserName != '' ">
-                AND  t4.scheduling_user_name LIKE CONCAT('%',#{salesLedgerDto.schedulingUserName},'%')
-            </if>
-            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
-                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
-            </if>
-            <if test="salesLedgerDto.customerContractNo != null and salesLedgerDto.customerContractNo !='' ">
-                AND  T1.customer_contract_no LIKE CONCAT('%',#{salesLedgerDto.customerContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.salesContractNo != null and salesLedgerDto.salesContractNo != '' ">
-                AND  T1.sales_contract_no LIKE CONCAT('%',#{salesLedgerDto.salesContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.projectName != null and salesLedgerDto.projectName != '' ">
-                AND T1.project_name LIKE CONCAT('%',#{salesLedgerDto.projectName},'%')
-            </if>
-            <if test="salesLedgerDto.entryDateStart != null and salesLedgerDto.entryDateStart != '' ">
-                AND t4.scheduling_date &gt;= DATE_FORMAT(#{salesLedgerDto.entryDateStart},'%Y-%m-%d')
-            </if>
-            <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
-                AND  t4.scheduling_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
-            </if>
-        </where>
-        group by t4.id
-        order by t4.scheduling_date desc
-    </select>
-    <select id="pageProductionAccounting"
-            resultType="com.ruoyi.production2.dto.SalesLedgerProductionAccountingDto">
-        SELECT
-        slpa.scheduling_user_id,
-        slpa.scheduling_user_name,
-        sum(ppout.quantity) as output_num,
-        sum(slpa.finished_num * work_hours) as wages,
-        CONCAT(
-        ROUND(
-        CASE
-        WHEN SUM(ppout.quantity) = 0 OR SUM(ppout.quantity) IS NULL THEN 0
-        ELSE SUM(slpa.finished_num) * 100.0 / SUM(ppout.quantity)
-        END,
-        2
-        ),
-        '%'
-        ) as output_rate
-        FROM sales_ledger_production_accounting slpa
-        LEFT JOIN production_product_main ppm ON slpa.product_main_id = ppm.id
-        LEFT JOIN production_product_output ppout ON ppm.id = ppout.product_main_id
-        <where>
-            <if test="ew.schedulingUserName != null and ew.schedulingUserName !=''">
-                and slpa.scheduling_user_name = #{ew.schedulingUserName}
-            </if>
-            <if test="ew.entryDate != null ">
-                and slpa.scheduling_date >= #{ew.entryDate}
-                and slpa.scheduling_date &lt; DATE_ADD(DATE(#{ew.entryDate}), INTERVAL 1 DAY)
-            </if>
-            <if test="ew.entryDateStart != null and ew.entryDateEnd != null">
-                and slpa.scheduling_date >= #{ew.entryDateStart}
-                and slpa.scheduling_date &lt; DATE_ADD(DATE(#{ew.entryDateEnd}), INTERVAL 1 DAY)
-            </if>
-
-        </where>
-        GROUP BY slpa.scheduling_user_id, slpa.scheduling_user_name
-    </select>
-
-    <select id="selectDailyWagesStats" resultType="java.util.Map">
-        SELECT DATE(ppout.create_time)                                                         AS dateStr,
-               SUM(ppout.quantity - IFNULL(ppout.scrap_qty, 0))                                AS numberOfCompleted,
-               SUM((ppout.quantity - IFNULL(ppout.scrap_qty, 0)) * IFNULL(pp.salary_quota, 0)) AS amount,
-               ROUND(
-                       SUM(ppout.quantity - IFNULL(ppout.scrap_qty, 0)) * 100 / NULLIF(SUM(ppout.quantity), 0),
-                       2
-               )                                                                               AS passRate
-        FROM production_product_output ppout
-                 LEFT JOIN production_product_main ppm ON ppm.id = ppout.product_main_id
-                 LEFT JOIN product_process_route_item ppri ON ppri.id = ppm.product_process_route_item_id
-                 LEFT JOIN product_process pp ON pp.id = ppri.process_id
-        WHERE ppout.create_time &gt;= #{startDate}
-          AND ppout.create_time &lt; #{endDate}
-        GROUP BY DATE(ppout.create_time)
-        ORDER BY DATE(ppout.create_time);
-    </select>
-    <select id="getByUserId" resultType="com.ruoyi.production2.dto.UserAccountDto">
-        select
-            slpa.scheduling_user_id as user_id,
-            pp.type,
-            sum(case when pp.type = 0 then slpa.work_hours else 0 end) as account,
-            sum(case when pp.type = 1 then slpa.work_hours else 0 end) as accountBalance
-        from sales_ledger_production_accounting slpa
-                 left join product_process pp on pp.name = slpa.process
-        where  slpa.scheduling_user_id = #{ew.userId}
-          and slpa.scheduling_date like concat(#{ew.date}, '%')
-        group by slpa.scheduling_user_id
-
-    </select>
-
-
-</mapper>
diff --git a/src/main/resources/mapper/production/SalesLedgerSchedulingMapper.xml b/src/main/resources/mapper/production/SalesLedgerSchedulingMapper.xml
deleted file mode 100644
index 92198b5..0000000
--- a/src/main/resources/mapper/production/SalesLedgerSchedulingMapper.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.SalesLedgerSchedulingMapper">
-
-    <select id="listPage" resultType="com.ruoyi.production2.dto.SalesLedgerSchedulingDto">
-        SELECT
-        T2.id as salesLedgerProductId,
-        T1.id as salesLedgerId,
-        ifNull(sum(t3.scheduling_num),0) AS schedulingNum,
-        T1.sales_contract_no,
-        T1.customer_contract_no,
-        T1.project_name,
-        T1.entry_date,
-        T1.customer_name,
-        T2.quantity,
-        T2.product_category,
-        T2.specification_model,
-        T2.speculative_trading_name,
-        T2.unit
-        FROM
-        sales_ledger_product T2
-        LEFT join sales_ledger_scheduling t3 on T2.id = t3.sales_ledger_product_id
-        LEFT JOIN sales_ledger T1 ON T1.id = T2.sales_ledger_id
-        <where>
-            T1.id is not null and T2.type = 1
-            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
-                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
-            </if>
-            <if test="salesLedgerDto.customerContractNo != null and salesLedgerDto.customerContractNo !='' ">
-                AND  T1.customer_contract_no LIKE CONCAT('%',#{salesLedgerDto.customerContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.salesContractNo != null and salesLedgerDto.salesContractNo != '' ">
-                AND  T1.sales_contract_no LIKE CONCAT('%',#{salesLedgerDto.salesContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.projectName != null and salesLedgerDto.projectName != '' ">
-                AND T1.project_name LIKE CONCAT('%',#{salesLedgerDto.projectName},'%')
-            </if>
-            <if test="salesLedgerDto.entryDateStart != null and salesLedgerDto.entryDateStart != '' ">
-                AND T1.entry_date &gt;= DATE_FORMAT(#{salesLedgerDto.entryDateStart},'%Y-%m-%d')
-            </if>
-            <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
-                AND  T1.entry_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
-            </if>
-        </where>
-        GROUP BY T2.id
-        <if test="salesLedgerDto.status != null and salesLedgerDto.status.equals('true')">
-            HAVING quantity - schedulingNum > 0
-        </if>
-        order by T1.entry_date desc
-    </select>
-    <select id="list" resultType="com.ruoyi.production2.dto.SalesLedgerSchedulingDto">
-        SELECT
-            T2.id,
-            ifNull(sum(t3.scheduling_num),0) AS schedulingNum,
-            T1.sales_contract_no,
-            T1.customer_contract_no,
-            T1.project_name,
-            T1.entry_date,
-            T1.customer_name,
-            T2.quantity,
-            T2.product_category,
-            T2.specification_model,
-            T2.unit
-        FROM
-            sales_ledger_product T2
-                LEFT JOIN sales_ledger T1 ON T1.id = T2.sales_ledger_id
-                LEFT join sales_ledger_scheduling t3 on T1.id = t3.sales_ledger_id
-        where T1.id is not null and T2.type = 1
-        GROUP BY T2.id
-    </select>
-    <select id="listPageProcess" resultType="com.ruoyi.production2.dto.SalesLedgerSchedulingProcessDto">
-        SELECT
-        t3.id as salesLedgerProductId,
-        T1.id as salesLedgerId,
-        T2.id,
-        T2.status,
-        T2.scheduling_user_id,
-        T2.scheduling_user_name,
-        T2.speculative_trading_name,
-        T2.scheduling_date,
-        ifNull(T2.scheduling_num,0) AS schedulingNum,
-        ifNull(T2.finished_num,0) AS successNum,
-        T1.sales_contract_no,
-        T1.customer_contract_no,
-        T1.project_name,
-        T1.customer_name,
-        t3.product_category,
-        t3.specification_model,
-        t3.unit,
-        T2.production_line
-        FROM
-        sales_ledger_scheduling T2
-        LEFT JOIN sales_ledger T1 ON T1.id = T2.sales_ledger_id
-        left join sales_ledger_product t3 on T2.sales_ledger_product_id = t3.id and slp.type = 1
-        <where>
-            t3.type = 1
-            <if test="salesLedgerDto.status != null and salesLedgerDto.status != '' ">
-                AND  T2.status = #{salesLedgerDto.status}
-            </if>
-            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
-                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
-            </if>
-            <if test="salesLedgerDto.customerContractNo != null and salesLedgerDto.customerContractNo !='' ">
-                AND  T1.customer_contract_no LIKE CONCAT('%',#{salesLedgerDto.customerContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.salesContractNo != null and salesLedgerDto.salesContractNo != '' ">
-                AND  T1.sales_contract_no LIKE CONCAT('%',#{salesLedgerDto.salesContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.projectName != null and salesLedgerDto.projectName != '' ">
-                AND T1.project_name LIKE CONCAT('%',#{salesLedgerDto.projectName},'%')
-            </if>
-            <if test="salesLedgerDto.entryDateStart != null and salesLedgerDto.entryDateStart != '' ">
-                AND T2.scheduling_date &gt;= DATE_FORMAT(#{salesLedgerDto.entryDateStart},'%Y-%m-%d')
-            </if>
-            <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
-                AND  T2.scheduling_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
-            </if>
-        </where>
-        order by T2.scheduling_date desc
-    </select>
-</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/production/SalesLedgerWorkMapper.xml b/src/main/resources/mapper/production/SalesLedgerWorkMapper.xml
deleted file mode 100644
index 974220b..0000000
--- a/src/main/resources/mapper/production/SalesLedgerWorkMapper.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.production.mapper.SalesLedgerWorkMapper">
-
-    <select id="listPage" resultType="com.ruoyi.production2.dto.SalesLedgerWorkDto">
-        SELECT
-        t4.id,
-        t4.status,
-        t4.scheduling_user_id,
-        t4.scheduling_user_name,
-        t4.scheduling_date,
-        t4.scheduling_num,
-        t4.finished_num,
-        t4.work_hours,
-        t4.process,
-        t4.type,
-        t4.remark,
-        t4.receive,
-        T1.sales_contract_no,
-        T1.customer_contract_no,
-        T1.project_name,
-        T1.customer_name,
-        t3.product_category,
-        t3.specification_model,
-        t3.unit,
-        t2.speculative_trading_name,
-        t4.production_line
-        FROM
-        sales_ledger_work t4
-        LEFT JOIN sales_ledger T1 ON T1.id = t4.sales_ledger_id
-        left join sales_ledger_product t3 on t4.sales_ledger_product_id = t3.id and slp.type = 1
-        left join sales_ledger_scheduling t2 on t4.sales_ledger_scheduling_id = t2.id
-        <where>
-            t3.type = 1
-            <if test="salesLedgerDto.status != null and salesLedgerDto.status != '' ">
-                AND  t4.status = #{salesLedgerDto.status}
-            </if>
-            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
-                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
-            </if>
-            <if test="salesLedgerDto.customerContractNo != null and salesLedgerDto.customerContractNo !='' ">
-                AND  T1.customer_contract_no LIKE CONCAT('%',#{salesLedgerDto.customerContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.salesContractNo != null and salesLedgerDto.salesContractNo != '' ">
-                AND  T1.sales_contract_no LIKE CONCAT('%',#{salesLedgerDto.salesContractNo},'%')
-            </if>
-            <if test="salesLedgerDto.projectName != null and salesLedgerDto.projectName != '' ">
-                AND T1.project_name LIKE CONCAT('%',#{salesLedgerDto.projectName},'%')
-            </if>
-            <if test="salesLedgerDto.entryDateStart != null and salesLedgerDto.entryDateStart != '' ">
-                AND t4.scheduling_date &gt;= DATE_FORMAT(#{salesLedgerDto.entryDateStart},'%Y-%m-%d')
-            </if>
-            <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
-                AND  t4.scheduling_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
-            </if>
-        </where>
-        order by t4.scheduling_date desc
-    </select>
-</mapper>
\ No newline at end of file

--
Gitblit v1.9.3