From 34e986e6e158450ee35319f1cac872a4bc974a74 Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期五, 16 一月 2026 18:02:41 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/main/resources/mapper/sales/InvoiceRegistrationProductMapper.xml                        |    4 
 src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java            |    4 
 src/main/resources/mapper/production/ProductProcessMapper.xml                               |    6 
 src/main/java/com/ruoyi/production/dto/ProductOrderDto.java                                 |   32 
 src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java                         |    2 
 src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java            |   32 
 src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java                    |    4 
 src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml                                 |    6 
 doc/20260116_create_table_staff_contract.sql                                                |   13 
 src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java                             |   14 
 src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java                              |    8 
 src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java                       |    9 
 src/main/java/com/ruoyi/purchase/dto/ProductRecordDto.java                                  |   18 
 src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java                                 |    2 
 src/main/java/com/ruoyi/purchase/service/IProductRecordService.java                         |    2 
 src/main/resources/mapper/production/ProcessRouteMapper.xml                                 |    3 
 src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java                       |   15 
 src/main/resources/mapper/production/ProductOrderMapper.xml                                 |   55 
 src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java                     |    4 
 src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java                             |    6 
 src/main/java/com/ruoyi/staff/service/StaffLeaveService.java                                |    7 
 src/main/java/com/ruoyi/purchase/service/impl/ProductRecordServiceImpl.java                 |   18 
 src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java              |    9 
 src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java                |   93 +
 src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java                               |    9 
 src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java                             |   26 
 src/main/java/com/ruoyi/staff/pojo/StaffLeave.java                                          |   35 
 doc/20260116_create_table_staff_leave.sql                                                   |   13 
 src/main/java/com/ruoyi/purchase/controller/TicketRegistrationController.java               |    8 
 src/main/java/com/ruoyi/staff/service/impl/StaffContractServiceImpl.java                    |   23 
 src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java                    |   21 
 src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java                          |    8 
 src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java                        |    5 
 src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java              |    7 
 src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml                     |   23 
 src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java                |    2 
 src/main/resources/mapper/production/ProductWorkOrderMapper.xml                             |   29 
 src/main/resources/mapper/production/ProductionProductInputMapper.xml                       |    5 
 src/main/java/com/ruoyi/staff/pojo/StaffContract.java                                       |   49 
 src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java               |   25 
 src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java                                  |   11 
 src/main/java/com/ruoyi/production/pojo/ProductBom.java                                     |   72 +
 src/main/java/com/ruoyi/production/service/ProductBomService.java                           |   24 
 src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java                      |    2 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java               |   24 
 src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java       |   16 
 src/main/java/com/ruoyi/production/controller/ProcessRouteController.java                   |    8 
 src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java              |   25 
 src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordOutService.java          |    2 
 src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java                  |   27 
 src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java                 |   96 +
 src/main/java/com/ruoyi/staff/mapper/StaffContractMapper.java                               |   25 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java       |  273 ++--
 src/main/java/com/ruoyi/purchase/mapper/ProductRecordMapper.java                            |    4 
 src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java    |   36 
 src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java                        |   14 
 src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java        |  188 --
 src/main/java/com/ruoyi/production/controller/SalesLedgerWorkController.java                |    1 
 src/main/java/com/ruoyi/production/dto/ProductBomDto.java                                   |   18 
 src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java                       |    6 
 src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml                      |    2 
 src/main/resources/mapper/production/ProductStructureMapper.xml                             |   21 
 src/main/resources/mapper/production/ProductionProductMainMapper.xml                        |   13 
 src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java                               |    5 
 src/main/resources/mapper/production/ProductProcessRouteMapper.xml                          |   26 
 src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java            |   63 +
 src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java                 |    4 
 src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java                                        |   16 
 src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java                  |   18 
 src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java            |   18 
 src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java                       |  111 +
 src/main/java/com/ruoyi/production/pojo/ProductStructure.java                               |   17 
 src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java                |   75 
 src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java                                  |   10 
 src/main/java/com/ruoyi/production/service/ProductOrderService.java                         |   11 
 src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java                             |    1 
 src/main/java/com/ruoyi/production/controller/ProductStructureController.java               |   21 
 src/main/java/com/ruoyi/production/pojo/ProcessRoute.java                                   |    8 
 src/main/java/com/ruoyi/staff/controller/StaffContractController.java                       |   34 
 src/main/java/com/ruoyi/procurementrecord/dto/ProcurementRecordOutAdd.java                  |    2 
 src/main/resources/mapper/staff/StaffOnJobMapper.xml                                        |    9 
 src/main/java/com/ruoyi/project/system/controller/SysUserController.java                    |    1 
 src/main/resources/mapper/staff/StaffContractMapper.xml                                     |   15 
 src/main/resources/mapper/production/ProcessRouteItemMapper.xml                             |    3 
 src/main/java/com/ruoyi/basic/pojo/ProductModel.java                                        |   14 
 src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordOutController.java    |    7 
 src/main/java/com/ruoyi/production/controller/ProductProcessController.java                 |   19 
 src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java                                  |    3 
 src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java                    |  155 +-
 src/main/java/com/ruoyi/common/config/MybatisHandler.java                                   |    3 
 src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java                     |    9 
 src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java                          |   45 
 src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java                       |    5 
 src/main/java/com/ruoyi/production/pojo/ProductOrder.java                                   |   43 
 src/main/java/com/ruoyi/staff/dto/StaffContractDto.java                                     |    9 
 src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java            |   10 
 src/main/java/com/ruoyi/production/controller/ProductOrderController.java                   |   43 
 src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java             |    5 
 src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordOutServiceImpl.java |    7 
 src/main/java/com/ruoyi/production/controller/ProductBomController.java                     |   87 +
 src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java                               |   46 
 src/main/resources/mapper/purchase/ProductRecordMapper.xml                                  |   13 
 src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java         |   29 
 src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml                  |  166 +-
 src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java                           |    9 
 src/main/java/com/ruoyi/production/controller/SalesLedgerSchedulingController.java          |    1 
 src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java               |    9 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java                      |   43 
 src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java                   |   28 
 src/main/java/com/ruoyi/production/pojo/ProductProcess.java                                 |   17 
 src/main/resources/mapper/production/ProductBomMapper.xml                                   |   48 
 src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java                  |   49 
 src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java                            |   61 +
 src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java     |  189 +++
 src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java                    |   69 
 src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java                                          |   42 
 src/main/java/com/ruoyi/production/service/ProductStructureService.java                     |    4 
 src/main/java/com/ruoyi/staff/service/StaffContractService.java                             |   19 
 src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java               |    2 
 src/main/java/com/ruoyi/production/service/ProductProcessService.java                       |    3 
 120 files changed, 2,555 insertions(+), 786 deletions(-)

diff --git a/doc/20260116_create_table_staff_contract.sql b/doc/20260116_create_table_staff_contract.sql
new file mode 100644
index 0000000..f8fc20a
--- /dev/null
+++ b/doc/20260116_create_table_staff_contract.sql
@@ -0,0 +1,13 @@
+# 鍛樺伐鍚堝悓琛�
+drop table if exists staff_contract;
+create table staff_contract
+(
+    id                  bigint auto_increment primary key,
+    staff_on_job_id     bigint not null default 0 comment '鍛樺伐鍦ㄨ亴id',
+    contract_start_time datetime null comment '鍚堝悓寮�濮嬫椂闂�',
+    contract_end_time   datetime null comment '鍚堝悓缁撴潫鏃堕棿',
+    contract_term       int    not null default 0 comment '鍚堝悓鏈熼檺',
+    tenant_id           bigint not null comment '绉熸埛id',
+    create_time         datetime null comment '褰曞叆鏃堕棿',
+    update_time         datetime null comment '鏇存柊鏃堕棿'
+);
diff --git a/doc/20260116_create_table_staff_leave.sql b/doc/20260116_create_table_staff_leave.sql
new file mode 100644
index 0000000..7e4b1cf
--- /dev/null
+++ b/doc/20260116_create_table_staff_leave.sql
@@ -0,0 +1,13 @@
+#鍛樺伐绂昏亴琛�
+drop table if exists staff_join_leave_record;
+drop table if exists staff_leave;
+create table staff_leave
+(
+    id              bigint auto_increment primary key,
+    staff_on_job_id bigint not null default 0 comment '鍛樺伐鍦ㄨ亴id',
+    reason          varchar(255) null comment '绂昏亴鍘熷洜',
+    remark          text null comment '绂昏亴澶囨敞',
+    tenant_id       bigint not null comment '绉熸埛id',
+    create_time     datetime null comment '褰曞叆鏃堕棿',
+    update_time     datetime null comment '鏇存柊鏃堕棿'
+);
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 5f0860a..48a3e9f 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -19,6 +19,7 @@
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.other.service.impl.TempFileServiceImpl;
 import com.ruoyi.project.system.domain.SysDept;
+import com.ruoyi.project.system.domain.SysNotice;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysDeptMapper;
 import com.ruoyi.project.system.mapper.SysUserMapper;
@@ -65,7 +66,7 @@
     private final ISysNoticeService sysNoticeService;
 
     @Override
-    public void addApprove(ApproveProcessVO approveProcessVO) throws  Exception {
+    public void addApprove(ApproveProcessVO approveProcessVO) throws Exception {
         SysUser sysUser = sysUserMapper.selectUserById(approveProcessVO.getApproveUser());
         SysDept sysDept = sysDeptMapper.selectDeptById(approveProcessVO.getApproveDeptId());
         String[] split = approveProcessVO.getApproveUserIds().split(",");
@@ -73,9 +74,9 @@
                 .map(Long::valueOf)  // 灏嗘瘡涓� String 杞崲涓� Long
                 .collect(Collectors.toList());
         List<SysUser> sysUsers = sysUserMapper.selectUserByIds(longList);
-        if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("瀹℃牳鐢ㄦ埛涓嶅瓨鍦�");
-        if(sysDept == null) throw new RuntimeException("閮ㄩ棬涓嶅瓨鍦�");
-        if(sysUser == null) throw new RuntimeException("鐢宠浜轰笉瀛樺湪");
+        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);
         Long approveId = dailyRedisCounter.incrementAndGetByDb();
         String formattedCount = String.format("%03d", approveId);
@@ -110,28 +111,28 @@
                 .get(0)
                 .getNickName());
         // 璁剧疆鐘舵�佷负閲嶆柊鎻愪氦
-        if(approveProcessVO.getId() != null){
+        if (approveProcessVO.getId() != null) {
             ApproveProcess approveProcess1 = approveProcessMapper.selectById(approveProcessVO.getId());
             approveProcess1.setApproveStatus(4);
             approveProcessMapper.updateById(approveProcess1);
         }
         save(approveProcess);
         //鍒濆鍖栧鎵硅妭鐐�
-        approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(),approveID,approveProcessVO.getApproveDeptId());
+        approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(), approveID, approveProcessVO.getApproveDeptId());
         // 闄勪欢缁戝畾
         tempFileService.migrateTempFilesToFormal(approveProcess.getId(), approveProcessVO.getTempFileIds(), FileNameType.ApproveProcess.getValue());
         /*娑堟伅閫氱煡*/
         String id = approveProcessVO.getApproveUserIds().split(",")[0];
         sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcessVO.getApproveType()),
-                approveID+"娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                approveID + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
                 Arrays.asList(Long.valueOf(id)),
                 approveProcessVO.getApproveDeptId(),
-                "/collaborativeApproval/approvalProcess?approveType="+approveProcessVO.getApproveType()+"&approveId="+approveID);
+                "/collaborativeApproval/approvalProcess?approveType=" + approveProcessVO.getApproveType() + "&approveId=" + approveID);
     }
 
     @Override
     public List<SysDept> selectDeptListByDeptIds(Long[] deptIds) {
-        List<SysDept> sysDeptList =new ArrayList<SysDept>();
+        List<SysDept> sysDeptList = new ArrayList<SysDept>();
         for (Long deptId : deptIds) {
             SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
             sysDeptList.add(sysDept);
@@ -140,8 +141,8 @@
     }
 
     @Override
-    public IPage<ApproveProcess> listAll(Page page,ApproveProcess approveProcess) {
-        IPage<ApproveProcess> approveProcessIPage = approveProcessMapper.listPage(page,approveProcess);
+    public IPage<ApproveProcess> listAll(Page page, ApproveProcess approveProcess) {
+        IPage<ApproveProcess> approveProcessIPage = approveProcessMapper.listPage(page, approveProcess);
         List<ApproveProcess> records = approveProcessIPage.getRecords();
         for (ApproveProcess record : records) {
             List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
@@ -154,15 +155,35 @@
 
     @Override
     public void delApprove(Long[] ids) {
-        for (Long id : ids) {
-            UpdateWrapper<ApproveProcess> queryWrapper = new UpdateWrapper<>();
-            queryWrapper.lambda().set(ApproveProcess::getApproveDelete, 1)
-                    .eq(ApproveProcess::getApproveId, id);
-            update(queryWrapper);
-            // 鍒犻櫎鍏宠仈鐨勫鎵硅妭鐐�
-            approveNodeService.delApproveNodeByApproveId(id);
-        }
+        ApproveProcess approveProcess;
+        for (Long approveId : ids) {
 
+            //  閫昏緫鍒犻櫎瀹℃壒娴佺▼
+            update(new UpdateWrapper<ApproveProcess>()
+                    .lambda()
+                    .set(ApproveProcess::getApproveDelete, 1)
+                    .eq(ApproveProcess::getApproveId, approveId));
+
+            //  鍒犻櫎瀹℃壒鑺傜偣
+            approveNodeService.delApproveNodeByApproveId(approveId);
+
+            //  鍙煡鏈�鏂颁竴鏉″鎵规祦绋�
+            ApproveProcess latestProcess = approveProcessMapper.selectOne(
+                    new LambdaQueryWrapper<ApproveProcess>()
+                            .eq(ApproveProcess::getApproveId, approveId)
+                            .orderByDesc(ApproveProcess::getCreateTime)
+                            .last("LIMIT 1"));
+
+            if (latestProcess == null) {
+                continue;
+            }
+
+            //  鍒犻櫎瀵瑰簲鐨勬秷鎭�氱煡
+            sysNoticeService.remove(new LambdaQueryWrapper<SysNotice>()
+                            .eq(SysNotice::getNoticeTitle, approveProcessType(latestProcess.getApproveType()))
+                            .eq(SysNotice::getSenderId, latestProcess.getApproveUser())
+                            .apply("CAST(notice_content AS CHAR) LIKE CONCAT('%', {0}, '%')", latestProcess.getApproveId()));
+        }
 
     }
 
@@ -183,25 +204,25 @@
     private final ApproveNodeMapper approveNodeMapper;
 
     // 鎶ヤ环瀹℃壒缂栬緫瀹℃牳浜�
-    public void updateApproveUser(ApproveGetAndUpdateVo approveGetAndUpdateVo){
+    public void updateApproveUser(ApproveGetAndUpdateVo approveGetAndUpdateVo) {
         LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
         approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveType, approveGetAndUpdateVo.getApproveType())
                 .eq(ApproveProcess::getApproveReason, approveGetAndUpdateVo.getApproveReason())
                 .last("limit 1");
         ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper);
-        if(approveProcess == null) throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
+        if (approveProcess == null) throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
         String[] split = approveGetAndUpdateVo.getApproveUserIds().split(",");
-        if(split.length == 0){
+        if (split.length == 0) {
             throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
         }
         List<SysUser> sysUsers = sysUserMapper.selectUserByIds(Arrays.asList(split).stream().map(Long::parseLong).collect(Collectors.toList()));
-        if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
+        if (CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
         //瀹℃牳涓笉鍙互缂栬緫瀹℃牳浜�
-        if(approveProcess.getApproveStatus() != 1){
+        if (approveProcess.getApproveStatus() != 1) {
             approveProcess.setApproveUserCurrentId(Long.parseLong(split[0]));
             approveProcess.setApproveUserCurrentName(sysUsers.stream().filter(user -> user.getUserId().equals(Long.parseLong(split[0]))).collect(Collectors.toList()).get(0).getNickName());
         }
-        if(approveGetAndUpdateVo.getApproveStatus() != null){
+        if (approveGetAndUpdateVo.getApproveStatus() != null) {
             approveProcess.setApproveStatus(approveGetAndUpdateVo.getApproveStatus());
         }
         approveProcess.setApproveUserIds(approveGetAndUpdateVo.getApproveUserIds());
@@ -214,14 +235,14 @@
                 .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                 .orderByAsc(ApproveNode::getApproveNodeOrder);
         approveNodeMapper.delete(approveNodeLambdaQueryWrapper);
-        approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(),approveProcess.getApproveId(),approveProcess.getTenantId());
+        approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approveProcess.getApproveId(), approveProcess.getTenantId());
         /*娑堟伅閫氱煡*/
         String id = approveProcess.getApproveUserIds().split(",")[0];
         sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
-                approveProcess.getApproveId()+"娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                approveProcess.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
                 Arrays.asList(Long.valueOf(id)),
                 approveProcess.getApproveDeptId(),
-                "/collaborativeApproval/approvalProcess?approveType="+approveProcess.getApproveType()+"&approveId="+approveProcess.getApproveId());
+                "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
     }
 
 
@@ -233,16 +254,16 @@
         approve.setApproveReason(approveGetAndUpdateVo.getApproveReason());
         SysUser sysUser = sysUserMapper.selectUserById(approveGetAndUpdateVo.getApproveUser());
         String[] split = approveGetAndUpdateVo.getApproveUserIds().split(",");
-        if(split.length == 0){
+        if (split.length == 0) {
             throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
         }
         List<SysUser> sysUsers = sysUserMapper.selectUserByIds(Arrays.asList(split).stream().map(Long::parseLong).collect(Collectors.toList()));
-        if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
-        if(sysUser == null) throw new RuntimeException("鐢宠浜轰笉瀛樺湪");
+        if (CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("璇烽�夋嫨瀹℃壒浜�");
+        if (sysUser == null) throw new RuntimeException("鐢宠浜轰笉瀛樺湪");
         approve.setApproveUserName(sysUser.getNickName());
         approve.setApproveUser(sysUser.getUserId());
         //瀹℃牳涓笉鍙互缂栬緫瀹℃牳浜�
-        if(approve.getApproveStatus() != 1){
+        if (approve.getApproveStatus() != 1) {
             approve.setApproveUserCurrentId(Long.parseLong(split[0]));
             approve.setApproveUserCurrentName(sysUsers.stream().filter(user -> user.getUserId().equals(Long.parseLong(split[0]))).collect(Collectors.toList()).get(0).getNickName());
         }
@@ -255,7 +276,7 @@
                 .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                 .orderByAsc(ApproveNode::getApproveNodeOrder);
         approveNodeMapper.delete(approveNodeLambdaQueryWrapper);
-        approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(),approve.getApproveId(),approve.getTenantId());
+        approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approve.getApproveId(), approve.getTenantId());
 
 //        int i = 0;
 //        for (ApproveNode approveNode : list) {
@@ -277,17 +298,17 @@
         /*娑堟伅閫氱煡*/
         String id = approve.getApproveUserIds().split(",")[0];
         sysNoticeService.simpleNoticeByUser(approveProcessType(approve.getApproveType()),
-                approve.getApproveId()+"娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                approve.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
                 Arrays.asList(Long.valueOf(id)),
                 approve.getApproveDeptId(),
-                "/collaborativeApproval/approvalProcess?approveType="+approve.getApproveType()+"&approveId="+approve.getApproveId());
+                "/collaborativeApproval/approvalProcess?approveType=" + approve.getApproveType() + "&approveId=" + approve.getApproveId());
 
     }
 
 
     //瀹℃壒绫诲瀷鑾峰彇(涓庡墠绔〉闈㈠搴�)
-    private String approveProcessType(Integer approveType){
-        switch (approveType){
+    private String approveProcessType(Integer approveType) {
+        switch (approveType) {
             case 1:
                 return "鍏嚭绠$悊";
             case 2:
@@ -305,7 +326,6 @@
         }
         return null;
     }
-
 
 
 }
diff --git a/src/main/java/com/ruoyi/basic/pojo/ProductModel.java b/src/main/java/com/ruoyi/basic/pojo/ProductModel.java
index 3997459..3e4fef7 100644
--- a/src/main/java/com/ruoyi/basic/pojo/ProductModel.java
+++ b/src/main/java/com/ruoyi/basic/pojo/ProductModel.java
@@ -5,6 +5,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.math.BigDecimal;
+
 @Data
 @TableName("product_model")
 public class ProductModel {
@@ -27,9 +29,6 @@
     @Excel(name = "浜у搧鍚嶇О")
     private String productName;
 
-    @Excel(name = "浜у搧缂栫爜")
-    private String productCode;
-
     /**
      * 瑙勬牸鍨嬪彿
      */
@@ -51,4 +50,13 @@
     @ApiModelProperty(value = "绉熸埛ID")
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
+    @TableField(exist = false)
+    @Excel(name = "鍏ュ簱鏁伴噺")
+    private BigDecimal inboundNum;
+    @TableField(exist = false)
+    @Excel(name = "鍑哄簱鏁伴噺")
+    private BigDecimal outboundNum;
+    @TableField(exist = false)
+    @Excel(name = "鍓╀綑搴撳瓨")
+    private BigDecimal stockQuantity;
 }
diff --git a/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
index bc3840f..cf9ef84 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
@@ -48,14 +48,7 @@
         if (productModelDto.getId() == null) {
             ProductModel productModel = new ProductModel();
             BeanUtils.copyProperties(productModelDto,productModel);
-            productModelMapper.insert(productModel);
-
-            String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
-            String idStr = String.format("%06d", productModel.getId()); // 鍏綅琛�0
-            String newProductCode = "BM" + dateStr + idStr;
-            // 鏇存柊鏁版嵁搴撲腑鐨刾roductCode
-            productModel.setProductCode(newProductCode);
-            return productModelMapper.updateById(productModel);
+            return productModelMapper.insert(productModel);
         } else {
             return productModelMapper.updateById(productModelDto);
         }
diff --git a/src/main/java/com/ruoyi/common/config/MybatisHandler.java b/src/main/java/com/ruoyi/common/config/MybatisHandler.java
index 71d9b56..adfaf53 100644
--- a/src/main/java/com/ruoyi/common/config/MybatisHandler.java
+++ b/src/main/java/com/ruoyi/common/config/MybatisHandler.java
@@ -18,7 +18,6 @@
             tenantId = SecurityUtils.getLoginUser().getTenantId();
         } catch (Exception ignored) {
         }
-        System.out.println("鎵ц鎻掑叆濉厖...");
         this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
         this.strictInsertFill(metaObject, "updateTime",  LocalDateTime.class, LocalDateTime.now());
         this.strictInsertFill(metaObject, "createUser", Integer.class, userId);
@@ -36,4 +35,4 @@
         this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 璧峰鐗堟湰 3.3.0(鎺ㄨ崘)
         this.strictUpdateFill(metaObject, "updateUser", Integer.class, userId);
     }
-}
\ No newline at end of file
+}
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 58b6c06..56ca983 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -514,9 +514,9 @@
         List<ProductOrderDto> productOrderDtoList = new ArrayList<>();
         productOrderList.forEach(productOrder -> {
             ProductOrderDto productOrderDto = productOrderMapper.productMainByOrderId(productOrder);
-            if (productOrderDto != null && productOrderDto.getPlanQuantity() != null && productOrderDto.getQuantity() != null) {
-                productOrderDto.setCompletionStatus(BigDecimal.valueOf(productOrderDto.getPlanQuantity()-productOrderDto.getQuantity()).divide(BigDecimal.valueOf(productOrderDto.getPlanQuantity()), 2, RoundingMode.HALF_UP));
-            }
+//            if (productOrderDto != null && productOrderDto.getPlanQuantity() != null && productOrderDto.getQuantity() != null) {
+//                productOrderDto.setCompletionStatus((productOrderDto.getPlanQuantity().subtract(productOrderDto.getQuantity())).divide(productOrderDto.getPlanQuantity(), 2, RoundingMode.HALF_UP));
+//            }
             productOrderDtoList.add(productOrderDto);
         });
         productionProgressDto.setCompletedOrderDetails(productOrderDtoList);
@@ -525,7 +525,7 @@
 
         // 2. 鍒濆鍖栨眹鎬绘暟鎹�
         int totalCount = productOrderDtoIPage.getRecords().size();
-        int completedCount = (int) productOrderDtoIPage.getRecords().stream().map(productOrderDto -> productOrderMapper.productMainByOrderId(productOrderDto)).filter(productOrderDto1 -> productOrderDto1.getQuantity() != null && productOrderDto1.getQuantity() == 0).count();
+        int completedCount = (int) productOrderDtoIPage.getRecords().stream().map(productOrderDto -> productOrderMapper.productMainByOrderId(productOrderDto)).filter(productOrderDto1 -> productOrderDto1.getQuantity() != null && productOrderDto1.getQuantity().compareTo(BigDecimal.ZERO) == 0).count();
 
         // 6. 璧嬪�兼眹鎬绘暟鎹�
         productionProgressDto.setTotalOrderCount(totalCount);
diff --git a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
index 1795c15..5234b3f 100644
--- a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
+++ b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
@@ -132,6 +133,14 @@
         return AjaxResult.success(result);
     }
 
+    @GetMapping("/listPageByProductProduction")
+    @Log(title = "鐢熶骇鍏ュ簱-鍏ュ簱绠$悊-鐢熶骇鍏ュ簱鏌ヨ", businessType = BusinessType.OTHER)
+    @ApiOperation(value = "鍏ュ簱鏌ヨ")
+    public AjaxResult listPageByProductProduction(Page page, ProcurementPageDto procurementDto) {
+        IPage<ProcurementPageDto> result = procurementRecordService.listPageByProductProduction(page, procurementDto);
+        return AjaxResult.success(result);
+    }
+
     @GetMapping("/listPageByCustom")
     @Log(title = "鑷畾涔夊叆搴�-鍏ュ簱绠$悊-鍏ュ簱鏌ヨ", businessType = BusinessType.OTHER)
     @ApiOperation(value = "鍏ュ簱鏌ヨ")
@@ -226,5 +235,10 @@
         util.exportExcel(response, customStorages, "鍏ュ簱鍙拌处");
     }
 
-
+    @GetMapping("/listPageProductionStock")
+    @Log(title = "搴撳瓨绠$悊-鎴愬搧搴撳瓨", businessType = BusinessType.OTHER)
+    public AjaxResult listPageProductionStock(Page page) {
+        IPage<ProductModel> result = procurementRecordService.listPageProductionStock(page);
+        return AjaxResult.success(result);
+    }
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordOutController.java b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordOutController.java
index 5245149..1fb594b 100644
--- a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordOutController.java
+++ b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordOutController.java
@@ -52,6 +52,13 @@
         return AjaxResult.success(result);
     }
 
