From 2a9c3934bb093c978a54a1c3e220e6a120855e77 Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期五, 09 一月 2026 15:11:35 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/jtwy' into jtwy

---
 src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java                            |    9 
 src/main/java/com/ruoyi/basic/pojo/Customer.java                                               |    4 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java        |   24 
 src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java                           |    2 
 src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java                   |   61 +
 src/main/java/com/ruoyi/device/dto/DeviceRepairDto.java                                        |    5 
 src/main/java/com/ruoyi/procurementrecord/controller/ProcurementExceptionRecordController.java |   46 +
 src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml                                    |   12 
 src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java            |   25 
 src/main/java/com/ruoyi/production/controller/ProductStructureController.java                  |    2 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java         |   24 
 src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java                            |    4 
 src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java                                 |   20 
 src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java                          |    9 
 src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java                          |   26 
 src/main/java/com/ruoyi/production/service/ProductionProductMainService.java                   |    4 
 src/main/resources/mapper/production/ProductOrderMapper.xml                                    |    5 
 src/main/resources/mapper/sales/SalesLedgerProductMapper.xml                                   |   25 
 src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml                       |    7 
 src/main/resources/mapper/basic/SupplierManageFileMapper.xml                                   |    9 
 src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementExceptionRecord.java                 |   54 +
 src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java                         |   15 
 src/main/java/com/ruoyi/production/service/ProductionProductInputService.java                  |   11 
 src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java                                |   32 
 src/main/resources/mapper/sales/ShipmentApprovalMapper.xml                                     |   24 
 src/main/java/com/ruoyi/device/controller/DeviceRepairController.java                          |   62 +
 src/main/java/com/ruoyi/device/dto/DeviceAssetInfoDto.java                                     |   28 
 src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java                           |    9 
 src/main/java/com/ruoyi/device/pojo/DeviceRepair.java                                          |   15 
 src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java                     |    8 
 src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java                 |   11 
 src/main/java/com/ruoyi/quality/pojo/QualityInspect.java                                       |    5 
 doc/create_table_process_route_item.sql                                                        |    4 
 src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java                       |   17 
 src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java                             |   20 
 src/main/java/com/ruoyi/basic/mapper/SupplierManageFileMapper.java                             |   15 
 doc/1767778273_add_product_order_id_to_product_work_order.sql                                  |    2 
 src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java                |    1 
 src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java                        |   15 
 src/main/java/com/ruoyi/sales/mapper/ShipmentApprovalMapper.java                               |   16 
 src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java                           |    5 
 src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml                        |    3 
 src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java                             |    4 
 src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java                           |    1 
 src/main/resources/mapper/procurementrecord/ProcurementExceptionRecordMapper.xml               |    5 
 src/main/resources/mapper/production/ProductWorkOrderMapper.xml                                |   66 +
 src/main/resources/mapper/sales/SalesLedgerMapper.xml                                          |    5 
 src/main/resources/mapper/production/ProductionProductInputMapper.xml                          |   30 
 src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java                                  |   93 +
 src/main/resources/mapper/basic/SupplierManageMapper.xml                                       |    8 
 src/main/resources/mapper/purchase/ProductRecordMapper.xml                                     |    4 
 src/main/java/com/ruoyi/device/service/IDeviceLedgerService.java                               |    2 
 src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java                                     |   28 
 src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java                               |    5 
 src/main/java/com/ruoyi/sales/pojo/SalesLedger.java                                            |    4 
 src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java             |   34 
 src/main/java/com/ruoyi/basic/controller/SupplierManageFileController.java                     |   63 +
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java                  |  112 +
 src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java          |    6 
 src/main/resources/mapper/production/ProductionProductOutputMapper.xml                         |   31 
 src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java                  |   37 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java                         |  145 ++
 src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java                      |   47 +
 src/main/java/com/ruoyi/production/pojo/ProductProcess.java                                    |    3 
 src/main/java/com/ruoyi/procurementrecord/dto/InventoryInformationDto.java                     |   28 
 src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java                           |   37 
 src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java                                      |    8 
 src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java                    |   16 
 src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java                                       |    9 
 src/main/java/com/ruoyi/sales/service/ShipmentApprovalService.java                             |   13 
 src/main/java/com/ruoyi/basic/service/impl/SupplierManageFileServiceImpl.java                  |   23 
 src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java                   |   12 
 src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java                                       |   39 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java          |  243 +++++
 src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java                                    |   12 
 src/main/java/com/ruoyi/basic/pojo/SupplierManage.java                                         |    3 
 src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java       |   62 +
 src/main/java/com/ruoyi/sales/service/impl/ShipmentApprovalServiceImpl.java                    |   32 
 src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java                                           |    6 
 src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java                           |   11 
 src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java                       |   77 +
 src/main/resources/mapper/quality/QualityInspectMapper.xml                                     |   17 
 src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java           |  113 ++
 src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java                       |   12 
 src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java               |   32 
 src/main/java/com/ruoyi/basic/service/SupplierManageFileService.java                           |   12 
 src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementExceptionRecordMapper.java         |    9 
 src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java                          |   14 
 src/main/resources/mapper/device/DeviceRepairMapper.xml                                        |    2 
 src/main/java/com/ruoyi/basic/pojo/SupplierManageFile.java                                     |   60 +
 src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml                         |    2 
 src/main/resources/mapper/production/ProductionProductMainMapper.xml                           |    8 
 src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java                    |   12 
 src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java                                  |    6 
 src/main/java/com/ruoyi/sales/pojo/ShipmentApproval.java                                       |  352 +++++++
 src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java           |   27 
 96 files changed, 2,570 insertions(+), 167 deletions(-)

diff --git a/doc/1767778273_add_product_order_id_to_product_work_order.sql b/doc/1767778273_add_product_order_id_to_product_work_order.sql
new file mode 100644
index 0000000..8804120
--- /dev/null
+++ b/doc/1767778273_add_product_order_id_to_product_work_order.sql
@@ -0,0 +1,2 @@
+alter table product_work_order
+    add product_order_id bigint not null default 0 comment '鐢熶骇璁㈠崟id';
diff --git a/doc/create_table_process_route_item.sql b/doc/create_table_process_route_item.sql
index ea0a8a7..a1efff9 100644
--- a/doc/create_table_process_route_item.sql
+++ b/doc/create_table_process_route_item.sql
@@ -50,6 +50,10 @@
     create_time      datetime null comment '褰曞叆鏃堕棿',
     update_time      datetime null comment '鏇存柊鏃堕棿',
     work_order_no    varchar(255) not null default '' comment '宸ュ崟缂栧彿',
+    plan_start_time  datetime null comment '璁″垝寮�濮嬫椂闂�',
+    plan_end_time    datetime null comment '璁″垝缁撴潫鏃堕棿',
+    actual_start_time  datetime null comment '瀹為檯寮�濮嬫椂闂�',
+    actual_end_time    datetime null comment '瀹為檯缁撴潫鏃堕棿',
     status           int not null default 0 comment '鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜� ',
     tenant_id        bigint   not null comment '绉熸埛id'
 );
diff --git a/src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java b/src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java
index 6fefc5d..64177e8 100644
--- a/src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java
+++ b/src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java
@@ -157,7 +157,14 @@
      * 鍒涘缓鏃堕棿
      */
     private LocalDateTime createTime;
-
+    /**
+     * 璁惧鎶ヤ慨id
+     */
+    private Long deviceRepairId;
+    /**
+     * 鎶ヤ慨閲戦
+     */
+    private BigDecimal maintenancePrice;
     private static final long serialVersionUID = 1L;
 
 
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
index 899d5c8..f5919de 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -10,6 +10,8 @@
 import com.ruoyi.approve.service.IApproveNodeService;
 import com.ruoyi.common.enums.FileNameType;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.device.mapper.DeviceRepairMapper;
+import com.ruoyi.device.pojo.DeviceRepair;
 import com.ruoyi.other.service.impl.TempFileServiceImpl;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysUserMapper;
@@ -43,6 +45,9 @@
 
     @Autowired
     private CommonFileMapper fileMapper;
+    @Autowired
+    private DeviceRepairMapper deviceRepairMapper;
+
 
 
     public ApproveProcess getApproveById(String id) {
@@ -135,11 +140,21 @@
             approveProcess.setApproveUserCurrentId(approveNode1.getApproveNodeUserId());
             approveProcess.setApproveUserCurrentName(approveNode1.getApproveNodeUser());
         }
-        if (approveProcess.getApproveStatus() != 1){
+        if(approveProcess.getApproveStatus().equals(2) || approveProcess.getApproveStatus().equals(3) || approveProcess.getApproveStatus().equals(4)){
             approveProcess.setApproveOverTime(new Date());
         }
         approveProcessMapper.updateById(approveProcess);
 
+        DeviceRepair deviceRepair = deviceRepairMapper.selectById(approveProcess.getDeviceRepairId());
+        if(deviceRepair == null) throw new RuntimeException("璁惧鎶ヤ慨涓嶅瓨鍦�");
+        if(approveProcess.getApproveStatus().equals(2)){
+            // 鍚屾剰
+            deviceRepair.setStatus(1);
+        }else if(approveProcess.getApproveStatus().equals(3)){
+            // 鎷掔粷
+            deviceRepair.setStatus(2);
+        }
+        deviceRepairMapper.updateById(deviceRepair);
         // 缁戝畾闄勪欢
         if(!CollectionUtils.isEmpty(approveNode.getTempFileIds()) && approveNode.getApproveNodeStatus() == 1){
             tempFileService.migrateTempFilesToFormal(approveNode.getId(), approveNode.getTempFileIds(), FileNameType.ApproveNode.getValue());
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
index 58e188c..404d594 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -74,16 +74,14 @@
         if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("瀹℃牳鐢ㄦ埛涓嶅瓨鍦�");
         if(sysDept == null) throw new RuntimeException("閮ㄩ棬涓嶅瓨鍦�");
         if(sysUser == null) throw new RuntimeException("鐢宠浜轰笉瀛樺湪");
-//        String today = LocalDate.now().format(DATE_FORMAT);
-        String approve_process = OrderUtils.countTodayByCreateTime(approveProcessMapper, "");
-//        Long approveId = dailyRedisCounter.incrementAndGetByDb();
-//        String formattedCount = String.format("%03d", approveId);
+        String today = LocalDate.now().format(DATE_FORMAT);
+        Long approveId = dailyRedisCounter.incrementAndGetByDb();
+        String formattedCount = String.format("%03d", approveId);
         //娴佺▼ ID
-//        String approveID = today + formattedCount;
+        String approveID = today + formattedCount;
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
         ApproveProcess approveProcess = new ApproveProcess();
-        BeanUtils.copyProperties(approveProcessVO, approveProcess);
-        approveProcess.setApproveId(approve_process);
+        approveProcess.setApproveId(approveID);
         approveProcess.setApproveUser(approveProcessVO.getApproveUser());
         approveProcess.setApproveUserName(sysUser.getNickName());
         approveProcess.setApproveDeptId(approveProcessVO.getApproveDeptId());
@@ -91,6 +89,8 @@
         approveProcess.setApproveUserNames(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.joining(",")));
         approveProcess.setApproveTime(StringUtils.isEmpty(approveProcessVO.getApproveTime()) ? null : dateFormat.parse(approveProcessVO.getApproveTime()));
         approveProcess.setApproveReason(approveProcessVO.getApproveReason());
+        approveProcess.setDeviceRepairId(approveProcessVO.getDeviceRepairId());
+        approveProcess.setMaintenancePrice(approveProcessVO.getMaintenancePrice());
         approveProcess.setApproveOverTime(null);
         approveProcess.setApproveStatus(0);
         approveProcess.setApproveDelete(0);
@@ -113,7 +113,7 @@
         }
         save(approveProcess);
         //鍒濆鍖栧鎵硅妭鐐�
-        approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(),approve_process,approveProcessVO.getApproveDeptId());
+        approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(),approveID,approveProcessVO.getApproveDeptId());
         // 闄勪欢缁戝畾
         tempFileService.migrateTempFilesToFormal(approveProcess.getId(), approveProcessVO.getTempFileIds(), FileNameType.ApproveProcess.getValue());
     }
diff --git a/src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java b/src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
index e9fb7f2..bf8edae 100644
--- a/src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
+++ b/src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
@@ -14,24 +14,37 @@
 
 @Data
 public class ApproveProcessVO {
-
+    /**
+     * 涓存椂鏂囦欢id鍒楄〃
+     */
     private List<String> tempFileIds;
-
+    /**
+     * 瀹℃壒娴佺▼id
+     */
     private Long id;
 
-
+    private String approveId;
+    /**
+     * 瀹℃壒閮ㄩ棬id
+     */
     private Long approveDeptId;
-
-    private String approveDeptName;
-
+    /**
+     * 瀹℃壒鏃堕棿
+     */
     private String approveTime;
-
+    /**
+     * 鐢宠浜篿d
+     */
     // 鐢宠浜�
     private Long approveUser;
-
+    /**
+     * 瀹℃壒浜篿d鍒楄〃
+     */
     // 瀹℃壒浜�
     private String approveUserIds;
-
+    /**
+     * 瀹℃壒鐞嗙敱
+     */
     private String approveReason;
 
     @Excel(name = "寮�濮嬫椂闂�", dateFormat = "yyyy-MM-dd",width = 30)
@@ -54,4 +67,12 @@
      * 瀹℃壒绫诲瀷
      */
     private Integer approveType;
+     /**
+     * 璁惧鎶ヤ慨id
+     */
+    private Long deviceRepairId;
+     /**
+     * 鎶ヤ慨閲戦
+     */
+    private BigDecimal maintenancePrice;
 }
