From cf6bff3922bbd0624b98834f6ea85c8e619e564f Mon Sep 17 00:00:00 2001
From: cl <418351270@qq.com>
Date: 星期二, 16 一月 2024 12:45:46 +0800
Subject: [PATCH] 修改数据采集

---
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP030/impl/COP030ServerInterfaceImpl.java                           |   83 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120/impl/OP120ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP020/impl/BOP020ServerInterfaceImpl.java                           |   84 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP040/impl/OP040ServerInterfaceImpl.java                             |  105 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP050/impl/EOP050ServerInterfaceImpl.java                           |   85 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/GlobalVariable.java                                                     |    2 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP080/impl/OP080ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP140/impl/OP140ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/resources/application-local.yml                                                                              |    8 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP160/impl/OP160ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/OPCComm.java                                                            |  153 --
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP010/impl/EOP010ServerInterfaceImpl.java                           |   76 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120B/impl/OP120BServerInterfaceImpl.java                           |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP080/impl/EOP080ServerInterfaceImpl.java                           |   83 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090B/impl/EOP090BServerInterfaceImpl.java                         |   23 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030/impl/BOP030ServerInterfaceImpl.java                           |   86 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP010/impl/DOP010ServerInterfaceImpl.java                           |   80 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP020/impl/EOP020ServerInterfaceImpl.java                           |   84 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030B/impl/BOP030BServerInterfaceImpl.java                         |   25 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP010/impl/OP010ServerInterfaceImpl.java                             |  118 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP030/impl/OP030ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070/impl/EOP070ServerInterfaceImpl.java                           |   84 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP050/impl/OP050ServerInterfaceImpl.java                             |  136 ++
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP110/impl/OP110ServerInterfaceImpl.java                             |  105 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP070/impl/OP070ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/OpcServiceMain.java                                                         |   30 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130/impl/OP130ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/modular/om/productionOrderBatchInfo/mapper/mapping/ProductionOrderBatchInfoMapper.xml |    2 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130B/impl/OP130BServerInterfaceImpl.java                           |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP150/impl/OP150ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP170/impl/OP170ServerInterfaceImpl.java                             |  106 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP090/impl/OP090ServerInterfaceImpl.java                             |  121 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP020/impl/DOP020ServerInterfaceImpl.java                           |   86 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP010/impl/COP010ServerInterfaceImpl.java                           |   83 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040B/impl/BOP040BServerInterfaceImpl.java                         |   25 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP040/impl/EOP040ServerInterfaceImpl.java                           |   84 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP060/impl/EOP060ServerInterfaceImpl.java                           |   83 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP010/impl/BOP010ServerInterfaceImpl.java                           |   81 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP030/impl/EOP030ServerInterfaceImpl.java                           |   84 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070B/impl/EOP070BServerInterfaceImpl.java                         |   23 
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090/impl/EOP090ServerInterfaceImpl.java                           |   83 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040/impl/BOP040ServerInterfaceImpl.java                           |   85 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP020/impl/COP020ServerInterfaceImpl.java                           |   83 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP100/impl/OP100ServerInterfaceImpl.java                             |  104 +
 guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP020/impl/OP020ServerInterfaceImpl.java                             |  110 +
 45 files changed, 3,584 insertions(+), 169 deletions(-)

diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/modular/om/productionOrderBatchInfo/mapper/mapping/ProductionOrderBatchInfoMapper.xml b/guns-vip-main/src/main/java/cn/stylefeng/guns/modular/om/productionOrderBatchInfo/mapper/mapping/ProductionOrderBatchInfoMapper.xml
index 0a1221a..f9a7765 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/modular/om/productionOrderBatchInfo/mapper/mapping/ProductionOrderBatchInfoMapper.xml
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/modular/om/productionOrderBatchInfo/mapper/mapping/ProductionOrderBatchInfoMapper.xml
@@ -42,7 +42,7 @@
             and work_order_no like CONCAT('%',#{paramCondition.workOrderNo},'%')
         </if>
         <if test="paramCondition.locationCode != null and paramCondition.locationCode != ''">
-            and location_code = #{paramCondition.locationCode}
+            and location_code like CONCAT('%',#{paramCondition.locationCode},'%')
         </if>
     </select>
 
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/OpcServiceMain.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/OpcServiceMain.java
index a616a56..9242219 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/OpcServiceMain.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/OpcServiceMain.java
@@ -13,6 +13,8 @@
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.params.ProductionOrdeInfoParam;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.result.ProductionOrdeInfoResult;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.service.ProductionOrdeInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
 import cn.stylefeng.guns.modular.sc.serialNumbersConf.service.SerialNumbersConfService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
@@ -143,22 +145,28 @@
     @Autowired
     private GreaseManageService greaseManageService;
 
+    @Autowired
+    private ProductionOrderRecordsService productionOrderRecordsService;
+
+    @Autowired
+    private ProductionOrderBatchInfoService productionOrderBatchInfoService;
+
     @Override
     public void run(String... args) throws Exception {
         if(GlobalVariable.TERMINATED) {
             opc.init(productionOrdeInfoService,passingStationCollectionService,paramCollectionService,collectionParamConfService,serialNumbersConfService,
                     equipmentStatusService,equipmentAlarmService,materialTraceabilityService,equipmentInfoService,
-                    repairManageInfoService,locationInfoService,greaseManageService);
+                    repairManageInfoService,locationInfoService,greaseManageService,productionOrderRecordsService,productionOrderBatchInfoService);
 
-            GlobalVariable.PRODUCT_TYPE_MAP.put("191.220001-01","1");
-            GlobalVariable.PRODUCT_TYPE_MAP.put("191.220003-01","2");
-            GlobalVariable.PRODUCT_TYPE_MAP.put("191.220002-01","3");
-            GlobalVariable.PRODUCT_TYPE_MAP.put("191.220004-01","4");
+            GlobalVariable.PRODUCT_TYPE_MAP.put("12980500000198","1");//C1 36V
+            GlobalVariable.PRODUCT_TYPE_MAP.put("12980500000174","2");//C1 48V
+            GlobalVariable.PRODUCT_TYPE_MAP.put("12980500000194","3");//T1 36V
+            GlobalVariable.PRODUCT_TYPE_MAP.put("12980500000201","4");//T1 48V
 
-            GlobalVariable.PRODUCT_CODE_MAP.put("1","191.220001-01");
-            GlobalVariable.PRODUCT_CODE_MAP.put("2","191.220003-01");
-            GlobalVariable.PRODUCT_CODE_MAP.put("3","191.220002-01");
-            GlobalVariable.PRODUCT_CODE_MAP.put("4","191.220004-01");
+            GlobalVariable.PRODUCT_CODE_MAP.put("1","12980500000198");
+            GlobalVariable.PRODUCT_CODE_MAP.put("2","12980500000174");
+            GlobalVariable.PRODUCT_CODE_MAP.put("3","12980500000194");
+            GlobalVariable.PRODUCT_CODE_MAP.put("4","12980500000201");
 
             ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
             cachedThreadPool.execute(new OP010TaskThreadPool());
@@ -171,8 +179,8 @@
             cachedThreadPool.execute(new OP090TaskThreadPool());
             cachedThreadPool.execute(new OP100TaskThreadPool());
             cachedThreadPool.execute(new OP110TaskThreadPool());
-     /*      cachedThreadPool.execute(new OP120TaskThreadPool());
-            cachedThreadPool.execute(new OP120BTaskThreadPool());*/
+           cachedThreadPool.execute(new OP120TaskThreadPool());
+            cachedThreadPool.execute(new OP120BTaskThreadPool());
             cachedThreadPool.execute(new OP130TaskThreadPool());
             cachedThreadPool.execute(new OP130BTaskThreadPool());
             cachedThreadPool.execute(new OP140TaskThreadPool());
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/GlobalVariable.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/GlobalVariable.java
index 19c6c38..2a20a7c 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/GlobalVariable.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/GlobalVariable.java
@@ -9,7 +9,7 @@
 
     public static boolean TERMINATED = true;
 
-    public static int SLEEP_TIME = 2000;
+    public static int SLEEP_TIME = 1000;
 
     public static int HEART_MAX_COUNT = 10;
 
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/OPCComm.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/OPCComm.java
index 2a2f230..bdf0b17 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/OPCComm.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/opc/OPCComm.java
@@ -10,6 +10,8 @@
 import cn.stylefeng.guns.modular.em.equipmentStatus.service.EquipmentStatusService;
 import cn.stylefeng.guns.modular.gm.greaseManage.service.GreaseManageService;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.service.ProductionOrdeInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
 import cn.stylefeng.guns.modular.sc.serialNumbersConf.service.SerialNumbersConfService;
 import cn.stylefeng.guns.plcserver.server.BOP010.callback.*;
@@ -106,6 +108,12 @@
     public LocationInfoService locationInfoService;
     @Autowired
     public GreaseManageService greaseManageService;
+
+    @Autowired
+    public ProductionOrderRecordsService productionOrderRecordsService;
+
+    @Autowired
+    public ProductionOrderBatchInfoService productionOrderBatchInfoService;
 
     //OP010
     private Item OP010_F_HEART_BEAT;//蹇冭烦
@@ -727,7 +735,9 @@
                      EquipmentInfoService equipmentInfoService,
                      RepairManageInfoService repairManageInfoService,
                      LocationInfoService locationInfoService,
-                     GreaseManageService greaseManageService
+                     GreaseManageService greaseManageService,
+                     ProductionOrderRecordsService productionOrderRecordsService,
+                     ProductionOrderBatchInfoService productionOrderBatchInfoService
                     ) throws Exception {
         this.productionOrdeInfoService = productionOrdeInfoService;
         this.passingStationCollectionService = passingStationCollectionService;
@@ -741,6 +751,8 @@
         this.repairManageInfoService = repairManageInfoService;
         this.locationInfoService = locationInfoService;
         this.greaseManageService = greaseManageService;
+        this.productionOrderRecordsService = productionOrderRecordsService;
+        this.productionOrderBatchInfoService = productionOrderBatchInfoService;
 
         // 鍔犺浇閰嶇疆鏂囦欢
         final ConnectionInformation ci = getCLSIDConnectionInfomation();
@@ -753,140 +765,7 @@
             logger.info("This is {} message.", "OPCserver connect success");
             this.server = server;
             // 鍚屾璇诲彇锛�500ms涓�娆�
-            final AccessBase access = new SyncAccess(server, 1000);
-
-            //final AccessBase access = new Async20Access(server, 1000,false);
-
-            //OP010鍥炶皟
-            access.addItem(OPCElement.OP010_F_HEART_BEAT, new DataCallBack_OP010_F_HEART_BEAT());//蹇冭烦
-           /* access.addItem(OPCElement.OP010_E_STATE, new DataCallBack_OP010_E_STATE());//璁惧鐘舵��*/
-
-            //OP020鍥炶皟
-            access.addItem(OPCElement.OP020_F_HEART_BEAT, new DataCallBack_OP020_F_HEART_BEAT());//蹇冭烦
-
-
-            //OP030鍥炶皟
-            access.addItem(OPCElement.OP030_F_HEART_BEAT, new DataCallBack_OP030_F_HEART_BEAT());//蹇冭烦
-
-            //OP040鍥炶皟
-            access.addItem(OPCElement.OP040_F_HEART_BEAT, new DataCallBack_OP040_F_HEART_BEAT());//蹇冭烦
-
-            //OP050鍥炶皟
-            access.addItem(OPCElement.OP050_F_HEART_BEAT, new DataCallBack_OP050_F_HEART_BEAT());//蹇冭烦
-
-
-            //OP070鍥炶皟
-            access.addItem(OPCElement.OP070_F_HEART_BEAT, new DataCallBack_OP070_F_HEART_BEAT());//蹇冭烦
-
-            //OP080鍥炶皟
-            access.addItem(OPCElement.OP080_F_HEART_BEAT, new DataCallBack_OP080_F_HEART_BEAT());//蹇冭烦
-
-            //OP090鍥炶皟
-            access.addItem(OPCElement.OP090_F_HEART_BEAT, new DataCallBack_OP090_F_HEART_BEAT());//蹇冭烦
-
-            //OP100鍥炶皟
-            access.addItem(OPCElement.OP100_F_HEART_BEAT, new DataCallBack_OP100_F_HEART_BEAT());//蹇冭烦
-
-            //OP110鍥炶皟
-            access.addItem(OPCElement.OP110_F_HEART_BEAT, new DataCallBack_OP110_F_HEART_BEAT());//蹇冭烦
-
-
-/*
-            //OP120鍥炶皟
-            access.addItem(OPCElement.OP120_F_HEART_BEAT, new DataCallBack_OP120_F_HEART_BEAT());//蹇冭烦
-
-            //OP120B鍥炶皟
-            access.addItem(OPCElement.OP120B_F_HEART_BEAT, new DataCallBack_OP120B_F_HEART_BEAT());//蹇冭烦
-      */
-
-
-            //OP130鍥炶皟
-            access.addItem(OPCElement.OP130_F_HEART_BEAT, new DataCallBack_OP130_F_HEART_BEAT());//蹇冭烦
-
-            //OP130B鍥炶皟
-            access.addItem(OPCElement.OP130B_F_HEART_BEAT, new DataCallBack_OP130B_F_HEART_BEAT());//蹇冭烦
-
-            //OP140鍥炶皟
-            access.addItem(OPCElement.OP140_F_HEART_BEAT, new DataCallBack_OP140_F_HEART_BEAT());//蹇冭烦
-
-            //OP150鍥炶皟
-/*
-            access.addItem(OPCElement.OP150_F_HEART_BEAT, new DataCallBack_OP150_F_HEART_BEAT());//蹇冭烦
-*/
-
-            //OP160鍥炶皟
-            access.addItem(OPCElement.OP160_F_HEART_BEAT, new DataCallBack_OP160_F_HEART_BEAT());//蹇冭烦
-
-
-            //OP170鍥炶皟
-            access.addItem(OPCElement.OP170_F_HEART_BEAT, new DataCallBack_OP170_F_HEART_BEAT());//蹇冭烦
-
-            //COP010鍥炶皟
-            access.addItem(OPCElement.COP010_F_HEART_BEAT, new DataCallBack_COP010_F_HEART_BEAT());//蹇冭烦
-
-            //COP020鍥炶皟
-            access.addItem(OPCElement.COP020_F_HEART_BEAT, new DataCallBack_COP020_F_HEART_BEAT());//蹇冭烦
-
-            //COP030鍥炶皟
-            access.addItem(OPCElement.COP030_F_HEART_BEAT, new DataCallBack_COP030_F_HEART_BEAT());//蹇冭烦
-
-            //BOP010鍥炶皟
-            access.addItem(OPCElement.BOP010_F_HEART_BEAT, new DataCallBack_BOP010_F_HEART_BEAT());//蹇冭烦
-
-            //BOP020鍥炶皟
-            access.addItem(OPCElement.BOP020_F_HEART_BEAT, new DataCallBack_BOP020_F_HEART_BEAT());//蹇冭烦
-
-            //BOP030鍥炶皟
-            access.addItem(OPCElement.BOP030_F_HEART_BEAT, new DataCallBack_BOP030_F_HEART_BEAT());//蹇冭烦
-
-            //BOP030B鍥炶皟
-            access.addItem(OPCElement.BOP030B_F_HEART_BEAT, new DataCallBack_BOP030B_F_HEART_BEAT());//蹇冭烦
-
-            //BOP040鍥炶皟
-            access.addItem(OPCElement.BOP040_F_HEART_BEAT, new DataCallBack_BOP040_F_HEART_BEAT());//蹇冭烦
-
-            //BOP040B鍥炶皟
-            access.addItem(OPCElement.BOP040B_F_HEART_BEAT, new DataCallBack_BOP040B_F_HEART_BEAT());//蹇冭烦
-
-            //DOP010鍥炶皟
-            access.addItem(OPCElement.DOP010_F_HEART_BEAT, new DataCallBack_DOP010_F_HEART_BEAT());//蹇冭烦
-
-            //DOP020鍥炶皟
-           /* access.addItem(OPCElement.DOP020_F_HEART_BEAT, new DataCallBack_DOP020_F_HEART_BEAT());//蹇冭烦*/
-
-            //EOP010鍥炶皟
-            access.addItem(OPCElement.EOP010_F_HEART_BEAT, new DataCallBack_EOP010_F_HEART_BEAT());//蹇冭烦
-
-            //EOP020鍥炶皟
-            access.addItem(OPCElement.EOP020_F_HEART_BEAT, new DataCallBack_EOP020_F_HEART_BEAT());//蹇冭烦
-
-            //EOP030鍥炶皟
-            access.addItem(OPCElement.EOP030_F_HEART_BEAT, new DataCallBack_EOP030_F_HEART_BEAT());//蹇冭烦
-
-             //EOP040鍥炶皟
-            access.addItem(OPCElement.EOP040_F_HEART_BEAT, new DataCallBack_EOP040_F_HEART_BEAT());//蹇冭烦
-
-            //EOP050鍥炶皟
-            access.addItem(OPCElement.EOP050_F_HEART_BEAT, new DataCallBack_EOP050_F_HEART_BEAT());//蹇冭烦
-
-            //EOP060鍥炶皟
-            access.addItem(OPCElement.EOP060_F_HEART_BEAT, new DataCallBack_EOP060_F_HEART_BEAT());//蹇冭烦
-
-            //EOP070鍥炶皟
-            access.addItem(OPCElement.EOP070_F_HEART_BEAT, new DataCallBack_EOP070_F_HEART_BEAT());//蹇冭烦
-
-            //EOP070B鍥炶皟
-            /*access.addItem(OPCElement.EOP070B_F_HEART_BEAT, new DataCallBack_EOP070B_F_HEART_BEAT());//蹇冭烦*/
-
-            //EOP080鍥炶皟
-            access.addItem(OPCElement.EOP080_F_HEART_BEAT, new DataCallBack_EOP080_F_HEART_BEAT());//蹇冭烦
-
-            //EOP090鍥炶皟
-            access.addItem(OPCElement.EOP090_F_HEART_BEAT, new DataCallBack_EOP090_F_HEART_BEAT());//蹇冭烦
-
-
-            //EOP090B鍥炶皟
-            access.addItem(OPCElement.EOP090B_F_HEART_BEAT, new DataCallBack_EOP090B_F_HEART_BEAT());//蹇冭烦
+            final AccessBase access = new SyncAccess(server, 500);
 
             //OP010缁�
             final Group OP010_GROUP = server.addGroup("OP010");
@@ -1047,7 +926,7 @@
             OP110_S_PRODUCT_STATE_CODE = OP110_GROUP.addItem((OPCElement.OP110_S_PRODUCT_STATE_CODE));//浜у搧鐘舵�佺紪鐮�
 
             //OP120缁�
-         /*   final Group OP120_GROUP = server.addGroup("OP120");
+            final Group OP120_GROUP = server.addGroup("OP120");
             OP120_F_HEART_BEAT = OP120_GROUP.addItem((OPCElement.OP120_F_HEART_BEAT));//蹇冭烦
             OP120_J_PLC_START = OP120_GROUP.addItem((OPCElement.OP120_J_PLC_START));//PLC寮�濮�
             OP120_J_PC_WRITE_ORDER = OP120_GROUP.addItem((OPCElement.OP120_J_PC_WRITE_ORDER));//PC璇绘暟鎹畬鎴�
@@ -1072,7 +951,7 @@
             OP120B_S_PRODUCT_CODE = OP120B_GROUP.addItem((OPCElement.OP120B_S_PRODUCT_CODE));//浜у搧缂栧彿
             OP120B_S_SFC_CODE = OP120B_GROUP.addItem((OPCElement.OP120B_S_SFC_CODE));//鎬绘垚缂栫爜
 
-            OP120B_S_PRODUCT_STATE_CODE = OP120B_GROUP.addItem((OPCElement.OP120B_S_PRODUCT_STATE_CODE));//浜у搧鐘舵�佺紪鐮�*/
+            OP120B_S_PRODUCT_STATE_CODE = OP120B_GROUP.addItem((OPCElement.OP120B_S_PRODUCT_STATE_CODE));//浜у搧鐘舵�佺紪鐮�
 
             //OP130缁�
             final Group OP130_GROUP = server.addGroup("OP130");
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP010/impl/BOP010ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP010/impl/BOP010ServerInterfaceImpl.java
index 12b8bbb..b25cffc 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP010/impl/BOP010ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP010/impl/BOP010ServerInterfaceImpl.java
@@ -12,6 +12,9 @@
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.params.ProductionOrdeInfoParam;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.result.ProductionOrdeInfoResult;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.service.ProductionOrdeInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.params.RepairManageInfoParam;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.result.RepairManageInfoResult;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
@@ -56,13 +59,32 @@
     private static List list = null;
     private static Group group = null;
 
+    private int count = 0;
 
-
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if (value.equals("false")) {
+            OPCUnit.write(opc.getBOP010_F_HEART_BEAT(), "true");
+            GlobalVariable.BOP010_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.BOP010_F_HEART_BEAT = false;
+        }
+    }
 
     @Override
-    public void monitor() {
+    public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getBOP010_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
 
             if(GlobalVariable.BOP010_F_HEART_BEAT) {
 
@@ -88,6 +110,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getBOP010_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleFinsh();
                     }
                 }
@@ -191,6 +214,60 @@
         }
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getBOP010_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getBOP010_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getBOP010_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
     //PC瀹屾垚
     public void handleFinsh() {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP020/impl/BOP020ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP020/impl/BOP020ServerInterfaceImpl.java
index 1d5e95e..3034b9e 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP020/impl/BOP020ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP020/impl/BOP020ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,34 @@
     private static String GROUP_NAME  = "BOP020_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if (value.equals("false")) {
+            OPCUnit.write(opc.getBOP020_F_HEART_BEAT(), "true");
+            GlobalVariable.BOP020_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.BOP020_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getBOP020_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.BOP020_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getBOP020_J_PLC_START());//PLC寮�濮�
@@ -64,6 +93,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getBOP020_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -145,6 +175,60 @@
 
         logger.info("BOP020宸ヤ綅,handleInfo END锛�");
     }
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getBOP020_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getBOP020_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getBOP020_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
     //PC瀹屾垚
     public void handleFinsh() {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030/impl/BOP030ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030/impl/BOP030ServerInterfaceImpl.java
index aa9edbc..98a449a 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030/impl/BOP030ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030/impl/BOP030ServerInterfaceImpl.java
@@ -8,9 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.params.GreaseManageParam;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.result.GreaseManageResult;
 import cn.stylefeng.guns.modular.gm.greaseManage.service.GreaseManageService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -51,10 +56,34 @@
     private static String GROUP_NAME  = "BOP030_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if (value.equals("false")) {
+            OPCUnit.write(opc.getBOP030_F_HEART_BEAT(), "true");
+            GlobalVariable.BOP030_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.BOP030_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getBOP030_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.BOP030_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getBOP030_J_PLC_START());//PLC寮�濮�
@@ -71,6 +100,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getBOP030_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -105,7 +135,7 @@
             }else{
                 OPCUnit.write(opc.getBOP030_OIL_STATE(), "true"); //鍐欐补鑴傜姸鎬�
             }
