hou преди 1 седмица
ревизия
3062d4426f
променени са 100 файла, в които са добавени 4476 реда и са изтрити 0 реда
  1. 24 0
      .classpath
  2. 7 0
      .gitignore
  3. 28 0
      .project
  4. 2 0
      image/.gitignore
  5. BIN
      image/background.png
  6. BIN
      image/bg/a_side.png
  7. BIN
      image/bg/b_side.png
  8. BIN
      image/bg/bar_add.png
  9. BIN
      image/bg/bar_bookmark.png
  10. BIN
      image/bg/bar_cmd_go.png
  11. BIN
      image/bg/bar_edit.png
  12. BIN
      image/bg/bar_pause.png
  13. BIN
      image/bg/bar_sampling.png
  14. BIN
      image/bg/bar_setting.png
  15. BIN
      image/bg/bar_stop.png
  16. BIN
      image/bg/close_bt.png
  17. BIN
      image/bg/company_setting_logo.png
  18. BIN
      image/bg/delete.png
  19. BIN
      image/bg/department_setting_logo.png
  20. BIN
      image/bg/download.png
  21. BIN
      image/bg/equipment_setting_logo.png
  22. BIN
      image/bg/gj_001_1_20.png
  23. BIN
      image/bg/gj_001_21_40.png
  24. BIN
      image/bg/gj_001_41_60.png
  25. BIN
      image/bg/green_dot.png
  26. BIN
      image/bg/grey_dot.png
  27. BIN
      image/bg/icon.png
  28. BIN
      image/bg/inductance_logo.png
  29. BIN
      image/bg/insulation_logo.png
  30. BIN
      image/bg/login.png
  31. BIN
      image/bg/logo.png
  32. BIN
      image/bg/logoff.png
  33. BIN
      image/bg/menu_data_analysis.png
  34. BIN
      image/bg/menu_data_preprocess.png
  35. BIN
      image/bg/menu_file.png
  36. BIN
      image/bg/menu_setting.png
  37. BIN
      image/bg/min_bt.png
  38. BIN
      image/bg/ng_bg.png
  39. BIN
      image/bg/ok_bg.png
  40. BIN
      image/bg/open_file.png
  41. BIN
      image/bg/refresh.png
  42. BIN
      image/bg/reset_logo.png
  43. BIN
      image/bg/resistance_logo.png
  44. BIN
      image/bg/save_bg.png
  45. BIN
      image/bg/scan_barcode.png
  46. BIN
      image/bg/tree_folder_icon.png
  47. BIN
      image/bg/tree_leaf_icon.png
  48. BIN
      image/bg/user.png
  49. BIN
      image/bg/vertical_line.png
  50. BIN
      image/bg/zoom_in.png
  51. BIN
      image/bg/zoom_out.png
  52. BIN
      image/close_bt.png
  53. 0 0
      image/cmd.txt
  54. BIN
      image/icon.ico
  55. BIN
      image/info_bt.png
  56. BIN
      image/min_bt.png
  57. 3 0
      lib/META-INF/MANIFEST.MF
  58. BIN
      lib/commons-codec-1.15.jar
  59. BIN
      lib/fastjson2-2.0.16.jar
  60. BIN
      lib/gson-2.10.jar
  61. BIN
      lib/iot-communication-1.4.4.jar
  62. BIN
      lib/jfreechart-1.5.4.jar
  63. BIN
      lib/jshortcut-0.4-oberzalek.jar
  64. BIN
      lib/kotlin-stdlib-1.8.10.jar
  65. BIN
      lib/netty-all-4.1.48.Final.jar
  66. BIN
      lib/okhttp-4.10.0.jar
  67. BIN
      lib/okio-jvm-3.3.0.jar
  68. BIN
      lib/s7connector-2.1.jar
  69. BIN
      lib/slf4j-api-2.0.6.jar
  70. BIN
      lib/sqlite-jdbc-3.36.0.3.jar
  71. 24 0
      result
  72. 10 0
      src/com/mes/component/CallFromJs.java
  73. 22 0
      src/com/mes/component/ConfigPanel.java
  74. 57 0
      src/com/mes/component/MesRadio.java
  75. 44 0
      src/com/mes/component/MesWebView.java
  76. 30 0
      src/com/mes/component/MyDialog.java
  77. 90 0
      src/com/mes/netty/MesMsgUtils.java
  78. 73 0
      src/com/mes/netty/ProtocolParam.java
  79. 168 0
      src/com/mes/netty/XDecoder.java
  80. 197 0
      src/com/mes/test/YgslConnectionTest.java
  81. 484 0
      src/com/mes/test/YgslUtilTest.java
  82. 58 0
      src/com/mes/ui/BindMaterialResp.java
  83. 15 0
      src/com/mes/ui/CenterRenderer.java
  84. 239 0
      src/com/mes/ui/DataUtil.java
  85. 214 0
      src/com/mes/ui/LoginFarme.java
  86. 1377 0
      src/com/mes/ui/MesClient.java
  87. 13 0
      src/com/mes/ui/MesRevice.java
  88. 69 0
      src/com/mes/ui/OprnoUtil.java
  89. 49 0
      src/com/mes/ui/QmData.java
  90. 43 0
      src/com/mes/ui/TableCellEditorButton.java
  91. 14 0
      src/com/mes/ui/TableCellRendererButton.java
  92. 67 0
      src/com/mes/ui/Test.java
  93. 184 0
      src/com/mes/ui/YgslResp.java
  94. 207 0
      src/com/mes/ui/YgslUtil.java
  95. 206 0
      src/com/mes/ui/YgslUtil2.java
  96. 207 0
      src/com/mes/ui/YgslUtil3.java
  97. 202 0
      src/com/mes/ui/YgslUtil4.java
  98. 15 0
      src/com/mes/util/Base64Utils.java
  99. 34 0
      src/com/mes/util/DateLocalUtils.java
  100. 0 0
      src/com/mes/util/ErrorMsg.java

+ 24 - 0
.classpath

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="module" value="true"/>
+		</attributes>
+	</classpathentry>
+    <classpathentry kind="src" path="image"/>
+	<classpathentry excluding="resources/" kind="src" path="src"/>
+	<classpathentry kind="src" path="src/resources"/>
+	<classpathentry kind="output" path="bin"/>
+	<classpathentry kind="lib" path="lib/s7connector-2.1.jar"/>
+	<classpathentry kind="lib" path="lib/slf4j-api-2.0.6.jar"/>
+	<classpathentry kind="lib" path="lib/okhttp-4.10.0.jar"/>
+	<classpathentry kind="lib" path="lib/kotlin-stdlib-1.8.10.jar"/>
+	<classpathentry kind="lib" path="lib/okio-jvm-3.3.0.jar"/>
+	<classpathentry kind="lib" path="lib/gson-2.10.jar"/>
+	<classpathentry kind="lib" path="lib/jfreechart-1.5.4.jar"/>
+	<classpathentry kind="lib" path="lib/jshortcut-0.4-oberzalek.jar"/>
+	<classpathentry kind="lib" path="lib/netty-all-4.1.48.Final.jar"/>
+	<classpathentry kind="lib" path="lib/sqlite-jdbc-3.36.0.3.jar"/>
+	<classpathentry kind="lib" path="lib/commons-codec-1.15.jar"/>
+	<classpathentry kind="lib" path="lib/fastjson2-2.0.16.jar"/>
+</classpath>

+ 7 - 0
.gitignore

@@ -0,0 +1,7 @@
+.idea
+.settings
+classes
+bin
+out
+*.db
+*.iml

+ 28 - 0
.project

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>MesYgsl</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+	<filteredResources>
+		<filter>
+			<id>1767577223658</id>
+			<name></name>
+			<type>30</type>
+			<matcher>
+				<id>org.eclipse.core.resources.regexFilterMatcher</id>
+				<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
+			</matcher>
+		</filter>
+	</filteredResources>
+</projectDescription>

+ 2 - 0
image/.gitignore

@@ -0,0 +1,2 @@
+META-INF
+_system~.ini

BIN
image/background.png


BIN
image/bg/a_side.png


BIN
image/bg/b_side.png


BIN
image/bg/bar_add.png


BIN
image/bg/bar_bookmark.png


BIN
image/bg/bar_cmd_go.png


BIN
image/bg/bar_edit.png


BIN
image/bg/bar_pause.png


BIN
image/bg/bar_sampling.png


BIN
image/bg/bar_setting.png


BIN
image/bg/bar_stop.png


BIN
image/bg/close_bt.png


BIN
image/bg/company_setting_logo.png


BIN
image/bg/delete.png


BIN
image/bg/department_setting_logo.png


BIN
image/bg/download.png


BIN
image/bg/equipment_setting_logo.png


BIN
image/bg/gj_001_1_20.png


BIN
image/bg/gj_001_21_40.png


BIN
image/bg/gj_001_41_60.png


BIN
image/bg/green_dot.png


BIN
image/bg/grey_dot.png


BIN
image/bg/icon.png


BIN
image/bg/inductance_logo.png


BIN
image/bg/insulation_logo.png


BIN
image/bg/login.png


BIN
image/bg/logo.png


BIN
image/bg/logoff.png


BIN
image/bg/menu_data_analysis.png


BIN
image/bg/menu_data_preprocess.png


BIN
image/bg/menu_file.png


BIN
image/bg/menu_setting.png


BIN
image/bg/min_bt.png


BIN
image/bg/ng_bg.png


BIN
image/bg/ok_bg.png


BIN
image/bg/open_file.png


BIN
image/bg/refresh.png


BIN
image/bg/reset_logo.png


BIN
image/bg/resistance_logo.png


BIN
image/bg/save_bg.png


BIN
image/bg/scan_barcode.png


BIN
image/bg/tree_folder_icon.png


BIN
image/bg/tree_leaf_icon.png


BIN
image/bg/user.png


BIN
image/bg/vertical_line.png


BIN
image/bg/zoom_in.png


BIN
image/bg/zoom_out.png


BIN
image/close_bt.png


+ 0 - 0
image/cmd.txt


BIN
image/icon.ico


BIN
image/info_bt.png


BIN
image/min_bt.png


+ 3 - 0
lib/META-INF/MANIFEST.MF

@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.mes.ui.MesClient
+

BIN
lib/commons-codec-1.15.jar


BIN
lib/fastjson2-2.0.16.jar


BIN
lib/gson-2.10.jar


BIN
lib/iot-communication-1.4.4.jar


BIN
lib/jfreechart-1.5.4.jar


BIN
lib/jshortcut-0.4-oberzalek.jar


BIN
lib/kotlin-stdlib-1.8.10.jar


BIN
lib/netty-all-4.1.48.Final.jar


BIN
lib/okhttp-4.10.0.jar


BIN
lib/okio-jvm-3.3.0.jar


BIN
lib/s7connector-2.1.jar


BIN
lib/slf4j-api-2.0.6.jar


BIN
lib/sqlite-jdbc-3.36.0.3.jar


+ 24 - 0
result

@@ -0,0 +1,24 @@
+023100610010
+010000
+0200
+03INSIGHTqcx
+04
+0501
+06001
+070001
+080001
+091
+101
+111
+12000000
+13000100
+14000000
+15000003
+1600324
+1700396
+1800360
+1900362
+202024-05-19:04:10:31
+212024-05-08:04:18:14
+221
+230000003081

+ 10 - 0
src/com/mes/component/CallFromJs.java

@@ -0,0 +1,10 @@
+package com.mes.component;
+
+import com.mes.ui.MesClient;
+
+public class CallFromJs {
+    public String callFromJs(String info){
+        System.out.print("ss:"+info);
+        return MesClient.sessionid+":java:" + info;
+    }
+}

+ 22 - 0
src/com/mes/component/ConfigPanel.java

