From 961ac0196685096572ee838c68585dc8faace8d8 Mon Sep 17 00:00:00 2001
From: sfd <sun.sunshine@163.com>
Date: 星期四, 08 五月 2025 17:08:47 +0800
Subject: [PATCH] Merge branch 'dev' of http://192.168.50.149:8085/r/aps-backend into dev

---
 aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomLineJob.java                                            |  280 +++++++++
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsMaterialStorageManagementMapper.java                     |    5 
 aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomLineJobService.java                                   |   62 ++
 aps-modules/aps-core/src/main/resources/mapper/core/ApsBomHeaderMapper.xml                                         |   12 
 aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlateStandardRequireController.java         |   10 
 aps-modules/aps-core/src/main/java/com/aps/core/service/IApsBomHeaderService.java                                  |   10 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomHeaderServiceImpl.java                          |   47 +
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlatePlanMapper.xml                                         |    5 
 aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireBatchService.java                  |    6 
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireMapper.java                          |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsBomHeaderMapper.java                                     |   13 
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireErrorMapper.java                     |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsBomHeaderController.java                    |    6 
 aps-modules/aps-job/src/main/resources/mapper/job/ApsBomHeaderJobMapper.xml                                        |  158 +++++
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireServiceImpl.java               |   49 
 aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomLineJobMapper.java                                      |   82 ++
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomStockDetailMapper.java            |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlatePlanMapper.java                                     |    5 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBomOrderDetailServiceImpl.java |    4 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireMapper.xml                              |    3 
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBatchMapper.java                     |    5 
 aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomHeaderJobServiceImpl.java                         |  226 +++++++
 aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireService.java                       |    4 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBatchMapper.xml                         |    6 
 aps-modules/aps-job/src/main/resources/mapper/job/ApsBomLineJobMapper.xml                                          |  206 +++++++
 aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomHeaderJobMapper.java                                    |   82 ++
 aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomHeaderJob.java                                          |  169 +++++
 aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomHeaderJobService.java                                 |   68 ++
 aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomLineJobServiceImpl.java                           |   97 +++
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomOrderDetailMapper.java            |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBatchServiceImpl.java          |   57 +
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomOrderDetailMapper.xml                |    4 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireErrorMapper.xml                         |    3 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomStockDetailMapper.xml                |    4 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsMaterialStorageManagementMapper.xml                         |    6 
 35 files changed, 1,667 insertions(+), 35 deletions(-)

diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsBomHeaderController.java b/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsBomHeaderController.java
index 1d7c37f..0aeb3f6 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsBomHeaderController.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsBomHeaderController.java
@@ -103,4 +103,10 @@
     {
         return toAjax(apsBomHeaderService.deleteApsBomHeaderByIds(ids));
     }
+
+    @PostMapping("/test")
+    public void test()
+    {
+        apsBomHeaderService.setBomDataToRedis("FORTUNA");
+    }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlateStandardRequireController.java b/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlateStandardRequireController.java
index 894f904..d084b25 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlateStandardRequireController.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsPlateStandardRequireController.java
@@ -127,4 +127,14 @@
     }
 
 
+    /**
+     * 鐢熸垚閽i噾璁″垝
+     * */
+    @PostMapping("/generatorPlan")
+    public AjaxResult generatorPlan()
+    {
+        apsPlateStandardRequireService.generatorPlan();
+        return success();
+    }
+
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsBomHeaderMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsBomHeaderMapper.java
index ebc5448..a4708dd 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsBomHeaderMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsBomHeaderMapper.java
@@ -1,8 +1,10 @@
 package com.aps.core.mapper;
 
-import java.util.List;
+import com.alibaba.fastjson2.JSONObject;
 import com.aps.core.domain.ApsBomHeader;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
 
 /**
  * BOM Header 鏁版嵁绠$悊Mapper鎺ュ彛
@@ -60,4 +62,13 @@
      * @return 缁撴灉
      */
     public int deleteApsBomHeaderByIds(Long[] ids);
+
+
+    /**
+     * 鏌ヨBOM鏁版嵁 鐢ㄤ簬瀛樺偍鍒皉edis涓�
+     *
+     * @param orgCode BOM Header 鏁版嵁绠$悊
+     * @return BOM Header 鏁版嵁绠$悊闆嗗悎
+     */
+    List<JSONObject> selectBomRedisData(String orgCode);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsMaterialStorageManagementMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsMaterialStorageManagementMapper.java
index dcfe594..33794ce 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsMaterialStorageManagementMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsMaterialStorageManagementMapper.java
@@ -64,4 +64,9 @@
 
 
    int updateMaterialStorageByVersion(BigDecimal remainderStock, Integer version);
+
+   /**
+    * 鍒濆鍖栧墿浣欏簱瀛樻暟閲�
+    * */
+   int initRemainderStock();
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlatePlanMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlatePlanMapper.java
index 96ce218..f354088 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlatePlanMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlatePlanMapper.java
@@ -83,4 +83,9 @@
      * 鏇存柊瀛愯鍒掓湭鍖归厤鏁伴噺
      * */
     int updatePlanUnMatchQtyByVersion(ApsPlatePlan plan);
+
+    /**
+     * 鍒濆鍖� 瀛愪欢宸ュ崟鐨� 鏈尮閰嶆暟閲�
+     * */
+    int initUnMatchQty();
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBatchMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBatchMapper.java
index e71c7d8..99c7704 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBatchMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBatchMapper.java
@@ -60,4 +60,9 @@
      * @return 缁撴灉
      */
     public int deleteApsPlateStandardRequireBatchByIds(Long[] ids);
+
+    /**
+     * 鍙栧嚭涓婁竴鎵规淇℃伅
+     * */
+    ApsPlateStandardRequireBatch selectLastRequireBatch();
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomOrderDetailMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomOrderDetailMapper.java
index 60d4690..9960819 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomOrderDetailMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomOrderDetailMapper.java
@@ -61,4 +61,6 @@
      * @return 缁撴灉
      */
     public int deleteApsPlateStandardRequireBomOrderDetailByIds(Long[] ids);
+
+    int deleteLastPatch(String batchNumber);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomStockDetailMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomStockDetailMapper.java
index 0413500..9dcb767 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomStockDetailMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireBomStockDetailMapper.java
@@ -60,4 +60,6 @@
      * @return 缁撴灉
      */
     public int deleteApsPlateStandardRequireBomStockDetailByIds(Long[] ids);
+
+    int deleteLastPatch(String batchNumber);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireErrorMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireErrorMapper.java
index 12f5b30..6d7a2d1 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireErrorMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireErrorMapper.java
@@ -60,4 +60,6 @@
      * @return 缁撴灉
      */
     public int deleteApsPlateStandardRequireErrorByIds(Long[] ids);
+    
+    int deleteLastPatch(String batchNumber);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireMapper.java
index dfdd85f..a42d1f8 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsPlateStandardRequireMapper.java
@@ -71,4 +71,6 @@
     public List<ApsPlateStandardRequire> selectPlateSupplyGapList(ApsPlateStandardRequire apsPlateStandardRequire);
 
     int batchInsert(List<ApsPlateStandardRequire> requireList);
+
+    int deleteLastPatch(String batchNumber);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsBomHeaderService.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsBomHeaderService.java
index d3172ba..c985f36 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsBomHeaderService.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsBomHeaderService.java
@@ -1,7 +1,8 @@
 package com.aps.core.service;
 
-import java.util.List;
 import com.aps.core.domain.ApsBomHeader;
+
+import java.util.List;
 
 /**
  * BOM Header 鏁版嵁绠$悊Service鎺ュ彛
@@ -58,4 +59,11 @@
      * @return 缁撴灉
      */
     public int deleteApsBomHeaderById(Long id);
+
+
+    /**
+     * 鍚屾BOM鏁版嵁鍒癛edis
+     * @return
+     */
+    public boolean setBomDataToRedis(String orgCode);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireBatchService.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireBatchService.java
index ba3ff13..ac0b987 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireBatchService.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireBatchService.java
@@ -2,6 +2,7 @@
 
 import java.util.List;
 import com.aps.core.domain.ApsPlateStandardRequireBatch;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 閽i噾璁″垝鏍囧噯闇�姹傝鍒掓壒娆¤〃Service鎺ュ彛
@@ -58,4 +59,9 @@
      * @return 缁撴灉
      */
     public int deleteApsPlateStandardRequireBatchById(Long id);