diff --git a/src/main/java/com/ruoyi/basic/controller/SupplierManageFileController.java b/src/main/java/com/ruoyi/basic/controller/SupplierManageFileController.java
new file mode 100644
index 0000000..ff54830
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/controller/SupplierManageFileController.java
@@ -0,0 +1,63 @@
+package com.ruoyi.basic.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.pojo.SupplierManageFile;
+import com.ruoyi.basic.service.SupplierManageFileService;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 渚涘簲鍟嗛檮浠�
+ */
+@RestController
+@RequestMapping("/basic/supplierManageFile")
+public class SupplierManageFileController {
+
+
+    @Resource
+    private SupplierManageFileService supplierManageFileService;
+
+
+    /**
+     * 鏂板
+     * @param supplierManageFile
+     * @return
+     */
+    @PostMapping("/add")
+    public AjaxResult add(@RequestBody SupplierManageFile supplierManageFile) {
+        return AjaxResult.success(supplierManageFileService.save(supplierManageFile));
+    }
+
+    /**
+     * 鍒犻櫎
+     * @param ids
+     * @return
+     */
+    @DeleteMapping("/del")
+    public AjaxResult delSupplierManageFile(@RequestBody List<Integer> ids) {
+        if(CollectionUtils.isEmpty(ids)){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        //鍒犻櫎妫�楠岄檮浠�
+        return AjaxResult.success(supplierManageFileService.removeBatchByIds(ids));
+    }
+
+    /**
+     *鍒嗛〉鏌ヨ
+     * @param page
+     * @param supplierManageFile
+     * @return
+     */
+    @GetMapping("/listPage")
+    public AjaxResult supplierManageFileListPage(Page page, SupplierManageFile supplierManageFile) {
+        return AjaxResult.success(supplierManageFileService.supplierManageFileListPage(page, supplierManageFile));
+    }
+
+
+
+
+}
diff --git a/src/main/java/com/ruoyi/basic/mapper/SupplierManageFileMapper.java b/src/main/java/com/ruoyi/basic/mapper/SupplierManageFileMapper.java
new file mode 100644
index 0000000..a3acd20
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/SupplierManageFileMapper.java
@@ -0,0 +1,15 @@
+package com.ruoyi.basic.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.basic.pojo.SupplierManageFile;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface SupplierManageFileMapper extends BaseMapper<SupplierManageFile> {
+
+
+    IPage<SupplierManageFile> supplierManageFileListPage(Page page, @Param("supplierManageFile") SupplierManageFile supplierManageFile);
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/Customer.java b/src/main/java/com/ruoyi/basic/pojo/Customer.java
index d68b918..511e691 100644
--- a/src/main/java/com/ruoyi/basic/pojo/Customer.java
+++ b/src/main/java/com/ruoyi/basic/pojo/Customer.java
@@ -31,6 +31,10 @@
      */
     @Excel(name = "瀹㈡埛鍚嶇О")
     private String customerName;
+    /** 瀹㈡埛鍒嗙被锛氶浂鍞鎴凤紝杩涢攢鍟嗗鎴� */
+
+    @Excel(name = "瀹㈡埛鍒嗙被")
+    private String customerType;
 
     /**
      * 绾崇◣浜鸿瘑鍒彿
diff --git a/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java b/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
index 142a6f2..a18a47b 100644
--- a/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
+++ b/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
@@ -56,6 +56,9 @@
     @JsonFormat(pattern = "yyyy-MM-dd")
 //    @Excel(name = "缁存姢鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd")
     private LocalDate maintainTime;
+    @Excel(name = "鏄惁鐧藉悕鍗�")
+    @ApiModelProperty(value = "鏄惁鐧藉悕鍗曪紙0鏄� 1鍚︼級")
+    private Integer isWhite;
 
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
     @TableField(fill = FieldFill.INSERT)
diff --git a/src/main/java/com/ruoyi/basic/pojo/SupplierManageFile.java b/src/main/java/com/ruoyi/basic/pojo/SupplierManageFile.java
new file mode 100644
index 0000000..31914fa
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/SupplierManageFile.java
@@ -0,0 +1,60 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 渚涘簲鍟嗙鐞�--闄勪欢
+ * supplier_manage_file
+ */
+@TableName(value = "supplier_manage_file")
+@Data
+public class SupplierManageFile implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 搴忓彿
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "鏂囦欢鍚嶇О")
+    private String name;
+
+    @ApiModelProperty(value = "鏂囦欢璺緞")
+    private String url;
+
+    @ApiModelProperty(value = "鏂囦欢澶у皬")
+    private int fileSize;
+
+    @ApiModelProperty(value = "渚涘簲鍟咺D")
+    @NotBlank(message = "渚涘簲鍟唅d涓嶈兘涓虹┖!")
+    private Long supplierId;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty(value = "淇敼鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+
+}
diff --git a/src/main/java/com/ruoyi/basic/service/SupplierManageFileService.java b/src/main/java/com/ruoyi/basic/service/SupplierManageFileService.java
new file mode 100644
index 0000000..2cea459
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/SupplierManageFileService.java
@@ -0,0 +1,12 @@
+package com.ruoyi.basic.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.basic.pojo.SupplierManageFile;
+
+public interface SupplierManageFileService extends IService<SupplierManageFile> {
+
+
+    IPage<SupplierManageFile> supplierManageFileListPage(Page page, SupplierManageFile supplierManageFile);
+}
diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
index 899e21f..f24a2d2 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -74,9 +74,13 @@
         // 2. 鏋勫缓鏌ヨ鏉′欢锛堝寮虹┖鍊煎畨鍏級
         LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
         String customerName = customer.getCustomerName();
+        String customerType = customer.getCustomerType();
         if (StringUtils.isNotBlank(customerName)) {
             queryWrapper.like(Customer::getCustomerName, customerName);
         }
+        if (StringUtils.isNotBlank(customerType)) {
+            queryWrapper.like(Customer::getCustomerType, customerType);
+        }
 
         // 3. 鎵ц鍒嗛〉鏌ヨ锛堜繚鐣欏垎椤靛厓鏁版嵁锛�
         IPage<Customer> customerPage = customerMapper.selectPage(page, queryWrapper);
diff --git a/src/main/java/com/ruoyi/basic/service/impl/SupplierManageFileServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/SupplierManageFileServiceImpl.java
new file mode 100644
index 0000000..93fe71d
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/impl/SupplierManageFileServiceImpl.java
@@ -0,0 +1,23 @@
+package com.ruoyi.basic.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.basic.mapper.SupplierManageFileMapper;
+import com.ruoyi.basic.pojo.SupplierManageFile;
+import com.ruoyi.basic.service.SupplierManageFileService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@AllArgsConstructor
+@Service
+public class SupplierManageFileServiceImpl extends ServiceImpl<SupplierManageFileMapper, SupplierManageFile> implements SupplierManageFileService {
+
+    private SupplierManageFileMapper supplierManageFileMapper;
+
+    @Override
+    public IPage<SupplierManageFile> supplierManageFileListPage(Page page, SupplierManageFile supplierManageFile) {
+        return supplierManageFileMapper.supplierManageFileListPage(page, supplierManageFile);
+    }
+}
diff --git a/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java b/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
index f00595f..2907826 100644
--- a/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
+++ b/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
@@ -84,7 +84,14 @@
     public void export(HttpServletResponse response, Long[] ids) {
          deviceLedgerService.export(response, ids);
     }
-
+    /**
+     *
+     */
+    @GetMapping("/report/forms")
+    @ApiOperation("鏌ヨ璁惧鍙拌处鍥捐〃鏁版嵁")
+    public AjaxResult report() {
+        return AjaxResult.success(deviceLedgerService.report());
+    }
     @PostMapping("import")
     @ApiModelProperty("瀵煎叆璁惧鍙拌处")
     public AjaxResult importData(MultipartFile file) throws IOException {
diff --git a/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java b/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
index 4606c83..130e5df 100644
--- a/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
+++ b/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
@@ -1,21 +1,33 @@
 package com.ruoyi.device.controller;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.approve.pojo.ApproveProcess;
+import com.ruoyi.approve.service.IApproveProcessService;
+import com.ruoyi.approve.vo.ApproveProcessVO;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.device.dto.DeviceRepairDto;
 import com.ruoyi.device.pojo.DeviceLedger;
 import com.ruoyi.device.pojo.DeviceRepair;
 import com.ruoyi.device.service.IDeviceLedgerService;
 import com.ruoyi.device.service.IDeviceRepairService;
+import com.ruoyi.framework.security.LoginUser;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.project.system.domain.SysDept;
+import com.ruoyi.project.system.domain.SysUser;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiModelProperty;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Arrays;
+import java.util.List;
 
 @Api(tags = "璁惧鎶ヤ慨绠$悊")
 @RequestMapping("/device/repair")
@@ -27,6 +39,8 @@
 
     @Autowired
     private IDeviceLedgerService deviceLedgerService;
+    @Autowired
+    private IApproveProcessService approveProcessService;
 
     @ApiModelProperty("璁惧鎶ヤ慨鍒楄〃")
     @GetMapping("/page")
@@ -35,9 +49,40 @@
     }
 
     @PostMapping()
+    @Transactional(rollbackFor = Exception.class)
     @ApiModelProperty("娣诲姞璁惧鎶ヤ慨")
-    public AjaxResult add( @RequestBody DeviceRepair deviceRepair) {
-        return deviceRepairService.saveDeviceRepair(deviceRepair);
+    public AjaxResult add( @RequestBody DeviceRepair deviceRepair) throws Exception {
+        deviceRepairService.saveDeviceRepair(deviceRepair);
+        ApproveProcessVO approveProcessVO = new ApproveProcessVO();
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        SysUser user = loginUser.getUser();
+        // 鑾峰彇褰撳墠鐧诲綍鍏徃
+        Long tenantId = loginUser.getTenantId();
+        if(null != tenantId){
+            LambdaQueryWrapper<DeviceRepair> QueryWrapper = new LambdaQueryWrapper<>();
+            QueryWrapper.eq(DeviceRepair::getDeviceLedgerId,deviceRepair.getDeviceLedgerId())
+                    .eq(DeviceRepair::getRemark,deviceRepair.getRemark())
+                    .eq(DeviceRepair::getDeviceName,deviceRepair.getDeviceName())
+                    .eq(DeviceRepair::getApproverId,deviceRepair.getApproverId())
+                    .eq(DeviceRepair::getRepairTime,deviceRepair.getRepairTime());
+            DeviceRepair one = deviceRepairService.getOne(QueryWrapper);
+            if(ObjectUtils.isEmpty(one)){
+                return AjaxResult.error("璁惧鎶ヤ慨涓嶅瓨鍦�");
+            }
+            //鑾峰彇褰撳墠鐧诲綍閮ㄩ棬id
+            approveProcessVO.setApproveDeptId(tenantId);
+            //鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛id
+            approveProcessVO.setApproveUser(loginUser.getUserId());
+            //鑾峰彇褰撳墠鏃堕棿
+            approveProcessVO.setApproveTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approveProcessVO.setApproveType(4);
+            approveProcessVO.setApproveUserIds(deviceRepair.getApproverId().toString());
+            approveProcessVO.setApproveReason(deviceRepair.getRemark());
+            approveProcessVO.setDeviceRepairId(one.getId());
+            approveProcessVO.setMaintenancePrice(deviceRepair.getMaintenancePrice());
+            approveProcessService.addApprove(approveProcessVO);
+        }
+        return AjaxResult.success();
     }
 
     @ApiModelProperty("鏍规嵁id鏌ヨ璁惧鎶ヤ慨")
@@ -62,6 +107,17 @@
     @DeleteMapping("/{ids}")
     @ApiModelProperty("鍒犻櫎璁惧鎶ヤ慨")
     public AjaxResult delete(@PathVariable("ids") Long[] ids) {
+        LambdaQueryWrapper<ApproveProcess> QueryWrapper = new LambdaQueryWrapper<>();
+        QueryWrapper.in(ApproveProcess::getDeviceRepairId,ids);
+        List<ApproveProcess> approveProcessList = approveProcessService.list(QueryWrapper);
+        if(!approveProcessList.isEmpty()){
+            approveProcessList.forEach(approveProcess -> {
+                if (approveProcess.getApproveStatus() != 0){
+                    //鎶涘嚭寮傚父
+                    throw new RuntimeException("鏈夋鍦ㄥ鐞嗕腑鐨勫鎵规祦绋嬶紝涓嶈兘鍒犻櫎");
+                }
+            });
+        }
         boolean b = deviceRepairService.removeBatchByIds(Arrays.asList(ids));
         if (!b) {
             return AjaxResult.error("鍒犻櫎澶辫触");
diff --git a/src/main/java/com/ruoyi/device/dto/DeviceAssetInfoDto.java b/src/main/java/com/ruoyi/device/dto/DeviceAssetInfoDto.java
new file mode 100644
index 0000000..d451e2d
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/dto/DeviceAssetInfoDto.java
@@ -0,0 +1,28 @@
+package com.ruoyi.device.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 璁惧璧勪骇淇℃伅Dto-璧勪骇鎶ヨ〃
+ */
+@Data
+public class DeviceAssetInfoDto {
+    /**
+     * 璁惧鎬绘暟
+     */
+    private Integer totalEquipment;
+    /**
+     * 璧勪骇鍘熷��
+     */
+    private BigDecimal totalOriginalValue;
+    /**
+     * 绱鎶樻棫
+     */
+    private BigDecimal totalDepreciation;
+    /**
+     * 鍑�鍊�
+     */
+    private BigDecimal totalNetValue;
+}
diff --git a/src/main/java/com/ruoyi/device/dto/DeviceRepairDto.java b/src/main/java/com/ruoyi/device/dto/DeviceRepairDto.java
index 92cfe8c..45cf329 100644
--- a/src/main/java/com/ruoyi/device/dto/DeviceRepairDto.java
+++ b/src/main/java/com/ruoyi/device/dto/DeviceRepairDto.java
@@ -3,6 +3,7 @@
 
 import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -68,7 +69,7 @@
     @ApiModelProperty("绉熸埛id")
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
-
-
+    @ApiModelProperty("缁翠慨浠锋牸")
+    private String maintenancePrice;
 }
 
diff --git a/src/main/java/com/ruoyi/device/pojo/DeviceRepair.java b/src/main/java/com/ruoyi/device/pojo/DeviceRepair.java
index 7ecb5f5..8b4dbbc 100644
--- a/src/main/java/com/ruoyi/device/pojo/DeviceRepair.java
+++ b/src/main/java/com/ruoyi/device/pojo/DeviceRepair.java
@@ -4,10 +4,9 @@
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.Api;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
-import nonapi.io.github.classgraph.json.Id;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
@@ -24,9 +23,9 @@
 
     @ApiModelProperty("璁惧鍙拌处id")
     private Long deviceLedgerId;
-
+    @ApiModelProperty("璁惧鍚嶇О")
     private String deviceName;
-
+    @ApiModelProperty("璁惧鍨嬪彿")
     private String deviceModel;
 
     @ApiModelProperty("鎶ヤ慨鏃堕棿")
@@ -49,7 +48,7 @@
     @ApiModelProperty("缁翠慨缁撴灉")
     private String maintenanceResult;
 
-    @ApiModelProperty("鐘舵�� 0 寰呯淮淇� 1瀹岀粨 2 澶辫触")
+    @ApiModelProperty("鐘舵��:0瀹℃牳涓�,1瀹℃牳閫氳繃,2瀹℃牳澶辫触,3缁翠慨涓�,4缁翠慨閫氳繃,5缁翠慨澶辫触")
     private Integer status;
 
     @ApiModelProperty("鍒涘缓鏃堕棿")
@@ -75,6 +74,8 @@
     @ApiModelProperty("绉熸埛id")
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
-
-
+    @ApiModelProperty("缁翠慨浠锋牸")
+    private BigDecimal maintenancePrice;
+    @ApiModelProperty("瀹℃壒浜篿d")
+    private Integer approverId;
 }
diff --git a/src/main/java/com/ruoyi/device/service/IDeviceLedgerService.java b/src/main/java/com/ruoyi/device/service/IDeviceLedgerService.java
index 22ec2d2..d800b14 100644
--- a/src/main/java/com/ruoyi/device/service/IDeviceLedgerService.java
+++ b/src/main/java/com/ruoyi/device/service/IDeviceLedgerService.java
@@ -3,6 +3,7 @@
 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.device.dto.DeviceAssetInfoDto;
 import com.ruoyi.device.dto.DeviceLedgerDto;
 import com.ruoyi.device.pojo.DeviceLedger;
 import com.ruoyi.framework.web.domain.AjaxResult;
@@ -22,4 +23,5 @@
     void export(HttpServletResponse response, Long[] ids);
 
     Boolean importData(MultipartFile file) throws IOException;
+    DeviceAssetInfoDto report();
 }
diff --git a/src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java b/src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java
index 58569db..444993c 100644
--- a/src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java
@@ -8,6 +8,7 @@
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.device.dto.DeviceAssetInfoDto;
 import com.ruoyi.device.dto.DeviceLedgerDto;
 import com.ruoyi.device.execl.DeviceLedgerExeclDto;
 import com.ruoyi.device.mapper.DeviceLedgerMapper;
@@ -24,6 +25,7 @@
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -119,4 +121,14 @@
 
         return true;
     }
+    @Override
+    public DeviceAssetInfoDto report() {
+        List<DeviceLedger> list = deviceLedgerMapper.selectList(null);
+        DeviceAssetInfoDto deviceAssetInfoDto = new DeviceAssetInfoDto();
+        deviceAssetInfoDto.setTotalEquipment(list.stream().map(DeviceLedger::getNumber).reduce(BigDecimal.ZERO, BigDecimal::add).intValue());
+        deviceAssetInfoDto.setTotalOriginalValue(list.stream().map(DeviceLedger::getTaxIncludingPriceTotal).reduce(BigDecimal.ZERO, BigDecimal::add));
+        deviceAssetInfoDto.setTotalNetValue(list.stream().map(DeviceLedger::getUnTaxIncludingPriceTotal).reduce(BigDecimal.ZERO, BigDecimal::add));
+        deviceAssetInfoDto.setTotalDepreciation(deviceAssetInfoDto.getTotalOriginalValue().subtract(deviceAssetInfoDto.getTotalNetValue()));
+        return deviceAssetInfoDto;
+    }
 }
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 cbe815a..5630e84 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -425,25 +425,29 @@
 //                .ge(SalesLedger::getEntryDate, startDate)
 //                .lt(SalesLedger::getEntryDate, endDate)
         );
-        BigDecimal receivableMoney = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+//        BigDecimal receivableMoney = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal receivableMoney = sumAmount(salesLedgers, SalesLedger::getContractAmount);
         // 搴斾粯
         List<PurchaseLedger> procurementRecords = purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>()
 //                .ge(PurchaseLedger::getEntryDate, startDate)
 //                .lt(PurchaseLedger::getEntryDate, endDate)
         );
-        BigDecimal payableMoney = procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+//        BigDecimal payableMoney = procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal payableMoney = sumAmount(procurementRecords, PurchaseLedger::getContractAmount);
         // 棰勬敹
         List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
 //                .ge(ReceiptPayment::getReceiptPaymentDate, startDate)
 //                .lt(ReceiptPayment::getReceiptPaymentDate, endDate)
         );
-        BigDecimal advanceMoney = receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+//        BigDecimal advanceMoney = receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal advanceMoney = sumAmount(receiptPayments, ReceiptPayment::getReceiptPaymentAmount);
         // 棰勪粯
         List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new LambdaQueryWrapper<PaymentRegistration>()
 //                .ge(PaymentRegistration::getPaymentDate, startDate)
 //                .lt(PaymentRegistration::getPaymentDate, endDate)
         );
-        BigDecimal prepayMoney = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+//        BigDecimal prepayMoney = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal prepayMoney = sumAmount(paymentRegistrations, PaymentRegistration::getCurrentPaymentAmount);
         StatisticsReceivablePayableDto statisticsReceivablePayableDto = new StatisticsReceivablePayableDto();
         statisticsReceivablePayableDto.setPayableMoney(payableMoney.subtract(prepayMoney));
         statisticsReceivablePayableDto.setReceivableMoney(receivableMoney.subtract(advanceMoney));
@@ -452,7 +456,13 @@
 
         return statisticsReceivablePayableDto;
     }
-
+    public static <T> BigDecimal sumAmount(List<T> list, java.util.function.Function<T, BigDecimal> amountExtractor) {
+        return list.stream()
+                // 鎻愬彇閲戦鏃讹紝灏唍ull鏇挎崲涓築igDecimal.ZERO
+                .map(item -> Optional.ofNullable(amountExtractor.apply(item)).orElse(BigDecimal.ZERO))
+                // 绱姞锛屽垵濮嬪�间负0锛岄伩鍏嶇┖娴侀棶棰�
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+    }
     @Autowired
     private DeviceRepairMapper deviceRepairMapper;
 
