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

---
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java                 |  630 +++++++++++++++++++++++++++
 aps-modules/aps-job/src/main/java/com/aps/job/util/AbstractQuartzJob.java                                          |    6 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessStatServiceImpl.java          |   19 
 aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialStorageManagementJobServiceImpl.java         |   11 
 aps-modules/aps-core/src/main/java/com/aps/core/enums/PLAN_TASK_STATUS.java                                        |    4 
 aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsGasPipingRouteStatMapper.java                            |   39 +
 aps-modules/aps-core/src/main/resources/mapper/core/ApsBomHeaderMapper.xml                                         |   11 
 aps-modules/aps-core/src/main/java/com/aps/core/service/IApsGasPipingRouteStatService.java                         |   17 
 aps-modules/aps-core/src/main/java/com/aps/core/service/IApsBomHeaderService.java                                  |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomHeaderServiceImpl.java                          |    4 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java                           |   39 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteLineServiceImpl.java           |   22 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteHeaderServiceImpl.java         |    5 
 aps-common/aps-common-redis/src/main/java/com/aps/common/redis/service/RedisLockUtils.java                         |    3 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireBatchServiceImpl.java |   18 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireErrorServiceImpl.java |   21 
 aps-modules/aps-core/src/main/java/com/aps/core/controller/mainPlan/ApsBomHeaderController.java                    |    9 
 aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomLineJobMapper.java                                      |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/domain/ApsGasPipingRouteStat.java                                  |   50 +
 aps-modules/aps-core/src/main/java/com/aps/core/controller/ApsGasPipingRouteStatController.java                    |   32 +
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireErrorMapper.xml                |    4 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessShopStatServiceImpl.java      |    5 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomStockDetailMapper.xml       |    4 
 aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsBomHeaderJobServiceImpl.java                         |   15 
 aps-modules/aps-job/src/main/java/com/aps/job/mapper/ApsBomHeaderJobMapper.java                                    |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlatePlanServiceImpl.java                 |    5 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireMapper.xml                     |    2 
 aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireBatchService.java         |    2 
 aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialManagementJobServiceImpl.java                |   10 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireServiceImpl.java      |   46 -
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomOrderDetailMapper.xml       |    2 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsGasPipingRouteStatMapper.xml                                |  263 +++++++++-
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomServiceImpl.java                                |    4 
 aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsStandardProcessRouteHeaderJobServiceImpl.java        |    7 
 aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsWeldSeamStandardJobServiceImpl.java                  |   26 
 aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireErrorService.java         |    4 
 aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsMaterialStorageManagementServiceImpl.java          |    9 
 aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateProcessStatMapper.xml                         |   10 
 38 files changed, 1,184 insertions(+), 180 deletions(-)

diff --git a/aps-common/aps-common-redis/src/main/java/com/aps/common/redis/service/RedisLockUtils.java b/aps-common/aps-common-redis/src/main/java/com/aps/common/redis/service/RedisLockUtils.java
index 4460773..1dafb95 100644
--- a/aps-common/aps-common-redis/src/main/java/com/aps/common/redis/service/RedisLockUtils.java
+++ b/aps-common/aps-common-redis/src/main/java/com/aps/common/redis/service/RedisLockUtils.java
@@ -29,6 +29,9 @@
      * 鍒ゆ柇鏄惁瀛樺湪閿�
      * */
     public boolean existLock(String key,String value){
+        if(null==this.redisTemplate.opsForValue().get(key)){
+            return false;
+        }
         return this.redisTemplate.opsForValue().get(key).equals(value);
     }
 
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/controller/ApsGasPipingRouteStatController.java b/aps-modules/aps-core/src/main/java/com/aps/core/controller/ApsGasPipingRouteStatController.java
index b75f897..96d4b38 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/controller/ApsGasPipingRouteStatController.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/controller/ApsGasPipingRouteStatController.java
@@ -16,6 +16,7 @@
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 姘斾綋绠¤矾浜ц兘璐熻浇缁熻Controller
@@ -62,7 +63,7 @@
     /**
      * 鑾峰彇姘斾綋绠¤矾浜ц兘璐熻浇缁熻璇︾粏淇℃伅
      */
-    @Operation(summary = "鑾峰彇姘斾綋绠¤矾浜ц兘璐熻浇缁熻璇︾粏淇℃伅", description = "鏍规嵁id鑾峰彇")
+    @Operation(summary = "鑾峰彇姘斾綋绠¤矾浜ц兘璐熻浇缁熻璇︾粏淇℃伅", description = "鏍规嵁ID鏌ヨ")
     @RequiresPermissions("aps:apsGasPipingRouteStat:query")
     @GetMapping(value = "/{id}")
     public AjaxResult getInfo(@PathVariable("id") String id)
@@ -73,7 +74,7 @@
     /**
      * 鏂板姘斾綋绠¤矾浜ц兘璐熻浇缁熻
      */
-    @Operation(summary = "鏂板姘斾綋绠¤矾浜ц兘璐熻浇缁熻", description = "鍗曚釜鏂板")
+    @Operation(summary = "鏂板姘斾綋绠¤矾浜ц兘璐熻浇缁熻", description = "鏂板")
     @RequiresPermissions("aps:apsGasPipingRouteStat:add")
     @Log(title = "姘斾綋绠¤矾浜ц兘璐熻浇缁熻", businessType = BusinessType.INSERT)
     @PostMapping
@@ -85,7 +86,7 @@
     /**
      * 淇敼姘斾綋绠¤矾浜ц兘璐熻浇缁熻
      */
-    @Operation(summary = "淇敼姘斾綋绠¤矾浜ц兘璐熻浇缁熻", description = "鍗曚釜淇敼")
+    @Operation(summary = "淇敼姘斾綋绠¤矾浜ц兘璐熻浇缁熻", description = "淇敼")
     @RequiresPermissions("aps:apsGasPipingRouteStat:edit")
     @Log(title = "姘斾綋绠¤矾浜ц兘璐熻浇缁熻", businessType = BusinessType.UPDATE)
     @PutMapping
@@ -97,7 +98,7 @@
     /**
      * 鍒犻櫎姘斾綋绠¤矾浜ц兘璐熻浇缁熻
      */
-    @Operation(summary = "鍒犻櫎姘斾綋绠¤矾浜ц兘璐熻浇缁熻", description = "鎵归噺鍒犻櫎")
+    @Operation(summary = "鍒犻櫎姘斾綋绠¤矾浜ц兘璐熻浇缁熻", description = "鍒犻櫎")
     @RequiresPermissions("aps:apsGasPipingRouteStat:remove")
     @Log(title = "姘斾綋绠¤矾浜ц兘璐熻浇缁熻", businessType = BusinessType.DELETE)
 	@DeleteMapping("/{ids}")
@@ -105,6 +106,29 @@
     {
         return toAjax(apsGasPipingRouteStatService.deleteApsGasPipingRouteStatByIds(ids));
     }
+    
+    /**
+     * 鐢熸垚姘斾綋绠¤矾浜ц兘璐熻浇缁熻鏁版嵁
+     */
+    @Operation(summary = "鐢熸垚姘斾綋绠¤矾浜ц兘璐熻浇缁熻鏁版嵁", description = "鏍规嵁棰勬祴鏁版嵁鍜屽伐鍗曟暟鎹敓鎴愮粺璁℃暟鎹�")
+    @RequiresPermissions("aps:apsGasPipingRouteStat:generate")
+    @Log(title = "姘斾綋绠¤矾浜ц兘璐熻浇缁熻", businessType = BusinessType.INSERT)
+    @PostMapping("/generate")
+    public AjaxResult generateGasPipingRouteStatData()
+    {
+        return toAjax(apsGasPipingRouteStatService.generateGasPipingRouteStatData());
+    }
+    
+    /**
+     * 鑱氬悎姘斾綋绠¤矾浜ц兘璐熻浇缁熻鏁版嵁
+     */
+    @Operation(summary = "鑱氬悎姘斾綋绠¤矾浜ц兘璐熻浇缁熻鏁版嵁", description = "鑱氬悎缁熻鏁版嵁锛屾敮鎸佸姩鎬侀�夋嫨琛岀淮搴�(rowGroupBy)杩涜鑱氬悎锛屽鎸夊伐搴忓悕绉般�佽溅闂淬�佸伐鍘傘�佷笓涓氱瓑")
+    @RequiresPermissions("aps:apsGasPipingRouteStat:aggregate")
+    @PostMapping("/aggregate")
+    public AjaxResult aggregateGasPipingRouteStat(@RequestBody Map<String, Object> params)
+    {
+        return success(apsGasPipingRouteStatService.aggregateGasPipingRouteStat(params));
+    }
 
     @Operation(summary = "璁$畻姘斾綋绠¤矾浜ц兘璐熻浇缁熻", description = "璁$畻")
     @PostMapping("/computeCapacity")
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 433c072..d1342ca 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
@@ -129,7 +129,8 @@
     @PostMapping("/setBomDataToRedis")
     public void setBomDataToRedis()
     {
-        apsBomHeaderService.setBomDataToRedis("");
+        apsBomHeaderService.setBomDataToRedis("FORTUNA");
+        //apsBomHeaderService.setBomDataToRedis("FORTUNE");
     }
 
     @PostMapping("/test")
@@ -137,4 +138,10 @@
     {
         apsBomHeaderService.setBomDataToRedis("FORTUNA");
     }
+
+    @GetMapping("/getBomRdsCount/{orgCode}")
+    public Integer getBomRdsCount(String orgCode)
+    {
+        return apsBomHeaderService.getBomKeys(orgCode);
+    }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/domain/ApsGasPipingRouteStat.java b/aps-modules/aps-core/src/main/java/com/aps/core/domain/ApsGasPipingRouteStat.java
index a803376..1a76989 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/domain/ApsGasPipingRouteStat.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/domain/ApsGasPipingRouteStat.java
@@ -61,17 +61,18 @@
     private BigDecimal processTotalTime;
 
     /** 璁″垝寮�宸ユ棩 */
-    @Excel(name = "璁″垝寮�宸ユ棩", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "璁″垝寮�宸ユ棩", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "璁″垝寮�宸ユ棩", type = "Date")
     private Date processPlanStartDay;
 
     /** 璁捐宸ユ椂 */
     @Excel(name = "璁捐宸ユ椂")
-    @Schema(description = "璁捐宸ユ椂", type = "Long")
-    private Long designTimes;
+    @Schema(description = "璁捐宸ユ椂", type = "BigDecimal")
+    private BigDecimal designTimes;
 
     /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */
-    @Schema(description = "鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�", type = "String")
+    @Schema(description = "鍒犻櫎鏍囧織", type = "String")
     private String delFlag;
 
     /** 宸ュ簭鍚嶇О */
@@ -99,7 +100,7 @@
     @Schema(description = "璁捐浜ц兘", type = "BigDecimal")
     private BigDecimal designCapacity;
 
-    /** 璁捐浜ц兘 */
+    /** 涓撲笟 */
     @Excel(name = "涓撲笟")
     @Schema(description = "涓撲笟", type = "String")
     private String major;
@@ -119,13 +120,38 @@
     @Schema(description = "鏃�", type = "String")
     private String planStartDay;
 
+    /** 璁″垝瀹屾垚鏃� */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "璁″垝瀹屾垚鏃�", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "璁″垝瀹屾垚鏃�", type = "Date")
+    private Date processPlanEndDay;
+
+    /** 璁㈠崟璁″垝瀹屾垚鏃� */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "璁㈠崟璁″垝瀹屾垚鏃�", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "璁㈠崟璁″垝瀹屾垚鏃�", type = "Date")
+    private Date orderPlanEndDay;
+
+    /** 璀﹀憡 */
+    @Excel(name = "璀﹀憡")
+    @Schema(description = "璀﹀憡", type = "Boolean")
+    private Boolean warning;
+    
+    /** 宸ュ巶 */
+    @Excel(name = "宸ュ巶")
+    @Schema(description = "宸ュ巶", type = "String")
+    private String plant;
+    
+    /** 杞﹂棿 */
+    @Excel(name = "杞﹂棿")
+    @Schema(description = "杞﹂棿", type = "String")
+    private String workshop;
+    
     /** 鎵规鍙� */
     @Excel(name = "鎵规鍙�")
+    @Schema(description = "鎵规鍙�", type = "String")
     private String batchNumber;
-
-    /** 宸ュ巶 */
-    private String plant;
-
+    
     @Transient
     private String searchStartDate;
 
@@ -135,14 +161,8 @@
     @Transient
     private String searchType;
 
-    private Boolean warning;
     private Integer num;
     private BigDecimal routeProcessNumber;