@@ -0,0 +1,22 @@
+package com.mes.component;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.*;
+
+public class ConfigPanel extends JPanel {
+
+    private static final Logger log = LoggerFactory.getLogger(ConfigPanel.class);
+
+    /**
+     * 创建一个配置面板
+     */
+    public ConfigPanel() {
+
+    }
+
+
+
+
+}

+ 57 - 0
src/com/mes/component/MesRadio.java

@@ -0,0 +1,57 @@
+package com.mes.component;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class MesRadio extends JPanel {
+
+    private String result = "";
+    private Integer i = 0;
+
+    public MesRadio(String[] radioTitles,String[] radioVals){
+        this.setLayout(new FlowLayout());
+        ButtonGroup group = new ButtonGroup();
+        i = 0;
+        for (String title:radioTitles){
+            JRadioButton radioButton = new JRadioButton(title);
+            radioButton.setFont(new Font("微软雅黑", Font.PLAIN, 28));
+
+            String val = radioVals[i];
+            radioButton.setName(val);
+
+            this.add(radioButton);
+            group.add(radioButton);
+
+            radioButton.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    result = val;
+                    System.out.println("选择:"+result);
+                }
+            });
+            i++;
+        }
+    }
+
+    public void setResult(String ret){
+        this.result = "";
+        Component[] components = this.getComponents();
+        for (Component jRadioButton:components){
+            if(jRadioButton instanceof JRadioButton){
+                JRadioButton jRadioButtonParam = (JRadioButton)jRadioButton;
+                if(ret.equals(jRadioButtonParam.getName())){
+                    jRadioButtonParam.setSelected(true);
+                    this.result = jRadioButtonParam.getName();
+                }else{
+                    jRadioButtonParam.setSelected(false);
+                }
+            }
+        }
+    }
+
+    public String getResult(){
+        return this.result;
+    }
+}

+ 44 - 0
src/com/mes/component/MesWebView.java

@@ -0,0 +1,44 @@
+package com.mes.component;
+
+import javafx.application.Platform;
+import javafx.beans.value.ObservableValue;
+import javafx.concurrent.Worker;
+import javafx.embed.swing.JFXPanel;
+import javafx.scene.Scene;
+import javafx.scene.web.WebEngine;
+import javafx.scene.web.WebView;
+import netscape.javascript.JSObject;
+
+import java.util.Date;
+
+public class MesWebView extends JFXPanel {
+
+    public static WebEngine engine = null;
+
+    public MesWebView(String url){
+
+        Platform.runLater(() -> {
+            WebView webView = new WebView();
+            setScene(new Scene(webView));
+            Date date = new Date();
+//            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesQuality/check?__sid="+sessionid+"&oprno="+mes_gw+"&t="+date.getTime();
+            System.out.print(url);
+            engine = webView.getEngine();
+            CallFromJs bridge = new CallFromJs();
+            engine.getLoadWorker().stateProperty().addListener(
+                    (ObservableValue<? extends Worker.State> ov, Worker.State oldState, Worker.State newState) -> {
+                        if (newState == Worker.State.SUCCEEDED) {
+                            JSObject window = (JSObject) engine.executeScript("window");
+                            window.setMember("apps", bridge);
+                            window.setMember("sout", System.out);
+                        }
+                    }
+            );
+            engine.load(url);
+        });
+    }
+
+    public void reloadWeb(){
+        engine.reload();
+    }
+}

+ 30 - 0
src/com/mes/component/MyDialog.java

@@ -0,0 +1,30 @@
+package com.mes.component;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class MyDialog extends JDialog {
+
+    public MyDialog(Frame owner, String title, String msg){
+        super(owner, title);
+        init(msg);
+    }
+
+    private void init(String msg){
+        Container container = this.getContentPane();
+        container.setLayout(null);
+        container.setBackground(Color.BLACK);
+        this.setSize(800,220);
+        this.setLocationRelativeTo(null);
+
+        JLabel tslabel = new JLabel(msg);
+        tslabel.setHorizontalAlignment(SwingConstants.CENTER);
+        tslabel.setForeground(Color.RED);
+        tslabel.setFont(new Font("微软雅黑", Font.PLAIN,48));
+        tslabel.setBounds(0,30,800,100);
+
+        container.add(tslabel);
+        this.setModal(true);
+        this.setVisible(true);
+    }
+}

+ 90 - 0
src/com/mes/netty/MesMsgUtils.java