diff --git a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementExceptionRecordController.java b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementExceptionRecordController.java
new file mode 100644
index 0000000..d9bc6fc
--- /dev/null
+++ b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementExceptionRecordController.java
@@ -0,0 +1,46 @@
+package com.ruoyi.procurementrecord.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.procurementrecord.dto.*;
+import com.ruoyi.procurementrecord.mapper.ProcurementExceptionRecordMapper;
+import com.ruoyi.procurementrecord.pojo.ProcurementExceptionRecord;
+import com.ruoyi.procurementrecord.service.ProcurementRecordService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * @author :yys
+ * @date : 2025/7/7 14:32
+ */
+@RestController
+@Api(tags = "閲囪喘寮傚父璁板綍")
+@RequestMapping("/procurementExceptionRecord")
+public class ProcurementExceptionRecordController extends BaseController {
+
+
+    @Autowired
+    private ProcurementExceptionRecordMapper procurementExceptionRecordMapper;
+
+    @PostMapping("/add")
+    @Transactional
+    public AjaxResult add(@RequestBody ProcurementExceptionRecord procurementExceptionRecord) {
+        return AjaxResult.success(procurementExceptionRecordMapper.insert(procurementExceptionRecord));
+    }
+
+    @PostMapping("/update")
+    @Transactional
+    public AjaxResult updatePro(@RequestBody ProcurementExceptionRecord procurementExceptionRecord) {
+        return AjaxResult.success(procurementExceptionRecordMapper.updateById(procurementExceptionRecord));
+    }
+}
diff --git a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
index 7ea2430..1795c15 100644
--- a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
+++ b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -119,7 +119,11 @@
         IPage<ProcurementPageDto> result = procurementRecordService.listPage(page, procurementDto);
         return AjaxResult.success(result);
     }
-
+    @GetMapping("/listReport")
+    @ApiOperation(value = "鏌ヨ搴撳瓨鍥捐〃鏁版嵁")
+    public AjaxResult listReport() {
+        return AjaxResult.success(procurementRecordService.getReportList());
+    }
     @GetMapping("/listPageByProduction")
     @Log(title = "鐢熶骇鍏ュ簱-鍏ュ簱绠$悊-鍏ュ簱鏌ヨ", businessType = BusinessType.OTHER)
     @ApiOperation(value = "鍏ュ簱鏌ヨ")
diff --git a/src/main/java/com/ruoyi/procurementrecord/dto/InventoryInformationDto.java b/src/main/java/com/ruoyi/procurementrecord/dto/InventoryInformationDto.java
new file mode 100644
index 0000000..2396b29
--- /dev/null
+++ b/src/main/java/com/ruoyi/procurementrecord/dto/InventoryInformationDto.java
@@ -0,0 +1,28 @@
+package com.ruoyi.procurementrecord.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 瀛樿揣鏍哥畻淇℃伅Dto-璧勪骇鎶ヨ〃
+ */
+@Data
+public class InventoryInformationDto {
+    /**
+     * 鎬诲簱瀛樻暟閲�
+     */
+    private Integer totalInventoryCount;
+    /**
+     * 鎬诲簱瀛橀噾棰�
+     */
+    private BigDecimal totalInventoryValue;
+    /**
+     * 搴撳瓨鍙樺姩鏁伴噺
+     */
+    private Integer inventoryChangeCount;
+    /**
+     * 搴撳瓨鍙樺姩閲戦
+     */
+    private BigDecimal inventoryChangeValue;
+}
diff --git a/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java b/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java
index d3f35a1..98ea4eb 100644
--- a/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java
+++ b/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java
@@ -21,5 +21,6 @@
     private Integer type;
 
     private String typeName;
+    private Integer purchaseLedgerId;
 
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementExceptionRecordMapper.java b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementExceptionRecordMapper.java
new file mode 100644
index 0000000..31dd4dc
--- /dev/null
+++ b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementExceptionRecordMapper.java
@@ -0,0 +1,9 @@
+package com.ruoyi.procurementrecord.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.procurementrecord.pojo.ProcurementExceptionRecord;
+
+
+public interface ProcurementExceptionRecordMapper extends BaseMapper<ProcurementExceptionRecord> {
+
+}
diff --git a/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementExceptionRecord.java b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementExceptionRecord.java
new file mode 100644
index 0000000..d9e7cc7
--- /dev/null
+++ b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementExceptionRecord.java
@@ -0,0 +1,54 @@
+package com.ruoyi.procurementrecord.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@TableName("procurement_exception_record")
+@Data
+@Builder
+public class ProcurementExceptionRecord {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 閲囪喘鍙拌处id
+     */
+    private Integer purchaseLedgerId;
+    /**
+     * 寮傚父鎻忚堪
+     */
+    private String exceptionReason;
+
+    /**
+     * 寮傚父鏁伴噺
+     */
+    private BigDecimal exceptionNum;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 淇敼鑰�
+     */
+    private Long updateUser;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 绉熸埛ID
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
index 1b699ef..8e68c64 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
@@ -57,4 +57,5 @@
     int updateManagementByCustom(ProcurementManagementUpdateDto procurementDto);
 
     BigDecimal getProcurementAmount(Long salesProductId);
+    InventoryInformationDto getReportList();
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java b/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
index fdd9c7c..3820823 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -416,6 +416,68 @@
     }
 
     @Override