-    private Date orderPlanEndDay;
-    /** 璁″垝瀹屾垚鏃� */
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @Excel(name = "璁″垝瀹屽伐鏃�", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
-    private Date processPlanEndDay;
 
     @Override
     public String toString() {
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/enums/PLAN_TASK_STATUS.java b/aps-modules/aps-core/src/main/java/com/aps/core/enums/PLAN_TASK_STATUS.java
index ec1945d..1714dab 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/enums/PLAN_TASK_STATUS.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/enums/PLAN_TASK_STATUS.java
@@ -2,8 +2,8 @@
 
 public enum PLAN_TASK_STATUS {
     IN_PROCESS("InProgress","杩涜涓�"),
-    FINISHED("Finished","瀹屾垚");
-
+    FINISHED("Finished","瀹屾垚"),
+    ERROR("Error","澶辫触");
     private String code;
     private String desc;
 
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsGasPipingRouteStatMapper.java b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsGasPipingRouteStatMapper.java
index 580dbfe..d2a255c 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsGasPipingRouteStatMapper.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/mapper/ApsGasPipingRouteStatMapper.java
@@ -4,6 +4,7 @@
 import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 姘斾綋绠¤矾浜ц兘璐熻浇缁熻Mapper鎺ュ彛
@@ -69,7 +70,6 @@
      */
     public int deleteApsGasPipingRouteStatByBatchNum(String batchNumber);
 
-
     /**
      * 鎵归噺鎻掑叆绠¤矾姘旀煖浜ц兘鏁版嵁
      * @param apsGasPipingRouteStatList
@@ -78,4 +78,41 @@
     public int insertApsGasPipingRouteStatBatch(List<ApsGasPipingRouteStat> apsGasPipingRouteStatList);
 
     List<ApsGasPipingRouteStat> queryTempStat();
+    
+    /**
+     * 鍒犻櫎鎵�鏈夋皵浣撶璺骇鑳借礋杞界粺璁℃暟鎹�
+     * 
+     * @return 缁撴灉
+     */
+    public int deleteAll();
+    
+    /**
+     * 鑱斿悎鏌ヨ鎵嬪伐姘斾綋棰勬祴鏁版嵁鐩稿叧淇℃伅
+     * 
+     * @return 鎵嬪伐姘斾綋棰勬祴鏁版嵁鍙婂叧鑱斾俊鎭�
+     */
+    public List<Map<String, Object>> selectPredictionRouteData();
+    
+    /**
+     * 鑱斿悎鏌ヨ鎵嬪伐姘斾綋宸ュ崟鏁版嵁鐩稿叧淇℃伅
+     * 
+     * @return 鎵嬪伐姘斾綋宸ュ崟鏁版嵁鍙婂叧鑱斾俊鎭�
+     */
+    public List<Map<String, Object>> selectMoRouteData();
+
+    /**
+     * 鏍规嵁鏃堕棿缁村害鑱氬悎鏌ヨ缁熻鏁版嵁
+     * 
+     * @param params 鏌ヨ鍙傛暟锛屽寘鍚椂闂磋寖鍥村拰杩囨护鏉′欢
+     * @return 鎸夊伐搴忓悕绉板拰鏃堕棿缁村害鑱氬悎鐨勬暟鎹�
+     */
+    public List<Map<String, Object>> selectAggregatedStatData(Map<String, Object> params);
+
+    /**
+     * 鏌ヨ鍘熷缁熻鏁版嵁锛堜笉杩涜鑱氬悎锛�
+     * 
+     * @param params 鏌ヨ鍙傛暟
+     * @return 鍘熷缁熻鏁版嵁鍒楄〃
+     */
+    public List<Map<String, Object>> selectRawStatData(Map<String, Object> params);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireBatchService.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireBatchService.java
index 7e619a5..aeedfb3 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireBatchService.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireBatchService.java
@@ -63,5 +63,5 @@
     String getNewBatchNumber();
 
     @Transactional
-    void initRequireBatch();
+    void initRequireBatch(String batchNumber);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireErrorService.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireErrorService.java
index 25bf22c..d3958e1 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireErrorService.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/ApsPlate/IApsPlateStandardRequireErrorService.java
@@ -1,6 +1,8 @@
 package com.aps.core.service.ApsPlate;
 
 import java.util.List;
+
+import com.aps.core.domain.ApsPlate.ApsPlateStandardRequire;
 import com.aps.core.domain.ApsPlate.ApsPlateStandardRequireError;
 
 /**
@@ -58,4 +60,6 @@
      * @return 缁撴灉
      */
     public int deleteApsPlateStandardRequireErrorById(Long id);
+
+    void saveRequireError(ApsPlateStandardRequire require, String message);
 }
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 c985f36..794b14f 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
@@ -66,4 +66,6 @@
      * @return
      */
     public boolean setBomDataToRedis(String orgCode);
+
+    Integer getBomKeys(String orgCode);
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsGasPipingRouteStatService.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsGasPipingRouteStatService.java
index ced6c54..bd738df 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsGasPipingRouteStatService.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/IApsGasPipingRouteStatService.java
@@ -6,6 +6,7 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 姘斾綋绠¤矾浜ц兘璐熻浇缁熻Service鎺ュ彛
@@ -88,4 +89,20 @@
 
     @Transactional
     void saveGasPipingRoutStateList();
+
+    /**
+     * 鏍规嵁鎵嬪伐姘斾綋棰勬祴鏁版嵁鍜屾墜宸ユ皵浣撳伐鍗曟暟鎹敓鎴愮粺璁℃暟鎹�
+     * 
+     * @return 缁撴灉
+     */
+    @Transactional
+    public int generateGasPipingRouteStatData();
+    
+    /**
+     * 鑱氬悎姘斾綋绠¤矾浜ц兘璐熻浇缁熻鏁版嵁
+     * 
+     * @param params 鑱氬悎鍙傛暟
+     * @return 鑱氬悎缁撴灉
+     */
+    public Map<String, Object> aggregateGasPipingRouteStat(Map<String, Object> params);
 }
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 e5ab958..939cd2b 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
@@ -131,4 +131,8 @@
         }
         return true;
     }
+    @Override
+    public Integer getBomKeys(String orgCode){
+        return redisTemplate.keys("BOM:BOM_"+orgCode+"*").size();
+    }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomServiceImpl.java
index 0b9717b..bd7b3c8 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsBomServiceImpl.java
@@ -140,10 +140,6 @@
                 bomLineList.add(apsBom);
             }
         }
-//        else {
-//            bomLineList = selectApsBomLineList(plant, itemNumber);
-//        }
-
         return bomLineList;
     }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java
index 756bec0..99c75aa 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsGasPipingRouteStatServiceImpl.java
@@ -6,9 +6,7 @@
 import com.aps.common.core.utils.uuid.IdUtils;
 import com.aps.common.security.utils.SecurityUtils;
 import com.aps.core.domain.*;
-import com.aps.core.mapper.ApsGasPipelineCapacityPlanMapper;
-import com.aps.core.mapper.ApsGasPipingPlanMapper;
-import com.aps.core.mapper.ApsGasPipingRouteStatMapper;
+import com.aps.core.mapper.*;
 import com.aps.core.service.IApsGasMaterialUsageService;
 import com.aps.core.service.IApsGasPipingRouteStatService;
 import com.aps.core.service.IApsStandardProcessService;
@@ -1009,4 +1007,630 @@
         log.info("鎵归噺鎻掑叆鏁版嵁瀹屾垚,batchNum:"+batchNum);
     }
 