-            logger.info("鍒版湡鏃ユ湡锛�"+duaDate+"褰撳墠鏃ユ湡锛�"+currentDate+"鍓╀綑澶╂暟锛氾細"+daysBetween);
+            //logger.info("鍒版湡鏃ユ湡锛�"+duaDate+"褰撳墠鏃ユ湡锛�"+currentDate+"鍓╀綑澶╂暟锛氾細"+daysBetween);
         }
     }
 
@@ -180,6 +210,60 @@
 
         logger.info("BOP030宸ヤ綅,handleInfo END锛�");
     }
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getBOP030_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getBOP030_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getBOP030_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
     //PC瀹屾垚
     public void handleFinsh() {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030B/impl/BOP030BServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030B/impl/BOP030BServerInterfaceImpl.java
index a32611f..c9b2525 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030B/impl/BOP030BServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP030B/impl/BOP030BServerInterfaceImpl.java
@@ -44,10 +44,35 @@
     private static String GROUP_NAME  = "BOP030B_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if (value.equals("false")) {
+            OPCUnit.write(opc.getBOP030B_F_HEART_BEAT(), "true");
+            GlobalVariable.BOP030B_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.BOP030B_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getBOP030B_F_HEART_BEAT());
+            assert isHeartBeat != null;
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.BOP030B_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getBOP030B_J_PLC_START());//PLC寮�濮�
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040/impl/BOP040ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040/impl/BOP040ServerInterfaceImpl.java
index 9725c76..310ba5d 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040/impl/BOP040ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040/impl/BOP040ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,35 @@
     private static String GROUP_NAME  = "BOP040_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if (value.equals("false")) {