+    public InventoryInformationDto getReportList() {
+        InventoryInformationDto inventoryInformationDto = new InventoryInformationDto();
+        IPage<ProcurementPageDto> procurementPageDtoIPage = this.listPage(new Page<>(1, -1), new ProcurementPageDto());
+        if(CollectionUtils.isEmpty(procurementPageDtoIPage.getRecords())){
+            return inventoryInformationDto;
+        }
+        // 璁$畻鎬诲簱瀛樻暟閲�
+        inventoryInformationDto.setTotalInventoryCount(procurementPageDtoIPage.getRecords().stream()
+                .map(ProcurementPageDto::getInboundNum0)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .intValue());
+        // 璁$畻鎬诲簱瀛橀噾棰�-ProcurementPageDto閲屾瘡涓璞$殑inboundNum0鍊煎拰taxInclusiveUnitPrice鐨勪箻绉紝涔嬪悗鐩稿姞寰楀埌鎬诲簱瀛橀噾棰�
+        BigDecimal totalInventoryValue = procurementPageDtoIPage.getRecords().stream()
+                // 杩囨护绌哄璞★紝閬垮厤NPE
+                .filter(Objects::nonNull)
+                // 澶勭悊姣忎釜瀵硅薄鐨勭┖鍊硷細null杞负0
+                .map(dto -> {
+                    // 鍏ュ簱鏁伴噺锛歯ull 鈫� 0
+                    BigDecimal inboundNum0 = Optional.ofNullable(dto.getInboundNum0()).orElse(BigDecimal.ZERO);
+                    // 鍚◣鍗曚环锛歯ull 鈫� 0
+                    BigDecimal taxInclusiveUnitPrice = Optional.ofNullable(dto.getTaxInclusiveUnitPrice()).orElse(BigDecimal.ZERO);
+                    // 璁$畻鍗曚釜瀵硅薄鐨勫簱瀛橀噾棰濓細鏁伴噺 脳 鍚◣鍗曚环
+                    return inboundNum0.multiply(taxInclusiveUnitPrice);
+                })
+                // 鎵�鏈夊崟涓噾棰濇眰鍜岋紝鍒濆鍊间负0
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        // 璁剧疆鎬诲簱瀛橀噾棰�
+        inventoryInformationDto.setTotalInventoryValue(totalInventoryValue);
+        // 璁$畻搴撳瓨鍙樺姩鏁伴噺-ProcurementPageDto閲屾瘡涓璞$殑inboundNum鍊煎拰inboundNum0鍊肩殑宸�硷紝涔嬪悗鐩稿姞寰楀埌搴撳瓨鍙樺姩鏁伴噺
+        inventoryInformationDto.setInventoryChangeCount(procurementPageDtoIPage.getRecords().stream()
+                // 杩囨护绌哄璞★紝閬垮厤NPE
+                .filter(Objects::nonNull)
+                // 澶勭悊姣忎釜瀵硅薄鐨勭┖鍊硷細null杞负0
+                .map(dto -> {
+                    // 鍏ュ簱鏁伴噺锛歯ull 鈫� 0
+                    BigDecimal inboundNum = Optional.ofNullable(dto.getInboundNum()).orElse(BigDecimal.ZERO);
+                    // 寰呭嚭搴撴暟閲忥細null 鈫� 0
+                    BigDecimal inboundNum0 = Optional.ofNullable(dto.getInboundNum0()).orElse(BigDecimal.ZERO);
+                    // 璁$畻鍗曚釜瀵硅薄鐨勫簱瀛樺彉鍔ㄦ暟閲忥細鏁伴噺 - 寰呭嚭搴撴暟閲�
+                    return inboundNum.subtract(inboundNum0);
+                })
+                // 鎵�鏈夊崟涓彉鍔ㄦ暟閲忔眰鍜岋紝鍒濆鍊间负0
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .intValue());
+        // 璁$畻搴撳瓨鍙樺姩閲戦ProcurementPageDto閲屾瘡涓璞$殑taxInclusiveTotalPrice鍊肩殑鍜�
+        BigDecimal inventoryChangeValue = procurementPageDtoIPage.getRecords().stream()
+                // 杩囨护绌哄璞★紝閬垮厤NPE
+                .filter(Objects::nonNull)
+                // 澶勭悊姣忎釜瀵硅薄鐨勭┖鍊硷細null杞负0
+                .map(dto -> {
+                    // 鍚◣鎬讳环锛歯ull 鈫� 0
+                    BigDecimal taxInclusiveTotalPrice = Optional.ofNullable(dto.getTaxInclusiveTotalPrice()).orElse(BigDecimal.ZERO);
+                    // 璁$畻鍗曚釜瀵硅薄鐨勫叆搴撳簱瀛橀噾棰濓細鍚◣鎬讳环
+                    return taxInclusiveTotalPrice;
+                })
+                // 鎵�鏈夊崟涓彉鍔ㄩ噾棰濇眰鍜岋紝鍒濆鍊间负0
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        // 璁剧疆搴撳瓨鍙樺姩閲戦
+        inventoryInformationDto.setInventoryChangeValue(inventoryChangeValue.subtract(totalInventoryValue));
+        return inventoryInformationDto;
+    }
+    @Override
     public IPage<ProcurementPageDto> listPageByProduction(Page page, ProcurementPageDto procurementDto) {
         IPage<ProcurementPageDto> procurementPageDtoIPage = procurementRecordMapper.listPageByProduction(page, procurementDto);
         List<ProcurementPageDto> procurementPageDtos = procurementPageDtoIPage.getRecords();
diff --git a/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
index 66ace47..5a502d7 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
@@ -1,23 +1,39 @@
 package com.ruoyi.production.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.production.dto.ProcessRouteItemDto;
 import com.ruoyi.production.dto.ProductProcessRouteItemDto;
-import com.ruoyi.production.pojo.ProcessRouteItem;
+import com.ruoyi.production.mapper.ProductWorkOrderMapper;
 import com.ruoyi.production.pojo.ProductProcessRouteItem;
+import com.ruoyi.production.pojo.ProductWorkOrder;
 import com.ruoyi.production.service.ProductProcessRouteItemService;
+import com.ruoyi.production.service.ProductWorkOrderService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.AllArgsConstructor;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
-@RequestMapping("productProcessRoute")
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RequestMapping("/productProcessRoute")
 @RestController
+@AllArgsConstructor
 @Api(tags = "鐢熶骇宸ヨ壓璺嚎")
 public class ProductProcessRouteItemController {
-    @Autowired
+
     private ProductProcessRouteItemService productProcessRouteItemService;
+
+    private ProductWorkOrderService productWorkOrderService;
+
+    private ProductWorkOrderMapper productWorkOrderMapper;
 
     @GetMapping("list")
     @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓椤圭洰")
@@ -25,10 +41,89 @@
         return R.ok(productProcessRouteItemService.listItem(orderId));
     }
 
-    @PostMapping ()
-    @ApiOperation("鏂板淇敼")
+    @PostMapping("/updateRouteItem")
+    @ApiOperation("鎵归噺鏂板淇敼")
+    @Transactional(rollbackFor = Exception.class)
     public R addOrUpdate(@RequestBody ProductProcessRouteItemDto processRouteItemDto) {
-        productProcessRouteItemService.remove(new QueryWrapper<ProductProcessRouteItem>().lambda().eq(ProductProcessRouteItem::getRouteId, processRouteItemDto.getRouteId()));
-        return R.ok(productProcessRouteItemService.saveBatch(processRouteItemDto.getProcessRouteItem()));
+        List<ProductProcessRouteItem> items = processRouteItemDto.getProcessRouteItem();
+        if (CollectionUtils.isEmpty(items)) {
+            return R.ok();
+        }
+
+        Map<Boolean, List<ProductProcessRouteItem>> partitioned = items.stream()
+                .collect(Collectors.partitioningBy(
+                        item -> item.getId() != null && item.getId() > 0
+                ));
+
+        List<ProductProcessRouteItem> toUpdate = partitioned.get(true);
+        List<ProductProcessRouteItem> toInsert = partitioned.get(false);
+        // 鎵归噺澶勭悊
+        boolean result = true;
+        if (!toInsert.isEmpty()) {
+            result = productProcessRouteItemService.saveBatch(toInsert);
+            if (result) {
+                // 鐢熸垚宸ュ崟鍙�
+                String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+                // 鏌ヨ浠婃棩鏈�澶у伐鍗曞彿
+                QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+                queryWrapper.likeRight("work_order_no", datePrefix)
+                        .select("MAX(work_order_no) as maxNo");
+
+                List<Map<String, Object>> maxNoList = productWorkOrderMapper.selectMaps(queryWrapper);
+                String maxWorkOrderNo = null;
+                if (!maxNoList.isEmpty() && maxNoList.get(0) != null && maxNoList.get(0).get("maxNo") != null) {
+                    maxWorkOrderNo = maxNoList.get(0).get("maxNo").toString();
+                }
+                int startSequence = 1;
+                if (maxWorkOrderNo != null && maxWorkOrderNo.startsWith(datePrefix)) {
+                    try {
+                        String seqStr = maxWorkOrderNo.substring(datePrefix.length());
+                        startSequence = Integer.parseInt(seqStr) + 1;
+                    } catch (NumberFormatException e) {
+                        startSequence = 1;
+                    }
+                }
+                // 鎵归噺鐢熸垚宸ュ崟
+                List<ProductWorkOrder> workOrders = new ArrayList<>();
+                for (int i = 0; i < toInsert.size(); i++) {
+                    ProductProcessRouteItem item = toInsert.get(i);
+                    String workOrderNoStr = String.format("%s%03d", datePrefix, startSequence + i);
+                    ProductWorkOrder workOrder = new ProductWorkOrder();
+                    workOrder.setProductProcessRouteItemId(item.getId());
+                    workOrder.setProductOrderId(item.getRouteId());
+                    workOrder.setWorkOrderNo(workOrderNoStr);
+                    workOrder.setStatus(1);
+                    workOrders.add(workOrder);
+                }
+                result = productWorkOrderService.saveBatch(workOrders);
+            }
+        }
+        if (!toUpdate.isEmpty()) {
+            result = productProcessRouteItemService.updateBatchById(toUpdate) && result;
+        }
+        return R.ok(result);
     }
+
+    @DeleteMapping("/deleteRouteItem")
+    @ApiOperation("鍒犻櫎鐢熶骇宸ヨ壓璺嚎")
+    @Transactional(rollbackFor = Exception.class)
+    public R deleteRouteItem(@RequestBody ProductProcessRouteItemDto processRouteItemDto) {
+        if (processRouteItemDto == null || processRouteItemDto.getId() == null) {
+            return R.fail("鍙傛暟閿欒锛孖D涓嶈兘涓虹┖");
+        }
+
+        try {
+            // 鍏堝垹闄ゅ叧鑱旂殑宸ュ崟鏁版嵁
+            LambdaQueryWrapper<ProductWorkOrder> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(ProductWorkOrder::getProductProcessRouteItemId, processRouteItemDto.getId());
+            productWorkOrderMapper.delete(wrapper);
+
+            // 鍒犻櫎涓昏〃鏁版嵁
+            productProcessRouteItemService.removeById(processRouteItemDto.getId());
+            return R.ok();
+        } catch (Exception e) {
+            throw new RuntimeException("鍒犻櫎澶辫触锛�" + e.getMessage());
+        }
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductStructureController.java b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
index f2f4ef1..26594f6 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
@@ -22,7 +22,7 @@
 
 
     @ApiOperation("鏍规嵁productId鏌ヨ")
-    @GetMapping("listByproductModelId/{productModelId}")
+    @GetMapping("/listByproductModelId/{productModelId}")
     public R listByproductModelId( @PathVariable("productModelId") Long productModelId){
         return R.ok(productStructureService.listByproductModelId( productModelId));
     }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
new file mode 100644
index 0000000..f595d98
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
@@ -0,0 +1,37 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductWorkOrderDto;
+import com.ruoyi.production.service.ProductWorkOrderService;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/productWorkOrder")
+public class ProductWorkOrderController {
+
+    private ProductWorkOrderService productWorkOrderservice;
+
+
+    /**
+     * 浜у搧宸ュ崟瀹炰綋绫诲垎椤垫煡璇�
+     */
+    @ApiOperation("浜у搧宸ュ崟瀹炰綋绫诲垎椤垫煡璇�")
+    @GetMapping("/page")
+    public R page(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
+        return R.ok(productWorkOrderservice.listPage(page, productWorkOrder));
+    }
+
+    /**
+     * 浜у搧宸ュ崟鏇存柊
+     */
+    @ApiOperation("浜у搧宸ュ崟鏇存柊")
+    @PostMapping ("/updateProductWorkOrder")
+    public R updateProductWorkOrder(@RequestBody ProductWorkOrderDto productWorkOrderDto) {
+        return R.ok(productWorkOrderservice.updateProductWorkOrder(productWorkOrderDto));
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
new file mode 100644
index 0000000..b4bf7dc
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
@@ -0,0 +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.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;
+
+@RequestMapping("productionProductInput")
+@RestController
+@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 a32cd4c..948d6de 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
@@ -2,14 +2,17 @@
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductProcessRouteItemDto;
 import com.ruoyi.production.dto.ProductionProductMainDto;
-import com.ruoyi.production.pojo.ProductionProductMain;
 import com.ruoyi.production.service.ProductionProductMainService;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 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;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.List;
 
 @RequestMapping("productionProductMain")
 @RestController
@@ -19,8 +22,31 @@
     @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));
     }
+
+    /**
+     * 鎶ュ伐鏂板鏇存柊
+     * @param productionProductMainDto
+     * @return
+     */
+    @PostMapping("addProductMain")
+    public R addProductMain(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.addProductMain(productionProductMainDto));
+    }
+
+    @ApiOperation("鍒犻櫎鎶ュ伐")
+    @DeleteMapping("/delete")
+    @Transactional(rollbackFor = Exception.class)
+    public R delete(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.removeProductMain(productionProductMainDto));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
new file mode 100644
index 0000000..ca9c1e8
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
@@ -0,0 +1,27 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductionProductInputDto;
+import com.ruoyi.production.dto.ProductionProductOutputDto;
+import com.ruoyi.production.service.ProductionProductInputService;
+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;
+
+@RequestMapping("productionProductOutput")
+@RestController
+@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/dto/ProductWorkOrderDto.java b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
new file mode 100644
index 0000000..2191029
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
@@ -0,0 +1,32 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductWorkOrder;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProductWorkOrderDto extends ProductWorkOrder {
+
+    //浜у搧鍚嶇О
+    @ApiModelProperty(value = "浜у搧鍚嶇О")
+    private String productName;
+
+    //瑙勬牸
+    @ApiModelProperty(value = "瑙勬牸")
+    private String model;
+
+    //宸ュ簭
+    @ApiModelProperty(value = "宸ュ簭")
+    private String processName;
+
+    //鍗曚綅
+    @ApiModelProperty(value = "鍗曚綅")
+    private String unit;
+
+
+    //鐢熶骇璁㈠崟鍙�
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟鍙�")
+    private String productOrderNpsNo;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
new file mode 100644
index 0000000..1e6e02e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
@@ -0,0 +1,14 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductionProductInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ProductionProductInputDto extends ProductionProductInput {
+    @ApiModelProperty(value = "鎶ュ伐鍗曞彿")
+    private String productNo;
+
+    @ApiModelProperty(value = "浜у搧鍨嬪彿")
+    private String model;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
index c90bf87..f6aa5ba 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -4,6 +4,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.math.BigDecimal;
+
 @Data
 public class ProductionProductMainDto extends ProductionProductMain {
     @ApiModelProperty(value = "宸ュ崟缂栧彿")
@@ -14,4 +16,13 @@
 
     @ApiModelProperty(value = "鎶ュ伐浜哄憳鏄电О")
     private String nickName;
+
+    @ApiModelProperty(value = "鎶ュ伐鏁伴噺")
+    private BigDecimal quantity;
+
+    @ApiModelProperty(value = "鏄惁鎶ュ伐")
+    private boolean reportWork;
+
+    @ApiModelProperty(value = "鎶ュ伐id")
+    private Long productMainId;
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java
new file mode 100644
index 0000000..f98cc80
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java
@@ -0,0 +1,15 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductionProductInput;
+import com.ruoyi.production.pojo.ProductionProductOutput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ProductionProductOutputDto extends ProductionProductOutput {
+    @ApiModelProperty(value = "鎶ュ伐鍗曞彿")
+    private String productNo;
+
+    @ApiModelProperty(value = "浜у搧鍨嬪彿")
+    private String model;
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
new file mode 100644
index 0000000..1d5242e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -0,0 +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.dto.ProductWorkOrderDto;
+import com.ruoyi.production.pojo.ProductWorkOrder;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Map;
+
+@Mapper
+public interface ProductWorkOrderMapper extends BaseMapper<ProductWorkOrder> {
+
+    IPage<ProductWorkOrderDto> pageProductWorkOrder(Page<ProductWorkOrderDto> page, @Param("c") ProductWorkOrderDto productWorkOrder);
+
+    int updatePlanQuantity(Map<String, Object> params);
+
+    /**
+     * 鍥炴粴宸ュ崟璁″垝鏁伴噺锛氫粠production_product_output鍙杚uantity鍔犲洖plan_quantity
+     * @param productMainId
+     * @return
+     */
+    int rollbackPlanQuantity(@Param("productMainId") Long productMainId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
index dba437c..78e7d2a 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
@@ -1,9 +1,21 @@
 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.dto.ProductionProductInputDto;
 import com.ruoyi.production.pojo.ProductionProductInput;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 @Mapper
 public interface ProductionProductInputMapper extends BaseMapper<ProductionProductInput> {
+    IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, @Param("c") ProductionProductInputDto productionProductInputDto);
+
+    /**
+     * 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎鎶曞叆琛ㄦ暟鎹�
+     */
+    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
index dd99553..c9d1268 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -3,16 +3,20 @@
 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.dto.ProductOrderDto;
 import com.ruoyi.production.dto.ProductionProductMainDto;
 import com.ruoyi.production.pojo.ProductionProductMain;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
-import javax.annotation.ManagedBean;
 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);
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
index cdcd121..0283d42 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
@@ -1,9 +1,21 @@
 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.dto.ProductionProductOutputDto;
 import com.ruoyi.production.pojo.ProductionProductOutput;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 @Mapper
 public interface ProductionProductOutputMapper extends BaseMapper<ProductionProductOutput> {
+    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, @Param("c") ProductionProductOutputDto productionProductOutputDto);
+
+    /**
+     * 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎浜у嚭琛ㄦ暟鎹�
+     */
+    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java b/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
index 9cfd326..66cbfdd 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
@@ -1,15 +1,13 @@
 package com.ruoyi.production.pojo;
 
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.*;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.time.LocalDateTime;
 
 @Data
+@TableName("process_route_item")
 public class ProcessRouteItem {
 
     @TableId(type = IdType.AUTO)
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcess.java b/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
index 01ed986..21ca82a 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
@@ -3,12 +3,13 @@
 import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
 @TableName("product_process")
 @Data
-public class ProductProcess {
+public class ProductProcess implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java b/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
index af13c69..fb04df8 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
@@ -13,7 +13,7 @@
     @TableId(type = IdType.AUTO)
     private Long id;
 
-    @ApiModelProperty(value = "宸ヨ壓璺嚎id")
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟id(product_order_id)")
     private Long routeId;
 
     @ApiModelProperty(value = "宸ュ簭id")
@@ -32,4 +32,7 @@
     @TableField(fill = FieldFill.UPDATE)
     private LocalDateTime updateTime;
 
+    @ApiModelProperty(value ="鎷栧姩鎺掑簭")
+    private Integer dragSort;
+
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java b/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
index bffa732..f225c45 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
@@ -5,14 +5,23 @@
 import lombok.Data;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
+/**
+ * 浜у搧宸ュ崟瀹炰綋绫�
+ * 瀵瑰簲鏁版嵁搴撹〃锛歱roduct_work_order
+ */
 @Data
 @TableName("product_work_order")
 public class ProductWorkOrder implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
+    /**
+     * 涓婚敭id
+     */
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
@@ -23,16 +32,36 @@
     private Long productProcessRouteItemId;
 
     /**
+     * 鐢熶骇璁㈠崟id
+     */
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟id")
+    private Long productOrderId;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    /**
      * 宸ュ崟缂栧彿
      */
-    @ApiModelProperty(value = "鐢熶骇璁㈠崟鍙�")
+    @ApiModelProperty(value = "宸ュ崟缂栧彿")
     private String workOrderNo;
 
     /**
-     * 鐢熶骇鐘舵�� 1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜�
+     * 鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜�
      */
-    @ApiModelProperty(value = "鐢熶骇鐘舵�� 1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜�")
-    private String status;
+    @ApiModelProperty(value = "鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜�")
+    private Integer status;
 
     /**
      * 绉熸埛id
@@ -41,14 +70,52 @@
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
 
-    //鍒涘缓鏃堕棿
-    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
-    @TableField(fill = FieldFill.INSERT)
-    private LocalDateTime createTime;
+    /**
+     * 璁″垝寮�濮嬫椂闂�
+     */
+    @ApiModelProperty(value = "璁″垝寮�濮嬫椂闂�")
+    private LocalDate planStartTime;
 
-    //淇敼鏃堕棿
-    @ApiModelProperty(value = "淇敼鏃堕棿")
-    @TableField(fill = FieldFill.UPDATE)
-    private LocalDateTime updateTime;
+    /**
+     * 璁″垝缁撴潫鏃堕棿
+     */
+    @ApiModelProperty(value = "璁″垝缁撴潫鏃堕棿")
+    private LocalDate planEndTime;
 
-}
+    /**
+     * 瀹為檯寮�濮嬫椂闂�
+     */
+    @ApiModelProperty(value = "瀹為檯寮�濮嬫椂闂�")
+    private LocalDate actualStartTime;
+
+    /**
+     * 瀹為檯缁撴潫鏃堕棿
+     */
+    @ApiModelProperty(value = "瀹為檯缁撴潫鏃堕棿")
+    private LocalDate actualEndTime;
+
+    /**
+     * 鏄惁鎶ュ伐
+     */
+    @ApiModelProperty(value = "鏄惁鎶ュ伐")
+    private boolean reportWork;
+
+
+    /**
+     * 璁″垝鏁伴噺
+     */
+    @ApiModelProperty(value = "璁″垝鏁伴噺")
+    private BigDecimal planQuantity;
+
+    /**
+     * 瀹為檯鏁伴噺
+     */
+    @ApiModelProperty(value = "鏁伴噺")
+    private BigDecimal quantity;
+
+    /**
+     * 鎶ュ伐id
+     */
+    @ApiModelProperty(value = "鎶ュ伐id")
+    private Long productMainId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
index 6502a33..c938170 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
@@ -1,8 +1,6 @@
 package com.ruoyi.production.pojo;
 
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.*;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -10,13 +8,14 @@
 import java.time.LocalDateTime;
 
 @Data
+@TableName("production_product_input")
 public class ProductionProductInput {
 
-    @TableId
+    @TableId(type = IdType.AUTO)
     private Long id;
 
     @ApiModelProperty(value = "鎶ュ伐id")
-    private Long productionProductId;
+    private Long productMainId;
 
     @ApiModelProperty(value = "浜у搧id")
     private Long productModelId;
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
index af1a21d..3dbe688 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
@@ -1,17 +1,16 @@
 package com.ruoyi.production.pojo;
 
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.*;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.time.LocalDateTime;
 
 @Data
+@TableName("production_product_main")
 public class ProductionProductMain {
 
-    @TableId
+    @TableId(type = IdType.AUTO)
     private Long id;
 
     @ApiModelProperty(value = "鎶ュ伐鍗曞彿")
@@ -20,15 +19,26 @@
     @ApiModelProperty(value = "鎶ュ伐浜哄憳id")
     private Long userId;
 
+    @ApiModelProperty(value = "鎶ュ伐浜哄憳")
+    private String userName;
+
+    @ApiModelProperty(value = "鐢熶骇椤圭洰id")
+    private Long productProcessRouteItemId;
+
     @ApiModelProperty(value = "宸ュ崟id")
-    private String workOrderId;
+    private Long workOrderId;
 
     @ApiModelProperty(value = "鎶ュ伐鐘舵��")
     private Integer status;
 
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
     private LocalDateTime createTime;
 
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
     @ApiModelProperty(value = "绉熸埛ID")
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
index 67e2fde..20e52ad 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -1,8 +1,6 @@
 package com.ruoyi.production.pojo;
 
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.*;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -10,13 +8,14 @@
 import java.time.LocalDateTime;
 
 @Data
+@TableName("production_product_output")
 public class ProductionProductOutput {
 
-    @TableId
+    @TableId(type = IdType.AUTO)
     private Long id;
 
     @ApiModelProperty(value = "鎶ュ伐id")
-    private Long productionProductId;
+    private Long productMainId;
 
     @ApiModelProperty(value = "浜у搧id")
     private Long productModelId;
diff --git a/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java b/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
new file mode 100644
index 0000000..392230e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
@@ -0,0 +1,15 @@
+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.dto.ProductWorkOrderDto;
+import com.ruoyi.production.pojo.ProductWorkOrder;
+
+public interface ProductWorkOrderService extends IService<ProductWorkOrder>{
+
+    IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder);
+
+    int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto);
+
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java b/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
new file mode 100644
index 0000000..1af1772
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
@@ -0,0 +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.dto.ProductionProductInputDto;
+import com.ruoyi.production.pojo.ProductionProductInput;
+
+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 8e1ec9a..0980cae 100644
--- a/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
@@ -12,4 +12,8 @@
 
 public interface ProductionProductMainService extends IService<ProductionProductMain> {
     IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto);
+
+    Boolean addProductMain(ProductionProductMainDto productionProductMainDto);
+
+    Boolean removeProductMain(ProductionProductMainDto productionProductMainDto);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java b/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
new file mode 100644
index 0000000..dea72b5
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
@@ -0,0 +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.dto.ProductionProductOutputDto;
+import com.ruoyi.production.pojo.ProductionProductOutput;
+
+public interface ProductionProductOutputService extends IService<ProductionProductOutput> {
+    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, ProductionProductOutputDto productionProductOutputDto);
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
new file mode 100644
index 0000000..6f70e7c
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -0,0 +1,32 @@
+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.dto.ProductWorkOrderDto;
+import com.ruoyi.production.mapper.ProductWorkOrderMapper;
+import com.ruoyi.production.pojo.ProductWorkOrder;
+import com.ruoyi.production.service.ProductWorkOrderService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@AllArgsConstructor
+@Transactional(rollbackFor = Exception.class)
+public class ProductWorkOrderServiceImpl extends ServiceImpl<ProductWorkOrderMapper, ProductWorkOrder> implements ProductWorkOrderService {
+
+    private ProductWorkOrderMapper productWorkOrdermapper;
+
+    @Override
+    public IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
+        return productWorkOrdermapper.pageProductWorkOrder(page, productWorkOrder);
+    }
+
+    @Override
+    public int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto) {
+        return productWorkOrdermapper.updateById(productWorkOrderDto);
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
new file mode 100644
index 0000000..49765c0
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
@@ -0,0 +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.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;
+
+@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 2a958ef..31a1e9c 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -1,29 +1,258 @@
 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.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 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.dto.ProcessRouteItemDto;
-import com.ruoyi.production.dto.ProductOrderDto;
+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.utils.SecurityUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.production.controller.ProductWorkOrderController;
+import com.ruoyi.production.dto.ProductStructureDto;
 import com.ruoyi.production.dto.ProductionProductMainDto;
-import com.ruoyi.production.mapper.ProcessRouteItemMapper;
-import com.ruoyi.production.mapper.ProductionProductMainMapper;
-import com.ruoyi.production.pojo.ProductionProductMain;
+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.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.mapper.QualityInspectParamMapper;
+import com.ruoyi.quality.mapper.QualityTestStandardMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.quality.pojo.QualityInspectParam;
+import com.ruoyi.quality.pojo.QualityTestStandard;
 import lombok.AllArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import com.ruoyi.production.mapper.ProductionProductMainMapper;
 
+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;
 
 @Service
 @AllArgsConstructor
 public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
-    @Autowired
+
     private ProductionProductMainMapper productionProductMainMapper;
+
+    private ProductWorkOrderController productWorkOrderController;
+
+    private ProductWorkOrderMapper productWorkOrderMapper;
+
+    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+
+    private ProductionProductOutputMapper productionProductOutputMapper;
+
+    private ProcessRouteItemMapper processRouteItemMapper;
+
+    private ProductModelMapper productModelMapper;
+
+    private QualityInspectMapper qualityInspectMapper;
+
+    private ProductProcessMapper productProcessMapper;
+
+    private ProductMapper productMapper;
+
+    private QualityTestStandardMapper qualityTestStandardMapper;
+
+    private QualityInspectParamMapper qualityInspectParamMapper;
+
+    private ProductStructureMapper productStructureMapper;
+
+    private ProductionProductInputMapper productionProductInputMapper;
+
+    private ProductOrderMapper productOrderMapper;
+
+    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+
 
     @Override
     public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) {
         return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addProductMain(ProductionProductMainDto dto) {
+        if (dto == null) {
+            throw new RuntimeException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        SysUser user = SecurityUtils.getLoginUser().getUser();
+
+
+
+        // 鏂板閫昏緫
+        ProductionProductMain productionProductMain = new ProductionProductMain();
+        ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId());
+        if (productProcessRouteItem == null) {
+            throw new RuntimeException("宸ヨ壓璺嚎椤逛笉瀛樺湪");
+        }
+
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+
+        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) {
+                Object maxNoObj = result.get("maxNo");
+                if (maxNoObj != null) {
+                    String lastNo = maxNoObj.toString();
+                    System.out.println("lastNo: " + lastNo);
+
+                    if (lastNo.startsWith(datePrefix)) {
+                        try {
+                            String seqStr = lastNo.substring(datePrefix.length());
+                            sequenceNumber = Integer.parseInt(seqStr) + 1;
+                        } catch (NumberFormatException e) {
+                            sequenceNumber = 1;
+                        }
+                    }
+                }
+            }
+        }
+
+        String productNo = String.format("%s%03d", datePrefix, sequenceNumber);
+        productionProductMain.setProductNo(productNo);
+        productionProductMain.setUserId(user.getUserId());
+        productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId());
+        productionProductMain.setWorkOrderId(dto.getWorkOrderId());
+        productionProductMain.setStatus(0);
+
+        // 娣诲姞鎶ュ伐涓昏〃
+        int insert = productionProductMainMapper.insert(productionProductMain);
+
+        //鏇存柊宸ュ崟
+        if (insert > 0) {
+            Map<String, Object> params = new HashMap<>();
+            params.put("quantity", dto.getQuantity());
+            params.put("productMainId", productionProductMain.getId());
+            params.put("workOrderId", dto.getWorkOrderId());
+            params.put("deductQuantity", dto.getQuantity());
+
+            productWorkOrderMapper.updatePlanQuantity(params);
+        }
+        ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId());
+        ProductModel productModel = productProcessRouteItem.getProductModelId() != null ?
+                productModelMapper.selectById(productProcessRouteItem.getProductModelId()) : null;
+
+        if (productModel != null) {
+            Product product = productMapper.selectById(productModel.getProductId());
+            int inspectType = "缁勮".equals(productProcess.getName()) ? 2 : 1;
+
+            QualityInspect qualityInspect = new QualityInspect();
+            qualityInspect.setProductId(product.getId());
+            qualityInspect.setProductName(product.getProductName());
+            qualityInspect.setModel(productModel.getModel());
+            qualityInspect.setUnit(productModel.getUnit());
+            qualityInspect.setQuantity(dto.getQuantity());
+            qualityInspect.setProcess(productProcess.getName());
+            qualityInspect.setInspectState(0);
+            qualityInspect.setInspectType(inspectType);
+            qualityInspect.setProductMainId(productionProductMain.getId());
+            qualityInspectMapper.insert(qualityInspect);
+
+            qualityTestStandardMapper.selectList(
+                    new LambdaQueryWrapper<QualityTestStandard>()
+                            .eq(QualityTestStandard::getProductId, product.getId())
+            ).forEach(standard -> {
+                QualityInspectParam param = new QualityInspectParam();
+                BeanUtils.copyProperties(standard, param);
+                param.setId(null);
+                param.setInspectId(qualityInspect.getId());
+                qualityInspectParamMapper.insert(param);
+            });
+        }
+        // 娣诲姞鎶曞叆
+        if (productModel != null) {
+            List<ProductStructureDto> productStructureDtos = productStructureMapper.listByproductModelId(productModel.getId());
+            for (ProductStructureDto productStructureDto : productStructureDtos) {
+                ProductionProductInput productionProductInput = new ProductionProductInput();
+                productionProductInput.setProductModelId(productStructureDto.getProductModelId());
+                productionProductInput.setQuantity(productStructureDto.getUnitQuantity());
+                productionProductInput.setProductMainId(productionProductMain.getId());
+                productionProductInputMapper.insert(productionProductInput);
+            }
+        }
+
+        // 娣诲姞浜у嚭
+        ProductionProductOutput productionProductOutput = new ProductionProductOutput();
+        productionProductOutput.setProductMainId(productionProductMain.getId());
+        productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId());
+        productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
+        productionProductOutputMapper.insert(productionProductOutput);
+
+        // 鑾峰彇鐢熶骇璁㈠崟
+        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
+        ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
+        if (productOrder == null) {
+            throw new RuntimeException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+        }
+        // 娣诲姞鐢熶骇鏍哥畻
+        SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
+                .salesLedgerWorkId(productionProductMain.getId())
+                .salesLedgerSchedulingId(0L)
+                .salesLedgerId(productOrder.getSalesLedgerId())
+                .salesLedgerProductId(productOrder.getProductModelId())
+                .schedulingUserId(user.getUserId())
+                .schedulingUserName(user.getNickName())
+                .finishedNum(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO)
+                .workHours(productProcess.getSalaryQuota())
+                .process(productProcess.getName())
+                .schedulingDate(LocalDate.now())
+                .tenantId(dto.getTenantId())
+                .build();
+        salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
+
+        return true;
+    }
+
+    @Override
+    @Transactional
+    public Boolean removeProductMain(ProductionProductMainDto dto) {
+        Long id = dto.getId();
+
+        // 鏇存柊宸ュ崟
+        productWorkOrderMapper.rollbackPlanQuantity(id);
+        // 鍒犻櫎璐ㄦ鍙傛暟鍜岃川妫�璁板綍
+        qualityInspectMapper.selectList(
+                new LambdaQueryWrapper<QualityInspect>()
+                        .eq(QualityInspect::getProductMainId, id)
+        ).forEach(q -> {
+            qualityInspectParamMapper.delete(
+                    new LambdaQueryWrapper<QualityInspectParam>()
+                            .eq(QualityInspectParam::getInspectId, q.getId()));
+            qualityInspectMapper.deleteById(q.getId());
+        });
+
+        // 鍒犻櫎浜у嚭璁板綍
+        productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
+                .eq(ProductionProductOutput::getProductMainId, id)
+        );
+
+        // 鍒犻櫎鍏宠仈鐨勬牳绠楁暟鎹�
+        salesLedgerProductionAccountingMapper.delete(
+                new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
+                        .eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, id)
+        );
+
+        // 鍒犻櫎涓昏〃
+        return productionProductMainMapper.deleteById(id) > 0;
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
new file mode 100644
index 0000000..654b9af
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
@@ -0,0 +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.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;
+
+@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/purchase/controller/PurchaseLedgerController.java b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
index fca4277..cbb2e00 100644
--- a/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
@@ -1,5 +1,6 @@
 package com.ruoyi.purchase.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -11,7 +12,10 @@
 import com.ruoyi.purchase.dto.PurchaseLedgerDto;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.purchase.service.IPurchaseLedgerService;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.service.ISalesLedgerProductService;
 import com.ruoyi.sales.service.ISalesLedgerService;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.web.bind.annotation.*;
@@ -19,6 +23,7 @@
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 閲囪喘鍙拌处Controller
@@ -29,10 +34,12 @@
 @RestController
 @RequestMapping("/purchase/ledger")
 @AllArgsConstructor
+@Api(tags = "111")
 public class PurchaseLedgerController extends BaseController {
     private IPurchaseLedgerService purchaseLedgerService;
 
     private ISalesLedgerService salesLedgerService;
+    private ISalesLedgerProductService salesLedgerProductService;
 
     /**
      * 鏌ヨ閲囪喘鍙拌处鍒楄〃
@@ -77,7 +84,42 @@
     public AjaxResult addOrEditPurchase(@RequestBody PurchaseLedgerDto purchaseLedgerDto) throws IOException {
         return toAjax(purchaseLedgerService.addOrEditPurchase(purchaseLedgerDto));
     }
+    /**
+     * 鏂板閲囪喘妯℃澘
+     */
+    @PostMapping("/addPurchaseTemplate")
+    public AjaxResult addPurchaseTemplate(@RequestBody PurchaseLedgerDto purchaseLedgerDto) throws IOException {
+        return toAjax(purchaseLedgerService.addPurchaseTemplate(purchaseLedgerDto));
+    }
+    /**
+     * 鏌ヨ閲囪喘妯℃澘
+     */
+    @ApiOperation("/2222")
+    @GetMapping("/getPurchaseTemplateList")
+    public AjaxResult getPurchaseTemplateList() {
+        PurchaseLedgerDto purchaseLedgerDto = new PurchaseLedgerDto();
+        purchaseLedgerDto.setApprovalStatus(3);
+        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerService.selectPurchaseLedgerListPage(new Page(1, -1), purchaseLedgerDto);
+        List<PurchaseLedgerDto> purchaseLedgers = purchaseLedgerDtoIPage.getRecords();
 
+        purchaseLedgers.forEach(purchaseLedgerDto1 -> {
+            LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedgerDto1.getId())
+                    .eq(SalesLedgerProduct::getType, 2);
+            List<SalesLedgerProduct> list = salesLedgerProductService.list(queryWrapper);
+            if (!list.isEmpty()) {
+                purchaseLedgerDto1.setProductData(list);
+            }
+        });
+        return AjaxResult.success(purchaseLedgers);
+    }
+    /**
+     * 淇敼閲囪喘鍙拌处瀹℃壒鐘舵��
+     */
+    @PostMapping("/updateApprovalStatus")
+    public AjaxResult addOrEditPurchase(@RequestBody PurchaseLedger purchaseLedger){
+        return toAjax(purchaseLedgerService.updateById(purchaseLedger));
+    }
     /**
      * 鏌ヨ閲囪喘鍙拌处鍜屼骇鍝佺埗瀛愬垪琛�
      */
@@ -149,7 +191,10 @@
      */
     @GetMapping("/listPage")
     public AjaxResult listPage(Page page, PurchaseLedgerDto purchaseLedger) {
-         return AjaxResult.success(purchaseLedgerService.selectPurchaseLedgerListPage(page ,purchaseLedger));
+        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerService.selectPurchaseLedgerListPage(page ,purchaseLedger);
+        //杩囨护鎺塧pprovalStatus=3鐨勮褰�
+        purchaseLedgerDtoIPage.getRecords().removeIf(purchaseLedgerDto -> purchaseLedgerDto.getApprovalStatus() == 3);
+         return AjaxResult.success(purchaseLedgerDtoIPage);
     }
 
     @ApiOperation("鐢熸垚閲囪喘搴忓垪鍙�")
diff --git a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
index 7d1e9e5..4808080 100644
--- a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -40,6 +40,11 @@
      */
     @Excel(name = "渚涘簲鍟嗗悕绉�")
     private String supplierName;
+     /**
+     * 鏄惁鐧藉悕鍗�
+     */
+    @Excel(name = "鏄惁鐧藉悕鍗�")
+    private Integer isWhite;
 
     /**
      * 褰曞叆浜哄鍚峣d
@@ -180,5 +185,10 @@
 
     @ApiModelProperty(value = "浠樻鏂瑰紡")
     private String paymentMethod;
-
+    @ApiModelProperty("瀹℃壒鐘舵��")
+    private Integer approvalStatus;
+    @ApiModelProperty(value = "妯℃澘鍚嶇О")
+    private String templateName;
+    @ApiModelProperty(value = "瀹℃壒浜篿d")
+    private Integer approverId;
 }
diff --git a/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java b/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
index 7b7ad72..838976d 100644
--- a/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
+++ b/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
@@ -148,10 +148,14 @@
     @TableField(exist = false)
     private Integer type;
 
-
-
     @ApiModelProperty(value = "浠樻鏂瑰紡")
     private String paymentMethod;
+    @ApiModelProperty("瀹℃壒鐘舵��")
+    private Integer approvalStatus;
 
+    @ApiModelProperty(value = "妯℃澘鍚嶇О")
+    private String templateName;
+    @ApiModelProperty(value = "瀹℃壒浜篿d")
+    private Integer approverId;
 
 }
diff --git a/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java b/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
index 3979810..c0eb379 100644
--- a/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
+++ b/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
@@ -39,4 +39,6 @@
     List<InvoiceRegistrationProduct> getProductBySalesNo(Long id);
 
     String getPurchaseNo();
+
+    int addPurchaseTemplate(PurchaseLedgerDto purchaseLedgerDto) throws IOException;
 }
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
index a20c5bb..7453caf 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -122,7 +122,49 @@
         }
         return purchaseLedgerMapper.selectList(queryWrapper);
     }
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int addPurchaseTemplate(PurchaseLedgerDto purchaseLedgerDto)throws IOException {
+        //褰曞叆浜�
+        SysUser sysUser = userMapper.selectUserById(purchaseLedgerDto.getRecorderId());
 
+        SupplierManage supplierManage = supplierManageMapper.selectById(purchaseLedgerDto.getSupplierId());
+        PurchaseLedger purchaseLedger = new PurchaseLedger();
+//        BeanUtils.copyProperties(purchaseLedger,purchaseLedgerDto);
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        if(ObjectUtils.isNotEmpty(loginUser) && null != loginUser.getTenantId()) {
+            purchaseLedger.setTenantId(loginUser.getTenantId());
+        }
+        purchaseLedger.setPaymentMethod(purchaseLedgerDto.getPaymentMethod());
+        purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId());
+        purchaseLedger.setSupplierId(purchaseLedgerDto.getSupplierId());
+        purchaseLedger.setTemplateName(purchaseLedgerDto.getTemplateName());
+//        purchaseLedger.setSalesLedgerPId(purchaseLedgerDto.getSalesLedgerId());
+        purchaseLedger.setApprovalStatus(3);
+        purchaseLedger.setSupplierName(supplierManage.getSupplierName());
+        purchaseLedger.setRecorderName(sysUser.getNickName());
+        purchaseLedger.setPhoneNumber(sysUser.getPhonenumber());
+        purchaseLedger.setPurchaseContractNumber(UUID.randomUUID().toString().replaceAll("-", ""));
+        purchaseLedger.setEntryDate(Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()));
+        int insert = purchaseLedgerMapper.insert(purchaseLedger);
+
+        LambdaQueryWrapper<PurchaseLedger> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(PurchaseLedger::getSupplierName, purchaseLedger.getSupplierName())
+                .eq(PurchaseLedger::getPurchaseContractNumber, purchaseLedger.getPurchaseContractNumber())
+                .eq(PurchaseLedger::getApprovalStatus,3);
+        PurchaseLedger purchaseLedger1 = purchaseLedgerMapper.selectOne(queryWrapper);
+
+        if(ObjectUtils.isNotEmpty(purchaseLedgerDto.getProductData())) {
+            // 4. 澶勭悊瀛愯〃鏁版嵁
+            List<SalesLedgerProduct> salesLedgerProductList = purchaseLedgerDto.getProductData();
+            salesLedgerProductList.forEach(salesLedgerProduct -> {
+                salesLedgerProduct.setSalesLedgerId(purchaseLedger1.getId());
+                salesLedgerProduct.setType(2);
+            });
+            salesLedgerProductList.forEach(salesLedgerProductMapper::insert);
+        }
+        return insert;
+    }
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int addOrEditPurchase(PurchaseLedgerDto purchaseLedgerDto) throws IOException {
@@ -169,7 +211,7 @@
             PurchaseLedger purchaseLedgerDB = purchaseLedgerMapper.selectById(purchaseLedger.getId());
             List<AccountExpense> accountExpenseDBs = accountExpenseService.getByInvoiceNumberList(purchaseLedger.getPurchaseContractNumber());
             if (!CollectionUtils.isEmpty(accountExpenseDBs)) {
-                accountExpenseDBs.forEach(accountExpenseDB -> {
+                accountExpenseDBs.forEach(accountExpenseDB ->{
                     accountExpenseDB.setExpenseDate(purchaseLedgerDB.getEntryDate());
                     accountExpenseDB.setExpenseType("0");
                     accountExpenseDB.setSupplierName(purchaseLedgerDB.getSupplierName());
@@ -383,7 +425,7 @@
     @Override
     public int deletePurchaseLedgerByIds(Long[] ids) {
         if (ids == null || ids.length == 0) {
-            throw new BaseException("璇烽�変腑鑷冲皯涓�鏉℃暟鎹�");
+           throw new BaseException("璇烽�変腑鑷冲皯涓�鏉℃暟鎹�");
         }
         // 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐彴璐︿骇鍝�
         LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
@@ -392,11 +434,11 @@
         salesLedgerProductMapper.delete(queryWrapper);
         // 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐彴璐︾殑鏉ョエ鐧昏
         LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getPurchaseLedgerId, ids);
+        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getSalesLedgerId,ids);
         ticketRegistrationMapper.delete(ticketRegistrationLambdaQueryWrapper);
         // 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐彴璐︾殑鏉ョエ鐧昏璁板綍
         LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        productRecordLambdaQueryWrapper.in(ProductRecord::getPurchaseLedgerId, ids);
+        productRecordLambdaQueryWrapper.in(ProductRecord::getPurchaseLedgerId,ids);
         productRecordMapper.delete(productRecordLambdaQueryWrapper);
         // 鎵归噺鍒犻櫎浠樻鐧昏
         LambdaQueryWrapper<PaymentRegistration> paymentRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -410,9 +452,12 @@
                 .map(QualityInspect::getId)
                 .collect(Collectors.toList());
 
-        LambdaQueryWrapper<QualityInspectParam> qualityStandardLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        qualityStandardLambdaQueryWrapper.in(QualityInspectParam::getInspectId, inspectIds);
-        qualityInspectParamMapper.delete(qualityStandardLambdaQueryWrapper);
+        if (inspectIds.size() > 0) {
+            LambdaQueryWrapper<QualityInspectParam> qualityStandardLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            qualityStandardLambdaQueryWrapper.in(QualityInspectParam::getInspectId, inspectIds);
+            qualityInspectParamMapper.delete(qualityStandardLambdaQueryWrapper);
+        }
+
         //鎵归噺鍒犻櫎鍘熸潗鏂欐楠屾暟鎹�
         qualityInspectMapper.delete(materialInspectLambdaQueryWrapper);
         // 鎵归噺鍒犻櫎閲囪喘鍙拌处
@@ -436,7 +481,7 @@
         // 3.鏌ヨ涓婁紶鏂囦欢
         LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>();
         salesLedgerFileWrapper.eq(CommonFile::getCommonId, purchaseLedger.getId())
-                .eq(CommonFile::getType, FileNameType.PURCHASE.getValue());
+                .eq(CommonFile::getType,FileNameType.PURCHASE.getValue());
         List<CommonFile> salesLedgerFiles = commonFileMapper.selectList(salesLedgerFileWrapper);
 
         // 4. 杞崲 DTO
diff --git a/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java b/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
index 9d96578..fdc57da 100644
--- a/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
+++ b/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
@@ -17,4 +17,9 @@
     IPage<QualityInspect> qualityInspectListPage(Page page, @Param("qualityInspect") QualityInspect qualityInspect);
 
     List<QualityInspect> qualityInspectExport(@Param("qualityInspect") QualityInspect qualityInspect);
+
+    /**
+     * 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎杩囩▼妫�楠�
+     */
+    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
 }
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
index 6c39977..e03b74a 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -140,5 +140,10 @@
 
     private Long purchaseLedgerId;
 
+    /**
+     * 鎶ュ伐id
+     */
+    private Long productMainId;
+
 
 }