+    /**
+     * 鏍规嵁鎵嬪伐姘斾綋棰勬祴鏁版嵁鍜屾墜宸ユ皵浣撳伐鍗曟暟鎹敓鎴愮粺璁℃暟鎹�
+     * 
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional
+    public int generateGasPipingRouteStatData() {
+        int count = 0;
+        
+        // 娓呯┖涔嬪墠鐨勬暟鎹�
+        apsGasPipingRouteStatMapper.deleteAll();
+        
+        // 鐢熸垚鎵规鍙�
+        String batchNumber = IdUtils.fastSimpleUUID();
+        List<ApsGasPipingRouteStat> statList = new ArrayList<>();
+        
+        // 澶勭悊鎵嬪伐姘斾綋棰勬祴鏁版嵁 - 浣跨敤鑱斿悎鏌ヨ鑾峰彇鎵�鏈夌浉鍏虫暟鎹�
+        List<Map<String, Object>> predictionDataList = apsGasPipingRouteStatMapper.selectPredictionRouteData();
+        
+        // 鎸夌墿鏂欎唬鐮佸垎缁勶紝渚夸簬澶勭悊鍚屼竴鐗╂枡鐨勪笉鍚屽伐搴�
+        Map<String, List<Map<String, Object>>> predictionGroups = predictionDataList.stream()
+                .collect(Collectors.groupingBy(data -> data.get("material_code").toString()));
+        
+        // 澶勭悊姣忎釜鐗╂枡鐨勫伐鑹鸿矾绾�
+        for (String materialCode : predictionGroups.keySet()) {
+            List<Map<String, Object>> materialData = predictionGroups.get(materialCode);
+            
+            // 鎸夊伐搴忓彿鎺掑簭
+            materialData.sort((a, b) -> {
+                String numA = a.get("process_number").toString();
+                String numB = b.get("process_number").toString();
+                return numA.compareTo(numB);
+            });
+            
+            // 鑾峰彇鎵�鏈夊伐搴忕殑淇℃伅骞跺垱寤虹粺璁¤褰�
+            List<ApsGasPipingRouteStat> processList = new ArrayList<>();
+            for (Map<String, Object> data : materialData) {
+                ApsGasPipingRouteStat stat = new ApsGasPipingRouteStat();
+                stat.setId(IdUtils.fastSimpleUUID());
+                stat.setWorkOrderNo(""); // 棰勬祴鏁版嵁娌℃湁宸ュ崟鍙�
+                stat.setItemNumber(data.get("material_code").toString());
+                stat.setProcessName(data.get("process_name").toString());
+                stat.setRoadProcessNumber(new BigDecimal(data.get("process_number").toString()));
+                
+                // 鐢熶骇鏁伴噺鍜屾爣鍑嗗伐鏃�
+                BigDecimal quantity = new BigDecimal(data.get("predict_quantity").toString()).setScale(4, RoundingMode.HALF_UP);
+                BigDecimal standardTime = new BigDecimal(data.get("standard_time").toString()).setScale(4, RoundingMode.HALF_UP);
+                
+                stat.setProductionQuantity(quantity);
+                stat.setStandardTime(standardTime);
+                stat.setProcessTotalTime(standardTime.multiply(quantity).setScale(4, RoundingMode.HALF_UP));
+                
+                // 宸ュ巶銆佷笓涓氬拰杞﹂棿
+                stat.setPlant(data.get("factory").toString());
+                stat.setMajor(data.get("domain") != null ? data.get("domain").toString() : "");
+                stat.setWorkshop(data.get("workshop") != null ? data.get("workshop").toString() : "");
+                
+                // 鎵规鍙峰拰鍒涘缓淇℃伅
+                stat.setBatchNumber(batchNumber);
+                stat.setCreateBy(SecurityUtils.getUsername());
+                stat.setCreateTime(truncateToSeconds(DateUtils.getNowDate()));
+                
+                processList.add(stat);
+            }
+            
+            // 璁$畻璁″垝瀹屽伐鏃ュ拰璁″垝寮�宸ユ棩
+            if (!processList.isEmpty()) {
+                int lastIndex = processList.size() - 1;
+                
+                // 鏈�鍚庝竴閬撳伐搴忕殑璁″垝瀹屽伐鏃ユ湡涓洪娴嬫棩鏈�
+                ApsGasPipingRouteStat lastProcess = processList.get(lastIndex);
+                Date predictDate = (Date) materialData.get(lastIndex).get("predict_date");
+                lastProcess.setProcessPlanEndDay(truncateToSeconds(predictDate));
+                
+                // 鏍囪鏄惁鍑虹幇杩囨椂闂村啿绐佺殑鎯呭喌
+                boolean hasTimeConflict = false;
+                
+                // 璁$畻姣忎釜宸ュ簭鐨勮鍒掑紑宸ユ棩鍜屽畬宸ユ棩 - 浠庢渶鍚庝竴閬撳伐搴忓紑濮嬪�掓帹
+                for (int i = lastIndex; i >= 0; i--) {
+                    ApsGasPipingRouteStat current = processList.get(i);
+                    
+                    // 濡傛灉褰撳墠鏄渶鍚庝竴閬撳伐搴忥紝璁″垝寮�宸ユ棩 = 璁″垝瀹屽伐鏃� - 宸ュ簭鎬诲伐鏃�
+                    if (i == lastIndex) {
+                        hasTimeConflict = calculateProcessPlanStartDay(current, hasTimeConflict);
+                    } else {
+                        // 闈炴渶鍚庝竴閬撳伐搴忥紝璁″垝瀹屽伐鏃ヤ负涓嬩竴閬撳伐搴忕殑璁″垝寮�宸ユ棩
+                        ApsGasPipingRouteStat next = processList.get(i + 1);
+                        current.setProcessPlanEndDay(next.getProcessPlanStartDay());
+                        
+                        // 濡傛灉宸茬粡鍑虹幇鏃堕棿鍐茬獊锛屽悗缁伐搴忕殑璁″垝寮�宸ユ棩鍜岃鍒掑畬宸ユ棩閮借涓哄綋鍓嶆椂闂�
+                        if (hasTimeConflict) {
+                            current.setProcessPlanStartDay(truncateToSeconds(new Date()));
+                        } else {
+                            // 鍚﹀垯姝e父璁$畻锛屽苟妫�鏌ユ槸鍚﹀嚭鐜版椂闂村啿绐�
+                            hasTimeConflict = calculateProcessPlanStartDay(current, hasTimeConflict);
+                        }
+                    }
+                    
+                    // 璁剧疆骞淬�佹湀銆佹棩
+                    setDateComponents(current);
+                }
+                
+                statList.addAll(processList);
+            }
+        }
+        
+        // 澶勭悊鎵嬪伐姘斾綋宸ュ崟鏁版嵁 - 浣跨敤鑱斿悎鏌ヨ鑾峰彇鎵�鏈夌浉鍏虫暟鎹�
+        List<Map<String, Object>> moDataList = apsGasPipingRouteStatMapper.selectMoRouteData();
+        
+        // 鎸夊伐鍗曞彿鍒嗙粍锛屼究浜庡鐞嗗悓涓�宸ュ崟鐨勪笉鍚屽伐搴�
+        Map<String, List<Map<String, Object>>> moGroups = moDataList.stream()
+                .collect(Collectors.groupingBy(data -> data.get("work_order_no").toString()));
+        
+        // 澶勭悊姣忎釜宸ュ崟鐨勫伐鑹鸿矾绾�
+        for (String workOrderNo : moGroups.keySet()) {
+            List<Map<String, Object>> workOrderData = moGroups.get(workOrderNo);
+            
+            // 鎸夊伐搴忓彿鎺掑簭
+            workOrderData.sort((a, b) -> {
+                String numA = a.get("process_number").toString();
+                String numB = b.get("process_number").toString();
+                return numA.compareTo(numB);
+            });
+            
+            // 鑾峰彇鎵�鏈夊伐搴忕殑淇℃伅骞跺垱寤虹粺璁¤褰�
+            List<ApsGasPipingRouteStat> processList = new ArrayList<>();
+            for (Map<String, Object> data : workOrderData) {
+                ApsGasPipingRouteStat stat = new ApsGasPipingRouteStat();
+                stat.setId(IdUtils.fastSimpleUUID());
+                stat.setWorkOrderNo(data.get("work_order_no").toString());
+                stat.setItemNumber(data.get("material_code").toString());
+                stat.setProcessName(data.get("process_name").toString());
+                stat.setRoadProcessNumber(new BigDecimal(data.get("process_number").toString()));
+                
+                // 鐢熶骇鏁伴噺鍜屾爣鍑嗗伐鏃�
+                BigDecimal quantity = new BigDecimal(data.get("quantity").toString()).setScale(4, RoundingMode.HALF_UP);
+                BigDecimal standardTime = new BigDecimal(data.get("standard_time").toString()).setScale(4, RoundingMode.HALF_UP);
+                
+                stat.setProductionQuantity(quantity);
+                stat.setStandardTime(standardTime);
+                stat.setProcessTotalTime(standardTime.multiply(quantity).setScale(4, RoundingMode.HALF_UP));
+                
+                // 宸ュ巶銆佷笓涓氬拰杞﹂棿
+                stat.setPlant(data.get("factory").toString());
+                stat.setMajor(data.get("domain") != null ? data.get("domain").toString() : "");
+                stat.setWorkshop(data.get("workshop") != null ? data.get("workshop").toString() : "");
+                
+                // 鎵规鍙峰拰鍒涘缓淇℃伅
+                stat.setBatchNumber(batchNumber);
+                stat.setCreateBy(SecurityUtils.getUsername());
+                stat.setCreateTime(truncateToSeconds(DateUtils.getNowDate()));
+                
+                processList.add(stat);
+            }
+            
+            // 璁$畻璁″垝瀹屽伐鏃ュ拰璁″垝寮�宸ユ棩
+            if (!processList.isEmpty()) {
+                int lastIndex = processList.size() - 1;
+                
+                // 鏈�鍚庝竴閬撳伐搴忕殑璁″垝瀹屽伐鏃ユ湡涓哄伐鍗曡鍒掑畬宸ユ棩鏈�
+                ApsGasPipingRouteStat lastProcess = processList.get(lastIndex);
+                Date planEnd = (Date) workOrderData.get(0).get("plan_end");
+                lastProcess.setProcessPlanEndDay(truncateToSeconds(planEnd));
+                
+                // 鏍囪鏄惁鍑虹幇杩囨椂闂村啿绐佺殑鎯呭喌
+                boolean hasTimeConflict = false;
+                
+                // 璁$畻姣忎釜宸ュ簭鐨勮鍒掑紑宸ユ棩鍜屽畬宸ユ棩 - 浠庢渶鍚庝竴閬撳伐搴忓紑濮嬪�掓帹
+                for (int i = lastIndex; i >= 0; i--) {
+                    ApsGasPipingRouteStat current = processList.get(i);
+                    
+                    // 濡傛灉褰撳墠鏄渶鍚庝竴閬撳伐搴忥紝璁″垝寮�宸ユ棩 = 璁″垝瀹屽伐鏃� - 宸ュ簭鎬诲伐鏃�
+                    if (i == lastIndex) {
+                        hasTimeConflict = calculateProcessPlanStartDay(current, hasTimeConflict);
+                    } else {
+                        // 闈炴渶鍚庝竴閬撳伐搴忥紝璁″垝瀹屽伐鏃ヤ负涓嬩竴閬撳伐搴忕殑璁″垝寮�宸ユ棩
+                        ApsGasPipingRouteStat next = processList.get(i + 1);
+                        current.setProcessPlanEndDay(next.getProcessPlanStartDay());
+                        
+                        // 濡傛灉宸茬粡鍑虹幇鏃堕棿鍐茬獊锛屽悗缁伐搴忕殑璁″垝寮�宸ユ棩鍜岃鍒掑畬宸ユ棩閮借涓哄綋鍓嶆椂闂�
+                        if (hasTimeConflict) {
+                            current.setProcessPlanStartDay(truncateToSeconds(new Date()));
+                        } else {
+                            // 鍚﹀垯姝e父璁$畻锛屽苟妫�鏌ユ槸鍚﹀嚭鐜版椂闂村啿绐�
+                            hasTimeConflict = calculateProcessPlanStartDay(current, hasTimeConflict);
+                        }
+                    }
+                    
+                    // 璁剧疆骞淬�佹湀銆佹棩
+                    setDateComponents(current);
+                }
+                
+                statList.addAll(processList);
+            }
+        }
+        
+        // 鎵归噺鎻掑叆鏁版嵁
+        if (!statList.isEmpty()) {
+            for (int i = 0; i < statList.size(); i += 500) {
+                int endIndex = Math.min(i + 500, statList.size());
+                List<ApsGasPipingRouteStat> batch = statList.subList(i, endIndex);
+                count += apsGasPipingRouteStatMapper.insertApsGasPipingRouteStatBatch(batch);
+            }
+        }
+        
+        return count;
+    }
+
+    /**
+     * 璁$畻宸ュ簭璁″垝寮�宸ユ棩锛屽苟鍒ゆ柇鏄惁鍙戠敓鏃堕棿鍐茬獊
+     * 
+     * @param stat 褰撳墠宸ュ簭缁熻瀵硅薄
+     * @param hasTimeConflict 涔嬪墠鏄惁宸茬粡鍙戠敓鏃堕棿鍐茬獊
+     * @return 鏄惁鍙戠敓鏃堕棿鍐茬獊
+     */
+    private boolean calculateProcessPlanStartDay(ApsGasPipingRouteStat stat, boolean hasTimeConflict) {
+        Date planEndDay = stat.getProcessPlanEndDay();
+        if (planEndDay == null) {
+            return hasTimeConflict;
+        }
+        
+        // 璁$畻宸ュ簭鎬诲伐鏃跺搴旂殑绉掓暟
+        long processTotalTimeSeconds = stat.getProcessTotalTime()
+                .multiply(BigDecimal.valueOf(60 * 60))
+                .longValue();
+        
+        // 鑾峰彇褰撳墠鏃堕棿骞剁簿纭埌绉掔骇鍒�
+        Date now = truncateToSeconds(new Date());
+        
+        // 璁$畻寮�宸ユ棩鏈熷苟绮剧‘鍒扮绾у埆
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(planEndDay);
+        
+        // 鍒嗘壒鍑忓幓绉掓暟锛岄伩鍏峣nt婧㈠嚭
+        long seconds = processTotalTimeSeconds;
+        while (seconds > 0) {
+            int step = (seconds > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) seconds;
+            calendar.add(Calendar.SECOND, -step);
+            seconds -= step;
+        }
+        
+        Date calculatedStartDay = truncateToSeconds(calendar.getTime());
+        
+        // 濡傛灉璁″垝瀹屽伐鏃ユ湡灏忎簬绛変簬褰撳墠鏃堕棿锛屽垯璁″垝寮�宸ユ棩涔熻涓鸿鍒掑畬宸ユ棩锛堝綋鍓嶆椂闂达級
+        if (planEndDay.compareTo(now) <= 0) {
+            stat.setProcessPlanStartDay(truncateToSeconds(planEndDay));
+            return true; // 鍙戠敓鏃堕棿鍐茬獊
+        } 
+        // 濡傛灉璁$畻鍑虹殑璁″垝寮�宸ユ棩灏忎簬绛変簬褰撳墠鏃堕棿锛屽垯璁句负褰撳墠鏃堕棿
+        else if (calculatedStartDay.compareTo(now) <= 0) {
+            stat.setProcessPlanStartDay(now);
+            return true; // 棣栨鍑虹幇鏃堕棿鍐茬獊
+        } 
+        // 鍚﹀垯姝e父璁剧疆璁″垝寮�宸ユ棩
+        else {
+            stat.setProcessPlanStartDay(calculatedStartDay);
+            return hasTimeConflict; // 淇濇寔鍘熸湁鍐茬獊鐘舵��
+        }
+    }
+    
+    /**
+     * 灏嗘棩鏈熺簿纭埌绉掔骇鍒紝鍘婚櫎姣淇℃伅
+     * 
+     * @param date 鍘熷鏃ユ湡
+     * @return 绮剧‘鍒扮鐨勬棩鏈�
+     */
+    private Date truncateToSeconds(Date date) {
+        if (date == null) {
+            return null;
+        }
+        
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.set(Calendar.MILLISECOND, 0);
+        return calendar.getTime();
+    }
+    
+    /**
+     * 璁剧疆鏃ユ湡鐩稿叧缁勪欢锛堝勾銆佹湀銆佹棩锛�
+     */
+    private void setDateComponents(ApsGasPipingRouteStat stat) {
+        if (stat.getProcessPlanStartDay() != null) {
+            SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
+            SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
+            SimpleDateFormat dayFormat = new SimpleDateFormat("dd");
+            
+            stat.setPlanStartYear(yearFormat.format(stat.getProcessPlanStartDay()));
+            stat.setPlanStartMonth(monthFormat.format(stat.getProcessPlanStartDay()));
+            stat.setPlanStartDay(dayFormat.format(stat.getProcessPlanStartDay()));
+        }
+    }
+
+    /**
+     * 鑱氬悎姘斾綋绠¤矾浜ц兘璐熻浇缁熻鏁版嵁
+     * 鍦⊿ervice灞傚畬鎴愯仛鍚堝鐞嗭紝鏀寔澶氱淮搴﹀垎缁�
+     * 
+     * @param params 鑱氬悎鍙傛暟
+     * @return 鑱氬悎缁撴灉
+     */
+    @Override
+    public Map<String, Object> aggregateGasPipingRouteStat(Map<String, Object> params) {
+        Map<String, Object> result = new HashMap<>();
+        List<Map<String, Object>> plantTable = new ArrayList<>();
+        
+        // 鑾峰彇鏃堕棿棰楃矑搴﹀弬鏁�
+        String timeGranularity = params.containsKey("timeGranularity") ? 
+                (String) params.get("timeGranularity") : "day"; // 榛樿涓�"鏃�"绮掑害
+        
+        // 鑾峰彇row缁村害鐨勮仛鍚堝瓧娈� - 榛樿涓哄伐搴忓悕绉�(processName)
+        String rowGroupBy = params.containsKey("rowGroupBy") ? 
+                (String) params.get("rowGroupBy") : "processName";
+        
+        // 纭畾鍒嗙粍缁村害 - 宸ュ巶銆佷笓涓氥�佽溅闂�
+        boolean groupByPlant = params.containsKey("groupByPlant") && Boolean.TRUE.equals(params.get("groupByPlant"));
+        boolean groupByMajor = params.containsKey("groupByMajor") && Boolean.TRUE.equals(params.get("groupByMajor"));
+        boolean groupByWorkshop = params.containsKey("groupByWorkshop") && Boolean.TRUE.equals(params.get("groupByWorkshop"));
+        // 濡傛灉rowGroupBy宸茬粡鏄煇涓淮搴︼紝鍒欒缁村害涓嶉渶瑕佸啀娆″垎缁�
+        if ("plant".equals(rowGroupBy)) groupByPlant = false;
+        if ("major".equals(rowGroupBy)) groupByMajor = false;
+        if ("workshop".equals(rowGroupBy)) groupByWorkshop = false;
+        
+        // 鏋勫缓鏌ヨ鏉′欢
+        Map<String, Object> queryParams = new HashMap<>();
+        
+        // 璁剧疆鏌ヨ鏉′欢 - 鍒嗙被鏉′欢
+        if (params.containsKey("plant")) {
+            Object plantParam = params.get("plant");
+            if (plantParam instanceof List) {
+                queryParams.put("plants", plantParam);
+            } else if (plantParam instanceof String) {
+                // 澶勭悊鍙兘鐨勯�楀彿鍒嗛殧瀛楃涓�
+                String plantStr = (String) plantParam;
+                if (plantStr.contains(",")) {
+                    List<String> plantList = Arrays.asList(plantStr.split(","));
+                    queryParams.put("plants", plantList);
+                } else {
+                    queryParams.put("plant", plantStr);
+                }
+            }
+        }
+        
+        if (params.containsKey("major")) {
+            Object majorParam = params.get("major");
+            if (majorParam instanceof List) {
+                queryParams.put("majors", majorParam);
+            } else if (majorParam instanceof String) {
+                // 澶勭悊鍙兘鐨勯�楀彿鍒嗛殧瀛楃涓�
+                String majorStr = (String) majorParam;
+                if (majorStr.contains(",")) {
+                    List<String> majorList = Arrays.asList(majorStr.split(","));
+                    queryParams.put("majors", majorList);
+                } else {
+                    queryParams.put("major", majorStr);
+                }
+            }
+        }
+        
+        if (params.containsKey("workshop")) {
+            Object workshopParam = params.get("workshop");
+            if (workshopParam instanceof List) {
+                queryParams.put("workshops", workshopParam);
+            } else if (workshopParam instanceof String) {
+                // 澶勭悊鍙兘鐨勯�楀彿鍒嗛殧瀛楃涓�
+                String workshopStr = (String) workshopParam;
+                if (workshopStr.contains(",")) {
+                    List<String> workshopList = Arrays.asList(workshopStr.split(","));
+                    queryParams.put("workshops", workshopList);
+                } else {
+                    queryParams.put("workshop", workshopStr);
+                }
+            }
+        }
+        
+        // 纭畾鏃堕棿鑼冨洿
+        List<String> timePoints = new ArrayList<>();
+        
+        if ("day".equalsIgnoreCase(timeGranularity)) {
+            // "鏃�"绮掑害锛氫紶鍏ヤ竴涓湀浠斤紝鑱氬悎璇ユ湀姣忎竴澶╃殑鏁版嵁
+            if (!params.containsKey("yearMonth")) {
+                result.put("plantTable", plantTable);
+                result.put("message", "鏃ョ矑搴﹁仛鍚堥渶瑕佹寚瀹歽earMonth鍙傛暟");
+                return result;
+            }
+            
+            String yearMonth = (String) params.get("yearMonth");
+            // 鐢熸垚鎸囧畾鏈堜唤涓殑姣忎竴澶�
+            YearMonth ym = YearMonth.parse(yearMonth);
+            int daysInMonth = ym.lengthOfMonth();
+            
+            for (int day = 1; day <= daysInMonth; day++) {
+                String dayStr = String.format("%02d", day);
+                timePoints.add(yearMonth + "-" + dayStr);
+            }
+            
+            // 璁剧疆鏌ヨ鍙傛暟
+            String[] ymParts = yearMonth.split("-");
+            queryParams.put("yearStart", ymParts[0]);
+            queryParams.put("monthStart", ymParts[1]);
+            queryParams.put("yearEnd", ymParts[0]);
+            queryParams.put("monthEnd", ymParts[1]);
+            
+        } else if ("month".equalsIgnoreCase(timeGranularity)) {
+            // "鏈�"绮掑害锛氫紶鍏ヤ竴涓椂闂村尯闂达紝鑱氬悎璇ュ尯闂村唴姣忎釜鏈堢殑鏁版嵁
+            if (!params.containsKey("startDate") || !params.containsKey("endDate")) {
+                result.put("plantTable", plantTable);
+                result.put("message", "鏈堢矑搴﹁仛鍚堥渶瑕佹寚瀹歴tartDate鍜宔ndDate鍙傛暟");
+                return result;
+            }
+            
+            String startDate = (String) params.get("startDate");
+            String endDate = (String) params.get("endDate");
+            
+            // 瑙f瀽寮�濮嬪拰缁撴潫骞存湀
+            YearMonth start = YearMonth.parse(startDate);
+            YearMonth end = YearMonth.parse(endDate);
+            
+            // 鐢熸垚鍖洪棿鍐呯殑姣忎釜鏈�
+            timePoints = getYearMonthsInRange(start, end);
+            
+            // 璁剧疆鏌ヨ鍙傛暟
+            String[] startParts = startDate.split("-");
+            String[] endParts = endDate.split("-");
+            queryParams.put("yearStart", startParts[0]);
+            queryParams.put("monthStart", startParts[1]);
+            queryParams.put("yearEnd", endParts[0]);
+            queryParams.put("monthEnd", endParts[1]);
+        }
+        
+        if (timePoints.isEmpty()) {
+            result.put("plantTable", plantTable);
+            result.put("message", "鏈兘鐢熸垚鏈夋晥鐨勬椂闂寸偣鍒楄〃");
+            return result;
+        }
+        
+        // 鏌ヨ鍘熷鏁版嵁锛堜笉渚濊禆鏁版嵁搴撹仛鍚堬級
+        List<Map<String, Object>> rawData = apsGasPipingRouteStatMapper.selectRawStatData(queryParams);
+        
+        if (rawData.isEmpty()) {
+            result.put("plantTable", plantTable);
+            result.put("timePoints", timePoints);
+            return result;
+        }
+        
+        // 鍦⊿ervice灞傚畬鎴愯仛鍚�
+        // 浣跨敤缁勫悎key鏉ュ疄鐜板缁村害鍒嗙粍锛堝姩鎬乺owGroupBy瀛楁 + 鍙�夌殑宸ュ巶/涓撲笟/杞﹂棿锛�
+        Map<String, Map<String, Object>> groupInfoMap = new HashMap<>();
+        Map<String, Map<String, BigDecimal>> groupTimeDataMap = new HashMap<>();
+        
+        // 閬嶅巻鍘熷鏁版嵁锛屾寜澶氱淮搴﹀垎缁勮繘琛岃仛鍚�
+        for (Map<String, Object> data : rawData) {
+            // 杩囨护宸ュ簭鍚嶇О涓虹┖鐨勬暟鎹�
+            String processName = getStringValue(data, "processName");
+            if (processName == null || processName.trim().isEmpty()) {
+                log.warn("璺宠繃澶勭悊锛氬伐搴忓悕绉颁负绌�");
+                continue;
+            }
+            
+            // 杩囨护杞﹂棿涓虹┖鐨勬暟鎹�
+            String workshop = getStringValue(data, "workshop");
+            if (workshop == null || workshop.trim().isEmpty()) {
+                log.warn("璺宠繃澶勭悊锛氳溅闂翠负绌猴紝宸ュ簭鍚嶇О={}", processName);
+                continue;
+            }
+            
+            // 鑾峰彇琛屽垎缁勫瓧娈靛��
+            String rowGroupValue = getStringValue(data, rowGroupBy);
+            if (rowGroupValue == null) {
+                log.warn("璺宠繃澶勭悊锛歿} 瀛楁鍊间负null", rowGroupBy);
+                continue;
+            }
+            
+            // 澶勭悊寮�宸ユ棩鏈�
+            Date processPlanStartDay = (Date) data.get("processPlanStartDay");
+            if (processPlanStartDay == null) {
+                log.warn("璺宠繃澶勭悊锛氳鍒掑紑宸ユ棩涓簄ull, {}={}", rowGroupBy, rowGroupValue);
+                continue;
+            }
+            
+            // 鏋勫缓鍒嗙粍閿� - 鍩轰簬row鍒嗙粍瀛楁鍜屽彲閫夌殑鍏朵粬缁村害
+            String plant = getStringValue(data, "plant");
+            String major = getStringValue(data, "major");
+            
+            StringBuilder groupKeyBuilder = new StringBuilder(rowGroupValue);
+            
+            // 鏍规嵁鐢ㄦ埛閫夋嫨鐨勫垎缁勭淮搴︽坊鍔犲埌鍒嗙粍閿�
+            if (groupByPlant && plant != null) {
+                groupKeyBuilder.append("_PLANT_").append(plant);
+            }
+            if (groupByMajor && major != null) {
+                groupKeyBuilder.append("_MAJOR_").append(major);
+            }
+            if (groupByWorkshop && workshop != null) {
+                groupKeyBuilder.append("_WORKSHOP_").append(workshop);
+            }
+            
+            String groupKey = groupKeyBuilder.toString();
+            
+            // 璁板綍鍒嗙粍鐨勫熀鏈俊鎭紙鍙褰曚竴娆★級
+            if (!groupInfoMap.containsKey(groupKey)) {
+                Map<String, Object> groupInfo = new HashMap<>();
+                groupInfo.put(rowGroupBy, rowGroupValue);
+                groupInfo.put("plant", plant);
+                groupInfo.put("major", major);
+                groupInfo.put("workshop", workshop);
+                groupInfo.put("processName", processName);
+                groupInfoMap.put(groupKey, groupInfo);
+            }
+            
+            // 璁$畻鏃堕棿鐐筀ey
+            String timeKey;
+            LocalDate planStartLocalDate = processPlanStartDay.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+            
+            if ("day".equalsIgnoreCase(timeGranularity)) {
+                // 鏃ョ矑搴�: 2025-05-25
+                timeKey = planStartLocalDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
+            } else {
+                // 鏈堢矑搴�: 2025-05
+                timeKey = planStartLocalDate.getYear() + "-" + String.format("%02d", planStartLocalDate.getMonthValue());
+            }
+            
+            // 鑾峰彇璇ュ垎缁勭殑鏃堕棿鐐规槧灏勶紝濡傛灉涓嶅瓨鍦ㄥ垯鍒涘缓
+            if (!groupTimeDataMap.containsKey(groupKey)) {
+                groupTimeDataMap.put(groupKey, new HashMap<>());
+            }
+            Map<String, BigDecimal> timeMap = groupTimeDataMap.get(groupKey);
+            
+            // 绱姞璇ュ垎缁勫湪璇ユ椂闂寸偣鐨勫伐鏃舵暟鎹�
+            BigDecimal processTotalTime = getBigDecimalValue(data, "processTotalTime");
+            if (processTotalTime != null) {
+                BigDecimal currentTotal = timeMap.getOrDefault(timeKey, BigDecimal.ZERO);
+                timeMap.put(timeKey, currentTotal.add(processTotalTime));
+            }
+        }
+        
+        // 鏋勫缓鏈�缁堣繑鍥炵殑鏁版嵁缁撴瀯
+        for (String groupKey : groupInfoMap.keySet()) {
+            Map<String, Object> rowEntry = new HashMap<>();
+            Map<String, Object> rowDetail = new HashMap<>();
+            
+            // 鑾峰彇璇ュ垎缁勭殑鍩烘湰淇℃伅
+            Map<String, Object> groupInfo = groupInfoMap.get(groupKey);
+            String rowGroupValue = (String) groupInfo.get(rowGroupBy);
+            
+            // 娣诲姞鍒嗙粍鍩烘湰淇℃伅
+            if (groupByPlant) {
+                rowDetail.put("plant", groupInfo.get("plant"));
+            }
+            if (groupByMajor) {
+                rowDetail.put("major", groupInfo.get("major"));
+            }
+            if (groupByWorkshop) {
+                rowDetail.put("workshop", groupInfo.get("workshop"));
+            }
+            
+            // 淇濈暀宸ュ簭鍚嶇О淇℃伅锛屼互渚垮墠绔睍绀�
+            if (!"processName".equals(rowGroupBy)) {
+                rowDetail.put("processName", groupInfo.get("processName"));
+            }
+            
+            // 娣诲姞鏃堕棿鏁版嵁
+            List<Map<String, Object>> timeDataList = new ArrayList<>();
+            Map<String, BigDecimal> timeMap = groupTimeDataMap.getOrDefault(groupKey, new HashMap<>());
+            
+            for (String timePoint : timePoints) {
+                Map<String, Object> pointData = new HashMap<>();
+                pointData.put("planDay", timePoint);
+                pointData.put("designTimes", 0); // 璁捐宸ユ椂鏆傛椂缁�0
+                
+                // 鑾峰彇璇ユ椂闂寸偣鐨勯渶姹傚伐鏃讹紝濡傛灉涓嶅瓨鍦ㄥ垯璁句负0
+                BigDecimal requireTimes = timeMap.getOrDefault(timePoint, BigDecimal.ZERO);
+                pointData.put("requireTimes", requireTimes);
+                
+                // 璁$畻浜ц兘璐熻嵎锛堟殏鏃朵负0锛�
+                pointData.put("capacityLoad", 0);
+                
+                timeDataList.add(pointData);
+            }
+            
+            rowDetail.put("timeData", timeDataList);
+            rowEntry.put(rowGroupValue, rowDetail);
+            plantTable.add(rowEntry);
+        }
+        
+        result.put("plantTable", plantTable);
+        result.put("timePoints", timePoints);
+        result.put("rowGroupBy", rowGroupBy);
+        
+        return result;
+    }
+    
+    /**
+     * 浠嶮ap涓畨鍏ㄨ幏鍙朣tring鍊�
+     */
+    private String getStringValue(Map<String, Object> data, String key) {
+        Object value = data.get(key);
+        if (value == null) {
+            return null;
+        }
+        return value.toString();
+    }
+    
+    /**
+     * 浠嶮ap涓畨鍏ㄨ幏鍙朆igDecimal鍊�
+     */
+    private BigDecimal getBigDecimalValue(Map<String, Object> data, String key) {
+        Object value = data.get(key);
+        if (value == null) {
+            return null;
+        }
+        
+        if (value instanceof BigDecimal) {
+            return (BigDecimal) value;
+        } else if (value instanceof Number) {
+            return new BigDecimal(((Number) value).toString());
+        } else if (value instanceof String) {
+            try {
+                return new BigDecimal((String) value);
+            } catch (NumberFormatException e) {
+                log.warn("鏃犳硶灏嗗�艰浆鎹负BigDecimal: {}", value);
+                return null;
+            }
+        }
+        
+        return null;
+    }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsMaterialStorageManagementServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsMaterialStorageManagementServiceImpl.java
index 20bdf34..01c6621 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsMaterialStorageManagementServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsMaterialStorageManagementServiceImpl.java
@@ -7,6 +7,7 @@
 import com.aps.core.domain.ApsMaterialStorageManagement;
 import com.aps.core.mapper.ApsMaterialStorageManagementMapper;
 import com.aps.core.service.IApsMaterialStorageManagementService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
