hou 1 неделя назад
Родитель
Сommit
692f911a09

+ 2 - 0
src/com/mes/ui/ErrorMsg.java

@@ -55,6 +55,8 @@ public class ErrorMsg {
                 lmsg = "气密已达最大NG次数";
             }else if(processMsgRet.equalsIgnoreCase("AL")) {
                 lmsg = "该工件存在未处理的报警信息";
+            }else if(processMsgRet.equalsIgnoreCase("NS")) {
+                lmsg = "操作失败(NS),请重试";
             }
 
             MesClient.setMenuStatus(lmsg,-1);

+ 80 - 10
src/com/mes/ui/MesClient.java

@@ -82,6 +82,15 @@ public class MesClient extends JFrame {
     public static JButton f_scan_data_bt_2;
     public static JButton btnUnbindLb;
     public static boolean bindLbStatus = false;
+    /** 质量查询已发送,避免定时器连发 */
+    public static boolean qualityRequestSent = false;
+    /** 开工已发送,避免重复开工 */
+    public static boolean startWorkRequestSent = false;
+    /** 冷板绑定后需与拉铆枪 okQty 对齐基准 */
+    public static boolean rivetCountNeedSync = false;
+    /** 冷板绑定 NS 自动重试次数 */
+    public static int lbBindRetryCount = 0;
+    public static final int LB_BIND_RETRY_MAX = 2;
 
     public static String user20 = "";
 
@@ -564,6 +573,7 @@ public class MesClient extends JFrame {
 
     public static void clearLbBindUi() {
         bindLbStatus = false;
+        rivetCountNeedSync = false;
         if (product_sn_lb != null) {
             product_sn_lb.setText("");
         }
@@ -583,6 +593,10 @@ public class MesClient extends JFrame {
         check_quality_result = false;
         tjStatus = 0;
         manualSubmitFlag = false;
+        qualityRequestSent = false;
+        startWorkRequestSent = false;
+        rivetCountNeedSync = false;
+        lbBindRetryCount = 0;
         MesClient.finish_ok_bt.setEnabled(false);
         MesClient.finish_ng_bt.setEnabled(false);
         product_sn.setText("");
@@ -688,7 +702,10 @@ public class MesClient extends JFrame {
                         work_status_jqb = 1;
                     }
                 }else if (work_status_jqb == 1){
-                    // 已扫码,等待允许加工信号
+                    // 已扫码,等待允许加工信号(只发一次,等回包)
+                    if (qualityRequestSent) {
+                        return;
+                    }
                     String sn = product_sn.getText();
                     if (sn == null || sn.trim().isEmpty() || "".equals(sn)) {
                         setMenuStatus("读码结果为空", -1);
@@ -698,13 +715,18 @@ public class MesClient extends JFrame {
                     Boolean checkQualityResult = DataUtil.checkQuality(MesClient.nettyClient, barcode36,MesClient.user20);
                     if (!checkQualityResult){
                         setMenuStatus("消息发送失败,请重试",-1);
+                        qualityRequestSent = false;
+                    } else {
+                        qualityRequestSent = true;
                     }
                 }else if (work_status_jqb == 2){
-                    //上料完成信号
+                    //上料完成信号:仅写 PLC,不再重复开工(开工已由质量回包触发)
                     if (MesClient.s7PLC.readBoolean("DB32.0.3")){
-                        //允许上料信号
                         MesClient.s7PLC.writeBoolean("DB32.0.2",false);
-                        DataUtil.startWork(nettyClient,MesClient.product_sn.getText(),user20);
+                        if (work_status == 0 && !startWorkRequestSent) {
+                            startWorkRequestSent = true;
+                            DataUtil.startWork(nettyClient, MesClient.product_sn.getText(), user20);
+                        }
                     }
                 }else if (work_status_jqb == 3){
                     if (MesClient.s7PLC.readBoolean("DB32.0.4")){
@@ -799,30 +821,78 @@ public class MesClient extends JFrame {
     }
 
     public static void scanBarcodeLb() {
+        if (bindLbStatus) {
+            setMenuStatus("冷板已绑定,如需重绑请先解绑", 1);
+            return;
+        }
         product_sn_lb.setText("");
         String scanBarcode = JOptionPane.showInputDialog(null, "请扫冷板码");
         System.out.println("冷板码=" + scanBarcode);
         if (scanBarcode != null && !scanBarcode.equalsIgnoreCase("")) {
             getUser();
-            product_sn_lb.setText(scanBarcode);
+            product_sn_lb.setText(scanBarcode.trim());
             mesClientFrame.repaint();
 
             if (!tcp_connect_flag) {
                 setMenuStatus("设备未连接Mes服务器", 1);
+                if (f_scan_data_bt_2 != null) {
+                    f_scan_data_bt_2.setEnabled(true);
+                }
+                return;
+            }
+
+            String productSn = product_sn.getText();
+            if ((productSn == null || productSn.trim().isEmpty()) && curSn != null && !curSn.trim().isEmpty()) {
+                productSn = curSn;
+                product_sn.setText(curSn);
+            }
+            if (productSn == null || productSn.trim().isEmpty()) {
+                setMenuStatus("工件码为空,请先扫工件码", 1);
+                if (f_scan_data_bt_2 != null) {
+                    f_scan_data_bt_2.setEnabled(true);
+                }
                 return;
             }
 
-            String warehouseSn = getBarcode(product_sn_lb.getText());
-            String sn = getBarcode(product_sn.getText());
-            Boolean retObj = DataUtil.bindWarehouse(nettyClient, sn, warehouseSn, user20, "400006");
-            if (!retObj) {
-                setMenuStatus("绑定失败!", 1);
+            if (f_scan_data_bt_2 != null) {
+                f_scan_data_bt_2.setEnabled(false);
             }
+            lbBindRetryCount = 0;
+            setMenuStatus("冷板绑定中...", 0);
+            sendColdPlateBind();
         } else {
             setMenuStatus("冷板码为空,请重新扫码", 1);
         }
     }
 
+    /** 发送冷板绑定(支持 NS 自动重试复用) */
+    public static void sendColdPlateBind() {
+        String lb = product_sn_lb != null ? product_sn_lb.getText() : "";
+        String productSn = product_sn != null ? product_sn.getText() : "";
+        if ((productSn == null || productSn.trim().isEmpty()) && curSn != null && !curSn.trim().isEmpty()) {
+            productSn = curSn;
+        }
+        if (lb == null || lb.trim().isEmpty() || productSn == null || productSn.trim().isEmpty()) {
+            setMenuStatus("冷板绑定参数为空", 1);
+            if (f_scan_data_bt_2 != null && work_status == 1 && !bindLbStatus) {
+                f_scan_data_bt_2.setEnabled(true);
+            }
+            return;
+        }
+        getUser();
+        String warehouseSn = getBarcode(lb.trim());
+        String sn = getBarcode(productSn.trim());
+        log.info("发送冷板绑定 sn={}, lb={}, retry={}", sn.trim(), lb.trim(), lbBindRetryCount);
+        Boolean retObj = DataUtil.bindWarehouse(nettyClient, sn, warehouseSn, user20, "400006");
+        if (!retObj) {
+            setMenuStatus("绑定失败!", 1);
+            lbBindRetryCount = 0;
+            if (f_scan_data_bt_2 != null) {
+                f_scan_data_bt_2.setEnabled(true);
+            }
+        }
+    }
+
     public static void logoff() {
         welcomeWin.setVisible(true);
         mesClientFrame.setVisible(false);

+ 48 - 5
src/com/mes/ui/MesRevice.java

@@ -25,6 +25,12 @@ public class MesRevice {
                 || ret.equalsIgnoreCase("UDF");
     }
 
+    private static void enableColdPlateScanIfNeeded() {
+        if (MesClient.work_status == 1 && !MesClient.bindLbStatus && MesClient.f_scan_data_bt_2 != null) {
+            MesClient.f_scan_data_bt_2.setEnabled(true);
+        }
+    }
+
     // 质量查询
     public static void checkQualityRevice(String processMsgRet, String mes_msg) {
         try {
@@ -37,14 +43,16 @@ public class MesRevice {
                 MesClient.check_quality_result = true;
                 MesClient.setMenuStatus("该工件可以加工", 0);
 
-                if (MesClient.work_status == 0) {
+                if (MesClient.work_status == 0 && !MesClient.startWorkRequestSent) {
                     String barcode36 = MesClient.getBarcode(MesClient.product_sn.getText());
                     MesClient.getUser();
+                    MesClient.startWorkRequestSent = true;
                     log.info("质量通过,发送开工 sn={}", barcode36.trim());
                     DataUtil.startWork(MesClient.nettyClient, barcode36, MesClient.user20);
                 }
             } else {
                 MesClient.check_quality_result = false;
+                MesClient.qualityRequestSent = false;
                 log.warn("质量查询不可加工 sn={}, ret={}", sn, processMsgRet);
                 ErrorMsg.setErrorMsg(mes_msg);
             }
@@ -70,14 +78,24 @@ public class MesRevice {
             String sn = ProtocolParam.getSn(mes_msg).trim();
             log.info("开工回包 sn={}, ret={}", sn, processMsgRet);
             if (processMsgRet.equalsIgnoreCase("OK")) {
+                // 已开工则忽略重复回包,避免把冷板绑定 UI 刷回「请扫描冷板码」
+                if (MesClient.work_status == 1) {
+                    log.info("忽略重复开工回包 sn={}, jqb={}, bindLb={}",
+                            sn, MesClient.work_status_jqb, MesClient.bindLbStatus);
+                    return;
+                }
                 MesClient.work_status = 1;
                 MesClient.f_scan_data_bt_1.setEnabled(false);
                 MesClient.tjStatus = 0;
                 MesClient.work_status_jqb = 2;
+                MesClient.startWorkRequestSent = true;
 
-                MesClient.f_scan_data_bt_2.setEnabled(true);
-                MesClient.setMenuStatus("请扫描冷板码", 0);
+                if (!MesClient.bindLbStatus) {
+                    MesClient.f_scan_data_bt_2.setEnabled(true);
+                    MesClient.setMenuStatus("请扫描冷板码", 0);
+                }
             } else {
+                MesClient.startWorkRequestSent = false;
                 log.warn("开工失败 sn={}, ret={}", sn, processMsgRet);
             }
         } catch (Exception e) {
@@ -90,25 +108,50 @@ public class MesRevice {
         try {
             String craft = ProtocolParam.getCraft(mes_msg);
             String sn = ProtocolParam.getSn(mes_msg).trim();
-            log.info("绑定回包 sn={}, craft={}, ret={}", sn, craft, processMsgRet);
+            log.info("绑定回包 sn={}, craft={}, ret={}, retry={}",
+                    sn, craft, processMsgRet, MesClient.lbBindRetryCount);
             if (processMsgRet.equalsIgnoreCase("OK")) {
                 if (isColdPlateCraft(craft)) {
+                    MesClient.lbBindRetryCount = 0;
                     MesClient.setMenuStatus("绑定成功!", 0);
                     MesClient.btnUnbindLb.setEnabled(true);
                     MesClient.bindLbStatus = true;
                     MesClient.f_scan_data_bt_2.setEnabled(false);
 
-                    MesClient.sortA = 0;
+                    // 不强制 sortA=0:下一轮拉铆采集时与枪 okQty 对齐,避免二次绑定后计数卡死
+                    MesClient.rivetCountNeedSync = true;
                     MesClient.aFinish = 0;
                     MesClient.param2.setText("0");
                     MesClient.work_status_jqb = 3;
                     log.info("冷板绑定成功 sn={}, lb={}", MesClient.curSn, MesClient.product_sn_lb.getText());
                 }
             } else if (isColdPlateCraft(craft) && processMsgRet.equalsIgnoreCase("PZ")) {
+                MesClient.lbBindRetryCount = 0;
                 log.warn("冷板绑定失败,需先上传密封圈照片 sn={}", sn);
                 MesClient.setMenuStatus("请先上传密封圈照片,再绑定冷板!", -1);
+                enableColdPlateScanIfNeeded();
+            } else if (isColdPlateCraft(craft) && processMsgRet != null
+                    && processMsgRet.trim().equalsIgnoreCase("NS")) {
+                // NS=服务端绑定失败(常见于报文拆包丢参数/记录未就绪),自动重试
+                if (MesClient.lbBindRetryCount < MesClient.LB_BIND_RETRY_MAX) {
+                    MesClient.lbBindRetryCount++;
+                    final int retryNo = MesClient.lbBindRetryCount;
+                    log.warn("冷板绑定返回 NS,自动重试 {}/{} sn={}", retryNo, MesClient.LB_BIND_RETRY_MAX, sn);
+                    MesClient.setMenuStatus("冷板绑定未就绪,自动重试(" + retryNo + ")...", 0);
+                    javax.swing.Timer retryTimer = new javax.swing.Timer(500, e -> MesClient.sendColdPlateBind());
+                    retryTimer.setRepeats(false);
+                    retryTimer.start();
+                } else {
+                    MesClient.lbBindRetryCount = 0;
+                    log.warn("冷板绑定失败,NS 重试耗尽 sn={}", sn);
+                    MesClient.setMenuStatus("冷板绑定失败:NS,请再扫一次", -1);
+                    enableColdPlateScanIfNeeded();
+                }
             } else if (isColdPlateCraft(craft)) {
+                MesClient.lbBindRetryCount = 0;
                 log.warn("冷板绑定失败 sn={}, ret={}", sn, processMsgRet);
+                MesClient.setMenuStatus("冷板绑定失败:" + processMsgRet, -1);
+                enableColdPlateScanIfNeeded();
             }
         } catch (Exception e) {
             log.error("绑定回包处理异常", e);

+ 17 - 1
src/com/mes/ui/PlcUtil.java

@@ -55,7 +55,16 @@ public class PlcUtil {
 
             MesClient.param2.setText(String.valueOf(MesClient.sortA));
             int currentOk = mesData.okQty;
-            if (currentOk == MesClient.sortA + 1){
+
+            // 绑定后/枪计数回落时先对齐基准,避免 sortA 与 okQty 脱节导致页面一直为 0
+            if (MesClient.rivetCountNeedSync || currentOk < MesClient.sortA) {
+                MesClient.sortA = Math.max(0, currentOk);
+                MesClient.aFinish = MesClient.sortA;
+                MesClient.param2.setText(String.valueOf(MesClient.sortA));
+                MesClient.rivetCountNeedSync = false;
+                log.info("拉铆计数基准同步 okQty={}, sortA={}, sn={}",
+                        currentOk, MesClient.sortA, MesClient.curSn);
+            } else if (currentOk == MesClient.sortA + 1){
                 // 更新计数
                 MesClient.sortA = currentOk;
                 MesClient.aFinish = currentOk;
@@ -86,6 +95,13 @@ public class PlcUtil {
                             MesClient.user_menu.getText()
                     );
                 }
+            } else if (currentOk > MesClient.sortA + 1) {
+                // 漏采时追赶显示,避免页面长期卡住
+                log.warn("拉铆计数跳跃追赶 okQty={}, sortA={}, sn={}",
+                        currentOk, MesClient.sortA, MesClient.curSn);
+                MesClient.sortA = currentOk;
+                MesClient.aFinish = currentOk;
+                MesClient.param2.setText(String.valueOf(currentOk));
             }
 
             // 不覆盖已扫工件码:拉铆枪 PLC 条码地址可能与开工/绑定 SN 不一致,覆盖后会导致 MES 结果提交失败

+ 2 - 0
src/com/mes/util/ErrorMsg.java

@@ -50,6 +50,8 @@ public class ErrorMsg {
                 lmsg = "气密已达最大NG次数";
             }else if(processMsgRet.equalsIgnoreCase("AL")) {
                 lmsg = "该工件存在未处理的报警信息";
+            }else if(processMsgRet.equalsIgnoreCase("NS")) {
+                lmsg = "操作失败(NS),请重试";
             }
         }catch (Exception e){ }
         return lmsg;