diff --git a/src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java b/src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
new file mode 100644
index 0000000..047cb37
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
@@ -0,0 +1,77 @@
+package com.ruoyi.sales.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.sales.mapper.ShipmentApprovalMapper;
+import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.pojo.ShipmentApproval;
+import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.sales.service.ISalesLedgerProductService;
+import com.ruoyi.sales.service.ShipmentApprovalService;
+import com.ruoyi.sales.service.ShippingInfoService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+@RestController
+@RequestMapping("/shipmentApproval")
+@Api(tags = "鍙戣揣瀹℃壒绠$悊")
+public class ShipmentApprovalController extends BaseController {
+
+    @Autowired
+    private ShipmentApprovalService shipmentApprovalService;
+    @Autowired
+    private ShipmentApprovalMapper shipmentApprovalMapper;
+
+    @Autowired
+    private ISalesLedgerProductService salesLedgerProductService;
+
+    @GetMapping("/listPage")
+    @ApiOperation("鍙戣揣瀹℃壒鍒楄〃")
+    public AjaxResult listPage(Page page, ShipmentApproval req) {
+        IPage<ShipmentApproval> listPage = shipmentApprovalService.listPage(page,req);
+        return AjaxResult.success(listPage);
+    }
+
+    @PostMapping("/update")
+    @ApiOperation("鍙戣揣瀹℃壒,鏇存柊鍙戣揣瀹℃壒鐘舵��")
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxResult update(@RequestBody ShipmentApproval req) {
+        ShipmentApproval shipmentApproval = shipmentApprovalMapper.selectById(req.getId());
+        if (shipmentApproval == null) {
+            return AjaxResult.error("鍙戣揣瀹℃壒涓嶅瓨鍦�");
+        }
+
+        shipmentApproval.setApproveStatus(req.getApproveStatus());
+        boolean update = shipmentApprovalService.updateById(shipmentApproval);
+        if(update){
+            SalesLedgerProduct salesLedgerProduct = salesLedgerProductService.getById(shipmentApproval.getSalesLedgerProductId());
+            salesLedgerProduct.setApproveStatus(req.getApproveStatus());
+            salesLedgerProductService.updateById(salesLedgerProduct);
+        }
+        return update ? AjaxResult.success() : AjaxResult.error();
+    }
+
+
+    /**
+     * 瀵煎嚭鍙戣揣淇℃伅绠$悊
+     */
+    @PostMapping("/export")
+    @ApiOperation("瀵煎嚭鍙戣揣瀹℃壒")
+    public void export(HttpServletResponse response) {
+        List<ShipmentApproval> list = shipmentApprovalService.list(null);
+        ExcelUtil<ShipmentApproval> util = new ExcelUtil<ShipmentApproval>(ShipmentApproval.class);
+        util.exportExcel(response, list, "鍙戣揣瀹℃壒");
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java b/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
index 56b3e15..c498b93 100644
--- a/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
+++ b/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
@@ -1,5 +1,6 @@
 package com.ruoyi.sales.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -7,13 +8,20 @@
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.sales.mapper.ShipmentApprovalMapper;
 import com.ruoyi.sales.mapper.ShippingInfoMapper;
 import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.pojo.ShipmentApproval;
 import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.sales.service.ISalesLedgerProductService;
+import com.ruoyi.sales.service.ISalesLedgerService;
 import com.ruoyi.sales.service.ShippingInfoService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
@@ -30,6 +38,10 @@
 
     @Autowired
     private ShippingInfoService shippingInfoService;
+    @Autowired
+    private ShipmentApprovalMapper shipmentApprovalMapper;
+    @Autowired
+    private ISalesLedgerProductService salesLedgerProductService;
 
 
     @GetMapping("/listPage")
@@ -41,8 +53,33 @@
 
     @PostMapping("/add")
     @ApiOperation("娣诲姞鍙戣揣淇℃伅")
+    @Transactional(rollbackFor = Exception.class)
     public AjaxResult add(@RequestBody ShippingInfo req) {
+        LambdaQueryWrapper<ShippingInfo> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(ShippingInfo::getSalesLedgerId, req.getSalesLedgerId());
+        wrapper.eq(ShippingInfo::getSalesLedgerProductId, req.getSalesLedgerProductId());
+        List<ShippingInfo> list = shippingInfoService.list(wrapper);
+        if(!CollectionUtils.isEmpty(list)){
+            return AjaxResult.error("鍙戣揣淇℃伅宸插瓨鍦�");
+        }
         boolean save = shippingInfoService.save(req);
+        if(save){
+            ShippingInfo shippingInfo = shippingInfoService.getOne(wrapper);
+            ShipmentApproval shipmentApproval = new ShipmentApproval();
+            shipmentApproval.setSalesLedgerId(req.getSalesLedgerId());
+            shipmentApproval.setSalesLedgerProductId(req.getSalesLedgerProductId());
+            shipmentApproval.setApproveUserId(req.getApproverId());
+            shipmentApproval.setApproveStatus(2);
+            shipmentApproval.setShippingInfoId(shippingInfo.getId());
+            shipmentApprovalMapper.insert(shipmentApproval);
+
+            SalesLedgerProduct salesLedgerProduct = salesLedgerProductService.getById(req.getSalesLedgerProductId());
+            if(salesLedgerProduct != null){
+                salesLedgerProduct.setApproveStatus(2);
+                salesLedgerProductService.updateById(salesLedgerProduct);
+            }
+
+        }
         return save ? AjaxResult.success() : AjaxResult.error();
     }
 
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
index 69b2b7b..0ccce79 100644
--- a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -2,6 +2,9 @@
 
 import com.ruoyi.common.config.MyBaseMapper;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 浜у搧淇℃伅Mapper鎺ュ彛
@@ -10,4 +13,5 @@
  * @date 2025-05-08
  */
 public interface SalesLedgerProductMapper extends MyBaseMapper<SalesLedgerProduct> {
+    List<SalesLedgerProduct> selectSalesLedgerProductList(@Param("salesLedgerProduct") SalesLedgerProduct salesLedgerProduct);
 }
diff --git a/src/main/java/com/ruoyi/sales/mapper/ShipmentApprovalMapper.java b/src/main/java/com/ruoyi/sales/mapper/ShipmentApprovalMapper.java
new file mode 100644
index 0000000..c3bf397
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/mapper/ShipmentApprovalMapper.java
@@ -0,0 +1,16 @@
+package com.ruoyi.sales.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.sales.pojo.ShipmentApproval;
+import com.ruoyi.sales.pojo.ShippingInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+
+public interface ShipmentApprovalMapper extends BaseMapper<ShipmentApproval> {
+    IPage<ShipmentApproval> listPage(Page page,@Param("req") ShipmentApproval req);
+
+}
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
index 35b7488..955f4da 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -140,5 +140,9 @@
 
     @ApiModelProperty(value = "浠樻鏂瑰紡")
     private String paymentMethod;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "鐢熶骇鐘舵��")
+    private String productionStatus = "鏈紑濮�";
 }
 
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
index 7628d95..f35b916 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -9,8 +9,10 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.Date;
 
 /**
  * 浜у搧淇℃伅瀵硅薄 sales_ledger_product
@@ -20,7 +22,7 @@
  */
 @TableName("sales_ledger_product")
 @Data