@@ -21,6 +22,7 @@
  * @date 2025-04-17
  */
 @Service
+@Slf4j
 public class ApsMaterialStorageManagementServiceImpl implements IApsMaterialStorageManagementService 
 {
     @Autowired
@@ -150,6 +152,7 @@
     @Override
     public boolean setStorageDataToRedis(String orgCode) {
         try {
+            log.info("寮�濮嬪悓姝� 鐗╂枡搴撳瓨鑷砇edis!");
             Set<String> keys = redisTemplate.keys("MaterialStorage:Material_*");
             if (keys != null && !keys.isEmpty()) {
                 redisTemplate.delete(keys);
@@ -169,14 +172,12 @@
                 bulkData.put("MaterialStorage:Material_"+apsMaterialStorageManagement.getApplicableFactories()+"_"+apsMaterialStorageManagement.getItemNumber(), jsonObject);
             });
             redisTemplate.opsForValue().multiSet(bulkData);
+            log.info("瀹屾垚鍚屾 鐗╂枡搴撳瓨鑷砇edis!");
         } catch (Exception e) {
             e.printStackTrace();
+            log.error("鍚屾鐗╂枡搴撳瓨鑷砇edis澶辫触!"+e.getMessage());
             return false;
         }
-//        Set<String> keys = redisTemplate.keys("MaterialStorage:Material_*");
-//        if (keys != null && !keys.isEmpty()) {
-//            redisTemplate.delete(keys);
-//        }
         return true;
     }
 
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java
index 6469be7..d00d0af 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlanTaskServiceImpl.java
@@ -90,36 +90,37 @@
     }
 
     @Override
-    public AjaxResult generatorPlan()
-    {
+    public AjaxResult generatorPlan() {
         String plateOrderPlanKey = PLATE_ORDER_PLAN.getKey();
         boolean existsLock = redisLockUtils.existLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_PLAN.getCode());
-        if (existsLock){
+        if (existsLock) {
             return AjaxResult.warn("閽i噾宸ュ崟璁″垝浠诲姟姝e湪鎵ц涓�!");
         }
-        LambdaQueryWrapper<ApsPlanTask> queryWrapper=new LambdaQueryWrapper<>();
-        queryWrapper.eq(ApsPlanTask::getTaskType,PLAN_TASK_TYPE.PLATE_PLAN.getCode());
-        queryWrapper.eq(ApsPlanTask::getTaskStatus,PLAN_TASK_STATUS.IN_PROCESS.getCode());
+        LambdaQueryWrapper<ApsPlanTask> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ApsPlanTask::getTaskType, PLAN_TASK_TYPE.PLATE_PLAN.getCode());
+        queryWrapper.eq(ApsPlanTask::getTaskStatus, PLAN_TASK_STATUS.IN_PROCESS.getCode());
         boolean existsDbTask = mapper.exists(queryWrapper);
-        if (existsDbTask){
+        if (existsDbTask) {
             return AjaxResult.warn("閽i噾宸ュ崟璁″垝浠诲姟姝e湪鎵ц涓�!!");
         }
+        String currentBatchNum = requireBatchService.getNewBatchNumber();
         try {
-            redisLockUtils.getLock(plateOrderPlanKey,PLAN_TASK_TYPE.PLATE_PLAN.getCode(), 3*60L);
-            String batchNum= requireBatchService.getNewBatchNumber();
-            this.savePlanTask(batchNum);
-            apsPlateStandardRequireService.generatorPlan(batchNum);
-            this.updateTaskStatus(batchNum, PLAN_TASK_STATUS.FINISHED);
+            redisLockUtils.getLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_PLAN.getCode(), 15 * 60L);
+            this.savePlanTask(currentBatchNum);
+            //Thread.sleep(60*1000);
+            apsPlateStandardRequireService.generatorPlan(currentBatchNum);
             /*娓呴櫎宸茬粡瀛樺湪鐨� 宸ュ崟璁″垝瀹屽伐鏃堕棿*/
             orderEndDayMapper.batchRemove();
-            log.info("璁″垝浠诲姟鎵ц瀹屾垚!"+batchNum);
+            this.updateTaskStatus(currentBatchNum, PLAN_TASK_STATUS.FINISHED);
+            log.info("璁″垝浠诲姟鎵ц瀹屾垚!" + currentBatchNum);
             return success();
-        }catch (Exception e){
-            redisLockUtils.releaseLock(plateOrderPlanKey,PLAN_TASK_TYPE.PLATE_PLAN.getCode());
-            log.error("璁″垝浠诲姟鎵ц澶辫触!"+e.getMessage());
-            return AjaxResult.error("璁″垝浠诲姟鎵ц澶辫触!"+e.getMessage());
-        }finally {
-            redisLockUtils.releaseLock(plateOrderPlanKey,PLAN_TASK_TYPE.PLATE_PLAN.getCode());
+        } catch (Exception e) {
+            redisLockUtils.releaseLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_PLAN.getCode());
+            log.error("璁″垝浠诲姟鎵ц澶辫触!" + e.getMessage());
+            this.updateTaskStatus(currentBatchNum, PLAN_TASK_STATUS.ERROR);
+            return AjaxResult.error("璁″垝浠诲姟鎵ц澶辫触!" + e.getMessage());
+        } finally {
+            redisLockUtils.releaseLock(plateOrderPlanKey, PLAN_TASK_TYPE.PLATE_PLAN.getCode());
         }
     }
 
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlatePlanServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlatePlanServiceImpl.java
index bb8550a..59914e9 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlatePlanServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlatePlanServiceImpl.java
@@ -13,6 +13,7 @@
 import com.aps.core.mapper.ApsPlatePlanTempMapper;
 import com.aps.core.service.ApsPlate.IApsPlatePlanService;
 import com.aps.system.api.domain.SysDictData;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,6 +30,7 @@
  * @author ruoyi
  * @date 2025-04-08
  */