+            OPCUnit.write(opc.getBOP040_F_HEART_BEAT(), "true");
+            GlobalVariable.BOP040_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.BOP040_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getBOP040_F_HEART_BEAT());
+            assert isHeartBeat != null;
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.BOP040_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getBOP040_J_PLC_START());//PLC寮�濮�
@@ -64,6 +94,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getBOP040_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -145,6 +176,60 @@
 
         logger.info("BOP040宸ヤ綅,handleInfo END锛�");
     }
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getBOP040_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getBOP040_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getBOP040_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
     //PC瀹屾垚
     public void handleFinsh() {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040B/impl/BOP040BServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040B/impl/BOP040BServerInterfaceImpl.java
index 2ef5a32..478bd20 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040B/impl/BOP040BServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/BOP040B/impl/BOP040BServerInterfaceImpl.java
@@ -44,10 +44,35 @@
     private static String GROUP_NAME  = "BOP040B_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if (value.equals("false")) {
+            OPCUnit.write(opc.getBOP040B_F_HEART_BEAT(), "true");
+            GlobalVariable.BOP040B_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.BOP040B_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getBOP040B_F_HEART_BEAT());
+            assert isHeartBeat != null;
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.BOP040B_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getBOP040B_J_PLC_START());//PLC寮�濮�
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP010/impl/COP010ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP010/impl/COP010ServerInterfaceImpl.java
index eee5d99..a105e5c 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP010/impl/COP010ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP010/impl/COP010ServerInterfaceImpl.java
@@ -6,9 +6,14 @@
 import cn.stylefeng.guns.modular.bs.locationInfo.service.LocationInfoService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.params.ProductionOrdeInfoParam;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.result.ProductionOrdeInfoResult;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.service.ProductionOrdeInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.params.RepairManageInfoParam;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.result.RepairManageInfoResult;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
@@ -53,13 +58,32 @@
     private static List list = null;
     private static Group group = null;
 
+    private int count = 0;
 
-
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getCOP010_F_HEART_BEAT(), "true");
+            GlobalVariable.COP010_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.COP010_F_HEART_BEAT = false;
+        }
+    }
 
     @Override
-    public void monitor() {
+    public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getCOP010_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
 
             if(GlobalVariable.COP010_F_HEART_BEAT) {
 
@@ -83,6 +107,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getCOP010_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleFinsh();
                     }
                 }
@@ -187,6 +212,60 @@
         }
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getCOP010_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getCOP010_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getCOP010_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
     //PC瀹屾垚
     public void handleFinsh() {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP020/impl/COP020ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP020/impl/COP020ServerInterfaceImpl.java
index 153a886..4de191a 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP020/impl/COP020ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP020/impl/COP020ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "COP020_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getCOP020_F_HEART_BEAT(), "true");
+            GlobalVariable.COP020_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.COP020_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getCOP020_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.COP020_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getCOP020_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getCOP020_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -145,6 +174,60 @@
 
         logger.info("COP020宸ヤ綅,handleInfo END锛�");
     }
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getCOP020_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getCOP020_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getCOP020_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
     //PC瀹屾垚
     public void handleFinsh() {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP030/impl/COP030ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP030/impl/COP030ServerInterfaceImpl.java
index 3838039..8684cc1 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP030/impl/COP030ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/COP030/impl/COP030ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "COP030_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getCOP030_F_HEART_BEAT(), "true");
+            GlobalVariable.COP030_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.COP030_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getCOP030_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.COP030_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getCOP030_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getCOP030_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -145,6 +174,60 @@
 
         logger.info("COP030宸ヤ綅,handleInfo END锛�");
     }
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getCOP030_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getCOP030_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getCOP030_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
     //PC瀹屾垚
     public void handleFinsh() {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP010/impl/DOP010ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP010/impl/DOP010ServerInterfaceImpl.java
index 6694640..d0acbeb 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP010/impl/DOP010ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP010/impl/DOP010ServerInterfaceImpl.java
@@ -12,6 +12,9 @@
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.params.ProductionOrdeInfoParam;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.result.ProductionOrdeInfoResult;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.service.ProductionOrdeInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.params.RepairManageInfoParam;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.result.RepairManageInfoResult;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
@@ -52,13 +55,31 @@
     private static List list = null;
     private static Group group = null;
 
+    private int count = 0;
 
-
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getDOP010_F_HEART_BEAT(), "true");
+            GlobalVariable.DOP010_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.DOP010_F_HEART_BEAT = false;
+        }
+    }
 
     @Override
-    public void monitor() {
+    public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getDOP010_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
 
             if(GlobalVariable.DOP010_F_HEART_BEAT) {
 
@@ -83,6 +104,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getDOP010_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleFinsh();
                     }
                 }
@@ -196,6 +218,60 @@
         }
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getDOP010_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getDOP010_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getDOP010_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
 
 
     //PC瀹屾垚
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP020/impl/DOP020ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP020/impl/DOP020ServerInterfaceImpl.java
index 766d579..8471ac0 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP020/impl/DOP020ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/DOP020/impl/DOP020ServerInterfaceImpl.java
@@ -8,9 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.params.GreaseManageParam;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.result.GreaseManageResult;
 import cn.stylefeng.guns.modular.gm.greaseManage.service.GreaseManageService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -51,10 +56,33 @@
     private static String GROUP_NAME  = "DOP020_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getDOP020_F_HEART_BEAT(), "true");
+            GlobalVariable.DOP020_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.DOP020_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getDOP020_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.DOP020_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getDOP020_J_PLC_START());//PLC寮�濮�
@@ -71,6 +99,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getDOP020_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -104,7 +133,7 @@
             }else{
                 OPCUnit.write(opc.getDOP020_OIL_STATE(), "true"); //鍐欐补鑴傜姸鎬�
             }
-            logger.info("鍒版湡鏃ユ湡锛�"+duaDate+"褰撳墠鏃ユ湡锛�"+currentDate+"鍓╀綑澶╂暟锛氾細"+daysBetween);
+            //logger.info("鍒版湡鏃ユ湡锛�"+duaDate+"褰撳墠鏃ユ湡锛�"+currentDate+"鍓╀綑澶╂暟锛氾細"+daysBetween);
         }
     }
 
@@ -180,6 +209,61 @@
         logger.info("DOP020宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getDOP020_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getDOP020_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getDOP020_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP010/impl/EOP010ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP010/impl/EOP010ServerInterfaceImpl.java
index 25c7aa2..ac0ab5b 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP010/impl/EOP010ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP010/impl/EOP010ServerInterfaceImpl.java
@@ -10,6 +10,9 @@
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
 import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
 import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -46,10 +49,33 @@
     private static String GROUP_NAME  = "EOP010_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP010_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP010_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP010_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP010_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP010_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP010_J_PLC_START());//PLC寮�濮�
@@ -69,6 +95,7 @@
                         handleMaterial();
                         handleInfo();
                         handleFinsh();
+
                     }
                 }
 
@@ -97,18 +124,63 @@
     }
 
     public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP010_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP010_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP010_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
         String materialCode = OPCUnit.read(opc.getEOP010_S_MATERIAL_CODE());
         MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
-        MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
         materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
         materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
         materialTraceabilityParam.setProductNo(S_SFC_CODE);
         materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
         materialTraceabilityParam.setLocationCode(LOCATION_CODE);
         materialTraceabilityParam.setMaterialCode(materialCode);
-        //materialTraceabilityParam.setAssemblyQty(1);
+        MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+        materialTraceabilityParam.setAssemblyQty(1);
         materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
         materialTraceabilityService.add(materialTraceabilityParam);