-public class SalesLedgerProduct {
+public class SalesLedgerProduct implements Serializable {
     private static final long serialVersionUID = 1L;
 
     /**
@@ -183,4 +185,28 @@
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @Excel(name = "鐧昏鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime registerDate;
+    /**
+     * 鍙戣揣杞︾墝鍙�
+     */
+    @Excel(name = "鍙戣揣杞︾墝鍙�")
+    @TableField(exist = false)
+    private String shippingCarNumber;
+
+    /**
+     * 鍙戣揣鏃ユ湡
+     */
+    @Excel(name = "鍙戣揣鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField(exist = false)
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date shippingDate;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "鐢熶骇鐘舵��")
+    private String productionStatus = "鏈紑濮�";
+    /**
+     * 鍙戣揣瀹℃壒鐘舵��
+     */
+//    @TableField(exist = false)
+    @ApiModelProperty(value = "瀹℃壒鐘舵��")
+    private Integer approveStatus;
 }
diff --git a/src/main/java/com/ruoyi/sales/pojo/ShipmentApproval.java b/src/main/java/com/ruoyi/sales/pojo/ShipmentApproval.java
new file mode 100644
index 0000000..41a0d34
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/pojo/ShipmentApproval.java
@@ -0,0 +1,352 @@
+package com.ruoyi.sales.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@TableName("shipment_approval")
+public class ShipmentApproval {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    @ApiModelProperty(value = "鍙戣揣淇℃伅id")
+    private Long shippingInfoId;
+    @ApiModelProperty(value = "閿�鍞彴璐d")
+    private Long salesLedgerId;
+    @ApiModelProperty(value = "閿�鍞姤浠蜂骇鍝佽〃id")
+    private Long salesLedgerProductId;
+     @ApiModelProperty(value = "鐢宠閮ㄩ棬id")
+    private Long approveDeptId;
+
+    @ApiModelProperty(value = "鐢宠閮ㄩ棬鍚嶇О")
+    @Excel(name = "鐢宠閮ㄩ棬")
+    private String approveDeptName;
+     @ApiModelProperty(value = "瀹℃壒鐢ㄦ埛id")
+    private Integer approveUserId;
+    @ApiModelProperty(value = "瀹℃壒鐢ㄦ埛鍚嶇О")
+    @Excel(name = "瀹℃壒鐢ㄦ埛")
+    private String approveUserNames;
+
+    /**
+     * 瀹℃壒鐘舵��
+     */
+    @ApiModelProperty(value = "瀹℃壒鐘舵�侊細0鏈嚭搴�,1宸插嚭搴�,2寰呭鏍�,3瀹℃牳瀹屾垚,4瀹℃牳澶辫触")
+    @Excel(name = "瀹℃壒鐘舵��", readConverterExp = "0=鏈嚭搴�,1=宸插嚭搴�,2=寰呭鏍�,3=瀹℃牳瀹屾垚,4=瀹℃牳澶辫触")
+    private Integer approveStatus;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Integer createUser;
+
+    @ApiModelProperty(value = "淇敼鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鍙戣揣鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField(exist = false)
+    private Date shippingDate;
+
+    @Excel(name = "鍙戣揣杞︾墝鍙�")
+    @TableField(exist = false)
+    private String shippingCarNumber;
+
+    /**
+     * 棰勮鏁伴噺
+     */
+
+    @TableField(exist = false)
+    private BigDecimal warnNum;
+
+    /**
+     * 浜у搧澶х被
+     */
+    @Excel(name = "浜у搧澶х被")
+    @TableField(exist = false)
+    private String productCategory;
+
+    /**
+     * 瑙勬牸鍨嬪彿
+     */
+    @Excel(name = "瑙勬牸鍨嬪彿")
+    @TableField(exist = false)
+    private String specificationModel;
+
+    /**
+     * 鍗曚綅
+     */
+    @Excel(name = "鍗曚綅")
+    @TableField(exist = false)
+    private String unit;
+
+    /**
+     * 鏁伴噺
+     */
+    @Excel(name = "鏁伴噺")
+    @TableField(exist = false)
+    private BigDecimal quantity;
+    @Excel(name = "鏈�浣庡簱瀛樻暟閲�")
+    @TableField(exist = false)
+    private BigDecimal minStock;
+    /**
+     * 绋庣巼
+     */
+    @Excel(name = "绋庣巼")
+    @TableField(exist = false)
+    private BigDecimal taxRate;
+
+    /**
+     * 鍚◣鍗曚环
+     */
+    @Excel(name = "鍚◣鍗曚环")
+    @TableField(exist = false)
+    private BigDecimal taxInclusiveUnitPrice;
+
+    /**
+     * 鍚◣鎬讳环
+     */
+    @Excel(name = "鍚◣鎬讳环")
+    @TableField(exist = false)
+    private BigDecimal taxInclusiveTotalPrice;
+
+    /**
+     * 涓嶅惈绋庢�讳环
+     */
+    @Excel(name = "涓嶅惈绋庢�讳环")
+    @TableField(exist = false)
+    private BigDecimal taxExclusiveTotalPrice;
+
+    /**
+     * 鍙戠エ绫诲瀷
+     */
+
+    @TableField(exist = false)
+    private String invoiceType;
+
+    /**
+     * 鍙拌处绫诲瀷 1.閿�鍞� 2锛岄噰璐�
+     */
+    @TableField(exist = false)
+    private Integer type;
+
+    /**
+     * 鏈鏉ョエ鏁�
+     */
+    @TableField(exist = false)
+    private BigDecimal ticketsNum;
+
+    /**
+     * 鏈鏉ョエ閲戦(鍏�)
+     */
+    @TableField(exist = false)
+    private BigDecimal ticketsAmount;
+
+    /**
+     * 鏈潵绁ㄦ暟
+     */
+    @TableField(exist = false)
+    private BigDecimal futureTickets;
+
+    /**
+     * 鏈潵绁ㄩ噾棰�(鍏�)
+     */
+    @TableField(exist = false)
+    private BigDecimal futureTicketsAmount;
+
+    @ApiModelProperty(value = "寮�绁ㄦ暟")
+    @TableField(exist = false)
+    private BigDecimal invoiceNum;
+
+    @ApiModelProperty(value = "鏈紑绁ㄦ暟")
+    @TableField(exist = false)
+    private BigDecimal noInvoiceNum;
+
+    @ApiModelProperty(value = "寮�绁ㄩ噾棰�")
+    @TableField(exist = false)
+    private BigDecimal invoiceAmount;
+
+    @ApiModelProperty(value = "鏈紑绁ㄩ噾棰�")
+    @TableField(exist = false)
+    private BigDecimal noInvoiceAmount;
+
+    @ApiModelProperty(value = "鏈寮�绁ㄦ暟")
+    @TableField(exist = false)
+    private BigDecimal currentInvoiceNum;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "鏈寮�绁ㄩ噾棰�")
+    private BigDecimal currentInvoiceAmount;
+
+    /**
+     *  浜у搧id
+     */
+    @TableField(exist = false)
+    private Long productId;
+
+    /**
+     * 浜у搧瑙勬牸id
+     */
+    @TableField(exist = false)
+    private Long productModelId;
+
+    @ApiModelProperty(value = "鍒濆鏈紑绁ㄦ暟")
+    @TableField(exist = false)
+    private BigDecimal originalNoInvoiceNum;
+
+    @ApiModelProperty(value = "涓存椂鏈紑绁ㄦ暟")
+    @TableField(exist = false)
+    private BigDecimal tempNoInvoiceNum;
+
+    @ApiModelProperty(value = "涓存椂鏈紑绁ㄩ噾棰�")
+    @TableField(exist = false)
+    private BigDecimal tempnoInvoiceAmount;
+
+    @ApiModelProperty(value = "涓存椂鏈潵绁ㄦ暟")
+    @TableField(exist = false)
+    private BigDecimal tempFutureTickets;
+
+    @ApiModelProperty(value = "涓存椂鏈潵绁ㄩ噾棰�")
+    @TableField(exist = false)
+    private BigDecimal tempFutureTicketsAmount;
+
+    @ApiModelProperty("鐧昏浜�")
+    @TableField(exist = false)
+    private String register;
+
+    @ApiModelProperty("鐧昏鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "鐧昏鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @TableField(exist = false)
+    private LocalDateTime registerDate;
+    /**
+     * 閿�鍞悎鍚屽彿
+     */
+    @Excel(name = "閿�鍞悎鍚屽彿")
+    @TableField(exist = false)
+    private String salesContractNo;
+
+    /**
+     * 瀹㈡埛鍚堝悓鍙�
+     */
+    @Excel(name = "瀹㈡埛鍚堝悓鍙�")
+    @TableField(exist = false)
+    private String customerContractNo;
+
+
+    /**
+     * 椤圭洰鍚嶇О
+     */
+    @Excel(name = "椤圭洰鍚嶇О")
+    @TableField(exist = false)
+    private String projectName;
+
+    /**
+     * 褰曞叆鏃ユ湡
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @TableField(exist = false)
+    private Date entryDate;
+
+    /**
+     * 涓氬姟鍛�
+     */
+    @Excel(name = "涓氬姟鍛�")
+    @TableField(exist = false)
+    private String salesman;
+
+    @TableField(exist = false)
+    private Long customerId;
+
+    /**
+     * 瀹㈡埛鍚嶇О
+     */
+    @Excel(name = "瀹㈡埛鍚嶇О")
+    @TableField(exist = false)
+    private String customerName;
+
+    /**
+     * 褰曞叆浜�
+     */
+    @TableField(exist = false)
+    private String entryPerson;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "褰曞叆浜�")
+    @Excel(name = "褰曞叆浜�")
+    private String entryPersonName;
+
+    /**
+     * 澶囨敞
+     */
+    @Excel(name = "澶囨敞")
+    @TableField(exist = false)
+    private String remarks;
+
+    /**
+     * 闄勪欢鏉愭枡锛屽瓨鍌ㄦ枃浠跺悕绛夌浉鍏充俊鎭�
+     */
+    @TableField(exist = false)
+    private String attachmentMaterials;
+
+
+    /**
+     * 鍚堝悓閲戦锛堜骇鍝佸惈绋庢�讳环锛�
+     */
+    @Excel(name = "鍚堝悓閲戦")
+    @TableField(exist = false)
+    private BigDecimal contractAmount;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "鏈紑绁ㄩ噾棰�(鍏�)")
+    @Excel(name = "鏈紑绁ㄩ噾棰�")
+    private BigDecimal noInvoiceAmountTotal = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "绛捐鏃ユ湡")
+    @TableField(exist = false)
+    private LocalDate executionDate;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "宸插紑绁ㄩ噾棰�(鍏�)")
+    @Excel(name = "宸插紑绁ㄩ噾棰�")
+    private BigDecimal invoiceTotal = BigDecimal.ZERO;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "鍥炴閲戦")
+    private BigDecimal receiptPaymentAmountTotal = BigDecimal.ZERO;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "寰呭洖娆鹃噾棰�")
+    private BigDecimal noReceiptAmount = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "浠樻鏂瑰紡")
+    @TableField(exist = false)
+    private String paymentMethod;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "鐢熶骇鐘舵��")
+    private String productionStatus = "鏈紑濮�";
+}
diff --git a/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java b/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
index 3f80dc0..fce7148 100644
--- a/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
+++ b/src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
@@ -23,7 +23,8 @@
 
     @ApiModelProperty(value = "閿�鍞彴璐d")
     private Long salesLedgerId;