+    @GetMapping("/listPageBySemiProduct")
+    @Log(title = "鐢熶骇鍑哄簱-鍑哄簱鍙拌处-鍑哄簱鏌ヨ", businessType = BusinessType.OTHER)
+    public AjaxResult listPageBySemiProduct(Page page, ProcurementRecordOutPageDto procurementDto) {
+        IPage<ProcurementRecordOutPageDto> result = procurementRecordOutService.listPageBySemiProduct(page, procurementDto);
+        return AjaxResult.success(result);
+    }
+
     @GetMapping("/listPageByCustom")
     @Log(title = "鑷畾涔夊嚭搴�-鍑哄簱鍙拌处-鍑哄簱鏌ヨ", businessType = BusinessType.OTHER)
     public AjaxResult listPageByCustom(Page page, ProcurementRecordOutPageDto procurementDto) {
diff --git a/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementRecordOutAdd.java b/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementRecordOutAdd.java
index 78a2f04..58fba64 100644
--- a/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementRecordOutAdd.java
+++ b/src/main/java/com/ruoyi/procurementrecord/dto/ProcurementRecordOutAdd.java
@@ -17,7 +17,7 @@
 
     private Integer userId;
 
-    private Integer salesLedgerProductId;
+    private Long salesLedgerProductId;
 
     /**
      * 鍑哄簱绫诲瀷 1-閲囪喘鍑哄簱 2-閿�鍞嚭搴� 3-鑷畾涔�
diff --git a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java
index 19e76e6..b41cf62 100644
--- a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java
+++ b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java
@@ -44,4 +44,6 @@
     IPage<ProcurementPageDtoCopy> listPagePRS(Page page, @Param("req") ProcurementPageDto procurementDto);
 
     BigDecimal getSumQuantity(@Param("productModelId") Long productModelId);
+
+    IPage<ProcurementPageDto> listPageByProductProduction(Page page, @Param("req") ProcurementPageDto procurementDto);
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java
index bb24eb5..eebd7cc 100644
--- a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java
+++ b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java
@@ -29,4 +29,8 @@
     IPage<ProcurementRecordOutPageDto> listPageByCustom(Page page,@Param("req") ProcurementRecordOutPageDto procurementDto);
 
     BigDecimal getSumQuantity(@Param("productModelId") Long productModelId);
+
+    ProcurementRecordOut selectCode(@Param("format") String format);
+
+    IPage<ProcurementRecordOutPageDto> listPageBySemiProduct(Page page,@Param("req") ProcurementRecordOutPageDto procurementDto);
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java
index 12dc8e9..dfa9756 100644
--- a/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java
+++ b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java
@@ -22,9 +22,9 @@
     private Integer id;
 
     /**
-     * 浜у搧淇℃伅琛╥d锛堣嚜瀹氫箟鍏ュ簱鏃朵负0锛�
+     * 浜у搧淇℃伅琛╥d锛堢敓浜ф墸搴撳瓨鐨勬椂鍊欎娇鐢級
      */
-    private Integer salesLedgerProductId;
+    private Long salesLedgerProductId;
 
     /**
      * 鍏ュ簱id
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordOutService.java b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordOutService.java
index a8fb7eb..31fc05e 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordOutService.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordOutService.java
@@ -27,4 +27,6 @@
     IPage<ProcurementRecordOutPageDto> listPageByProduct(Page page, ProcurementRecordOutPageDto procurementDto);
 
     IPage<ProcurementRecordOutPageDto> listPageByCustom(Page page, ProcurementRecordOutPageDto procurementDto);
+
+    IPage<ProcurementRecordOutPageDto> listPageBySemiProduct(Page page, ProcurementRecordOutPageDto procurementDto);
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
index 8e68c64..4c3ffee 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.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.basic.pojo.ProductModel;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.procurementrecord.dto.*;
 import com.ruoyi.procurementrecord.pojo.CustomStorage;
@@ -58,4 +59,8 @@
 
     BigDecimal getProcurementAmount(Long salesProductId);
     InventoryInformationDto getReportList();
+
+    IPage<ProductModel> listPageProductionStock(Page page);
+
+    IPage<ProcurementPageDto> listPageByProductProduction(Page page, ProcurementPageDto procurementDto);
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordOutServiceImpl.java b/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordOutServiceImpl.java
index b6e215c..1255afd 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordOutServiceImpl.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordOutServiceImpl.java
@@ -69,7 +69,7 @@
         Long aLong = procurementRecordOutMapper.selectCount(procurementRecordLambdaQueryWrapper);
         ProcurementRecordOut.ProcurementRecordOutBuilder procurementRecordOut = ProcurementRecordOut.builder()
                 .procurementRecordStorageId(procurementRecordOutAdd.getId())
-                .code("LS" + dateFormat.format(now) + String.format("%03d", aLong1 + 1))
+                .code("SC" + dateFormat.format(now) + String.format("%03d", aLong1 + 1))
                 .salesLedgerProductId(procurementRecordOutAdd.getSalesLedgerProductId())
                 .inboundBatches(aLong.equals(0L) ? "绗�1鎵规" : "绗�"+ (aLong + 1) + "鎵规")
                 .inboundNum(new BigDecimal(procurementRecordOutAdd.getQuantity()))
@@ -119,4 +119,9 @@
     public IPage<ProcurementRecordOutPageDto> listPageByCustom(Page page, ProcurementRecordOutPageDto procurementDto) {
         return procurementRecordOutMapper.listPageByCustom(page, procurementDto);
     }
+
+    @Override
+    public IPage<ProcurementRecordOutPageDto> listPageBySemiProduct(Page page, ProcurementRecordOutPageDto procurementDto) {
+        return procurementRecordOutMapper.listPageBySemiProduct(page, procurementDto);
+    }
 }
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 d0399a6..35ec34c 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -2,8 +2,11 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.common.utils.OrderUtils;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -17,6 +20,7 @@
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
 import com.ruoyi.procurementrecord.service.ProcurementRecordService;
+import com.ruoyi.procurementrecord.utils.StockUtils;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
@@ -48,6 +52,8 @@
     private final ProcurementRecordOutMapper procurementRecordOutMapper;
 
     private final SalesLedgerProductMapper salesLedgerProductMapper;
+    private final StockUtils stockUtils;
+    private final ProductModelMapper productModelMapper;
 
     @Override
     public List<ProcurementDto> listProcurementBySalesLedgerId(ProcurementDto procurementDto) {
@@ -69,18 +75,18 @@
             List<ProcurementRecordStorage> collect1 = procurementRecordStorages.stream()
                     .filter(procurementRecordStorage -> procurementRecordStorage.getSalesLedgerProductId().equals(dto.getId()))
                     .collect(Collectors.toList());
-            
+
             // 濡傛灉娌℃湁鐩稿叧鐨勫叆搴撹褰曪紝璺宠繃璇ユ潯鏁版嵁
             if(CollectionUtils.isEmpty(collect1)){
                 dto.setQuantity0(dto.getQuantity());
                 continue;
             }
-            
+
             // 璁$畻宸插叆搴撴暟閲忔�诲拰锛屽苟璁剧疆寰呭叆搴撴暟閲�
             BigDecimal totalInboundNum = collect1.stream()
                     .map(ProcurementRecordStorage::getInboundNum)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
-            
+
             // 寰呭叆搴撴暟閲� = 鎬绘暟閲� - 宸插叆搴撴暟閲�
             dto.setQuantity0(dto.getQuantity().subtract(totalInboundNum));
         }
@@ -606,7 +612,7 @@
         List<ProcurementRecordOut> recordOutList = procurementRecordOutMapper.selectList(queryWrapper);
 
         // 2. 鎸塖alesLedgerProductId鍒嗙粍锛岀粺璁℃瘡涓猧d瀵瑰簲鐨勫凡鍑哄簱鏁伴噺鎬诲拰-宸插嚭搴撴暟閲�
-        Map<Integer, BigDecimal> storageIdToTotalOutNumMap = recordOutList.stream()
+        Map<Long, BigDecimal> storageIdToTotalOutNumMap = recordOutList.stream()
                 .collect(Collectors.groupingBy(
                         ProcurementRecordOut::getSalesLedgerProductId,
                         Collectors.reducing(
@@ -758,7 +764,10 @@
             procurementRecordLambdaQueryWrapper.eq(ProcurementRecordStorage::getSalesLedgerProductId, detail.getId())
                     .eq(ProcurementRecordStorage::getType, procurementDto.getType());
             Long aLong = procurementRecordMapper.selectCount(procurementRecordLambdaQueryWrapper);
-
+            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(detail.getId());
+            if (ObjectUtils.isNull(detail.getProductModelId())){
+                detail.setProductModelId(salesLedgerProduct.getProductModelId());
+            }
             ProcurementRecordStorage.ProcurementRecordStorageBuilder procurementRecordBuilder = ProcurementRecordStorage.builder()
                     .salesLedgerProductId(detail.getId())
                     .inboundBatches(aLong.equals(0L) ? "绗�1鎵规("+ procurementDto.getTypeName() +")" : "绗�"+ (aLong + 1) + "鎵规(" + procurementDto.getTypeName() + ")" )
@@ -872,5 +881,22 @@
         }
         return procurementPageDtoCopyIPage;
     }
+    @Override
+    public IPage<ProductModel> listPageProductionStock(Page page) {
+        ProductModel productModel = new ProductModel();
+        IPage<ProductModel> iPage = productModelMapper.listPageProductModel(page, productModel);
+        iPage.getRecords().forEach(item -> {
+            item.setInboundNum(stockUtils.getStockQuantity(item.getId()).get("inboundNum"));
+            item.setOutboundNum(stockUtils.getStockQuantity(item.getId()).get("outboundNum"));
+            item.setStockQuantity(stockUtils.getStockQuantity(item.getId()).get("stockQuantity"));
+        });
+        return iPage;
+    }
+
+    @Override
+    public IPage<ProcurementPageDto> listPageByProductProduction(Page page, ProcurementPageDto procurementDto) {
+        IPage<ProcurementPageDto> procurementPageDtoIPage = procurementRecordMapper.listPageByProductProduction(page, procurementDto);
+        return procurementPageDtoIPage;
+    }
 
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
index ce2cbc9..0d61f87 100644
--- a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -6,6 +6,8 @@
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
 
 @Component
 @RequiredArgsConstructor
@@ -13,12 +15,18 @@
     private final ProcurementRecordOutMapper procurementRecordOutMapper;
     private final ProcurementRecordMapper procurementRecordMapper;
 
-    // 鑾峰彇鍟嗗搧鍓╀綑搴撳瓨
-    public  BigDecimal getStockQuantity(Long productModelId) {
+    // 鑾峰彇鍟嗗搧鍏ュ簱鏁伴噺,鍑哄簱鏁伴噺,鍓╀綑搴撳瓨
+    public Map<String, BigDecimal> getStockQuantity(Long productModelId) {
         // 鍏ュ簱鏁伴噺
         BigDecimal sumQuantity = procurementRecordMapper.getSumQuantity(productModelId);
         // 鍑哄簱鏁伴噺
         BigDecimal outQuantity = procurementRecordOutMapper.getSumQuantity(productModelId);
-        return outQuantity.compareTo(sumQuantity) > 0 ? BigDecimal.ZERO : sumQuantity.subtract(outQuantity);
+        // 鍓╀綑搴撳瓨
+        BigDecimal stockQuantity = outQuantity.compareTo(sumQuantity) > 0 ? BigDecimal.ZERO : sumQuantity.subtract(outQuantity);
+        Map<String, BigDecimal> stockMap = new HashMap<>();
+        stockMap.put("inboundNum", sumQuantity);
+        stockMap.put("outboundNum", outQuantity);
+        stockMap.put("stockQuantity", stockQuantity);
+        return stockMap;
     }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProcessRouteController.java b/src/main/java/com/ruoyi/production/controller/ProcessRouteController.java
index 495ac52..31ff3fb 100644
--- a/src/main/java/com/ruoyi/production/controller/ProcessRouteController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProcessRouteController.java
@@ -1,9 +1,12 @@
 package com.ruoyi.production.controller;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.dto.ProcessRouteDto;
 import com.ruoyi.production.pojo.ProcessRoute;
+import com.ruoyi.production.pojo.ProcessRouteItem;
+import com.ruoyi.production.service.ProcessRouteItemService;
 import com.ruoyi.production.service.ProcessRouteService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -19,6 +22,9 @@
 
     @Autowired
     private ProcessRouteService processRouteService;
+
+    @Autowired
+    private ProcessRouteItemService processRouteItemService;
 
     @GetMapping("page")
     @ApiOperation("鍒嗛〉鏌ヨ")
@@ -39,6 +45,8 @@
     @ApiOperation("鍒犻櫎宸ヨ壓璺嚎")
     @DeleteMapping("/{ids}")
     public R delete(@PathVariable("ids") Long[] ids) {
+        //鍒犻櫎宸ヨ壓璺嚎璇︽儏
+        processRouteItemService.remove(Wrappers.<ProcessRouteItem>lambdaQuery().in(ProcessRouteItem::getRouteId,Arrays.asList(ids)));
         return R.ok(processRouteService.removeBatchByIds(Arrays.asList(ids)));
     }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java b/src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java
index 4fec36e..451548d 100644
--- a/src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java
@@ -1,14 +1,20 @@
 package com.ruoyi.production.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 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.domain.AjaxResult;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.dto.ProcessRouteItemDto;
+import com.ruoyi.production.pojo.ProcessRoute;
 import com.ruoyi.production.pojo.ProcessRouteItem;
 import com.ruoyi.production.service.ProcessRouteItemService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.Arrays;
@@ -26,11 +32,22 @@
         return R.ok(processRouteItemService.listProcessRouteItemDto(processRouteItemDto));
     }
 
-
     @PostMapping ()
     @ApiOperation("鏂板淇敼")
-    public R addOrUpdate(@RequestBody ProcessRouteItemDto processRouteItemDto) {
-        processRouteItemService.remove(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRouteItemDto.getRouteId()));
-        return R.ok(processRouteItemService.saveBatch(processRouteItemDto.getProcessRouteItem()));
+    public R addOrUpdate(@RequestBody ProcessRouteItem processRouteItem) {
+        return R.ok(processRouteItemService.saveOrUpdate(processRouteItem));
+    }
+
+    @PostMapping ("/sort")
+    @ApiOperation("鎺掑簭")
+    public R sort(@RequestBody ProcessRouteItem processRouteItem) {
+        return R.ok(processRouteItemService.sort(processRouteItem));
+    }
+
+    @ApiOperation("鍒犻櫎宸ヨ壓璺嚎鏄庣粏")
+    @DeleteMapping("/batchDelete/{id}")
+    @Log(title = "鍒犻櫎", businessType = BusinessType.DELETE)
+    public AjaxResult batchDelete(@PathVariable("id") Long id) {
+        return AjaxResult.success(processRouteItemService.batchDelete(id));
     }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductBomController.java b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
new file mode 100644
index 0000000..b8d9416
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -0,0 +1,87 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+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.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.pojo.ProcessRoute;
+import com.ruoyi.production.pojo.ProductBom;
+import com.ruoyi.production.pojo.ProductProcess;
+import com.ruoyi.production.service.ProcessRouteService;
+import com.ruoyi.production.service.ProductBomService;
+import com.ruoyi.production.service.ProductProcessService;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * BOM涓昏〃 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@RestController
+@RequestMapping("/productBom")
+public class ProductBomController {
+
+    @Autowired
+    private ProductBomService productBomService;
+
+    @Autowired
+    private ProcessRouteService processRouteService;
+
+    @GetMapping("/listPage")
+    @Log(title = "BOM-鍒嗛〉鏌ヨ", businessType = BusinessType.OTHER)
+    @ApiOperation("BOM-鍒嗛〉鏌ヨ")
+    public AjaxResult listPage(Page page, ProductBomDto productBomDto) {
+        IPage<ProductBomDto> listPage = productBomService.listPage(page, productBomDto);
+        return AjaxResult.success(listPage);
+    }
+
+    @ApiModelProperty("鏂板BOM")
+    @PostMapping("/add")
+    @Log(title = "鏂板", businessType = BusinessType.INSERT)
+    public AjaxResult add( @RequestBody ProductBom productBom) {
+        return productBomService.add(productBom);
+    }
+
+    @ApiOperation("鏇存柊BOM")
+    @Log(title = "淇敼", businessType = BusinessType.UPDATE)
+    @PutMapping("/update")
+    public AjaxResult update(@RequestBody ProductBom productBom) {
+        return AjaxResult.success(productBomService.updateById(productBom));
+    }
+
+    @ApiOperation("鍒犻櫎BOM")
+    @DeleteMapping("/batchDelete")
+    @Log(title = "鍒犻櫎", businessType = BusinessType.DELETE)
+    public AjaxResult batchDelete(@RequestBody List<Integer> ids) {
+        List<ProcessRoute> list = processRouteService.list(Wrappers.<ProcessRoute>lambdaQuery().in(ProcessRoute::getBomId, ids));
+        if (list.size()>0){
+            return AjaxResult.error("璇OM宸茬粡瀛樺湪瀵瑰簲鐨勫伐鑹鸿矾绾�,鏃犳硶杩涜鍒犻櫎");
+        }
+        if(CollectionUtils.isEmpty(ids)){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        return AjaxResult.success(productBomService.removeBatchByIds(ids));
+    }
+
+    @GetMapping("/getByModel")
+    @Log(title = "BOM-鏍规嵁閫夋嫨鐨勮鏍煎瀷鍙穒d鏌ヨ瀛樺湪鐨刡om", businessType = BusinessType.OTHER)
+    @ApiOperation("BOM-鏍规嵁閫夋嫨鐨勮鏍煎瀷鍙穒d鏌ヨ瀛樺湪鐨刡om")
+    public AjaxResult getByModel(Long productModelId) {
+        List<ProductBom> productBoms = productBomService.list(Wrappers.<ProductBom>lambdaQuery().eq(ProductBom::getProductModelId, productModelId));
+        return AjaxResult.success(productBoms);
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
index 15a7ca6..658b40a 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -1,18 +1,26 @@
 package com.ruoyi.production.controller;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.dto.ProductOrderDto;
+import com.ruoyi.production.pojo.ProcessRoute;
 import com.ruoyi.production.pojo.ProductOrder;
 import com.ruoyi.production.service.ProductOrderService;
+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.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
 
 @RequestMapping("productOrder")
 @RestController
+@Api(tags = "鐢熶骇璁㈠崟")
 public class ProductOrderController {
 
     @Autowired
@@ -25,6 +33,35 @@
         return R.ok(productOrderService.pageProductOrder(page, productOrder));
     }
 
+    @ApiOperation("缁戝畾宸ヨ壓璺嚎")
+    @PostMapping("/bindingRoute")
+    public R bindingRoute(@RequestBody ProductOrder productOrder) {
+        return R.ok(productOrderService.bindingRoute(productOrder));
+    }
+
+    @ApiOperation("鏌ヨ瑙勬牸鍨嬪彿瀵瑰簲鐨勫伐鑹鸿矾绾�")
+    @GetMapping("/listProcessRoute")
+    public R listProcessRoute(Long productModelId) {
+        return R.ok(productOrderService.listProcessRoute(productModelId));
+    }
+
+    /**
+     * 瀵煎嚭鐢熶骇璁㈠崟
+     */
+    @Log(title = "鐢熶骇璁㈠崟", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, ProductOrderDto productOrderDto) {
+        List<ProductOrderDto> list;
+        list = productOrderService.pageProductOrder(new Page<>(1, -1), productOrderDto).getRecords();
+        ExcelUtil<ProductOrderDto> util = new ExcelUtil<ProductOrderDto>(ProductOrderDto.class);
+        util.exportExcel(response, list, "鐢熶骇璁㈠崟鏁版嵁");
+    }
+
+    @ApiOperation("鏌ヨ鐢熶骇璁㈠崟瀵瑰簲鐨凚OM")
+    @GetMapping("/listProcessBom")
+    public R listProcessBom(Long orderId) {
+        return R.ok(productOrderService.listProcessBom(orderId));
+    }
 
 
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductProcessController.java b/src/main/java/com/ruoyi/production/controller/ProductProcessController.java
index 77920b2..cff0c60 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductProcessController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductProcessController.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.device.pojo.DeviceRepair;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
@@ -18,7 +19,9 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 @RestController
@@ -66,5 +69,21 @@
     @GetMapping("/list")
     public AjaxResult list() {
         return AjaxResult.success(productProcessService.list());
+        }
+
+    /**
+     * 瀵煎叆宸ュ簭
+     */
+    @Log(title = "宸ュ簭", businessType = BusinessType.IMPORT)
+    @PostMapping("/importData")
+    public AjaxResult importData(MultipartFile file) throws Exception {
+        return productProcessService.importData(file);
+    }
+
+    @PostMapping("/downloadTemplate")
+    @Log(title = "宸ュ簭-涓嬭浇妯℃澘", businessType = BusinessType.EXPORT)
+    public void downloadTemplate(HttpServletResponse response) {
+        ExcelUtil<ProductProcess> util = new ExcelUtil<ProductProcess>(ProductProcess.class);
+        util.importTemplateExcel(response, "宸ュ簭妯℃澘");
     }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java
new file mode 100644
index 0000000..bb1b010
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java
@@ -0,0 +1,18 @@
+package com.ruoyi.production.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@RestController
+@RequestMapping("/productProcessRoute")
+public class ProductProcessRouteController {
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
index beefe5e..2d5231d 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
@@ -2,11 +2,13 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.dto.ProductProcessRouteItemDto;
 import com.ruoyi.production.mapper.*;
 import com.ruoyi.production.pojo.*;
 import com.ruoyi.production.service.ProductProcessRouteItemService;
+import com.ruoyi.production.service.ProductProcessRouteService;
 import com.ruoyi.production.service.ProductWorkOrderService;
 import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.quality.pojo.QualityInspect;
@@ -34,175 +36,43 @@
 @Api(tags = "鐢熶骇宸ヨ壓璺嚎")
 public class ProductProcessRouteItemController {
 
-    private final ProductOrderMapper productOrderMapper;
+
     private ProductProcessRouteItemService productProcessRouteItemService;
-
-    private ProductWorkOrderService productWorkOrderService;
-
-    private ProductWorkOrderMapper productWorkOrderMapper;
-
-    private SalesLedgerProductMapper salesLedgerProductMapper;
-
-    private ProductionProductMainMapper productionProductMainMapper;
-
-    private ProductionProductInputMapper productionProductInputMapper;
-
-    private ProductionProductOutputMapper productionProductOutputMapper;
-
-    private QualityInspectMapper qualityInspectMapper;
-
-    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+    private ProductProcessRouteService productProcessRouteService;
 
     @GetMapping("list")
-    @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓椤圭洰")
+    @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓璺嚎瀛愯〃")
     public R list(Long orderId) {
         return R.ok(productProcessRouteItemService.listItem(orderId));
     }
 
-    @PostMapping("/updateRouteItem")
-    @ApiOperation("鎵归噺鏂板淇敼")
-    @Transactional(rollbackFor = Exception.class)
-    public R addOrUpdate(@RequestBody ProductProcessRouteItemDto processRouteItemDto) {
-
-        ProductOrder productOrder = productOrderMapper.selectById(processRouteItemDto.getRouteId());
-        if (productOrder == null) {
-            return R.fail("鏈壘鍒癐D涓篬" + processRouteItemDto.getRouteId() + "]鐨勪骇鍝佽鍗�");
-        }
-        SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectOne(new LambdaQueryWrapper<SalesLedgerProduct>()
-                .eq(SalesLedgerProduct::getSalesLedgerId, productOrder.getSalesLedgerId()));
-
-        if (salesLedgerProduct == null) {
-            return R.fail("鏈壘鍒伴攢鍞彴璐D涓篬" + productOrder.getSalesLedgerId() + "]鐨勫彴璐︿骇鍝�");
-        }
-
-        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.setPlanQuantity(salesLedgerProduct.getQuantity());
-                    workOrder.setStatus(1);
-                    workOrders.add(workOrder);
-                }
-                result = productWorkOrderService.saveBatch(workOrders);
-            }
-        }
-        if (!toUpdate.isEmpty()) {
-            result = productProcessRouteItemService.updateBatchById(toUpdate) && result;
-        }
-        return R.ok(result);
+    @GetMapping("listMain")
+    @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓璺嚎涓昏〃")
+    public R listMain(Long orderId) {
+        return R.ok(productProcessRouteService.listMain(orderId));
     }
 
-    @DeleteMapping("/deleteRouteItem")
+    @PostMapping("/addRouteItem")
+    @ApiOperation("鏂板鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾胯鎯�")
+    public R addRouteItem(@RequestBody ProductProcessRouteItem productProcessRouteItem) {
+        return productProcessRouteItemService.addRouteItem(productProcessRouteItem);
+    }
+
+    @PostMapping("/updateRouteItem")
+    @ApiOperation("淇敼鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾胯鎯�")
+    public R updateRouteItem(@RequestBody ProductProcessRouteItem productProcessRouteItem) {
+        return R.ok(productProcessRouteItemService.updateById(productProcessRouteItem));
+    }
+
+    @DeleteMapping("/deleteRouteItem/{id}")
     @ApiOperation("鍒犻櫎鐢熶骇宸ヨ壓璺嚎")
-    @Transactional(rollbackFor = Exception.class)
-    public R deleteRouteItem(@RequestBody ProductProcessRouteItemDto processRouteItemDto) {
+    public R deleteRouteItem(@PathVariable("id") Long id) {
+        return productProcessRouteItemService.deleteRouteItem(id);
+    }
 
-        if (processRouteItemDto == null || processRouteItemDto.getId() == null) {
-            return R.fail("鍒犻櫎澶辫触锛氬伐鑹鸿矾绾块」ID涓嶈兘涓虹┖");
-        }
-        Long routeItemId = processRouteItemDto.getId();
-
-        try {
-            // 鏌ヨ宸ュ崟
-            ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectOne(
-                    new LambdaQueryWrapper<ProductWorkOrder>()
-                            .eq(ProductWorkOrder::getProductProcessRouteItemId, routeItemId)
-                            .last("LIMIT 1")
-            );
-            if (productWorkOrder == null) {
-                return R.fail("鍒犻櫎澶辫触锛氭湭鎵惧埌鍏宠仈鐨勭敓浜у伐鍗�");
-            }
-            Long workOrderId = productWorkOrder.getId();
-            Long productOrderId = productWorkOrder.getProductOrderId();
-
-            // 鏌ヨ鐢熶骇涓昏〃
-            List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(
-                    new LambdaQueryWrapper<ProductionProductMain>()
-                            .eq(ProductionProductMain::getWorkOrderId, workOrderId)
-            );
-            if (!productionProductMains.isEmpty()) {
-                // 鎵归噺鍒犻櫎瀛愯〃
-                for (ProductionProductMain main : productionProductMains) {
-                    Long mainId = main.getId();
-                    // 鍒犻櫎鎶曞叆
-                    productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
-                            .eq(ProductionProductInput::getProductMainId, mainId));
-                    // 鍒犻櫎浜у嚭
-                    productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
-                            .eq(ProductionProductOutput::getProductMainId, mainId));
-                    // 鍒犻櫎璐ㄦ
-                    qualityInspectMapper.delete(new LambdaQueryWrapper<QualityInspect>()
-                            .eq(QualityInspect::getProductMainId, mainId));
-                }
-            }
-
-            //  鍒犻櫎鎶ュ伐锛堢敓浜т富琛級
-            productionProductMainMapper.delete(new LambdaQueryWrapper<ProductionProductMain>()
-                    .eq(ProductionProductMain::getWorkOrderId, workOrderId));
-
-            // 鏌ヨ璁㈠崟 + 鍒犻櫎鏍哥畻
-            ProductOrder productOrder = productOrderMapper.selectById(productOrderId);
-            if (productOrder != null && productOrder.getSalesLedgerId() != null) {
-                salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
-                        .eq(SalesLedgerProductionAccounting::getSalesLedgerId, productOrder.getSalesLedgerId()));
-            }
-
-            // 鍒犻櫎鍏宠仈宸ュ崟
-            productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
-                    .eq(ProductWorkOrder::getProductProcessRouteItemId, routeItemId));
-
-            // 鍒犻櫎涓昏〃鏁版嵁
-            boolean removeFlag = productProcessRouteItemService.removeById(routeItemId);
-            if (!removeFlag) {
-                return R.fail("鍒犻櫎澶辫触锛氬伐鑹鸿矾绾块」涓昏〃鏁版嵁涓嶅瓨鍦�");
-            }
-
-            return R.ok();
-        } catch (Exception e) {
-            return R.fail("鍒犻櫎鐢熶骇宸ヨ壓璺嚎澶辫触锛�" + e.getMessage());
-        }
+    @PostMapping ("/sortRouteItem")
+    @ApiOperation("鎺掑簭")
+    public R sortRouteItem(@RequestBody ProductProcessRouteItem productProcessRouteItem) {
+        return R.ok(productProcessRouteItemService.sortRouteItem(productProcessRouteItem));
     }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductStructureController.java b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