+
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+                materialTraceabilityService.add(materialTraceabilityParam);
+
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+
     }
     //PC璇诲弬鏁颁俊鎭�
     public void handleInfo() throws Exception {
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP020/impl/EOP020ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP020/impl/EOP020ServerInterfaceImpl.java
index 364d6fe..368fcd3 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP020/impl/EOP020ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP020/impl/EOP020ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "EOP020_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP020_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP020_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP020_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP020_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP020_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP020_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP020_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -146,6 +175,61 @@
         logger.info("EOP020宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP020_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP020_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP020_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP030/impl/EOP030ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP030/impl/EOP030ServerInterfaceImpl.java
index 74072c5..eaea5ac 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP030/impl/EOP030ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP030/impl/EOP030ServerInterfaceImpl.java
@@ -8,9 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.params.GreaseManageParam;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.result.GreaseManageResult;
 import cn.stylefeng.guns.modular.gm.greaseManage.service.GreaseManageService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -49,10 +54,33 @@
     private static String GROUP_NAME  = "EOP030_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP030_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP030_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP030_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP030_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP030_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP030_J_PLC_START());//PLC寮�濮�
@@ -69,6 +97,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP030_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -152,6 +181,61 @@
         logger.info("EOP030宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP030_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP030_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP030_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP040/impl/EOP040ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP040/impl/EOP040ServerInterfaceImpl.java
index f5d5bf8..474d869 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP040/impl/EOP040ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP040/impl/EOP040ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "EOP040_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP040_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP040_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP040_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP040_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP040_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP040_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP040_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -146,6 +175,61 @@
         logger.info("EOP040宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP040_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP040_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP040_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP050/impl/EOP050ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP050/impl/EOP050ServerInterfaceImpl.java
index 7316df6..e32a505 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP050/impl/EOP050ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP050/impl/EOP050ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "EOP050_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP050_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP050_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP050_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP050_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP050_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP050_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP050_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -146,6 +175,62 @@
         logger.info("EOP050宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP050_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP050_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP050_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP060/impl/EOP060ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP060/impl/EOP060ServerInterfaceImpl.java
index d93938d..09256e3 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP060/impl/EOP060ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP060/impl/EOP060ServerInterfaceImpl.java
@@ -14,6 +14,9 @@
 import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
 import cn.stylefeng.guns.modular.dq.materialTraceability.model.result.MaterialTraceabilityResult;
 import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.params.RepairManageInfoParam;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.result.RepairManageInfoResult;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
@@ -53,10 +56,33 @@
     private static String GROUP_NAME  = "EOP060_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP060_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP060_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP060_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP060_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP060_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP060_J_PLC_START());//PLC寮�濮�
@@ -79,6 +105,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP060_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -218,6 +245,62 @@
         logger.info("EOP060宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP060_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP060_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP060_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070/impl/EOP070ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070/impl/EOP070ServerInterfaceImpl.java
index 3e836c6..4a50b16 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070/impl/EOP070ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070/impl/EOP070ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "EOP070_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP070_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP070_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP070_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP070_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP070_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP070_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP070_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -146,6 +175,61 @@
         logger.info("EOP070宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP070_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP070_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP070_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070B/impl/EOP070BServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070B/impl/EOP070BServerInterfaceImpl.java
index 3fe5458..1d9e8e4 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070B/impl/EOP070BServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP070B/impl/EOP070BServerInterfaceImpl.java
@@ -44,10 +44,33 @@
     private static String GROUP_NAME  = "EOP070B_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP070B_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP070B_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP070B_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP070B_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP070B_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP070B_J_PLC_START());//PLC寮�濮�
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP080/impl/EOP080ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP080/impl/EOP080ServerInterfaceImpl.java
index 77b8509..91e8a68 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP080/impl/EOP080ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP080/impl/EOP080ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "EOP080_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP080_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP080_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP080_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP080_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP080_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP080_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP080_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -146,6 +175,60 @@
         logger.info("EOP080宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP080_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP080_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP080_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090/impl/EOP090ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090/impl/EOP090ServerInterfaceImpl.java
index 0304077..a7d0565 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090/impl/EOP090ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090/impl/EOP090ServerInterfaceImpl.java
@@ -8,6 +8,11 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +49,33 @@
     private static String GROUP_NAME  = "EOP090_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP090_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP090_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP090_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP090_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP090_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP090_J_PLC_START());//PLC寮�濮�
@@ -64,6 +92,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getEOP090_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -146,6 +175,60 @@
         logger.info("EOP090宸ヤ綅,handleInfo END锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getEOP090_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getEOP090_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getEOP090_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090B/impl/EOP090BServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090B/impl/EOP090BServerInterfaceImpl.java
index b4a3847..7449766 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090B/impl/EOP090BServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/EOP090B/impl/EOP090BServerInterfaceImpl.java
@@ -44,10 +44,33 @@
     private static String GROUP_NAME  = "EOP090B_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getEOP090B_F_HEART_BEAT(), "true");
+            GlobalVariable.EOP090B_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.EOP090B_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+            String isHeartBeat = OPCUnit.read(opc.getEOP090B_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.EOP090B_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getEOP090B_J_PLC_START());//PLC寮�濮�
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP010/impl/OP010ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP010/impl/OP010ServerInterfaceImpl.java
index 8588d57..7cbc39a 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP010/impl/OP010ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP010/impl/OP010ServerInterfaceImpl.java
@@ -7,10 +7,18 @@
 import cn.stylefeng.guns.modular.bs.locationInfo.service.LocationInfoService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.entity.ProductionOrdeInfo;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.params.ProductionOrdeInfoParam;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.result.ProductionOrdeInfoResult;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.service.ProductionOrdeInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.params.RepairManageInfoParam;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.result.RepairManageInfoResult;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
@@ -57,13 +65,32 @@
 
     private static Integer ACTUAL_ONLINE_QTY  = 0 ;//涓婄嚎鏁伴噺
 
+    private int count = 0;
 
-
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP010_F_HEART_BEAT(), "true");
+            GlobalVariable.OP010_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP010_F_HEART_BEAT = false;
+        }
+    }
 
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP010_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
 
             if(GlobalVariable.OP010_F_HEART_BEAT) {
 
@@ -89,6 +116,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP010_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleFinsh();
                     }
                 }
@@ -156,6 +184,7 @@
     }
     //PC涓嬪彂宸ュ崟
     public void handleOrder() {
+
         logger.info("OP010宸ヤ綅,handleOrder PC澶勭悊寮�濮嬶紒");
         IN_TIME = DateTool.getLocalTimeForDate();
         ProductionOrdeInfoParam param = new ProductionOrdeInfoParam();
@@ -216,6 +245,18 @@
             S_PRODUCT_TYPE = GlobalVariable.PRODUCT_TYPE_MAP.get(S_PRODUCT_CODE);
             ACTUAL_ONLINE_QTY = result.getActualOnlineQty();
 
+
+            //鏂板鎶ュ伐璁板綍
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            productionOrderRecordsParam.setMaterialCode(S_PRODUCT_CODE);
+            productionOrderRecordsParam.setStartTime(DateTool.getLocalTimeForDate());
+            productionOrderRecordsParam.setWhetherPass("true");
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+            productionOrderRecordsService.add(productionOrderRecordsParam);
+
+
             OPCUnit.write(opc.getOP010_S_ORDER_CODE(),S_ORDER_CODE); //宸ュ崟缂栧彿
             OPCUnit.write(opc.getOP010_S_PRODUCT_CODE(), S_PRODUCT_TYPE); //浜у搧缂栧彿
             OPCUnit.write(opc.getOP010_S_SFC_CODE(), S_SFC_CODE); //鎬绘垚缂栫爜
@@ -229,6 +270,61 @@
     }
 
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP010_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP010_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP010_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
     //PC瀹屾垚
     public void handleFinsh() {
         logger.info("OP010宸ヤ綅,handleFinsh PC澶勭悊寮�濮嬶紒");
@@ -239,8 +335,26 @@
             S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
             S_SFC_CODE = OPCUnit.read(opc.getOP010_S_SFC_CODE());//鎬绘垚缂栫爜
         }
-        //澶勭悊杩囩珯淇℃伅
+
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP010_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+        //澶勭悊杩囩珯淇℃伅
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP020/impl/OP020ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP020/impl/OP020ServerInterfaceImpl.java
index cf9772f..a728950 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP020/impl/OP020ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP020/impl/OP020ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP020_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP020_F_HEART_BEAT(), "true");
+            GlobalVariable.OP020_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP020_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP020_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP020_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP020_J_PLC_START());//PLC寮�濮�
@@ -64,6 +96,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP020_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +124,62 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP020_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP020_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP020宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP020_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP020_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP020_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                //productionOrderBatchInfoParam.setProductionLine((remainingQuantity-1)+"");
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -146,6 +235,7 @@
         logger.info("OP020宸ヤ綅,handleInfo END锛�");
     }
 
+
     //PC瀹屾垚
     public void handleFinsh() {
         if("".equals(S_ORDER_CODE)){
@@ -155,8 +245,26 @@
             S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
             S_SFC_CODE = OPCUnit.read(opc.getOP020_S_SFC_CODE());//鎬绘垚缂栫爜
         }
-        //澶勭悊杩囩珯淇℃伅
+
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP020_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+        //澶勭悊杩囩珯淇℃伅
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP030/impl/OP030ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP030/impl/OP030ServerInterfaceImpl.java
index dd31962..639c489 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP030/impl/OP030ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP030/impl/OP030ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP030_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP030_F_HEART_BEAT(), "true");
+            GlobalVariable.OP030_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP030_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP030_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP030_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP030_J_PLC_START());//PLC寮�濮�
@@ -64,6 +96,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP030_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +124,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP030_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP030_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP030宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP030_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP030_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP030_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +245,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP030_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP040/impl/OP040ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP040/impl/OP040ServerInterfaceImpl.java
index 8aabdd4..73e3c48 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP040/impl/OP040ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP040/impl/OP040ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP040_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP040_F_HEART_BEAT(), "true");
+            GlobalVariable.OP040_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP040_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP040_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP040_F_HEART_BEAT) {
 
                 //PC璇诲伐鍗�
@@ -65,6 +97,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP040_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -92,6 +125,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP040_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP040_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP040宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP040_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP040_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP040_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -158,6 +246,23 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP040_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP050/impl/OP050ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP050/impl/OP050ServerInterfaceImpl.java
index 8cca803..ec7996e 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP050/impl/OP050ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP050/impl/OP050ServerInterfaceImpl.java
@@ -7,10 +7,19 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.model.params.ParamCollectionParam;
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
+import cn.stylefeng.guns.modular.cm.passingStationCollection.model.result.PassingStationCollectionResult;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.params.GreaseManageParam;
 import cn.stylefeng.guns.modular.gm.greaseManage.model.result.GreaseManageResult;
 import cn.stylefeng.guns.modular.gm.greaseManage.service.GreaseManageService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -51,10 +60,34 @@
     private static String GROUP_NAME  = "OP050_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP050_F_HEART_BEAT(), "true");
+            GlobalVariable.OP050_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP050_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP050_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP050_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP050_J_PLC_START());//PLC寮�濮�
@@ -71,6 +104,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP050_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -108,7 +142,7 @@
             }else{
                 OPCUnit.write(opc.getOP050_OIL_STATE(), "true"); //鍐欐补鑴傜姸鎬�
             }