-
+    @ApiModelProperty(value = "閿�鍞姤浠蜂骇鍝佽〃id")
+    private Long salesLedgerProductId;
     @TableField(exist = false)
     @ApiModelProperty(value = "閿�鍞悎鍚屽彿")
     @Excel(name = "閿�鍞悎鍚屽彿")
@@ -64,5 +65,8 @@
     @ApiModelProperty(value = "绉熸埛ID")
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
+    @ApiModelProperty(value = "瀹℃壒浜篿d")
+    @TableField(exist = false)
+    private Integer approverId;
 
 }
diff --git a/src/main/java/com/ruoyi/sales/service/ShipmentApprovalService.java b/src/main/java/com/ruoyi/sales/service/ShipmentApprovalService.java
new file mode 100644
index 0000000..6af2c00
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/service/ShipmentApprovalService.java
@@ -0,0 +1,13 @@
+package com.ruoyi.sales.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.sales.pojo.ShipmentApproval;
+import com.ruoyi.sales.pojo.ShippingInfo;
+
+
+public interface ShipmentApprovalService extends IService<ShipmentApproval>{
+    IPage<ShipmentApproval> listPage(Page page, ShipmentApproval req);
+
+}
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 3d51cb0..1dafbe4 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -4,14 +4,8 @@
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.production.mapper.ProcessRouteItemMapper;
-import com.ruoyi.production.mapper.ProcessRouteMapper;
-import com.ruoyi.production.mapper.ProductOrderMapper;
-import com.ruoyi.production.mapper.ProductProcessRouteItemMapper;
-import com.ruoyi.production.pojo.ProcessRoute;
-import com.ruoyi.production.pojo.ProcessRouteItem;
-import com.ruoyi.production.pojo.ProductOrder;
-import com.ruoyi.production.pojo.ProductProcessRouteItem;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.sales.dto.InvoiceRegistrationProductDto;
@@ -30,6 +24,8 @@
 
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -53,11 +49,14 @@
     private ProductOrderMapper productOrderMapper;
 
     private ProcessRouteItemMapper processRouteItemMapper;
+
     private ProductProcessRouteItemMapper productProcessRouteItemMapper;
-    @Autowired
+
     private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
-    @Autowired
+
     private ProcessRouteMapper processRouteMapper;
+
+    private ProductWorkOrderMapper productWorkOrderMapper;
 
     @Override
     public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -66,11 +65,11 @@
 
     @Override
     public List<SalesLedgerProduct> selectSalesLedgerProductList(SalesLedgerProduct salesLedgerProduct) {
-        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerProduct.getSalesLedgerId())
-                .eq(SalesLedgerProduct::getType, salesLedgerProduct.getType());
-        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(queryWrapper);
-        if (!CollectionUtils.isEmpty(salesLedgerProducts)) {
+//        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
+//        queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerProduct.getSalesLedgerId())
+//                .eq(SalesLedgerProduct::getType, salesLedgerProduct.getType());
+        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectSalesLedgerProductList(salesLedgerProduct);
+        if(!CollectionUtils.isEmpty(salesLedgerProducts)){
             InvoiceRegistrationProductDto invoiceRegistrationProductDto = new InvoiceRegistrationProductDto();
             invoiceRegistrationProductDto.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId().intValue());
             List<InvoiceRegistrationProductDto> invoiceRegistrationProductDtoList = invoiceRegistrationProductMapper.invoiceRegistrationProductList(invoiceRegistrationProductDto);
@@ -80,8 +79,8 @@
                     BigDecimal invoiceNum = BigDecimal.ZERO;
                     BigDecimal invoiceAmount = BigDecimal.ZERO;
                     for (InvoiceRegistrationProductDto registrationProductDto : invoiceRegistrationProductDtoList) {
-                        if (ledgerProduct.getId().intValue() == registrationProductDto.getSalesLedgerProductId()) {
-                            invoiceNum = invoiceNum.add(registrationProductDto.getInvoiceNum());
+                        if(ledgerProduct.getId().intValue() == registrationProductDto.getSalesLedgerProductId()){
+                            invoiceNum =  invoiceNum.add(registrationProductDto.getInvoiceNum());
                             invoiceAmount = invoiceAmount.add(registrationProductDto.getInvoiceAmount());
                         }
                     }
@@ -107,7 +106,7 @@
             return 0; // 娌℃湁鍙垹闄ょ殑鏁版嵁
         }
 
-        // 鍙兘灞炰簬澶氫釜涓昏〃锛堜絾閫氬父涓�涓帴鍙e彧澶勭悊涓�涓富琛級
+        // 鍙兘灞炰簬澶氫釜涓昏〃
         Set<Long> mainIds = deletedProducts.stream()
                 .map(SalesLedgerProduct::getSalesLedgerId)
                 .filter(Objects::nonNull)
@@ -116,12 +115,40 @@
         // 2. 鎵ц鍒犻櫎鎿嶄綔
         int result = salesLedgerProductMapper.deleteBatchIds(Arrays.asList(ids));
         //鍒犻櫎瀵瑰簲鐨勭敓浜ц鍗�
-        for (Long id : ids) {
-            ProductOrder productOrder = productOrderMapper.selectOne(new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getProductModelId, id));
-            if (productOrder != null) {
-                productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>().eq(ProductProcessRouteItem::getRouteId, productOrder.getId()));
-                productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getProductModelId, id));
+        //鎵归噺鏌ヨproductOrder
+        List<ProductOrder> productOrders = productOrderMapper.selectList(
+                new LambdaQueryWrapper<ProductOrder>()
+                        .in(ProductOrder::getProductModelId, ids)
+        );
+
+        if (!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::getRouteId, orderIds)
+            );
+
+            if (!CollectionUtils.isEmpty(allRouteItems)) {
+                List<Long> routeItemIds = allRouteItems.stream()
+                        .map(ProductProcessRouteItem::getId)
+                        .collect(Collectors.toList());
+
+                // 鎵归噺鍒犻櫎workOrder
+                productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
+                                .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
             }
+
+            // 鎵归噺鍒犻櫎processRouteItem
+            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
+                            .in(ProductProcessRouteItem::getRouteId, orderIds));
+
+            // 鎵归噺鍒犻櫎productOrder
+            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
+                    .in(ProductOrder::getProductModelId, ids));
         }
 
         // 3. 瀵规瘡涓富琛↖D杩涜閲戦鏇存柊
@@ -161,12 +188,47 @@
             ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
             if (processRoute != null) {
                 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(productOrder.getProductModelId());
+                    productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                     productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                     productProcessRouteItem.setRouteId(productOrder.getId());
-                    productProcessRouteItemMapper.insert(productProcessRouteItem);
+                    int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
+                    if (insert > 0) {
+                        // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
+                        QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+                        queryWrapper.likeRight("work_order_no", datePrefix)
+                                .orderByDesc("work_order_no")
+                                .last("LIMIT 1");
+
+                        ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+
+                        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 = 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);
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 06d6437..2154217 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -9,7 +9,6 @@
 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.account.pojo.AccountExpense;
 import com.ruoyi.account.pojo.AccountIncome;
 import com.ruoyi.account.service.AccountIncomeService;
 import com.ruoyi.basic.mapper.CustomerMapper;
@@ -24,6 +23,7 @@
 import com.ruoyi.production.pojo.*;
 import com.ruoyi.project.system.domain.SysDept;
 import com.ruoyi.project.system.mapper.SysDeptMapper;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.sales.dto.MonthlyAmountDto;
 import com.ruoyi.sales.dto.SalesLedgerDto;
 import com.ruoyi.sales.mapper.*;
@@ -99,6 +99,16 @@
     private final ProcessRouteItemMapper processRouteItemMapper;
 
     private final ProductProcessRouteItemMapper productProcessRouteItemMapper;
+
+    private final ProductWorkOrderMapper productWorkOrderMapper;
+
+    private final ProductionProductMainMapper productionProductMainMapper;
+
+    private final ProductionProductOutputMapper productionProductOutputMapper;
+
+    private final ProductionProductInputMapper productionProductInputMapper;
+
+    private final QualityInspectMapper qualityInspectMapper;
 
     @Autowired
     private SysDeptMapper sysDeptMapper;
@@ -366,10 +376,85 @@
             return 0;
         }
         // 鍒犻櫎閿�鍞鐞嗘暟鎹�
-        // 1. 鍏堝垹闄ゅ瓙琛ㄦ暟鎹�
-        LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
-        productWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList);
-        salesLedgerProductMapper.delete(productWrapper);
+        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList)
+                .select(SalesLedgerProduct::getId);
+
+        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(queryWrapper);
+        List<Long> productIds = products.stream()
+                .map(SalesLedgerProduct::getId)
+                .collect(Collectors.toList());
+
+        //鎵归噺鏌ヨproductOrder
+        List<ProductOrder> productOrders = productOrderMapper.selectList(
+                new LambdaQueryWrapper<ProductOrder>()
+                        .in(ProductOrder::getProductModelId, 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::getRouteId, orderIds)
+            );
+
+            if (!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 (!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 (!CollectionUtils.isEmpty(productMainIds)) {
+                        productionProductOutputMapper.deleteByProductMainIds(productMainIds);
+                        productionProductInputMapper.deleteByProductMainIds(productMainIds);
+                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
+                    }
+
+                    // 鍒犻櫎鐢熶骇涓昏〃鏁版嵁
+                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
+
+                    // 鍒犻櫎宸ュ崟鏁版嵁
+                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
+                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
+                }
+            }
+            // 鎵归噺鍒犻櫎processRouteItem
+            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
+                    .in(ProductProcessRouteItem::getRouteId, orderIds));
+
+            // 鎵归噺鍒犻櫎productOrder
+            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
+                    .in(ProductOrder::getProductModelId, productIds));
+        }
+
+        // 鎵归噺鍒犻櫎浜у搧瀛愯〃
+        if (!productIds.isEmpty()) {
+            salesLedgerProductMapper.deleteBatchIds(productIds);
+        }
 
         LambdaQueryWrapper<InvoiceRegistrationProduct> wrapper = new LambdaQueryWrapper<>();
         wrapper.in(InvoiceRegistrationProduct::getSalesLedgerId, idList);
@@ -394,7 +479,6 @@
             wrapperTree.in(ReceiptPayment::getInvoiceLedgerId, invoiceLedgerIds);
             receiptPaymentMapper.delete(wrapperTree);
         }
-
 
         // 鍒犻櫎鐢熶骇绠℃帶鏁版嵁
         // 鍒犻櫎鐢熶骇璁㈠崟鏁版嵁
@@ -596,12 +680,48 @@
                 ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
                 if (processRoute != null) {
                     List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
+                    // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
+                    String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+                    int dragSort = 1;
                     for (ProcessRouteItem processRouteItem : processRouteItems) {
                         ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
-                        productProcessRouteItem.setProductModelId(productOrder.getProductModelId());
+                        productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                         productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                         productProcessRouteItem.setRouteId(productOrder.getId());
-                        productProcessRouteItemMapper.insert(productProcessRouteItem);
+                        productProcessRouteItem.setDragSort(dragSort);
+                        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
+                        if (insert > 0) {
+                            // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
+                            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+                            queryWrapper.likeRight("work_order_no", datePrefix)
+                                    .orderByDesc("work_order_no")
+                                    .last("LIMIT 1");
+
+                            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+
+                            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 = 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);
+                        }
+                        dragSort++;
                     }
                     productOrder.setRouteId(processRoute.getId());
                     productOrderMapper.updateById(productOrder);
@@ -659,12 +779,12 @@
 
             return datePart + String.format("%03d", nextSequence);
         } finally {
-            // 3. 閲婃斁閿侊紙浣跨敤Lua鑴氭湰淇濊瘉鍘熷瓙鎬э紝閬垮厤璇垹鍏朵粬绾跨▼鐨勯攣锛�
+            // 3. 閲婃斁閿�
             String luaScript = "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end";
             redisTemplate.execute(
                     new DefaultRedisScript<>(luaScript, Long.class),
                     Collections.singletonList(lockKey),
-                    lockValue // 鍙湁鎸佹湁鐩稿悓鍊肩殑绾跨▼鎵嶈兘鍒犻櫎閿�
+                    lockValue
             );
         }
     }
@@ -673,7 +793,7 @@
         if (sequences.isEmpty()) {
             return 1;
         }