+@Slf4j
 @Service
 public class ApsPlatePlanServiceImpl implements IApsPlatePlanService
 {
@@ -221,6 +223,7 @@
     @Override
     public boolean setSubPlansToRedis() {
         try {
+            log.info("寮�濮嬭缃挘閲戝瓙璁″垝鍒皉edis");
             Set<String> keys = redisTemplate.keys("PLATE_SUB_PLAN:*");
             if (keys != null && !keys.isEmpty()) {
                 redisTemplate.delete(keys);
@@ -235,9 +238,11 @@
                 bulkData.put("PLATE_SUB_PLAN:"+key, value);
             }
             redisTemplate.opsForValue().multiSet(bulkData);
+            log.info("璁剧疆閽i噾瀛愯鍒掑埌redis瀹屾垚");
             return true;
         } catch (Exception e) {
             e.printStackTrace();
+            log.error("璁剧疆閽i噾瀛愯鍒掑埌redis澶辫触"+e.getMessage());
             return false;
         }
     }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessShopStatServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessShopStatServiceImpl.java
index 2315067..2436835 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessShopStatServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessShopStatServiceImpl.java
@@ -18,6 +18,7 @@
 import com.aps.core.domain.ApsPlate.ApsPlateProcessShopStat;
 import com.aps.core.domain.ApsPlate.ApsPlateProcessStat;
 import com.aps.core.mapper.*;
+import com.aps.core.service.ApsPlate.IApsPlateProcessStatService;
 import com.aps.system.api.domain.SysDictData;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -59,6 +60,9 @@
 
     @Resource
     private ApsPlatePlanMapper apsPlatePlanMapper;
+    @Autowired
+    private IApsPlateProcessStatService apsPlateProcessStatService;
+
 
 
     /**
@@ -136,6 +140,7 @@
     @Override
     public void saveShopStat() {
         try {
+            apsPlateProcessStatService.savePlateProcessStat();
             // 寮�濮嬩箣鍓嶅厛鍒犻櫎鎵�鏈夊巻鍙叉暟鎹�
             apsPlateProcessShopStatMapper.deleteAll();
 
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessStatServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessStatServiceImpl.java
index 6544ed3..410a1d6 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessStatServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateProcessStatServiceImpl.java
@@ -2,12 +2,15 @@
 
 import java.math.BigDecimal;
 import java.time.*;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import cn.hutool.core.util.IdUtil;
 import com.aps.common.core.utils.uuid.IdUtils;
 import com.aps.common.security.utils.SecurityUtils;
+import com.aps.core.domain.ApsPlate.ApsPlateStandardRequireBomOrderDetail;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.aps.core.mapper.ApsPlateProcessStatMapper;
@@ -109,9 +112,11 @@
     public void savePlateProcessStat() {
         String batchNum = IdUtils.fastSimpleUUID();
         List<ApsPlateProcessStat> tempList = apsPlateProcessStatMapper.queryTempStat();
+        ApsPlateProcessStat apsPlateProcessStat = tempList.stream().filter(x -> x.getWorkOrderNo().equals("MO-250409003498")).findFirst().get();
         Map<String, List<ApsPlateProcessStat>> groupByOrderNo = tempList.stream().collect(groupingBy(ApsPlateProcessStat::getWorkOrderNo));
         Boolean hasBefore = false;
         LocalDateTime now = LocalDateTime.now();
+        List<ApsPlateProcessStat> totalList=new ArrayList<>();
         for (Map.Entry<String, List<ApsPlateProcessStat>> entry : groupByOrderNo.entrySet()) {
             List<ApsPlateProcessStat> statPerOrder = entry.getValue();
             /*num 涓烘牴鎹畬宸ユ椂闂存帓搴忓嚭鐨勫簭鍙凤紝鎸夋鎺掑簭锛屽彲淇濊瘉鏄寜瀹屽伐鏃堕棿鍊掑彊鎺掑垪*/
@@ -176,13 +181,21 @@
                     }
                 }
                 last = stat;
-                apsPlateProcessStatMapper.insertApsPlateProcessStat(stat);
+                totalList.add(stat);
+                //apsPlateProcessStatMapper.insertApsPlateProcessStat(stat);
             }
             hasBefore=false;
-
         }
         apsPlateProcessStatMapper.removeOtherStat(batchNum);
-
+        if(!totalList.isEmpty()){
+            int batchSize = 1000;
+            totalList.forEach(x->x.setId(String.valueOf(IdUtil.getSnowflakeNextId())));
+            for (int i = 0; i < totalList.size(); i += batchSize) {
+                int end = Math.min(i + batchSize, totalList.size());
+                List<ApsPlateProcessStat> batch = totalList.subList(i, end);
+                apsPlateProcessStatMapper.batchInsertPlateStat(batch);
+            }
+        }
     }
 
 
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireBatchServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireBatchServiceImpl.java
index e765fc6..5046800 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireBatchServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireBatchServiceImpl.java
@@ -136,16 +136,12 @@
 
     @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();
-        }
+    public void initRequireBatch(String currentBatchNumber) {
+        apsPlateStandardRequireMapper.deleteLastPatch(currentBatchNumber);
+        apsPlateStandardRequireBomOrderDetailMapper.deleteLastPatch(currentBatchNumber);
+        apsPlateStandardRequireBomStockDetailMapper.deleteLastPatch(currentBatchNumber);
+        apsPlateStandardRequireErrorMapper.deleteLastPatch(currentBatchNumber);
+        apsPlatePlanMapper.initUnMatchQty();
+        apsMaterialStorageManagementMapper.initRemainderStock();
     }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireErrorServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireErrorServiceImpl.java
index 606a101..a342cee 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireErrorServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireErrorServiceImpl.java
@@ -1,7 +1,11 @@
 package com.aps.core.service.impl.ApsPlate;
 
 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.domain.ApsPlate.ApsPlateStandardRequire;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.aps.core.mapper.ApsPlateStandardRequireErrorMapper;
@@ -93,4 +97,21 @@
     {
         return apsPlateStandardRequireErrorMapper.deleteApsPlateStandardRequireErrorById(id);
     }
+
+    @Override
+    public void saveRequireError(ApsPlateStandardRequire require, String message) {
+        ApsPlateStandardRequireError data = ApsPlateStandardRequireError.builder()
+                .id(IdUtil.getSnowflakeNextId())
+                .requireId(require.getId())
+                .batchNumber(require.getBatchNumber())
+                .docNum(require.getDocNum())
+                .itemNum(require.getBomLineCode())
+                .orgCode(require.getOrgCode())
+                .message(message)
+                .delFlag("0")
+                .build();
+        data.setCreateBy(SecurityUtils.getUsername());
+        data.setCreateTime(DateUtils.getNowDate());
+        apsPlateStandardRequireErrorMapper.insertApsPlateStandardRequireError(data);
+    }
 }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireServiceImpl.java
index e6b8cd9..a7653f6 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsPlate/ApsPlateStandardRequireServiceImpl.java
@@ -1,29 +1,27 @@
 package com.aps.core.service.impl.ApsPlate;
 
-import java.math.BigDecimal;
-import java.util.*;
-
 import cn.hutool.core.util.IdUtil;
 import com.aps.common.core.utils.DateUtils;
 import com.aps.common.security.utils.DictUtils;
 import com.aps.common.security.utils.SecurityUtils;
-import com.aps.core.domain.*;
-import com.aps.core.domain.ApsPlate.ApsPlatePlan;
-import com.aps.core.domain.ApsPlate.ApsPlateStandardRequireBomOrderDetail;
-import com.aps.core.domain.ApsPlate.ApsPlateStandardRequireBomStockDetail;
+import com.aps.core.domain.ApsBom;
+import com.aps.core.domain.ApsMaterialStorageManagement;
+import com.aps.core.domain.ApsPlate.*;
+import com.aps.core.domain.ApsStandardProcessRouteLine;
 import com.aps.core.mapper.*;
-import com.aps.core.service.*;
 import com.aps.core.service.ApsPlate.*;
+import com.aps.core.service.IApsBomService;
+import com.aps.core.service.IApsMaterialStorageManagementService;
+import com.aps.core.service.IApsStandardProcessRouteLineService;
 import com.aps.system.api.domain.SysDictData;
 import jakarta.annotation.Resource;
-import com.aps.core.domain.ApsPlate.ApsPlateStandardRequire;
-import com.aps.core.mapper.ApsPlateStandardRequireMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
 
 /**
  * 閽i噾宸ュ崟鏍囧噯闇�姹係ervice涓氬姟灞傚鐞�
@@ -39,29 +37,17 @@
     private ApsPlateStandardRequireMapper apsPlateStandardRequireMapper;
 
     @Resource
-    private ApsPlateStandardRequireBatchMapper requireBatchMapper;
-
-    @Resource
     ApsPlatePlanMapper platePlanMapper;
 
     @Resource
-    ApsBomHeaderMapper bomHeaderMapper;
-    @Resource
     IApsBomService bomLineService;
-
-    @Resource
-    ApsMaterialStorageManagementMapper itemStorageMapper;
 
     @Resource
     ApsPlateStandardRequireBomStockDetailMapper plateBomStockDetailMapper;
 
     @Resource
     IApsPlateStandardRequireBomStockDetailService bomStockDetailService;
-    @Resource
-    ApsStandardProcessRouteHeaderMapper standardProcessRouteHeaderMapper;
 
-    @Resource
-    ApsStandardProcessRouteLineMapper ApsStandardProcessRouteLineMapper;
 
     @Resource
     ApsPlateStandardRequireBomOrderDetailMapper plateBomOrderDetailMapper;
@@ -76,10 +62,11 @@
     IApsStandardProcessRouteLineService routeLineService;
 
     @Resource
-    IApsPlateStandardRequireBatchService requireBatchService;
+    IApsPlateStandardRequireErrorService requireErrorService;
     @Resource
     private IApsMaterialStorageManagementService storageManagementService;
-
+    @Resource
+    IApsPlateStandardRequireBatchService requireBatchService;
     /**
      * 鏌ヨ閽i噾宸ュ崟鏍囧噯闇�姹�
      * 
@@ -167,9 +154,7 @@
     @Transactional
     @Override
     public void generatorPlan(String batchNum){
-
-        /*鍒濆鍖栨暟鎹�*/
-        requireBatchService.initRequireBatch();
+        requireBatchService.initRequireBatch(batchNum);
         /*瀹氫箟宸ュ巶涓哄崡閫� */
         String plantCode="FORTUNA";
         /*鑾峰彇閽i噾涓诲崟淇℃伅*/