index 26594f6..2f99a00 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
@@ -1,7 +1,12 @@
 package com.ruoyi.production.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.domain.AjaxResult;
 import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductProcessDto;
 import com.ruoyi.production.dto.ProductStructureDto;
 import com.ruoyi.production.pojo.ProductStructure;
 import com.ruoyi.production.service.ProductStructureService;
@@ -15,21 +20,21 @@
 
 @RequestMapping("productStructure")
 @RestController
-@Api(tags = "浜у搧缁撴瀯")
+@Api(tags = "BOM")
 public class ProductStructureController {
     @Autowired
     private ProductStructureService productStructureService;
 
 
-    @ApiOperation("鏍规嵁productId鏌ヨ")
-    @GetMapping("/listByproductModelId/{productModelId}")
-    public R listByproductModelId( @PathVariable("productModelId") Long productModelId){
-        return R.ok(productStructureService.listByproductModelId( productModelId));
-    }
-
-    @ApiOperation("鏂板浜у搧缁撴瀯")
+    @ApiOperation("鏂板BOM")
     @PostMapping()
     public R addOrUpdate(@RequestBody ProductStructureDto productStructureDto){
         return R.ok(productStructureService.addProductStructureDto(productStructureDto));
     }
+
+    @ApiOperation("BOM鏌ョ湅璇︽儏")
+    @GetMapping("/listBybomId/{bomId}")
+    public R listBybomId( @PathVariable("bomId") Long bomId){
+        return R.ok(productStructureService.listBybomId(bomId));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
index f595d98..188a701 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
@@ -34,4 +34,13 @@
         return R.ok(productWorkOrderservice.updateProductWorkOrder(productWorkOrderDto));
     }
 
+    /**
+     * pda鏍规嵁浜岀淮鐮佺殑宸ュ崟id鏌ヨ鏁版嵁
+     */
+    @ApiOperation("pda鏍规嵁浜岀淮鐮佺殑宸ュ崟id鏌ヨ鏁版嵁")
+    @GetMapping("/getProductWorkOrderById")
+    public R getProductWorkOrderById(Long id) {
+        return R.ok(productWorkOrderservice.getById(id));
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/production/controller/SalesLedgerSchedulingController.java b/src/main/java/com/ruoyi/production/controller/SalesLedgerSchedulingController.java
index ae73e64..907cd44 100644
--- a/src/main/java/com/ruoyi/production/controller/SalesLedgerSchedulingController.java
+++ b/src/main/java/com/ruoyi/production/controller/SalesLedgerSchedulingController.java
@@ -38,6 +38,7 @@
 @RestController
 @Api(tags = "鐢熶骇璁㈠崟")
 @RequestMapping("/salesLedger/scheduling")
+@Deprecated // 鏍囪璇ョ被宸插純鐢�
 public class SalesLedgerSchedulingController extends BaseController {
 
     @Autowired
diff --git a/src/main/java/com/ruoyi/production/controller/SalesLedgerWorkController.java b/src/main/java/com/ruoyi/production/controller/SalesLedgerWorkController.java
index 4051ecf..d4265bf 100644
--- a/src/main/java/com/ruoyi/production/controller/SalesLedgerWorkController.java
+++ b/src/main/java/com/ruoyi/production/controller/SalesLedgerWorkController.java
@@ -30,6 +30,7 @@
 @RestController
 @Api(tags = "鐢熶骇鎶ュ伐(鎺掍骇璁板綍)")
 @RequestMapping("/salesLedger/work")
+@Deprecated // 鏍囪璇ョ被宸插純鐢�
 public class SalesLedgerWorkController extends BaseController {
 
 
diff --git a/src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java b/src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java
index 5689dae..232a00c 100644
--- a/src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java
@@ -13,4 +13,6 @@
 
     @ApiModelProperty("瑙勬牸")
     private String model;
+
+    private String bomNo;
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java b/src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java
index 450d586..705354c 100644
--- a/src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java
@@ -27,6 +27,5 @@
     private Long productId;
 
 
-    private List<ProcessRouteItem> processRouteItem;
     private String model;
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProductBomDto.java b/src/main/java/com/ruoyi/production/dto/ProductBomDto.java
new file mode 100644
index 0000000..ab695ca
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductBomDto.java
@@ -0,0 +1,18 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductBom;
+import lombok.Data;
+
+import java.util.List;
+
+//鍒嗛〉鏌ヨ鍥炴樉鏁版嵁
+@Data
+public class ProductBomDto extends ProductBom {
+
+    //浜у搧鍚嶇О
+    private String productName;
+
+    //浜у搧瑙勬牸鍨嬪彿
+    private String productModelName;
+
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductOrderDto.java b/src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
index f9fdbbd..b12803d 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
@@ -1,5 +1,7 @@
 package com.ruoyi.production.dto;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import com.ruoyi.production.pojo.ProductOrder;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -7,32 +9,38 @@
 import java.math.BigDecimal;
 
 @Data
+@ExcelIgnoreUnannotated
 public class ProductOrderDto extends ProductOrder {
 
     @ApiModelProperty(value = "閿�鍞悎鍚屽彿")
+    @Excel(name = "閿�鍞悎鍚屽彿")
     private String salesContractNo;
 
     @ApiModelProperty(value = "椤圭洰鍚�")
+    @Excel(name = "椤圭洰鍚�")
     private String projectName;
 
-    @ApiModelProperty(value = "瀹㈡埛鍚�")
+    @ApiModelProperty(value = "瀹㈡埛鍚嶇О")
+    @Excel(name = "瀹㈡埛鍚嶇О")
     private String customerName;
 
     @ApiModelProperty(value = "浜у搧鍚嶇О")
+    @Excel(name = "浜у搧鍚嶇О")
     private String productCategory;
 
     @ApiModelProperty(value = "瑙勬牸")
+    @Excel(name = "瑙勬牸")
     private String specificationModel;
-    @ApiModelProperty(value = "璁″垝鏁伴噺")
-    private Integer planQuantity;
-    @ApiModelProperty(value = "鏁伴噺")
-    private Integer Quantity;
-    @ApiModelProperty(value = "宸ュ崟鍙�")
-    private String workOrderNo;
-    @ApiModelProperty(value = "鏄惁鎶ュ伐")
-    private Integer reportWork;
-    @ApiModelProperty(value = "宸ュ崟鐘舵��")
-    private Integer status;
-    @ApiModelProperty(value = "璁㈠崟瀹屾垚搴�")
+
+    @ApiModelProperty(value = "宸ヨ壓璺嚎缂栧彿")
+    @Excel(name = "宸ヨ壓璺嚎缂栧彿")
+    private String processRouteCode;
+
+    @ApiModelProperty(value = "瀹屾垚鐘舵��")
+    @Excel(name = "瀹屾垚鐘舵��")
     private BigDecimal completionStatus;
+
+    @ApiModelProperty(value = "BOM缂栧彿")
+    @Excel(name = "BOM缂栧彿")
+    private String bomNo;
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java b/src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java
index 80c1fe3..d235ccb 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java
@@ -23,7 +23,5 @@
 
     private String productName;
 
-
-    private List<ProductProcessRouteItem> processRouteItem;
     private String model;
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
index 2191029..f4ebe75 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
@@ -1,9 +1,12 @@
 package com.ruoyi.production.dto;
 
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import com.ruoyi.production.pojo.ProductWorkOrder;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
 
 @EqualsAndHashCode(callSuper = true)
 @Data
@@ -29,4 +32,7 @@
     //鐢熶骇璁㈠崟鍙�
     @ApiModelProperty(value = "鐢熶骇璁㈠崟鍙�")
     private String productOrderNpsNo;
+
+    @ApiModelProperty(value = "瀹屾垚杩涘害")
+    private BigDecimal completionStatus;
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
index 1e6e02e..13bb4a3 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
@@ -11,4 +11,10 @@
 
     @ApiModelProperty(value = "浜у搧鍨嬪彿")
     private String model;
+
+    @ApiModelProperty(value = "浜у搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty(value = "鍗曚綅")
+    private String unit;
 }
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
index cb34380..3e171bc 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -21,9 +21,15 @@
     @ApiModelProperty(value = "鎶ュ伐鏁伴噺")
     private BigDecimal quantity;
 
-    @ApiModelProperty(value = "鏄惁鎶ュ伐")
-    private boolean reportWork;
+    //浜у搧鍚嶇О
+    private String productName;
 
-    @ApiModelProperty(value = "鎶ュ伐id")
-    private Long productMainId;
+    //浜у搧瑙勬牸鍨嬪彿
+    private String productModelName;
+
+    //鍗曚綅
+    private String unit;
+
+    //閿�鍞悎鍚屽彿
+    private String salesContractNo;
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java
new file mode 100644
index 0000000..1183335
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java
@@ -0,0 +1,26 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.pojo.ProductBom;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * BOM涓昏〃 Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@Mapper
+public interface ProductBomMapper extends BaseMapper<ProductBom> {
+
+    IPage<ProductBomDto> listPage(Page page, @Param("c") ProductBomDto productBomDto);
+
+    ProductBomDto getById(@Param("bomId") Long bomId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java
index 9ce5878..94d41f3 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java
@@ -3,10 +3,15 @@
 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.ProductBomDto;
 import com.ruoyi.production.dto.ProductOrderDto;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.pojo.ProcessRoute;
 import com.ruoyi.production.pojo.ProductOrder;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 @Mapper
 public interface ProductOrderMapper extends BaseMapper<ProductOrder> {
@@ -16,4 +21,8 @@
      * 鏍规嵁璁㈠崟ID鏌ヨ宸ュ崟鎶ュ伐
      */
      ProductOrderDto productMainByOrderId(@Param("c") ProductOrder productOrder);
+
+    List<ProcessRoute> listProcessRoute(@Param("productModelId") Long productModelId);
+
+    List<ProductStructureDto> listProcessBom(@Param("orderId") Long orderId);
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java
index 9bf001c..f21c308 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java
@@ -5,8 +5,10 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.production.dto.ProductProcessDto;
 import com.ruoyi.production.pojo.ProductProcess;
+import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+@Mapper
 public interface ProductProcessMapper extends BaseMapper<ProductProcess> {
     IPage<ProductProcessDto> listPage(Page page,@Param("productProcessDto") ProductProcessDto productProcessDto);
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java
new file mode 100644
index 0000000..06ae748
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java
@@ -0,0 +1,21 @@
+package com.ruoyi.production.mapper;
+
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProductProcessRoute;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ *  Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@Mapper
+public interface ProductProcessRouteMapper extends BaseMapper<ProductProcessRoute> {
+
+    ProcessRouteDto listMain(@Param("orderId") Long orderId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
index 0460c75..bd1831f 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
@@ -12,5 +12,8 @@
 
 @Mapper
 public interface ProductStructureMapper  extends BaseMapper<ProductStructure> {
-    List<ProductStructureDto> listByproductModelId(@Param("productModelId") Long productModelId);
+
+    List<ProductStructureDto> listBybomId(@Param("bomId") Long bomId);
+
+    List<ProductStructureDto> listBybomAndProcess(@Param("bomId") Long bomId, @Param("processId") Long processId);
 }
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
index 93f443e..46f988f 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -17,14 +17,5 @@
 
     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);
-
     List<ProductWorkOrderDto> selectProductWorkOrderDtoList();
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProcessRoute.java b/src/main/java/com/ruoyi/production/pojo/ProcessRoute.java
index 88034cb..2eabc15 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProcessRoute.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProcessRoute.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -10,12 +11,14 @@
 
 @TableName("process_route")
 @Data
+@ApiModel(value = "processRoute", description = "宸ヨ壓璺嚎涓昏〃")
 public class ProcessRoute {
 
     @ApiModelProperty(value = "搴忓彿")
     private Long id;
 
     @ApiModelProperty(value = "浜у搧ID")
+    //product_model
     private Long productModelId;
 
     @ApiModelProperty(value = "鎻忚堪")
@@ -30,9 +33,12 @@
     private LocalDateTime createTime;
 
     @ApiModelProperty(value = "鏇存柊鏃堕棿")
-    @TableField(fill = FieldFill.UPDATE)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
     private LocalDateTime updateTime;
 
     @ApiModelProperty(value = "宸ヨ壓璺嚎缂栫爜")
     private String processRouteCode;
+
+    @ApiModelProperty(value = "BOM鐨処D")
+    private Long bomId;
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java b/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
index 66cbfdd..f2ebd44 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
@@ -1,6 +1,7 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -8,6 +9,7 @@
 
 @Data
 @TableName("process_route_item")
+@ApiModel(value = "processRouteItem", description = "宸ヨ壓璺嚎瀛愯〃")
 public class ProcessRouteItem {
 
     @TableId(type = IdType.AUTO)
@@ -32,5 +34,8 @@
     @TableField(fill = FieldFill.UPDATE)
     private LocalDateTime updateTime;
 
+    @ApiModelProperty(value ="鎷栧姩鎺掑簭")
+    private Integer dragSort;
+
 
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductBom.java b/src/main/java/com/ruoyi/production/pojo/ProductBom.java
new file mode 100644
index 0000000..802724a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductBom.java
@@ -0,0 +1,72 @@
+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.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * <p>
+ * BOM涓昏〃
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@Getter
+@Setter
+@TableName("product_bom")
+@ApiModel(value = "ProductBom瀵硅薄", description = "BOM涓昏〃")
+public class ProductBom implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("bom缂栧彿")
+    private String bomNo;
+
+    @ApiModelProperty("浜у搧瑙勬牸id")
+    private Long productModelId;
+
+    @ApiModelProperty("澶囨敞")
+    private String remark;
+
+    @ApiModelProperty("鐗堟湰鍙�")
+    private String version;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("鍒涘缓鑰�")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUser;
+
+    @ApiModelProperty("鏇存柊鑰�")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Long updateUser;
+
+    @ApiModelProperty("绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductOrder.java b/src/main/java/com/ruoyi/production/pojo/ProductOrder.java
index d47062f..c729ea9 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductOrder.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductOrder.java
@@ -1,11 +1,15 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
 @Data
@@ -24,7 +28,7 @@
     private Long salesLedgerId;
 
     /**
-     * 閿�鍞彴璐︿骇鍝乮d
+     * 閿�鍞彴璐︿骇鍝乮d(sales_ledger_product)
      */
     @ApiModelProperty(value = "閿�鍞彴璐︿骇鍝乮d")
     private Long productModelId;
@@ -39,6 +43,7 @@
      * 鐢熶骇璁㈠崟鍙�
      */
     @ApiModelProperty(value = "鐢熶骇璁㈠崟鍙�")
+    @Excel(name = "鐢熶骇璁㈠崟鍙�")
     private String npsNo;
 
     /**
@@ -51,11 +56,45 @@
     //鍒涘缓鏃堕棿
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
     @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "鍒涘缓鏃堕棿")
     private LocalDateTime createTime;
 
     //淇敼鏃堕棿
     @ApiModelProperty(value = "淇敼鏃堕棿")
-    @TableField(fill = FieldFill.UPDATE)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime updateTime;
 
+
+    /**
+     * 闇�姹傛暟閲�
+     */
+    @ApiModelProperty(value = "闇�姹傛暟閲�")
+    @Excel(name = "闇�姹傛暟閲�")
+    private BigDecimal quantity;
+
+    /**
+     * 瀹屾垚鏁伴噺
+     */
+    @ApiModelProperty(value = "瀹屾垚鏁伴噺")
+    @Excel(name = "瀹屾垚鏁伴噺")
+    private BigDecimal completeQuantity;
+
+    @Excel(name = "寮�濮嬫椂闂�")
+    @ApiModelProperty(value = "寮�濮嬫椂闂�")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty(value = "缁撴潫鏃堕棿")
+    @Excel(name = "缁撴潫鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime endTime;
+
+
+
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcess.java b/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
index 21ca82a..d25f9cf 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
@@ -1,7 +1,12 @@
 package com.ruoyi.production.pojo;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.annotations.ApiModel;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -9,6 +14,8 @@
 
 @TableName("product_process")
 @Data
+@ExcelIgnoreUnannotated
+@ApiModel(value = "productProcess", description = "宸ュ簭琛�")
 public class ProductProcess implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -19,34 +26,42 @@
     /**
      * 宸ュ簭鍚嶇О
      */
+    @Excel(name = "宸ュ簭鍚嶇О")
     private String name;
 
     /**
      * 宸ュ簭缂栧彿
      */
+    @Excel(name = "宸ュ簭缂栧彿")
     private String no;
 
     /**
      * 澶囨敞
      */
+    @Excel(name = "澶囨敞")
     private String remark;
 
 
     /**
      * 宸ヨ祫瀹氶
      */
+    @Excel(name = "宸ヨ祫瀹氶")
     private BigDecimal salaryQuota;
 
     /**
      * 鍒涘缓鏃堕棿
      */
     @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime createTime;
 
     /**
      * 淇敼鏃堕棿
      */
-    @TableField(fill = FieldFill.UPDATE)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime updateTime;
 
     /**
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java b/src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java
new file mode 100644
index 0000000..fac6d15
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java
@@ -0,0 +1,61 @@
+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.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@Getter
+@Setter
+@TableName("product_process_route")
+@ApiModel(value = "ProductProcessRoute瀵硅薄", description = "")
+public class ProductProcessRoute implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("浜у搧id")
+    //product_model
+    private Long productModelId;
+
+    @ApiModelProperty("鎻忚堪")
+    private String description;
+
+    @ApiModelProperty("绉熸埛id")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty("褰曞叆鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("鍏宠仈bom鐨刬d")
+    private Long bomId;
+
+    @ApiModelProperty("宸ヨ壓璺嚎缂栫爜")
+    private String processRouteCode;
+
+    @ApiModelProperty("鐢熶骇璁㈠崟鐨刬d")
+    private Long productOrderId;
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java b/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
index fb04df8..4b6762c 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
@@ -14,7 +14,10 @@
     private Long id;
 
     @ApiModelProperty(value = "鐢熶骇璁㈠崟id(product_order_id)")
-    private Long routeId;
+    private Long productOrderId;
+
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾縤d(product_process_route)")
+    private Long productRouteId;
 
     @ApiModelProperty(value = "宸ュ簭id")
     private Long processId;
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductStructure.java b/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
index 8a53b2e..de0d605 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
@@ -1,12 +1,14 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
 import lombok.Data;
 
 import java.math.BigDecimal;
 
 @TableName("product_structure")
 @Data
+@ApiModel(value = "ProductStructure", description = "BOM瀛愯〃")
 public class ProductStructure {
 
     private static final long serialVersionUID = 1L;
@@ -40,20 +42,15 @@
     private String unit;
 
     /**
-     * 鐖剁骇id
-     */
-    private Long parentId;
-
-    /**
-     * 鐩樻暟閲�
-     */
-    private BigDecimal diskQuantity;
-
-    /**
      * 绉熸埛ID
      */
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
 
+    /**
+     * 鍏宠仈BOMid
+     */
+    private Long bomId;
+
 
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java b/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
index f225c45..4efc694 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
@@ -1,8 +1,11 @@
 package com.ruoyi.production.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.io.Serializable;
 import java.math.BigDecimal;
@@ -42,13 +45,17 @@
      */
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
     @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime createTime;
 
     /**
      * 淇敼鏃堕棿
      */
     @ApiModelProperty(value = "淇敼鏃堕棿")
-    @TableField(fill = FieldFill.UPDATE)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime updateTime;
 
     /**
@@ -58,9 +65,9 @@
     private String workOrderNo;
 
     /**
-     * 鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜�
+     * 鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸插畬鎴�
      */
-    @ApiModelProperty(value = "鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸茬敓浜�")
+    @ApiModelProperty(value = "鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸插畬鎴�")
     private Integer status;
 
     /**
@@ -74,48 +81,45 @@
      * 璁″垝寮�濮嬫椂闂�
      */
     @ApiModelProperty(value = "璁″垝寮�濮嬫椂闂�")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate planStartTime;
 
     /**
      * 璁″垝缁撴潫鏃堕棿
      */
     @ApiModelProperty(value = "璁″垝缁撴潫鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate planEndTime;
 
     /**
      * 瀹為檯寮�濮嬫椂闂�
      */
     @ApiModelProperty(value = "瀹為檯寮�濮嬫椂闂�")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate actualStartTime;
 
     /**
      * 瀹為檯缁撴潫鏃堕棿
      */
     @ApiModelProperty(value = "瀹為檯缁撴潫鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate actualEndTime;
 
     /**
-     * 鏄惁鎶ュ伐
+     * 闇�姹傞噺
      */
-    @ApiModelProperty(value = "鏄惁鎶ュ伐")
-    private boolean reportWork;
-
-
-    /**
-     * 璁″垝鏁伴噺
-     */
-    @ApiModelProperty(value = "璁″垝鏁伴噺")
+    @ApiModelProperty(value = "闇�姹傛暟閲�")
     private BigDecimal planQuantity;
 
     /**
-     * 瀹為檯鏁伴噺
+     * 瀹屾垚鏁伴噺
      */
-    @ApiModelProperty(value = "鏁伴噺")
-    private BigDecimal quantity;
+    @ApiModelProperty(value = "瀹屾垚鏁伴噺")
+    private BigDecimal completeQuantity;
 
-    /**
-     * 鎶ュ伐id
-     */
-    @ApiModelProperty(value = "鎶ュ伐id")
-    private Long productMainId;
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
index 3dbe688..2b7a20d 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
@@ -1,8 +1,10 @@
 package com.ruoyi.production.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.time.LocalDateTime;
 
@@ -33,10 +35,14 @@
 
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
     @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime createTime;
 
     @ApiModelProperty(value = "鏇存柊鏃堕棿")
-    @TableField(fill = FieldFill.UPDATE)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime updateTime;
 
     @ApiModelProperty(value = "绉熸埛ID")
diff --git a/src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java b/src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java
index 1872eee..3299048 100644
--- a/src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java
+++ b/src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java
@@ -11,4 +11,8 @@
 
 public interface ProcessRouteItemService extends IService<ProcessRouteItem> {
     List<ProcessRouteItemDto> listProcessRouteItemDto( ProcessRouteItemDto processRouteItemDto);
+
+    int sort(ProcessRouteItem processRouteItem);
+
+    String batchDelete(Long id);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductBomService.java b/src/main/java/com/ruoyi/production/service/ProductBomService.java
new file mode 100644
index 0000000..0736338
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductBomService.java
@@ -0,0 +1,24 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.pojo.ProductBom;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * BOM涓昏〃 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+public interface ProductBomService extends IService<ProductBom> {
+
+    IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto);
+
+    AjaxResult add(ProductBom productBom);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductOrderService.java b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
index 325ec47..78a3de1 100644
--- a/src/main/java/com/ruoyi/production/service/ProductOrderService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -3,11 +3,22 @@
 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.ProductBomDto;
 import com.ruoyi.production.dto.ProductOrderDto;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.pojo.ProcessRoute;
 import com.ruoyi.production.pojo.ProductOrder;
+
+import java.util.List;
 
 
 public interface ProductOrderService extends IService<ProductOrder> {
 
     IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder);
+
+    int bindingRoute(ProductOrder productOrder);
+
+    List<ProcessRoute> listProcessRoute(Long productModelId);
+
+    List<ProductStructureDto> listProcessBom(Long orderId);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java b/src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java
index f527657..c37eea1 100644
--- a/src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java
@@ -1,6 +1,7 @@
 package com.ruoyi.production.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.dto.ProductProcessRouteItemDto;
 import com.ruoyi.production.pojo.ProductProcessRouteItem;
 
@@ -8,4 +9,10 @@
 
 public interface ProductProcessRouteItemService extends IService<ProductProcessRouteItem> {
     List<ProductProcessRouteItemDto> listItem(Long orderId);
+
+    R deleteRouteItem(Long id);
+
+    R addRouteItem(ProductProcessRouteItem productProcessRouteItem);
+
+    int sortRouteItem(ProductProcessRouteItem productProcessRouteItem);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java b/src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java
new file mode 100644
index 0000000..238aa1e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java
@@ -0,0 +1,18 @@
+package com.ruoyi.production.service;
+
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProductProcessRoute;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+public interface ProductProcessRouteService extends IService<ProductProcessRoute> {
+
+    ProcessRouteDto listMain(Long orderId);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductProcessService.java b/src/main/java/com/ruoyi/production/service/ProductProcessService.java
index 42ec232..a5ab6c3 100644
--- a/src/main/java/com/ruoyi/production/service/ProductProcessService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductProcessService.java
@@ -8,6 +8,7 @@
 import com.ruoyi.production.dto.*;
 import com.ruoyi.production.pojo.ProductProcess;
 import com.ruoyi.production.pojo.SalesLedgerScheduling;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.List;
@@ -20,4 +21,6 @@
     IPage<ProductProcessDto> listPage(Page page, ProductProcessDto productProcessDto);
 
     AjaxResult add(ProductProcessDto productProcessDto);
+
+    AjaxResult importData(MultipartFile file);
 }
diff --git a/src/main/java/com/ruoyi/production/service/ProductStructureService.java b/src/main/java/com/ruoyi/production/service/ProductStructureService.java
index c75c150..b85a040 100644
--- a/src/main/java/com/ruoyi/production/service/ProductStructureService.java
+++ b/src/main/java/com/ruoyi/production/service/ProductStructureService.java
@@ -10,8 +10,8 @@
 public interface ProductStructureService extends IService<ProductStructure> {
 
 
-    ProductModelDto listByproductModelId(Long productId);
-
     Boolean addProductStructureDto(ProductStructureDto productStructureDto);
 
+    List<ProductStructureDto> listBybomId(Long bomId);
+
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java
index 86df76a..5614366 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java
@@ -1,6 +1,7 @@
 package com.ruoyi.production.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.production.dto.ProcessRouteItemDto;
@@ -10,11 +11,13 @@
 import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
 @Service
 @AllArgsConstructor
+@Transactional(rollbackFor = Exception.class)
 public class ProcessRouteItemServiceImpl extends ServiceImpl<ProcessRouteItemMapper, ProcessRouteItem> implements ProcessRouteItemService {
 
     @Autowired
@@ -24,4 +27,64 @@
     public List<ProcessRouteItemDto> listProcessRouteItemDto(ProcessRouteItemDto processRouteItemDto) {
         return processRouteItemMapper.listProcessRouteItemDto( processRouteItemDto);
     }
+
+    //鎺掑簭
+    @Override
+    public int sort(ProcessRouteItem processRouteItem) {
+        //鏌ヨ琚敼鍔ㄧ殑杩欐潯鏁版嵁
+        ProcessRouteItem oldProcessRouteItem = processRouteItemMapper.selectById(processRouteItem.getId());
+        //鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+        List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(Wrappers.<ProcessRouteItem>lambdaQuery()
+                .eq(ProcessRouteItem::getRouteId, oldProcessRouteItem.getRouteId())
+                .orderByAsc(ProcessRouteItem::getDragSort));
+        // 鑾峰彇鐩爣浣嶇疆锛堢Щ鍔ㄥ埌绗嚑涓箣鍚庯級
+        Integer targetPosition = processRouteItem.getDragSort();
+        if (targetPosition != null && targetPosition >= 0) {
+            // 绉诲姩鍏冪礌鍒版柊鐨勪綅缃�
+            processRouteItems.remove(oldProcessRouteItem);
+            processRouteItems.add(targetPosition-1, oldProcessRouteItem);
+            // 鏇存柊鎵�鏈夊彈褰卞搷鐨勬帓搴忓瓧娈�
+            for (int i = 0; i < processRouteItems.size(); i++) {
+                ProcessRouteItem item = processRouteItems.get(i);
+                if (!item.getId().equals(oldProcessRouteItem.getId())) {
+                    // 妫�鏌ユ槸鍚﹂渶瑕佹洿鏂版帓搴忓��
+                    if (item.getDragSort() != i+1) {
+                        item.setDragSort(i+1);
+                        processRouteItemMapper.updateById(item);
+                    }
+                } else {
+                    // 鏇存柊鍘熻褰曠殑鏂版帓搴忎綅缃�
+                    oldProcessRouteItem.setDragSort(targetPosition);
+                    processRouteItemMapper.updateById(oldProcessRouteItem);
+                }
+            }
+            return 1;
+        }
+        return 0;
+    }
+
+    @Override
+    public String batchDelete(Long id) {
+        // 鏌ヨ瑕佸垹闄ょ殑鏁版嵁
+        ProcessRouteItem deleteProcessRouteItem = processRouteItemMapper.selectById(id);
+        if (deleteProcessRouteItem == null) {
+            return "鍒犻櫎澶辫触锛屾湭鎵惧埌瀵瑰簲鏁版嵁";
+        }
+        Long routeId = deleteProcessRouteItem.getRouteId();
+        // 鍒犻櫎鎸囧畾鏁版嵁
+        processRouteItemMapper.deleteById(id);
+        // 鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+        List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(Wrappers.<ProcessRouteItem>lambdaQuery()
+                .eq(ProcessRouteItem::getRouteId, routeId)
+                .orderByAsc(ProcessRouteItem::getDragSort));
+        // 閲嶆柊璁剧疆鎺掑簭鍊硷紝浣垮簭鍙疯繛缁�
+        for (int i = 0; i < processRouteItems.size(); i++) {
+            ProcessRouteItem item = processRouteItems.get(i);
+            if (!item.getDragSort().equals(i+1)) {
+                item.setDragSort(i+1);
+                processRouteItemMapper.updateById(item);
+            }
+        }
+        return "鍒犻櫎鎴愬姛";
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
index 9fafe5f..a5427d2 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
@@ -35,7 +35,7 @@
         this.save(processRoute);
         String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
         String idStr = String.format("%06d", processRoute.getId());
-        String newProductCode = "GY" + dateStr + idStr;
+        String newProductCode = "GYLX" + dateStr + idStr;
         // 鏇存柊鏁版嵁搴撲腑鐨刾roductCode
         processRoute.setProcessRouteCode(newProductCode);
         return processRouteMapper.updateById(processRoute);
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
new file mode 100644
index 0000000..d519593
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
@@ -0,0 +1,49 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.pojo.ProductBom;
+import com.ruoyi.production.mapper.ProductBomMapper;
+import com.ruoyi.production.pojo.ProductProcess;
+import com.ruoyi.production.service.ProductBomService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * BOM涓昏〃 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@Service
+public class ProductBomServiceImpl extends ServiceImpl<ProductBomMapper, ProductBom> implements ProductBomService {
+
+    @Autowired
+    private ProductBomMapper productBomMapper;
+
+    @Override
+    public IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto) {
+        return productBomMapper.listPage(page,productBomDto);
+    }
+
+    @Override
+    public AjaxResult add(ProductBom productBom) {
+        boolean save = productBomMapper.insert(productBom) > 0;
+        if (save) {
+            // 鏍规嵁id鐢熸垚no瀛楁锛欸X + 8浣嶆暟瀛楋紙涓嶈冻8浣嶅墠闈㈣ˉ0锛�
+            String no = "BM." + String.format("%05d", productBom.getId());
+            productBom.setBomNo(no);
+            productBomMapper.updateById(productBom);
+            return AjaxResult.success();
+        }
+        return AjaxResult.error();
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
index 26ec8fa..075815c 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -1,22 +1,111 @@
 package com.ruoyi.production.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 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.ProductBomDto;
 import com.ruoyi.production.dto.ProductOrderDto;
-import com.ruoyi.production.mapper.ProductOrderMapper;
-import com.ruoyi.production.pojo.ProductOrder;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.ProcessRouteService;
 import com.ruoyi.production.service.ProductOrderService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
 
 @Service
 public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements ProductOrderService {
 
     @Autowired
     private ProductOrderMapper productOrderMapper;
+
+    @Autowired
+    private ProcessRouteMapper processRouteMapper;
+
+    @Autowired
+    private ProductProcessRouteMapper productProcessRouteMapper;
+
+    @Autowired
+    private ProcessRouteItemMapper processRouteItemMapper;
+
+    @Autowired
+    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+
+    @Autowired
+    private ProductWorkOrderMapper productWorkOrderMapper;
+
+
     @Override
     public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) {
         return productOrderMapper.pageProductOrder(page, productOrder);
     }
+
+    @Override
+    public int bindingRoute(ProductOrder productOrder) {
+        //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎涓昏〃
+        ProcessRoute processRoute = processRouteMapper.selectById(productOrder.getRouteId());
+        ProductProcessRoute productProcessRoute = new ProductProcessRoute();
+        productProcessRoute.setProductModelId(processRoute.getProductModelId());
+        productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
+        productProcessRoute.setProductOrderId(productOrder.getId());
+        productProcessRoute.setBomId(processRoute.getBomId());
+        productProcessRouteMapper.insert(productProcessRoute);
+        //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎瀛愯〃
+        List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
+        // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        for (ProcessRouteItem processRouteItem : processRouteItems) {
+            ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
+            productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
+            productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
+            productProcessRouteItem.setProductOrderId(productOrder.getId());
+            productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
+            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(productOrder.getQuantity());
+                productWorkOrder.setWorkOrderNo(workOrderNoStr);
+                productWorkOrder.setStatus(1);
+                productWorkOrderMapper.insert(productWorkOrder);
+            }
+        }
+        return productOrderMapper.updateById(productOrder);
+    }
+
+    @Override
+    public List<ProcessRoute> listProcessRoute(Long productModelId) {
+        return productOrderMapper.listProcessRoute(productModelId);
+    }
+
+    @Override
+    public List<ProductStructureDto> listProcessBom(Long orderId) {
+        return productOrderMapper.listProcessBom(orderId);
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
index 455b6e5..6c87939 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
@@ -1,23 +1,206 @@
 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.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.production.dto.ProductProcessRouteItemDto;
-import com.ruoyi.production.mapper.ProductProcessRouteItemMapper;
-import com.ruoyi.production.pojo.ProductProcessRouteItem;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
 import com.ruoyi.production.service.ProductProcessRouteItemService;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import lombok.AllArgsConstructor;
+import org.apache.poi.ss.formula.functions.T;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Service
+@Transactional(rollbackFor = Exception.class)
+@AllArgsConstructor
 public class ProductProcessRouteItemServiceImpl extends ServiceImpl<ProductProcessRouteItemMapper, ProductProcessRouteItem> implements ProductProcessRouteItemService {
 
-    @Autowired
+
     private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+
+    private ProductionProductMainMapper productionProductMainMapper;
+
+    private ProductionProductInputMapper productionProductInputMapper;
+
+    private ProductionProductOutputMapper productionProductOutputMapper;
+
+    private QualityInspectMapper qualityInspectMapper;
+
+    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+
+    private ProductWorkOrderMapper productWorkOrderMapper;
+
+    private ProductOrderMapper productOrderMapper;
+
+    private ProductProcessRouteMapper productProcessRouteMapper;
+
+    private SalesLedgerProductMapper salesLedgerProductMapper;
+
+
     @Override
     public List<ProductProcessRouteItemDto> listItem(Long orderId) {
         return productProcessRouteItemMapper.listItem(orderId);
     }
+
+    @Override
+    public R deleteRouteItem(Long id) {
+        Long routeItemId = id;
+        try {
+            // 鏌ヨ宸ュ崟
+            ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectOne(
+                    new LambdaQueryWrapper<ProductWorkOrder>()
+                            .eq(ProductWorkOrder::getProductProcessRouteItemId, routeItemId)
+                            .last("LIMIT 1")
+            );
+            if (productWorkOrder == null) {
+                throw new RuntimeException("鍒犻櫎澶辫触锛氭湭鎵惧埌鍏宠仈鐨勭敓浜у伐鍗�");
+            }
+            Long workOrderId = productWorkOrder.getId();
+            Long productOrderId = productWorkOrder.getProductOrderId();
+            // 鏌ヨ鐢熶骇涓昏〃
+            List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(
+                    new LambdaQueryWrapper<ProductionProductMain>()
+                            .eq(ProductionProductMain::getWorkOrderId, workOrderId)
+            );
+            if (!productionProductMains.isEmpty()) {
+                // 鎵归噺鍒犻櫎瀛愯〃
+                for (ProductionProductMain main : productionProductMains) {
+                    Long mainId = main.getId();
+                    // 鍒犻櫎鎶曞叆
+                    productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
+                            .eq(ProductionProductInput::getProductMainId, mainId));
+                    // 鍒犻櫎浜у嚭
+                    productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
+                            .eq(ProductionProductOutput::getProductMainId, mainId));
+                    // 鍒犻櫎璐ㄦ
+                    qualityInspectMapper.delete(new LambdaQueryWrapper<QualityInspect>()
+                            .eq(QualityInspect::getProductMainId, mainId));
+                }
+            }
+            //  鍒犻櫎鎶ュ伐锛堢敓浜т富琛級
+            productionProductMainMapper.delete(new LambdaQueryWrapper<ProductionProductMain>()
+                    .eq(ProductionProductMain::getWorkOrderId, workOrderId));
+            // 鏌ヨ璁㈠崟 + 鍒犻櫎鏍哥畻
+            ProductOrder productOrder = productOrderMapper.selectById(productOrderId);
+            if (productOrder != null && productOrder.getSalesLedgerId() != null) {
+                salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
+                        .eq(SalesLedgerProductionAccounting::getSalesLedgerId, productOrder.getSalesLedgerId()));
+            }
+            // 鍒犻櫎鍏宠仈宸ュ崟
+            productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
+                    .eq(ProductWorkOrder::getProductProcessRouteItemId, routeItemId));
+
+            // 鍒犻櫎涓昏〃鏁版嵁
+            ProductProcessRouteItem deleteProductProcessRouteItem = productProcessRouteItemMapper.selectById(routeItemId);
+            Long productRouteId = deleteProductProcessRouteItem.getProductRouteId();
+            // 鍒犻櫎鎸囧畾鏁版嵁
+            productProcessRouteItemMapper.deleteById(id);
+            // 鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+            List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery()
+                    .eq(ProductProcessRouteItem::getProductRouteId, productRouteId)
+                    .orderByAsc(ProductProcessRouteItem::getDragSort));
+            // 閲嶆柊璁剧疆鎺掑簭鍊硷紝浣垮簭鍙疯繛缁�
+            for (int i = 0; i < productProcessRouteItems.size(); i++) {
+                ProductProcessRouteItem item = productProcessRouteItems.get(i);
+                if (!item.getDragSort().equals(i + 1)) {
+                    item.setDragSort(i + 1);
+                    productProcessRouteItemMapper.updateById(item);
+                }
+            }
+            return R.ok();
+        } catch (Exception e) {
+            throw new RuntimeException("鍒犻櫎鐢熶骇宸ヨ壓璺嚎澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @Override
+    public R addRouteItem(ProductProcessRouteItem productProcessRouteItem) {
+        ProductOrder productOrder = productOrderMapper.selectById(productProcessRouteItem.getProductOrderId());
+        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
+        // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        if (insert > 0) {
+            // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
+            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+            queryWrapper.likeRight("work_order_no", datePrefix)
+                    .orderByDesc("work_order_no")
+                    .last("LIMIT 1");
+            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+            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(productProcessRouteItem.getProductOrderId());
+            productWorkOrder.setPlanQuantity(productOrder.getQuantity());
+            productWorkOrder.setWorkOrderNo(workOrderNoStr);
+            productWorkOrder.setStatus(1);
+            productWorkOrderMapper.insert(productWorkOrder);
+        }
+        return R.ok();
+    }
+
+    @Override
+    public int sortRouteItem(ProductProcessRouteItem productProcessRouteItem) {
+        //鏌ヨ琚敼鍔ㄧ殑杩欐潯鏁版嵁
+        ProductProcessRouteItem oldProductProcessRouteItem = productProcessRouteItemMapper.selectById(productProcessRouteItem.getId());
+        //鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+        List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery()
+                .eq(ProductProcessRouteItem::getProductRouteId, oldProductProcessRouteItem.getProductRouteId())
+                .orderByAsc(ProductProcessRouteItem::getDragSort));
+        // 鑾峰彇鐩爣浣嶇疆锛堢Щ鍔ㄥ埌绗嚑涓箣鍚庯級
+        Integer targetPosition = productProcessRouteItem.getDragSort();
+        if (targetPosition != null && targetPosition >= 0) {
+            // 绉诲姩鍏冪礌鍒版柊鐨勪綅缃�
+            productProcessRouteItems.remove(oldProductProcessRouteItem);
+            productProcessRouteItems.add(targetPosition-1, oldProductProcessRouteItem);
+            // 鏇存柊鎵�鏈夊彈褰卞搷鐨勬帓搴忓瓧娈�
+            for (int i = 0; i < productProcessRouteItems.size(); i++) {
+                ProductProcessRouteItem item = productProcessRouteItems.get(i);
+                if (!item.getId().equals(oldProductProcessRouteItem.getId())) {
+                    // 妫�鏌ユ槸鍚﹂渶瑕佹洿鏂版帓搴忓��
+                    if (item.getDragSort() != i+1) {
+                        item.setDragSort(i+1);
+                        productProcessRouteItemMapper.updateById(item);
+                    }
+                } else {
+                    // 鏇存柊鍘熻褰曠殑鏂版帓搴忎綅缃�
+                    oldProductProcessRouteItem.setDragSort(targetPosition);
+                    productProcessRouteItemMapper.updateById(oldProductProcessRouteItem);
+                }
+            }
+            return 1;
+        }
+        return 0;
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java
new file mode 100644
index 0000000..f5b2e92
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java
@@ -0,0 +1,29 @@
+package com.ruoyi.production.service.impl;
+
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProductProcessRoute;
+import com.ruoyi.production.mapper.ProductProcessRouteMapper;
+import com.ruoyi.production.service.ProductProcessRouteService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@Service
+public class ProductProcessRouteServiceImpl extends ServiceImpl<ProductProcessRouteMapper, ProductProcessRoute> implements ProductProcessRouteService {
+
+    @Autowired
+    private ProductProcessRouteMapper productProcessRouteMapper;
+
+    @Override
+    public ProcessRouteDto listMain(Long orderId) {
+        return productProcessRouteMapper.listMain(orderId);
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java
index e44ae02..6a8cf73 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java
@@ -1,8 +1,11 @@
 package com.ruoyi.production.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.production.dto.ProductProcessDto;
 import com.ruoyi.production.mapper.ProductProcessMapper;
@@ -11,6 +14,10 @@
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
 
 @Service
 public class ProductProcessServiceImpl extends ServiceImpl<ProductProcessMapper, ProductProcess> implements ProductProcessService {
@@ -27,7 +34,7 @@
         ProductProcess productProcess = new ProductProcess();
         BeanUtils.copyProperties(productProcessDto,productProcess);
         boolean save = productProcessMapper.insert(productProcess) > 0;
-        if (save) {
+        if (save && ObjectUtils.isNotNull(productProcessDto.getNo())) {
             // 鏍规嵁id鐢熸垚no瀛楁锛欸X + 8浣嶆暟瀛楋紙涓嶈冻8浣嶅墠闈㈣ˉ0锛�
             String no = "GX" + String.format("%08d", productProcess.getId());
             productProcess.setNo(no);
@@ -37,4 +44,20 @@
         }
         return AjaxResult.error();
     }
+
+    @Override
+    public AjaxResult importData(MultipartFile file) {
+        try {
+            ExcelUtil<ProductProcess> util = new ExcelUtil<ProductProcess>(ProductProcess.class);
+            List<ProductProcess> productProcessList = util.importExcel(file.getInputStream());
+            if(CollectionUtils.isEmpty(productProcessList)){
+                return AjaxResult.warn("妯℃澘閿欒鎴栧鍏ユ暟鎹负绌�");
+            }
+            this.saveOrUpdateBatch(productProcessList);
+            return AjaxResult.success(true);
+        }catch (Exception e){
+            e.printStackTrace();
+            return AjaxResult.error("瀵煎叆澶辫触");
+        }
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
index b54617f..310a723 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
@@ -1,13 +1,16 @@
 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.extension.service.impl.ServiceImpl;
 import com.ruoyi.basic.dto.ProductModelDto;
+import com.ruoyi.basic.dto.ProductTreeDto;
 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.production.dto.ProductStructureDto;
+import com.ruoyi.production.mapper.ProductBomMapper;
 import com.ruoyi.production.mapper.ProductStructureMapper;
 import com.ruoyi.production.pojo.ProductStructure;
 import com.ruoyi.production.service.ProductStructureService;
@@ -17,7 +20,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.HashMap;
+import java.util.ArrayList;
 import java.util.List;
 
 @Service
@@ -27,29 +30,22 @@
 
     @Autowired
     private  ProductStructureMapper productStructureMapper;
-    @Autowired
-    private ProductModelMapper productModelMapper;
-    @Autowired
-    private ProductMapper productMapper;
 
-    @Override
-    public ProductModelDto listByproductModelId(Long productModelId) {
-        ProductModel productModel = productModelMapper.selectById(productModelId);
-        Product product = productMapper.selectById(productModel.getProductId());
-        ProductModelDto productModelDto = new ProductModelDto();
-        BeanUtils.copyProperties(productModel,productModelDto);
-        productModelDto.setProductName(product.getProductName());
-        List<ProductStructureDto> productStructureDtos = productStructureMapper.listByproductModelId(productModelId);
-        productModelDto.setProductStructureList(productStructureDtos);
-        return productModelDto;
-    }
+
 
     @Override
     public Boolean addProductStructureDto(ProductStructureDto productStructureDto) {
-        this.remove(new QueryWrapper<ProductStructure>().lambda().eq(ProductStructure::getParentId, productStructureDto.getParentId()));
+        this.remove(new QueryWrapper<ProductStructure>().lambda().eq(ProductStructure::getBomId, productStructureDto.getBomId()));
         productStructureDto.getProductStructureList().forEach(productStructure -> {
-            productStructure.setParentId(productStructureDto.getParentId());
+            productStructure.setBomId(productStructureDto.getBomId());
         });
         return this.saveBatch(productStructureDto.getProductStructureList());
     }
+
+    @Override
+    public List<ProductStructureDto> listBybomId(Long bomId) {
+        List<ProductStructureDto> tree = productStructureMapper.listBybomId(bomId);
+        return tree;
+
+    }
 }
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 6c1b7aa..9beb28d 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -5,6 +5,8 @@
 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.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.basic.mapper.ProductMapper;
@@ -13,6 +15,8 @@
 import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
+import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
 import com.ruoyi.procurementrecord.utils.StockUtils;
 import com.ruoyi.production.controller.ProductWorkOrderController;
 import com.ruoyi.production.dto.ProductStructureDto;
@@ -21,21 +25,20 @@
 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.mapper.QualityTestStandardParamMapper;
-import com.ruoyi.quality.pojo.QualityInspect;
-import com.ruoyi.quality.pojo.QualityInspectParam;
-import com.ruoyi.quality.pojo.QualityTestStandard;
-import com.ruoyi.quality.pojo.QualityTestStandardParam;
+import com.ruoyi.project.system.mapper.SysUserMapper;
+import com.ruoyi.quality.mapper.*;
+import com.ruoyi.quality.pojo.*;
+import io.swagger.models.auth.In;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import com.ruoyi.production.mapper.ProductionProductMainMapper;
+import oshi.driver.mac.net.NetStat;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
 import java.util.List;
@@ -43,8 +46,10 @@
 
 @Service
 @AllArgsConstructor
+@Transactional(rollbackFor = Exception.class)
 public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
 
+    private final ProcurementRecordOutMapper procurementRecordOutMapper;
     private ProductionProductMainMapper productionProductMainMapper;
 
     private ProductWorkOrderController productWorkOrderController;
@@ -52,6 +57,7 @@
     private ProductWorkOrderMapper productWorkOrderMapper;
 
     private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+    private SysUserMapper userMapper;
 
     private ProductionProductOutputMapper productionProductOutputMapper;
 
@@ -62,11 +68,13 @@
     private QualityInspectMapper qualityInspectMapper;
 
     private ProductProcessMapper productProcessMapper;
+    private ProductProcessRouteMapper productProcessRouteMapper;
 
     private ProductMapper productMapper;
 
-    private QualityTestStandardMapper qualityTestStandardMapper;
+
     private QualityTestStandardParamMapper qualityTestStandardParamMapper;
+    private QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
 
     private QualityInspectParamMapper qualityInspectParamMapper;
 
@@ -87,41 +95,35 @@
     }
 
     @Override
-    @Transactional(rollbackFor = Exception.class)
     public Boolean addProductMain(ProductionProductMainDto dto) {
-        if (dto == null) {
-            throw new RuntimeException("鍙傛暟涓嶈兘涓虹┖");
-        }
-
-        SysUser user = SecurityUtils.getLoginUser().getUser();
-
-
-
-        // 鏂板閫昏緫
+        SysUser user = userMapper.selectUserById(dto.getUserId());
         ProductionProductMain productionProductMain = new ProductionProductMain();
+        //褰撳墠宸ヨ壓璺嚎瀵瑰簲鐨勫伐搴忚鎯�
         ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId());
         if (productProcessRouteItem == null) {
             throw new RuntimeException("宸ヨ壓璺嚎椤逛笉瀛樺湪");
         }
-
-        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
-
+        //褰撳墠鍏蜂綋宸ュ簭
+        ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId());
+        //宸ヨ壓璺嚎涓綋鍓嶅伐搴忓搴旂殑浜у嚭瑙勬牸鍨嬪彿
+        ProductModel productModel = productModelMapper.selectById(productProcessRouteItem.getProductModelId());
+        //鏌ヨ璇ョ敓浜ц鍗曞搴旂殑bom
+        ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectById(productProcessRouteItem.getProductRouteId());
+        /*鏂板鎶ュ伐涓昏〃*/
+        //鏌ヨ鏈�澶ф姤宸ョ紪鍙�
+        String datePrefix = "BG" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
         QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>();
         queryWrapper.select("MAX(product_no) as maxNo")
                 .likeRight("product_no", datePrefix);
-
         List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper);
-
         int sequenceNumber = 1;
         if (resultList != null && !resultList.isEmpty()) {
             Map<String, Object> result = resultList.get(0);
-
             if (result != null) {
                 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());
@@ -133,91 +135,118 @@
                 }
             }
         }
-
         String productNo = String.format("%s%03d", datePrefix, sequenceNumber);
         productionProductMain.setProductNo(productNo);
-        productionProductMain.setUserId(user.getUserId());
+        productionProductMain.setUserId(dto.getUserId());
+        productionProductMain.setUserName(dto.getUserName());
         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);
+        productionProductMainMapper.insert(productionProductMain);
+        /*鏂板鎶ュ伐鎶曞叆琛�*/
+        List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId());
+        if (productStructureDtos.size() == 0) {
+            //濡傛灉璇ュ伐搴忔病鏈変骇鍝佺粨鏋勭殑鎶曞叆鍝�,閭h繖涓姇鍏ュ搧鍜屼骇鍑哄搧鏄悓涓�涓�
+            ProductStructureDto productStructureDto = new ProductStructureDto();
+            productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId());
+            productStructureDto.setUnitQuantity(BigDecimal.ONE);
+            productStructureDtos.add(productStructureDto);
         }
-        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());
-            qualityInspect.setProductModelId(productModel.getId());
-            qualityInspectMapper.insert(qualityInspect);
-
-            List<QualityTestStandardParam> qualityTestStandardParams = qualityTestStandardParamMapper.selectListByProductId(product.getId());
-            if (qualityTestStandardParams.size()>0) {
-                qualityTestStandardParams.forEach(standard -> {
-                    QualityInspectParam param = new QualityInspectParam();
-                    BeanUtils.copyProperties(standard, param);
-                    param.setId(null);
-                    param.setInspectId(qualityInspect.getId());
-                    qualityInspectParamMapper.insert(param);
-                });
+        for (ProductStructureDto productStructureDto : productStructureDtos) {
+            ProductModel productModel1 = productModelMapper.selectById(productStructureDto.getProductModelId());
+            Product product = productMapper.selectById(productModel1.getProductId());
+            BigDecimal stockQuantity = stockUtils.getStockQuantity(productModel1.getId()).get("stockQuantity");
+            if (!(stockQuantity.compareTo(BigDecimal.ZERO) > 0)) {
+                throw new RuntimeException(product.getProductName() + "搴撳瓨涓�0");
             }
-        }
-        // 娣诲姞鎶曞叆
-        if (productModel != null) {
-            List<ProductStructureDto> productStructureDtos = productStructureMapper.listByproductModelId(productModel.getId());
-            for (ProductStructureDto productStructureDto : productStructureDtos) {
-                ProductModel productModel1 = productModelMapper.selectById(productStructureDto.getProductModelId());
-
-                BigDecimal stockQuantity = stockUtils.getStockQuantity(productModel1.getId());
-                if (!(stockQuantity.compareTo(BigDecimal.ZERO) > 0)) {
-                    throw new RuntimeException("搴撳瓨涓嶈冻");
-                }
-                ProductionProductInput productionProductInput = new ProductionProductInput();
-                productionProductInput.setProductModelId(productStructureDto.getProductModelId());
-                productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
-                productionProductInput.setProductMainId(productionProductMain.getId());
-                productionProductInputMapper.insert(productionProductInput);
+            if (stockQuantity.compareTo(productStructureDto.getUnitQuantity().multiply(dto.getQuantity())) < 0) {
+                throw new RuntimeException(product.getProductName() + "搴撳瓨涓嶈冻");
             }
+            ProductionProductInput productionProductInput = new ProductionProductInput();
+            productionProductInput.setProductModelId(productStructureDto.getProductModelId());
+            productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
+            productionProductInput.setProductMainId(productionProductMain.getId());
+            productionProductInputMapper.insert(productionProductInput);
+            //瀵瑰簲鐨勫簱瀛樺嚭搴�
+            DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyyMMdd");
+            LocalDate now = LocalDate.now();
+            ProcurementRecordOut procurementRecordOut1 = procurementRecordOutMapper.selectCode(dateFormat.format(now));
+            Long aLong = procurementRecordOut1 == null ? 1L : Long.valueOf(procurementRecordOut1.getCode().split("LS" + dateFormat.format(now))[1]);
+            ProcurementRecordOut.ProcurementRecordOutBuilder procurementRecordOut = ProcurementRecordOut.builder()
+                    .procurementRecordStorageId(0)
+                    .code("LS" + dateFormat.format(now) + String.format("%03d", aLong + 1))
+                    .salesLedgerProductId(productionProductMain.getId())//鍏宠仈鎶ュ伐浜у嚭
+                    .inboundBatches(aLong.equals(0L) ? "绗�1鎵规" : "绗�" + (aLong + 1) + "鎵规")
+                    .inboundNum(productionProductInput.getQuantity())
+                    .type(4)
+                    .createBy(user.getNickName())
+                    .productModelId(productModel1.getId());
+            procurementRecordOutMapper.insert(procurementRecordOut.build());
         }
-
-        // 娣诲姞浜у嚭
+        /*鏂板鎶ュ伐浜у嚭琛�*/
         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("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+        //瀵瑰簲鐨勮繃绋嬫鎴栬�呭嚭鍘傛
+        List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
+        int inspectType = 1;
+        if (productProcessRouteItem.getDragSort()==productProcessRouteItems.size()){
+            //鏈�鍚庝竴閬撳伐搴忕敓鎴愬嚭鍘傛
+            inspectType = 2;
         }
-        // 娣诲姞鐢熶骇鏍哥畻
+        Product product = productMapper.selectById(productModel.getProductId());
+        QualityInspect qualityInspect = new QualityInspect();
+        qualityInspect.setProductId(product.getId());
+        qualityInspect.setProductName(product.getProductName());
+        qualityInspect.setModel(productModel.getModel());
+        qualityInspect.setUnit(productModel.getUnit());
+        qualityInspect.setQuantity(dto.getQuantity());
+        qualityInspect.setProcess(productProcess.getName());
+        qualityInspect.setInspectState(0);
+        qualityInspect.setInspectType(inspectType);
+        qualityInspect.setProductMainId(productionProductMain.getId());
+        qualityInspect.setProductModelId(productModel.getId());
+        qualityInspectMapper.insert(qualityInspect);
+        List<QualityTestStandardBinding> qualityTestStandardBindings = qualityTestStandardBindingMapper.selectList(
+                new LambdaQueryWrapper<QualityTestStandardBinding>()
+                        .eq(QualityTestStandardBinding::getProductId, product.getId()));
+        if (qualityTestStandardBindings.size()>0){
+            qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
+                    .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandardBindings.get(0).getTestStandardId()))
+                    .forEach(qualityTestStandardParam -> {
+                QualityInspectParam param = new QualityInspectParam();
+                BeanUtils.copyProperties(qualityTestStandardParam, param);
+                param.setId(null);
+                param.setInspectId(qualityInspect.getId());
+                qualityInspectParamMapper.insert(param);
+            });
+        }
+        /*鏇存柊宸ュ崟鍜岀敓浜ц鍗�*/
+        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
+        productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(dto.getQuantity()));
+        if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())){
+            productWorkOrder.setActualStartTime(LocalDate.now());//瀹為檯寮�濮嬫椂闂�
+        }
+        if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0){
+            productWorkOrder.setActualEndTime(LocalDate.now());//瀹為檯缁撴潫鏃堕棿
+        }
+        productWorkOrderMapper.updateById(productWorkOrder);
+        //鐢熶骇璁㈠崟
+        ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
+        if (ObjectUtils.isNull(productOrder.getStartTime())){
+            productOrder.setStartTime(LocalDateTime.now());//寮�濮嬫椂闂�
+        }
+        if (productProcessRouteItem.getDragSort()==productProcessRouteItems.size()){
+            //濡傛灉鏄渶鍚庝竴閬撳伐搴忔姤宸ヤ箣鍚庣敓浜ц鍗曞畬鎴愭暟閲�+
+            productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(dto.getQuantity()));
+            if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0){
+                productOrder.setEndTime(LocalDateTime.now());//缁撴潫鏃堕棿
+            }
+        }
+        productOrderMapper.updateById(productOrder);
+        /*娣诲姞鐢熶骇鏍哥畻*/
         SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
                 .salesLedgerWorkId(productionProductMain.getId())
                 .salesLedgerSchedulingId(0L)
@@ -232,40 +261,54 @@
                 .tenantId(dto.getTenantId())
                 .build();
         salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
-
         return true;
     }
 
     @Override
-    @Transactional
     public Boolean removeProductMain(ProductionProductMainDto dto) {
-        Long id = dto.getId();
-
-        // 鏇存柊宸ュ崟
-        productWorkOrderMapper.rollbackPlanQuantity(id);
-        // 鍒犻櫎璐ㄦ鍙傛暟鍜岃川妫�璁板綍
+        ProductionProductMain productionProductMain = productionProductMainMapper.selectById(dto.getId());
+        //璇ユ姤宸ュ搴旂殑宸ヨ壓璺嚎璇︽儏
+        ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId());
+        ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(Wrappers.<ProductionProductOutput>lambdaQuery().eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())).get(0);
+        /*鍒犻櫎鏍哥畻*/
+        salesLedgerProductionAccountingMapper.delete(
+                new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
+                        .eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, productionProductMain.getId())
+        );
+        /*鏇存柊宸ュ崟鍜岀敓浜ц鍗�*/
+        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId());
+        productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().subtract(productionProductOutput.getQuantity()));
+        productWorkOrder.setActualEndTime(null);
+        productWorkOrderMapper.updateById(productWorkOrder);
+        //鍒ゆ柇鏄惁鏄渶鍚庝竴閬撳伐搴�
+        List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
+        if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()){
+            ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
+            productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().subtract(productionProductOutput.getQuantity()));
+            productOrder.setEndTime(null);
+            productOrderMapper.updateById(productOrder);
+        }
+        /*鍒犻櫎浜у嚭*/
+        //鍒犻櫎璐ㄦ
         qualityInspectMapper.selectList(
                 new LambdaQueryWrapper<QualityInspect>()
-                        .eq(QualityInspect::getProductMainId, id)
+                        .eq(QualityInspect::getProductMainId, productionProductMain.getId())
         ).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)