-            logger.info("鍒版湡鏃ユ湡锛�"+duaDate+"褰撳墠鏃ユ湡锛�"+currentDate+"鍓╀綑澶╂暟锛氾細"+daysBetween);
+            //logger.info("鍒版湡鏃ユ湡锛�"+duaDate+"褰撳墠鏃ユ湡锛�"+currentDate+"鍓╀綑澶╂暟锛氾細"+daysBetween);
         }
     }
 
@@ -128,6 +162,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP050_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP050_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP050宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP050_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP050_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP050_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -196,6 +285,7 @@
 
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP050_S_PRODUCT_STATE_CODE());
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
@@ -208,9 +298,17 @@
         PassingStationCollectionService passingStationCollectionService = opc.passingStationCollectionService;
         passingStationCollectionService.add(param);
 
-        //鏍规嵁鍒嗘�绘垚缂栫爜锛屽皢EOP杩囩珯鏁版嵁缁戝畾鍏崇郴淇敼涓烘�绘垚缂栫爜
+
+
         String  copSfcCode = OPCUnit.read(opc.getOP050_S_SFC_CODE_COP());//COP鍒嗘�绘垚
         String  bopSfcCode = OPCUnit.read(opc.getOP050_S_SFC_CODE_BOP());//BOP鍒嗘�绘垚
+
+        //鏍规嵁鍒嗘�绘垚缂栫爜锛屽皢EOP鐗╂枡鏁版嵁缁戝畾鍏崇郴淇敼涓烘�绘垚缂栫爜
+        MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+        materialTraceabilityService.updateSFC(S_SFC_CODE,copSfcCode);
+        materialTraceabilityService.updateSFC(S_SFC_CODE,bopSfcCode);
+
+        //鏍规嵁鍒嗘�绘垚缂栫爜锛屽皢EOP杩囩珯鏁版嵁缁戝畾鍏崇郴淇敼涓烘�绘垚缂栫爜
         passingStationCollectionService.updateSFC(S_SFC_CODE,copSfcCode);
         passingStationCollectionService.updateSFC(S_SFC_CODE,bopSfcCode);
 
@@ -220,6 +318,40 @@
         paramCollectionService.updateSFC(S_SFC_CODE,copSfcCode);
         paramCollectionService.updateSFC(S_SFC_CODE,bopSfcCode);
 
+        logger.info("S_SFC_CODE:"+S_SFC_CODE);
+        logger.info("copSfcCode:"+copSfcCode);
+        logger.info("bopSfcCode:"+bopSfcCode);
+
+        //鏌ヨCOP鍜孊OP鏄惁鍚堟牸
+        PassingStationCollectionParam passingStationCollectionParam = new PassingStationCollectionParam();
+        passingStationCollectionParam.setSfcCode(S_SFC_CODE);
+        List<PassingStationCollectionResult> passingStationCollectionResultList =
+                opc.passingStationCollectionService.findListBySpec(passingStationCollectionParam);
+
+        String isProductState = "true";
+        for(int i=0;i<passingStationCollectionResultList.size();i++){
+            PassingStationCollectionResult passingStationCollectionResult = passingStationCollectionResultList.get(i);
+            if("false".equals(passingStationCollectionResult.getOutRsSign())){
+                isProductState = "false";
+                break;
+            }
+        }
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE) || "false".equals(isProductState)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass("false");
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
 
         OPCUnit.write(opc.getOP050_J_PC_FINISH(), "true"); //PC瀹屾垚
 
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP070/impl/OP070ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP070/impl/OP070ServerInterfaceImpl.java
index fb4cabd..b50264f 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP070/impl/OP070ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP070/impl/OP070ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP070_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP070_F_HEART_BEAT(), "true");
+            GlobalVariable.OP070_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP070_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP070_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP070_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP070_J_PLC_START());//PLC寮�濮�
@@ -64,6 +96,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP070_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +124,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP070_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP070_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP070宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP070_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP070_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP070_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +245,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP070_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP080/impl/OP080ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP080/impl/OP080ServerInterfaceImpl.java
index 013b419..da5ec10 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP080/impl/OP080ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP080/impl/OP080ServerInterfaceImpl.java
@@ -11,6 +11,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.params.RepairManageInfoParam;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.model.result.RepairManageInfoResult;
 import cn.stylefeng.guns.modular.sc.repairManageInfo.service.RepairManageInfoService;
@@ -50,10 +58,34 @@
     private static String GROUP_NAME  = "OP080_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP080_F_HEART_BEAT(), "true");
+            GlobalVariable.OP080_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP080_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP080_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP080_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP080_J_PLC_START());//PLC寮�濮�
@@ -76,6 +108,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP080_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -151,6 +184,61 @@
         logger.info("OP080宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
     }
 
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP080_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP080_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP080_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
+    }
+
     //PC璇诲弬鏁颁俊鎭�
     public void handleInfo() throws Exception {
         logger.info("OP080宸ヤ綅,handleInfo START锛�");
@@ -215,6 +303,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP080_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP090/impl/OP090ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP090/impl/OP090ServerInterfaceImpl.java
index b337cf4..e8cd4ff 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP090/impl/OP090ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP090/impl/OP090ServerInterfaceImpl.java
@@ -7,8 +7,16 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.model.params.ParamCollectionParam;
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
+import cn.stylefeng.guns.modular.cm.passingStationCollection.model.result.PassingStationCollectionResult;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
 import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -45,10 +53,34 @@
     private static String GROUP_NAME  = "OP090_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP090_F_HEART_BEAT(), "true");
+            GlobalVariable.OP090_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP090_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP090_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP090_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP090_J_PLC_START());//PLC寮�濮�
@@ -65,6 +97,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP090_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -92,6 +125,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP090_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP090_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP090宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP090_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP090_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP090_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -184,6 +272,39 @@
         ParamCollectionService paramCollectionService = opc.paramCollectionService;
         paramCollectionService.updateSFC(S_SFC_CODE,eopSfcCode);
 