@@ -0,0 +1,90 @@
+package com.mes.netty;
+
+public class MesMsgUtils {
+
+    public static int SYNR_LEN = 46;
+    public static int AXTW_LEN = 46;
+    public static int ACLW_LEN = 46;
+    public static int MCJW_LEN = 96;
+    public static int AQDW_LEN = 96;
+    public static int MBDW_LEN = 96;
+    public static int MJBW_LEN = 96;
+    public static int MQDW_LEN = 96;
+    public static int MKSW_LEN = 96;
+    public static int MSBW_LEN = 96;
+    public static int MCSW_LEN = 96;
+    public static int AQRW_LEN = 96;
+
+    public static String MSG_TYPE[] = {
+        "SYNR",
+        "AXTW",
+        "ACLW",
+        "MCJW",
+        "AQDW",
+        "MBDW",
+        "MJBW",
+        "MQDW",
+        "MKSW",
+        "MSBW",
+        "MCSW",
+        "AQRW",
+    };
+
+    public static int isMsgContentOK(String msg, String msg_type) {
+        //ret=0OK,1 空内容,2 长度不符
+        int ret = 0;
+        if(msg==null||msg.equalsIgnoreCase("")) {
+            ret = 1;
+            return ret;
+        }
+
+        int len = msg.length();
+        //System.out.println("len="+len);
+        switch(msg_type) {
+            case "SYNR":
+            case "AXTW":
+            case "ACLW":
+                if(len==SYNR_LEN) {
+                    ret = 0;
+                }else {
+                    ret = 2;
+                }
+                break;
+            default:
+                if(len==AQDW_LEN) {
+                    ret = 0;
+                }else {
+                    ret = 2;
+                }
+                break;
+        }
+        return ret;
+    }
+
+    // 判断报文类型是否在清单里
+    public static boolean isMsgTypeOk(String msg_type) {
+        for (String str : MSG_TYPE) {
+            if (str.equals(msg_type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // 处理报文数据
+    public static String processMsg(String msg, String msg_type) {
+        String processMsgRet = "";
+        if(msg_type.equalsIgnoreCase("SYNR")) {
+
+        }else if(msg_type.equalsIgnoreCase("AXTW")) {
+
+        }else if(msg_type.equalsIgnoreCase("ACLW")) {
+
+        }else{
+            processMsgRet = ProtocolParam.getResult(msg);
+        }
+        return processMsgRet;
+    }
+
+
+}

+ 73 - 0
src/com/mes/netty/ProtocolParam.java

@@ -0,0 +1,73 @@
+package com.mes.netty;
+
+
+// 固定格式报文各参数获取方法
+public class ProtocolParam {
+    // bbbbfffffARWAQDWGWOP100 GY100000ID151245P00000106200123062900001      RSOKDA2023-09-07ZT10:16:58
+    public static Integer fixedLength = 96; // 固定长度
+
+    // 获取消息类型  所有报文都可使用
+    public static String getMsgType(String msg){
+        System.out.print(msg);
+        if(msg.length() < 16){
+            return "";
+        }
+        return msg.substring(12,16);
+    }
+
+    // 获取工位号
+    public static String getOprno(String msg){
+        if(msg.length() < 24){
+            return "";
+        }
+        return msg.substring(18,24);
+    }
+
+    // 获取工艺号
+    public static String getCraft(String msg){
+        if(msg.length() < 32){
+            return "";
+        }
+        return msg.substring(26,32);
+    }
+
+    // 获取镭雕码或设备报警故障代码
+    public static String getSn(String msg){
+        if(msg.length() < 70){
+            return "";
+        }
+        return msg.substring(34,70);
+    }
+
+    public static String getLx(String msg){
+        if(msg.length() < 72){
+            return "";
+        }
+        return msg.substring(70,72);
+    }
+
+    // 获取结果
+    public static String getResult(String msg){
+        if(msg.length() < 74){
+            return "";
+        }
+        return msg.substring(72,74);
+    }
+
+    // 获取日期
+    public static String getDay(String msg){
+        if(msg.length() < 86){
+            return "";
+        }
+        return msg.substring(76,86);
+    }
+
+    // 获取时间
+    public static String getTime(String msg){
+        if(msg.length() < 96){
+            return "";
+        }
+        return msg.substring(88,96);
+    }
+
+}

+ 168 - 0
src/com/mes/netty/XDecoder.java

@@ -0,0 +1,168 @@
+package com.mes.netty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+
+import java.util.List;
+
+public class XDecoder extends ByteToMessageDecoder {
+    static final int PACKET_SIZE = 46; // 最短包长度
+    static final int PACKET_MAX_SIZE = 1000; // 最长包长度
+
+    // 用来临时保留没有处理过的请求报文
+    ByteBuf tempMsg = Unpooled.buffer();
+
+    /**
+     * @param ctx
+     * @param in 请求的数据
+     * @param out 将粘在一起的报文拆分后的结果保留起来
+     * @throws Exception
+     */
+    @Override
+    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+        System.out.println(Thread.currentThread() + "收到了一次数据包,长度是:" + in.readableBytes());
+        String content = hexStringToAscii(ByteBufUtil.hexDump(in));
+        System.out.println("接收包内容:" + hexStringToAscii(ByteBufUtil.hexDump(in)));
+
+        // 合并报文
+        ByteBuf message = null;
+        int tmpMsgSize = tempMsg.readableBytes();
+        // 如果暂存有上一次余下的请求报文,则合并
+        if (tmpMsgSize > 0) {
+            message = Unpooled.buffer();
+            message.writeBytes(tempMsg);
+            message.writeBytes(in);
+            System.out.println("合并:上一数据包余下的长度为:" + tmpMsgSize + ",合并后长度为:" + message.readableBytes());
+            System.out.println("合并后包内容:" + hexStringToAscii(ByteBufUtil.hexDump(message)));
+        } else {
+            message = in;
+        }
+
+//        System.out.println(Thread.currentThread() + "收到了一次数据包,长度是:" + message.readableBytes());
+        int size = 0;
+        String split = "bbbbfffffARW";
+
+        while (true){
+            size = message.readableBytes();
+            if(size >= PACKET_SIZE){
+                String retType = "NG:";
+                int qcsize = 0;
+                String str = hexStringToAscii(ByteBufUtil.hexDump(message));
+                String[] lists = str.split(split);
+
+                if(lists.length == 1 && size > PACKET_MAX_SIZE){ // 大于最大包长度
+                    byte[] request = new byte[size - PACKET_MAX_SIZE];
+                    // 每次从总的消息中读取n个字节的数据
+                    message.readBytes(request);
+                    // 将拆分后的结果放入out列表中,交由后面的业务逻辑去处理
+                    out.add(retType+hexStringToAscii(ByteBufUtil.hexDump(Unpooled.copiedBuffer(request))));
+                    break;
+                }
+
+                if(lists[0].length() > 0){
+                    byte[] request = new byte[lists[0].length()];
+                    // 每次从总的消息中读取n个字节的数据
+                    message.readBytes(request);
+                    // 将拆分后的结果放入out列表中,交由后面的业务逻辑去处理
+                    out.add(retType+hexStringToAscii(ByteBufUtil.hexDump(Unpooled.copiedBuffer(request))));
+                }else{
+                    if(lists.length > 1){
+                        String ss = lists[1];
+                        if(ss.length() <= 4){
+                            qcsize += ss.length();
+                        }else{
+                            String msgType = ProtocolParam.getMsgType(split+ss);
+                            if(!MesMsgUtils.isMsgTypeOk(msgType)){
+                                qcsize += split.length() + ss.length();
+                            }else{
+                                Integer ppsize = checkResultSize(ss,msgType,split);
+                                if(ppsize > 0){
+                                    qcsize = ppsize;
+                                    retType = "OK:";
+                                }else{
+                                    qcsize += split.length() + ss.length();
+                                }
+                            }
+                        }
+                    }
+                }
+
+
+                if(qcsize > 0){
+                    byte[] request = new byte[qcsize];
+                    // 每次从总的消息中读取n个字节的数据
+                    message.readBytes(request);
+                    // 将拆分后的结果放入out列表中,交由后面的业务逻辑去处理
+                    out.add(retType+hexStringToAscii(ByteBufUtil.hexDump(Unpooled.copiedBuffer(request))));
+                }
+            }else{
+                break;
+            }
+        }
+
+        // 多余的报文存起来
+        // 第一个报文: i+  暂存
+        // 第二个报文: 1 与第一次
+        size = message.readableBytes();
+        if (size != 0) {
+            System.out.println("多余的数据长度:" + size);
+            // 剩下来的数据放到tempMsg暂存
+            tempMsg.clear();
+            tempMsg.writeBytes(message.readBytes(size));
+        }
+    }
+
+    private Integer checkResultSize(String str, String msg_type, String split){
+        String oldstr = str;
+        str = split+str;
+        int tpsize = 0;
+        switch(msg_type) {
+            case "SYNR": // 同步
+                if(str.length() >= MesMsgUtils.SYNR_LEN){
+                    tpsize = MesMsgUtils.SYNR_LEN;
+                }
+                break;
+            case "AXTW": // 心跳
+                if(str.length() >= MesMsgUtils.AXTW_LEN){
+                    tpsize = MesMsgUtils.AXTW_LEN;
+                }
+                break;
+            case "ACLW": // 重连
+                if(str.length() >= MesMsgUtils.ACLW_LEN){
+                    tpsize = MesMsgUtils.ACLW_LEN;
+                }
+                break;
+            case "MCJW":
+            case "AQDW":
+            case "MBDW":
+            case "MJBW":
+            case "MQDW":
+            case "MKSW":
+            case "MSBW":
+            case "MCSW":
+            case "AQRW":
+            default: // 默认新报文
+                if(str.length() >= ProtocolParam.fixedLength){ // 大于固定长度
+                    tpsize = ProtocolParam.fixedLength;
+                }
+                break;
+        }
+
+        return tpsize;
+    }
+
+    // 16字符串转Ascii
+    private String hexStringToAscii(String hexString) {
+        StringBuilder sbuilder = new StringBuilder();
+        for (int i = 0; i < hexString.length(); i += 2) {
+            String hexByte = hexString.substring(i, i + 2);
+            int byteValue = Integer.parseInt(hexByte, 16);
+            char c = (char) byteValue;
+            sbuilder.append(c);
+        }
+        return sbuilder.toString();
+    }
+}

+ 197 - 0
src/com/mes/test/YgslConnectionTest.java

@@ -0,0 +1,197 @@
+package com.mes.test;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.DelimiterBasedFrameDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import io.netty.util.CharsetUtil;
+
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+
+public class YgslConnectionTest {
+
+    private static final int PORT = 4545;
+
+    public static void main(String[] args) {
+        Scanner scanner = new Scanner(System.in);
+
+        System.out.println("========================================");
+        System.out.println("       扭力枪连接测试工具");
+        System.out.println("========================================");
+        System.out.println("请选择要测试的枪:");
+        System.out.println("1. A枪 (192.168.100.121)");
+        System.out.println("2. B枪 (192.168.100.122)");
+        System.out.println("3. C枪 (192.168.100.123)");
+        System.out.println("4. D枪 (192.168.100.124)");
+        System.out.println("5. 测试所有枪");
+        System.out.println("0. 退出");
+        System.out.println("========================================");
+
+        while (true) {
+            System.out.print("\n请输入选项: ");
+            String input = scanner.nextLine().trim();
+
+            switch (input) {
+                case "1":
+                    testConnection("A枪", "192.168.100.121");
+                    break;
+                case "2":
+                    testConnection("B枪", "192.168.100.122");
+                    break;
+                case "3":
+                    testConnection("C枪", "192.168.100.123");
+                    break;
+                case "4":
+                    testConnection("D枪", "192.168.100.124");
+                    break;
+                case "5":
+                    testAllConnections();
+                    break;
+                case "0":
+                    System.out.println("退出测试程序");
+                    scanner.close();
+                    System.exit(0);
+                    break;
+                default:
+                    System.out.println("无效选项,请重新输入");
+            }
+        }
+    }
+
+    private static void testConnection(String gunName, String ip) {
+        System.out.println("\n========================================");
+        System.out.println("开始测试 " + gunName + " (" + ip + ":" + PORT + ")");
+        System.out.println("========================================");
+
+        EventLoopGroup group = new NioEventLoopGroup();
+        Bootstrap bootstrap = new Bootstrap();
+
+        try {
+            bootstrap.group(group)
+                    .channel(NioSocketChannel.class)
+                    .option(ChannelOption.TCP_NODELAY, true)
+                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
+                    .handler(new ChannelInitializer<SocketChannel>() {
+                        protected void initChannel(SocketChannel socketChannel) throws Exception {
+                            ByteBuf delimiter = Unpooled.copiedBuffer(new byte[]{0x00});
+                            socketChannel.pipeline()
+                                    .addLast(new DelimiterBasedFrameDecoder(1024, delimiter))
+                                    .addLast("encoder", new StringEncoder(CharsetUtil.UTF_8))
+                                    .addLast(new SimpleChannelInboundHandler<String>() {
+                                        @Override
+                                        protected void channelRead0(ChannelHandlerContext ctx, String msg) {
+                                            System.out.println(gunName + " 收到数据: " + msg);
+                                        }
+
+                                        @Override
+                                        public void channelActive(ChannelHandlerContext ctx) {
+                                            System.out.println(gunName + " 连接成功!通道已激活");
+                                            System.out.println("本地地址: " + ctx.channel().localAddress());
+                                            System.out.println("远程地址: " + ctx.channel().remoteAddress());
+                                        }
+
+                                        @Override
+                                        public void channelInactive(ChannelHandlerContext ctx) {
+                                            System.out.println(gunName + " 连接断开");
+                                        }
+
+                                        @Override
+                                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+                                            System.out.println(gunName + " 发生异常: " + cause.getMessage());
+                                            cause.printStackTrace();
+                                        }
+                                    });
+                        }
+                    })
+                    .remoteAddress(ip, PORT);
+
+            ChannelFuture future = bootstrap.connect().sync();
+            System.out.println(gunName + " TCP连接建立成功");
+
+            System.out.println("\n按回车键断开连接...");
+            System.in.read();
+
+            future.channel().close().sync();
+            System.out.println(gunName + " 连接已关闭");
+
+        } catch (Exception e) {
+            System.out.println(gunName + " 连接失败: " + e.getMessage());
+            e.printStackTrace();
+        } finally {
+            group.shutdownGracefully();
+            System.out.println(gunName + " 测试完成");
+        }
+    }
+
+    private static void testAllConnections() {
+        System.out.println("\n========================================");
+        System.out.println("开始测试所有枪的连接");
+        System.out.println("========================================");
+
+        String[] guns = {"A枪", "B枪", "C枪", "D枪"};
+        String[] ips = {"192.168.100.121", "192.168.100.122", "192.168.100.123", "192.168.100.124"};
+
+        for (int i = 0; i < guns.length; i++) {
+            System.out.println("\n--- 测试 " + guns[i] + " (" + ips[i] + ") ---");
+            boolean connected = quickTestConnection(ips[i]);
+            if (connected) {
+                System.out.println("✓ " + guns[i] + " 连接成功");
+            } else {
+                System.out.println("✗ " + guns[i] + " 连接失败");
+            }
+        }
+
+        System.out.println("\n========================================");
+        System.out.println("所有枪测试完成");
+        System.out.println("========================================");
+    }
+
+    private static boolean quickTestConnection(String ip) {
+        EventLoopGroup group = new NioEventLoopGroup();
+        Bootstrap bootstrap = new Bootstrap();
+
+        try {
+            bootstrap.group(group)
+                    .channel(NioSocketChannel.class)
+                    .option(ChannelOption.TCP_NODELAY, true)
+                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
+                    .handler(new ChannelInitializer<SocketChannel>() {
+                        protected void initChannel(SocketChannel socketChannel) throws Exception {
+                            ByteBuf delimiter = Unpooled.copiedBuffer(new byte[]{0x00});
+                            socketChannel.pipeline()
+                                    .addLast(new DelimiterBasedFrameDecoder(1024, delimiter))
+                                    .addLast("encoder", new StringEncoder(CharsetUtil.UTF_8))
+                                    .addLast(new SimpleChannelInboundHandler<String>() {
+                                        @Override
+                                        protected void channelRead0(ChannelHandlerContext ctx, String msg) {
+                                        }
+
+                                        @Override
+                                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+                                        }
+                                    });
+                        }
+                    })
+                    .remoteAddress(ip, PORT);
+
+            ChannelFuture future = bootstrap.connect();
+            if (future.isSuccess()) {
+                future.channel().close().sync();
+                return true;
+            }
+            return false;
+
+        } catch (Exception e) {
+            System.out.println("连接异常: " + e.getMessage());
+            return false;
+        } finally {
+            group.shutdownGracefully();
+        }
+    }
+}

+ 484 - 0
src/com/mes/test/YgslUtilTest.java

@@ -0,0 +1,484 @@
+package com.mes.test;
+
+import com.mes.ui.YgslUtil;
+import com.mes.ygsl.YgslClient;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.DelimiterBasedFrameDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import io.netty.util.CharsetUtil;
+
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+
+public class YgslUtilTest {
+
+    private static YgslClient ygslClient;
+    private static Scanner scanner;
+    private static volatile boolean connected = false;
+
+    public static void main(String[] args) {
+        scanner = new Scanner(System.in);
+
+        System.out.println("========================================");
+        System.out.println("       A枪工具类测试工具");
+        System.out.println("========================================");
+        System.out.println("设备IP: 192.168.100.121");
+        System.out.println("设备端口: 4545");
+        System.out.println("========================================");
+
+        while (true) {
+            System.out.println("\n请选择操作:");
+            System.out.println("1. 连接设备");
+            System.out.println("2. 断开连接");
+            System.out.println("3. 通讯启动 (comStart)");
+            System.out.println("4. 通讯停止 (comStop)");
+            System.out.println("5. 心跳测试 (comHeart)");
+            System.out.println("6. 使能工具 (enableTool)");
+            System.out.println("7. 禁用工具 (disableTool)");
+            System.out.println("8. 订阅拧紧结果 (lastTighteningResultSubscribe)");
+            System.out.println("9. 设置pSet (pSet)");
+            System.out.println("10. 选择set (selectSet)");
+            System.out.println("11. 上传jobId (jobIdUpload)");
+            System.out.println("12. 选择job (selectJob)");
+            System.out.println("13. 重启job (restartJob)");
+            System.out.println("14. 自动测试序列");
+            System.out.println("0. 退出");
+            System.out.println("========================================");
+
+            System.out.print("\n请输入选项: ");
+            String input = scanner.nextLine().trim();
+
+            if (!connected && !input.equals("1") && !input.equals("0")) {
+                System.out.println("请先连接设备(选项1)!");
+                continue;
+            }
+
+            switch (input) {
+                case "1":
+                    connectDevice();
+                    break;
+                case "2":
+                    disconnectDevice();
+                    break;
+                case "3":
+                    testComStart();
+                    break;
+                case "4":
+                    testComStop();
+                    break;
+                case "5":
+                    testComHeart();
+                    break;
+                case "6":
+                    testEnableTool();
+                    break;
+                case "7":
+                    testDisableTool();
+                    break;
+                case "8":
+                    testLastTighteningResultSubscribe();
+                    break;
+                case "9":
+                    testPSet();
+                    break;
+                case "10":
+                    testSelectSet();
+                    break;
+                case "11":
+                    testJobIdUpload();
+                    break;
+                case "12":
+                    testSelectJob();
+                    break;
+                case "13":
+                    testRestartJob();
+                    break;
+                case "14":
+                    runAutoTestSequence();
+                    break;
+                case "0":
+                    System.out.println("退出测试程序");
+                    disconnectDevice();
+                    scanner.close();
+                    System.exit(0);
+                    break;
+                default:
+                    System.out.println("无效选项,请重新输入");
+            }
+        }
+    }
+
+    private static void connectDevice() {
+        if (connected) {
+            System.out.println("设备已连接");
+            return;
+        }
+
+        System.out.println("\n========================================");
+        System.out.println("正在连接设备...");
+        System.out.println("========================================");
+
+        EventLoopGroup group = new NioEventLoopGroup();
+        Bootstrap bootstrap = new Bootstrap();
+
+        try {
+            bootstrap.group(group)
+                    .channel(NioSocketChannel.class)
+                    .option(ChannelOption.TCP_NODELAY, true)
+                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
+                    .option(ChannelOption.SO_KEEPALIVE, true)
+                    .handler(new ChannelInitializer<SocketChannel>() {
+                        protected void initChannel(SocketChannel socketChannel) throws Exception {
+                            ByteBuf delimiter = Unpooled.copiedBuffer(new byte[]{0x00});
+                            socketChannel.pipeline()
+                                    .addLast(new DelimiterBasedFrameDecoder(1024, delimiter))
+                                    .addLast("encoder", new StringEncoder(CharsetUtil.UTF_8))
+                                    .addLast(new SimpleChannelInboundHandler<String>() {
+                                        @Override
+                                        protected void channelRead0(ChannelHandlerContext ctx, String msg) {
+                                            handleServerResponse(msg);
+                                        }
+
+                                        @Override
+                                        public void channelActive(ChannelHandlerContext ctx) {
+                                            System.out.println("✓ 设备连接成功!");
+                                            System.out.println("  本地地址: " + ctx.channel().localAddress());
+                                            System.out.println("  远程地址: " + ctx.channel().remoteAddress());
+                                            connected = true;
+                                        }
+
+                                        @Override
+                                        public void channelInactive(ChannelHandlerContext ctx) {
+                                            System.out.println("✗ 设备连接断开");
+                                            connected = false;
+                                        }
+
+                                        @Override
+                                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+                                            System.out.println("✗ 连接异常: " + cause.getMessage());
+                                            cause.printStackTrace();
+                                        }
+                                    });
+                        }
+                    })
+                    .remoteAddress("192.168.100.121", 4545);
+
+            ChannelFuture future = bootstrap.connect().sync();
+            ygslClient = new YgslClient();
+            ygslClient.future = future;
+            ygslClient.socketChannel = (SocketChannel) future.channel();
+
+            System.out.println("✓ TCP连接建立成功");
+
+        } catch (Exception e) {
+            System.out.println("✗ 连接失败: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    private static void disconnectDevice() {
+        if (!connected || ygslClient == null) {
+            System.out.println("设备未连接");
+            return;
+        }
+
+        try {
+            ygslClient.future.channel().close().sync();
+            System.out.println("✓ 设备已断开连接");
+            connected = false;
+        } catch (Exception e) {
+            System.out.println("✗ 断开连接失败: " + e.getMessage());
+        }
+    }
+
+    private static void handleServerResponse(String msg) {
+        waitingForReply = false;
+
+        System.out.println("\n========================================");
+        System.out.println("收到服务器回复");
+        System.out.println("========================================");
+        System.out.println("原始数据: " + msg);
+        System.out.println("数据长度: " + msg.length());
+        System.out.println("十六进制: " + stringToHex(msg));
+
+        if (msg.length() >= 4) {
+            String mid = msg.substring(0, 4);
+            System.out.println("MID (消息ID): " + mid);
+
+            switch (mid) {
+                case "0002":
+                    System.out.println("消息类型: 通讯启动确认");
+                    break;
+                case "0004":
+                    System.out.println("消息类型: 命令错误");
+                    if (msg.length() >= 8) {
+                        String errorCode = msg.substring(4, 8);
+                        System.out.println("错误代码: " + errorCode);
+                    }
+                    break;
+                case "0005":
+                    System.out.println("消息类型: 命令被接受");
+                    if (msg.length() >= 8) {
+                        String replyMid = msg.substring(4, 8);
+                        System.out.println("回复的MID: " + replyMid);
+                    }
+                    break;
+                case "0010":
+                    System.out.println("消息类型: pSet确认");
+                    break;
+                case "0011":
+                    System.out.println("消息类型: 选择set确认");
+                    break;
+                case "0031":
+                    System.out.println("消息类型: 选择job确认");
+                    break;
+                case "0061":
+                    System.out.println("消息类型: 拧紧数据上报");
+                    System.out.println("这是拧紧结果数据,包含扭矩、角度等信息");
+                    break;
+                case "0099":
+                    System.out.println("消息类型: 心跳回复");
+                    break;
+                default:
+                    System.out.println("消息类型: 未知");
+            }
+        }
+
+        System.out.println("========================================");
+    }
+
+    private static String stringToHex(String input) {
+        StringBuilder hexString = new StringBuilder();
+        for (char ch : input.toCharArray()) {
+            hexString.append(String.format("%02X", (int) ch));
+        }
+        return hexString.toString();
+    }
+
+    private static void testComStart() {
+        System.out.println("\n>>> 发送命令: 通讯启动 (comStart)");
+        System.out.println("预期回复: 0002 (通讯启动确认)");
+        String cmd = "002000010050        ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.comStart(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testComStop() {
+        System.out.println("\n>>> 发送命令: 通讯停止 (comStop)");
+        System.out.println("预期回复: 0005 (命令被接受) 或 0004 (命令错误)");
+        String cmd = "002000030050        ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.comStop(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testComHeart() {
+        System.out.println("\n>>> 发送命令: 心跳 (comHeart)");
+        System.out.println("预期回复: 0099 (心跳回复)");
+        String cmd = "002099990010        ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.comHeart(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testEnableTool() {
+        System.out.println("\n>>> 发送命令: 使能工具 (enableTool)");
+        System.out.println("预期回复: 0005 (命令被接受) 或 0004 (命令错误)");
+        String cmd = "00200043000         ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.enableTool(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testDisableTool() {
+        System.out.println("\n>>> 发送命令: 禁用工具 (disableTool)");
+        System.out.println("预期回复: 0005 (命令被接受) 或 0004 (命令错误)");
+        String cmd = "00200042000         ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.disableTool(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testLastTighteningResultSubscribe() {
+        System.out.println("\n>>> 发送命令: 订阅拧紧结果 (lastTighteningResultSubscribe)");
+        System.out.println("预期回复: 0061 (拧紧数据上报)");
+        String cmd = "002000600010        ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.lastTighteningResultSubscribe(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testPSet() {
+        System.out.println("\n>>> 发送命令: 设置pSet (pSet)");
+        System.out.println("预期回复: 0010 (pSet确认)");
+        String cmd = "002000100010        ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.pSet(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testSelectSet() {
+        System.out.println("\n>>> 发送命令: 选择set (selectSet)");
+        System.out.println("预期回复: 0011 (选择set确认)");
+        String cmd = "002300180010        001";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.selectSet(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testJobIdUpload() {
+        System.out.println("\n>>> 发送命令: 上传jobId (jobIdUpload)");
+        System.out.println("预期回复: 0031 (选择job确认)");
+        String cmd = "002000300010        ";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.jobIdUpload(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testSelectJob() {
+        System.out.println("\n>>> 发送命令: 选择job (selectJob)");
+        System.out.println("预期回复: 0031 (选择job确认)");
+        String cmd = "002000380010        01";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.selectJob(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static void testRestartJob() {
+        System.out.println("\n>>> 发送命令: 重启job (restartJob)");
+        System.out.println("预期回复: 0005 (命令被接受) 或 0004 (命令错误)");
+        String cmd = "002000390010        01";
+        System.out.println("发送的原始字符串: " + cmd);
+        System.out.println("发送的十六进制: " + stringToHex(cmd));
+        System.out.println("发送的字节数: " + cmd.length());
+        Boolean result = YgslUtil.restartJob(ygslClient);
+        System.out.println("发送结果: " + (result ? "成功" : "失败"));
+        System.out.println("等待回复(最多5秒)...");
+        startReplyTimeoutMonitor(5000);
+    }
+
+    private static volatile boolean waitingForReply = false;
+
+    private static void startReplyTimeoutMonitor(long timeoutMs) {
+        waitingForReply = true;
+        new Thread(() -> {
+            try {
+                Thread.sleep(timeoutMs);
+                if (waitingForReply) {
+                    System.out.println("\n⚠ 超时警告: " + timeoutMs + "ms内未收到服务器回复");
+                    System.out.println("可能的原因:");
+                    System.out.println("  1. 设备未收到命令");
+                    System.out.println("  2. 设备处理时间过长");
+                    System.out.println("  3. 设备回复格式不正确");
+                    System.out.println("  4. 网络传输问题");
+                    System.out.println("  5. 设备不支持该命令");
+                    waitingForReply = false;
+                }
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        }).start();
+    }
+
+    private static void runAutoTestSequence() {
+        System.out.println("\n========================================");
+        System.out.println("开始自动测试序列");
+        System.out.println("========================================");
+
+        if (!connected) {
+            System.out.println("请先连接设备!");
+            return;
+        }
+
+        System.out.println("\n步骤1: 通讯启动");
+        testComStart();
+        sleep(1000);
+
+        System.out.println("\n步骤2: 订阅拧紧结果");
+        testLastTighteningResultSubscribe();
+        sleep(1000);
+
+        System.out.println("\n步骤3: 设置pSet");
+        testPSet();
+        sleep(1000);
+
+        System.out.println("\n步骤4: 选择set");
+        testSelectSet();
+        sleep(1000);
+
+        System.out.println("\n步骤5: 上传jobId");
+        testJobIdUpload();
+        sleep(1000);
+
+        System.out.println("\n步骤6: 选择job");
+        testSelectJob();
+        sleep(1000);
+
+        System.out.println("\n步骤7: 使能工具");
+        testEnableTool();
+        sleep(1000);
+
+        System.out.println("\n步骤8: 发送心跳");
+        testComHeart();
+        sleep(1000);
+
+        System.out.println("\n========================================");
+        System.out.println("自动测试序列完成");
+        System.out.println("========================================");
+    }
+
+    private static void sleep(long millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+}

+ 58 - 0
src/com/mes/ui/BindMaterialResp.java

@@ -0,0 +1,58 @@
+package com.mes.ui;
+
+public class BindMaterialResp {
+    private String materialId;
+    private String materialTitle;
+    private String craft;
+    private String batchSn;
+    private String lastTimes;
+    private String type;
+
+    public String getMaterialId() {
+        return materialId;
+    }
+
+    public void setMaterialId(String materialId) {
+        this.materialId = materialId;
+    }
+
+    public String getMaterialTitle() {
+        return materialTitle;
+    }
+
+    public void setMaterialTitle(String materialTitle) {
+        this.materialTitle = materialTitle;
+    }
+
+    public String getCraft() {
+        return craft;
+    }
+
+    public void setCraft(String craft) {
+        this.craft = craft;
+    }
+
+    public String getBatchSn() {
+        return batchSn;
+    }
+
+    public void setBatchSn(String batchSn) {
+        this.batchSn = batchSn;
+    }
+
+    public String getLastTimes() {
+        return lastTimes;
+    }
+
+    public void setLastTimes(String lastTimes) {
+        this.lastTimes = lastTimes;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}

+ 15 - 0
src/com/mes/ui/CenterRenderer.java

@@ -0,0 +1,15 @@
+package com.mes.ui;
+
+import javax.swing.*;
+import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.*;
+
+public class CenterRenderer extends DefaultTableCellRenderer {
+    public Component getTableCellRendererComponent(JTable table,Object value,
+                                                   boolean isSelected, boolean hasFocus,
+                                                   int row, int column){
+        JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+        label.setHorizontalAlignment(JLabel.CENTER); // 设置水平对齐方式为居中
+        return label;
+    }
+}

+ 239 - 0
src/com/mes/ui/DataUtil.java

@@ -0,0 +1,239 @@
+package com.mes.ui;
+
+import com.alibaba.fastjson2.JSONObject;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Properties;
+
+public class DataUtil {
+
+    public static String rightPad(final String str, final int size) {
+        if (str == null) {
+            return null;
+        }
+
+        String strret = str;
+        if(str.length() > size){
+            strret = str.substring(0,size);
+        }
+        return String.format("%-"+size+"s", strret);
+    }
+
+    public static JSONObject getBindMaterail() {
+        try{
+            String enconding = "UTF-8";
+            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
+            Properties pro = new Properties();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
+            pro.load(br);
+            String mes_server_ip = pro.getProperty("mes.server_ip");
+            String oprno = pro.getProperty("mes.gw").trim();
+            String lineSn = pro.getProperty("mes.line_sn").trim();
+            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesLineProcessMaterial/materials";
+            String params = "__ajax=json&oprno="+oprno+"&lineSn="+lineSn;
+            System.out.println("params="+params);
+            String result = doPost(url,params);
+            System.out.println("result="+result);
+
+            if(result == null || result.equalsIgnoreCase("false")) {
+                return null;
+            }else {
+                return JSONObject.parseObject(result);
+            }
+        }catch (Exception e){
+            return null;
+        }
+    }
+
+    public static JSONObject saveBindMaterail(String batchSn,String craft,String materialId,String type) {
+        try{
+            String enconding = "UTF-8";
+            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
+            Properties pro = new Properties();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
+            pro.load(br);
+            String mes_server_ip = pro.getProperty("mes.server_ip");
+            String oprno = pro.getProperty("mes.gw").trim();
+            String lineSn = pro.getProperty("mes.line_sn").trim();
+            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesMaterialPrebind/bind";
+            String params = "__ajax=json&oprno="+oprno+"&lineSn="+lineSn+"&batchSn="+batchSn+"&craft="+craft+"&materialId="+materialId+"&type="+type;
+            System.out.println("params="+params);
+            String result = doPost(url,params);
+            System.out.println("result="+result);
+
+            if(result == null || result.equalsIgnoreCase("false")) {
+                return null;
+            }else {
+                return JSONObject.parseObject(result);
+            }
+        }catch (Exception e){
+            return null;
+        }
+    }
+
+    // 上传扭力参数
+    public static JSONObject upParams(String upparams) {
+        try{
+            String mes_server_ip = MesClient.mes_server_ip;
+            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesProductYgsl/batchsave";
+            String params = "__ajax=json&params="+upparams;
+            System.out.println("params="+params);
+            String result = doPost(url,params);
+            System.out.println("result="+result);
+
+            if(result == null || result.equalsIgnoreCase("false")) {
+                return null;
+            }else {
+                return JSONObject.parseObject(result);
+            }
+        }catch (Exception e){
+            return null;
+        }
+    }
+
+    // HTTP方式 - 检查工件质量
+    public static JSONObject pcCheck(String sn, String userCode) {
+        try{
+            String enconding = "UTF-8";
+            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
+            Properties pro = new Properties();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
+            pro.load(br);
+
+            String mes_server_ip = pro.getProperty("mes.server_ip");
+            String oprno = pro.getProperty("mes.gw").trim();
+            String lineSn = pro.getProperty("mes.line_sn").trim();
+            String url = "http://" + mes_server_ip + ":8980/js/a/mes/mesProductRecord/pccheck";
+
+            String params = "__ajax=json"
+                    + "&sn=" + sn
+                    + "&oprno=" + oprno
+                    + "&lineSn=" + lineSn
+                    + "&ucode=" + userCode;
+
+            System.out.println("pcCheck params=" + params);
+
+            // 发送 POST 请求
+            String resultParams = doPost(url, params);
+            System.out.println("pcCheck result=" + resultParams);
+
+            // 处理返回结果
+            if(resultParams == null || resultParams.trim().isEmpty() || resultParams.equalsIgnoreCase("false")) {
+                return null;
+            } else {
+                return JSONObject.parseObject(resultParams);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    // HTTP方式 - 上传加工结果
+    public static JSONObject pcResult(String sn, String userCode, String ldFlag, String result) {
+        try{
+            String enconding = "UTF-8";
+            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
+            Properties pro = new Properties();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
+            pro.load(br);
+
+            String mes_server_ip = pro.getProperty("mes.server_ip");
+            String oprno = pro.getProperty("mes.gw").trim();
+            String lineSn = pro.getProperty("mes.line_sn").trim();
+            String url = "http://" + mes_server_ip + ":8980/js/a/mes/mesProductRecord/pcresult";
+
+            String params = "__ajax=json"
+                    + "&sn=" + sn
+                    + "&oprno=" + oprno
+                    + "&lineSn=" + lineSn
+                    + "&ldFlag=" + ldFlag
+                    + "&ucode=" + userCode
+                    + "&result=" + result
+                    + "&craft="
+                    + "&remark="
+                    + "&ps=";
+
+            System.out.println("pcResult params=" + params);
+
+            // 发送 POST 请求
+            String resultParams = doPost(url, params);
+            System.out.println("pcResult result=" + resultParams);
+
+            // 处理返回结果
+            if(resultParams == null || resultParams.trim().isEmpty() || resultParams.equalsIgnoreCase("false")) {
+                return null;
+            } else {
+                return JSONObject.parseObject(resultParams);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static String doPost(String httpUrl, String param) {
+        HttpURLConnection connection = null;
+        InputStream is = null;
+        OutputStream os = null;
+        BufferedReader br = null;
+        String result = null;
+        try {
+            URL url = new URL(httpUrl);
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setRequestMethod("POST");
+            connection.setConnectTimeout(15000);
+            connection.setReadTimeout(60000);
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
+            os = connection.getOutputStream();
+            os.write(param.getBytes());
+            if (connection.getResponseCode() == 200) {
+                is = connection.getInputStream();
+                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+                StringBuffer sbf = new StringBuffer();
+                String temp = null;
+                while ((temp = br.readLine()) != null) {
+                    sbf.append(temp);
+                    sbf.append("\r\n");
+                }
+                result = sbf.toString();
+            }
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (null != br) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (null != os) {
+                try {
+                    os.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (null != is) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if(connection != null) {
+                connection.disconnect();
+            }
+        }
+        return result;
+    }
+}

+ 214 - 0
src/com/mes/ui/LoginFarme.java

@@ -0,0 +1,214 @@
+package com.mes.ui;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.mes.component.MesRadio;
+import com.mes.component.MesWebView;
+import com.mes.util.Base64Utils;
+import com.mes.util.HttpUtils;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.time.LocalDateTime;
+
+public class LoginFarme extends JFrame {
+    //登录模块组件
+    static JLabel userNameLabel= new JLabel("<html><body>用户名:</body></html>",JLabel.LEFT);//用户名
+    static JLabel userPasswordLabel= new JLabel("<html><body>密码:</body></html>",JLabel.LEFT);//用户名
+    public static JTextField userNameTxt;
+    public static JPasswordField userPasswordTxt;
+    static JButton loginButton = new JButton("用户密码登录");
+    static JButton scanLoginButton = new JButton("扫  码  登  录");
+
+    public LoginFarme(){
+        setTitle("MES系统客户端:"+MesClient.mes_gw+" - "+MesClient.mes_gw_des);
+
+        ImageIcon bg = new ImageIcon(MesClient.class.getResource("/background.png"));
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        JLabel imgLabel = new JLabel(bg);//将背景图放在标签里。
+        getLayeredPane().add(imgLabel, new Integer(Integer.MIN_VALUE));//注意这里是关键,将背景标签添加到jfram的LayeredPane面板里。
+        imgLabel.setBounds(0,0,bg.getIconWidth(), bg.getIconHeight());//设置背景标签的位置
+        Container contentPane=getContentPane();
+        contentPane.setLayout(null);//布局,很重要
+        JPanel welcomePanel = new JPanel();
+        //welcomePanel.setLayout(new GridLayout(3, 1));
+        welcomePanel.setLayout(null);
+        //welcomeLable.setBounds(10, 5, 700, 100);
+        welcomePanel.setBounds(30, 330, 890, 300);
+        welcomePanel.setOpaque(false);//背景透明
+        contentPane.add(welcomePanel);
+
+        //登录页面
+        userNameLabel.setBounds(300, 100, 120, 40);
+        userNameLabel.setFont(new java.awt.Font("Dialog",   1,   16));
+        userPasswordLabel.setBounds(300, 150, 120, 40);
+        userPasswordLabel.setFont(new java.awt.Font("Dialog",   1,   16));
+        userNameTxt = new JTextField(20);
+        userNameTxt.setText("system");
+        userNameTxt.setBounds(400, 105, 150, 30);
+        userPasswordTxt = new JPasswordField(20);
+        userPasswordTxt.setBounds(400, 155, 150, 30);
+        userPasswordTxt.setText("Aa111111");
+        loginButton.setFont(new java.awt.Font("Dialog",   1,   16));
+        loginButton.setBounds(300, 200, 255, 40);
+        loginButton.setIcon(new ImageIcon(MesClient.class.getResource("/bg/user.png")));
+
+//        scanLoginButton.setVisible(false);
+        scanLoginButton.setFont(new java.awt.Font("Dialog",   1,   16));
+        scanLoginButton.setBounds(300, 250, 255, 40);
+        scanLoginButton.setIcon(new ImageIcon(MesClient.class.getResource("/bg/scan_barcode.png")));
+
+        welcomePanel.add(userNameLabel);
+        welcomePanel.add(userPasswordLabel);
+        welcomePanel.add(userNameTxt);
+        welcomePanel.add(userPasswordTxt);
+        welcomePanel.add(loginButton);
+        welcomePanel.add(scanLoginButton);
+        loginButton.addActionListener(new ActionListener(){
+            public void actionPerformed(ActionEvent e) {
+                login();
+            }
+        });
+        scanLoginButton.addActionListener(new ActionListener(){
+            public void actionPerformed(ActionEvent e) {
+                scanLogin();
+            }
+        });
+
+        ((JPanel)contentPane).setOpaque(false); //注意这里,将内容面板设为透明。这样LayeredPane面板中的背景才能显示出来。
+        //welcomeWin.setSize(902,678);
+        setResizable(false);//禁止最大化
+        setIconImage(Toolkit.getDefaultToolkit().getImage(MesClient.class.getResource("/bg/logo.png")));
+
+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+        int width = 902;
+        int height = 678;
+        setBounds((d.width-width)/2, (d.height-height)/2-(d.height-height)/4, width, height);
+        /*****正常模式******/
+        setVisible(true);
+    }
+
+    //登录
+    public static void login() {
+        String user_str = userNameTxt.getText().toString();
+        String password_str = userPasswordTxt.getText().toString();
+        if(user_str.equalsIgnoreCase("")||password_str.equalsIgnoreCase("")) {
+            JOptionPane.showMessageDialog(MesClient.mesClientFrame,"用户名或密码不能为空","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+        String username = Base64Utils.getBase64(user_str);
+        String password = Base64Utils.getBase64(password_str);
+        System.out.println("&username=" + username + "&password=" + password);
+        String url = "http://"+MesClient.mes_server_ip+":8980/js/a/login?__ajax=json&username="+username+"&password="+password+"&validCode=&__sid=";
+        String loginResult = HttpUtils.sendRequest(url);
+        if(loginResult.equalsIgnoreCase("false")) {
+            JOptionPane.showMessageDialog(MesClient.mesClientFrame,"登录异常,请检查网络或联系网络管理员","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }else {
+            JSONObject retObj = JSONObject.parseObject(loginResult);
+            if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
+                //检查用户权限是否可登录界面
+                checkUserAuthority(retObj);
+            }else {
+                //ret = "msg save error";
+                //ret = false;
+                JOptionPane.showMessageDialog(MesClient.mesClientFrame,"登录失败,用户名或密码错误","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+                return;
+            }
+        }
+    }
+    //扫码登录
+    public static void scanLogin() {
+        //userNameTxt.setText("");
+        //userPasswordTxt.setText("");
+        String scanContent = JOptionPane.showInputDialog(null, "请扫码工牌二维码");
+        System.out.println("scanContent="+scanContent);
+        if(scanContent!=null&&!scanContent.equalsIgnoreCase("")) {
+            String url = "http://"+MesClient.mes_server_ip+":8980/js/a/mes/mesLogin/login?__login=true&__ajax=json&username="+scanContent;
+            String loginResult = HttpUtils.sendRequest(url);
+            System.out.println("loginResult="+loginResult);
+            if(loginResult.equalsIgnoreCase("false")) {
+                JOptionPane.showMessageDialog(MesClient.mesClientFrame,"登录异常,请检查网络或联系网络管理员","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+                return;
+            }else {
+                JSONObject retObj = JSONObject.parseObject(loginResult);
+                if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
+                    //检查用户权限是否可登录界面
+                    checkUserAuthority(retObj);
+                }else {
+                    JOptionPane.showMessageDialog(MesClient.mesClientFrame,"登录失败,用户名或密码错误","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+                    return;
+                }
+            }
+        }else {
+            JOptionPane.showMessageDialog(MesClient.mesClientFrame,"扫码内容错误","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+    }
+
+    //检查用户权限是否可登录界面
+    public static void checkUserAuthority(JSONObject retObj) {
+        //设置登录用户名
+        JSONObject userObj = JSONObject.parseObject(retObj.get("user").toString());
+        String user_id = userObj.getString("id").toString();
+
+        //获取sessionid,判断权限
+        MesClient.sessionid = retObj.get("sessionid").toString();
+        if(MesClient.sessionid!=null&&!MesClient.sessionid.equalsIgnoreCase("")) {
+            //请求权限
+            String url_authority = "http://"+MesClient.mes_server_ip+":8980/js/a/mes/mesLineProcess/userAuth?__ajax=json&type=0&__sid="+MesClient.sessionid+"&oprno="+MesClient.mes_gw+"&lineSn="+MesClient.mes_line_sn;
+            String authorityResult = HttpUtils.sendRequest(url_authority);
+            System.out.println("authorityResult="+authorityResult);
+            JSONObject authorityObj = JSONObject.parseObject(authorityResult);
+            if(authorityObj.get("result")!=null&&authorityObj.get("result").toString().equalsIgnoreCase("true")) {
+                JSONObject authObjTmp = JSONObject.parseObject(authorityObj.get("data").toString());
+                MesClient.mes_auth = Integer.parseInt(authObjTmp.getString("auth").toString());
+                if(MesClient.mes_auth==0) {
+                    //无权限登录
+                    JOptionPane.showMessageDialog(MesClient.mesClientFrame,"您无权登录该工位","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+                    return;
+                }else if(MesClient.mes_auth==1||MesClient.mes_auth==2) {
+                    // 获取等于所处时间-当前小时
+                    LocalDateTime now = LocalDateTime.now();
+                    MesClient.userLoginHours = now.getHour();
+
+                    //启动心跳显示
+                    MesClient.startHeartBeatTimer();
+
+                    //初始化扭力枪tcp连接
+                    MesClient.initYgslTcpConnection();
+                    //启动扭力枪心跳包
+                    MesClient.startYgslHeartBeatTimer();
+
+                    //1操作工人,2管理员
+                    //登录成功
+                    MesClient.user_menu.setText(user_id);
+                    MesClient.welcomeWin.setVisible(false);
+                    MesClient.mesClientFrame.setVisible(true);
+
+                    if(MesClient.jfxPanel == null){
+                        String url = "http://"+ MesClient.mes_server_ip+":8980/js/a/mes/mesProductRecord/work?__sid="+MesClient.sessionid+"&oprno="+MesClient.mes_gw+"&lineSn="+MesClient.mes_line_sn;
+                        MesClient.jfxPanel = new MesWebView(url);
+                        MesClient.jfxPanel.setSize(990, 550);
+                        MesClient.indexPanelB.add(MesClient.jfxPanel);
+                    }
+
+                    if(MesClient.jfxPanel2 == null){
+                        String url = "http://"+ MesClient.mes_server_ip+":8980/js/a/mes/mesProcessCheckRecord/ulist?__sid="+MesClient.sessionid+"&oprno="+MesClient.mes_gw+"&lineSn="+MesClient.mes_line_sn;
+                        MesClient.jfxPanel2 = new MesWebView(url);
+                        MesClient.jfxPanel2.setSize(990, 550);
+                        MesClient.indexPanelC.add(MesClient.jfxPanel2);
+                    }
+
+                    MesClient.initWarehouseData();
+                }
+
+            }
+
+        }else {
+            JOptionPane.showMessageDialog(MesClient.mesClientFrame,"登录失败,用户名或密码错误","提示窗口", JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+    }
+}

Файловите разлики са ограничени, защото са твърде много
+ 1377 - 0
src/com/mes/ui/MesClient.java


+ 13 - 0
src/com/mes/ui/MesRevice.java

@@ -0,0 +1,13 @@
+package com.mes.ui;
+
+/**
+ * TCP报文回复处理类(已废弃)
+ * 改为HTTP方式后,此类不再使用
+ * 保留空类以避免其他地方可能的引用报错
+ */
+public class MesRevice {
+
+    // 此类已废弃,改为HTTP方式通信
+    // 原有的TCP报文处理逻辑已移除
+
+}

+ 69 - 0
src/com/mes/ui/OprnoUtil.java

@@ -0,0 +1,69 @@
+package com.mes.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class OprnoUtil {
+    public static String[] xtoprnos = new String[]{
+            "OP040", "OP070", "OP080", "OP090", "OP095", "OP100", "OP110", "OP120",
+            "OP130", "OP140", "OP150", "OP160", "OP170", "OP180", "OP190", "OP200",
+            "OP210", "OP220", "OP230", "OP240","OP245", "OP250", "OP260", "OP270", "OP280",
+            "OP290", "OP300", "OP310", "OP320", "OP330", "OP335", "OP340", "OP350",
+            "OP360", "OP370", "OP380", "OP390", "OP400", "OP410", "OP420", "OP430",
+            "OP440", "OP450", "OP460", "OP470", "OP480", "OP490", "OP500", "OP510",
+            "OP520", "OP530", "OP540"
+    };
+    public static String[] xtoprnodes = new String[]{
+            "镭雕二维码", "小总成焊接", "CMT焊接", "TIG手工焊", "人工反面补焊", "焊缝铣削", "检漏一序", "焊道检验",
+            "框架找漏", "TIG手工焊", "找漏复检", "捡漏二序", "CNC总成反面加工", "总成正反面干冰清洗", "框架清洁", "框架涂胶",
+            "FDS", "清理溢胶", "冷板激光焊", "液冷板FSW","螺栓适配", "封堵片焊接", "总成正面装配", "总成正面拉铆", "总成反面拉铆",
+            "钉头涂胶", "防爆阀拉铆", "框架终检", "静置", "半成品气密", "底护板气密", "粘贴MPP", "总成反面装配",
+            "底护板安装", "底护板复拧", "总成气密", "液冷板气密", "反面粘贴保温棉", "反面终检", "胶水固化", "型腔封堵",
+            "粘贴陶瓷胶带", "总成清洁", "蓝光检测", "总成检具", "正面终检", "CCD错漏检测", "绝缘耐压检测", "接地点检测",
+            "GP12", "下线拍照", "称重包装"
+    };
+    public static String[] lboprnos = new String[]{
+
+    };
+    public static String[] lboprnodes = new String[]{
+
+    };
+    public static String getGwDes(String lineSn,String oprno){
+        String des = "";
+        oprno = formatOprno(oprno);
+        if(lineSn.equals("XT")){
+            int i = 0;
+            for (String gw:xtoprnos){
+                if(gw.equals(oprno)){
+                    des = xtoprnodes[i];
+                    break;
+                }
+                i++;
+            }
+        }else if(lineSn.equals("LB")){
+            int i = 0;
+            for (String gw:lboprnos){
+                if(gw.equals(oprno)){
+                    des = lboprnodes[i];
+                    break;
+                }
+                i++;
+            }
+        }
+        return des;
+    }
+
+    public static String formatOprno(String oprno){
+        List<String> lists = new ArrayList<>();
+
+        if(oprno.length() == 6){
+            String ysoprno = oprno.substring(0,5).trim();
+            if(!lists.contains(ysoprno)){
+                oprno = ysoprno;
+            }
+        }
+
+        return  oprno;
+    }
+}

+ 49 - 0
src/com/mes/ui/QmData.java

@@ -0,0 +1,49 @@
+package com.mes.ui;
+
+public class QmData {
+    private String sn;
+    private String createTime;
+    private String param1;
+    private String param2;
+    private String result;
+
+    public String getSn() {
+        return sn;
+    }
+
+    public void setSn(String sn) {
+        this.sn = sn;
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getParam1() {
+        return param1;
+    }
+
+    public void setParam1(String param1) {
+        this.param1 = param1;
+    }
+
+    public String getParam2() {
+        return param2;
+    }
+
+    public void setParam2(String param2) {
+        this.param2 = param2;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+}

+ 43 - 0
src/com/mes/ui/TableCellEditorButton.java

@@ -0,0 +1,43 @@
+package com.mes.ui;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class TableCellEditorButton extends DefaultCellEditor {
+    private JButton btn;
+    public TableCellEditorButton() {
+        super(new JTextField());
+        //设置点击一次就激活,否则默认好像是点击2次激活。
+        this.setClickCountToStart(1);
+        btn = new JButton("扫码");
+        btn.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                System.out.println("按钮事件触发----");
+                int selectedRow = MesClient.table.getSelectedRow();//获得选中行的索引
+//                MesClient.rowData[selectedRow][1] = (new Date()).getTime();
+//                MesClient.table.repaint(); //重绘
+
+//                MesClient.scan_type = selectedRow + 4;
+                BindMaterialResp bindMaterialResp = new BindMaterialResp();
+                bindMaterialResp.setMaterialTitle(MesClient.rowData[selectedRow][0] + "");
+                bindMaterialResp.setBatchSn(MesClient.rowData[selectedRow][1] + "");
+                bindMaterialResp.setLastTimes(MesClient.rowData[selectedRow][2] + "");
+                bindMaterialResp.setCraft(MesClient.rowData[selectedRow][4] + "");
+                bindMaterialResp.setMaterialId(MesClient.rowData[selectedRow][5] + "");
+                bindMaterialResp.setType(MesClient.rowData[selectedRow][6] + "");
+
+                MesClient.scanBatchSn(bindMaterialResp);
+            }
+        });
+
+    }
+    @Override
+    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+
+        return btn;
+    }
+}

+ 14 - 0
src/com/mes/ui/TableCellRendererButton.java

@@ -0,0 +1,14 @@
+package com.mes.ui;
+
+import javax.swing.*;
+import javax.swing.table.TableCellRenderer;
+import java.awt.*;
+
+public class TableCellRendererButton implements TableCellRenderer {
+    @Override
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
+                                                   int row, int column) {
+        JButton button = new JButton("扫码");
+        return button;
+    }
+}

+ 67 - 0
src/com/mes/ui/Test.java

@@ -0,0 +1,67 @@
+package com.mes.ui;
+
+import com.mes.ygsl.YgslClient;
+import com.mes.ygsl.YgslParam;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public class Test {
+    public static YgslClient ygslClient;
+
+    public static void main(String[] args) {
+        String content = "023100610010        010000020003INSIGHTqcx               04                         050106001070001080001091101111120000001300010014000000150000031600324170039618003601900362202024-05-19:04:10:31212024-05-08:04:18:14221230000003081";
+        System.out.println("getTighteningStatus:"+YgslParam.getTighteningStatus(content));
+        System.out.println("getTorqueStatus:"+YgslParam.getTorqueStatus(content));
+        System.out.println("getAngleStatus:"+YgslParam.getAngleStatus(content));
+        System.out.println("getTorqueMinLimit:"+YgslParam.getTorqueMinLimit(content));
+        System.out.println("getTorqueMaxLimit:"+YgslParam.getTorqueMaxLimit(content));
+        System.out.println("getTorqueFinalTarget:"+YgslParam.getTorqueFinalTarget(content));
+        System.out.println("getTorque:"+YgslParam.getTorque(content));
+        System.out.println("getAngleMin:"+YgslParam.getAngleMin(content));
+        System.out.println("getAngleMax:"+YgslParam.getAngleMax(content));
+        System.out.println("getFinalAngleTarget:"+YgslParam.getFinalAngleTarget(content));
+        System.out.println("getAngle:"+YgslParam.getAngle(content));
+        System.out.println("getTimeStamp:"+YgslParam.getTimeStamp(content));
+        System.out.println("getBatchStatus:"+YgslParam.getBatchStatus(content));
+        System.out.println("getBatchSize:"+YgslParam.getBatchSize(content));
+        System.out.println("getBatchCounter:"+YgslParam.getBatchCounter(content));
+        System.out.println("getJobID:"+YgslParam.getJobID(content));
+
+        int val = 1234;
+        BigDecimal divisor = BigDecimal.valueOf(val).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
+        System.out.println("divisor:"+divisor);
+//        if(ygslClient==null) {
+//            //初始化TCP连接
+//            ygslClient = new YgslClient();
+//
+//            YgslUtil.comStart(ygslClient);
+//        }
+    }
+
+    public static String stringToHex(String input) {
+        StringBuilder hexString = new StringBuilder();
+
+        for (char ch : input.toCharArray()) {
+            hexString.append(Integer.toHexString((int) ch));
+        }
+
+        return hexString.toString();
+    }
+
+    /**
+     * 将字符串消息转为ByteBuf
+     * 16进制字符串转二进制
+     * @param hex 字符串消息
+     */
+    public static ByteBuf getSendByteBuf(String hex) {
+        byte[] bytes = new byte[hex.length() / 2];
+        for (int i = 0; i < hex.length(); i += 2) {
+            int value = Integer.parseInt(hex.substring(i, i + 2), 16);
+            bytes[i/2] = (byte)(value & 0xFF);
+        }
+        return Unpooled.wrappedBuffer(bytes).writeByte(0x00);
+    }
+}

+ 184 - 0
src/com/mes/ui/YgslResp.java

@@ -0,0 +1,184 @@
+package com.mes.ui;
+
+public class YgslResp {
+    private Integer id;
+    private String sn;
+    private String lineSn;
+    private String oprno;
+    private String pos;
+    private String tighteningStatus;
+    private String torqueStatus;
+    private String angleStatus;
+    private String torqueMin;
+    private String torqueMax;
+    private String torqueFinal;
+    private String torque;
+    private String angleMin;
+    private String angleMax;
+    private String angleFinal;
+    private String angle;
+    private String tighteningDate;
+    private String serialNumber;
+    private String tighteningId;
+    private String createBy;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getSn() {
+        return sn;
+    }
+
+    public void setSn(String sn) {
+        this.sn = sn;
+    }
+
+    public String getLineSn() {
+        return lineSn;
+    }
+
+    public void setLineSn(String lineSn) {
+        this.lineSn = lineSn;
+    }
+
+    public String getOprno() {
+        return oprno;
+    }
+
+    public void setOprno(String oprno) {
+        this.oprno = oprno;
+    }
+
+    public String getPos() {
+        return pos;
+    }
+
+    public void setPos(String pos) {
+        this.pos = pos;
+    }
+
+    public String getTighteningStatus() {
+        return tighteningStatus;
+    }
+
+    public void setTighteningStatus(String tighteningStatus) {
+        this.tighteningStatus = tighteningStatus;
+    }
+
+    public String getTorqueStatus() {
+        return torqueStatus;
+    }
+
+    public void setTorqueStatus(String torqueStatus) {
+        this.torqueStatus = torqueStatus;
+    }
+
+    public String getAngleStatus() {
+        return angleStatus;
+    }
+
+    public void setAngleStatus(String angleStatus) {
+        this.angleStatus = angleStatus;
+    }
+
+    public String getTorqueMin() {
+        return torqueMin;
+    }
+
+    public void setTorqueMin(String torqueMin) {
+        this.torqueMin = torqueMin;
+    }
+
+    public String getTorqueMax() {
+        return torqueMax;
+    }
+
+    public void setTorqueMax(String torqueMax) {
+        this.torqueMax = torqueMax;
+    }
+
+    public String getTorqueFinal() {
+        return torqueFinal;
+    }
+
+    public void setTorqueFinal(String torqueFinal) {
+        this.torqueFinal = torqueFinal;
+    }
+
+    public String getTorque() {
+        return torque;
+    }
+
+    public void setTorque(String torque) {
+        this.torque = torque;
+    }
+
+    public String getAngleMin() {
+        return angleMin;
+    }
+
+    public void setAngleMin(String angleMin) {
+        this.angleMin = angleMin;
+    }
+
+    public String getAngleMax() {
+        return angleMax;
+    }
+
+    public void setAngleMax(String angleMax) {
+        this.angleMax = angleMax;
+    }
+
+    public String getAngleFinal() {
+        return angleFinal;
+    }
+
+    public void setAngleFinal(String angleFinal) {
+        this.angleFinal = angleFinal;
+    }
+
+    public String getAngle() {
+        return angle;
+    }
+
+    public void setAngle(String angle) {
+        this.angle = angle;
+    }
+
+    public String getTighteningDate() {
+        return tighteningDate;
+    }
+
+    public void setTighteningDate(String tighteningDate) {
+        this.tighteningDate = tighteningDate;
+    }
+
+    public String getSerialNumber() {
+        return serialNumber;
+    }
+
+    public void setSerialNumber(String serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    public String getTighteningId() {
+        return tighteningId;
+    }
+
+    public void setTighteningId(String tighteningId) {
+        this.tighteningId = tighteningId;
+    }
+
+    public String getCreateBy() {
+        return createBy;
+    }
+
+    public void setCreateBy(String createBy) {
+        this.createBy = createBy;
+    }
+}

+ 207 - 0
src/com/mes/ui/YgslUtil.java

@@ -0,0 +1,207 @@
+package com.mes.ui;
+
+import com.mes.ygsl.YgslClient;
+//import com.mes.ygsl.YgslClient2;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+
+public class YgslUtil {
+
+    // 心跳
+    public static Boolean comHeart(YgslClient ygslClient){
+        try{
+            String synr_str = "002099990010        ";
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // 通讯启动  对应回复 0002 通讯启动确认
+    public static Boolean comStart(YgslClient ygslClient){
+        try{
+            String synr_str = "002000010050        ";
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // 通讯停止 对应回复 0005 命令被接受   0004 命令错误
+    public static Boolean comStop(YgslClient ygslClient){
+        try{
+            String synr_str = "002000030050        ";
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // 使能工具 回复 0004/0005
+    public static Boolean enableTool(YgslClient ygslClient){
+        try{
+            String synr_str = "00200043000   01    ";
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+
+            String synr_str2 = "002300180010        001";
+            System.out.println("切换到Pset1模式,开启枪");
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // 禁用工具 回复 0004/0005
+    public static Boolean disableTool(YgslClient ygslClient){
+        try{
+            String synr_str = "00200042000   01    ";
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+
+            String synr_str2 = "002300180010        002";
+            System.out.println("切换到Pset2模式,关闭枪");
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static Boolean uploadVin(YgslClient ygslClient, String sn){
+        try{
+            String synr_str = "05400050002         "+"01"+formatSn(sn)+"02"+formatSn("")+"03"+formatSn("")+"04"+formatSn("");
+            System.out.println("1上传VIN【0050】:"+synr_str+":"+synr_str.length());
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static String formatSn(String sn){
+        int length = 128;
+        return String.format("%1$-" + length + "s", sn);
+    }
+
+    //上次拧紧结果数据订阅   0061 拧紧数据上报
+    public static Boolean lastTighteningResultSubscribe(YgslClient ygslClient){
+        try{
+            String synr_str = "002000600010        ";
+            System.out.println("lastTighteningResultSubscribe:"+synr_str);
+            System.out.println(stringToHex(synr_str));
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // 接收到订阅拧紧数据后回复
+    public static Boolean lastTighteningResultDataAcknowledge(YgslClient ygslClient){
+        try{
+            String synr_str = "0020006200010       ";
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // 设置setId  对应回复 0010 pset
+    public static Boolean pSet(YgslClient ygslClient){
+        try{
+            String synr_str = "002000100010        ";
+            System.out.println("pSet:"+synr_str);
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // 选择 setId   0018 pset
+    public static Boolean selectSet(YgslClient ygslClient){
+        try{
+            String synr_str = "002300180010        001";
+            System.out.println("selectSet:"+synr_str);
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static Boolean jobIdUpload(YgslClient ygslClient){
+        try{
+            String synr_str = "002000300010        ";
+            System.out.println("jobIdUpload:"+synr_str);
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static Boolean selectJob(YgslClient ygslClient){
+        try{
+            String synr_str = "002000380010        01";
+            System.out.println("selectJob:"+synr_str);
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static Boolean restartJob(YgslClient ygslClient){
+        try{
+            String synr_str = "002000390010        01";
+            System.out.println("restartJob:"+synr_str);
+            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static String stringToHex(String input) {
+        StringBuilder hexString = new StringBuilder();
+
+        for (char ch : input.toCharArray()) {
+            hexString.append(Integer.toHexString((int) ch));
+        }
+
+        return hexString.toString();
+    }
+
+    /**
+     * 将字符串消息转为ByteBuf
+     * 16进制字符串转二进制
+     * @param hex 字符串消息
+     */
+    public static ByteBuf getSendByteBuf(String hex) {
+        hex = hex + "00";
+        byte[] bytes = new byte[hex.length() / 2];
+        for (int i = 0; i < hex.length(); i += 2) {
+            int value = Integer.parseInt(hex.substring(i, i + 2), 16);
+            bytes[i/2] = (byte)(value & 0xFF);
+        }
+        return Unpooled.wrappedBuffer(bytes);
+    }
+}

+ 206 - 0
src/com/mes/ui/YgslUtil2.java

@@ -0,0 +1,206 @@
+//package com.mes.ui;
+//
+//import com.mes.ygsl.YgslClient;
+//import com.mes.ygsl.YgslClient2;
+//import io.netty.buffer.ByteBuf;
+//import io.netty.buffer.Unpooled;
+//
+//public class YgslUtil2 {
+//
+//    // 心跳
+//    public static Boolean comHeart(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002099990010        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 通讯启动  对应回复 0002 通讯启动确认
+//    public static Boolean comStart(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002000010050        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 通讯停止 对应回复 0005 命令被接受   0004 命令错误
+//    public static Boolean comStop(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002000030050        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 使能工具 回复 0004/0005
+//    public static Boolean enableTool(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "00200043000   02    ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//
+////            String synr_str2 = "002300180010        001";
+////            System.out.println("切换到Pset1模式,开启枪");
+////            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 禁用工具 回复 0004/0005
+//    public static Boolean disableTool(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "00200042000   02    ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//
+////            String synr_str2 = "002300180010        002";
+////            System.out.println("切换到Pset2模式,关闭枪");
+////            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean uploadVin(YgslClient2 ygslClient,String sn){
+//        try{
+//            String synr_str = "05400050002         "+"01"+formatSn(sn)+"02"+formatSn("")+"03"+formatSn("")+"04"+formatSn("");
+//            System.out.println("2上传VIN【0050】:"+synr_str+":"+synr_str.length());
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static String formatSn(String sn){
+//        int length = 128;
+//        return String.format("%1$-" + length + "s", sn);
+//    }
+//
+//    // 设置setId  对应回复 0010 pset
+//    public static Boolean pSet(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002000100010        ";
+//            System.out.println("**************************pSet2:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 选择 setId   0018 pset
+//    public static Boolean selectSet(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002300180010        001";
+//            System.out.println("**************************selectSet2:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    //上次拧紧结果数据订阅   0061 拧紧数据上报
+//    public static Boolean lastTighteningResultSubscribe(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002000600010        ";
+//            System.out.println(stringToHex(synr_str));
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 接收到订阅拧紧数据后回复
+//    public static Boolean lastTighteningResultDataAcknowledge(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "0020006200010       ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean jobIdUpload(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002000300010        ";
+//            System.out.println("jobIdUpload2:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean selectJob(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002000380010        02";
+//            System.out.println("selectJob2:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean restartJob(YgslClient2 ygslClient){
+//        try{
+//            String synr_str = "002000390010        01";
+//            System.out.println("restartJob2:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static String stringToHex(String input) {
+//        StringBuilder hexString = new StringBuilder();
+//
+//        for (char ch : input.toCharArray()) {
+//            hexString.append(Integer.toHexString((int) ch));
+//        }
+//
+//        return hexString.toString();
+//    }
+//
+//    /**
+//     * 将字符串消息转为ByteBuf
+//     * 16进制字符串转二进制
+//     * @param hex 字符串消息
+//     */
+//    public static ByteBuf getSendByteBuf(String hex) {
+//        hex = hex + "00";
+//        byte[] bytes = new byte[hex.length() / 2];
+//        for (int i = 0; i < hex.length(); i += 2) {
+//            int value = Integer.parseInt(hex.substring(i, i + 2), 16);
+//            bytes[i/2] = (byte)(value & 0xFF);
+//        }
+//        return Unpooled.wrappedBuffer(bytes);
+//    }
+//}

+ 207 - 0
src/com/mes/ui/YgslUtil3.java

@@ -0,0 +1,207 @@
+//package com.mes.ui;
+//
+//import com.mes.ygsl.YgslClient2;
+//import com.mes.ygsl.YgslClient3;
+//import io.netty.buffer.ByteBuf;
+//import io.netty.buffer.Unpooled;
+//
+//public class YgslUtil3 {
+//
+//    // 心跳
+//    public static Boolean comHeart(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002099990010        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 通讯启动  对应回复 0002 通讯启动确认
+//    public static Boolean comStart(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002000010050        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 通讯停止 对应回复 0005 命令被接受   0004 命令错误
+//    public static Boolean comStop(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002000030050        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 使能工具 回复 0004/0005
+//    public static Boolean enableTool(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "00200043000   01    ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//
+//            String synr_str2 = "002300180010        001";
+//            System.out.println("切换到Pset1模式,开启枪");
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 禁用工具 回复 0004/0005
+//    public static Boolean disableTool(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "00200042000   01    ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//
+//            String synr_str2 = "002300180010        002";
+//            System.out.println("切换到Pset2模式,开启枪");
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 设置setId  对应回复 0010 pset
+//    public static Boolean pSet(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002000100010        ";
+//            System.out.println("pSet3:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 选择 setId   0018 pset
+//    public static Boolean selectSet(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002300180010        001";
+//            System.out.println("selectSet3:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    //上次拧紧结果数据订阅   0061 拧紧数据上报
+//    public static Boolean lastTighteningResultSubscribe(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002000600010        ";
+//            System.out.println(stringToHex(synr_str));
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    // 接收到订阅拧紧数据后回复
+//    public static Boolean lastTighteningResultDataAcknowledge(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "0020006200010       ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean jobIdUpload(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002000300010        ";
+//            System.out.println("jobIdUpload3:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean selectJob(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002000380010        03";
+//            System.out.println("selectJob3:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean restartJob(YgslClient3 ygslClient){
+//        try{
+//            String synr_str = "002000390010        01";
+//            System.out.println("restartJob3:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static String stringToHex(String input) {
+//        StringBuilder hexString = new StringBuilder();
+//
+//        for (char ch : input.toCharArray()) {
+//            hexString.append(Integer.toHexString((int) ch));
+//        }
+//
+//        return hexString.toString();
+//    }
+//
+//    /**
+//     * 将字符串消息转为ByteBuf
+//     * 16进制字符串转二进制
+//     * @param hex 字符串消息
+//     */
+//    public static ByteBuf getSendByteBuf(String hex) {
+//        hex = hex + "00";
+//        byte[] bytes = new byte[hex.length() / 2];
+//        for (int i = 0; i < hex.length(); i += 2) {
+//            int value = Integer.parseInt(hex.substring(i, i + 2), 16);
+//            bytes[i/2] = (byte)(value & 0xFF);
+//        }
+//        return Unpooled.wrappedBuffer(bytes);
+//    }
+//
+//    public static Boolean uploadVin(YgslClient3 ygslClient, String sn){
+//        try{
+//            String synr_str = "05400050002         "+"01"+formatSn(sn)+"02"+formatSn("")+"03"+formatSn("")+"04"+formatSn("");
+//            System.out.println("3上传VIN【0050】:"+synr_str+":"+synr_str.length());
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static String formatSn(String sn){
+//        int length = 128;
+//        return String.format("%1$-" + length + "s", sn);
+//    }
+//}
+//

+ 202 - 0
src/com/mes/ui/YgslUtil4.java

@@ -0,0 +1,202 @@
+//package com.mes.ui;
+//
+//import com.mes.ygsl.YgslClient2;
+//import com.mes.ygsl.YgslClient4;
+//import io.netty.buffer.ByteBuf;
+//import io.netty.buffer.Unpooled;
+//
+//public class YgslUtil4 {
+//
+//    public static Boolean comHeart(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002099990010        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean comStart(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002000010050        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean comStop(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002000030050        ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean enableTool(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "00200043000   01    ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            String synr_str2 = "002300180010        001";
+//            System.out.println("切换到Pset1模式,开启枪");
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean disableTool(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "00200042000   01    ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            String synr_str2 = "002300180010        002";
+//            System.out.println("切换到Pset2模式,关闭枪");
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str2)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean pSet(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002000100010        ";
+//            System.out.println("pSet4:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean selectSet(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002300180010        001";
+//            System.out.println("selectSet4:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean lastTighteningResultSubscribe(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002000600010        ";
+//            System.out.println(stringToHex(synr_str));
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean lastTighteningResultDataAcknowledge(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "0020006200010       ";
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean jobIdUpload(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002000300010        ";
+//            System.out.println("jobIdUpload4:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean selectJob(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002000380010        04";
+//            System.out.println("selectJob4:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean restartJob(YgslClient4 ygslClient){
+//        try{
+//            String synr_str = "002000390010        01";
+//            System.out.println("restartJob4:"+synr_str);
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static String stringToHex(String input) {
+//        StringBuilder hexString = new StringBuilder();
+//
+//        for (char ch : input.toCharArray()) {
+//            hexString.append(Integer.toHexString((int) ch));
+//        }
+//
+//        return hexString.toString();
+//    }
+//
+//    public static ByteBuf getSendByteBuf(String hex) {
+//        hex = hex + "00";
+//        byte[] bytes = new byte[hex.length() / 2];
+//        for (int i = 0; i < hex.length(); i += 2) {
+//            int value = Integer.parseInt(hex.substring(i, i + 2), 16);
+//            bytes[i/2] = (byte)(value & 0xFF);
+//        }
+//        return Unpooled.wrappedBuffer(bytes);
+//    }
+//
+//    public static Boolean selectSetDisable(YgslClient4 ygslClient4) {
+//        try{
+//            String synr_str = "002300180010        002";
+//            System.out.println("selectSet4:"+synr_str);
+//            ygslClient4.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static Boolean uploadVin(YgslClient4 ygslClient, String sn){
+//        try{
+//            String synr_str = "05400050002         "+"01"+formatSn(sn)+"02"+formatSn("")+"03"+formatSn("")+"04"+formatSn("");
+//            System.out.println("4上传VIN【0050】:"+synr_str+":"+synr_str.length());
+//            ygslClient.future.channel().writeAndFlush(getSendByteBuf(stringToHex(synr_str)));
+//            return true;
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            return false;
+//        }
+//    }
+//
+//    public static String formatSn(String sn){
+//        int length = 128;
+//        return String.format("%1$-" + length + "s", sn);
+//    }
+//}

+ 15 - 0
src/com/mes/util/Base64Utils.java

@@ -0,0 +1,15 @@
+package com.mes.util;
+
+import org.apache.commons.codec.binary.Base64;
+
+public class Base64Utils {
+	public static String getBase64(String str) {
+		// 待编码的二进制数据
+        byte[] binaryData = str.getBytes();
+        // 使用Base64.encodeBase64String进行编码
+        String encodedString = Base64.encodeBase64String(binaryData);
+        // 输出编码后的结果
+        System.out.println("Base64编码结果: " + encodedString);
+        return encodedString;
+	}
+}

+ 34 - 0
src/com/mes/util/DateLocalUtils.java

@@ -0,0 +1,34 @@
+package com.mes.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateLocalUtils {
+	public static SimpleDateFormat DATA_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//璁剧疆鏃ユ湡鏍煎紡
+	public static SimpleDateFormat DATA_FORMAT1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+	
+	
+	public static String getCurrentTime() {
+		String currentTime = DATA_FORMAT.format(new Date());
+		return currentTime;
+	}
+	
+	public static String getCurrentTime1() {
+		String currentTime = DATA_FORMAT1.format(new Date());
+		return currentTime;
+	}
+	
+	//获取当前时间,年月日
+	public static SimpleDateFormat DATA_FORMAT2 = new SimpleDateFormat("yyyy-MM-dd");
+	public static String getCurrentDate() {
+		String currentTime = DATA_FORMAT2.format(new Date());
+		return currentTime;
+	}
+	
+	//获取当前时间,时分秒
+	public static SimpleDateFormat DATA_FORMAT3 = new SimpleDateFormat("HH:mm:ss");
+	public static String getCurrentTimeHMS() {
+		String currentTime = DATA_FORMAT3.format(new Date());
+		return currentTime;
+	}
+}

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


Някои файлове не бяха показани, защото твърде много файлове са промени