-        );
-
+                .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()));
+        /*鍒犻櫎鎶曞叆*/
+        procurementRecordOutMapper.delete(new LambdaQueryWrapper<ProcurementRecordOut>()
+                .eq(ProcurementRecordOut::getSalesLedgerProductId, productionProductMain.getId()));
+        productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
+                .eq(ProductionProductInput::getProductMainId, productionProductMain.getId()));
         // 鍒犻櫎涓昏〃
-        return productionProductMainMapper.deleteById(id) > 0;
+        productionProductMainMapper.deleteById(productionProductMain.getId());
+        return true;
     }
 }
diff --git a/src/main/java/com/ruoyi/project/system/controller/SysUserController.java b/src/main/java/com/ruoyi/project/system/controller/SysUserController.java
index 4ddd819..8b01634 100644
--- a/src/main/java/com/ruoyi/project/system/controller/SysUserController.java
+++ b/src/main/java/com/ruoyi/project/system/controller/SysUserController.java
@@ -157,6 +157,7 @@
         }
         user.setCreateBy(getUsername());
         user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
+        user.setTenantId(user.getDeptId());
         return toAjax(userService.insertUser(user));
     }
 
diff --git a/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
index cbb2e00..378a9c3 100644
--- a/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
@@ -22,7 +23,9 @@
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 /**
@@ -191,10 +194,27 @@
      */
     @GetMapping("/listPage")
     public AjaxResult listPage(Page page, PurchaseLedgerDto purchaseLedger) {
-        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerService.selectPurchaseLedgerListPage(page ,purchaseLedger);
-        //杩囨护鎺塧pprovalStatus=3鐨勮褰�
-        purchaseLedgerDtoIPage.getRecords().removeIf(purchaseLedgerDto -> purchaseLedgerDto.getApprovalStatus() == 3);
-         return AjaxResult.success(purchaseLedgerDtoIPage);
+        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = Optional.ofNullable(
+                purchaseLedgerService.selectPurchaseLedgerListPage(page, purchaseLedger)
+        ).orElse(new Page<>());
+
+        // 澶勭悊null
+        Optional.ofNullable(purchaseLedgerDtoIPage.getRecords())
+                .filter(CollectionUtils::isNotEmpty)
+                .ifPresent(records -> {
+                    // 杩囨护approvalStatus=3鐨勮褰�
+                    records.removeIf(dto -> dto != null && dto.getApprovalStatus() == 3);
+                    // 淇鏈敹浠樻閲戦
+                    records.forEach(dto -> {
+                        if (dto == null) return;
+                        BigDecimal unReceiptAmt = Optional.ofNullable(dto.getUnReceiptPaymentAmount()).orElse(BigDecimal.ZERO);
+                        if (unReceiptAmt.compareTo(BigDecimal.ZERO) == 0) {
+                            dto.setUnReceiptPaymentAmount(Optional.ofNullable(dto.getContractAmount()).orElse(BigDecimal.ZERO));
+                        }
+                    });
+                });
+
+        return AjaxResult.success(purchaseLedgerDtoIPage);
     }
 
     @ApiOperation("鐢熸垚閲囪喘搴忓垪鍙�")