+        logger.info("S_SFC_CODE:"+S_SFC_CODE);
+        logger.info("eopSfcCode:"+eopSfcCode);
+
+        //鏌ヨCOP鍜孊OP鏄惁鍚堟牸
+        PassingStationCollectionParam passingStationCollectionParam = new PassingStationCollectionParam();
+        passingStationCollectionParam.setSfcCode(S_SFC_CODE);
+        List<PassingStationCollectionResult> passingStationCollectionResultList =
+                opc.passingStationCollectionService.findListBySpec(passingStationCollectionParam);
+
+        String isProductState = "true";
+        for(int i=0;i<passingStationCollectionResultList.size();i++){
+            PassingStationCollectionResult passingStationCollectionResult = passingStationCollectionResultList.get(i);
+            if("false".equals(passingStationCollectionResult.getOutRsSign())){
+                isProductState = "false";
+                break;
+            }
+        }
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE) || "false".equals(isProductState)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass("false");
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
         OPCUnit.write(opc.getOP090_J_PC_FINISH(), "true"); //PC瀹屾垚
 
         logger.info("OP090宸ヤ綅,handleFinsh PC澶勭悊瀹屾垚锛�");
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP100/impl/OP100ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP100/impl/OP100ServerInterfaceImpl.java
index dedc471..fd0287f 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP100/impl/OP100ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP100/impl/OP100ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,33 @@
     private static String GROUP_NAME  = "OP100_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP100_F_HEART_BEAT(), "true");
+            GlobalVariable.OP100_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP100_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP100_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP100_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP100_J_PLC_START());//PLC寮�濮�
@@ -64,6 +95,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP100_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +123,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP100_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP100_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP100宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP100_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP100_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP100_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +244,23 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP100_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP110/impl/OP110ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP110/impl/OP110ServerInterfaceImpl.java
index a02d9f5..7fd8d74 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP110/impl/OP110ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP110/impl/OP110ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP110_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP110_F_HEART_BEAT(), "true");
+            GlobalVariable.OP110_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP110_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP110_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP110_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP110_J_PLC_START());//PLC寮�濮�
@@ -64,6 +96,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP110_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +124,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP110_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP110_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP110宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP110_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP110_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP110_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +245,23 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP110_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120/impl/OP120ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120/impl/OP120ServerInterfaceImpl.java
index ed853d4..a28b770 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120/impl/OP120ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120/impl/OP120ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP120_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP120_F_HEART_BEAT(), "true");
+            GlobalVariable.OP120_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP120_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP120_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP120_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP120_J_PLC_START());//PLC寮�濮�
@@ -64,6 +96,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP120_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +124,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP120_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP120_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP120宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP120_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP120_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP120_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +245,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP120_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120B/impl/OP120BServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120B/impl/OP120BServerInterfaceImpl.java
index 1c7854f..25759bf 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120B/impl/OP120BServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP120B/impl/OP120BServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP120B_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP120B_F_HEART_BEAT(), "true");
+            GlobalVariable.OP120B_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP120B_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP120B_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP120B_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP120B_J_PLC_START());//PLC寮�濮�
@@ -64,6 +96,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP120B_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        //handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +124,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP120B_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP120B_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP120B宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP120B_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP120B_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP120B_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +245,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP120B_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130/impl/OP130ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130/impl/OP130ServerInterfaceImpl.java
index ded465f..9815413 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130/impl/OP130ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130/impl/OP130ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP130_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP130_F_HEART_BEAT(), "true");
+            GlobalVariable.OP130_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP130_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP130_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP130_F_HEART_BEAT) {
 
                 //PC璇诲伐鍗�
@@ -65,6 +97,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP130_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -92,6 +125,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP130_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP130_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP130宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP130_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP130_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP130_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -161,6 +249,24 @@
 
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP130_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130B/impl/OP130BServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130B/impl/OP130BServerInterfaceImpl.java
index eb3b8f1..9a00e21 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130B/impl/OP130BServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP130B/impl/OP130BServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP130B_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP130B_F_HEART_BEAT(), "true");
+            GlobalVariable.OP130B_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP130B_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP130B_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP130B_F_HEART_BEAT) {
 
                     //PC璇诲伐鍗�
@@ -65,6 +97,7 @@
                     if(isPLCFinish.equals("true")){
                         String isFinish = OPCUnit.read(opc.getOP130B_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                         if(isFinish.equals("false")){
+                           // handleMaterial();
                             handleInfo();
                             handleFinsh();
                         }
@@ -92,6 +125,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP130B_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP130B_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP130B宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP130B_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP130B_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP130B_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setProductionLine((remainingQuantity-1)+"");
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -159,6 +247,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP130B_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP140/impl/OP140ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP140/impl/OP140ServerInterfaceImpl.java
index 4dbc944..f07443a 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP140/impl/OP140ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP140/impl/OP140ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP140_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP140_F_HEART_BEAT(), "true");
+            GlobalVariable.OP140_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP140_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP140_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP140_F_HEART_BEAT) {
 
                 //PC璇诲伐鍗�
@@ -65,6 +97,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP140_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -92,6 +125,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP140_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP140_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP140宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP140_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP140_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP140_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -158,6 +246,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP140_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP150/impl/OP150ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP150/impl/OP150ServerInterfaceImpl.java
index 727f47d..b8dba82 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP150/impl/OP150ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP150/impl/OP150ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP150_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP150_F_HEART_BEAT(), "true");
+            GlobalVariable.OP150_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP150_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP150_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP150_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP150_J_PLC_START());//PLC寮�濮�
@@ -65,6 +97,7 @@
                     String isFinish = OPCUnit.read(opc.getOP150_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
                        /* handleInfo();*/
+                        handleMaterial();
                         handleFinsh();
                     }
                 }