+
+    String getNewBatchNumber();
+
+    @Transactional
+    void initRequireBatch();
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireService.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireService.java
index 4691aaf..51b05ea 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireService.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsPlateStandardRequireService.java
@@ -1,6 +1,7 @@
 package com.aps.core.service;
 
 import com.aps.core.domain.ApsPlateStandardRequire;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
@@ -66,4 +67,7 @@
      * @return
      */
     public List<ApsPlateStandardRequire> selectPlateSupplyGapList(ApsPlateStandardRequire apsPlateStandardRequire);
+
+    @Transactional
+    void generatorPlan();
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomHeaderServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomHeaderServiceImpl.java
index 7ec3fdd..f1edfa2 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomHeaderServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomHeaderServiceImpl.java
@@ -1,12 +1,16 @@
 package com.aps.core.service.impl;
 
-import java.util.List;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
 import com.aps.common.core.utils.DateUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import com.aps.core.mapper.ApsBomHeaderMapper;
 import com.aps.core.domain.ApsBomHeader;
+import com.aps.core.mapper.ApsBomHeaderMapper;
 import com.aps.core.service.IApsBomHeaderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
 
 /**
  * BOM Header 鏁版嵁绠$悊Service涓氬姟灞傚鐞�
@@ -19,6 +23,9 @@
 {
     @Autowired
     private ApsBomHeaderMapper apsBomHeaderMapper;
+
+    @Autowired
+    public RedisTemplate redisTemplate;
 
     /**
      * 鏌ヨBOM Header 鏁版嵁绠$悊
@@ -93,4 +100,36 @@
     {
         return apsBomHeaderMapper.deleteApsBomHeaderById(id);
     }
+
+    /**
+     * 璁剧疆BOM鏁版嵁鍒癛edis
+     * @return
+     */
+    @Override
+    public boolean setBomDataToRedis(String orgCode) {
+        try {
+            List<JSONObject> bomRedisData = apsBomHeaderMapper.selectBomRedisData(orgCode);
+            String nowMainItemCode = "";
+            JSONArray bomLine = new JSONArray();
+            for (int i=0,size=bomRedisData.size();i<size;i++) {
+                JSONObject jsonObject = bomRedisData.get(i);
+                if("".equals(nowMainItemCode)){
+                    nowMainItemCode = jsonObject.getString("mainitemcode");
+                }
+                if(!nowMainItemCode.equals(jsonObject.getString("mainitemcode"))){
+                    redisTemplate.opsForValue().set("BOM:BOM_"+orgCode+"_"+nowMainItemCode, bomLine);
+                    bomLine = new JSONArray();
+                }
+                bomLine.add(jsonObject);
+                nowMainItemCode = jsonObject.getString("mainitemcode");
+                if(i==size-1){
+                    redisTemplate.opsForValue().set("BOM:BOM_"+orgCode+"_"+nowMainItemCode, bomLine);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBatchServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBatchServiceImpl.java
index a0552a7..47f26f1 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBatchServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBatchServiceImpl.java
@@ -1,12 +1,17 @@
 package com.aps.core.service.impl;
 
 import java.util.List;
+
+import cn.hutool.core.util.IdUtil;
 import com.aps.common.core.utils.DateUtils;
+import com.aps.common.security.utils.SecurityUtils;
+import com.aps.core.mapper.*;
+import jakarta.annotation.Resource;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import com.aps.core.mapper.ApsPlateStandardRequireBatchMapper;
 import com.aps.core.domain.ApsPlateStandardRequireBatch;
 import com.aps.core.service.IApsPlateStandardRequireBatchService;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 閽i噾璁″垝鏍囧噯闇�姹傝鍒掓壒娆¤〃Service涓氬姟灞傚鐞�
@@ -19,6 +24,25 @@
 {
     @Autowired
     private ApsPlateStandardRequireBatchMapper apsPlateStandardRequireBatchMapper;
+
+    @Resource
+    ApsMaterialStorageManagementMapper apsMaterialStorageManagementMapper;
+
+    @Resource
+    ApsPlatePlanMapper apsPlatePlanMapper;
+
+    @Resource
+    ApsPlateStandardRequireMapper apsPlateStandardRequireMapper;
+
+    @Resource
+    ApsPlateStandardRequireBomOrderDetailMapper apsPlateStandardRequireBomOrderDetailMapper;
+
+    @Resource
+    ApsPlateStandardRequireBomStockDetailMapper apsPlateStandardRequireBomStockDetailMapper;
+
+    @Resource
+    ApsPlateStandardRequireErrorMapper apsPlateStandardRequireErrorMapper;
+
 
     /**
      * 鏌ヨ閽i噾璁″垝鏍囧噯闇�姹傝鍒掓壒娆¤〃
@@ -93,4 +117,35 @@
     {
         return apsPlateStandardRequireBatchMapper.deleteApsPlateStandardRequireBatchById(id);
     }
+
+    /**
+     * 鐢熸垚鏂版壒娆″彿
+     * */
+    @Override
+    public String getNewBatchNumber() {
+        String batchNum = String.valueOf(IdUtil.getSnowflakeNextId()) ;
+        ApsPlateStandardRequireBatch batchBuilder = ApsPlateStandardRequireBatch.builder()
+                .id(IdUtil.getSnowflakeNextId())
+                .batchNumber(batchNum)
+                .delFlag("0").build();
+        batchBuilder.setCreateBy(SecurityUtils.getUsername());
+        batchBuilder.setCreateTime(DateUtils.getNowDate());
+        apsPlateStandardRequireBatchMapper.insertApsPlateStandardRequireBatch(batchBuilder);
+        return batchNum;
+    }
+
+    @Transactional
+    @Override
+    public void initRequireBatch() {
+        ApsPlateStandardRequireBatch batch=apsPlateStandardRequireBatchMapper.selectLastRequireBatch();
+        if (batch!=null){
+            String batchNumber = batch.getBatchNumber();
+            apsPlateStandardRequireMapper.deleteLastPatch(batchNumber);
+            apsPlateStandardRequireBomOrderDetailMapper.deleteLastPatch(batchNumber);
+            apsPlateStandardRequireBomStockDetailMapper.deleteLastPatch(batchNumber);
+            apsPlateStandardRequireErrorMapper.deleteLastPatch(batchNumber);
+            apsPlatePlanMapper.initUnMatchQty();
+            apsMaterialStorageManagementMapper.initRemainderStock();
+        }
+    }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBomOrderDetailServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBomOrderDetailServiceImpl.java
index e82eee2..bc6c7b0 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBomOrderDetailServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireBomOrderDetailServiceImpl.java
@@ -115,7 +115,9 @@
                 .docNo(platePlan.getDocumentNumber())
                 .beforeProdAmount(stock)
                 .deductionAmount(netRequirement)
-                .afterProdAmount(subtract).build();
+                .afterProdAmount(subtract)
+                .batchNumber(require.getBatchNumber())
+                .build();
         apsPlateStandardRequireBomOrderDetailMapper.insertApsPlateStandardRequireBomOrderDetail(bomOrderDetail);
     }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireServiceImpl.java
index 0e40df7..6181c6d 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlateStandardRequireServiceImpl.java
@@ -3,7 +3,6 @@
 import java.math.BigDecimal;
 import java.util.*;
 
-import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.IdUtil;
 import com.aps.common.core.utils.DateUtils;
 import com.aps.common.security.utils.DictUtils;
@@ -18,6 +17,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.aps.core.service.IApsPlateStandardRequireService;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
@@ -69,6 +69,9 @@
 
     @Resource
     IApsStandardProcessRouteLineService routeLineService;
+
+    @Resource
+    IApsPlateStandardRequireBatchService requireBatchService;
 
     /**
      * 鏌ヨ閽i噾宸ュ崟鏍囧噯闇�姹�
@@ -154,14 +157,18 @@
         return apsPlateStandardRequireMapper.selectPlateSupplyGapList(apsPlateStandardRequire);
     }
 
-    private void generatorPlan(){
+    @Transactional
+    @Override
+    public void generatorPlan(){
 
+        /*鍒濆鍖栨暟鎹�*/
+        requireBatchService.initRequireBatch();
         /*瀹氫箟宸ュ巶涓哄崡閫� */
         String plantCode="FORTUNA";
         /*瀹氫箟涓诲崟绫诲瀷涓洪挘閲戜富鍗�*/
         String mainOrderType = "閽i噾涓讳欢";
         /*鐢熸垚鏂版壒娆″彿*/
-        String batchNum=getBatch();
+        String batchNum= requireBatchService.getNewBatchNumber();
         /*鑾峰彇閽i噾涓诲崟淇℃伅*/
         List<ApsPlatePlan> mainPlans = platePlanMapper.selectPlatePlanByPlantMajor(plantCode,mainOrderType);
         for (ApsPlatePlan mainPlan : mainPlans) {
@@ -215,6 +222,8 @@
         }
         /*鏌ユ壘搴撳瓨锛岃绠楀噣闇�姹傦紝淇濆瓨鍓╀綑搴撳瓨锛屼繚瀛樺簱瀛樻墸鍑忔槑缁�*/
         BigDecimal remainderStock = BigDecimal.ZERO;
+        /*榛樿鍑�闇�姹備负BOM鐢ㄩ噺*/
+        require.setNetRequirement(require.getBomUseAmount());
         Optional<ApsMaterialStorageManagement> itemStorage = getItemStorage(plant, itemNumber);
         if (itemStorage.isPresent()) {
             ApsMaterialStorageManagement storage = itemStorage.get();
@@ -282,33 +291,19 @@
         if (require.getNetRequirement().compareTo(BigDecimal.ZERO) > 0) {
             require.setMatchState("寰呭尮閰�");
             require.setMatchMode("宸ュ崟鍖归厤");
+            /*浣跨敤瀛愪欢宸ュ崟杩涜闇�姹傚尮閰�*/
+            matchRequireAndSubPlan(require);
         }
-        /*浣跨敤瀛愪欢宸ュ崟杩涜闇�姹傚尮閰�*/
-        matchRequireAndSubPlan(require);
-
         allRequires.add(require);
-        /*褰撳墠Bom鑺傜偣澶勭悊瀹屾垚鍚庯紝澶勭悊涓嬬骇BOM*/
-        List<ApsBom> bomLineList = bomLineService.selectApsBomLineList(plant, itemNumber);
-        if (!bomLineList.isEmpty()) {
-            bomLineList.forEach(line -> {
-                getBomRequires(plant, line, batchNum, require.getStartDate(), plan, allRequires, level + 1);
-            });
+        if (require.getNetRequirement().compareTo(BigDecimal.ZERO) > 0) {
+            /*褰撳墠Bom鑺傜偣澶勭悊瀹屾垚鍚庯紝澶勭悊涓嬬骇BOM*/
+            List<ApsBom> bomLineList = bomLineService.selectApsBomLineList(plant, itemNumber);
+            if (!bomLineList.isEmpty()) {
+                bomLineList.forEach(line -> {
+                    getBomRequires(plant, line, batchNum, require.getStartDate(), plan, allRequires, level + 1);
+                });
+            }
         }
-    }
-
-    /**
-     * 鐢熸垚鏂版壒娆″彿
-     * */
-    private  String getBatch() {
-        String batchNum = System.currentTimeMillis() + "";
-        ApsPlateStandardRequireBatch batchBuilder = ApsPlateStandardRequireBatch.builder()
-                .id(IdUtil.getSnowflakeNextId())
-                .batchNumber(batchNum)
-                .delFlag("0").build();
-        batchBuilder.setCreateBy(SecurityUtils.getUsername());
-        batchBuilder.setCreateTime(DateUtils.getNowDate());
-        requireBatchMapper.insertApsPlateStandardRequireBatch(batchBuilder);
-        return batchNum;
     }
     /**
      * 鑾峰彇鐗╂枡搴撳瓨淇℃伅
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsBomHeaderMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsBomHeaderMapper.xml
index 96ca63c..31c225b 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsBomHeaderMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsBomHeaderMapper.xml
@@ -102,4 +102,16 @@
             #{id}
         </foreach>
     </delete>
+
+    <select id="selectBomRedisData" parameterType="String" resultType="com.alibaba.fastjson2.JSONObject">
+        SELECT a.item_code as mainItemCode,f.num as mainStock,b.item_code as subItemCode,b.num as usageNum,c.num as subStock,d.self_made as selfMade FROM aps_bom_header a
+        LEFT JOIN aps_bom_line b on a.bom_header_id=b.bom_header_id
+        LEFT JOIN aps_material_storage_management c on b.item_code=c.item_number
+        LEFT JOIN aps_material_management d on b.item_code=d.item_number
+        LEFT JOIN aps_material_storage_management as f on a.item_code=f.item_number
+        <if test="orgCode != null and orgCode != ''">
+            WHERE a.org_code=#{orgCode} and d.applicable_factories=#{orgCode} and c.applicable_factories=#{orgCode}
+        </if>
+        ORDER BY mainItemCode
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsMaterialStorageManagementMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsMaterialStorageManagementMapper.xml
index 747cd2a..2d391a7 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsMaterialStorageManagementMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsMaterialStorageManagementMapper.xml
@@ -98,4 +98,10 @@
         set remainder_stock=#{remainderStock},version=version+1
         where id=#{id} and version=#{version}
     </update>
+
+    <update id="initRemainderStock">
+        update aps_material_storage_management
+        set remainder_stock=num,version=0
+        where 1=1
+    </update>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlatePlanMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlatePlanMapper.xml
index fccc5a1..99f4e68 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlatePlanMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlatePlanMapper.xml
@@ -306,4 +306,9 @@
         </if>
     </select>
 
+    <update id="initUnMatchQty" >
+        update aps_plate_plan
+            set unmatched_quantity=production_quantity, version=0
+        where   del_flag='0' and professional_affiliation !='0'
+    </update>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBatchMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBatchMapper.xml
index 40b6aeb..7b8f502 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBatchMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBatchMapper.xml
@@ -75,4 +75,10 @@
             #{id}
         </foreach>
     </delete>
+
+    <select id="selectLastRequireBatch" parameterType="Long" resultMap="ApsPlateStandardRequireBatchResult">
+        <include refid="selectApsPlateStandardRequireBatchVo"/>
+        order by create_time desc,id desc
+        limit  1
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomOrderDetailMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomOrderDetailMapper.xml
index 149e3fc..5d6ac40 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomOrderDetailMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomOrderDetailMapper.xml
@@ -125,4 +125,8 @@
             #{id}
         </foreach>
     </delete>
+
+    <update id="deleteLastPatch" parameterType="String">
+        update aps_plate_standard_require_bom_order_detail set del_flag = '1' where batch_number = #{batchNumber}
+    </update>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomStockDetailMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomStockDetailMapper.xml
index e94a2cd..552802d 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomStockDetailMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireBomStockDetailMapper.xml
@@ -118,4 +118,8 @@
             #{id}
         </foreach>
     </delete>
+
+    <update id="deleteLastPatch" parameterType="String">
+        update aps_plate_standard_require_bom_stock_detail set del_flag = '1' where batch_number = #{batchNumber}
+    </update>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireErrorMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireErrorMapper.xml
index 3899980..a59df7c 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireErrorMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireErrorMapper.xml
@@ -100,4 +100,7 @@
             #{id}
         </foreach>
     </delete>
+    <update id="deleteLastPatch" parameterType="String">
+        update aps_plate_standard_require_error set del_flag = '1' where batch_number = #{batchNumber}
+    </update>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireMapper.xml
index ba9c463..3721c3b 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlateStandardRequireMapper.xml
@@ -216,4 +216,7 @@
         )
         </foreach>
     </insert>
+    <update id="deleteLastPatch" parameterType="String">
+        update aps_plate_standard_require set del_flag = '1' where batch_number = #{batchNumber}
+    </update>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomHeaderJob.java b/aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomHeaderJob.java
new file mode 100644
index 0000000..99d151e
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomHeaderJob.java
@@ -0,0 +1,169 @@
+package com.aps.job.domain;
+
+import com.aps.common.core.annotation.Excel;
+import com.aps.common.core.web.domain.BaseEntity;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * BOM Header 鏁版嵁绠$悊瀵硅薄 aps_bom_header_job
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+public class ApsBomHeaderJob extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 涓婚敭ID */
+    private Long id;
+
+    /** bomID */
+    @JsonProperty("HID")
+    @Excel(name = "bomID")
+    private String bomHeaderId;
+
+    /** 鏂欏彿 */
+    @JsonProperty("HItemCode")
+    @Excel(name = "鏂欏彿")
+    private String itemCode;
+
+    /** 鐗╂枡鎻忚堪 */
+    @JsonProperty("HItemName")
+    @Excel(name = "鐗╂枡鎻忚堪")
+    private String itemName;
+
+    /** 鐢熸晥鏃ユ湡 */
+    @JsonProperty("HEffectiveDate")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鐢熸晥鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date startDate;
+
+    /** 澶辨晥鏃ユ湡 */
+    @JsonProperty("HDisableDate")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "澶辨晥鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date endDate;
+
+    /** 宸ュ巶缂栫爜 */
+    @JsonProperty("HOrgName")
+    @Excel(name = "宸ュ巶缂栫爜")
+    private String orgCode;
+
+    @JsonProperty("BOMLines")
+    private List<ApsBomLineJob> bomLines;
+
+    /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */
+    private String delFlag;
+
+    public List<ApsBomLineJob> getBomLines() {
+        return bomLines;
+    }
+
+    public void setBomLines(List<ApsBomLineJob> bomLines) {
+        this.bomLines = bomLines;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setBomHeaderId(String bomHeaderId) 
+    {
+        this.bomHeaderId = bomHeaderId;
+    }
+
+    public String getBomHeaderId() 
+    {
+        return bomHeaderId;
+    }
+
+    public void setItemCode(String itemCode) 
+    {
+        this.itemCode = itemCode;
+    }
+
+    public String getItemCode() 
+    {
+        return itemCode;
+    }
+
+    public void setItemName(String itemName) 
+    {
+        this.itemName = itemName;
+    }
+
+    public String getItemName() 
+    {
+        return itemName;
+    }
+
+    public void setStartDate(Date startDate) 
+    {
+        this.startDate = startDate;
+    }
+
+    public Date getStartDate() 
+    {
+        return startDate;
+    }
+
+    public void setEndDate(Date endDate) 
+    {
+        this.endDate = endDate;
+    }
+
+    public Date getEndDate() 
+    {
+        return endDate;
+    }
+
+    public void setOrgCode(String orgCode) 
+    {
+        this.orgCode = orgCode;
+    }
+
+    public String getOrgCode() 
+    {
+        return orgCode;
+    }
+
+    public void setDelFlag(String delFlag) 
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getDelFlag() 
+    {
+        return delFlag;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("bomHeaderId", getBomHeaderId())
+            .append("itemCode", getItemCode())
+            .append("itemName", getItemName())
+            .append("startDate", getStartDate())
+            .append("endDate", getEndDate())
+            .append("orgCode", getOrgCode())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomLineJob.java b/aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomLineJob.java
new file mode 100644
index 0000000..fa9f869
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/domain/ApsBomLineJob.java
@@ -0,0 +1,280 @@
+package com.aps.job.domain;
+
+import com.aps.common.core.annotation.Excel;
+import com.aps.common.core.web.domain.BaseEntity;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * BOM鏁版嵁绠$悊瀵硅薄 aps_bom_line_job
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+public class ApsBomLineJob extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 涓婚敭ID */
+    private Long id;
+
+    /** bom_line_id */
+    @JsonProperty("LID")
+    @Excel(name = "bom_line_id")
+    private String bomLineId;
+
+    /** 鐖惰妭鐐笲OM ID */
+    @JsonProperty("HID")
+    @Excel(name = "鐖惰妭鐐笲OM ID")
+    private String bomHeaderId;
+
+    /** 鏂欏彿 */
+    @JsonProperty("LItemCode")
+    @Excel(name = "鏂欏彿")
+    private String itemCode;
+
+    /** 鐗╂枡鎻忚堪 */
+    @JsonProperty("LItemName")
+    @Excel(name = "鐗╂枡鎻忚堪")
+    private String itemName;
+
+    /** 鐢熸晥鏃ユ湡 */
+    @JsonProperty("LEffectiveDate")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鐢熸晥鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date startDate;
+
+    /** 澶辨晥鏃ユ湡 */
+    @JsonProperty("LDisableDate")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "澶辨晥鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date endDate;
+
+    /** 宸ュ巶缂栫爜 */
+    @JsonProperty("LOrgName")
+    @Excel(name = "宸ュ巶缂栫爜")
+    private String orgCode;
+
+    /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */
+    private String delFlag;
+
+    /** 鍥惧彿 */
+    @Excel(name = "鍥惧彿")
+    private String drawingNo;
+
+    /** 搴忓彿 */
+    @Excel(name = "搴忓彿")
+    private String processNo;
+
+    /** 鍗曚綅 */
+    @Excel(name = "鍗曚綅")
+    private String unit;
+
+    /** 鏁伴噺 */
+    @JsonProperty("UsageQty")
+    @Excel(name = "鏁伴噺")
+    private BigDecimal num;
+
+    /** 鎬绘暟閲� */
+    @Excel(name = "鎬绘暟閲�")
+    private BigDecimal totalNum;
+
+    /** 鍑嗗宸ユ椂 */
+    @Excel(name = "鍑嗗宸ユ椂")
+    private BigDecimal preparationTime;
+
+    /** 鍔犲伐宸ユ椂 */
+    @Excel(name = "鍔犲伐宸ユ椂")
+    private BigDecimal processingTime;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setBomLineId(String bomLineId) 
+    {
+        this.bomLineId = bomLineId;
+    }
+
+    public String getBomLineId() 
+    {
+        return bomLineId;
+    }
+
+    public void setBomHeaderId(String bomHeaderId) 
+    {
+        this.bomHeaderId = bomHeaderId;
+    }
+
+    public String getBomHeaderId() 
+    {
+        return bomHeaderId;
+    }
+
+    public void setItemCode(String itemCode) 
+    {
+        this.itemCode = itemCode;
+    }
+
+    public String getItemCode() 
+    {
+        return itemCode;
+    }
+
+    public void setItemName(String itemName) 
+    {
+        this.itemName = itemName;
+    }
+
+    public String getItemName() 
+    {
+        return itemName;
+    }
+
+    public void setStartDate(Date startDate) 
+    {
+        this.startDate = startDate;
+    }
+
+    public Date getStartDate() 
+    {
+        return startDate;
+    }
+
+    public void setEndDate(Date endDate) 
+    {
+        this.endDate = endDate;
+    }
+
+    public Date getEndDate() 
+    {
+        return endDate;
+    }
+
+    public void setOrgCode(String orgCode) 
+    {
+        this.orgCode = orgCode;
+    }
+
+    public String getOrgCode() 
+    {
+        return orgCode;
+    }
+
+    public void setDelFlag(String delFlag) 
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getDelFlag() 
+    {
+        return delFlag;
+    }
+
+    public void setDrawingNo(String drawingNo) 
+    {
+        this.drawingNo = drawingNo;
+    }
+
+    public String getDrawingNo() 
+    {
+        return drawingNo;
+    }
+
+    public void setProcessNo(String processNo) 
+    {
+        this.processNo = processNo;
+    }
+
+    public String getProcessNo() 
+    {
+        return processNo;
+    }
+
+    public void setUnit(String unit) 
+    {
+        this.unit = unit;
+    }
+
+    public String getUnit() 
+    {
+        return unit;
+    }
+
+    public void setNum(BigDecimal num) 
+    {
+        this.num = num;
+    }
+
+    public BigDecimal getNum() 
+    {
+        return num;
+    }
+
+    public void setTotalNum(BigDecimal totalNum) 
+    {
+        this.totalNum = totalNum;
+    }
+
+    public BigDecimal getTotalNum() 
+    {
+        return totalNum;
+    }
+
+    public void setPreparationTime(BigDecimal preparationTime) 
+    {
+        this.preparationTime = preparationTime;
+    }
+
+    public BigDecimal getPreparationTime() 
+    {
+        return preparationTime;
+    }
+
+    public void setProcessingTime(BigDecimal processingTime) 
+    {
+        this.processingTime = processingTime;
+    }
+
+    public BigDecimal getProcessingTime() 
+    {
+        return processingTime;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("bomLineId", getBomLineId())
+            .append("bomHeaderId", getBomHeaderId())
+            .append("itemCode", getItemCode())
+            .append("itemName", getItemName())
+            .append("startDate", getStartDate())
+            .append("endDate", getEndDate())
+            .append("orgCode", getOrgCode())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("drawingNo", getDrawingNo())
+            .append("processNo", getProcessNo())
+            .append("unit", getUnit())
+            .append("num", getNum())
+            .append("totalNum", getTotalNum())
+            .append("preparationTime", getPreparationTime())
+            .append("processingTime", getProcessingTime())
+            .toString();
+    }
+}
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomHeaderJobMapper.java b/aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomHeaderJobMapper.java
new file mode 100644
index 0000000..5854349
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomHeaderJobMapper.java
@@ -0,0 +1,82 @@
+package com.aps.job.mapper;
+
+import com.aps.job.domain.ApsBomHeaderJob;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * BOM Header 鏁版嵁绠$悊Mapper鎺ュ彛
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+public interface ApsBomHeaderJobMapper 
+{
+    /**
+     * 鏌ヨBOM Header 鏁版嵁绠$悊
+     * 
+     * @param id BOM Header 鏁版嵁绠$悊涓婚敭
+     * @return BOM Header 鏁版嵁绠$悊
+     */
+    public ApsBomHeaderJob selectApsBomHeaderJobById(Long id);
+
+    /**
+     * 鏌ヨBOM Header 鏁版嵁绠$悊鍒楄〃
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return BOM Header 鏁版嵁绠$悊闆嗗悎
+     */
+    public List<ApsBomHeaderJob> selectApsBomHeaderJobList(ApsBomHeaderJob apsBomHeaderJob);
+
+    /**
+     * 鏂板BOM Header 鏁版嵁绠$悊
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int insertApsBomHeaderJob(ApsBomHeaderJob apsBomHeaderJob);
+
+    /**
+     * 淇敼BOM Header 鏁版嵁绠$悊
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int updateApsBomHeaderJob(ApsBomHeaderJob apsBomHeaderJob);
+
+    /**
+     * 鍒犻櫎BOM Header 鏁版嵁绠$悊
+     * 
+     * @param id BOM Header 鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    public int deleteApsBomHeaderJobById(Long id);
+
+    /**
+     * 鎵归噺鍒犻櫎BOM Header 鏁版嵁绠$悊
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteApsBomHeaderJobByIds(Long[] ids);
+
+    /**
+     * 鎵归噺鎻掑叆BOM Header鏁版嵁
+     * @param list
+     * @return
+     */
+    public int insertApsBomHeaderJobBatch(@Param("list") List<ApsBomHeaderJob> list);
+
+    /**
+     * 鎵归噺鎻掑叆BOM Header鏁版嵁鍒颁笟鍔¤〃
+     * @return
+     */
+    public void insertIntoApsBomHeader();
+
+    /**
+     * 鍒犻櫎BOM Header鏁版嵁
+     * @return
+     */
+    public void deleteApsBomHeader();
+}
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomLineJobMapper.java b/aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomLineJobMapper.java
new file mode 100644
index 0000000..3d2385d
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomLineJobMapper.java
@@ -0,0 +1,82 @@
+package com.aps.job.mapper;
+
+import com.aps.job.domain.ApsBomLineJob;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * BOM鏁版嵁绠$悊Mapper鎺ュ彛
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+public interface ApsBomLineJobMapper 
+{
+    /**
+     * 鏌ヨBOM鏁版嵁绠$悊
+     * 
+     * @param id BOM鏁版嵁绠$悊涓婚敭
+     * @return BOM鏁版嵁绠$悊
+     */
+    public ApsBomLineJob selectApsBomLineJobById(Long id);
+
+    /**
+     * 鏌ヨBOM鏁版嵁绠$悊鍒楄〃
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return BOM鏁版嵁绠$悊闆嗗悎
+     */
+    public List<ApsBomLineJob> selectApsBomLineJobList(ApsBomLineJob apsBomLineJob);
+
+    /**
+     * 鏂板BOM鏁版嵁绠$悊
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int insertApsBomLineJob(ApsBomLineJob apsBomLineJob);
+
+    /**
+     * 淇敼BOM鏁版嵁绠$悊
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int updateApsBomLineJob(ApsBomLineJob apsBomLineJob);
+
+    /**
+     * 鍒犻櫎BOM鏁版嵁绠$悊
+     * 
+     * @param id BOM鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    public int deleteApsBomLineJobById(Long id);
+
+    /**
+     * 鎵归噺鍒犻櫎BOM鏁版嵁绠$悊
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteApsBomLineJobByIds(Long[] ids);
+
+    /**
+     * 鎵归噺鎻掑叆BOM Line鏁版嵁绠$悊
+     * @param list
+     * @return
+     */
+    public int insertApsBomLineJobBatch(@Param("list") List<ApsBomLineJob> list);
+
+    /**
+     * 鎵归噺鎻掑叆BOM Line鏁版嵁绠$悊鍒颁笟鍔¤〃
+     * @return
+     */
+    public void insertIntoApsBomLine();
+
+    /**
+     * 鍒犻櫎BOM Line鏁版嵁
+     */
+    public void deleteApsBomLine() ;
+
+}
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomHeaderJobService.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomHeaderJobService.java
new file mode 100644
index 0000000..2804618
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomHeaderJobService.java
@@ -0,0 +1,68 @@
+package com.aps.job.service;
+
+import com.aps.job.domain.ApsBomHeaderJob;
+
+import java.util.List;
+
+/**
+ * BOM Header 鏁版嵁绠$悊Service鎺ュ彛
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+public interface IApsBomHeaderJobService 
+{
+    /**
+     * 鏌ヨBOM Header 鏁版嵁绠$悊
+     * 
+     * @param id BOM Header 鏁版嵁绠$悊涓婚敭
+     * @return BOM Header 鏁版嵁绠$悊
+     */
+    public ApsBomHeaderJob selectApsBomHeaderJobById(Long id);
+
+    /**
+     * 鏌ヨBOM Header 鏁版嵁绠$悊鍒楄〃
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return BOM Header 鏁版嵁绠$悊闆嗗悎
+     */
+    public List<ApsBomHeaderJob> selectApsBomHeaderJobList(ApsBomHeaderJob apsBomHeaderJob);
+
+    /**
+     * 鏂板BOM Header 鏁版嵁绠$悊
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int insertApsBomHeaderJob(ApsBomHeaderJob apsBomHeaderJob);
+
+    /**
+     * 淇敼BOM Header 鏁版嵁绠$悊
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int updateApsBomHeaderJob(ApsBomHeaderJob apsBomHeaderJob);
+
+    /**
+     * 鎵归噺鍒犻櫎BOM Header 鏁版嵁绠$悊
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑BOM Header 鏁版嵁绠$悊涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteApsBomHeaderJobByIds(Long[] ids);
+
+    /**
+     * 鍒犻櫎BOM Header 鏁版嵁绠$悊淇℃伅
+     * 
+     * @param id BOM Header 鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    public int deleteApsBomHeaderJobById(Long id);
+
+    /**
+     * 鍚屾U9 BOM鏁版嵁
+     * @return
+     */
+    public boolean syncBomData(Integer pageIndex, Integer pageSize, String orgCode, String itemCodeList);
+}
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomLineJobService.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomLineJobService.java
new file mode 100644
index 0000000..2afbb46
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/IApsBomLineJobService.java
@@ -0,0 +1,62 @@
+package com.aps.job.service;
+
+import com.aps.job.domain.ApsBomLineJob;
+
+import java.util.List;
+
+/**
+ * BOM鏁版嵁绠$悊Service鎺ュ彛
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+public interface IApsBomLineJobService 
+{
+    /**
+     * 鏌ヨBOM鏁版嵁绠$悊
+     * 
+     * @param id BOM鏁版嵁绠$悊涓婚敭
+     * @return BOM鏁版嵁绠$悊
+     */
+    public ApsBomLineJob selectApsBomLineJobById(Long id);
+
+    /**
+     * 鏌ヨBOM鏁版嵁绠$悊鍒楄〃
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return BOM鏁版嵁绠$悊闆嗗悎
+     */
+    public List<ApsBomLineJob> selectApsBomLineJobList(ApsBomLineJob apsBomLineJob);
+
+    /**
+     * 鏂板BOM鏁版嵁绠$悊
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int insertApsBomLineJob(ApsBomLineJob apsBomLineJob);
+
+    /**
+     * 淇敼BOM鏁版嵁绠$悊
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    public int updateApsBomLineJob(ApsBomLineJob apsBomLineJob);
+
+    /**
+     * 鎵归噺鍒犻櫎BOM鏁版嵁绠$悊
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑BOM鏁版嵁绠$悊涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteApsBomLineJobByIds(Long[] ids);
+
+    /**
+     * 鍒犻櫎BOM鏁版嵁绠$悊淇℃伅
+     * 
+     * @param id BOM鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    public int deleteApsBomLineJobById(Long id);
+}
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomHeaderJobServiceImpl.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomHeaderJobServiceImpl.java
new file mode 100644
index 0000000..3a1fa14
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomHeaderJobServiceImpl.java
@@ -0,0 +1,226 @@
+package com.aps.job.service.impl;
+
+import cn.hutool.core.util.IdUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.aps.common.core.utils.DateUtils;
+import com.aps.common.core.utils.StringUtils;
+import com.aps.job.domain.ApsBomHeaderJob;
+import com.aps.job.domain.ApsBomLineJob;
+import com.aps.job.domain.ApsWorkOrderJobLog;
+import com.aps.job.mapper.ApsBomHeaderJobMapper;
+import com.aps.job.mapper.ApsBomLineJobMapper;
+import com.aps.job.mapper.ApsWorkOrderJobLogMapper;
+import com.aps.job.service.IApsBomHeaderJobService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * BOM Header 鏁版嵁绠$悊Service涓氬姟灞傚鐞�
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+@Service
+public class ApsBomHeaderJobServiceImpl implements IApsBomHeaderJobService 
+{
+    @Autowired
+    private ApsBomHeaderJobMapper apsBomHeaderJobMapper;
+
+    @Autowired
+    private ApsBomLineJobMapper apsBomLineJobMapper;
+
+    /**
+     * 鑾峰彇璁㈠崟鎺ュ彛
+     * */
+    @Value("${u9.bomJobUrl}")
+    private String getBomUrl;
+
+    @Autowired
+    private ApsWorkOrderJobLogMapper jobLogMapper;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    /**
+     * 鏌ヨBOM Header 鏁版嵁绠$悊
+     * 
+     * @param id BOM Header 鏁版嵁绠$悊涓婚敭
+     * @return BOM Header 鏁版嵁绠$悊
+     */
+    @Override
+    public ApsBomHeaderJob selectApsBomHeaderJobById(Long id)
+    {
+        return apsBomHeaderJobMapper.selectApsBomHeaderJobById(id);
+    }
+
+    /**
+     * 鏌ヨBOM Header 鏁版嵁绠$悊鍒楄〃
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return BOM Header 鏁版嵁绠$悊
+     */
+    @Override
+    public List<ApsBomHeaderJob> selectApsBomHeaderJobList(ApsBomHeaderJob apsBomHeaderJob)
+    {
+        return apsBomHeaderJobMapper.selectApsBomHeaderJobList(apsBomHeaderJob);
+    }
+
+    /**
+     * 鏂板BOM Header 鏁版嵁绠$悊
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertApsBomHeaderJob(ApsBomHeaderJob apsBomHeaderJob)
+    {
+        apsBomHeaderJob.setCreateTime(DateUtils.getNowDate());
+        return apsBomHeaderJobMapper.insertApsBomHeaderJob(apsBomHeaderJob);
+    }
+
+    /**
+     * 淇敼BOM Header 鏁版嵁绠$悊
+     * 
+     * @param apsBomHeaderJob BOM Header 鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateApsBomHeaderJob(ApsBomHeaderJob apsBomHeaderJob)
+    {
+        apsBomHeaderJob.setUpdateTime(DateUtils.getNowDate());
+        return apsBomHeaderJobMapper.updateApsBomHeaderJob(apsBomHeaderJob);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎BOM Header 鏁版嵁绠$悊
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑BOM Header 鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteApsBomHeaderJobByIds(Long[] ids)
+    {
+        return apsBomHeaderJobMapper.deleteApsBomHeaderJobByIds(ids);
+    }
+
+    /**
+     * 鍒犻櫎BOM Header 鏁版嵁绠$悊淇℃伅
+     * 
+     * @param id BOM Header 鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteApsBomHeaderJobById(Long id)
+    {
+        return apsBomHeaderJobMapper.deleteApsBomHeaderJobById(id);
+    }
+
+    @Override
+    public boolean syncBomData(Integer pageIndex, Integer pageSize, String orgCode, String itemCodeList) {
+        try {
+            // 璁剧疆璇锋眰澶�
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            // 璁剧疆璇锋眰浣�
+            while (true) {
+                ApsWorkOrderJobLog jobLog = new ApsWorkOrderJobLog();
+                JSONObject requestBody = new JSONObject();
+                requestBody.put("PageIndex", pageIndex);
+                requestBody.put("PageSize", pageSize);
+                if(!StringUtils.isEmpty(orgCode)){
+                    requestBody.put("OrgCode", orgCode);
+                }
+                // 鍒涘缓HttpEntity瀵硅薄
+                HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
+                // 鍙戦�丳OST璇锋眰
+                ResponseEntity<String> response = restTemplate.postForEntity(getBomUrl, request, String.class);
+                JSONObject responseBodyJson = JSONObject.parseObject(response.getBody());
+                if (response.getStatusCode().is2xxSuccessful() && "200".equals(responseBodyJson.getString("status"))) {
+                    JSONArray jsonArray = responseBodyJson.getJSONArray("data");
+                    if (!jsonArray.isEmpty()) {
+                        List<ApsBomHeaderJob> headerList = new ArrayList<>();
+                        List<ApsBomLineJob> lineList = new ArrayList<>();
+                        for (Object o : jsonArray) {
+                            //o瀵硅薄涓殑灞炴�ц祴鍊肩粰ApsBomHeaderJob瀵硅薄
+                            JSONObject bomHeader = (JSONObject) o;
+                            JSONArray bomLines = bomHeader.getJSONArray("BOMLines");
+                            ApsBomHeaderJob insertBomHeader = new ApsBomHeaderJob();
+                            insertBomHeader.setId(IdUtil.getSnowflakeNextId());
+                            insertBomHeader.setBomHeaderId(bomHeader.getString("HID"));
+                            insertBomHeader.setItemCode(bomHeader.getString("HItemCode"));
+                            insertBomHeader.setItemName(bomHeader.getString("HItemName"));
+                            insertBomHeader.setStartDate(DateUtils.parseDate(bomHeader.getString("HEffectiveDate")));
+                            insertBomHeader.setEndDate(DateUtils.parseDate(bomHeader.getString("HDisableDate")));
+                            insertBomHeader.setOrgCode(bomHeader.getString("HOrgName").contains("娌堥槼")?"FORTUNE":bomHeader.getString("HOrgName").contains("鍗楅��")?"FORTUNA":bomHeader.getString("HOrgName").contains("鍖椾含")?"FORTUBE":bomHeader.getString("HOrgName"));
+                            headerList.add(insertBomHeader);
+                            for(Object line : bomLines){
+                                JSONObject lineJson = (JSONObject) line;
+                                ApsBomLineJob bomLine = new ApsBomLineJob();
+                                bomLine.setId(IdUtil.getSnowflakeNextId());
+                                bomLine.setBomHeaderId(lineJson.getString("HID"));
+                                bomLine.setBomLineId(lineJson.getString("LID"));
+                                bomLine.setItemCode(lineJson.getString("LItemCode"));
+                                bomLine.setItemName(lineJson.getString("LItemName"));
+                                bomLine.setNum(lineJson.getBigDecimal("UsageQty"));
+                                bomLine.setStartDate(DateUtils.parseDate(lineJson.getString("LEffectiveDate")));
+                                bomLine.setEndDate(DateUtils.parseDate(lineJson.getString("LDisableDate")));
+                                bomLine.setOrgCode(lineJson.getString("LOrgName").contains("娌堥槼")?"FORTUNE":lineJson.getString("LOrgName").contains("鍗楅��")?"FORTUNA":lineJson.getString("LOrgName").contains("鍖椾含")?"FORTUBE":lineJson.getString("LOrgName"));
+                                lineList.add(bomLine);
+                            }
+                        }
+                        List<ApsBomHeaderJob> temp1 = new ArrayList<>();
+                        for(int i=0;i<headerList.size();i++){
+                            temp1.add(headerList.get(i));
+                            if(temp1.size()>=20){
+                                apsBomHeaderJobMapper.insertApsBomHeaderJobBatch(temp1);
+                                temp1 = new ArrayList<>();
+                            }
+                        }
+                        List<ApsBomLineJob> temp2 = new ArrayList<>();
+                        for(int j=0;j<lineList.size();j++){
+                            temp2.add(lineList.get(j));
+                            if(temp2.size()>=20){
+                                apsBomLineJobMapper.insertApsBomLineJobBatch(temp2);
+                                temp2 = new ArrayList<>();
+                            }
+                        }
+                        jobLog.setRequestData(requestBody.toJSONString());
+                        jobLog.setPageNum(Long.valueOf(pageIndex));
+                        jobLog.setPageCount(Long.valueOf(pageSize));
+                        jobLog.setCreateTime(DateUtils.getNowDate());
+                        jobLog.setBizType("bom");
+                        jobLog.setResult("header:"+headerList.size() + " line:"+lineList.size());
+                        jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                        pageIndex++;
+                    }else{
+                        break;
+                    }
+                }else{
+                    jobLog.setRequestData(requestBody.toJSONString());
+                    jobLog.setResponseData(response.getBody());
+                    jobLog.setPageNum(Long.valueOf(pageIndex));
+                    jobLog.setPageCount(Long.valueOf(pageSize));
+                    jobLog.setCreateTime(DateUtils.getNowDate());
+                    jobLog.setBizType("bom");
+                    jobLog.setResult("error");
+                    jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                    break;
+                }
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomLineJobServiceImpl.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomLineJobServiceImpl.java
new file mode 100644
index 0000000..8bc1c11
--- /dev/null
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomLineJobServiceImpl.java
@@ -0,0 +1,97 @@
+package com.aps.job.service.impl;
+
+import com.aps.common.core.utils.DateUtils;
+import com.aps.job.domain.ApsBomLineJob;
+import com.aps.job.mapper.ApsBomLineJobMapper;
+import com.aps.job.service.IApsBomLineJobService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * BOM鏁版嵁绠$悊Service涓氬姟灞傚鐞�
+ * 
+ * @author hjy
+ * @date 2025-05-08
+ */
+@Service
+public class ApsBomLineJobServiceImpl implements IApsBomLineJobService 
+{
+    @Autowired
+    private ApsBomLineJobMapper apsBomLineJobMapper;
+
+    /**
+     * 鏌ヨBOM鏁版嵁绠$悊
+     * 
+     * @param id BOM鏁版嵁绠$悊涓婚敭
+     * @return BOM鏁版嵁绠$悊
+     */
+    @Override
+    public ApsBomLineJob selectApsBomLineJobById(Long id)
+    {
+        return apsBomLineJobMapper.selectApsBomLineJobById(id);
+    }
+
+    /**
+     * 鏌ヨBOM鏁版嵁绠$悊鍒楄〃
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return BOM鏁版嵁绠$悊
+     */
+    @Override
+    public List<ApsBomLineJob> selectApsBomLineJobList(ApsBomLineJob apsBomLineJob)
+    {
+        return apsBomLineJobMapper.selectApsBomLineJobList(apsBomLineJob);
+    }
+
+    /**
+     * 鏂板BOM鏁版嵁绠$悊
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertApsBomLineJob(ApsBomLineJob apsBomLineJob)
+    {
+        apsBomLineJob.setCreateTime(DateUtils.getNowDate());
+        return apsBomLineJobMapper.insertApsBomLineJob(apsBomLineJob);
+    }
+
+    /**
+     * 淇敼BOM鏁版嵁绠$悊
+     * 
+     * @param apsBomLineJob BOM鏁版嵁绠$悊
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateApsBomLineJob(ApsBomLineJob apsBomLineJob)
+    {
+        apsBomLineJob.setUpdateTime(DateUtils.getNowDate());
+        return apsBomLineJobMapper.updateApsBomLineJob(apsBomLineJob);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎BOM鏁版嵁绠$悊
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑BOM鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteApsBomLineJobByIds(Long[] ids)
+    {
+        return apsBomLineJobMapper.deleteApsBomLineJobByIds(ids);
+    }
+
+    /**
+     * 鍒犻櫎BOM鏁版嵁绠$悊淇℃伅
+     * 
+     * @param id BOM鏁版嵁绠$悊涓婚敭
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteApsBomLineJobById(Long id)
+    {
+        return apsBomLineJobMapper.deleteApsBomLineJobById(id);
+    }
+}
diff --git a/aps-modules/aps-job/src/main/resources/mapper/job/ApsBomHeaderJobMapper.xml b/aps-modules/aps-job/src/main/resources/mapper/job/ApsBomHeaderJobMapper.xml
new file mode 100644
index 0000000..1eec45e
--- /dev/null
+++ b/aps-modules/aps-job/src/main/resources/mapper/job/ApsBomHeaderJobMapper.xml
@@ -0,0 +1,158 @@
+<?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.aps.job.mapper.ApsBomHeaderJobMapper">
+    
+    <resultMap type="ApsBomHeaderJob" id="ApsBomHeaderJobResult">
+        <result property="id"    column="id"    />
+        <result property="bomHeaderId"    column="bom_header_id"    />
+        <result property="itemCode"    column="item_code"    />
+        <result property="itemName"    column="item_name"    />
+        <result property="startDate"    column="start_date"    />
+        <result property="endDate"    column="end_date"    />
+        <result property="orgCode"    column="org_code"    />
+        <result property="delFlag"    column="del_flag"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectApsBomHeaderJobVo">
+        select id, bom_header_id, item_code, item_name, start_date, end_date, org_code, del_flag, create_by, create_time, update_by, update_time from aps_bom_header_job
+    </sql>
+
+    <select id="selectApsBomHeaderJobList" parameterType="ApsBomHeaderJob" resultMap="ApsBomHeaderJobResult">
+        <include refid="selectApsBomHeaderJobVo"/>
+        <where>  
+            <if test="bomHeaderId != null  and bomHeaderId != ''"> and bom_header_id = #{bomHeaderId}</if>
+            <if test="itemCode != null  and itemCode != ''"> and item_code = #{itemCode}</if>
+            <if test="itemName != null  and itemName != ''"> and item_name like concat('%', #{itemName}, '%')</if>
+            <if test="startDate != null "> and start_date = #{startDate}</if>
+            <if test="endDate != null "> and end_date = #{endDate}</if>
+            <if test="orgCode != null  and orgCode != ''"> and org_code = #{orgCode}</if>
+        </where>
+    </select>
+    
+    <select id="selectApsBomHeaderJobById" parameterType="Long" resultMap="ApsBomHeaderJobResult">
+        <include refid="selectApsBomHeaderJobVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertApsBomHeaderJob" parameterType="ApsBomHeaderJob">
+        insert into aps_bom_header_job
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="bomHeaderId != null">bom_header_id,</if>
+            <if test="itemCode != null">item_code,</if>
+            <if test="itemName != null">item_name,</if>
+            <if test="startDate != null">start_date,</if>
+            <if test="endDate != null">end_date,</if>
+            <if test="orgCode != null">org_code,</if>
+            <if test="delFlag != null">del_flag,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">#{id},</if>
+            <if test="bomHeaderId != null">#{bomHeaderId},</if>
+            <if test="itemCode != null">#{itemCode},</if>
+            <if test="itemName != null">#{itemName},</if>
+            <if test="startDate != null">#{startDate},</if>
+            <if test="endDate != null">#{endDate},</if>
+            <if test="orgCode != null">#{orgCode},</if>
+            <if test="delFlag != null">#{delFlag},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateApsBomHeaderJob" parameterType="ApsBomHeaderJob">
+        update aps_bom_header_job
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="bomHeaderId != null">bom_header_id = #{bomHeaderId},</if>
+            <if test="itemCode != null">item_code = #{itemCode},</if>
+            <if test="itemName != null">item_name = #{itemName},</if>
+            <if test="startDate != null">start_date = #{startDate},</if>
+            <if test="endDate != null">end_date = #{endDate},</if>
+            <if test="orgCode != null">org_code = #{orgCode},</if>
+            <if test="delFlag != null">del_flag = #{delFlag},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteApsBomHeaderJobById" parameterType="Long">
+        delete from aps_bom_header_job where id = #{id}
+    </delete>
+
+    <delete id="deleteApsBomHeaderJobByIds" parameterType="String">
+        delete from aps_bom_header_job where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <insert id="insertApsBomHeaderJobBatch">
+        INSERT INTO aps_bom_header_job (
+        id,
+        bom_header_id,
+        item_code,
+        item_name,
+        start_date,
+        end_date,
+        org_code,
+        create_time
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.id},
+            #{item.bomHeaderId},
+            #{item.itemCode},
+            #{item.itemName},
+            #{item.startDate},
+            #{item.endDate},
+            #{item.orgCode},
+            now()
+            )
+        </foreach>
+    </insert>
+
+    <!-- 鎻掑叆鏁版嵁鍒� aps_bom_header -->
+    <insert id="insertIntoApsBomHeader">
+        INSERT INTO aps_bom_header (
+            id,
+            bom_header_id,
+            item_code,
+            item_name,
+            start_date,
+            end_date,
+            org_code,
+            create_time
+        )
+        SELECT
+            id,
+            bom_header_id,
+            item_code,
+            item_name,
+            start_date,
+            end_date,
+            org_code,
+            now()
+        FROM aps_bom_header_job
+    </insert>
+
+    <!-- 鍒犻櫎 aps_process_route 琛ㄤ腑鐨勬暟鎹� -->
+    <delete id="deleteApsBomHeader">
+        DELETE FROM aps_bom_header
+    </delete>
+
+</mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-job/src/main/resources/mapper/job/ApsBomLineJobMapper.xml b/aps-modules/aps-job/src/main/resources/mapper/job/ApsBomLineJobMapper.xml
new file mode 100644
index 0000000..452300d
--- /dev/null
+++ b/aps-modules/aps-job/src/main/resources/mapper/job/ApsBomLineJobMapper.xml
@@ -0,0 +1,206 @@
+<?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.aps.job.mapper.ApsBomLineJobMapper">
+    
+    <resultMap type="ApsBomLineJob" id="ApsBomLineJobResult">
+        <result property="id"    column="id"    />
+        <result property="bomLineId"    column="bom_line_id"    />
+        <result property="bomHeaderId"    column="bom_header_id"    />
+        <result property="itemCode"    column="item_code"    />
+        <result property="itemName"    column="item_name"    />
+        <result property="startDate"    column="start_date"    />
+        <result property="endDate"    column="end_date"    />
+        <result property="orgCode"    column="org_code"    />
+        <result property="delFlag"    column="del_flag"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="drawingNo"    column="drawing_no"    />
+        <result property="processNo"    column="process_no"    />
+        <result property="unit"    column="unit"    />
+        <result property="num"    column="num"    />
+        <result property="totalNum"    column="total_num"    />
+        <result property="preparationTime"    column="preparation_time"    />
+        <result property="processingTime"    column="processing_time"    />
+    </resultMap>
+
+    <sql id="selectApsBomLineJobVo">
+        select id, bom_line_id, bom_header_id, item_code, item_name, start_date, end_date, org_code, del_flag, create_by, create_time, update_by, update_time, drawing_no, process_no, unit, num, total_num, preparation_time, processing_time from aps_bom_line_job
+    </sql>
+
+    <select id="selectApsBomLineJobList" parameterType="ApsBomLineJob" resultMap="ApsBomLineJobResult">
+        <include refid="selectApsBomLineJobVo"/>
+        <where>  
+            <if test="bomLineId != null  and bomLineId != ''"> and bom_line_id = #{bomLineId}</if>
+            <if test="bomHeaderId != null  and bomHeaderId != ''"> and bom_header_id = #{bomHeaderId}</if>
+            <if test="itemCode != null  and itemCode != ''"> and item_code = #{itemCode}</if>
+            <if test="itemName != null  and itemName != ''"> and item_name like concat('%', #{itemName}, '%')</if>
+            <if test="startDate != null "> and start_date = #{startDate}</if>
+            <if test="endDate != null "> and end_date = #{endDate}</if>
+            <if test="orgCode != null  and orgCode != ''"> and org_code = #{orgCode}</if>
+            <if test="drawingNo != null  and drawingNo != ''"> and drawing_no = #{drawingNo}</if>
+            <if test="processNo != null  and processNo != ''"> and process_no = #{processNo}</if>
+            <if test="unit != null  and unit != ''"> and unit = #{unit}</if>
+            <if test="num != null "> and num = #{num}</if>
+            <if test="totalNum != null "> and total_num = #{totalNum}</if>
+            <if test="preparationTime != null "> and preparation_time = #{preparationTime}</if>
+            <if test="processingTime != null "> and processing_time = #{processingTime}</if>
+        </where>
+    </select>
+    
+    <select id="selectApsBomLineJobById" parameterType="Long" resultMap="ApsBomLineJobResult">
+        <include refid="selectApsBomLineJobVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertApsBomLineJob" parameterType="ApsBomLineJob">
+        insert into aps_bom_line_job
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="bomLineId != null">bom_line_id,</if>
+            <if test="bomHeaderId != null">bom_header_id,</if>
+            <if test="itemCode != null">item_code,</if>
+            <if test="itemName != null">item_name,</if>
+            <if test="startDate != null">start_date,</if>
+            <if test="endDate != null">end_date,</if>
+            <if test="orgCode != null">org_code,</if>
+            <if test="delFlag != null">del_flag,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="drawingNo != null">drawing_no,</if>
+            <if test="processNo != null">process_no,</if>
+            <if test="unit != null">unit,</if>
+            <if test="num != null">num,</if>
+            <if test="totalNum != null">total_num,</if>
+            <if test="preparationTime != null">preparation_time,</if>
+            <if test="processingTime != null">processing_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">#{id},</if>
+            <if test="bomLineId != null">#{bomLineId},</if>
+            <if test="bomHeaderId != null">#{bomHeaderId},</if>
+            <if test="itemCode != null">#{itemCode},</if>
+            <if test="itemName != null">#{itemName},</if>
+            <if test="startDate != null">#{startDate},</if>
+            <if test="endDate != null">#{endDate},</if>
+            <if test="orgCode != null">#{orgCode},</if>
+            <if test="delFlag != null">#{delFlag},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="drawingNo != null">#{drawingNo},</if>
+            <if test="processNo != null">#{processNo},</if>
+            <if test="unit != null">#{unit},</if>
+            <if test="num != null">#{num},</if>
+            <if test="totalNum != null">#{totalNum},</if>
+            <if test="preparationTime != null">#{preparationTime},</if>
+            <if test="processingTime != null">#{processingTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateApsBomLineJob" parameterType="ApsBomLineJob">
+        update aps_bom_line_job
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="bomLineId != null">bom_line_id = #{bomLineId},</if>
+            <if test="bomHeaderId != null">bom_header_id = #{bomHeaderId},</if>
+            <if test="itemCode != null">item_code = #{itemCode},</if>
+            <if test="itemName != null">item_name = #{itemName},</if>
+            <if test="startDate != null">start_date = #{startDate},</if>
+            <if test="endDate != null">end_date = #{endDate},</if>
+            <if test="orgCode != null">org_code = #{orgCode},</if>
+            <if test="delFlag != null">del_flag = #{delFlag},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="drawingNo != null">drawing_no = #{drawingNo},</if>
+            <if test="processNo != null">process_no = #{processNo},</if>
+            <if test="unit != null">unit = #{unit},</if>
+            <if test="num != null">num = #{num},</if>
+            <if test="totalNum != null">total_num = #{totalNum},</if>
+            <if test="preparationTime != null">preparation_time = #{preparationTime},</if>
+            <if test="processingTime != null">processing_time = #{processingTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteApsBomLineJobById" parameterType="Long">
+        delete from aps_bom_line_job where id = #{id}
+    </delete>
+
+    <delete id="deleteApsBomLineJobByIds" parameterType="String">
+        delete from aps_bom_line_job where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <insert id="insertApsBomLineJobBatch">
+        INSERT INTO aps_bom_line_job (
+        id,
+        bom_line_id,
+        bom_header_id,
+        item_code,
+        item_name,
+        start_date,
+        end_date,
+        org_code,
+        num,
+        create_time
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.id},
+            #{item.bomLineId},
+            #{item.bomHeaderId},
+            #{item.itemCode},
+            #{item.itemName},
+            #{item.startDate},
+            #{item.endDate},
+            #{item.orgCode},
+            #{item.num},
+            now()
+            )
+        </foreach>
+    </insert>
+
+    <!-- 鎻掑叆鏁版嵁鍒� aps_bom_line -->
+    <insert id="insertIntoApsBomLine">
+        INSERT INTO aps_bom_line (
+            id,
+            bom_line_id,
+            bom_header_id,
+            item_code,
+            item_name,
+            start_date,
+            end_date,
+            org_code,
+            num,
+            create_time
+        )
+        SELECT
+            id,
+            bom_line_id,
+            bom_header_id,
+            item_code,
+            item_name,
+            start_date,
+            end_date,
+            org_code,
+            num,
+            now()
+        FROM aps_bom_line_job
+    </insert>
+
+    <!-- 鍒犻櫎 aps_process_route 琛ㄤ腑鐨勬暟鎹� -->
+    <delete id="deleteApsBomLine">
+        DELETE FROM aps_bom_line
+    </delete>
+
+</mapper>
\ No newline at end of file

--
Gitblit v1.9.3