diff --git a/src/main/java/com/ruoyi/purchase/controller/TicketRegistrationController.java b/src/main/java/com/ruoyi/purchase/controller/TicketRegistrationController.java
index eb5ed21..baefa12 100644
--- a/src/main/java/com/ruoyi/purchase/controller/TicketRegistrationController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/TicketRegistrationController.java
@@ -139,12 +139,12 @@
     }
 
 
-    @GetMapping("/getProductRecordById")
-    public AjaxResult getProductRecordById(Long id) {
-        if (id == null) {
+    @PostMapping("/getProductRecordById")
+    public AjaxResult getProductRecordById(@RequestBody ProductRecordDto productRecordDto) {
+        if (productRecordDto.getId() == null) {
             return AjaxResult.error("鍙傛暟閿欒");
         }
-        return AjaxResult.success(productRecordService.getProductRecordById(id));
+        return AjaxResult.success(productRecordService.getProductRecordById(productRecordDto));
     }
 
     @ApiModelProperty("淇敼鏉ョエ鐧昏")
diff --git a/src/main/java/com/ruoyi/purchase/dto/ProductRecordDto.java b/src/main/java/com/ruoyi/purchase/dto/ProductRecordDto.java
index b4edc0d..1b3c691 100644
--- a/src/main/java/com/ruoyi/purchase/dto/ProductRecordDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/ProductRecordDto.java
@@ -5,6 +5,7 @@
 import com.ruoyi.sales.pojo.CommonFile;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 @Data
@@ -28,12 +29,21 @@
     private String projectName;
     private Long issUerId;
     private String issUer;
+    /**
+     * 鍚堝悓閲戦锛堜骇鍝佸惈绋庢�讳环锛�
+     */
+    private BigDecimal contractAmount = BigDecimal.ZERO;
     //澧炲�肩◣
-    private String invoiceAmount = "0";
-
+    /**
+     * 宸叉潵绁ㄩ噾棰濓紙鍙戠エ閲戦锛�
+     */
+    private BigDecimal invoiceTotal = BigDecimal.ZERO;
+    private BigDecimal invoiceAmount = BigDecimal.ZERO;
+    /**
+     * 鍙戠エ鍙�
+     */
     private String invoiceNumber;
-
-    private String unTicketsPrice = "0";
+    private BigDecimal unTicketsPrice = BigDecimal.ZERO;
 
     private List<CommonFile> commonFiles;
 
diff --git a/src/main/java/com/ruoyi/purchase/mapper/ProductRecordMapper.java b/src/main/java/com/ruoyi/purchase/mapper/ProductRecordMapper.java
index 9d003ba..b4bdea9 100644
--- a/src/main/java/com/ruoyi/purchase/mapper/ProductRecordMapper.java
+++ b/src/main/java/com/ruoyi/purchase/mapper/ProductRecordMapper.java
@@ -8,6 +8,8 @@
 import com.ruoyi.purchase.pojo.ProductRecord;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 閲囪喘鍙拌处浜у搧寮�绁ㄨ褰昅apper鎺ュ彛
  *
@@ -18,5 +20,5 @@
 
     IPage<ProductRecordDto> productRecordPage(Page page, @Param("c") TicketRegistrationDto ticketRegistrationDto);
 
-    ProductRecordDto getProductRecordById(Long id);
+    List<ProductRecordDto> getProductRecordById(@Param("c") ProductRecordDto productRecordDto);
 }
diff --git a/src/main/java/com/ruoyi/purchase/service/IProductRecordService.java b/src/main/java/com/ruoyi/purchase/service/IProductRecordService.java
index 2fa21ca..3ab3d32 100644
--- a/src/main/java/com/ruoyi/purchase/service/IProductRecordService.java
+++ b/src/main/java/com/ruoyi/purchase/service/IProductRecordService.java
@@ -24,5 +24,5 @@
 
     AjaxResult updateRecord(ProductRecordDto productRecordDto);
 
-    ProductRecordDto getProductRecordById(Long id);
+    ProductRecordDto getProductRecordById(ProductRecordDto productRecordDto);
 }
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/ProductRecordServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/ProductRecordServiceImpl.java
index 7c1d837..d5c67b9 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/ProductRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/ProductRecordServiceImpl.java
@@ -101,9 +101,19 @@
         return AjaxResult.success("淇敼鎴愬姛");
     }
 
-    @Override
-    public ProductRecordDto getProductRecordById(Long id) {
-        ProductRecordDto productRecordDto = productRecordMapper.getProductRecordById(id);
-        return productRecordDto;
+     @Override
+    public ProductRecordDto getProductRecordById(ProductRecordDto productRecordDto) {
+        List<ProductRecordDto> productRecordDtoList = productRecordMapper.getProductRecordById(productRecordDto);
+        if(productRecordDtoList != null && productRecordDtoList.size() > 0){
+            ProductRecordDto productRecordDto1 = productRecordDtoList.get(productRecordDtoList.size() - 1);
+            // 杩囨护鍑轰笌浼犲叆鐨� productRecordDto 涓婚敭鐩稿悓鐨勮褰�
+            ProductRecordDto productRecordDto2 = productRecordDtoList.stream().filter(item ->
+                            item.getId().equals(productRecordDto.getId()))
+                    .findFirst().orElse(null);
+            productRecordDto2.setFutureTickets(productRecordDto1.getFutureTickets());
+            productRecordDto2.setFutureTicketsAmount(productRecordDto1.getFutureTicketsAmount());
+            return productRecordDto2;
+        }
+        return null;
     }
 }
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 55ea7ae..cac741c 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -36,14 +36,8 @@
 import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.purchase.pojo.TicketRegistration;
 import com.ruoyi.purchase.service.IPurchaseLedgerService;
-import com.ruoyi.quality.mapper.QualityInspectMapper;
-import com.ruoyi.quality.mapper.QualityInspectParamMapper;
-import com.ruoyi.quality.mapper.QualityTestStandardMapper;
-import com.ruoyi.quality.mapper.QualityTestStandardParamMapper;
-import com.ruoyi.quality.pojo.QualityInspect;
-import com.ruoyi.quality.pojo.QualityInspectParam;
-import com.ruoyi.quality.pojo.QualityTestStandard;
-import com.ruoyi.quality.pojo.QualityTestStandardParam;
+import com.ruoyi.quality.mapper.*;
+import com.ruoyi.quality.pojo.*;
 import com.ruoyi.sales.mapper.*;
 import com.ruoyi.sales.pojo.CommonFile;
 import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
@@ -110,7 +104,7 @@
 
     private final StringRedisTemplate redisTemplate;
     private final QualityInspectMapper qualityInspectMapper;
-    private final QualityTestStandardMapper qualityTestStandardMapper;
+    private final QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
     private final QualityTestStandardParamMapper qualityTestStandardParamMapper;
     private final QualityInspectParamMapper qualityInspectParamMapper;
 
@@ -205,36 +199,45 @@
         }
         //鏂板鍘熸潗鏂欐楠�
         for (SalesLedgerProduct saleProduct : productList) {
-            QualityInspect qualityInspect = new QualityInspect();
-            qualityInspect.setInspectType(0);
-            qualityInspect.setSupplier(purchaseLedger.getSupplierName());
-            qualityInspect.setPurchaseLedgerId(purchaseLedger.getId());
-            qualityInspect.setProductId(saleProduct.getId());
-            qualityInspect.setProductName(saleProduct.getProductCategory());
-            qualityInspect.setModel(saleProduct.getSpecificationModel());
-            qualityInspect.setProductModelId(saleProduct.getProductModelId());
-            qualityInspect.setUnit(saleProduct.getUnit());
-            qualityInspect.setQuantity(saleProduct.getQuantity());
-            qualityInspectMapper.insert(qualityInspect);
-
-            List<QualityTestStandardParam> qualityTestStandardParams = qualityTestStandardParamMapper.selectListByProductId(saleProduct.getProductId());
-            if (qualityTestStandardParams.size()>0) {
-                qualityTestStandardParams.forEach(standard -> {
-                    QualityInspectParam param = new QualityInspectParam();
-                    com.ruoyi.common.utils.bean.BeanUtils.copyProperties(standard, param);
-                    param.setId(null);
-                    param.setInspectId(qualityInspect.getId());
-                    qualityInspectParamMapper.insert(param);
-                });
+            //鏄惁鎺ㄩ�佽川妫�锛屽鏋渢rue灏辨坊鍔�
+            if (saleProduct.getIsChecked()) {
+                addQualityInspect(purchaseLedger, saleProduct);
             }
         }
-
         // 5. 杩佺Щ涓存椂鏂囦欢鍒版寮忕洰褰�
         if (purchaseLedgerDto.getTempFileIds() != null && !purchaseLedgerDto.getTempFileIds().isEmpty()) {
             migrateTempFilesToFormal(purchaseLedger.getId(), purchaseLedgerDto.getTempFileIds());
         }
 
         return 1;
+    }
+
+    private void addQualityInspect(PurchaseLedger purchaseLedger, SalesLedgerProduct saleProduct) {
+        QualityInspect qualityInspect = new QualityInspect();
+        qualityInspect.setInspectType(0);
+        qualityInspect.setSupplier(purchaseLedger.getSupplierName());
+        qualityInspect.setPurchaseLedgerId(purchaseLedger.getId());
+        qualityInspect.setProductId(saleProduct.getId());
+        qualityInspect.setProductName(saleProduct.getProductCategory());
+        qualityInspect.setModel(saleProduct.getSpecificationModel());
+        qualityInspect.setProductModelId(saleProduct.getProductModelId());
+        qualityInspect.setUnit(saleProduct.getUnit());
+        qualityInspect.setQuantity(saleProduct.getQuantity());
+        qualityInspectMapper.insert(qualityInspect);
+        List<QualityTestStandardBinding> qualityTestStandardBindings = qualityTestStandardBindingMapper.selectList(
+                new LambdaQueryWrapper<QualityTestStandardBinding>()
+                        .eq(QualityTestStandardBinding::getProductId, saleProduct.getProductId()));
+        if (qualityTestStandardBindings.size()>0){
+            qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
+                    .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandardBindings.get(0).getTestStandardId()))
+                    .forEach(qualityTestStandardParam -> {
+                        QualityInspectParam param = new QualityInspectParam();
+                        com.ruoyi.common.utils.bean.BeanUtils.copyProperties(qualityTestStandardParam, param);
+                        param.setId(null);
+                        param.setInspectId(qualityInspect.getId());
+                        qualityInspectParamMapper.insert(param);
+                    });
+        }
     }
 
     private void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, Integer type) {
@@ -304,6 +307,8 @@
 
                 LocalDateTime localDateTime = entryDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                 salesLedgerProduct.setRegisterDate(localDateTime);
+                salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
+                salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                 salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
                 salesLedgerProductMapper.insert(salesLedgerProduct);
             }
@@ -397,6 +402,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int deletePurchaseLedgerByIds(Long[] ids) {
         if (ids == null || ids.length == 0) {
            throw new BaseException("璇烽�変腑鑷冲皯涓�鏉℃暟鎹�");
@@ -408,7 +414,7 @@
         salesLedgerProductMapper.delete(queryWrapper);
         // 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐彴璐︾殑鏉ョエ鐧昏
         LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getSalesLedgerId,ids);
+        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getPurchaseLedgerId,ids);
         ticketRegistrationMapper.delete(ticketRegistrationLambdaQueryWrapper);
         // 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐彴璐︾殑鏉ョエ鐧昏璁板綍
         LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -422,6 +428,11 @@
         LambdaQueryWrapper<QualityInspect> materialInspectLambdaQueryWrapper = new LambdaQueryWrapper<>();
         materialInspectLambdaQueryWrapper.in(QualityInspect::getPurchaseLedgerId, ids);
         List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(materialInspectLambdaQueryWrapper);
+        qualityInspects.stream().forEach(qualityInspect -> {
+            if (ObjectUtils.isNotEmpty(qualityInspect.getInspectState())&&qualityInspect.getInspectState().equals(1)) {
+                throw new BaseException("宸叉彁浜ょ殑妫�楠屽崟涓嶈兘鍒犻櫎");
+            }
+        });
         List<Long> inspectIds = qualityInspects.stream()
                 .map(QualityInspect::getId)
                 .collect(Collectors.toList());
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
index 66d3875..a828596 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -1,6 +1,7 @@
 package com.ruoyi.purchase.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
@@ -29,6 +30,7 @@
 import com.ruoyi.sales.mapper.CommonFileMapper;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
 import com.ruoyi.sales.pojo.CommonFile;
+import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.service.ISalesLedgerProductService;
 import lombok.RequiredArgsConstructor;
@@ -162,6 +164,14 @@
                     productRecord.setPurchaseLedgerId(ticketRegistrationDto.getPurchaseLedgerId());
                     productRecord.setCreatedAt(DateUtils.getNowDate());
                     BeanUtils.copyProperties(salesLedgerProduct, productRecord);
+                    //鍚屾鏇存柊鍏朵粬鍓╀綑鏁伴噺鍜岄噾棰�
+                    productRecordMapper.update(
+                            null,
+                            new LambdaUpdateWrapper<ProductRecord>()
+                                    .eq(ProductRecord::getPurchaseLedgerId, ticketRegistrationDto.getPurchaseLedgerId())
+                                    .set(ProductRecord::getFutureTickets, salesLedgerProduct.getFutureTickets())
+                                    .set(ProductRecord::getFutureTicketsAmount, salesLedgerProduct.getFutureTicketsAmount())
+                    );
                     productRecord.setSaleLedgerProjectId(salesLedgerProduct.getId());
                     productRecord.setId(null);
                     productRecord.setType("2");
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
index dec920d..f39a456 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -146,7 +146,7 @@
             procurementRecordOutAdd.setDetails(details);
 
             ProcurementRecordStorage.ProcurementRecordStorageBuilder procurementRecordBuilder = ProcurementRecordStorage.builder()
-                    .salesLedgerProductId(details1.getId())
+                    .salesLedgerProductId(0)
                     .inboundBatches( "鐢熶骇鍗婃垚鍝佸叆搴�")
                     .inboundNum(details1.getInboundQuantity())
                     .type(2)
@@ -173,7 +173,7 @@
             List<Details> details = new ArrayList<>();
             Details details1 = new Details();
             details1.setInboundQuantity(qualityInspect.getQuantity());
-            details1.setId(Math.toIntExact(salesLedgerProduct.getProductId()));
+            details1.setId(Math.toIntExact(salesLedgerProduct.getId()));
             details1.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
             details1.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
             details1.setProductModelId(salesLedgerProduct.getProductModelId());
diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
index dce7ce7..22001e6 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
@@ -8,6 +8,7 @@
 import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
 import com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy;
 import com.ruoyi.procurementrecord.service.ProcurementRecordService;
+import com.ruoyi.procurementrecord.utils.StockUtils;
 import com.ruoyi.sales.dto.SalesLedgerProductDto;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.service.ISalesLedgerProductService;
@@ -25,11 +26,12 @@
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.framework.web.page.TableDataInfo;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
  * 浜у搧淇℃伅Controller
- * 
+ *
  * @author ruoyi
  * @date 2025-05-08
  */
@@ -41,6 +43,8 @@
     private ISalesLedgerProductService salesLedgerProductService;
     @Autowired
     private ProcurementRecordService procurementRecordService;