-        // 鎺掑簭鍚庢煡鎵剧涓�涓己澶辩殑姝f暣鏁帮紙涓庡師閫昏緫涓�鑷达級
+        // 鎺掑簭鍚庢煡鎵剧涓�涓己澶辩殑姝f暣鏁�
         sequences.sort(Integer::compareTo);
         int next = 1;
         for (int seq : sequences) {
@@ -703,14 +823,13 @@
                 .filter(Objects::nonNull)
                 .reduce(BigDecimal.ZERO, BigDecimal::add);
 
-        // 鏋勯�犱富琛ㄦ洿鏂板璞★紙鏀寔浠绘剰涓昏〃绫诲瀷锛�
+        // 鏋勯�犱富琛ㄦ洿鏂板璞�
         try {
             S entity = mainEntityClass.getDeclaredConstructor().newInstance();
             Field idField = mainEntityClass.getDeclaredField("id");
             idField.setAccessible(true);
             idField.set(entity, mainId);
 
-            // 璁剧疆 contractAmount 瀛楁锛屾敞鎰忚繖閲屽亣璁惧瓧娈靛悕涓� "contractAmount"
             Field amountField = mainEntityClass.getDeclaredField("contractAmount");
             amountField.setAccessible(true);
             amountField.set(entity, totalAmount);
diff --git a/src/main/java/com/ruoyi/sales/service/impl/ShipmentApprovalServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/ShipmentApprovalServiceImpl.java
new file mode 100644
index 0000000..0df4c34
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/service/impl/ShipmentApprovalServiceImpl.java
@@ -0,0 +1,32 @@
+package com.ruoyi.sales.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.sales.mapper.ShipmentApprovalMapper;
+import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.pojo.ShipmentApproval;
+import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.sales.service.ShipmentApprovalService;
+import com.ruoyi.sales.service.ShippingInfoService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author :yys
+ * @date : 2025/10/22 9:33
+ */
+@Service
+@Slf4j
+public class ShipmentApprovalServiceImpl extends ServiceImpl<ShipmentApprovalMapper, ShipmentApproval> implements ShipmentApprovalService {
+
+    @Autowired
+    private ShipmentApprovalMapper shipmentApprovalMapper;
+
+    @Override
+    public IPage<ShipmentApproval> listPage(Page page, ShipmentApproval req) {
+        IPage<ShipmentApproval> listPage = shipmentApprovalMapper.listPage(page, req);
+        return listPage;
+    }
+}
diff --git a/src/main/resources/mapper/basic/SupplierManageFileMapper.xml b/src/main/resources/mapper/basic/SupplierManageFileMapper.xml
new file mode 100644
index 0000000..265c9a4
--- /dev/null
+++ b/src/main/resources/mapper/basic/SupplierManageFileMapper.xml
@@ -0,0 +1,9 @@
+<?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.basic.mapper.SupplierManageFileMapper">
+    <select id="supplierManageFileListPage" resultType="com.ruoyi.basic.pojo.SupplierManageFile">
+        select *
+        from supplier_manage_file
+        where supplier_id = #{supplierManageFile.supplierId}
+    </select>
+</mapper>
diff --git a/src/main/resources/mapper/basic/SupplierManageMapper.xml b/src/main/resources/mapper/basic/SupplierManageMapper.xml
index 9e65903..ba7fac3 100644
--- a/src/main/resources/mapper/basic/SupplierManageMapper.xml
+++ b/src/main/resources/mapper/basic/SupplierManageMapper.xml
@@ -22,12 +22,16 @@
         T1.update_time,
         T1.update_user,
         T1.tenant_id,
+        T1.is_white,
         T2.nick_name AS maintainUserName
         FROM supplier_manage T1
         LEFT JOIN sys_user T2 ON T1.maintain_user_id = T2.user_id
         <where>
             <if test="supplierManageDto.supplierName != null and supplierManageDto.supplierName != '' ">
                 AND T1.supplier_name LIKE CONCAT('%',#{supplierManageDto.supplierName},'%')
+            </if>
+            <if test="supplierManageDto.isWhite != null">
+                AND T1.is_white = #{supplierManageDto.isWhite}
             </if>
         </where>
     </select>
@@ -50,6 +54,7 @@
         T1.update_time,
         T1.update_user,
         T1.tenant_id,
+        T1.is_white,
         T2.nick_name AS maintainUserName
         FROM supplier_manage T1
         LEFT JOIN sys_user T2 ON T1.maintain_user_id = T2.user_id
@@ -57,6 +62,9 @@
             <if test="supplierManageDto.supplierName != null and supplierManageDto.supplierName != '' ">
                 AND T1.supplier_name LIKE CONCAT('%',#{supplierManageDto.supplierName},'%')
             </if>
+            <if test="supplierManageDto.isWhite != null">
+                AND T1.is_white = #{supplierManageDto.isWhite}
+            </if>
         </where>
     </select>
 
diff --git a/src/main/resources/mapper/device/DeviceRepairMapper.xml b/src/main/resources/mapper/device/DeviceRepairMapper.xml
index d093980..8969d0c 100644
--- a/src/main/resources/mapper/device/DeviceRepairMapper.xml
+++ b/src/main/resources/mapper/device/DeviceRepairMapper.xml
@@ -14,6 +14,7 @@
                 dr.maintenance_name,
                 dr.maintenance_time,
                 dr.maintenance_result,
+                dr.maintenance_price,
                 dr.status,
                 dr.create_time,
                 dr.update_time,
@@ -59,6 +60,7 @@
                dr.maintenance_name,
                dr.maintenance_time,
                dr.maintenance_result,
+               dr.maintenance_price,
                dr.status,
                dr.create_time,
                dr.update_time,
diff --git a/src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml b/src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml
index 2968e9a..611d51e 100644
--- a/src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml
+++ b/src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml
@@ -2,11 +2,12 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper">
     <select id="listPage" resultType="com.ruoyi.measuringinstrumentledger.dto.SparePartsDto">
-        select sp.*,sp1.name as parentName from spare_parts sp
+        select sp.*,sp1.name as parentName
+        from spare_parts sp
         left join spare_parts sp1 on sp1.id = sp.parent_id
         <where>
-            <if test="spareParts.name != null">
-                and name like concat('%',#{spareParts.name},'%')
+            <if test="spareParts.name != null and spareParts.name != ''">
+                and sp.name like concat('%',#{spareParts.name},'%')
             </if>
         </where>
     </select>
diff --git a/src/main/resources/mapper/procurementrecord/ProcurementExceptionRecordMapper.xml b/src/main/resources/mapper/procurementrecord/ProcurementExceptionRecordMapper.xml
new file mode 100644
index 0000000..3363ce7
--- /dev/null
+++ b/src/main/resources/mapper/procurementrecord/ProcurementExceptionRecordMapper.xml
@@ -0,0 +1,5 @@
+<?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.procurementrecord.mapper.ProcurementExceptionRecordMapper">
+
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
index 6119edd..cffeca8 100644
--- a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -137,6 +137,7 @@
         sum(t1.total_price) as totalPrice,
         sum(t1.inbound_num) as inboundNum,
         sum(t1.inbound_num) as inboundNum0,
+        t1.inbound_num as totalInboundNum,
         t1.create_time,
         t1.update_time,
         t1.create_by,
@@ -171,7 +172,7 @@
                 and t1.create_time &lt;= #{req.endDate}
             </if>
         </where>
-        group by t2.product_category,t2.specification_model,t1.unit_price
+        group by t3.supplier_name,t2.product_category,t2.specification_model,t1.unit_price
         order by t1.create_time desc
     </select>
     <select id="listCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">
diff --git a/src/main/resources/mapper/production/ProductOrderMapper.xml b/src/main/resources/mapper/production/ProductOrderMapper.xml
index df9f8b8..616d12f 100644
--- a/src/main/resources/mapper/production/ProductOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -14,7 +14,7 @@
         <result property="updateTime" column="update_time"/>
     </resultMap>
     <select id="pageProductOrder" resultType="com.ruoyi.production.dto.ProductOrderDto">
-        select po.*,sl.sales_contract_no,sl.project_name,sl.customer_name,slp.product_category,slp.specification_model
+        select po.*,sl.sales_contract_no,sl.customer_name,slp.product_category,slp.specification_model
         from product_order po
         left join sales_ledger sl on po.sales_ledger_id = sl.id
         left join sales_ledger_product slp on po.product_model_id = slp.id
@@ -25,9 +25,6 @@
             </if>
             <if test="c.salesContractNo != null and c.salesContractNo != ''">
                 and sl.sales_contract_no like concat('%',#{c.salesContractNo},'%')
-            </if>
-            <if test="c.projectName != null and c.projectName != ''">
-                and sl.project_name like concat('%',#{c.projectName},'%')
             </if>
             <if test="c.customerName != null and c.customerName != ''">
                 and sl.customer_name like concat('%',#{c.customerName},'%')
diff --git a/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml b/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
index d1c013d..caa7890 100644
--- a/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
+++ b/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
@@ -21,7 +21,7 @@
                  left join product p on pm.product_id = p.id
                  left join product_process pp on pp.id = ppri.process_id
         where ppri.route_id = #{orderId}
-        order by ppri.id
+        order by ppri.drag_sort
     </select>
 
 
diff --git a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
new file mode 100644
index 0000000..cd5d97e
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -0,0 +1,66 @@
+<?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.production.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.production.dto.ProductWorkOrderDto">
+        SELECT
+        pwo.*,
+        pp.NAME as processName,
+        pm.model,
+        pm.unit,
+        p.product_name AS productName,
+        po.nps_no AS productOrderNpsNo
+        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>
+            <if test="c.workOrderNo != null and c.workOrderNo != ''">
+                pwo.work_order_no like concat('%',#{c.workOrderNo},'%')
+            </if>
+        </where>
+    </select>
+
+    <update id="updatePlanQuantity" parameterType="java.util.Map">
+        UPDATE product_work_order
+        SET
+            report_work = #{reportWork},
+            quantity = #{quantity},
+            plan_quantity = plan_quantity - #{deductQuantity},
+            product_main_id = #{productMainId}
+        WHERE id = #{workOrderId}
+    </update>
+
+    <update id="rollbackPlanQuantity" parameterType="java.lang.Long">
+        UPDATE product_work_order pwo
+        INNER JOIN production_product_main ppm
+        ON pwo.id = ppm.work_order_id
+        AND ppm.id = #{productMainId}
+        INNER JOIN production_product_output ppo
+        ON ppo.product_main_id = ppm.id
+        SET
+        pwo.plan_quantity = pwo.plan_quantity + ppo.quantity,
+        pwo.report_work = 0,
+        pwo.quantity = 0
+        WHERE pwo.id = ppm.work_order_id
+    </update>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductInputMapper.xml b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
index bd92aaf..7d203f3 100644
--- a/src/main/resources/mapper/production/ProductionProductInputMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -2,5 +2,35 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.production.mapper.ProductionProductInputMapper">
 
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductInput">
+        <id property="id" column="id"/>
+        <result property="productMainId" column="product_main_id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="quantity" column="quantity"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+    <select id="listPageProductionProductInputDto" resultType="com.ruoyi.production.dto.ProductionProductInputDto">
+        select ppi.*,
+        pm.model as model,
+        ppm.product_no as productNo
+        from
+        production_product_input ppi
+        left join production_product_main ppm on ppm.id = ppi.product_main_id
+        left join product_model pm on pm.id = ppi.product_model_id
+        <where>
+            <if test="c.productMainId != null and c.productMainId > 0">
+                and ppm.id = #{c.productMainId}
+            </if>
+        </where>
+        order by ppi.id
+    </select>
 
+    <delete id="deleteByProductMainIds" parameterType="java.util.List">
+        DELETE FROM production_product_input
+        WHERE product_main_id IN
+        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductMainMapper.xml b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
index 24feb0d..3a0542c 100644
--- a/src/main/resources/mapper/production/ProductionProductMainMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -37,4 +37,12 @@
         </where>
         order by ppm.id
     </select>
+
+    <delete id="deleteByWorkOrderIds" parameterType="java.util.List">
+        DELETE FROM production_product_main
+        WHERE work_order_id IN
+        <foreach collection="workOrderIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductOutputMapper.xml b/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
index 790c100..e5d17fc 100644
--- a/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
@@ -2,5 +2,36 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.production.mapper.ProductionProductOutputMapper">
 
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductOutput">
+        <id property="id" column="id"/>
+        <result property="productMainId" column="product_main_id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="quantity" column="quantity"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
 
+    <select id="listPageProductionProductOutputDto" resultType="com.ruoyi.production.dto.ProductionProductOutputDto">
+        select ppo.*,
+        pm.model as model,
+        ppm.product_no as productNo
+        from
+        production_product_output ppo
+        left join production_product_main ppm on ppm.id = ppo.product_main_id
+        left join product_model pm on pm.id = ppo.product_model_id
+        <where>
+            <if test="c.productMainId != null and c.productMainId > 0">
+                and ppm.id = #{c.productMainId}
+            </if>
+        </where>
+        order by ppo.id
+    </select>
+
+    <delete id="deleteByProductMainIds" parameterType="java.util.List">
+        DELETE FROM production_product_output
+        WHERE product_main_id IN
+        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
 </mapper>
diff --git a/src/main/resources/mapper/purchase/ProductRecordMapper.xml b/src/main/resources/mapper/purchase/ProductRecordMapper.xml
index 5c338d7..2c0cba4 100644
--- a/src/main/resources/mapper/purchase/ProductRecordMapper.xml
+++ b/src/main/resources/mapper/purchase/ProductRecordMapper.xml
@@ -28,10 +28,10 @@
         left join product_model pm on pm.id = pr.product_model_id
         WHERE type = 2
         <if test="c.salesContractNo != null and c.salesContractNo != ''">
-            and sl.sales_contract_no = #{c.salesContractNo}
+            and sl.sales_contract_no like concat('%',#{c.salesContractNo},'%')
         </if>
         <if test="c.supplierName != null and c.supplierName != ''">
-            and pl.supplier_name = #{c.supplierName}
+            and pl.supplier_name like concat('%',#{c.supplierName},'%')
         </if>
         <if test="c.createdAtStart != null and c.createdAtStart != ''">
             and pr.created_at &gt;= date_format(#{c.createdAtStart},'%Y-%m-%d hh:mm:ss')
diff --git a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
index 9368d70..b513ac1 100644
--- a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
+++ b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -14,21 +14,30 @@
         pl.id,
         pl.purchase_contract_number ,
         pl.sales_contract_no,
+        pl.supplier_id,
         pl.supplier_name,
         pl.project_name,
         pl.contract_amount,
         sum(pr.tickets_amount)as receipt_payment_amount,
         pl.contract_amount-sum(pr.tickets_amount) AS unReceipt_payment_amount,
         pl.entry_date,
-        pl.execution_date,
+        pl.recorder_id,
         pl.recorder_name,
+        pl.template_name,
+        pl.approver_id,
+        sm.is_white,
+        pl.approval_status,
         pl.payment_method
         from purchase_ledger pl
         left join product_record pr on pl.id = pr.purchase_ledger_id
+        left join supplier_manage sm on pl.supplier_id = sm.id
         <where>
             1 = 1
             <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''">
                and pl.purchase_contract_number like concat('%',#{c.purchaseContractNumber},'%')
+            </if>
+            <if test="c.approvalStatus != null and c.approvalStatus != ''">
+                and pl.approval_status = #{c.approvalStatus}
             </if>
             <if test="c.supplierName != null and c.supplierName != ''">
                 and pl.supplier_name like concat('%',#{c.supplierName},'%')
@@ -51,6 +60,7 @@
         pl.recorder_name,
         pl.contract_amount
         order by pl.entry_date desc
+
     </select>
     <select id="getPaymentRegistrationDtoById" resultType="com.ruoyi.purchase.dto.PaymentRegistrationDto">
         SELECT
diff --git a/src/main/resources/mapper/quality/QualityInspectMapper.xml b/src/main/resources/mapper/quality/QualityInspectMapper.xml
index 8344fc5..4e8a057 100644
--- a/src/main/resources/mapper/quality/QualityInspectMapper.xml
+++ b/src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -8,16 +8,16 @@
         where
         inspect_type=#{qualityInspect.inspectType}
         <if test="qualityInspect.supplier != null and qualityInspect.supplier != '' ">
-            AND supplier = #{qualityInspect.supplier}
+            AND supplier like concat('%',#{qualityInspect.supplier},'%')
         </if>
         <if test="qualityInspect.customer != null and qualityInspect.customer != '' ">
-            AND customer = #{qualityInspect.customer}
+            AND customer like concat('%',#{qualityInspect.customer},'%')
         </if>
         <if test="qualityInspect.process != null and qualityInspect.process != '' ">
-            AND process = #{qualityInspect.process}
+            AND process like concat('%',#{qualityInspect.process},'%')
         </if>
         <if test="qualityInspect.productName != null and qualityInspect.productName != '' ">
-            AND product_name = #{qualityInspect.productName}
+            AND product_name like concat('%',#{qualityInspect.productName},'%')
         </if>
         <if test="qualityInspect.entryDateStart != null and qualityInspect.entryDateStart != '' ">
             AND check_time &gt;= DATE_FORMAT(#{qualityInspect.entryDateStart},'%Y-%m-%d')
@@ -46,4 +46,13 @@
             AND product_name = #{qualityInspect.productName}
         </if>
     </select>
+
+    <delete id="deleteByProductMainIds">
+        DELETE FROM quality_inspect
+        WHERE product_main_id IN
+        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
 </mapper>
diff --git a/src/main/resources/mapper/sales/SalesLedgerMapper.xml b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
index a4949aa..5d83bb1 100644
--- a/src/main/resources/mapper/sales/SalesLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -58,13 +58,10 @@
         T1.contract_amount,
         T1.execution_date,
         T2.nick_name AS entry_person_name,
-        T1.payment_method,
-        t3.shipping_car_number,
-        t3.shipping_date
+        T1.payment_method
         FROM
         sales_ledger T1
         LEFT JOIN sys_user T2 ON T1.entry_person = T2.user_id
-        left join shipping_info t3 on T1.id = t3.sales_ledger_id
         <where>
             <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
                 AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
new file mode 100644
index 0000000..ec8d8d4
--- /dev/null
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -0,0 +1,25 @@
+<?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.sales.mapper.SalesLedgerProductMapper">
+
+    <select id="selectSalesLedgerProductList" resultType="com.ruoyi.sales.pojo.SalesLedgerProduct">
+        SELECT
+        T1.*,
+        t3.shipping_car_number,
+        t3.shipping_date
+        FROM
+        sales_ledger_product T1
+        left join shipping_info t3 on T1.id = t3.sales_ledger_id
+        <where>
+            1=1
+            <if test="salesLedgerProduct.salesLedgerId != null and salesLedgerProduct.salesLedgerId != '' ">
+                AND  T1.sales_ledger_id = #{salesLedgerProduct.salesLedgerId}
+            </if>
+            <if test="salesLedgerProduct.type != null and salesLedgerProduct.type != '' ">
+                AND  T1.type = #{salesLedgerProduct.type}
+            </if>
+        </where>
+    </select>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/sales/ShipmentApprovalMapper.xml b/src/main/resources/mapper/sales/ShipmentApprovalMapper.xml
new file mode 100644
index 0000000..8b9792e
--- /dev/null
+++ b/src/main/resources/mapper/sales/ShipmentApprovalMapper.xml
@@ -0,0 +1,24 @@
+<?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.sales.mapper.ShipmentApprovalMapper">
+
+    <select id="listPage" resultType="com.ruoyi.sales.pojo.ShipmentApproval">
+        SELECT *,
+        si.shipping_car_number,
+        T2.nick_name AS entry_person_name
+        FROM shipment_approval sa
+                 LEFT JOIN shipping_info si ON sa.shipping_info_id = si.id
+                 LEFT JOIN sales_ledger sl ON sa.sales_ledger_id = sl.id
+                 LEFT JOIN sales_ledger_product slp ON sa.sales_ledger_product_id = slp.id
+                 LEFT JOIN sys_user T2 ON sl.entry_person = T2.user_id
+        <where>
+            1=1
+            <if test="req.approveStatus != null and req.approveStatus != '' ">
+                AND  sa.approve_status = #{req.approveStatus}
+            </if>
+            <if test="req.salesContractNo != null and req.salesContractNo != '' ">
+                AND  sl.sales_contract_no LIKE CONCAT('%',#{req.salesContractNo},'%')
+            </if>
+        </where>
+    </select>
+</mapper>
\ No newline at end of file

--
Gitblit v1.9.3