@@ -91,6 +124,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP150_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP150_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP150宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP150_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP150_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP150_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +245,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP150_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP160/impl/OP160ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP160/impl/OP160ServerInterfaceImpl.java
index b9490b2..b6650e9 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP160/impl/OP160ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP160/impl/OP160ServerInterfaceImpl.java
@@ -8,6 +8,14 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -44,10 +52,34 @@
     private static String GROUP_NAME  = "OP160_P";//缁勫悕
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP160_F_HEART_BEAT(), "true");
+            GlobalVariable.OP160_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP160_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP160_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP160_F_HEART_BEAT) {
                 //PC璇诲伐鍗�
                 String isPLCStart = OPCUnit.read(opc.getOP160_J_PLC_START());//PLC寮�濮�
@@ -64,6 +96,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP160_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -91,6 +124,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP160_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP160_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP160宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP160_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP160_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP160_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -157,6 +245,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP160_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        if("false".equals(S_PRODUCT_STATE_CODE)){
+            ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+            productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+            productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+            ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+            List<ProductionOrderRecordsResult> list = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+            if(list.size()>0){
+                ProductionOrderRecordsResult productionOrderRecordsResult = list.get(0);
+                productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+                productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+                productionOrderRecordsService.update(productionOrderRecordsParam);
+            }
+        }
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP170/impl/OP170ServerInterfaceImpl.java b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP170/impl/OP170ServerInterfaceImpl.java
index 4b1340e..26114ce 100644
--- a/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP170/impl/OP170ServerInterfaceImpl.java
+++ b/guns-vip-main/src/main/java/cn/stylefeng/guns/plcserver/server/OP170/impl/OP170ServerInterfaceImpl.java
@@ -8,9 +8,17 @@
 import cn.stylefeng.guns.modular.cm.paramCollection.service.ParamCollectionService;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.model.params.PassingStationCollectionParam;
 import cn.stylefeng.guns.modular.cm.passingStationCollection.service.PassingStationCollectionService;
+import cn.stylefeng.guns.modular.dq.materialTraceability.model.params.MaterialTraceabilityParam;
+import cn.stylefeng.guns.modular.dq.materialTraceability.service.MaterialTraceabilityService;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.params.ProductionOrdeInfoParam;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.model.result.ProductionOrdeInfoResult;
 import cn.stylefeng.guns.modular.om.productionOrdeInfo.service.ProductionOrdeInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.params.ProductionOrderBatchInfoParam;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.model.result.ProductionOrderBatchInfoResult;
+import cn.stylefeng.guns.modular.om.productionOrderBatchInfo.service.ProductionOrderBatchInfoService;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.params.ProductionOrderRecordsParam;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.model.result.ProductionOrderRecordsResult;
+import cn.stylefeng.guns.modular.om.productionOrderRecords.service.ProductionOrderRecordsService;
 import cn.stylefeng.guns.plcserver.opc.GlobalVariable;
 import cn.stylefeng.guns.plcserver.opc.OPCComm;
 import cn.stylefeng.guns.plcserver.opc.unit.OPCUnit;
@@ -47,10 +55,34 @@
     private static String GROUP_NAME  = "OP170_P";//宸ヤ綅鍙�
     private static List list = null;
     private static Group group = null;
+
+    private int count = 0;
+
+    /**
+     * 璁剧疆蹇冭烦鏍囧織浣嶏紝淇濆瓨鍒板叏灞�鍙橀噺
+     */
+    public void setHeartbeat(String value) {
+        if ("false".equals(value)) {
+            OPCUnit.write(opc.getOP170_F_HEART_BEAT(), "true");
+            GlobalVariable.OP170_F_HEART_BEAT = true;
+            count = 0;
+        } else {
+            count++;
+        }
+        // 寰幆璇诲彇棰戠巼鏄細500ms涓�娆★紝濡傛灉瓒呰繃6娆★紝涔熷氨鏄�3s璁ゅ畾瓒呮椂
+        if (count > GlobalVariable.HEART_MAX_COUNT) {
+            GlobalVariable.OP170_F_HEART_BEAT = false;
+        }
+    }
+
     @Override
     public synchronized void monitor() {
         String ecpStr = "";//寮傚父璁板綍鏍囪
         try{
+
+            String isHeartBeat = OPCUnit.read(opc.getOP170_F_HEART_BEAT());
+            setHeartbeat(isHeartBeat);
+
             if(GlobalVariable.OP170_F_HEART_BEAT) {
 
                 //PC璇诲伐鍗�
@@ -68,6 +100,7 @@
                 if(isPLCFinish.equals("true")){
                     String isFinish = OPCUnit.read(opc.getOP170_J_PC_FINISH());//PC鎿嶄綔瀹屾垚
                     if(isFinish.equals("false")){
+                        handleMaterial();
                         handleInfo();
                         handleFinsh();
                     }
@@ -95,6 +128,61 @@
         S_SFC_CODE = OPCUnit.read(opc.getOP170_S_SFC_CODE());//鎬绘垚缂栫爜
         OPCUnit.write(opc.getOP170_J_PC_WRITE_ORDER(), "true"); //PC璇诲伐鍗曞畬鎴�
         logger.info("OP170宸ヤ綅,handleOrder PC澶勭悊瀹屾垚锛�");
+    }
+
+    public void handleMaterial() {
+        if("".equals(S_ORDER_CODE)){
+            IN_TIME = DateTool.getLocalTimeForDate();
+            S_ORDER_CODE = OPCUnit.read(opc.getOP170_S_ORDER_CODE());//宸ュ崟缂栧彿
+            S_PRODUCT_TYPE = OPCUnit.read(opc.getOP170_S_PRODUCT_CODE());//浜у搧缂栧彿
+            S_PRODUCT_CODE = GlobalVariable.PRODUCT_CODE_MAP.get(S_PRODUCT_TYPE);
+            S_SFC_CODE = OPCUnit.read(opc.getOP170_S_SFC_CODE());//鎬绘垚缂栫爜
+        }
+        //鏌ヨ鎵规涓婃枡淇℃伅
+        ProductionOrderBatchInfoParam productionOrderBatchInfoParam = new ProductionOrderBatchInfoParam();
+        productionOrderBatchInfoParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderBatchInfoParam.setLocationCode(LOCATION_CODE);
+        ProductionOrderBatchInfoService productionOrderBatchInfoService = opc.productionOrderBatchInfoService;
+        List<ProductionOrderBatchInfoResult> list1 = productionOrderBatchInfoService.findListBySpec(productionOrderBatchInfoParam);
+        for(int i=0;i<list1.size();i++){
+            ProductionOrderBatchInfoResult productionOrderBatchInfoResult = list1.get(i);
+
+            //鍒ゆ柇鏄惁鏈夎宸ヤ綅
+            String[] locationCodes = productionOrderBatchInfoResult.getLocationCode().split("/");
+            logger.info("褰撳墠宸ヤ綅锛�"+locationCodes.toString());
+            boolean isLocationCode = false;
+            if(locationCodes.length>0)
+            {
+                for (int j=0;j<locationCodes.length;j++){
+                    String location = locationCodes[j];
+                    if(location.equals(LOCATION_CODE)){
+                        isLocationCode = true;
+                    }
+                }
+            }
+
+            int remainingQuantity =  productionOrderBatchInfoResult.getResidueQuantity();//鍓╀綑鏁伴噺
+            if(remainingQuantity>0 && isLocationCode){
+                //鏂板鐗╂枡杩芥函
+                MaterialTraceabilityParam materialTraceabilityParam = new MaterialTraceabilityParam();
+                materialTraceabilityParam.setWorkOrderNo(S_ORDER_CODE);
+                materialTraceabilityParam.setProductCode(S_PRODUCT_CODE);
+                materialTraceabilityParam.setProductNo(S_SFC_CODE);
+                materialTraceabilityParam.setLineCode(PRODUCTION_LINE);
+                materialTraceabilityParam.setLocationCode(LOCATION_CODE);
+                materialTraceabilityParam.setAssemblyQty(1);
+                materialTraceabilityParam.setAssemblyTime(DateTool.getLocalTimeForDate());
+                materialTraceabilityParam.setMaterialCode(productionOrderBatchInfoResult.getMaterialCode());//鐗╂枡缂栫爜
+                materialTraceabilityParam.setMaterialBatchNo(productionOrderBatchInfoResult.getBatch());//鐗╂枡鎵规
+
+                MaterialTraceabilityService materialTraceabilityService = opc.materialTraceabilityService;
+                materialTraceabilityService.add(materialTraceabilityParam);
+                //鏇存柊鍓╀綑鏁伴噺
+                productionOrderBatchInfoParam.setId(productionOrderBatchInfoResult.getId());
+                productionOrderBatchInfoParam.setResidueQuantity(remainingQuantity-1);//鍓╀綑鏁伴噺
+                productionOrderBatchInfoService.update(productionOrderBatchInfoParam);
+            }
+        }
     }
 
     //PC璇诲弬鏁颁俊鎭�
@@ -161,6 +249,24 @@
         }
         //澶勭悊杩囩珯淇℃伅
         String S_PRODUCT_STATE_CODE = OPCUnit.read(opc.getOP170_S_PRODUCT_STATE_CODE());
+
+        //淇敼鎶ュ伐璁板綍
+        ProductionOrderRecordsParam productionOrderRecordsParam = new ProductionOrderRecordsParam();
+        productionOrderRecordsParam.setWorkOrderNo(S_ORDER_CODE);
+        productionOrderRecordsParam.setProductNo(S_SFC_CODE);
+        ProductionOrderRecordsService productionOrderRecordsService = opc.productionOrderRecordsService;
+
+        List<ProductionOrderRecordsResult> list2 = productionOrderRecordsService.findListBySpec(productionOrderRecordsParam);
+        if(list2.size()>0){
+            ProductionOrderRecordsResult productionOrderRecordsResult = list2.get(0);
+            productionOrderRecordsParam.setId(productionOrderRecordsResult.getId());
+            productionOrderRecordsParam.setWhetherPass(S_PRODUCT_STATE_CODE);
+            productionOrderRecordsParam.setEndTime(DateTool.getLocalTimeForDate());
+            productionOrderRecordsService.update(productionOrderRecordsParam);
+        }
+
+
+
         PassingStationCollectionParam param = new PassingStationCollectionParam();
         param.setWorkOrderNo(S_ORDER_CODE);
         param.setProductCode(S_PRODUCT_CODE);
diff --git a/guns-vip-main/src/main/resources/application-local.yml b/guns-vip-main/src/main/resources/application-local.yml
index 6305690..808ace9 100644
--- a/guns-vip-main/src/main/resources/application-local.yml
+++ b/guns-vip-main/src/main/resources/application-local.yml
@@ -21,12 +21,12 @@
   datasource:
                  driverClassName: net.sourceforge.jtds.jdbc.Driver
                  #    url: jdbc:jtds:sqlserver://120.48.135.247:1433;DatabaseName=festo_guns
-#                 url: jdbc:jtds:sqlserver://172.20.1.10:1433;DatabaseName=MideaMes
+                 url: jdbc:jtds:sqlserver://172.20.1.10:1433;DatabaseName=Jcdm019-Mes
 #                 url: jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=MideaMesT1
-                 url: jdbc:jtds:sqlserver://192.168.0.189:1433;DatabaseName=Jcdm019-Mes
+#                 url: jdbc:jtds:sqlserver://192.168.10.196:1433;DatabaseName=Jcdm019-Mes
                  username: sa
-#                 password: admin@123
-                 password: JCDM@2023
+                 password: admin@123
+#                 password: JCDM@2023
     # 杩炴帴姹犲ぇ灏忔牴鎹疄闄呮儏鍐佃皟鏁�
                  max-active: 100
                  max-pool-prepared-statement-per-connection-size: 100

--
Gitblit v1.9.3