+    @Autowired
+    private StockUtils stockUtils;
 
 
     /**
@@ -71,13 +75,20 @@
     {
         List<SalesLedgerProduct> list = salesLedgerProductService.selectSalesLedgerProductList(salesLedgerProduct);
         list.forEach(item -> {
-            ProcurementPageDto procurementDto = new ProcurementPageDto();
-            procurementDto.setSalesLedgerProductId(item.getId());
-            procurementDto.setProductCategory(item.getProductCategory());
-            IPage<ProcurementPageDtoCopy> result = procurementRecordService.listPageCopyByProduction(new Page<>(1,-1), procurementDto);
-            if(result.getRecords().size()>0) {
-                ProcurementPageDtoCopy procurementDtoCopy = result.getRecords().get(0);
-                if (item.getQuantity().compareTo(procurementDtoCopy.getInboundNum0()) >= 0 && item.getApproveStatus() == 0) {
+                if (item.getFutureTickets().compareTo(BigDecimal.ZERO) == 0) {
+                    item.setFutureTickets(item.getQuantity());
+                }
+            if (item.getFutureTicketsAmount().compareTo(BigDecimal.ZERO) == 0) {
+                item.setFutureTicketsAmount(item.getTaxInclusiveTotalPrice());
+            }
+//            ProcurementPageDto procurementDto = new ProcurementPageDto();
+//            procurementDto.setSalesLedgerProductId(item.getId());
+//            procurementDto.setProductCategory(item.getProductCategory());
+//            IPage<ProcurementPageDtoCopy> result = procurementRecordService.listPageCopyByProduction(new Page<>(1,-1), procurementDto);
+            BigDecimal stockQuantity = stockUtils.getStockQuantity(item.getProductModelId()).get("stockQuantity");
+            if(stockQuantity != null) {
+//                ProcurementPageDtoCopy procurementDtoCopy = result.getRecords().get(0);
+                if (item.getQuantity().compareTo(stockQuantity) >= 0 && item.getApproveStatus() == 0) {
                     item.setApproveStatus(1);
                     salesLedgerProductService.addOrUpdateSalesLedgerProduct(item);
                 }
diff --git a/src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java b/src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
index b8fab54..ee7f721 100644
--- a/src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
+++ b/src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
@@ -3,6 +3,8 @@
 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.google.common.math.LongMath;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
@@ -60,41 +62,60 @@
     @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);
-
-            if(req.getApproveStatus()==3){
-                ProcurementRecordStorage procurementRecordStorage = procurementRecordStorageService.getOne(new LambdaQueryWrapper<ProcurementRecordStorage>()
-                        .eq(ProcurementRecordStorage::getSalesLedgerProductId, req.getSalesLedgerProductId()));
-                if(procurementRecordStorage==null){
-                    return AjaxResult.error("閲囪喘璁板綍涓嶅瓨鍦�");
-                }
-                //鍙戣揣瀹℃壒閫氳繃锛岀敓浜ц璁㈠崟鍑哄簱璁板綍
-                ProcurementRecordOutAdd procurementRecordOutAdd = new ProcurementRecordOutAdd();
-                procurementRecordOutAdd.setId(procurementRecordStorage.getId());
-                procurementRecordOutAdd.setSalesLedgerProductId(Math.toIntExact(salesLedgerProduct.getId()));
-                procurementRecordOutAdd.setType(2);
-                procurementRecordOutAdd.setUserId(Math.toIntExact(getUserId()));
-                procurementRecordOutAdd.setQuantity(String.valueOf(salesLedgerProduct.getQuantity()));
-                //鑾峰彇褰撳墠鏃堕棿
-                LocalDate now = LocalDate.now();
-                procurementRecordOutAdd.setTime(now.toString());
-                procurementRecordOutService.stockout(procurementRecordOutAdd);
-            }
+        if (!update) {
+            //  浜嬪姟鍥炴粴
+            throw new ServiceException("鍙戣揣瀹℃壒鏇存柊澶辫触");
         }
-        return update ? AjaxResult.success() : AjaxResult.error();
+        //  鏌ヨ鍏宠仈鐨勯攢鍞彴璐︿骇鍝�
+        SalesLedgerProduct salesLedgerProduct = salesLedgerProductService.getById(shipmentApproval.getSalesLedgerProductId());
+        if (salesLedgerProduct == null) {
+            //  鎶涘紓甯镐簨鍔″洖婊�
+            throw new ServiceException("閿�鍞彴璐︿笉瀛樺湪锛屽鎵瑰洖婊�");
+        }
+
+        //  鍚屾鏇存柊閿�鍞彴璐︿骇鍝佺殑瀹℃壒鐘舵��
+        salesLedgerProduct.setApproveStatus(req.getApproveStatus());
+        salesLedgerProductService.updateById(salesLedgerProduct);
+
+        //  瀹℃壒閫氳繃
+        if (req.getApproveStatus() == 3) {
+            // 鏌ヨ閲囪喘鍏ュ簱璁板綍
+            LambdaQueryWrapper<ProcurementRecordStorage> lambdaQueryWrapper = new LambdaQueryWrapper<ProcurementRecordStorage>()
+                    .eq(ProcurementRecordStorage::getSalesLedgerProductId, req.getSalesLedgerProductId());
+            ProcurementRecordStorage procurementRecordStorage = procurementRecordStorageService.getOne(lambdaQueryWrapper);
+
+            if (procurementRecordStorage == null) {
+                // 淇濊瘉鍓嶉潰鐨勪慨鏀瑰叏閮ㄥ洖婊�
+                throw new ServiceException("閲囪喘璁板綍涓嶅瓨鍦紝瀹℃壒鍥炴粴");
+            }
+
+            //  鐢熸垚鍑哄簱璁板綍
+            ProcurementRecordOutAdd procurementRecordOutAdd = new ProcurementRecordOutAdd();
+            procurementRecordOutAdd.setId(procurementRecordStorage.getId());
+            procurementRecordOutAdd.setSalesLedgerProductId((long) Math.toIntExact(salesLedgerProduct.getId()));
+            procurementRecordOutAdd.setType(2);
+            procurementRecordOutAdd.setUserId(Math.toIntExact(getUserId()));
+            procurementRecordOutAdd.setQuantity(salesLedgerProduct.getQuantity().toPlainString());
+            procurementRecordOutAdd.setTime(LocalDate.now().toString());
+
+            procurementRecordOutService.stockout(procurementRecordOutAdd);
+        }
+
+        return AjaxResult.success();
     }
 
 
+
     /**
      * 瀵煎嚭鍙戣揣淇℃伅绠$悊
      */
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
index c528b55..4c04ce6 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -111,22 +111,22 @@
     /**
      * 鏈鏉ョエ鏁�
      */
-    private BigDecimal ticketsNum;
+    private BigDecimal ticketsNum=BigDecimal.ZERO;
 
     /**
      * 鏈鏉ョエ閲戦(鍏�)
      */
-    private BigDecimal ticketsAmount;
+    private BigDecimal ticketsAmount=BigDecimal.ZERO;
 
     /**
      * 鏈潵绁ㄦ暟
      */
-    private BigDecimal futureTickets;
+    private BigDecimal futureTickets=BigDecimal.ZERO;
 
     /**
      * 鏈潵绁ㄩ噾棰�(鍏�)
      */
-    private BigDecimal futureTicketsAmount;
+    private BigDecimal futureTicketsAmount=BigDecimal.ZERO;
 
     @ApiModelProperty(value = "寮�绁ㄦ暟")
     private BigDecimal invoiceNum;
@@ -221,4 +221,7 @@
 
     @ApiModelProperty(value = "浠樻鎬婚噾棰�")
     private BigDecimal ticketsTotal = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "鏄惁璐ㄦ")
+    private Boolean isChecked;
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java
index 4722ac4..614fc20 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/InvoiceLedgerServiceImpl.java
@@ -381,55 +381,71 @@
 
     /**
      * 澶勭悊褰撴湀寮�绁ㄥ彴璐﹀垹闄�
+     *
      * @param invoiceRegistrationProductId
      * @param invoiceRegistrationProduct
      */
-    private void dealCurrentMonthDel(Integer invoiceRegistrationProductId,InvoiceRegistrationProduct invoiceRegistrationProduct){
+
+    private void dealCurrentMonthDel(Integer invoiceRegistrationProductId, InvoiceRegistrationProduct invoiceRegistrationProduct) {
+
         // 鍒犻櫎寮�绁ㄥ彴璐�
-        QueryWrapper<InvoiceLedger> delMapper = new QueryWrapper<>();
-        delMapper.eq("invoice_registration_product_id", invoiceRegistrationProductId);
-        invoiceLedgerMapper.delete(delMapper);
-        // 鍒犻櫎寮�绁ㄧ櫥璁板苟鍥炴粴
+        QueryWrapper<InvoiceLedger> delLedgerWrapper = new QueryWrapper<>();
+        delLedgerWrapper.eq("invoice_registration_product_id", invoiceRegistrationProductId);
+        invoiceLedgerMapper.delete(delLedgerWrapper);
+
+        // 鏌ヨ褰撳墠浜у搧涓嬬殑鎵�鏈夊紑绁ㄧ櫥璁�
         QueryWrapper<InvoiceRegistrationProduct> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("sales_ledger_id", invoiceRegistrationProduct.getSalesLedgerId());
         queryWrapper.eq("sales_ledger_product_id", invoiceRegistrationProduct.getSalesLedgerProductId());
         queryWrapper.orderByAsc("create_time");
-        List<InvoiceRegistrationProduct> invoiceRegistrationProductList = invoiceRegistrationProductMapper.selectList(queryWrapper);
-//        InvoiceRegistrationProduct invoiceRegistrationProduct = invoiceRegistrationProductMapper.selectById(invoiceRegistrationProductId);
-        int index =  -1;
-        for (int i = 0; i < invoiceRegistrationProductList.size(); i++) {
-            InvoiceRegistrationProduct currentInvoiceRegProduct = invoiceRegistrationProductList.get(i);
-            if(invoiceRegistrationProduct.getId().equals(currentInvoiceRegProduct.getId())){
+        List<InvoiceRegistrationProduct> allList = invoiceRegistrationProductMapper.selectList(queryWrapper);
+
+        int index = -1;
+        for (int i = 0; i < allList.size(); i++) {
+            if (invoiceRegistrationProductId.equals(allList.get(i).getId())) {
                 index = i;
+                break;
             }
         }
-        if(index == -1){
+        if (index == -1) {
             return;
         }
-        for (int i = index + 1; i < invoiceRegistrationProductList.size(); i++) {
-            InvoiceRegistrationProduct currentInvoiceRegProduct = invoiceRegistrationProductList.get(i);
-            // 鍥炴粴鏈紑绁ㄦ暟/鏈紑绁ㄩ噾棰�
-            BigDecimal noInvoiceAmount = currentInvoiceRegProduct.getNoInvoiceAmount().add(invoiceRegistrationProduct.getInvoiceAmount());
-            BigDecimal noInvoiceNum = currentInvoiceRegProduct.getNoInvoiceNum().add(invoiceRegistrationProduct.getInvoiceNum());
-            currentInvoiceRegProduct.setNoInvoiceAmount(noInvoiceAmount);
-            currentInvoiceRegProduct.setNoInvoiceNum(noInvoiceNum);
-            invoiceRegistrationProductMapper.updateById(currentInvoiceRegProduct);
+
+        for (int i = index + 1; i < allList.size(); i++) {
+            InvoiceRegistrationProduct current = allList.get(i);
+
+            current.setNoInvoiceNum(current.getNoInvoiceNum().add(invoiceRegistrationProduct.getInvoiceNum()));
+            current.setNoInvoiceAmount(current.getNoInvoiceAmount().add(invoiceRegistrationProduct.getInvoiceAmount()));
+
+            invoiceRegistrationProductMapper.updateById(current);
         }
+
+        // 鍒犻櫎褰撳墠寮�绁ㄧ櫥璁�
         invoiceRegistrationProductMapper.deleteById(invoiceRegistrationProductId);
-        // 淇敼sale_product鏁版嵁
-        SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(invoiceRegistrationProduct.getSalesLedgerProductId());
+
+        // 鏌ヨ鍒犻櫎鍚庣殑鍓╀綑寮�绁ㄧ櫥璁�
         QueryWrapper<InvoiceRegistrationProduct> newQueryWrapper = new QueryWrapper<>();
-        queryWrapper.eq("sales_ledger_id", invoiceRegistrationProduct.getSalesLedgerId());
-        queryWrapper.eq("sales_ledger_product_id", invoiceRegistrationProduct.getSalesLedgerProductId());
-        queryWrapper.orderByAsc("create_time");
-        List<InvoiceRegistrationProduct> newInvoiceRegistrationProductList = invoiceRegistrationProductMapper.selectList(newQueryWrapper);
-        if(CollectionUtils.isEmpty(newInvoiceRegistrationProductList)){
+        newQueryWrapper.eq("sales_ledger_id", invoiceRegistrationProduct.getSalesLedgerId());
+        newQueryWrapper.eq("sales_ledger_product_id", invoiceRegistrationProduct.getSalesLedgerProductId());
+        newQueryWrapper.orderByAsc("create_time");
+        List<InvoiceRegistrationProduct> remainList = invoiceRegistrationProductMapper.selectList(newQueryWrapper);
+
+        // 鏌ヨ閿�鍞彴璐︿骇鍝�
+        SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(invoiceRegistrationProduct.getSalesLedgerProductId());
+
+        if (CollectionUtils.isEmpty(remainList)) {
+            // 娌℃湁浠讳綍寮�绁ㄨ褰曪紝鎭㈠鍒濆鐘舵��
+            salesLedgerProduct.setInvoiceNum(BigDecimal.ZERO);
+            salesLedgerProduct.setInvoiceAmount(BigDecimal.ZERO);
             salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
             salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
-        }else {
+        } else {
+            salesLedgerProduct.setInvoiceNum(salesLedgerProduct.getInvoiceNum().subtract(invoiceRegistrationProduct.getInvoiceNum()));
+            salesLedgerProduct.setInvoiceAmount(salesLedgerProduct.getInvoiceAmount().subtract(invoiceRegistrationProduct.getInvoiceAmount()));
             salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getNoInvoiceNum().add(invoiceRegistrationProduct.getInvoiceNum()));
             salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getNoInvoiceAmount().add(invoiceRegistrationProduct.getInvoiceAmount()));
         }
+
         salesLedgerProductMapper.updateById(salesLedgerProduct);
     }
 
@@ -438,46 +454,59 @@
      * @param invoiceRegistrationProduct
      * @param invoiceLedger
      */
-    private void dealOtherMonthDel(InvoiceRegistrationProduct invoiceRegistrationProduct,InvoiceLedger invoiceLedger ){
-        InvoiceRegistrationProduct copyRegProduct = new InvoiceRegistrationProduct();
-        BeanUtils.copyProperties(invoiceRegistrationProduct, copyRegProduct);
-        BigDecimal invoiceNum = copyRegProduct.getInvoiceNum().negate();
-        BigDecimal invoiceAmount = copyRegProduct.getInvoiceAmount().negate();
-        // invoice_registration_product
-        // 鍒犻櫎寮�绁ㄧ櫥璁板苟鍥炴粴
+    private void dealOtherMonthDel(InvoiceRegistrationProduct invoiceRegistrationProduct, InvoiceLedger invoiceLedger) {
+        //鏌ヨ鍘嗗彶寮�绁ㄧ櫥璁�
         QueryWrapper<InvoiceRegistrationProduct> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("sales_ledger_id", invoiceRegistrationProduct.getSalesLedgerId());
         queryWrapper.eq("sales_ledger_product_id", invoiceRegistrationProduct.getSalesLedgerProductId());
         queryWrapper.orderByAsc("create_time");
-        List<InvoiceRegistrationProduct> invoiceRegistrationProductList = invoiceRegistrationProductMapper.selectList(queryWrapper);
-        InvoiceRegistrationProduct lastInvoiceRegistrationProduct = invoiceRegistrationProductList.get(invoiceRegistrationProductList.size() - 1);
-        BigDecimal noInvoiceNum = lastInvoiceRegistrationProduct.getNoInvoiceNum().subtract(invoiceNum);
-        BigDecimal noInvoiceAmount = lastInvoiceRegistrationProduct.getNoInvoiceAmount().subtract(invoiceAmount);
-        copyRegProduct.setInvoiceNum(invoiceNum);
-        copyRegProduct.setInvoiceAmount(invoiceAmount);
-        copyRegProduct.setNoInvoiceNum(noInvoiceNum);
-        copyRegProduct.setNoInvoiceAmount(noInvoiceAmount);
-        copyRegProduct.setId(null);
-        invoiceRegistrationProductMapper.insert(copyRegProduct);
+        List<InvoiceRegistrationProduct> list = invoiceRegistrationProductMapper.selectList(queryWrapper);
+
+        if (CollectionUtils.isEmpty(list)) {
+            return;
+        }
+
+        InvoiceRegistrationProduct last = list.get(list.size() - 1);
+
+        BigDecimal negateInvoiceNum = invoiceRegistrationProduct.getInvoiceNum().negate();
+        BigDecimal negateInvoiceAmount = invoiceRegistrationProduct.getInvoiceAmount().negate();
+
+        InvoiceRegistrationProduct copy = new InvoiceRegistrationProduct();
+        BeanUtils.copyProperties(invoiceRegistrationProduct, copy);
+
+        copy.setId(null);
+        copy.setInvoiceNum(negateInvoiceNum);
+        copy.setInvoiceAmount(negateInvoiceAmount);
+
+        // 鏈紑绁� = 涓婁竴鏉� + 鏈鍐插洖鐨勬暟閲�
+        copy.setNoInvoiceNum(last.getNoInvoiceNum().add(invoiceRegistrationProduct.getInvoiceNum()));
+        copy.setNoInvoiceAmount(last.getNoInvoiceAmount().add(invoiceRegistrationProduct.getInvoiceAmount()));
+
+        invoiceRegistrationProductMapper.insert(copy);
+
         // 澶嶅埗寮�绁ㄥ彴璐�
-        InvoiceLedger invoiceLedgerCopy = new InvoiceLedger();
-        BeanUtils.copyProperties(invoiceLedger, invoiceLedgerCopy);
-        invoiceLedgerCopy.setInvoiceRegistrationProductId(copyRegProduct.getId());
-        BigDecimal invoiceTotal = invoiceLedgerCopy.getInvoiceTotal().negate();
-        invoiceLedgerCopy.setInvoiceTotal(invoiceTotal);
-        invoiceLedgerCopy.setId(null);
-        invoiceLedgerCopy.setInvoiceDate(LocalDate.now());
-        invoiceLedgerMapper.insert(invoiceLedgerCopy);
-        // 鏇存柊sales_leger_product
-        QueryWrapper<SalesLedgerProduct> salesLedgerProductQueryWrapper = new QueryWrapper<>();
-        salesLedgerProductQueryWrapper.eq("id", invoiceRegistrationProduct.getSalesLedgerProductId());
-        SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectOne(salesLedgerProductQueryWrapper);
-        salesLedgerProduct.setNoInvoiceNum(noInvoiceNum);
-        salesLedgerProduct.setNoInvoiceAmount(noInvoiceAmount);
-        BigDecimal newInvoiceNum = salesLedgerProduct.getInvoiceNum().add(invoiceNum);
-        BigDecimal newInvocieAmount = salesLedgerProduct.getInvoiceAmount().add(invoiceAmount);
-        salesLedgerProduct.setInvoiceNum(newInvoiceNum);
-        salesLedgerProduct.setInvoiceAmount(newInvocieAmount);
+        InvoiceLedger ledgerCopy = new InvoiceLedger();
+        BeanUtils.copyProperties(invoiceLedger, ledgerCopy);
+
+        ledgerCopy.setId(null);
+        ledgerCopy.setInvoiceRegistrationProductId(copy.getId());
+        ledgerCopy.setInvoiceTotal(invoiceLedger.getInvoiceTotal().negate());
+        ledgerCopy.setInvoiceDate(LocalDate.now());
+
+        invoiceLedgerMapper.insert(ledgerCopy);
+
+        // 鍥炴粴 sales_ledger_product
+        SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(invoiceRegistrationProduct.getSalesLedgerProductId());
+
+        // 宸插紑绁�
+        salesLedgerProduct.setInvoiceNum(salesLedgerProduct.getInvoiceNum().add(negateInvoiceNum));
+        salesLedgerProduct.setInvoiceAmount(salesLedgerProduct.getInvoiceAmount().add(negateInvoiceAmount));
+
+        // 鏈紑绁�
+        salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getNoInvoiceNum().add(invoiceRegistrationProduct.getInvoiceNum()));
+        salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getNoInvoiceAmount().add(invoiceRegistrationProduct.getInvoiceAmount()));
+
         salesLedgerProductMapper.updateById(salesLedgerProduct);
     }
+
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
index 62090d1..1d71938 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
@@ -2,6 +2,8 @@
 
 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;
@@ -70,6 +72,13 @@
                 invoiceAmountTotal = invoiceAmountTotal.add(currentInvoiceNum);
                 InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct();
                 BeanUtils.copyProperties(productDatum, invoiceRegistrationProduct);
+                //鏇存柊宸插紑绁ㄥ墿浣欐湭寮�绁ㄦ暟
+                invoiceRegistrationProductMapper.update(
+                        null,
+                        new LambdaUpdateWrapper<InvoiceRegistrationProduct>()
+                                .eq(InvoiceRegistrationProduct::getSalesLedgerId, salesLedgerDto.getId())
+                                .set(InvoiceRegistrationProduct::getNoInvoiceAmount, productDatum.getNoInvoiceAmount())
+                );
                 invoiceRegistrationProduct.setId(null);
                 invoiceRegistrationProduct.setSalesLedgerId(salesLedgerDto.getId().intValue());
                 invoiceRegistrationProduct.setInvoiceRegistrationId(invoiceRegistration.getId());
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 9b056ce..d4ad7e0 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -59,6 +59,7 @@
     private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
 
     private ProcessRouteMapper processRouteMapper;
+    private ProductProcessRouteMapper productProcessRouteMapper;
 
     private ProductWorkOrderMapper productWorkOrderMapper;
 
@@ -140,7 +141,7 @@
             // 鎵归噺鏌ヨprocessRouteItems
             List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                     new LambdaQueryWrapper<ProductProcessRouteItem>()
-                            .in(ProductProcessRouteItem::getRouteId, orderIds)
+                            .in(ProductProcessRouteItem::getProductOrderId, orderIds)
             );
 
             if (!CollectionUtils.isEmpty(allRouteItems)) {
@@ -153,9 +154,13 @@
                                 .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
             }
 
-            // 鎵归噺鍒犻櫎processRouteItem
+            // 鎵归噺鍒犻櫎productProcessRouteItem
             productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
-                            .in(ProductProcessRouteItem::getRouteId, orderIds));
+                            .in(ProductProcessRouteItem::getProductOrderId, orderIds));
+
+            // 鎵归噺鍒犻櫎productProcessRoute
+            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
+                    .in(ProductProcessRoute::getProductOrderId, orderIds));
 
             // 鎵归噺鍒犻櫎productOrder
             productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
@@ -204,10 +209,20 @@
             productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
             productOrder.setProductModelId(salesLedgerProduct.getId());
             productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
+            productOrder.setQuantity(salesLedgerProduct.getQuantity());//闇�姹傛暟閲�
+            productOrder.setCompleteQuantity(BigDecimal.ZERO);//瀹屾垚鏁伴噺
             productOrderMapper.insert(productOrder);
 
             ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
             if (processRoute != null) {
+                //鏂板鐢熶骇璁㈠崟宸ヨ壓璺嚎涓昏〃
+                ProductProcessRoute productProcessRoute = new ProductProcessRoute();
+                productProcessRoute.setProductModelId(processRoute.getProductModelId());
+                productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
+                productProcessRoute.setProductOrderId(productOrder.getId());
+                productProcessRoute.setBomId(processRoute.getBomId());
+                productProcessRouteMapper.insert(productProcessRoute);
+                //鏂板鐢熶骇璁㈠崟宸ヨ壓璺嚎瀛愯〃
                 List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
                 // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
                 String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
@@ -215,7 +230,8 @@
                     ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                     productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                     productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
-                    productProcessRouteItem.setRouteId(productOrder.getId());
+                    productProcessRouteItem.setProductOrderId(productOrder.getId());
+                    productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
                     int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                     if (insert > 0) {
                         // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
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 ad5d908..36a550f 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -12,13 +12,16 @@
 import com.ruoyi.account.pojo.AccountIncome;
 import com.ruoyi.account.service.AccountIncomeService;
 import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.common.enums.FileNameType;
 import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.other.mapper.TempFileMapper;
 import com.ruoyi.other.pojo.TempFile;
+import com.ruoyi.production.dto.ProductStructureDto;
 import com.ruoyi.production.mapper.*;
 import com.ruoyi.production.pojo.*;
 import com.ruoyi.project.system.domain.SysDept;
@@ -96,6 +99,7 @@
     private final ProductOrderMapper productOrderMapper;
 
     private final ProcessRouteMapper processRouteMapper;
+    private final ProductProcessRouteMapper productProcessRouteMapper;
 
     private final ProcessRouteItemMapper processRouteItemMapper;
 
@@ -122,6 +126,10 @@
     private static final long LOCK_EXPIRE_TIME = 30;  // 閿佽嚜鍔ㄨ繃鏈熸椂闂达紙绉掞級
 
     private final RedisTemplate<String, String> redisTemplate;
+    @Autowired
+    private ProductModelMapper productModelMapper;
+    @Autowired
+    private ProductStructureMapper productStructureMapper;
 
     @Override
     public List<SalesLedger> selectSalesLedgerList(SalesLedgerDto salesLedgerDto) {
@@ -400,7 +408,7 @@
             // 鎵归噺鏌ヨprocessRouteItems
             List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                     new LambdaQueryWrapper<ProductProcessRouteItem>()
-                            .in(ProductProcessRouteItem::getRouteId, orderIds)
+                            .in(ProductProcessRouteItem::getProductOrderId, orderIds)
             );
 
             if (!CollectionUtils.isEmpty(allRouteItems)) {
@@ -455,7 +463,11 @@
             }
             // 鎵归噺鍒犻櫎processRouteItem
             productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
-                    .in(ProductProcessRouteItem::getRouteId, orderIds));
+                    .in(ProductProcessRouteItem::getProductOrderId, orderIds));
+
+            // 鎵归噺鍒犻櫎productProcessRoute
+            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
+                    .in(ProductProcessRoute::getProductOrderId, orderIds));
 
             // 鎵归噺鍒犻櫎productOrder
             productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
@@ -661,20 +673,31 @@
                 productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
                 productOrder.setProductModelId(salesLedgerProduct.getId());
                 productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
+                productOrder.setQuantity(salesLedgerProduct.getQuantity());//闇�姹傛暟閲�
+                productOrder.setCompleteQuantity(BigDecimal.ZERO);//瀹屾垚鏁伴噺
                 productOrderMapper.insert(productOrder);
 
                 ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