@@ -296,7 +281,10 @@
         if (itemStorageOpt.isPresent()) {
 
             ApsMaterialStorageManagement     itemStorage=itemStorageOpt.get();
-            BigDecimal remainderStock =itemStorage.getRemainderStock();
+            BigDecimal remainderStock =BigDecimal.ZERO;
+            if(null!=itemStorage.getRemainderStock()){
+                remainderStock = itemStorage.getRemainderStock();
+            }
             /*璁$畻鍑�闇�姹� 榛樿=闇�姹傛暟閲�*/
             if (remainderStock.compareTo(BigDecimal.ZERO) == 0) {
                 require.setNetRequirement(require.getBomUseAmount());
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteHeaderServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteHeaderServiceImpl.java
index 56fedf2..e5a5776 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteHeaderServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteHeaderServiceImpl.java
@@ -5,6 +5,7 @@
 import com.aps.core.domain.ApsStandardProcessRouteHeader;
 import com.aps.core.mapper.ApsStandardProcessRouteHeaderMapper;
 import com.aps.core.service.IApsStandardProcessRouteHeaderService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
@@ -21,6 +22,7 @@
  * @date 2025-05-06
  */
 @Service
+@Slf4j
 public class ApsStandardProcessRouteHeaderServiceImpl implements IApsStandardProcessRouteHeaderService 
 {
     @Autowired
@@ -106,6 +108,7 @@
     @Override
     public boolean setProcessRouteDataToRedis(String orgCode) {
         try {
+            log.info("寮�濮嬪悓姝ユ爣鍑嗗伐鑹鸿矾绾挎暟鎹嚦Redis");
             Set<String> keys = redisTemplate.keys("ROUTE:ROUTE_*");
             if (keys != null && !keys.isEmpty()) {
                 redisTemplate.delete(keys);
@@ -116,9 +119,11 @@
                 bulkData.put("ROUTE:ROUTE_"+jsonObject.getString("org_code")+"_"+jsonObject.getString("item_code"), jsonObject.getBigDecimal("standardtime"));
             }
             redisTemplate.opsForValue().multiSet(bulkData);
+            log.info("瀹屾垚鍚屾鏍囧噯宸ヨ壓璺嚎鏁版嵁鑷砇edis");
             return true;
         } catch (Exception e) {
             e.printStackTrace();
+            log.error("鍚屾鏍囧噯宸ヨ壓璺嚎鏁版嵁鑷砇edis澶辫触"+e.getMessage());
             return false;
         }
     }
diff --git a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteLineServiceImpl.java b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteLineServiceImpl.java
index b9b2ac3..0185f67 100644
--- a/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteLineServiceImpl.java
+++ b/aps-modules/aps-core/src/main/java/com/aps/core/service/impl/ApsStandardProcessRouteLineServiceImpl.java
@@ -12,6 +12,7 @@
 import com.aps.core.domain.ApsStandardProcessRouteHeader;
 import com.aps.core.mapper.ApsPlateStandardRequireErrorMapper;
 import com.aps.core.mapper.ApsStandardProcessRouteHeaderMapper;
+import com.aps.core.service.ApsPlate.IApsPlateStandardRequireErrorService;
 import jakarta.annotation.Resource;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -34,7 +35,7 @@
     @Resource
     ApsStandardProcessRouteHeaderMapper standardProcessRouteHeaderMapper;
     @Resource
-    ApsPlateStandardRequireErrorMapper requireErrorMapper;
+    IApsPlateStandardRequireErrorService requireErrorService;
     @Resource
     private RedisTemplate redisTemplate;
 
@@ -141,7 +142,7 @@
             ret.setRouteTime(totalRouteTime);
             ret.setRouteId(routeHeader.getRouteId());
         }else {
-            saveRequireError(require,"鏍囧噯宸ヨ壓璺嚎涓嶅瓨鍦�");
+            requireErrorService.saveRequireError(require,"鏍囧噯宸ヨ壓璺嚎涓嶅瓨鍦�");
         }
         // 杩斿洖鎬诲伐鏃�
         return ret;
@@ -170,7 +171,7 @@
             ret.setRouteTime(totalRouteTime.multiply(netRequirement));
             return  ret;
         } else {
-            saveRequireError(require,"鏍囧噯宸ヨ壓璺嚎涓嶅瓨鍦�");
+            requireErrorService.saveRequireError(require,"鏍囧噯宸ヨ壓璺嚎涓嶅瓨鍦�");
             /*// 鏌ヨ鏍囧噯宸ヨ壓璺嚎澶撮儴淇℃伅
             Optional<ApsStandardProcessRouteHeader> firstProcessRoute = standardProcessRouteHeaderMapper.queryStandardProcessRouteHeaderByPlantAndItemCode(plant, itemCode).stream().findFirst();
             if (firstProcessRoute.isPresent()) {
@@ -193,19 +194,4 @@
         }
     }
 
-    private void saveRequireError(ApsPlateStandardRequire require,String message) {
-        ApsPlateStandardRequireError data = ApsPlateStandardRequireError.builder()
-                .id(IdUtil.getSnowflakeNextId())
-                .requireId(require.getId())
-                .batchNumber(require.getBatchNumber())
-                .docNum(require.getDocNum())
-                .itemNum(require.getBomLineCode())
-                .orgCode(require.getOrgCode())
-                .message(message)
-                .delFlag("0")
-                .build();
-        data.setCreateBy(SecurityUtils.getUsername());
-        data.setCreateTime(DateUtils.getNowDate());
-        requireErrorMapper.insertApsPlateStandardRequireError(data);
-    }
 }
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 aaa2a8e..174bc86 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
@@ -109,13 +109,10 @@
         LEFT JOIN aps_bom_line b on a.bom_header_id=b.bom_header_id
         LEFT JOIN aps_material_management d on b.item_code=d.item_number
         LEFT JOIN aps_material_management c on a.item_code=c.item_number
-        <where>
-            <if test="orgCode != null and orgCode != ''">
-                and a.org_code=#{orgCode} and d.applicable_factories=#{orgCode}
-            </if>
-            and d.material_type='鍒堕�犱欢'
-            and c.material_type='鍒堕�犱欢'
-        </where>
+        where   d.material_type='鍒堕�犱欢' and c.material_type='鍒堕�犱欢'
+        <if test="orgCode != null and orgCode != ''">
+            and a.org_code=#{orgCode} and d.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/ApsGasPipingRouteStatMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsGasPipingRouteStatMapper.xml
index 20beb21..4b097a5 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsGasPipingRouteStatMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsGasPipingRouteStatMapper.xml
@@ -28,8 +28,10 @@
         <result property="planStartDay"    column="plan_start_day"    />
         <result property="processPlanEndDay"    column="process_plan_end_day"    />
         <result property="orderPlanEndDay"    column="order_plan_end_day"    />
-        <result property="routeProcessNumber"    column="route_process_number"    />
         <result property="warning"    column="warning"    />
+        <result property="plant"    column="plant"    />
+        <result property="workshop"    column="workshop"    />
+        <result property="batchNumber"    column="batch_number"    />
     </resultMap>
 
     <sql id="selectApsGasPipingRouteStatVo">
@@ -38,27 +40,27 @@
                process_plan_start_day, design_times, del_flag, create_by,
                process_name, create_time, item_number, standard_dosage,
                process_total_dosage, design_capacity, major, plan_start_year,
-               plan_start_month, plan_start_day , warning, plant
+               plan_start_month, plan_start_day, process_plan_end_day, order_plan_end_day,
+               warning, plant, workshop, batch_number
         from aps_gas_piping_route_stat
     </sql>
 
     <select id="selectApsGasPipingRouteStatList" parameterType="com.aps.core.domain.ApsGasPipingRouteStat" resultMap="ApsGasPipingRouteStatResult">
         <include refid="selectApsGasPipingRouteStatVo"/>
-        <where>  
+        <where>
             <if test="workOrderNo != null  and workOrderNo != ''"> and work_order_no = #{workOrderNo}</if>
-            <if test="roadProcessNumber != null  and roadProcessNumber != ''"> and road_process_number = #{roadProcessNumber}</if>
-            <if test="currentProcessNumber != null  and currentProcessNumber != ''"> and current_process_number = #{currentProcessNumber}</if>
-            <if test="productionQuantity != null  and productionQuantity != ''"> and production_quantity = #{productionQuantity}</if>
-            <if test="standardTime != null  and standardTime != ''"> and standard_time = #{standardTime}</if>
-            <if test="processTotalTime != null  and processTotalTime != ''"> and process_total_time = #{processTotalTime}</if>
-            <if test="processPlanStartDay != null  and processPlanStartDay != ''"> and process_plan_start_day = #{processPlanStartDay}</if>
+            <if test="roadProcessNumber != null "> and road_process_number = #{roadProcessNumber}</if>
+            <if test="currentProcessNumber != null "> and current_process_number = #{currentProcessNumber}</if>
+            <if test="productionQuantity != null "> and production_quantity = #{productionQuantity}</if>
+            <if test="standardTime != null "> and standard_time = #{standardTime}</if>
+            <if test="processTotalTime != null "> and process_total_time = #{processTotalTime}</if>
+            <if test="processPlanStartDay != null "> and process_plan_start_day = #{processPlanStartDay}</if>
             <if test="designTimes != null "> and design_times = #{designTimes}</if>
-            <if test="processName != null  and processName != ''"> and process_name like '%' || #{processName} || '%')</if>
-            <if test="major != null and major != ''"> and major = #{major} </if>
-            <if test="planStartYear != null and planStartYear != ''"> and plan_start_year = #{planStartYear} </if>
-            <if test="planStartMonth != null and planStartMonth != ''"> and plan_start_month = #{planStartMonth} </if>
-            <if test="planStartDay != null and planStartDay != ''"> and plan_start_day = #{planStartDay} </if>
-            <if test="searchStartDate != null and searchStartDate != '' and searchEndDate != null and searchEndDate != ''"> and (process_plan_start_day &gt;= #{searchStartDate} and process_plan_start_day &lt;= #{searchEndDate}) </if>
+            <if test="processName != null  and processName != ''"> and process_name = #{processName}</if>
+            <if test="itemNumber != null  and itemNumber != ''"> and item_number = #{itemNumber}</if>
+            <if test="standardDosage != null "> and standard_dosage = #{standardDosage}</if>
+            <if test="processTotalDosage != null "> and process_total_dosage = #{processTotalDosage}</if>
+            <if test="designCapacity != null "> and design_capacity = #{designCapacity}</if>
             <if test="major != null and major != ''">
                 <if test="major == 'piping'">
                     and process_name in (select process_name from aps_standard_process where major='绠¤矾')
@@ -66,8 +68,19 @@
                 <if test="major == 'gas'">
                     and process_name in (select process_name from aps_standard_process where major='姘旀煖')
                 </if>
+                <if test="major != 'piping' and major != 'gas'">
+                    and major = #{major}
+                </if>
             </if>
-            <if test="plant != null and plant != ''"> and plant = #{plant} </if>
+            <if test="planStartYear != null  and planStartYear != ''"> and plan_start_year = #{planStartYear}</if>
+            <if test="planStartMonth != null  and planStartMonth != ''"> and plan_start_month = #{planStartMonth}</if>
+            <if test="planStartDay != null  and planStartDay != ''"> and plan_start_day = #{planStartDay}</if>
+            <if test="processPlanEndDay != null "> and process_plan_end_day = #{processPlanEndDay}</if>
+            <if test="orderPlanEndDay != null "> and order_plan_end_day = #{orderPlanEndDay}</if>
+            <if test="warning != null "> and warning = #{warning}</if>
+            <if test="plant != null and plant != ''"> and plant = #{plant}</if>
+            <if test="workshop != null and workshop != ''"> and workshop = #{workshop}</if>
+            <if test="batchNumber != null and batchNumber != ''"> and batch_number = #{batchNumber}</if>
         </where>
     </select>
     
@@ -81,12 +94,12 @@
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="id != null">id,</if>
             <if test="workOrderNo != null">work_order_no,</if>
-            <if test="roadProcessNumber != null and roadProcessNumber != ''">road_process_number,</if>
+            <if test="roadProcessNumber != null">road_process_number,</if>
             <if test="currentProcessNumber != null">current_process_number,</if>
             <if test="productionQuantity != null">production_quantity,</if>
             <if test="standardTime != null">standard_time,</if>
             <if test="processTotalTime != null">process_total_time,</if>
-            <if test="processPlanStartDay != null ">process_plan_start_day,</if>
+            <if test="processPlanStartDay != null">process_plan_start_day,</if>
             <if test="designTimes != null">design_times,</if>
             <if test="delFlag != null">del_flag,</if>
             <if test="createBy != null">create_by,</if>
@@ -102,18 +115,20 @@
             <if test="planStartDay != null">plan_start_day,</if>
             <if test="processPlanEndDay != null">process_plan_end_day,</if>
             <if test="orderPlanEndDay != null">order_plan_end_day,</if>
-            <if test="batchNumber != null">batch_number,</if>
             <if test="warning != null">warning,</if>
+            <if test="plant != null">plant,</if>
+            <if test="workshop != null">workshop,</if>
+            <if test="batchNumber != null">batch_number,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="id != null">#{id},</if>
             <if test="workOrderNo != null">#{workOrderNo},</if>
-            <if test="roadProcessNumber != null and roadProcessNumber != ''">#{roadProcessNumber},</if>
+            <if test="roadProcessNumber != null">#{roadProcessNumber},</if>
             <if test="currentProcessNumber != null">#{currentProcessNumber},</if>
             <if test="productionQuantity != null">#{productionQuantity},</if>
             <if test="standardTime != null">#{standardTime},</if>
             <if test="processTotalTime != null">#{processTotalTime},</if>
-            <if test="processPlanStartDay != null ">#{processPlanStartDay},</if>
+            <if test="processPlanStartDay != null">#{processPlanStartDay},</if>
             <if test="designTimes != null">#{designTimes},</if>
             <if test="delFlag != null">#{delFlag},</if>
             <if test="createBy != null">#{createBy},</if>
@@ -129,8 +144,10 @@
             <if test="planStartDay != null">#{planStartDay},</if>
             <if test="processPlanEndDay != null">#{processPlanEndDay},</if>
             <if test="orderPlanEndDay != null">#{orderPlanEndDay},</if>
-            <if test="batchNumber != null">#{batchNumber},</if>
             <if test="warning != null">#{warning},</if>
+            <if test="plant != null">#{plant},</if>
+            <if test="workshop != null">#{workshop},</if>
+            <if test="batchNumber != null">#{batchNumber},</if>
          </trim>
     </insert>
 
@@ -138,12 +155,12 @@
         update aps_gas_piping_route_stat
         <trim prefix="SET" suffixOverrides=",">
             <if test="workOrderNo != null">work_order_no = #{workOrderNo},</if>
-            <if test="roadProcessNumber != null and roadProcessNumber != ''">road_process_number = #{roadProcessNumber},</if>
+            <if test="roadProcessNumber != null">road_process_number = #{roadProcessNumber},</if>
             <if test="currentProcessNumber != null">current_process_number = #{currentProcessNumber},</if>
             <if test="productionQuantity != null">production_quantity = #{productionQuantity},</if>
             <if test="standardTime != null">standard_time = #{standardTime},</if>
             <if test="processTotalTime != null">process_total_time = #{processTotalTime},</if>
-            <if test="processPlanStartDay != null and processPlanStartDay != ''">process_plan_start_day = #{processPlanStartDay},</if>
+            <if test="processPlanStartDay != null">process_plan_start_day = #{processPlanStartDay},</if>
             <if test="designTimes != null">design_times = #{designTimes},</if>
             <if test="delFlag != null">del_flag = #{delFlag},</if>
             <if test="createBy != null">create_by = #{createBy},</if>
@@ -157,6 +174,12 @@
             <if test="planStartYear != null">plan_start_year = #{planStartYear},</if>
             <if test="planStartMonth != null">plan_start_month = #{planStartMonth},</if>
             <if test="planStartDay != null">plan_start_day = #{planStartDay},</if>
+            <if test="processPlanEndDay != null">process_plan_end_day = #{processPlanEndDay},</if>
+            <if test="orderPlanEndDay != null">order_plan_end_day = #{orderPlanEndDay},</if>
+            <if test="warning != null">warning = #{warning},</if>
+            <if test="plant != null">plant = #{plant},</if>
+            <if test="workshop != null">workshop = #{workshop},</if>
+            <if test="batchNumber != null">batch_number = #{batchNumber},</if>
         </trim>
         where id = #{id}
     </update>
@@ -171,31 +194,37 @@
             #{id}
         </foreach>
     </delete>
-
+    
     <delete id="deleteApsGasPipingRouteStatByBatchNum" parameterType="String">
         delete from aps_gas_piping_route_stat where batch_number != #{batchNumber}
     </delete>
-
-    <insert id="insertApsGasPipingRouteStatBatch">
-        INSERT INTO aps_gas_piping_route_stat
-        (
-        id,work_order_no, road_process_number, current_process_number, production_quantity, standard_time,
-        process_total_time, process_plan_start_day, design_times, del_flag, create_by, process_name,
-        create_time, item_number, standard_dosage, process_total_dosage, design_capacity, major,
-        plan_start_year, plan_start_month, plan_start_day,batch_number,process_plan_end_day,warning,order_plan_end_day,plant
-        )
-        VALUES
-        <foreach collection="apsGasPipingRouteStatList" item="stat" separator=",">
+    
+    <insert id="insertApsGasPipingRouteStatBatch" parameterType="java.util.List">
+        insert into aps_gas_piping_route_stat (
+            id, work_order_no, road_process_number, current_process_number,
+            production_quantity, standard_time, process_total_time,
+            process_plan_start_day, design_times, del_flag, create_by,
+            process_name, create_time, item_number, standard_dosage,
+            process_total_dosage, design_capacity, major, plan_start_year,
+            plan_start_month, plan_start_day, process_plan_end_day, order_plan_end_day,
+            warning, plant, workshop, batch_number
+        ) values 
+        <foreach item="item" index="index" collection="list" separator=",">
             (
-            #{stat.id},#{stat.workOrderNo}, #{stat.roadProcessNumber}, #{stat.currentProcessNumber}, #{stat.productionQuantity},
-            #{stat.standardTime}, #{stat.processTotalTime}, #{stat.processPlanStartDay}, #{stat.designTimes}, #{stat.delFlag},
-            #{stat.createBy}, #{stat.processName}, #{stat.createTime}, #{stat.itemNumber}, #{stat.standardDosage},
-            #{stat.processTotalDosage}, #{stat.designCapacity}, #{stat.major}, #{stat.planStartYear},
-            #{stat.planStartMonth}, #{stat.planStartDay}, #{stat.batchNumber}, #{stat.processPlanEndDay},#{stat.warning},#{stat.orderPlanEndDay},#{stat.plant}
+                #{item.id}, #{item.workOrderNo}, #{item.roadProcessNumber}, #{item.currentProcessNumber},
+                #{item.productionQuantity}, #{item.standardTime}, #{item.processTotalTime},
+                #{item.processPlanStartDay}, #{item.designTimes}, #{item.delFlag}, #{item.createBy},
+                #{item.processName}, #{item.createTime}, #{item.itemNumber}, #{item.standardDosage},
+                #{item.processTotalDosage}, #{item.designCapacity}, #{item.major}, #{item.planStartYear},
+                #{item.planStartMonth}, #{item.planStartDay}, #{item.processPlanEndDay}, #{item.orderPlanEndDay},
+                #{item.warning}, #{item.plant}, #{item.workshop}, #{item.batchNumber}
             )
         </foreach>
-
     </insert>
+    
+    <delete id="deleteAll">
+        delete from aps_gas_piping_route_stat
+    </delete>
 
     <select id="queryTempStat"  resultMap="ApsGasPipingRouteStatResult" >
         select row_number() over (partition by rt.work_order_no order by rt.process_number desc ) as num,
@@ -219,5 +248,155 @@
         where pl.document_number is not null and rt.work_order_no is not null and pl.plan_end_day is not null
         order by rt.work_order_no asc, rt.process_number desc
     </select>
+    
+    <!-- 鑱斿悎鏌ヨ鎵嬪伐姘斾綋棰勬祴鏁版嵁鐩稿叧淇℃伅 -->
+    <select id="selectPredictionRouteData" resultType="java.util.Map">
+        SELECT 
+            p.id as prediction_id,
+            p.material_code,
+            p.factory,
+            p.predict_quantity,
+            p.predict_date,
+            h.route_id,
+            l.route_name as process_name,
+            l.route_num as process_number,
+            l.standard_time,
+            m.domain,
+            s.work_shop as workshop
+        FROM aps_gas_pipeline_prediction p
+        JOIN aps_standard_process_route_header h ON p.material_code = h.item_code AND p.factory = h.org_code
+        JOIN aps_standard_process_route_line l ON h.route_id = l.route_id
+        LEFT JOIN aps_material_product_group_management m ON p.material_code = m.material_code AND p.factory = m.factory
+        LEFT JOIN aps_standard_process s ON l.route_name = s.process_name
+        ORDER BY p.material_code, l.route_num
+    </select>
+    
+    <!-- 鑱斿悎鏌ヨ鎵嬪伐姘斾綋宸ュ崟鏁版嵁鐩稿叧淇℃伅 -->
+    <select id="selectMoRouteData" resultType="java.util.Map">
+        SELECT 
+            mo.id as mo_id,
+            mo.mo as work_order_no,
+            mo.material_code,
+            mo.factory,
+            mo.quantity,
+            mo.plan_end,
+            r.process_name,
+            r.process_number,
+            r.standard_time,
+            m.domain,
+            s.work_shop as workshop
+        FROM aps_gas_pipeline_mo mo
+        JOIN aps_process_route r ON mo.mo = r.work_order_no
+        LEFT JOIN aps_material_product_group_management m ON mo.material_code = m.material_code AND mo.factory = m.factory
+        LEFT JOIN aps_standard_process s ON r.process_name = s.process_name
+        ORDER BY mo.mo, r.process_number
+    </select>
+    
+    <!-- 鑱氬悎鏌ヨ缁熻鏁版嵁 - 鎸夊伐搴忓悕绉板拰鏃堕棿鑱氬悎 -->
+    <select id="selectAggregatedStatData" parameterType="java.util.Map" resultType="java.util.Map">
+        SELECT 
+            process_name AS "processName",
+            plan_start_year AS "year",
+            plan_start_month AS "month",
+            <choose>
+                <when test="timeGranularity != null and timeGranularity == 'day'">
+                    plan_start_day AS "day"
+                </when>
+                <otherwise>
+                    '01' AS "day"
+                </otherwise>
+            </choose>,
+            plant AS "plant",
+            major AS "major",
+            workshop AS "workshop",
+            SUM(process_total_time) AS "totalProcessTime"
+        FROM aps_gas_piping_route_stat
+        <where>
+            <if test="yearStart != null and monthStart != null">
+                (plan_start_year > #{yearStart} OR 
+                 (plan_start_year = #{yearStart} AND plan_start_month >= #{monthStart}))
+                AND
+                (plan_start_year &lt; #{yearEnd} OR 
+                 (plan_start_year = #{yearEnd} AND plan_start_month &lt;= #{monthEnd}))
+            </if>
+            <if test="plant != null and plant != ''">
+                AND plant = #{plant}
+            </if>
+            <if test="major != null and major != ''">
+                AND major = #{major}
+            </if>
+            <if test="workshop != null and workshop != ''">
+                AND workshop = #{workshop}
+            </if>
+        </where>
+        GROUP BY 
+            process_name, 
+            plan_start_year, 
+            plan_start_month
+            <if test="timeGranularity != null and timeGranularity == 'day'">
+                , plan_start_day
+            </if>, 
+            plant, 
+            major, 
+            workshop
+        ORDER BY 
+            process_name, 
+            plan_start_year, 
+            plan_start_month
+            <if test="timeGranularity != null and timeGranularity == 'day'">
+                , plan_start_day
+            </if>
+    </select>
+
+    <!-- 鏌ヨ鍘熷缁熻鏁版嵁锛堜笉杩涜鑱氬悎锛�- 鐢ㄤ簬鍦⊿ervice灞傝嚜琛屽鐞嗚仛鍚堥�昏緫 -->
+    <select id="selectRawStatData" parameterType="java.util.Map" resultType="java.util.Map">
+        SELECT 
+            process_name AS "processName",
+            process_plan_start_day AS "processPlanStartDay",
+            plant AS "plant",
+            major AS "major",
+            workshop AS "workshop",
+            process_total_time AS "processTotalTime"
+        FROM aps_gas_piping_route_stat
+        <where>
+            <if test="yearStart != null and monthStart != null">
+                (EXTRACT(YEAR FROM process_plan_start_day) > #{yearStart} OR 
+                 (EXTRACT(YEAR FROM process_plan_start_day) = #{yearStart} AND EXTRACT(MONTH FROM process_plan_start_day) >= #{monthStart}))
+                AND
+                (EXTRACT(YEAR FROM process_plan_start_day) &lt; #{yearEnd} OR 
+                 (EXTRACT(YEAR FROM process_plan_start_day) = #{yearEnd} AND EXTRACT(MONTH FROM process_plan_start_day) &lt;= #{monthEnd}))
+            </if>
+            <if test="plants != null and plants.size() > 0">
+                AND plant IN
+                <foreach collection="plants" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="plant != null and plant != ''">
+                AND plant = #{plant}
+            </if>
+            <if test="majors != null and majors.size() > 0">
+                AND major IN
+                <foreach collection="majors" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="major != null and major != ''">
+                AND major = #{major}
+            </if>
+            <if test="workshops != null and workshops.size() > 0">
+                AND workshop IN
+                <foreach collection="workshops" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="workshop != null and workshop != ''">
+                AND workshop = #{workshop}
+            </if>
+        </where>
+        ORDER BY 
+            process_name, 
+            process_plan_start_day
+    </select>
 
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateProcessStatMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateProcessStatMapper.xml
index a7f7adc..2db812a 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateProcessStatMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateProcessStatMapper.xml
@@ -173,10 +173,13 @@
             production_quantity,
             standard_time,
             process_total_time,
+            process_plan_start_day,
             process_plan_end_day,
+            order_plan_end_day,
             batch_number,
             create_by,
-            del_flag
+            del_flag,
+            warning
         )
         values
         <foreach collection="list" item="item" index="index" separator=",">
@@ -190,10 +193,13 @@
             #{item.productionQuantity},
             #{item.standardTime},
             #{item.processTotalTime},
+            #{item.processPlanStartDay},
             #{item.processPlanEndDay},
+            #{item.orderPlanEndDay},
             #{item.batchNumber},
             #{item.createBy},
-            '0'
+            '0',
+            #{item.warning}
         )
         </foreach>
     </insert>
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomOrderDetailMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomOrderDetailMapper.xml
index 69ff69f..306615d 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomOrderDetailMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomOrderDetailMapper.xml
@@ -127,7 +127,7 @@
     </delete>
 
     <update id="deleteLastPatch" parameterType="String">
-        update aps_plate_standard_require_bom_order_detail set del_flag = '1' where batch_number = #{batchNumber}
+        update aps_plate_standard_require_bom_order_detail set del_flag = '1' where del_flag = '0' and batch_number != #{batchNumber}
     </update>
 
     <insert id="batchInsert" parameterType="com.aps.core.domain.ApsPlate.ApsPlateStandardRequireBomOrderDetail">
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomStockDetailMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomStockDetailMapper.xml
index 4ede8e3..8a6bfc3 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomStockDetailMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireBomStockDetailMapper.xml
@@ -120,7 +120,9 @@
     </delete>
 
     <update id="deleteLastPatch" parameterType="String">
-        update aps_plate_standard_require_bom_stock_detail set del_flag = '1' where batch_number = #{batchNumber}
+        update aps_plate_standard_require_bom_stock_detail
+        set del_flag = '1'
+        where del_flag = '0' and batch_number != #{batchNumber}
     </update>
 
     <insert id="batchInsert" parameterType="com.aps.core.domain.ApsPlate.ApsPlateStandardRequireBomStockDetail">
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireErrorMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireErrorMapper.xml
index bba08bb..5ab7280 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireErrorMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireErrorMapper.xml
@@ -103,6 +103,8 @@
         </foreach>
     </delete>
     <update id="deleteLastPatch" parameterType="String">
-        update aps_plate_standard_require_error set del_flag = '1' where batch_number = #{batchNumber}
+        update aps_plate_standard_require_error
+        set del_flag = '1'
+        where del_flag = '0' and batch_number != #{batchNumber}
     </update>
 </mapper>
\ No newline at end of file
diff --git a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireMapper.xml b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireMapper.xml
index 1e16f2c..b8d1c57 100644
--- a/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireMapper.xml
+++ b/aps-modules/aps-core/src/main/resources/mapper/core/ApsPlate/ApsPlateStandardRequireMapper.xml
@@ -226,6 +226,6 @@
         </foreach>
     </insert>
     <update id="deleteLastPatch" parameterType="String">
-        update aps_plate_standard_require set del_flag = '1' where batch_number = #{batchNumber}
+        update aps_plate_standard_require set del_flag = '1' where del_flag = '0' and batch_number != #{batchNumber}
     </update>
 </mapper>
\ No newline at end of file
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
index e2302d9..1c600bc 100644
--- 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
@@ -1,6 +1,7 @@
 package com.aps.job.mapper;
 
 import com.aps.job.domain.ApsBomHeaderJob;
+import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -11,6 +12,7 @@
  * @author hjy
  * @date 2025-05-08
  */
+@Mapper
 public interface ApsBomHeaderJobMapper 
 {
     /**
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
index 6990931..5025d34 100644
--- 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
@@ -1,6 +1,7 @@
 package com.aps.job.mapper;
 
 import com.aps.job.domain.ApsBomLineJob;
+import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -11,6 +12,7 @@
  * @author hjy
  * @date 2025-05-08
  */
+@Mapper
 public interface ApsBomLineJobMapper 
 {
     /**
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
index 5f71212..2906f0c 100644
--- 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
@@ -3,6 +3,7 @@
 import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
 import com.aps.common.core.constant.SecurityConstants;
 import com.aps.common.core.utils.DateUtils;
 import com.aps.common.core.utils.StringUtils;
@@ -15,6 +16,7 @@
 import com.aps.job.mapper.ApsWorkOrderJobLogMapper;
 import com.aps.job.service.IApsBomHeaderJobService;
 import com.aps.system.api.RemoteCoreService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpEntity;
@@ -35,6 +37,7 @@
  * @date 2025-05-08
  */
 @Service
+@Slf4j
 public class ApsBomHeaderJobServiceImpl implements IApsBomHeaderJobService 
 {
     @Autowired
@@ -213,6 +216,8 @@
                         jobLog.setResult("header:"+headerList.size() + " line:"+lineList.size());
                         jobLog.setCreateBy(batchNum);
                         jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                        log.info("BOM鍚屾锛�"+ JSON.toJSONString(jobLog));
+
                         pageIndex++;
                     }else{
                         break;
@@ -227,6 +232,7 @@
                     jobLog.setResult("error");
                     jobLog.setCreateBy(batchNum);
                     jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                    log.info("BOM鍚屾锛�"+ JSON.toJSONString(jobLog));
                     break;
                 }
             }
@@ -241,6 +247,7 @@
             jobLog.setResult("error");
             jobLog.setCreateBy(batchNum);
             jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+            log.info("BOM鍚屾寮傚父淇℃伅锛�"+ JSON.toJSONString(jobLog));
             return false;
         }
         return true;
@@ -258,16 +265,24 @@
     @Override
     public boolean syncBomDataJob(Integer pageIndex, Integer pageSize, String orgCode, String itemCodeList){
         try {
+            log.info("鍏ㄩ噺鍚屾BOM鏁版嵁瀹氭椂浠诲姟寮�濮�");
+            log.info(" DELETE FROM aps_bom_header_job");
             apsBomHeaderJobMapper.deleteApsBomHeaderJob();
+            log.info(" DELETE FROM aps_bom_line_job");
             apsBomLineJobMapper.deleteApsBomLineJob();
             boolean res = syncBomData(pageIndex, pageSize, orgCode, itemCodeList);
             if(!res){
                 return false;
             }
+            log.info("灏咮OM鍚屾鍒癛edis");
             remoteCoreService.setBomDataToRedis(SecurityConstants.INNER);
+            log.info("deleteApsBomHeader");
             apsBomHeaderJobMapper.deleteApsBomHeader();
+            log.info("deleteApsBomLine");
             apsBomLineJobMapper.deleteApsBomLine();
+            log.info("insertIntoApsBomHeader");
             apsBomHeaderJobMapper.insertIntoApsBomHeader();
+            log.info("insertIntoApsBomLine");
             apsBomLineJobMapper.insertIntoApsBomLine();
         } catch (Exception e) {
             e.printStackTrace();
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialManagementJobServiceImpl.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialManagementJobServiceImpl.java
index cae8691..754d359 100644
--- a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialManagementJobServiceImpl.java
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialManagementJobServiceImpl.java
@@ -3,6 +3,7 @@
 import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
 import com.aps.common.core.utils.DateUtils;
 import com.aps.common.core.utils.StringUtils;
 import com.aps.common.core.utils.uuid.IdUtils;
@@ -11,6 +12,7 @@
 import com.aps.job.mapper.ApsMaterialManagementJobMapper;
 import com.aps.job.mapper.ApsWorkOrderJobLogMapper;
 import com.aps.job.service.IApsMaterialManagementJobService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpEntity;
@@ -31,6 +33,7 @@
  * @date 2025-05-10
  */
 @Service
+@Slf4j
 public class ApsMaterialManagementJobServiceImpl implements IApsMaterialManagementJobService 
 {
     @Autowired
@@ -182,6 +185,7 @@
                         jobLog.setResult("material:"+materialList.size());
                         jobLog.setCreateBy(batchNum);
                         jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                        log.info("鐗╂枡鍚屾锛�"+ JSON.toJSONString(jobLog));
                         pageIndex++;
                     }else{
                         break;
@@ -196,6 +200,7 @@
                     jobLog.setResult("error");
                     jobLog.setCreateBy(batchNum);
                     jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                    log.info("鐗╂枡鍚屾锛�"+ JSON.toJSONString(jobLog));
                     break;
                 }
             }
@@ -210,6 +215,7 @@
             jobLog.setResult("error");
             jobLog.setCreateBy(batchNum);
             jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+            log.info("鐗╂枡鍚屾锛�"+ JSON.toJSONString(jobLog));
             return false;
         }
         return true;
@@ -219,12 +225,16 @@
     @Override
     public boolean syncApsMaterialDataJob(int pageIndex, int pageSize, String orgCode, String itemCodeList) {
         try {
+            log.info("寮�濮嬫竻闄ょ墿鏂欎腑闂磋〃aps_material_management_job");
             apsMaterialManagementJobMapper.deleteApsMaterialJob();
+            log.info("寮�濮嬪悓姝ョ墿鏂欎俊鎭�");
             boolean res = syncApsMaterialData(pageIndex, pageSize, orgCode, itemCodeList);
             if(!res){
                 return false;
             }
+            log.info("寮�濮嬫竻闄ょ墿鏂欒〃 aps_material_management");
             apsMaterialManagementJobMapper.deleteApsMaterial();
+            log.info("鎻掑叆鏁版嵁鍒� aps_material_management");
             apsMaterialManagementJobMapper.insertIntoApsMaterialManagement();
             return true;
         } catch (Exception e) {
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialStorageManagementJobServiceImpl.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialStorageManagementJobServiceImpl.java
index 8999522..10e1953 100644
--- a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialStorageManagementJobServiceImpl.java
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsMaterialStorageManagementJobServiceImpl.java
@@ -1,6 +1,7 @@
 package com.aps.job.service.impl;
 
 import cn.hutool.core.util.IdUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.aps.common.core.utils.DateUtils;
@@ -11,6 +12,7 @@
 import com.aps.job.mapper.ApsMaterialStorageManagementJobMapper;
 import com.aps.job.mapper.ApsWorkOrderJobLogMapper;
 import com.aps.job.service.IApsMaterialStorageManagementJobService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpEntity;
@@ -31,6 +33,7 @@
  * @date 2025-05-08
  */
 @Service
+@Slf4j
 public class ApsMaterialStorageManagementJobServiceImpl implements IApsMaterialStorageManagementJobService 
 {
     @Autowired
@@ -174,6 +177,7 @@
                         jobLog.setResult("storage:"+storageList.size());
                         jobLog.setCreateBy(batchNum);
                         jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                        log.info("鐗╂枡鍚屾锛�"+ JSON.toJSONString(jobLog));
                         pageIndex++;
                     }else{
                         break;
@@ -188,6 +192,7 @@
                     jobLog.setResult("error");
                     jobLog.setCreateBy(batchNum);
                     jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                    log.info("鐗╂枡鍚屾寮傚父锛�"+ JSON.toJSONString(jobLog));
                     break;
                 }
             }
@@ -202,6 +207,7 @@
             jobLog.setResult("error");
             jobLog.setCreateBy(batchNum);
             jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+            log.info("鐗╂枡鍚屾寮傚父锛�"+ JSON.toJSONString(jobLog));
             return false;
         }
         return true;
@@ -211,12 +217,17 @@
     @Override
     public boolean syncApsMaterialStorageDataJob(int pageIndex, int pageSize, String orgCode, String itemCodeList) {
         try {
+            log.info("寮�濮嬪悓姝ュ簱瀛樻暟鎹�");
+            log.info("delete ApsMaterialStorageJob");
             apsMaterialStorageManagementJobMapper.deleteApsMaterialStorageJob();
+            log.info("sync ApsMaterialStorageData");
             boolean res = syncApsMaterialStorageData(pageIndex, pageSize, orgCode, itemCodeList);
             if(!res){
                 return false;
             }
+            log.info("delete ApsMaterialStorage");
             apsMaterialStorageManagementJobMapper.deleteApsMaterialStorage();
+            log.info("insertInto ApsMaterialStorage ");
             apsMaterialStorageManagementJobMapper.insertIntoApsMaterialStorage();
             return true;
         } catch (Exception e) {
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsStandardProcessRouteHeaderJobServiceImpl.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsStandardProcessRouteHeaderJobServiceImpl.java
index 00d6248..25332a9 100644
--- a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsStandardProcessRouteHeaderJobServiceImpl.java
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsStandardProcessRouteHeaderJobServiceImpl.java
@@ -1,6 +1,7 @@
 package com.aps.job.service.impl;
 
 import cn.hutool.core.util.IdUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.aps.common.core.constant.SecurityConstants;
@@ -15,6 +16,7 @@
 import com.aps.job.mapper.ApsWorkOrderJobLogMapper;
 import com.aps.job.service.IApsStandardProcessRouteHeaderJobService;
 import com.aps.system.api.RemoteCoreService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpEntity;
@@ -34,6 +36,7 @@
  * @author hjy
  * @date 2025-05-09
  */
+@Slf4j
 @Service
 public class ApsStandardProcessRouteHeaderJobServiceImpl implements IApsStandardProcessRouteHeaderJobService 
 {
@@ -213,6 +216,7 @@
                         jobLog.setResult("header:"+headerList.size() + " line:"+lineList.size());
                         jobLog.setCreateBy(batchNum);
                         jobLogMapper.insertApsWorkOrderJobLog(jobLog);
+                        log.info("鏍囧噯宸ヨ壓璺嚎鍚屾锛�"+ JSON.toJSONString(jobLog));
                         pageIndex++;
                     }else{
                         break;
@@ -226,6 +230,7 @@
                     jobLog.setBizType("processRoute");
                     jobLog.setResult("error");
                     jobLog.setCreateBy(batchNum);
+                    log.info("鏍囧噯宸ヨ壓璺嚎鍚屾锛�"+ JSON.toJSONString(jobLog));
                     jobLogMapper.insertApsWorkOrderJobLog(jobLog);
                     break;
                 }
@@ -240,6 +245,7 @@
             jobLog.setBizType("processRoute");
             jobLog.setResult("error");
             jobLog.setCreateBy(batchNum);
+            log.info("鏍囧噯宸ヨ壓璺嚎鍚屾锛�"+ JSON.toJSONString(jobLog));
             jobLogMapper.insertApsWorkOrderJobLog(jobLog);
             return false;
         }
@@ -250,6 +256,7 @@
     @Override
     public boolean syncProcessRouteDataJob(Integer pageIndex, Integer pageSize, String orgCode, String itemCodeList) {
         try {
+
             apsStandardProcessRouteHeaderJobMapper.deleteProcessRouteHeaderJob();
             apsStandardProcessRouteLineJobMapper.deleteProcessRouteLineJob();
             boolean res = syncProcessRouteData(pageIndex, pageSize, orgCode, itemCodeList);
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsWeldSeamStandardJobServiceImpl.java b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsWeldSeamStandardJobServiceImpl.java
index 3e6c84b..99f01a4 100644
--- a/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsWeldSeamStandardJobServiceImpl.java
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/service/impl/ApsWeldSeamStandardJobServiceImpl.java
@@ -1,5 +1,6 @@
 package com.aps.job.service.impl;
 
+import cn.hutool.core.collection.ListUtil;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
@@ -95,6 +96,7 @@
     public boolean syncWeldSeamStandardData()
     {
         try {
+            log.info("寮�濮嬪悓姝ョ墿鏂欐爣鍑嗙剨缂濇暟鎹�");
             // 浣跨敤POST鏂规硶璋冪敤鎺ュ彛
             HttpHeaders headers = new HttpHeaders();
             headers.setContentType(MediaType.APPLICATION_JSON);
@@ -174,23 +176,32 @@
             if (jobList.isEmpty()) {
                 return false;
             }
-            
+            log.info("娓呯┖鏃ф暟鎹� deleteAllApsWeldSeamStandardJob");
             // 娓呯┖鏃ф暟鎹�
             deleteAllApsWeldSeamStandardJob();
             
             // 鎵归噺鎻掑叆鏂版暟鎹�
-            batchInsertApsWeldSeamStandardJob(jobList);
-            
+            List<List<ApsWeldSeamStandardJob>> dataGroup = ListUtil.split(jobList, 1000);
+            for (List<ApsWeldSeamStandardJob> data : dataGroup) {
+                batchInsertApsWeldSeamStandardJob(data);
+            }
+
+            // 鍒犻櫎涓氬姟琛ㄦ暟鎹紙鍏ㄩ噺瑕嗙洊锛�
+            deleteAllApsWeldSeamStandard();
             // 鍚屾鏁版嵁鍒颁笟鍔¤〃
-            syncToBizTable(jobList);
-            
+            for (List<ApsWeldSeamStandardJob> data : dataGroup) {
+                syncToBizTable(data);
+            }
             return true;
         } catch (Exception e) {
             log.error("鍚屾鐗╂枡鏍囧噯鐒婄紳鏁版嵁寮傚父", e);
             throw e;
         }
     }
-    
+
+    private void deleteAllApsWeldSeamStandard() {
+        apsWeldSeamStandardMapper.deleteAllApsWeldSeamStandard();
+    }
     /**
      * 鍚屾鏁版嵁鍒颁笟鍔¤〃
      * 
@@ -198,9 +209,6 @@
      */
     private void syncToBizTable(List<ApsWeldSeamStandardJob> jobList) {
         try {
-            // 鍒犻櫎涓氬姟琛ㄦ暟鎹紙鍏ㄩ噺瑕嗙洊锛�
-            apsWeldSeamStandardMapper.deleteAllApsWeldSeamStandard();
-            
             if (jobList == null || jobList.isEmpty()) {
                 return;
             }
diff --git a/aps-modules/aps-job/src/main/java/com/aps/job/util/AbstractQuartzJob.java b/aps-modules/aps-job/src/main/java/com/aps/job/util/AbstractQuartzJob.java
index 833fca7..2db5dbd 100644
--- a/aps-modules/aps-job/src/main/java/com/aps/job/util/AbstractQuartzJob.java
+++ b/aps-modules/aps-job/src/main/java/com/aps/job/util/AbstractQuartzJob.java
@@ -78,7 +78,11 @@
         sysJobLog.setStartTime(startTime);
         sysJobLog.setStopTime(new Date());
         long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime();
-        sysJobLog.setJobMessage(sysJobLog.getJobName() + " 鎬诲叡鑰楁椂锛�" + runMs + "姣");
+        long totalSeconds = runMs / 1000;
+        long minutes = totalSeconds / 60;
+        long seconds = totalSeconds % 60;
+        String formattedTime = minutes + "鍒�" + seconds + "绉�";
+        sysJobLog.setJobMessage(sysJobLog.getJobName() + " 鎬诲叡鑰楁椂锛�" +formattedTime);
         if (e != null)
         {
             sysJobLog.setStatus("1");

--
Gitblit v1.9.3