+                List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomId(processRoute.getBomId());
                 if (processRoute != null) {
+                    //鏂板鐢熶骇璁㈠崟宸ヨ壓璺嚎涓昏〃
+                    ProductProcessRoute productProcessRoute = new ProductProcessRoute();
+                    productProcessRoute.setProductModelId(processRoute.getProductModelId());
+                    productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
+                    productProcessRoute.setProductOrderId(productOrder.getId());
+                    productProcessRoute.setBomId(processRoute.getBomId());
+                    productProcessRouteMapper.insert(productProcessRoute);
+                    //鏂板鐢熶骇璁㈠崟宸ヨ壓璺嚎瀛愯〃
                     List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
                     // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
                     String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
-                    int dragSort = 1;
                     for (ProcessRouteItem processRouteItem : processRouteItems) {
                         ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                         productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                         productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
-                        productProcessRouteItem.setRouteId(productOrder.getId());
-                        productProcessRouteItem.setDragSort(dragSort);
+                        productProcessRouteItem.setProductOrderId(productOrder.getId());
+                        productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
+                        productProcessRouteItem.setDragSort(processRouteItem.getDragSort());
                         int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                         if (insert > 0) {
                             // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
@@ -700,14 +723,20 @@
                             // 鐢熸垚瀹屾暣鐨勫伐鍗曞彿
                             String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                             ProductWorkOrder productWorkOrder = new ProductWorkOrder();
+                            productStructureDtos.stream().forEach(productStructureDto -> {
+                                if (productStructureDto.getProductModelId().equals(productProcessRouteItem.getProductModelId())){
+                                    productWorkOrder.setPlanQuantity(productWorkOrder.getPlanQuantity());
+                                }
+                            });
+                            if (Objects.equals(productProcessRouteItem.getProductModelId(), salesLedgerProduct.getProductModelId())) {
+                                productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
+                            }
                             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);
diff --git a/src/main/java/com/ruoyi/staff/controller/StaffContractController.java b/src/main/java/com/ruoyi/staff/controller/StaffContractController.java
new file mode 100644
index 0000000..af4c90c
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/controller/StaffContractController.java
@@ -0,0 +1,34 @@
+package com.ruoyi.staff.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.staff.pojo.StaffContract;
+import com.ruoyi.staff.service.StaffContractService;
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+/**
+ * 鍛樺伐鍙拌处/鍚堝悓绠$悊
+ */
+@RestController
+@RequestMapping("/staff/staffContract")
+@Api(tags = "鍛樺伐鍙拌处/鍚堝悓绠$悊")
+public class StaffContractController {
+
+    @Resource
+    private StaffContractService staffContractService;
+
+
+    /**
+     * 鍛樺伐鍚堝悓鍒嗛〉鏌ヨ
+     * @param page
+     * @param staffContract
+     * @return
+     */
+    @GetMapping("/listPage")
+    public AjaxResult staffContractListPage(Page page, StaffContract staffContract) {
+        return AjaxResult.success(staffContractService.staffContractListPage(page, staffContract));
+    }
+}
diff --git a/src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java b/src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java
index 7ddf17d..55a93b2 100644
--- a/src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java
+++ b/src/main/java/com/ruoyi/staff/controller/StaffOnJobController.java
@@ -4,6 +4,7 @@
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.staff.dto.StaffOnJobDto;
 import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
 import com.ruoyi.staff.pojo.StaffOnJob;
 import com.ruoyi.staff.service.IStaffJoinLeaveRecordService;
@@ -52,14 +53,48 @@
     }
 
     /**
-     * 鍦ㄨ亴鍛樺伐璇︽儏
-     * @param staffNo
+     * 鏂板鍏ヨ亴
+     * @param staffOnJob
      * @return
      */
-    @GetMapping("/staffNo")
-    public AjaxResult staffOnJobDetail(String staffNo) {
-        return AjaxResult.success(staffOnJobService.staffOnJobDetail(staffNo));
+    @PostMapping("")
+    public AjaxResult add(@RequestBody StaffOnJobDto staffOnJob) {
+        return AjaxResult.success(staffOnJobService.add(staffOnJob));
     }
+
+    /**
+     * 鏇存柊鍏ヨ亴淇℃伅
+     * @param staffOnJobDto
+     * @return
+     */
+    @PutMapping("/{id}")
+    public AjaxResult update(@PathVariable("id") Long id, @RequestBody StaffOnJobDto staffOnJobDto) {
+        return AjaxResult.success(staffOnJobService.update(id, staffOnJobDto));
+    }
+
+    /**
+     * 鍒犻櫎鍏ヨ亴
+     * @param ids
+     * @return
+     */
+    @DeleteMapping("/del")
+    public AjaxResult delStaffOnJobs(@RequestBody List<Integer> ids) {
+        if(CollectionUtils.isEmpty(ids)){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        return AjaxResult.success(staffOnJobService.delStaffOnJobs(ids));
+    }
+
+    /**
+     * 鍦ㄨ亴鍛樺伐璇︽儏
+     * @param id
+     * @return
+     */
+    @GetMapping("/{id}")
+    public AjaxResult staffJoinLeaveRecordDetail(@PathVariable("id") Long id) {
+        return AjaxResult.success(staffOnJobService.staffOnJobDetail(id));
+    }
+
     /**
      * 鍦ㄨ亴鍛樺伐瀵煎叆
      */
diff --git a/src/main/java/com/ruoyi/staff/dto/StaffContractDto.java b/src/main/java/com/ruoyi/staff/dto/StaffContractDto.java
new file mode 100644
index 0000000..3d74c67
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/dto/StaffContractDto.java
@@ -0,0 +1,9 @@
+package com.ruoyi.staff.dto;
+
+import com.ruoyi.staff.pojo.StaffContract;
+import lombok.Data;
+
+@Data
+public class StaffContractDto extends StaffContract {
+    private String staffName;
+}
diff --git a/src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java b/src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java
index 13c2051..04f5169 100644
--- a/src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java
+++ b/src/main/java/com/ruoyi/staff/dto/StaffOnJobDto.java
@@ -1,10 +1,26 @@
 package com.ruoyi.staff.dto;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
 import com.ruoyi.staff.pojo.StaffOnJob;
 import lombok.Data;
 
+import java.util.Date;
+
 @Data
 public class StaffOnJobDto extends StaffOnJob {
+    @Excel(name = "宀椾綅",sort = 7)
     private String postName;
+
+    @Excel(name = "鍚堝悓骞撮檺")
+    private String contractTerm;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鍚堝悓寮�濮嬫棩鏈�", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date contractStartTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鍚堝悓缁撴潫鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date contractEndTime;
 }
diff --git a/src/main/java/com/ruoyi/staff/mapper/StaffContractMapper.java b/src/main/java/com/ruoyi/staff/mapper/StaffContractMapper.java
new file mode 100644
index 0000000..9545082
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/mapper/StaffContractMapper.java
@@ -0,0 +1,25 @@
+package com.ruoyi.staff.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.staff.dto.StaffContractDto;
+import com.ruoyi.staff.dto.StaffOnJobDto;
+import com.ruoyi.staff.pojo.StaffContract;
+import com.ruoyi.staff.pojo.StaffOnJob;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface StaffContractMapper extends BaseMapper<StaffContract> {
+    /**
+     * 鍛樺伐鍚堝悓鍒嗛〉鏌ヨ
+     * @param page
+     * @param staffContract
+     * @return
+     */
+    IPage<StaffContractDto> staffContractListPage(Page page, @Param("staffContract") StaffContract staffContract);
+
+}
diff --git a/src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java b/src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java
new file mode 100644
index 0000000..d8fce17
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java
@@ -0,0 +1,10 @@
+package com.ruoyi.staff.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.staff.pojo.StaffLeave;
+import org.apache.ibatis.annotations.Mapper;
+
+
+@Mapper
+public interface StaffLeaveMapper extends BaseMapper<StaffLeave> {
+}
diff --git a/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java b/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java
index b11847e..1451487 100644
--- a/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java
+++ b/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java
@@ -4,7 +4,6 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.staff.dto.StaffOnJobDto;
-import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
 import com.ruoyi.staff.pojo.StaffOnJob;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -16,5 +15,5 @@
 
     IPage<StaffOnJobDto> staffOnJobListPage(Page page, @Param("staffOnJob") StaffOnJob staffOnJob);
 
-    List<StaffOnJob> staffOnJobList(@Param("staffOnJob") StaffOnJob staffOnJob);
+    List<StaffOnJobDto> staffOnJobList(@Param("staffOnJob") StaffOnJob staffOnJob);
 }
diff --git a/src/main/java/com/ruoyi/staff/pojo/StaffContract.java b/src/main/java/com/ruoyi/staff/pojo/StaffContract.java
new file mode 100644
index 0000000..9b2afee
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/pojo/StaffContract.java
@@ -0,0 +1,49 @@
+package com.ruoyi.staff.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+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.time.LocalDateTime;
+import java.util.Date;
+
+@TableName("staff_contract")
+@Data
+public class StaffContract {
+
+    @ApiModelProperty(value = "搴忓彿")
+    private Long id;
+
+    @ApiModelProperty(value = "鍦ㄨ亴鍛樺伐ID")
+    private Long staffOnJobId;
+
+    @ApiModelProperty(value = "鍚堝悓鏈熼檺")
+    private String contractTerm;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @ApiModelProperty(value = "鍚堝悓寮�濮嬫椂闂�")
+    private Date contractStartTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @ApiModelProperty(value = "鍚堝悓缁撴潫鏃堕棿")
+    private Date contractEndTime;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/ruoyi/staff/pojo/StaffLeave.java b/src/main/java/com/ruoyi/staff/pojo/StaffLeave.java
new file mode 100644
index 0000000..9965c6d
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/pojo/StaffLeave.java
@@ -0,0 +1,35 @@
+package com.ruoyi.staff.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@TableName("staff_leave")
+@Data
+public class StaffLeave {
+
+    @ApiModelProperty(value = "搴忓彿")
+    private Long id;
+
+    @ApiModelProperty(value = "鍦ㄨ亴鍛樺伐ID")
+    private Long staffOnJobId;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java b/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
index 1cee908..2db3869 100644
--- a/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
+++ b/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
@@ -31,98 +31,97 @@
     /**
      * 鐘舵��(0:绂昏亴;1:鍦ㄨ亴)
      */
-    @Excel(name = "鐘舵��",readConverterExp = "0=绂昏亴,1=鍦ㄨ亴")
+    @Excel(name = "鐘舵��", readConverterExp = "0=绂昏亴,1=鍦ㄨ亴", sort = 1)
     private Integer staffState;
 
     /**
      * 鍛樺伐缂栧彿
      */
-    @Excel(name = "鍛樺伐缂栧彿", type = Excel.Type.EXPORT, cellType = Excel.ColumnType.STRING)
+    @Excel(name = "鍛樺伐缂栧彿", type = Excel.Type.EXPORT, cellType = Excel.ColumnType.STRING, sort = 2)
     private String staffNo;
 
     /**
      * 鍛樺伐濮撳悕
      */
-    @Excel(name = "鍛樺伐濮撳悕")
+    @Excel(name = "鍛樺伐濮撳悕", sort = 3)
     private String staffName;
 
     /**
      * 鎬у埆
      */
-    @Excel(name = "鎬у埆")
+    @Excel(name = "鎬у埆", sort = 4)
     private String sex;
 
     /**
      * 绫嶈疮
      */
-    @Excel(name = "绫嶈疮")
+    @Excel(name = "绫嶈疮", sort = 5)
     private String nativePlace;
 
     /**
      * 宀椾綅
      */
-    @Excel(name = "宀椾綅")
     private Integer sysPostId;
 
     /**
      * 瀹跺涵浣忓潃
      */
-    @Excel(name = "瀹跺涵浣忓潃")
+    @Excel(name = "瀹跺涵浣忓潃", sort = 6)
     private String adress;
 
     /**
      * 绗竴瀛﹀巻
      */
-    @Excel(name = "绗竴瀛﹀巻")
+    @Excel(name = "绗竴瀛﹀巻", sort = 8)
     private String firstStudy;
 
     /**
      * 涓撲笟
      */
-    @Excel(name = "涓撲笟")
+    @Excel(name = "涓撲笟", sort = 9)
     private String profession;
 
     /**
      * 韬唤璇佸彿鐮�
      */
-    @Excel(name = "韬唤璇佸彿鐮�")
+    @Excel(name = "韬唤璇佸彿鐮�", sort = 10)
     private String identityCard;
 
     /**
      * 骞撮緞
      */
-    @Excel(name = "骞撮緞")
+    @Excel(name = "骞撮緞", sort = 11)
     private String age;
 
     /**
      * 鑱旂郴鐢佃瘽
      */
-    @Excel(name = "鑱旂郴鐢佃瘽")
+    @Excel(name = "鑱旂郴鐢佃瘽", sort = 12)
     private String phone;
 
     /**
      * 绱ф�ヨ仈绯讳汉
      */
-    @Excel(name = "绱ф�ヨ仈绯讳汉")
+    @Excel(name = "绱ф�ヨ仈绯讳汉", sort = 13)
     private String emergencyContact;
 
     /**
      * 绱ф�ヨ仈绯讳汉鐢佃瘽
      */
-    @Excel(name = "绱ф�ヨ仈绯讳汉鐢佃瘽")
+    @Excel(name = "绱ф�ヨ仈绯讳汉鐢佃瘽", sort = 14)
     private String emergencyContactPhone;
 
     /**
      * 鍚堝悓骞撮檺
      */
-    @Excel(name = "鍚堝悓骞撮檺")
+    @Excel(name = "鍚堝悓骞撮檺", sort = 15)
     private String contractTerm;
 
     /**
      * 鍚堝悓鍒版湡鏃ユ湡
      */
     @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "鍚堝悓鍒版湡鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    @Excel(name = "鍚堝悓鍒版湡鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd", sort = 16)
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date contractExpireTime;
 
@@ -130,7 +129,7 @@
      * 缁撴潫璇曠敤鏃堕棿
      */
     @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "缁撴潫璇曠敤鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd")
+    @Excel(name = "缁撴潫璇曠敤鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd", sort = 17)
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date trialEndDate;
 
@@ -138,7 +137,7 @@
      * 寮�濮嬭瘯鐢ㄦ棩鏈�
      */
     @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "寮�濮嬭瘯鐢ㄦ棩鏈�", width = 30, dateFormat = "yyyy-MM-dd")
+    @Excel(name = "寮�濮嬭瘯鐢ㄦ棩鏈�", width = 30, dateFormat = "yyyy-MM-dd", sort = 18)
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date trialStartDate;
 
@@ -146,7 +145,7 @@
      * 绛捐鏃堕棿
      */
     @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "绛捐鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd")
+    @Excel(name = "绛捐鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd", sort = 19)
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date signDate;
 
@@ -159,7 +158,7 @@
     /**
      * 璇曠敤鏈熷伐璧�
      */
-    @Excel(name = "璇曠敤鏈熷伐璧�")
+    @Excel(name = "璇曠敤鏈熷伐璧�", sort = 20)
     private BigDecimal proSalary;
 
     /**
@@ -171,9 +170,8 @@
     /**
      * 澶囨敞锛堢鍒╁緟閬囷級
      */
-    @Excel(name = "澶囨敞锛堢鍒╁緟閬囷級")
+    @Excel(name = "澶囨敞锛堢鍒╁緟閬囷級", sort = 21)
     private String remark;
-
 
 
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
diff --git a/src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java b/src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java
index 419e2f4..e6e5a40 100644
--- a/src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java
+++ b/src/main/java/com/ruoyi/staff/service/IStaffOnJobService.java
@@ -6,6 +6,7 @@
 import com.ruoyi.staff.dto.StaffOnJobDto;
 import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
 import com.ruoyi.staff.pojo.StaffOnJob;
+import org.bouncycastle.crypto.digests.LongDigest;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
@@ -16,7 +17,13 @@
 
     IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJob staffOnJob);
 
-    List<StaffJoinLeaveRecord> staffOnJobDetail(String staffNo);
+     StaffOnJobDto staffOnJobDetail(Long id);
+
+    int add(StaffOnJobDto staffOnJob);
+
+    int update(Long id, StaffOnJobDto staffOnJob);
+
+    int delStaffOnJobs(List<Integer> ids);
 
     void staffOnJobExport(HttpServletResponse response, StaffOnJob staffOnJob);
 
diff --git a/src/main/java/com/ruoyi/staff/service/StaffContractService.java b/src/main/java/com/ruoyi/staff/service/StaffContractService.java
new file mode 100644
index 0000000..5c2319c
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/service/StaffContractService.java
@@ -0,0 +1,19 @@
+package com.ruoyi.staff.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.staff.dto.StaffContractDto;
+import com.ruoyi.staff.dto.StaffOnJobDto;
+import com.ruoyi.staff.pojo.StaffContract;
+import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
+import com.ruoyi.staff.pojo.StaffOnJob;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+public interface StaffContractService extends IService<StaffContract> {
+
+    IPage<StaffContractDto> staffContractListPage(Page page, StaffContract staffContract);
+}
diff --git a/src/main/java/com/ruoyi/staff/service/StaffLeaveService.java b/src/main/java/com/ruoyi/staff/service/StaffLeaveService.java
new file mode 100644
index 0000000..67aede2
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/service/StaffLeaveService.java
@@ -0,0 +1,7 @@
+package com.ruoyi.staff.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.staff.pojo.StaffLeave;
+
+public interface StaffLeaveService extends IService<StaffLeave> {
+}
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffContractServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffContractServiceImpl.java
new file mode 100644
index 0000000..ba6e123
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffContractServiceImpl.java
@@ -0,0 +1,23 @@
+package com.ruoyi.staff.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.staff.dto.StaffContractDto;
+import com.ruoyi.staff.mapper.StaffContractMapper;
+import com.ruoyi.staff.pojo.StaffContract;
+import com.ruoyi.staff.service.StaffContractService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@AllArgsConstructor
+@Service
+public class StaffContractServiceImpl extends ServiceImpl<StaffContractMapper, StaffContract> implements StaffContractService {
+    private StaffContractMapper staffContractMapper;
+
+    @Override
+    public IPage<StaffContractDto> staffContractListPage(Page page, StaffContract staffContract) {
+        return staffContractMapper.staffContractListPage(page,staffContract);
+    }
+}
+
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
new file mode 100644
index 0000000..0fc3807
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
@@ -0,0 +1,15 @@
+package com.ruoyi.staff.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.staff.mapper.StaffLeaveMapper;
+import com.ruoyi.staff.service.StaffLeaveService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import com.ruoyi.staff.pojo.StaffLeave;
+
+@AllArgsConstructor
+@Service
+public class StaffLeaveServiceImpl extends ServiceImpl<StaffLeaveMapper, StaffLeave> implements StaffLeaveService {
+
+}
+
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
index 437eede..69e0638 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -1,40 +1,44 @@
 package com.ruoyi.staff.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.dto.WordDateDto;
+import com.ruoyi.project.system.domain.SysPost;
+import com.ruoyi.project.system.mapper.SysPostMapper;
 import com.ruoyi.staff.dto.StaffOnJobDto;
+import com.ruoyi.staff.mapper.StaffContractMapper;
 import com.ruoyi.staff.mapper.StaffJoinLeaveRecordMapper;
+import com.ruoyi.staff.mapper.StaffLeaveMapper;
 import com.ruoyi.staff.mapper.StaffOnJobMapper;
+import com.ruoyi.staff.pojo.StaffContract;
 import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
+import com.ruoyi.staff.pojo.StaffLeave;
 import com.ruoyi.staff.pojo.StaffOnJob;
-import com.ruoyi.staff.service.IStaffJoinLeaveRecordService;
 import com.ruoyi.staff.service.IStaffOnJobService;
 import freemarker.template.Configuration;
 import freemarker.template.Template;
-import freemarker.template.TemplateException;
 import lombok.AllArgsConstructor;
 
 import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
-import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.ZoneId;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+
+import static com.ruoyi.common.enums.StaffJoinLeaveRecordDimissionReason.StaffJoinLeaveRecordDimissionReasonOther;
 
 @AllArgsConstructor
 @Service
@@ -43,7 +47,12 @@
 
     private StaffOnJobMapper staffOnJobMapper;
 
+    private SysPostMapper sysPostMapper;
+
     private StaffJoinLeaveRecordMapper staffJoinLeaveRecordMapper;
+    private StaffContractMapper staffContractMapper;
+    private StaffLeaveMapper staffLeaveMapper;
+
 
     //鍦ㄨ亴鍛樺伐鍙拌处鍒嗛〉鏌ヨ
     @Override
@@ -51,19 +60,93 @@
         return staffOnJobMapper.staffOnJobListPage(page,staffOnJob);
     }
 
+    //鏂板鍏ヨ亴
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int add(StaffOnJobDto staffOnJobPrams) {
+        String[] ignoreProperties = {"id"};//鎺掗櫎id灞炴��
+        // 鍒ゆ柇缂栧彿鏄惁瀛樺湪
+        List<StaffOnJob> staffOnJobs = staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery().eq(StaffOnJob::getStaffNo, staffOnJobPrams.getStaffNo()));
+        if (staffOnJobs.size()>0){
+            throw new BaseException("缂栧彿涓�"+staffOnJobPrams.getStaffNo()+"鐨勫憳宸ュ凡缁忓瓨鍦�,鏃犳硶鏂板!!!");
+        }
+        // 鍒涘缓鍏ヨ亴鏁版嵁
+        staffOnJobMapper.insert(staffOnJobPrams);
+
+        // 鍒涘缓鍚堝悓璁板綍
+        StaffContract staffContract = new StaffContract();
+        staffContract.setStaffOnJobId(staffOnJobPrams.getId());
+        staffContract.setContractTerm(staffOnJobPrams.getContractTerm());
+        staffContract.setContractStartTime(staffOnJobPrams.getContractStartTime());
+        staffContract.setContractEndTime(staffOnJobPrams.getContractEndTime());
+        return staffContractMapper.insert(staffContract);
+    }
+
+    //鏇存柊鍏ヨ亴淇℃伅
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int update(Long id, StaffOnJobDto staffOnJobParams) {
+        // 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
+        StaffOnJob job = staffOnJobMapper.selectById(id);
+        if (job == null){
+            throw new BaseException("缂栧彿涓�"+staffOnJobParams.getStaffNo()+"鐨勫憳宸ヤ笉瀛樺湪,鏃犳硶鏇存柊!!!");
+        }
+
+        // 鏇存柊鍛樺伐鏁版嵁
+        String[] ignoreProperties = {"id"};//鎺掗櫎id灞炴��
+        BeanUtils.copyProperties(staffOnJobParams,job,ignoreProperties);
+        staffOnJobMapper.updateById(job);
+
+        // 鑾峰彇鏈�鏂板悎鍚屾暟鎹紝骞朵笖鏇存柊
+        StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
+                .eq(StaffContract::getStaffOnJobId, id)
+                .orderByDesc(StaffContract::getId));
+        if (contract != null){
+            BeanUtils.copyProperties(staffOnJobParams,contract,ignoreProperties);
+            return staffContractMapper.updateById(contract);
+        }
+        return 0;
+    }
+
+    //鍒犻櫎鍏ヨ亴
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int delStaffOnJobs(List<Integer> ids) {
+        // 鍒犻櫎鍏ヨ亴鏁版嵁
+        staffOnJobMapper.deleteBatchIds(ids);
+        // 鍒犻櫎绂昏亴鏁版嵁
+        staffLeaveMapper.delete(Wrappers.<StaffLeave>lambdaQuery().in(StaffLeave::getStaffOnJobId, ids));
+        // 鍒犻櫎鍚堝悓鏁版嵁
+        return staffContractMapper.delete(Wrappers.<StaffContract>lambdaQuery().in(StaffContract::getStaffOnJobId, ids));
+    }
+
     //鍦ㄨ亴鍛樺伐璇︽儏
     @Override
-    public List<StaffJoinLeaveRecord> staffOnJobDetail(String staffNo) {
-        return staffJoinLeaveRecordMapper.selectList(Wrappers.<StaffJoinLeaveRecord>lambdaQuery()
-                .eq(StaffJoinLeaveRecord::getStaffState,1)
-                .eq(StaffJoinLeaveRecord::getStaffNo,staffNo));
+    public StaffOnJobDto staffOnJobDetail(Long id) {
+        StaffOnJob staffOnJob  = staffOnJobMapper.selectById(id);
+        StaffOnJobDto staffOnJobDto = new StaffOnJobDto();
+        BeanUtils.copyProperties(staffOnJob, staffOnJobDto);
+        // 鏌ヨ宀椾綅鍚嶇О
+        SysPost post = sysPostMapper.selectPostById((long) staffOnJob.getSysPostId());
+        staffOnJobDto.setPostName(post.getPostName());
+
+        // 鏌ヨ鍚堝悓淇℃伅
+        StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
+                .eq(StaffContract::getStaffOnJobId, staffOnJob.getId())
+                .orderByDesc(StaffContract::getId));
+        if (contract != null){
+            staffOnJobDto.setContractTerm(contract.getContractTerm());
+            staffOnJobDto.setContractStartTime(contract.getContractStartTime());
+            staffOnJobDto.setContractEndTime(contract.getContractEndTime());
+        }
+        return staffOnJobDto;
     }
 
     //鍦ㄨ亴鍛樺伐瀵煎嚭
     @Override
     public void staffOnJobExport(HttpServletResponse response, StaffOnJob staffOnJob) {
-        List<StaffOnJob> staffOnJobs = staffOnJobMapper.staffOnJobList(staffOnJob);
-        ExcelUtil<StaffOnJob> util = new ExcelUtil<StaffOnJob>(StaffOnJob.class);
+        List<StaffOnJobDto> staffOnJobs = staffOnJobMapper.staffOnJobList(staffOnJob);
+        ExcelUtil<StaffOnJobDto> util = new ExcelUtil<StaffOnJobDto>(StaffOnJobDto.class);
         util.exportExcel(response, staffOnJobs, "鍦ㄨ亴鍛樺伐鍙拌处瀵煎嚭");
     }
 
diff --git a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
index 6384411..6270d57 100644
--- a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -261,7 +261,7 @@
         left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id and t2.type = 1
         left join sales_ledger t3 on t3.id = t2.sales_ledger_id
         <where>
-            t1.type = 2
+            t1.type = 2 and t1.sales_ledger_product_id != 0
             <if test="req.customerName != null and req.customerName != ''">
                 and t3.customer_name like  concat('%',#{req.customerName},'%')
             </if>
@@ -358,4 +358,25 @@
         from procurement_record_storage
         where product_model_id = #{productModelId}
     </select>
+    <select id="listPageByProductProduction" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDto">
+        select
+        t1.*,
+        t2.model as specification_model  ,
+        t2.unit,
+        t3.product_name as product_category
+        from  procurement_record_storage t1
+        left  join product_model t2 on t1.product_model_id = t2.id
+        left join product t3 on t2.product_id = t3.id
+        <where>
+            t1.type = 2 and t1.sales_ledger_product_id  = 0
+            <if test="req.productCategory != null and req.productCategory != ''">
+                and t3.product_name like  concat('%',#{req.productCategory},'%')
+            </if>
+
+            <if test="req.timeStr != null and req.timeStr != ''">
+                and t1.create_time like  concat('%',#{req.timeStr},'%')
+            </if>
+        </where>
+        order by t1.create_time desc
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml b/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
index 0fc12a9..adc64dd 100644
--- a/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
@@ -19,85 +19,82 @@
         t1.create_by,
         t2.warn_num,
         t4.unit_price,
-        t4.unit_price *  t1.inbound_num as totalPrice
-        from  procurement_record_out t1
+        t4.unit_price * t1.inbound_num as totalPrice
+        from procurement_record_out t1
         left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id and t2.type = 2
         left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
         left join procurement_record_storage t4 on t4.id = t1.procurement_record_storage_id
         <where>
             and t1.type = 1
             <if test="req.supplierName != null and req.supplierName != ''">
-                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
+                and t3.supplier_name like concat('%',#{req.supplierName},'%')
             </if>
             <if test="req.productCategory != null and req.productCategory != ''">
-                and t2.product_category like  concat('%',#{req.productCategory},'%')
+                and t2.product_category like concat('%',#{req.productCategory},'%')
             </if>
             <if test="req.timeStr != null and req.timeStr != ''">
-                and t1.create_time like  concat('%',#{req.timeStr},'%')
+                and t1.create_time like concat('%',#{req.timeStr},'%')
             </if>
         </where>
         order by t1.create_time desc
     </select>
     <select id="list" resultType="com.ruoyi.procurementrecord.dto.ProcurementRecordOutPageDto">
-        select
-            t3.supplier_name,
-            t2.product_category,
-            t1.id,
-            t2.specification_model,
-            t2.unit,
-            t2.tax_rate,
-            t2.tax_inclusive_unit_price,
-            t2.tax_inclusive_total_price,
-            t2.tax_exclusive_total_price,
-            t1.inbound_num,
-            t1.create_time,
-            t1.create_time as time,
-            t1.create_by
-        from  procurement_record_out t1
-                  left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
-                  left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
-            where t1.type = 1
+        select t3.supplier_name,
+               t2.product_category,
+               t1.id,
+               t2.specification_model,
+               t2.unit,
+               t2.tax_rate,
+               t2.tax_inclusive_unit_price,
+               t2.tax_inclusive_total_price,
+               t2.tax_exclusive_total_price,
+               t1.inbound_num,
+               t1.create_time,
+               t1.create_time as time,
+               t1.create_by
+        from procurement_record_out t1
+                 left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
+                 left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
+        where t1.type = 1
     </select>
 
     <select id="listOne" resultType="com.ruoyi.procurementrecord.dto.ProcurementRecordOutPageDto">
-        select
-            t3.customer_contract_no,
-            t3.sales_contract_no,
-            t3.customer_name,
-            t2.product_category,
-            t1.id,
-            t2.specification_model,
-            t2.unit,
-            t2.tax_rate,
-            t2.tax_inclusive_unit_price,
-            t2.tax_inclusive_total_price,
-            t2.tax_exclusive_total_price,
-            t1.inbound_num,
-            t1.create_time,
-            t1.create_time as time,
-            t1.create_by
-        from  procurement_record_out t1
-            left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
-            left join sales_ledger t3 on t3.id = t2.sales_ledger_id
+        select t3.customer_contract_no,
+               t3.sales_contract_no,
+               t3.customer_name,
+               t2.product_category,
+               t1.id,
+               t2.specification_model,
+               t2.unit,
+               t2.tax_rate,
+               t2.tax_inclusive_unit_price,
+               t2.tax_inclusive_total_price,
+               t2.tax_exclusive_total_price,
+               t1.inbound_num,
+               t1.create_time,
+               t1.create_time as time,
+               t1.create_by
+        from procurement_record_out t1
+                 left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
+                 left join sales_ledger t3 on t3.id = t2.sales_ledger_id
         where t1.type = 2
     </select>
 
     <select id="listTwo" resultType="com.ruoyi.procurementrecord.dto.ProcurementRecordOutPageDto">
-        select
-            t1.supplier_name,
-            t1.product_category,
-            t1.id,
-            t1.specification_model,
-            t1.unit,
-            t1.tax_rate,
-            t1.tax_inclusive_unit_price,
-            t1.tax_inclusive_total_price,
-            t1.tax_exclusive_total_price,
-            t1.inbound_num,
-            t1.create_time,
-            t1.create_time as time,
-            t1.create_by
-        from  procurement_record_out t1
+        select t1.supplier_name,
+               t1.product_category,
+               t1.id,
+               t1.specification_model,
+               t1.unit,
+               t1.tax_rate,
+               t1.tax_inclusive_unit_price,
+               t1.tax_inclusive_total_price,
+               t1.tax_exclusive_total_price,
+               t1.inbound_num,
+               t1.create_time,
+               t1.create_time as time,
+               t1.create_by
+        from procurement_record_out t1
         where t1.type = 3
     </select>
     <select id="listPageByProduct" resultType="com.ruoyi.procurementrecord.dto.ProcurementRecordOutPageDto">
@@ -118,21 +115,21 @@
         t1.create_time,
         t1.create_by,
         t4.unit_price,
-        t4.unit_price *  t1.inbound_num as totalPrice
-        from  procurement_record_out t1
+        t4.unit_price * t1.inbound_num as totalPrice
+        from procurement_record_out t1
         left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id and t2.type = 1
         left join sales_ledger t3 on t3.id = t2.sales_ledger_id
         left join procurement_record_storage t4 on t4.id = t1.procurement_record_storage_id
         <where>
             and t1.type = 2
             <if test="req.customerName != null and req.customerName != ''">
-                and t3.customer_name like  concat('%',#{req.customerName},'%')
+                and t3.customer_name like concat('%',#{req.customerName},'%')
             </if>
             <if test="req.productCategory != null and req.productCategory != ''">
-                and t2.product_category like  concat('%',#{req.productCategory},'%')
+                and t2.product_category like concat('%',#{req.productCategory},'%')
             </if>
             <if test="req.timeStr != null and req.timeStr != ''">
-                and t1.create_time like  concat('%',#{req.timeStr},'%')
+                and t1.create_time like concat('%',#{req.timeStr},'%')
             </if>
         </where>
         order by t1.create_time desc
@@ -153,18 +150,18 @@
         t1.create_by,
         t2.item_type,
         t2.code
-        from  procurement_record_out t1
+        from procurement_record_out t1
         left join custom_storage t2 on t2.id = t1.procurement_record_storage_id
         <where>
             t1.type = 3
             <if test="req.supplierName != null and req.supplierName != ''">
-                and t2.supplier_name like  concat('%',#{req.supplierName},'%')
+                and t2.supplier_name like concat('%',#{req.supplierName},'%')
             </if>
             <if test="req.productCategory != null and req.productCategory != ''">
-                and t2.product_category like  concat('%',#{req.productCategory},'%')
+                and t2.product_category like concat('%',#{req.productCategory},'%')
             </if>
             <if test="req.timeStr != null and req.timeStr != ''">
-                and t1.create_time like  concat('%',#{req.timeStr},'%')
+                and t1.create_time like concat('%',#{req.timeStr},'%')
             </if>
         </where>
         order by t1.create_time desc
@@ -173,7 +170,40 @@
     <select id="getSumQuantity" resultType="BigDecimal">
         select COALESCE(sum(inbound_num), 0)
         from procurement_record_out
-        where type = 1
-          and product_model_id = #{productModelId}
+        where
+           product_model_id = #{productModelId}
     </select>
+    <select id="selectCode" resultType="com.ruoyi.procurementrecord.pojo.ProcurementRecordOut">
+        select *
+        from procurement_record_out
+        where code like concat('%', #{format})
+        order by id desc
+        limit 1
+    </select>
+    <select id="listPageBySemiProduct" resultType="com.ruoyi.procurementrecord.dto.ProcurementRecordOutPageDto">
+        select
+        t1.id,
+        t1.code,
+        t2.unit,
+        t1.inbound_num,
+        t1.create_time,
+        t1.create_by,
+        t2.model as specification_model,
+        t2.product_code,
+        t3.product_name as product_category
+        from procurement_record_out t1
+        left join product_model t2 on t2.id = t1.product_model_id
+        left join product t3 on t3.id = t2.product_id
+        <where>
+            and t1.type = 4
+            <if test="req.productCategory !=null and req.productCategory !=''">
+                t3.product_name like concat('%',#{req.productCategory},'%')
+            </if>
+            <if test="req.timeStr != null and req.timeStr != ''">
+                and t1.create_time like concat('%',#{req.timeStr},'%')
+            </if>
+        </where>
+        order by t1.create_time desc
+    </select>
+
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/production/ProcessRouteItemMapper.xml b/src/main/resources/mapper/production/ProcessRouteItemMapper.xml
index 3814aeb..1b5e2b4 100644
--- a/src/main/resources/mapper/production/ProcessRouteItemMapper.xml
+++ b/src/main/resources/mapper/production/ProcessRouteItemMapper.xml
@@ -10,6 +10,7 @@
         <result property="tenantId" column="tenant_id"/>
         <result property="createTime" column="create_time"/>
         <result property="updateTime" column="update_time"/>
+        <result property="dragSort" column="drag_sort"/>
     </resultMap>
 
     <select id="listProcessRouteItemDto" resultType="com.ruoyi.production.dto.ProcessRouteItemDto">
@@ -29,6 +30,6 @@
                 left join process_route pr on pr.id = pri.route_id
         where
             pri.route_id = #{c.routeId}
-        order by pri.id
+        order by pri.drag_sort
     </select>
 </mapper>
diff --git a/src/main/resources/mapper/production/ProcessRouteMapper.xml b/src/main/resources/mapper/production/ProcessRouteMapper.xml
index c5e09fc..51c11b4 100644
--- a/src/main/resources/mapper/production/ProcessRouteMapper.xml
+++ b/src/main/resources/mapper/production/ProcessRouteMapper.xml
@@ -13,8 +13,9 @@
     </resultMap>
 
     <select id="pageProcessRouteDto" resultType="com.ruoyi.production.dto.ProcessRouteDto">
-        select ps.*, p.product_name,pm.product_id,pm.model
+        select ps.*, p.product_name,pm.product_id,pm.model,pb.bom_no
         from process_route ps
+        left join product_bom pb on ps.bom_id = pb.id
         left join product_model pm on ps.product_model_id = pm.id
         left join product p on pm.product_id = p.id
         <where>
diff --git a/src/main/resources/mapper/production/ProductBomMapper.xml b/src/main/resources/mapper/production/ProductBomMapper.xml
new file mode 100644
index 0000000..ec06cd3
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductBomMapper.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.production.mapper.ProductBomMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductBom">
+        <id column="id" property="id"/>
+        <result column="product_model_id" property="productModelId"/>
+        <result column="bom_no" property="bomNo"/>
+        <result column="remark" property="remark"/>
+        <result column="version" property="version"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="create_user" property="createUser"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="tenant_id" property="tenantId"/>
+    </resultMap>
+    <select id="listPage" resultType="com.ruoyi.production.dto.ProductBomDto">
+        select * from (select pb.*,
+        pm.model productModelName,
+        p.product_name productName
+        from product_bom pb
+        left join product_model pm on pb.product_model_id = pm.id
+        left join product p on pm.product_id = p.id)A
+        where 1=1
+        <if test="c.productModelName != null">
+            and productModelName = #{c.productModelName}
+        </if>
+        <if test="c.productName != null">
+            and productName = #{c.productName}
+        </if>
+        <if test="c.bomNo != null">
+            and bom_no = #{c.bomNo}
+        </if>
+        <if test="c.version != null">
+            and version = #{c.version}
+        </if>
+    </select>
+    <select id="getById" resultType="com.ruoyi.production.dto.ProductBomDto">
+        select pb.*,
+               pm.model productModelName,
+               p.product_name productName
+        from product_bom pb
+                 left join product_model pm on pb.product_model_id = pm.id
+                 left join product p on pm.product_id = p.id
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductOrderMapper.xml b/src/main/resources/mapper/production/ProductOrderMapper.xml
index d4ffc40..b47d5cf 100644
--- a/src/main/resources/mapper/production/ProductOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -14,11 +14,19 @@
         <result property="updateTime" column="update_time"/>
     </resultMap>
     <select id="pageProductOrder" resultType="com.ruoyi.production.dto.ProductOrderDto">
-        select po.*,sl.sales_contract_no,sl.customer_name,slp.product_category,slp.specification_model
+        select po.*,
+        sl.sales_contract_no,
+        sl.customer_name,
+        slp.product_category,
+        slp.specification_model,
+        ppr.process_route_code,
+        pb.bom_no,
+        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus
         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
-        left join process_route pr on po.route_id = pr.id
+        left join product_process_route ppr on po.id = ppr.product_order_id
+        left join product_bom pb on pb.id = ppr.bom_id
         <where>
             <if test="c.npsNo != null and c.npsNo != ''">
                 and po.nps_no like concat('%',#{c.npsNo},'%')
@@ -38,17 +46,44 @@
         </where>
     </select>
     <select id="productMainByOrderId" resultType="com.ruoyi.production.dto.ProductOrderDto">
-        select
-            po.*,
-            pwo.work_order_no,
-            pwo.report_work,
-            pwo.status,
-            pwo.quantity,
-            pwo.plan_quantity
+        select po.*,
+               pwo.work_order_no,
+               pwo.report_work,
+               pwo.status,
+               pwo.quantity,
+               pwo.plan_quantity
         from product_order po
-        left join product_work_order pwo on po.id = pwo.product_order_id
+                 left join product_work_order pwo on po.id = pwo.product_order_id
         where po.id = #{c.id}
     </select>
+    <select id="listProcessRoute" resultType="com.ruoyi.production.pojo.ProcessRoute">
+        select pr.*
+        from process_route pr
+                 left join product_model pm on pr.product_model_id = pm.id
+                 left join sales_ledger_product slp on pm.id = slp.product_model_id
+        where slp.id = #{productModelId}
+    </select>
+    <select id="listProcessBom" resultType="com.ruoyi.production.dto.ProductStructureDto">
+        select ps.id,
+               ps.product_model_id,
+               ps.process_id,
+               ps.unit_quantity,
+               ps.unit_quantity * po.quantity as demandedQuantity,
+               ps.unit,
+               p.product_name,
+               pp.name as  process_name,
+               pm.product_id,
+               pm.model
+        from
+            product_structure ps
+                left join product_model pm on ps.product_model_id = pm.id
+                left join product p on pm.product_id = p.id
+                left join product_process pp on ps.process_id = pp.id
+                left join product_process_route ppr on ps.bom_id = ppr.bom_id
+                left join product_order po on po.id = ppr.product_order_id
+        where ppr.product_order_id = #{orderId}
+        order by ps.id
+    </select>
 
 
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductProcessMapper.xml b/src/main/resources/mapper/production/ProductProcessMapper.xml
index 37822b7..a2292e2 100644
--- a/src/main/resources/mapper/production/ProductProcessMapper.xml
+++ b/src/main/resources/mapper/production/ProductProcessMapper.xml
@@ -4,11 +4,7 @@
 
     <select id="listPage" resultType="com.ruoyi.production.dto.ProductProcessDto">
         SELECT
-        p.id,
-        p.name,
-        p.no,
-        p.remark,
-        p.salary_quota
+        *
         FROM
         product_process p
         <where>
diff --git a/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml b/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
index caa7890..13f0ad7 100644
--- a/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
+++ b/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
@@ -20,7 +20,7 @@
                  left join product_model pm on ppri.product_model_id = pm.id
                  left join product p on pm.product_id = p.id
                  left join product_process pp on pp.id = ppri.process_id
-        where ppri.route_id = #{orderId}
+        where ppri.product_order_id = #{orderId}
         order by ppri.drag_sort
     </select>
 
diff --git a/src/main/resources/mapper/production/ProductProcessRouteMapper.xml b/src/main/resources/mapper/production/ProductProcessRouteMapper.xml
new file mode 100644
index 0000000..dd4809f
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductProcessRouteMapper.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.production.mapper.ProductProcessRouteMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductProcessRoute">
+        <id column="id" property="id"/>
+        <result column="product_model_id" property="productModelId"/>
+        <result column="description" property="description"/>
+        <result column="tenant_id" property="tenantId"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="bom_id" property="bomId"/>
+        <result column="process_route_code" property="processRouteCode"/>
+        <result column="product_order_id" property="productOrderId"/>
+    </resultMap>
+    <select id="listMain" resultType="com.ruoyi.production.dto.ProcessRouteDto">
+        select ppr.*, p.product_name, pm.product_id, pm.model, pb.bom_no
+        from product_process_route ppr
+                 left join product_bom pb on ppr.bom_id = pb.id
+                 left join product_model pm on ppr.product_model_id = pm.id
+                 left join product p on pm.product_id = p.id
+        where ppr.product_order_id = #{orderId}
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductStructureMapper.xml b/src/main/resources/mapper/production/ProductStructureMapper.xml
index df5a966..e4a0795 100644
--- a/src/main/resources/mapper/production/ProductStructureMapper.xml
+++ b/src/main/resources/mapper/production/ProductStructureMapper.xml
@@ -9,11 +9,9 @@
         <result property="unitQuantity" column="unit_quantity"/>
         <result property="demandedQuantity" column="demanded_quantity"/>
         <result property="unit" column="unit"/>
-        <result property="diskQuantity" column="disk_quantity"/>
         <result property="tenantId" column="tenant_id"/>
     </resultMap>
-
-    <select id="listByproductModelId" resultType="com.ruoyi.production.dto.ProductStructureDto">
+    <select id="listBybomId" resultType="com.ruoyi.production.dto.ProductStructureDto">
         select ps.*,
                p.product_name,
                pp.name as  process_name,
@@ -24,7 +22,22 @@
                 left join product_model pm on ps.product_model_id = pm.id
                 left join product p on pm.product_id = p.id
                 left join product_process pp on ps.process_id = pp.id
-        where ps.parent_id = #{productModelId}
+        where ps.bom_id = #{bomId}
+        order by ps.id
+    </select>
+    <select id="listBybomAndProcess" resultType="com.ruoyi.production.dto.ProductStructureDto">
+        select ps.*,
+               p.product_name,
+               pp.name as  process_name,
+               pm.product_id,
+               pm.model
+        from
+            product_structure ps
+                left join product_model pm on ps.product_model_id = pm.id
+                left join product p on pm.product_id = p.id
+                left join product_process pp on ps.process_id = pp.id
+        where ps.bom_id = #{bomId}
+        and ps.process_id=#{processId}
         order by ps.id
     </select>
 </mapper>
diff --git a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
index ac0348a..9a03b30 100644
--- a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
+++ b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -25,9 +25,10 @@
         pm.model,
         pm.unit,
         p.product_name AS productName,
-        po.nps_no AS productOrderNpsNo
+        po.nps_no AS productOrderNpsNo,
+        ROUND(pwo.complete_quantity / pwo.plan_quantity * 100, 2) AS completionStatus
         FROM
-        `product_work_order` pwo
+        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
@@ -44,28 +45,4 @@
         from product_work_order pwo
         left join product_order po on po.id = pwo.product_order_id
     </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 7d203f3..a885977 100644
--- a/src/main/resources/mapper/production/ProductionProductInputMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -13,11 +13,14 @@
     <select id="listPageProductionProductInputDto" resultType="com.ruoyi.production.dto.ProductionProductInputDto">
         select ppi.*,
         pm.model as model,
-        ppm.product_no as productNo
+        ppm.product_no as productNo,
+        p.product_name,
+        pm.unit
         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
+        left join product p on p.id = pm.product_id
         <where>
             <if test="c.productMainId != null and c.productMainId > 0">
                 and ppm.id = #{c.productMainId}
diff --git a/src/main/resources/mapper/production/ProductionProductMainMapper.xml b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
index 3a0542c..1d98782 100644
--- a/src/main/resources/mapper/production/ProductionProductMainMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -16,10 +16,20 @@
         select ppm.*,
                pwo.work_order_no as workOrderNo,
                pwo.status as workOrderStatus,
-               u.nick_name as nickName
+               u.nick_name as nickName,
+               p.product_name as productName,
+               pm.model as productModelName,
+               ppo.quantity,
+               pm.unit,
+               sl.sales_contract_no salesContractNo
         from
             production_product_main ppm
                 left join product_work_order pwo on pwo.id = ppm.work_order_id
+                left join product_order po on po.id = pwo.product_order_id
+                left join production_product_output ppo on ppm.id = ppo.product_main_id
+                left join product_model pm on pm.id = ppo.product_model_id
+                left join product p on p.id = pm.product_id
+                left join sales_ledger sl on sl.id = po.sales_ledger_id
                 left join sys_user u on u.user_id = ppm.user_id
         <where>
             <if test="c.nickName != null and c.nickName != ''">
@@ -36,6 +46,7 @@
             </if>
         </where>
         order by ppm.id
+
     </select>
 
     <delete id="deleteByWorkOrderIds" parameterType="java.util.List">
diff --git a/src/main/resources/mapper/purchase/ProductRecordMapper.xml b/src/main/resources/mapper/purchase/ProductRecordMapper.xml
index 2c0cba4..aa850cb 100644
--- a/src/main/resources/mapper/purchase/ProductRecordMapper.xml
+++ b/src/main/resources/mapper/purchase/ProductRecordMapper.xml
@@ -34,10 +34,10 @@
             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')
+            and pr.created_at &gt;= str_to_date(#{c.createdAtStart}, '%Y-%m-%d')
         </if>
         <if test="c.createdAtEnd != null and c.createdAtEnd != ''">
-            and pr.created_at &lt;= date_format(#{c.createdAtEnd},'%Y-%m-%d hh:mm:ss')
+            and pr.created_at &lt; date_add(str_to_date(#{c.createdAtEnd}, '%Y-%m-%d'), interval 1 day)
         </if>
         <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''">
             and tr.purchase_contract_number like concat('%',#{c.purchaseContractNumber},'%')
@@ -60,7 +60,12 @@
                  left join sales_ledger sl on sl.id = pl.sales_ledger_id
                  left join ticket_registration tr on tr.id = pr.ticket_registration_id
                  left join product_model pm on pm.id = pr.product_model_id
-
-        WHERE type = 2 and pr.id = #{id}
+        WHERE type = 2
+        <if test="c.purchaseLedgerId != null and c.purchaseLedgerId != ''">
+            and pr.purchase_ledger_id = #{c.purchaseLedgerId}
+        </if>
+        <if test="c.productModelId != null and c.productModelId != ''">
+            and pm.id = #{c.productModelId}
+        </if>
     </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
index c4f4e88..51c46b4 100644
--- a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
+++ b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -18,8 +18,8 @@
         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,
+        sum(tr.invoice_amount)as receipt_payment_amount,
+        pl.contract_amount-sum(tr.invoice_amount) AS unReceipt_payment_amount,
         pl.entry_date,
         pl.recorder_id,
         pl.recorder_name,
@@ -29,7 +29,9 @@
         pl.approval_status,
         pl.payment_method
         from purchase_ledger pl
+        left join sales_ledger_product slp on slp.sales_ledger_id = pl.id and slp.type=2
         left join product_record pr on pl.id = pr.purchase_ledger_id
+        left join ticket_registration tr on tr.id = pr.ticket_registration_id
         left join supplier_manage sm on pl.supplier_id = sm.id
         <where>
             1 = 1
diff --git a/src/main/resources/mapper/sales/InvoiceRegistrationProductMapper.xml b/src/main/resources/mapper/sales/InvoiceRegistrationProductMapper.xml
index 3178871..cfd47e5 100644
--- a/src/main/resources/mapper/sales/InvoiceRegistrationProductMapper.xml
+++ b/src/main/resources/mapper/sales/InvoiceRegistrationProductMapper.xml
@@ -110,10 +110,10 @@
                      )
             </if>
             <if test="invoiceRegistrationProductDto.invoiceDateStart != null and invoiceRegistrationProductDto.invoiceDateStart != ''">
-                AND T3.invoice_date &gt;= date_format(#{invoiceRegistrationProductDto.invoiceDateStart}, '%Y-%m-%d')
+                AND T3.invoice_date &gt;= str_to_date(#{invoiceRegistrationProductDto.invoiceDateStart}, '%Y-%m-%d')
             </if>
             <if test="invoiceRegistrationProductDto.invoiceDateEnd != null and invoiceRegistrationProductDto.invoiceDateEnd != ''">
-                AND T3.invoice_date &lt;= date_format(#{invoiceRegistrationProductDto.invoiceDateEnd}, '%Y-%m-%d')
+                AND T3.invoice_date &lt; date_add(str_to_date(#{invoiceRegistrationProductDto.invoiceDateEnd}, '%Y-%m-%d'), interval 1 day)
             </if>
             <if test="invoiceRegistrationProductDto.createTimeStart != null ">
                 AND T1.create_time &gt;= date_format(#{invoiceRegistrationProductDto.createTimeStart}, '%Y-%m-%d %H:%i:%s')
diff --git a/src/main/resources/mapper/staff/StaffContractMapper.xml b/src/main/resources/mapper/staff/StaffContractMapper.xml
new file mode 100644
index 0000000..ac2ad70
--- /dev/null
+++ b/src/main/resources/mapper/staff/StaffContractMapper.xml
@@ -0,0 +1,15 @@
+<?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.staff.mapper.StaffContractMapper">
+    <select id="staffContractListPage" resultType="com.ruoyi.staff.dto.StaffContractDto">
+        SELECT
+        sc.*
+        FROM staff_contract as sc
+        LEFT JOIN
+        staff_on_job soj ON soj.id = sc.staff_on_job_id
+        where 1=1
+        <if test="staffContract.staffOnJobId != null">
+            AND soj.id = #{staffContract.staffOnJobId}
+        </if>
+    </select>
+</mapper>
diff --git a/src/main/resources/mapper/staff/StaffOnJobMapper.xml b/src/main/resources/mapper/staff/StaffOnJobMapper.xml
index 71eb981..6e0a956 100644
--- a/src/main/resources/mapper/staff/StaffOnJobMapper.xml
+++ b/src/main/resources/mapper/staff/StaffOnJobMapper.xml
@@ -22,12 +22,15 @@
             AND  contract_expire_time &lt;= DATE_FORMAT(#{staffOnJob.entryDateEnd},'%Y-%m-%d')
         </if>
     </select>
-    <select id="staffOnJobList" resultType="com.ruoyi.staff.pojo.StaffOnJob">
+    <select id="staffOnJobList" resultType="com.ruoyi.staff.dto.StaffOnJobDto">
         SELECT
-        *
+        staff_on_job.*,
+        sp.post_name as postName
         FROM staff_on_job
+        LEFT JOIN
+        sys_post sp ON sp.post_id = staff_on_job.sys_post_id
         where 1=1
-        <if test="staffOnJob.staffState != null and staffOnJob.staffState != '' ">
+        <if test="staffOnJob.staffState != null">
             AND staff_state = #{staffOnJob.staffState}
         </if>
         <if test="staffOnJob.staffName != null and staffOnJob.staffName != '' ">

--
Gitblit v1.9.3