jingbo 1 неделя назад
Сommit
3d3e9303de
99 измененных файлов с 2916 добавлено и 0 удалено
  1. 24 0
      .classpath
  2. 7 0
      .gitignore
  3. 17 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. BIN
      lib/commons-codec-1.15.jar
  58. BIN
      lib/fastjson2-2.0.16.jar
  59. BIN
      lib/gson-2.10.jar
  60. BIN
      lib/iot-communication-1.4.4.jar
  61. BIN
      lib/jfreechart-1.5.4.jar
  62. BIN
      lib/jshortcut-0.4-oberzalek.jar
  63. BIN
      lib/kotlin-stdlib-1.8.10.jar
  64. BIN
      lib/logback-classic-1.2.13.jar
  65. BIN
      lib/logback-core-1.2.13.jar
  66. BIN
      lib/netty-all-4.1.48.Final.jar
  67. BIN
      lib/okhttp-4.10.0.jar
  68. BIN
      lib/okio-jvm-3.3.0.jar
  69. BIN
      lib/s7connector-2.1.jar
  70. BIN
      lib/slf4j-api-1.7.36.jar
  71. BIN
      lib/sqlite-jdbc-3.36.0.3.jar
  72. 13 0
      src/com/mes/component/CallFromJs.java
  73. 62 0
      src/com/mes/component/MesRadio.java
  74. 47 0
      src/com/mes/component/MesWebView.java
  75. 30 0
      src/com/mes/component/MyDialog.java
  76. 90 0
      src/com/mes/netty/MesMsgUtils.java
  77. 63 0
      src/com/mes/netty/NettyClient.java
  78. 88 0
      src/com/mes/netty/NettyClientHandler.java
  79. 77 0
      src/com/mes/netty/ProtocolParam.java
  80. 172 0
      src/com/mes/netty/XDecoder.java
  81. 58 0
      src/com/mes/ui/BindMaterialResp.java
  82. 281 0
      src/com/mes/ui/DataUtil.java
  83. 191 0
      src/com/mes/ui/LoginFrame.java
  84. 648 0
      src/com/mes/ui/MesClient.java
  85. 93 0
      src/com/mes/ui/MesRevice.java
  86. 79 0
      src/com/mes/ui/OprnoUtil.java
  87. 48 0
      src/com/mes/ui/TableCellEditorButton.java
  88. 14 0
      src/com/mes/ui/TableCellRendererButton.java
  89. 17 0
      src/com/mes/util/Base64Utils.java
  90. 45 0
      src/com/mes/util/Config.java
  91. 34 0
      src/com/mes/util/DateLocalUtils.java
  92. 51 0
      src/com/mes/util/ErrorMsg.java
  93. 155 0
      src/com/mes/util/HttpUtils.java
  94. 215 0
      src/com/mes/util/JdbcUtils.java
  95. 115 0
      src/com/mes/util/S7Util.java
  96. 67 0
      src/com/mes/util/UpdateQualityTimer.java
  97. 60 0
      src/com/mes/util/WorkTimer.java
  98. 9 0
      src/resources/config/config.properties
  99. 44 0
      src/resources/logback.xml

+ 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

+ 17 - 0
.project

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mesclient-sd</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>
+</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


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/logback-classic-1.2.13.jar


BIN
lib/logback-core-1.2.13.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-1.7.36.jar


BIN
lib/sqlite-jdbc-3.36.0.3.jar


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

@@ -0,0 +1,13 @@
+package com.mes.component;
+
+import com.mes.ui.MesClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CallFromJs {
+    public static final Logger log =  LoggerFactory.getLogger(CallFromJs.class);
+    public String callFromJs(String info){
+        log.info("ss:"+info);
+        return MesClient.sessionid+":java:" + info;
+    }
+}

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

@@ -0,0 +1,62 @@
+package com.mes.component;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class MesRadio extends JPanel {
+
+    public static final Logger log =  LoggerFactory.getLogger(MesRadio.class);
+
+    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;
+                    log.info("选择:"+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;
+    }
+}

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

@@ -0,0 +1,47 @@
+package com.mes.component;
+
+import com.mes.netty.ProtocolParam;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+
+public class MesWebView extends JFXPanel {
+
+    public static final Logger log =  LoggerFactory.getLogger(MesWebView.class);
+
+    public static WebEngine engine = null;
+
+    public MesWebView(String url){
+
+        Platform.runLater(() -> {
+            WebView webView = new WebView();
+            setScene(new Scene(webView));
+            Date date = new Date();
+            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;
+    }
+
+
+}

+ 63 - 0
src/com/mes/netty/NettyClient.java

@@ -0,0 +1,63 @@
+package com.mes.netty;
+
+import com.mes.util.Config;
+import io.netty.bootstrap.Bootstrap;
+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.string.StringEncoder;
+import java.util.concurrent.TimeUnit;
+
+import com.mes.ui.MesClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NettyClient {
+
+    public static final Logger log =  LoggerFactory.getLogger(NettyClientHandler.class);
+    public SocketChannel socketChannel;
+    public static ChannelFuture future;
+
+    public  void run(Object msg){
+        //配置线程组
+        EventLoopGroup group = new NioEventLoopGroup();
+        //创建服务启动器
+        Bootstrap bootstrap = new Bootstrap();
+
+        //配置参数
+        bootstrap.group(group)
+                .channel(NioSocketChannel.class)
+                .option(ChannelOption.TCP_NODELAY,true)
+                .handler(new ChannelInitializer<SocketChannel>() {
+                    protected void initChannel(SocketChannel socketChannel) throws Exception {
+                        socketChannel.pipeline()
+                                .addLast(new XDecoder())
+                                .addLast(new StringEncoder())
+//                                    .addLast(new StringDecoder())
+                                .addLast(new NettyClientHandler());
+                    }
+                })
+                .remoteAddress(Config.server_ip, Config.tcp_port);
+
+        //连接
+        future = bootstrap.connect();
+        log.info("客户端正在连接服务端...");
+        //客户端断线重连逻辑
+        future.addListener((ChannelFutureListener) future1 -> {
+            if (future1.isSuccess()) {
+                MesClient.tcp_connect_flag = true;     //tcp连接成功
+                MesClient.allow_connect_again = true;  // 当下一次连接断开时, 允许再次发送同步请求
+                log.info("连接Netty服务端成功");
+                future.channel().writeAndFlush(msg);
+            } else {
+                //tcp连接失败
+                MesClient.tcp_connect_flag = false;
+                log.info("连接失败,进行断线重连");
+                future1.channel().eventLoop().schedule(() -> run(msg), 10, TimeUnit.SECONDS);
+            }
+        });
+        socketChannel = (SocketChannel) future.channel();
+
+    }
+}

+ 88 - 0
src/com/mes/netty/NettyClientHandler.java

@@ -0,0 +1,88 @@
+package com.mes.netty;
+
+import com.mes.ui.MesClient;
+import com.mes.ui.MesRevice;
+import com.mes.util.HttpUtils;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class NettyClientHandler extends ChannelInboundHandlerAdapter {
+
+    public static final Logger log =  LoggerFactory.getLogger(NettyClientHandler.class);
+
+    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    public static byte[] responseByte;
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        log.info("mes connecting:{}", sdf.format(new Date()));
+    }
+
+    @Override
+    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+        Channel channel = ctx.channel();
+        log.info("TCP连接断开, ip: {}", channel.remoteAddress());
+        MesClient.tcp_connect_flag = false;
+        channel.close();     // 关闭通道
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        log.info("==============================================================================");
+        log.info("| TCP返回报文内容: {}", msg);
+        String mes_msg = formatResult(msg.toString());
+        if(mes_msg.isEmpty()){ // error msg
+            log.info("| TCP返回报文内容格式错误, 弃用!");
+            log.info("==============================================================================");
+            return;
+        }
+
+        String msg_type = ProtocolParam.getMsgType(mes_msg);
+        log.info("| TCP返回报文类型: {}", msg_type);
+
+        String processMsgRet = MesMsgUtils.processMsg(mes_msg, msg_type);
+        log.info("| TCP返回报文结果: {}", processMsgRet);
+        log.info("==============================================================================");
+        switch(msg_type) {
+            case "AQDW": // 查询质量
+                MesRevice.checkQualityRevice(processMsgRet,mes_msg);
+                break;
+            case "MKSW":
+                MesRevice.startRevice(processMsgRet,mes_msg);
+                break;
+            case "MBDW":
+                MesRevice.bindRevice(processMsgRet,mes_msg);
+                break;
+            case "MJBW":
+                MesRevice.unbindRevice(processMsgRet,mes_msg);
+                break;
+            case "MQDW":
+                MesRevice.updateResultRevice(processMsgRet,mes_msg);
+                break;
+        }
+
+
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        ctx.close();
+    }
+
+    private String formatResult(String msg){
+//        log.info("length:{} content:{}", msg.length(), msg);
+        String msgType = msg.substring(0,2).trim();
+        if(msgType.equals("OK")){
+            return msg.substring(3,msg.length());
+        }else{
+            return "";
+        }
+    }
+
+}

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

@@ -0,0 +1,77 @@
+package com.mes.netty;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// 固定格式报文各参数获取方法
+public class ProtocolParam {
+    public static final Logger log =  LoggerFactory.getLogger(ProtocolParam.class);
+    // bbbbfffffARWAQDWGWOP100 GY100000ID151245P00000106200123062900001      RSOKDA2023-09-07ZT10:16:58
+    public static Integer fixedLength = 96; // 固定长度
+
+    // 获取消息类型  所有报文都可使用
+    public static String getMsgType(String msg){
+//        log.info(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);
+    }
+
+}

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

@@ -0,0 +1,172 @@
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class XDecoder extends ByteToMessageDecoder {
+
+    public static final Logger log =  LoggerFactory.getLogger(XDecoder.class);
+    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 {
+//        log.info(Thread.currentThread() + "收到了一次数据包,长度是:" + in.readableBytes());
+//        String content = hexStringToAscii(ByteBufUtil.hexDump(in));
+//        log.info("接收包内容:" + hexStringToAscii(ByteBufUtil.hexDump(in)));
+
+        // 合并报文
+        ByteBuf message = null;
+        int tmpMsgSize = tempMsg.readableBytes();
+        // 如果暂存有上一次余下的请求报文,则合并
+        if (tmpMsgSize > 0) {
+            message = Unpooled.buffer();
+            message.writeBytes(tempMsg);
+            message.writeBytes(in);
+//            log.info("合并:上一数据包余下的长度为:" + tmpMsgSize + ",合并后长度为:" + message.readableBytes());
+//            log.info("合并后包内容:" + hexStringToAscii(ByteBufUtil.hexDump(message)));
+        } else {
+            message = in;
+        }
+
+//        log.info(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) {
+//            log.info("多余的数据长度:" + 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();
+    }
+}

+ 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;
+    }
+}

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

@@ -0,0 +1,281 @@
+package com.mes.ui;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.mes.netty.NettyClient;
+import com.mes.util.Config;
+import com.mes.util.DateLocalUtils;
+import com.mes.util.JdbcUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Properties;
+
+public class DataUtil {
+
+    public static final Logger log =  LoggerFactory.getLogger(DataUtil.class);
+
+    public static Boolean synrTcp(NettyClient nettyClient,String mes_gw){
+        try{
+            //TCP连接后,直接先发同步报文
+            String start = "aaaabbbbbABW";
+            String msgType = "SYNR";
+            String gw = "GW"+DataUtil.rightPad(mes_gw, 6);
+            String da = "DA" + DateLocalUtils.getCurrentDate();
+            String zt = "ZT" + DateLocalUtils.getCurrentTimeHMS();
+            String synr_str = start + msgType + gw + da + zt;
+            //插入报文本地数据
+            String gy = "";
+            String sn = "";
+            JdbcUtils.insertData(gw, gy, synr_str, msgType, sn);
+
+            nettyClient.run(synr_str);
+
+            return true;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean heartBeat(NettyClient nettyClient,String mes_gw){
+        try{
+            //TCP连接后,直接先发同步报文
+            String start = "aaaabbbbbABW";
+            String msgType = "AXTW";
+            String gw = "GW"+DataUtil.rightPad(mes_gw, 6);
+            String da = "DA" + DateLocalUtils.getCurrentDate();
+            String zt = "ZT" + DateLocalUtils.getCurrentTimeHMS();
+            String axtw_str = start + msgType + gw + da + zt;
+            //插入报文本地数据
+            String gy = "";
+            String sn = "";
+            JdbcUtils.insertData(gw, gy, axtw_str, msgType, sn);
+            nettyClient.future.channel().writeAndFlush(axtw_str);
+
+            return true;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean checkQuality(NettyClient nettyClient, String sn, String user){
+        try{
+            String msgType = "AQDW";
+            String gy = "100000";
+            Boolean aqdw_str = sendMessage(nettyClient,msgType,gy,"",sn,"",user,"00","");
+            return aqdw_str;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean startWork(NettyClient nettyClient,String sn,String user){
+        try{
+            String msgType = "MKSW";
+            String gy = "";
+            Boolean aqdw_str = sendMessage(nettyClient,msgType,gy,"",sn,"",user,"00","");
+            return aqdw_str;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean bindUser(NettyClient nettyClient,String sn,String user){
+        try{
+            String msgType = "MBDW";
+            String gy = "400001";
+            String param = rightPad(user, 36);
+            Boolean aqdw_str = sendMessage(nettyClient,msgType,gy,"",sn,"",user,"01",param);
+            return aqdw_str;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean bindWarehouse(NettyClient nettyClient,String sn,String wsn,String user,String craft){
+        try{
+            String msgType = "MBDW";
+            String param = rightPad(wsn, 36);
+            Boolean aqdw_str = sendMessage(nettyClient,msgType,craft,"",sn,"",user,"01",param);
+            return aqdw_str;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean unBindWarehouse(NettyClient nettyClient,String sn,String wsn,String user,String craft){
+        try{
+            String msgType = "MJBW";
+            String param = rightPad(wsn, 36);
+            Boolean aqdw_str = sendMessage(nettyClient,msgType,craft,"",sn,"",user,"01",param);
+            return aqdw_str;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean sendQuality(String sn,String result,String user){
+        try{
+            String msgType = "MQDW";
+            String craft = "100000";
+            String lx = "";
+            String paramNums = "00";
+            String params = "";
+
+            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
+            Properties pro = new Properties();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+            pro.load(br);
+            String gw = "GW"+rightPad(pro.getProperty("mes.gw"), 6);
+            String start = "aaaabbbbbABW";
+            String gy = "GY" + rightPad(craft, 6);
+            String reslx = "LX" + rightPad(lx, 2);
+            String id = pro.getProperty("mes.line_sn") + rightPad(sn, 36);
+            String rs = "RS"+ rightPad(result, 2);
+            String da = "DA" + DateLocalUtils.getCurrentDate();
+            String zt = "ZT" + DateLocalUtils.getCurrentTimeHMS();
+            String yh = "YH" + rightPad(user, 20);
+            String aqdw_str = start + msgType + gw + gy + reslx + id + rs + da + zt + yh + paramNums + params;
+            log.info("向submit_record表中插入更新质量报文: {}", aqdw_str);
+            MesClient.nettyClient.future.channel().writeAndFlush(aqdw_str);
+            JdbcUtils.insertData(gw, gy, aqdw_str, msgType, sn);
+//            JdbcUtils.insertSubmitRecord(gw, sn, aqdw_str);
+            return true;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    public static Boolean sendMessage(NettyClient nettyClient,String msgType,String craft,String lx,String sn,String result,String user,String paramNums,String params){
+        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 gw = "GW"+rightPad(pro.getProperty("mes.gw"), 6);
+            String start = "aaaabbbbbABW";
+            String gy = "GY" + rightPad(craft, 6);
+            String reslx = "LX" + rightPad(lx, 2);
+            String id = pro.getProperty("mes.line_sn") + rightPad(sn, 36);
+            String rs = "RS"+ rightPad(result, 2);
+            String da = "DA" + DateLocalUtils.getCurrentDate();
+            String zt = "ZT" + DateLocalUtils.getCurrentTimeHMS();
+            String yh = "YH" + rightPad(user, 20);
+            String aqdw_str = start + msgType + gw + gy + reslx + id + rs + da + zt + yh + paramNums + params;
+            log.info("向服务端发送TCP报文: {}", aqdw_str);
+            JdbcUtils.insertData(gw, gy, aqdw_str, msgType, sn);
+            nettyClient.future.channel().writeAndFlush(aqdw_str);
+            return true;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    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 url = "http://"+ Config.server_ip+":8980/js/a/mes/mesLineProcessMaterial/materials";
+            String params = "__ajax=json&oprno="+Config.gw.trim()+"&lineSn="+Config.line_sn.trim();
+            String result = doPost(url,params);
+
+            if(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 url = "http://"+Config.server_ip+":8980/js/a/mes/mesMaterialPrebind/bind";
+            String params = "__ajax=json&oprno="+Config.gw.trim()+"&lineSn="+Config.line_sn.trim()+"&batchSn="+batchSn+"&craft="+craft+"&materialId="+materialId+"&type="+type;
+            String result = doPost(url,params);
+            if(result.equalsIgnoreCase("false")) {
+                return null;
+            }else {
+                return JSONObject.parseObject(result);
+            }
+        }catch (Exception e){
+            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();
+                }
+            }
+            connection.disconnect();
+        }
+        return result;
+    }
+}

+ 191 - 0
src/com/mes/ui/LoginFrame.java

@@ -0,0 +1,191 @@
+package com.mes.ui;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.mes.component.MesWebView;
+import com.mes.util.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.*;
+import java.awt.*;
+import java.time.LocalDateTime;
+import java.util.Objects;
+
+
+public class LoginFrame extends JFrame {
+
+    public static final Logger log = LoggerFactory.getLogger(LoginFrame.class);
+    //登录模块组件
+    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 LoginFrame() {
+        setTitle("MES系统客户端:" + Config.gw + " - " + Config.gw_des);
+
+        ImageIcon bg = new ImageIcon(Objects.requireNonNull(MesClient.class.getResource("/background.png")));
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        JLabel imgLabel = new JLabel(bg);//将背景图放在标签里。
+        getLayeredPane().add(imgLabel, new Integer(Integer.MIN_VALUE));//注意这里是关键,将背景标签添加到frame的LayeredPane面板里。
+        imgLabel.setBounds(0, 0, bg.getIconWidth(), bg.getIconHeight());//设置背景标签的位置
+        Container contentPane = getContentPane();
+        contentPane.setLayout(null);//布局,很重要
+        JPanel welcomePanel = new JPanel();
+        welcomePanel.setLayout(null);
+        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", Font.BOLD, 16));
+        userPasswordLabel.setBounds(300, 150, 120, 40);
+        userPasswordLabel.setFont(new java.awt.Font("Dialog", Font.BOLD, 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", Font.BOLD, 16));
+        loginButton.setBounds(300, 200, 255, 40);
+        loginButton.setIcon(new ImageIcon(Objects.requireNonNull(MesClient.class.getResource("/bg/user.png"))));
+
+        scanLoginButton.setFont(new java.awt.Font("Dialog", Font.BOLD, 16));
+        scanLoginButton.setBounds(300, 250, 255, 40);
+        scanLoginButton.setIcon(new ImageIcon(Objects.requireNonNull(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(e -> login());
+        scanLoginButton.addActionListener(e -> scanLogin());
+
+        ((JPanel) contentPane).setOpaque(false); //注意这里,将内容面板设为透明。这样LayeredPane面板中的背景才能显示出来。
+        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();
+        String password_str = userPasswordTxt.getText();
+        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);
+        log.info("登录 -->  用户名: {}, 密码: {}", username, password);
+        String url = "http://" + Config.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);
+        } 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);
+            }
+        }
+    }
+
+    //扫码登录
+    public static void scanLogin() {
+        String scanContent = JOptionPane.showInputDialog(null, "请扫码工牌二维码");
+        log.info("scanContent={}", scanContent);
+        if (scanContent != null && !scanContent.equalsIgnoreCase("")) {
+            String url = "http://" + Config.server_ip + ":8980/js/a/mes/mesLogin/login?__login=true&__ajax=json&username=" + scanContent;
+            String loginResult = HttpUtils.sendRequest(url);
+            log.info("loginResult={}", loginResult);
+            if (loginResult.equalsIgnoreCase("false")) {
+                JOptionPane.showMessageDialog(MesClient.mesClientFrame, "登录异常,请检查网络或联系网络管理员", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+            } 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);
+                }
+            }
+        } else {
+            JOptionPane.showMessageDialog(MesClient.mesClientFrame, "扫码内容错误", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+        }
+    }
+
+    //检查用户权限是否可登录界面
+    public static void checkUserAuthority(JSONObject retObj) {
+        //设置登录用户名
+        JSONObject userObj = JSONObject.parseObject(retObj.get("user").toString());
+        String user_id = userObj.getString("id");
+
+        //获取session id,判断权限
+        MesClient.sessionid = retObj.get("sessionid").toString();
+        if (MesClient.sessionid != null && !MesClient.sessionid.equalsIgnoreCase("")) {
+            //请求权限
+            String url_authority = "http://" + Config.server_ip + ":8980/js/a/mes/mesLineProcess/userAuth?__ajax=json&type=0&__sid=" + MesClient.sessionid + "&oprno=" + Config.gw + "&lineSn=" + Config.line_sn;
+            String authorityResult = HttpUtils.sendRequest(url_authority);
+            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"));
+                if (MesClient.mes_auth == 0) {
+                    //无权限登录
+                    JOptionPane.showMessageDialog(MesClient.mesClientFrame, "您无权登录该工位", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+                } else if (MesClient.mes_auth == 1 || MesClient.mes_auth == 2) {
+                    // 获取等于所处时间-当前小时
+                    MesClient.userLoginHours = LocalDateTime.now().getHour();
+                    //初始化tcp连接,发送同步报文
+                    MesClient.initTcpConnection();
+                    //启动timer心跳包
+                    MesClient.startHeartBeatTimer();
+
+                    //1操作工人,2管理员
+                    //登录成功
+                    MesClient.user_menu.setText(user_id);
+                    MesClient.welcomeWin.setVisible(false);
+                    MesClient.mesClientFrame.setVisible(true);
+                    MesClient.getUser();
+
+
+                    String url1 = "http://" + Config.server_ip + ":8980/js/a/mes/mesProductRecord/work?__sid=" + MesClient.sessionid + "&oprno=" + Config.gw + "&lineSn=" + Config.line_sn;
+                    MesWebView jfxPanel = new MesWebView(url1);
+                    jfxPanel.setSize(990, 550);
+                    MesClient.indexPanelB.add(jfxPanel);
+
+
+                    String url2 = "http://" + Config.server_ip + ":8980/js/a/mes/mesProcessCheckRecord/ulist?__sid=" + MesClient.sessionid + "&oprno=" + Config.gw + "&lineSn=" + Config.line_sn;
+                    MesWebView jfxPanel2 = new MesWebView(url2);
+                    jfxPanel2.setSize(990, 550);
+                    MesClient.indexPanelC.add(jfxPanel2);
+
+
+                    MesClient.initWarehouseData();
+                    UpdateQualityTimer.start();  // 开启更新质量的定时任务
+                    WorkTimer.start();
+                }
+
+            }
+
+        } else {
+            JOptionPane.showMessageDialog(MesClient.mesClientFrame, "登录失败,用户名或密码错误", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+        }
+    }
+}

+ 648 - 0
src/com/mes/ui/MesClient.java

@@ -0,0 +1,648 @@
+package com.mes.ui;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.mes.component.MesRadio;
+import com.mes.component.MesWebView;
+import com.mes.netty.NettyClient;
+import com.mes.util.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class MesClient extends JFrame {
+
+    public static final Logger log = LoggerFactory.getLogger(MesClient.class);
+
+    public static int mes_auth = 0; // 权限级别 0=无权限 1=操作工人 2=管理员
+    public static boolean tcp_connect_flag = false;     //TCP连接状态
+    public static boolean allow_connect_again = false;   // 是否允许断线重连, true 表示 允许
+    public static Boolean check_quality_result = false;
+    public static Integer work_status = 0;
+
+    public static String user20 = "";
+    public static String sessionid = "";
+    public static NettyClient nettyClient;
+
+
+    public static JPanel contentPane;
+    public static MesClient mesClientFrame;
+    public static JTabbedPane tabbedPane;
+    public static JScrollPane indexScrollPaneA;
+    public static JScrollPane searchScrollPane;
+    public static JScrollPane searchScrollPaneDj;
+
+
+    public static JButton heart_beat_menu;
+    public static JButton status_menu;
+    public static JButton user_menu;
+    public static JButton finish_ok_bt;
+    public static JButton finish_ng_bt;
+    public static JTextField product_sn;
+    public static JButton f_scan_data_bt_1;
+    public static JFrame welcomeWin;
+    public static JPanel indexPanelB;
+    public static MesWebView jfxPanel = null;
+    public static JPanel indexPanelC;
+    public static MesWebView jfxPanel2 = null;
+    public static MesRadio mesRadioHj;
+    public static JTable table;
+    public static Object[] columnNames = {"物料名称", "绑定批次", "剩余次数", "操作"};
+    public static Object[][] rowData = null;
+
+    public static void main(String[] args) {
+        EventQueue.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    // 显示界面
+                    mesClientFrame = new MesClient();
+                    mesClientFrame.setVisible(false);
+
+                    JdbcUtils.getConn();
+
+                    welcomeWin = new LoginFrame();
+                    welcomeWin.setVisible(true);
+                } catch (Exception e) {
+                    log.error(e.getMessage());
+                }
+            }
+        });
+    }
+
+
+    // 初始化TCP
+    public static void initTcpConnection() {
+        try {
+            if (nettyClient == null) {
+                nettyClient = new NettyClient();
+                tcp_connect_flag = false;       //设置TCP连接状态
+                DataUtil.synrTcp(nettyClient, Config.gw);
+            }
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    //启动心跳包程序
+    public static java.util.Timer heartBeatTimer;
+    public static java.util.Timer heartBeatIconTimer;
+    public static boolean iconREDFlag = true;
+
+    public static void startHeartBeatTimer() {
+        if (heartBeatTimer != null) {
+            heartBeatTimer.cancel();
+        }
+        heartBeatTimer = new java.util.Timer();
+        heartBeatTimer.schedule(new TimerTask() {
+            public void run() {
+                if (nettyClient != null && tcp_connect_flag) {
+                    DataUtil.heartBeat(nettyClient, Config.gw);
+                    heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
+                }
+            }
+        }, 100, Config.heart_beat_cycle * 1000);
+
+        //心跳显示图标
+        if (heartBeatIconTimer != null) {
+            heartBeatIconTimer.cancel();
+        }
+        heartBeatIconTimer = new Timer();
+        heartBeatIconTimer.schedule(new TimerTask() {
+            public void run() {
+                if (tcp_connect_flag) {
+                    if (iconREDFlag) {
+                        heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
+                        iconREDFlag = false;
+                    } else {
+                        heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")));
+                        iconREDFlag = true;
+                    }
+                    heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
+                    heart_beat_menu.setForeground(Color.GREEN);
+                    heart_beat_menu.repaint();
+                } else {
+                    heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
+                    heart_beat_menu.setText("Mes连接断开");
+                    heart_beat_menu.setForeground(Color.RED);
+                    heart_beat_menu.repaint();
+
+                    //若未连接则尝试连接
+                    if (nettyClient != null) {
+                        //TCP重新同步连接
+                        if (allow_connect_again) {
+                            log.info("TCP连接已断开, 在心跳循环中, 发送同步连接请求");
+                            allow_connect_again = false;   // 只允许重新同步连接一次
+                            DataUtil.synrTcp(nettyClient, Config.gw);
+                        }
+
+                    }
+                }
+            }
+        }, 100, Config.heart_icon_cycle * 1000);
+    }
+
+
+    public static void initWarehouseData() {
+        resetScanA();
+    }
+
+    public static void resetScanA() {
+        work_status = 0;
+        check_quality_result = false;
+        MesClient.finish_ok_bt.setEnabled(false);
+        MesClient.finish_ng_bt.setEnabled(false);
+        product_sn.setText("");
+        MesClient.f_scan_data_bt_1.setEnabled(true);
+        MesClient.setMenuStatus("请扫工件码", 0);
+
+        S7Util.disable();
+        S7Util.writeIsComplete(false);
+
+
+        shiftUserCheck();
+    }
+
+    public static int userLoginHours;//用户登录所处小时
+
+    //换班用户信息检查
+    private static void shiftUserCheck() {
+        LocalDateTime now = LocalDateTime.now();
+        // 判断时间范围
+        if (userLoginHours >= 8 && userLoginHours < 20) {
+
+            int hour = now.getHour();
+            if (hour >= 20 || hour < 8) {
+                logoff();
+            }
+        } else {
+            int hour = now.getHour();
+            if (hour >= 8 && hour < 20) {
+                logoff();
+            }
+        }
+    }
+
+    public static void resetScanB() {
+
+    }
+
+    //获取用户20位
+    public static void getUser() {
+        user20 = user_menu.getText();
+        String space_tmp1 = "";
+        if (user20.length() < 20) {
+            for (int i = 0; i < 20 - user20.length(); i++) {
+                space_tmp1 = space_tmp1 + " ";
+            }
+        }
+        user20 = user20 + space_tmp1;
+    }
+
+    //获取barcode内容36位
+    public static String getBarcode(String barcodeTmp) {
+        String barcodeRet = barcodeTmp;
+        if (barcodeTmp.equalsIgnoreCase("")) {
+            return "";
+        } else {
+            if (barcodeTmp.length() < 36) {
+                String space = "";
+                for (int i = 0; i < 36 - barcodeTmp.length(); i++) {
+                    space = space + " ";
+                }
+                barcodeRet = barcodeTmp + space;
+            }
+        }
+        return barcodeRet;
+    }
+
+    public static String getBarcode33(String barcodeTmp) {
+        String barcodeRet = barcodeTmp;
+        if (barcodeTmp.equalsIgnoreCase("")) {
+            return "";
+        } else {
+            if (barcodeTmp.length() < 33) {
+                String space = "";
+                for (int i = 0; i < 33 - barcodeTmp.length(); i++) {
+                    space = space + " ";
+                }
+                barcodeRet = barcodeTmp + space;
+            }
+        }
+        return barcodeRet;
+    }
+
+
+    public static void scanBarcode() {
+        if (work_status == 1) {
+            JOptionPane.showMessageDialog(mesClientFrame, "工作中,勿扫码", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+        product_sn.setText("");
+        //弹窗扫工件码
+        String scanBarcode = JOptionPane.showInputDialog(null, "请扫工件码");
+        if (scanBarcode != null && !scanBarcode.equalsIgnoreCase("")) {
+            //获取扫码内容36位
+            String barcode33 = getBarcode33(scanBarcode);//处理36为码
+            product_sn.setText(scanBarcode);
+            //刷新界面
+            mesClientFrame.repaint();
+
+            if (!tcp_connect_flag) {
+                JOptionPane.showMessageDialog(mesClientFrame, "设备未连接Mes服务器", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+                return;
+            }
+
+            // 查询工件质量
+            Boolean sendret = DataUtil.checkQuality(nettyClient, barcode33, user20);
+            if (!sendret) {
+                JOptionPane.showMessageDialog(mesClientFrame, "消息发送失败,请重试", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+            }
+        } else {
+            JOptionPane.showMessageDialog(mesClientFrame, "请扫工件码", "提示窗口", JOptionPane.INFORMATION_MESSAGE);
+        }
+    }
+
+    public static void logoff() {
+        mesClientFrame.setVisible(false);
+        welcomeWin.setVisible(true);
+        nettyClient = null;
+        tcp_connect_flag = false;
+        allow_connect_again = false;
+        mes_auth = 0;
+        UpdateQualityTimer.stop();  // 停止更新质量的定时任务
+        WorkTimer.stop();
+    }
+
+    public MesClient() {
+        setIconImage(Toolkit.getDefaultToolkit().getImage(MesClient.class.getResource("/bg/logo.png")));
+        setTitle("MES系统客户端:" + Config.gw + "- " + Config.gw_des);
+        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        setBounds(0, 0, 1024, 768);
+
+        JMenuBar menuBar = new JMenuBar();
+        menuBar.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 26));
+        setJMenuBar(menuBar);
+        JMenu fileMenu = new JMenu("用户");
+        fileMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/user.png")));
+        fileMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        menuBar.add(fileMenu);
+
+        JMenuItem exitMenuItem = new JMenuItem("退出");
+        exitMenuItem.setIcon(new ImageIcon(MesClient.class.getResource("/bg/logoff.png")));
+        exitMenuItem.setFont(new Font("微软雅黑", Font.PLAIN, 22));
+        fileMenu.add(exitMenuItem);
+        exitMenuItem.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {//只能检测到mousePressed事件
+                super.mouseClicked(e);
+                logoff();
+            }
+        });
+
+        JMenu settingMenu = new JMenu("设置");
+        //settingMenu.setVisible(false);
+        settingMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/menu_setting.png")));
+        settingMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        menuBar.add(settingMenu);
+
+        JMenuItem resetTcpMenu = new JMenuItem("重连MES");
+        resetTcpMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/reset_logo.png")));
+        resetTcpMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        resetTcpMenu.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {
+                super.mouseClicked(e);
+                //重连mes
+                nettyClient.future.channel().close();
+            }
+        });
+        settingMenu.add(resetTcpMenu);
+
+        JMenuItem resetTcpMenu_1 = new JMenuItem("刷新工件");
+        resetTcpMenu_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/reset_logo.png")));
+        resetTcpMenu_1.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        resetTcpMenu_1.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {
+                super.mouseClicked(e);
+                resetScanA();
+            }
+        });
+        settingMenu.add(resetTcpMenu_1);
+
+
+        JMenuItem menuItem2 = new JMenuItem("手动提交");
+        menuItem2.setIcon(new ImageIcon(MesClient.class.getResource("/bg/reset_logo.png")));
+        menuItem2.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        menuItem2.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {
+                super.mouseClicked(e);
+                MesClient.finish_ok_bt.setEnabled(true);
+                MesClient.finish_ng_bt.setEnabled(true);
+            }
+        });
+        settingMenu.add(menuItem2);
+
+
+
+
+
+        contentPane = new JPanel();
+        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+        setContentPane(contentPane);
+        contentPane.setLayout(new BorderLayout(0, 0));
+
+        JToolBar toolBar = new JToolBar();
+        contentPane.add(toolBar, BorderLayout.NORTH);
+
+        JLabel equipment_statu_label = new JLabel("状态:");
+        equipment_statu_label.setHorizontalAlignment(SwingConstants.CENTER);
+        equipment_statu_label.setForeground(Color.BLACK);
+        equipment_statu_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        equipment_statu_label.setBackground(Color.LIGHT_GRAY);
+        toolBar.add(equipment_statu_label);
+
+        status_menu = new JButton("设备未连接MES服务器");
+        status_menu.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+            }
+        });
+        status_menu.setForeground(Color.GREEN);
+        status_menu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        status_menu.setBackground(Color.BLACK);
+        toolBar.add(status_menu);
+
+        JLabel space_1 = new JLabel("    ");
+        toolBar.add(space_1);
+
+        JLabel heart_beat_status_label = new JLabel("心跳:");
+        heart_beat_status_label.setHorizontalAlignment(SwingConstants.CENTER);
+        heart_beat_status_label.setForeground(Color.BLACK);
+        heart_beat_status_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        heart_beat_status_label.setBackground(Color.LIGHT_GRAY);
+        toolBar.add(heart_beat_status_label);
+
+        heart_beat_menu = new JButton("");
+        heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")));
+        heart_beat_menu.setForeground(Color.GREEN);
+        heart_beat_menu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        heart_beat_menu.setBackground(Color.BLACK);
+        toolBar.add(heart_beat_menu);
+
+        JLabel space_2 = new JLabel("    ");
+        toolBar.add(space_2);
+
+        JLabel user_status_label = new JLabel("登录用户:");
+        user_status_label.setHorizontalAlignment(SwingConstants.CENTER);
+        user_status_label.setForeground(Color.BLACK);
+        user_status_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        user_status_label.setBackground(Color.LIGHT_GRAY);
+        toolBar.add(user_status_label);
+
+        user_menu = new JButton("");
+        user_menu.setForeground(Color.GREEN);
+        user_menu.setFont(new Font("微软雅黑", Font.PLAIN, 22));
+        user_menu.setBackground(Color.BLACK);
+        toolBar.add(user_menu);
+
+        JLabel space_3 = new JLabel("    ");
+        toolBar.add(space_3);
+
+        JLabel space_4 = new JLabel("    ");
+        toolBar.add(space_4);
+
+        tabbedPane = new JTabbedPane(JTabbedPane.TOP);
+        tabbedPane.setMinimumSize(new Dimension(400, 50));
+        tabbedPane.setFont(new Font("宋体", Font.BOLD, 22));
+        contentPane.add(tabbedPane);
+
+        //首页
+        JPanel indexPanelA = new JPanel();
+        indexScrollPaneA = new JScrollPane(indexPanelA);
+        indexPanelA.setLayout(null);
+
+        product_sn = new JTextField();
+        product_sn.setHorizontalAlignment(SwingConstants.CENTER);
+        product_sn.setEditable(false);
+        product_sn.setFont(new Font("微软雅黑", Font.PLAIN, 28));
+        product_sn.setBounds(81, 70, 602, 70);
+        indexPanelA.add(product_sn);
+        product_sn.setColumns(10);
+
+        f_scan_data_bt_1 = new JButton("扫码");
+        f_scan_data_bt_1.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                scanBarcode();
+            }
+        });
+        f_scan_data_bt_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/scan_barcode.png")));
+        f_scan_data_bt_1.setFont(new Font("微软雅黑", Font.PLAIN, 32));
+        f_scan_data_bt_1.setBounds(693, 70, 198, 70);
+        indexPanelA.add(f_scan_data_bt_1);
+
+        finish_ok_bt = new JButton("OK");
+        finish_ok_bt.setEnabled(false);
+        finish_ok_bt.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                if (work_status == 1 && check_quality_result) {
+
+                    String sn = getBarcode(product_sn.getText());
+                    Boolean result = DataUtil.sendQuality(sn, "OK", user20);
+                    if (result) {
+                        MesClient.resetScanA();
+                        MesClient.setMenuStatus("结果提交成功,请扫下一件", 0);
+                        MesClient.scanBarcode();
+                    } else {
+                        MesClient.setMenuStatus("结果提交失败,请重试", -1);
+                    }
+                }
+
+            }
+        });
+        finish_ok_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ok_bg.png")));
+        finish_ok_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32));
+        finish_ok_bt.setBounds(185, 291, 240, 80);
+        finish_ok_bt.setEnabled(false);
+        indexPanelA.add(finish_ok_bt);
+
+        finish_ng_bt = new JButton("NG");
+        finish_ng_bt.setEnabled(false);
+        finish_ng_bt.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                if (work_status == 1 && check_quality_result) {
+
+                    String sn = getBarcode(product_sn.getText());
+                    Boolean result = DataUtil.sendQuality(sn, "NG", user20);
+                    if (result) {
+                        MesClient.resetScanA();
+                        MesClient.setMenuStatus("结果提交成功,请扫下一件", 0);
+                        MesClient.scanBarcode();
+                    } else {
+                        MesClient.setMenuStatus("结果提交失败,请重试", -1);
+                    }
+                }
+            }
+        });
+        finish_ng_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ng_bg.png")));
+        finish_ng_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32));
+        finish_ng_bt.setBounds(508, 291, 240, 80);
+        finish_ng_bt.setEnabled(false);
+        indexPanelA.add(finish_ng_bt);
+
+        tabbedPane.addTab("工作面板", new ImageIcon(MesClient.class.getResource("/bg/a_side.png")), indexScrollPaneA, null);
+        tabbedPane.setEnabledAt(0, true);
+
+        indexPanelC = new JPanel();
+        searchScrollPaneDj = new JScrollPane(indexPanelC);
+        indexPanelC.setLayout(null);
+
+        tabbedPane.addTab("开班点检", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), searchScrollPaneDj, null);
+
+
+        indexPanelB = new JPanel();
+        searchScrollPane = new JScrollPane(indexPanelB);
+        indexPanelB.setLayout(null);
+
+        tabbedPane.addTab("工作记录", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), searchScrollPane, null);
+
+
+        tabbedPane.addChangeListener(new ChangeListener() {
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
+                int selectedIndex = tabbedPane.getSelectedIndex();
+                if (selectedIndex == 1) {
+
+                }
+            }
+        });
+    }
+
+    public static void setMenuStatus(String msg, int error) {
+        if (error == 0) {
+            MesClient.status_menu.setForeground(Color.GREEN);
+        } else {
+            MesClient.status_menu.setForeground(Color.RED);
+        }
+        MesClient.status_menu.setText(msg);
+    }
+
+    public static void getMaterailData() {
+        JSONObject retObj = DataUtil.getBindMaterail();
+        if (retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
+            java.util.List<BindMaterialResp> arrs = retObj.getList("data", BindMaterialResp.class);
+            int i = 0;
+            rowData = new Object[arrs.size()][7];
+            for (BindMaterialResp bindMaterialResp : arrs) {
+                rowData[i][0] = bindMaterialResp.getMaterialTitle();
+                rowData[i][1] = bindMaterialResp.getBatchSn();
+                rowData[i][2] = bindMaterialResp.getLastTimes();
+                rowData[i][3] = "";
+                rowData[i][4] = bindMaterialResp.getCraft();
+                rowData[i][5] = bindMaterialResp.getMaterialId();
+                rowData[i][6] = bindMaterialResp.getType();
+                i++;
+            }
+            bindBatchPanel();
+        }
+    }
+
+    public static void updateMaterailData() {
+        JSONObject retObj = DataUtil.getBindMaterail();
+        if (retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
+            List<BindMaterialResp> arrs = retObj.getList("data", BindMaterialResp.class);
+
+            int i = 0;
+            for (BindMaterialResp bindMaterialResp : arrs) {
+                rowData[i][0] = bindMaterialResp.getMaterialTitle();
+                rowData[i][1] = bindMaterialResp.getBatchSn();
+                rowData[i][2] = bindMaterialResp.getLastTimes();
+                rowData[i][3] = "";
+                rowData[i][4] = bindMaterialResp.getCraft();
+                rowData[i][5] = bindMaterialResp.getMaterialId();
+                rowData[i][6] = bindMaterialResp.getType();
+                i++;
+            }
+
+            MesClient.table.repaint();
+        }
+    }
+
+    // 绑定物料批次码
+    public static void scanBatchSn(BindMaterialResp bindMaterialResp) {
+        //弹窗扫工件码
+        String scanBarcodeTitle = "请扫物料:" + bindMaterialResp.getMaterialTitle();
+        String scanBarcode = JOptionPane.showInputDialog(null, scanBarcodeTitle);
+        if (scanBarcode != null && !scanBarcode.equalsIgnoreCase("")) {
+
+            JSONObject retObj = DataUtil.saveBindMaterail(scanBarcode, bindMaterialResp.getCraft(), bindMaterialResp.getMaterialId(), bindMaterialResp.getType());
+            if (retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
+                MesClient.setMenuStatus("扫物料:" + bindMaterialResp.getMaterialTitle() + "成功", 0);
+                updateMaterailData();
+            } else {
+                if (retObj.get("result") == null) {
+                    MesClient.setMenuStatus("请求失败,请重试", -1);
+                } else {
+                    if (retObj.get("result").toString().equalsIgnoreCase("false")) {
+                        MesClient.setMenuStatus(retObj.getString("message"), -1);
+                    }
+                }
+            }
+        }
+    }
+
+    public static void bindBatchPanel() {
+        JPanel indexPanelBB = new JPanel();
+        JPanel panel = new JPanel();
+        panel.setBounds(0, 0, 990, 550);
+//        panel.setBounds(81, 50, 810, 479);
+        indexPanelBB.add(panel);
+
+        panel.setLayout(new GridLayout(0, 1, 0, 0));
+        table = new JTable(rowData, columnNames) {
+            public boolean isCellEditable(int row, int column) {
+                if (column == 3) {
+                    return true;
+                }
+                return false;
+            }
+        };
+        table.setRowHeight(40);
+        table.setEnabled(true);
+        table.setFont(new Font("微软雅黑", Font.PLAIN, 14));
+
+        table.getColumnModel().getColumn(3).setCellRenderer(new TableCellRendererButton());
+        table.getColumnModel().getColumn(3).setCellEditor(new TableCellEditorButton());
+
+
+        JScrollPane scrollPane = new JScrollPane(table);
+        panel.add(scrollPane);
+
+        JScrollPane indexScrollPaneB = new JScrollPane(indexPanelBB);
+        indexPanelBB.setLayout(null);
+        tabbedPane.addTab("绑定物料", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), indexScrollPaneB, null);
+    }
+}

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

@@ -0,0 +1,93 @@
+package com.mes.ui;
+
+import com.mes.netty.ProtocolParam;
+import com.mes.component.MyDialog;
+import com.mes.util.ErrorMsg;
+import com.mes.util.S7Util;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class MesRevice {
+
+    // 质量查询
+    public static void checkQualityRevice(String processMsgRet,String mes_msg){
+        try{
+            if(processMsgRet.equalsIgnoreCase("UD")) {
+                MesClient.check_quality_result = true;  //质量合格,可以绑定加工
+                MesClient.setMenuStatus("该工件可以加工", 0);
+                if(MesClient.work_status == 0 ){
+                    String barcode36 = MesClient.getBarcode(MesClient.product_sn.getText());//处理36为码
+                    DataUtil.startWork(MesClient.nettyClient,barcode36,MesClient.user20);
+                }
+            }else {
+                MesClient.check_quality_result = false;
+                String lmsg = ErrorMsg.getErrorMsg(processMsgRet, ProtocolParam.getLx(mes_msg));
+                MesClient.setMenuStatus(lmsg,-1);
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    // 开始回复处理
+    public static void startRevice(String processMsgRet,String mes_msg){
+        try{
+            if(processMsgRet.equalsIgnoreCase("OK")) {
+                MesClient.f_scan_data_bt_1.setEnabled(false);
+//                MesClient.finish_ok_bt.setEnabled(true);
+//                MesClient.finish_ng_bt.setEnabled(true);
+                MesClient.setMenuStatus("该工件正在加工", 0);
+
+                S7Util.writeIsComplete(false);
+                S7Util.enable();
+                MesClient.work_status = 1;
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    // 绑定
+    public static void bindRevice(String processMsgRet,String mes_msg){
+        try{
+            if(processMsgRet.equalsIgnoreCase("OK")) {
+
+            }else{
+
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    // 解绑
+    public static void unbindRevice(String processMsgRet,String mes_msg){
+        try{
+            if(processMsgRet.equalsIgnoreCase("OK")) {
+
+            }else{
+
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    // 上传质量
+    public static void updateResultRevice(String processMsgRet,String mes_msg){
+        try{
+            if(processMsgRet.equalsIgnoreCase("OK")) {
+
+                MesClient.resetScanA();
+                MesClient.setMenuStatus("结果提交成功,请扫下一件",0);
+                MesClient.scanBarcode();
+
+            }else{
+                MesClient.setMenuStatus("结果提交失败,请重试",-1);
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

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

@@ -0,0 +1,79 @@
+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[]{
+            "OP070","OP080", "OP100",
+            "OP110", "OP120", "OP130", "OP140", "OP150",
+            "OP160", "OP170", "OP180", "OP190", "OP200",
+            "OP210", "OP220", "OP230", "OP240", "OP250",
+            "OP260", "OP270", "OP280", "OP290", "OP300",
+            "OP310", "OP320", "OP330", "OP340", "OP350",
+            "OP360", "OP370", "OP380", "OP390", "OP400",
+            "OP410", "OP420", "OP430", "OP440", "OP450",
+            "OP460", "OP470", "OP480", "OP490", "OP500",
+            "OP520", "OP510", "OP550"
+    };
+    public static String[] xtoprnodes = new String[]{
+            "右边梁镭雕二维码","左边梁防爆阀拉铆","CMT框架一序焊接",
+            "人工补焊", "框架CMT二序焊接", "人工补焊", "焊道检查", "总成正面CNC",
+            "总成反面CNC", "框架去毛刺+清洁", "封堵片焊接+打磨", "边框气密", "焊道补焊",
+            "框架反面涂胶", "液冷板安装", "正面溢胶清理,补胶", "液冷板激光点固", "液冷板水嘴处焊接",
+            "焊道打磨", "液冷板FSW", "匙孔补焊打磨", "总成反面拉铆", "总成正面拉铆1",
+            "总成正面拉铆2", "边梁套筒涂胶+压合", "箱体封堵", "胶水固化", "半成品气密",
+            "补强板安装", "胶水固化", "拆卸补强板压紧工装", "FSW焊道涂胶+双层拉铆螺母涂胶", "人工抹胶",
+            "胶水固化", "反面部件装配", "底护板装配+底部套筒螺母安装", "底护板螺栓复拧", "总成气密",
+            "液冷板气密", "总成正面装配", "总成清洁", "总成检具检验", "GP12",
+            "CCD", "GP12", "称重"
+    };
+    public static String[] lboprnos = new String[]{
+            "OP040","OP050","OP060","OP070","OP080","OP090","OP100","OP110",
+            "OP120","OP130","OP140","OP150","OP160","OP170","OP180","OP190",
+            "OP200","OP210","OP220"
+    };
+    public static String[] lboprnodes = new String[]{
+            "左右冷板FSW(反面)","左右冷板FSW(正面)","左右冷板正面CNC","左右冷板反面CNC","去毛刺吹铝屑","超声波清洗","冷板FSW堵头反面焊接","冷板FSW堵头正面焊接",
+            "打磨焊道","水嘴自动激光焊","底护板支撑柱+BDU柱+线束支架焊接","冷板气检","冷板总成正面CNC","冷板总成反面CNC","去毛刺吹铝屑,清洁","高压冲洗",
+            "M5+M6钢丝牙套安装","冷板汽检","冷板氦检"
+    };
+    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;
+    }
+}

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

@@ -0,0 +1,48 @@
+package com.mes.ui;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class TableCellEditorButton extends DefaultCellEditor {
+
+    public static final Logger log =  LoggerFactory.getLogger(TableCellEditorButton.class);
+    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) {
+                log.info("按钮事件触发----");
+                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;
+    }
+}

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

@@ -0,0 +1,17 @@
+package com.mes.util;
+
+import com.mes.ui.MesClient;
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Base64Utils {
+    public static final Logger log =  LoggerFactory.getLogger(Base64Utils.class);
+	public static String getBase64(String str) {
+		// 待编码的二进制数据
+        byte[] binaryData = str.getBytes();
+        // 使用Base64.encodeBase64String进行编码
+        String encodedString = Base64.encodeBase64String(binaryData);
+        return encodedString;
+	}
+}

+ 45 - 0
src/com/mes/util/Config.java

@@ -0,0 +1,45 @@
+package com.mes.util;
+
+import com.mes.ui.OprnoUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.Properties;
+
+
+public class Config {
+    private static final Logger log = LoggerFactory.getLogger(Config.class);
+
+    public static final String line_sn;
+    public static final String gw;
+    public static final String gw_des;
+
+    public static final String server_ip;
+    public static final Integer tcp_port;
+    public static final Integer heart_beat_cycle;
+    public static final Integer heart_icon_cycle = 1;
+
+    private Config() {}
+    static {
+        Properties prop = new Properties();
+        try(InputStream is = Config.class.getClassLoader().getResourceAsStream("config/config.properties")) {
+            BufferedReader br = new BufferedReader(new InputStreamReader(Objects.requireNonNull(is), StandardCharsets.UTF_8));
+            prop.load(br);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+
+        line_sn = prop.getProperty("mes.line_sn");
+        gw = prop.getProperty("mes.gw");
+        gw_des = OprnoUtil.getGwDes(line_sn, gw);
+        server_ip = prop.getProperty("mes.server_ip");
+        tcp_port = Integer.parseInt(prop.getProperty("mes.tcp_port"));
+        heart_beat_cycle = Integer.parseInt(prop.getProperty("mes.heart_beat_cycle"));
+    }
+
+}

+ 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;
+	}
+}

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

@@ -0,0 +1,51 @@
+package com.mes.util;
+
+public class ErrorMsg {
+    public static String getErrorMsg(String processMsgRet,String lx){
+        String lmsg = "该工件本工位不可加工";
+        try{
+            if(processMsgRet.equalsIgnoreCase("OK")||processMsgRet.equalsIgnoreCase("NG")) {
+                lmsg = "该工件本工位已加工,结果:"+processMsgRet;
+            }else if(processMsgRet.equalsIgnoreCase("NE")) {
+                lmsg = "该工件未录入系统";
+            }else if(processMsgRet.equalsIgnoreCase("NN")) {
+                lmsg = "该工件跳过该工位";
+            }else if(processMsgRet.equalsIgnoreCase("QN")) {
+                lmsg = "该工件OP"+ lx+"0加工NG";
+            }else if(processMsgRet.equalsIgnoreCase("QD")) {
+                lmsg = "该工件OP"+ lx+"0未加工";
+            }else if(processMsgRet.equalsIgnoreCase("NF")) {
+                lmsg = "该工件已合格下线";
+            }else if(processMsgRet.equalsIgnoreCase("NR")) {
+                lmsg = "该工件离线返修中";
+            }else if(processMsgRet.equalsIgnoreCase("NB")) {
+                lmsg = "该工件已报废";
+            }else if(processMsgRet.equalsIgnoreCase("ND")) {
+                lmsg = "该工件NG待处理";
+            }else if(processMsgRet.equalsIgnoreCase("FN")) {
+                lmsg = "首件检查工件不合格停机";
+            }else if(processMsgRet.equalsIgnoreCase("GN")) {
+                lmsg = "更换配件首件检查不合格停机";
+            }else if(processMsgRet.equalsIgnoreCase("DJ")) {
+                lmsg = "未进行开班点检";
+            }else if(processMsgRet.equalsIgnoreCase("BM")) {
+                lmsg = "未绑定物料";
+            }else if(processMsgRet.equalsIgnoreCase("PL")) {
+                lmsg = "配件寿命不足";
+            }else if(processMsgRet.equalsIgnoreCase("QM")) {
+                lmsg = "两次气密必须间隔15分钟";
+            }else if(processMsgRet.equalsIgnoreCase("GS")) {
+                lmsg = "工件码格式不正确";
+            }else if(processMsgRet.equalsIgnoreCase("CF")) {
+                lmsg = "工件码重复";
+            }else if(processMsgRet.equalsIgnoreCase("JS")) {
+                lmsg = "4小时内未进行胶管更换";
+            } else if (processMsgRet.equalsIgnoreCase("PZ")) {
+                lmsg = "未拍照!!";
+            } else if (processMsgRet.equalsIgnoreCase("CS")) {
+                lmsg = "不在规定范围内";
+            }
+        }catch (Exception e){ }
+        return lmsg;
+    }
+}

+ 155 - 0
src/com/mes/util/HttpUtils.java

@@ -0,0 +1,155 @@
+package com.mes.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
+public class HttpUtils {
+
+    public static final Logger log =  LoggerFactory.getLogger(HttpUtils.class);
+	/**
+	 * HTTP请求,正确报文解析,并保存数据到生产记录数据
+	 * @return 
+	 * @throws URISyntaxException
+	 */
+    //http post请求
+    public static String sendRequest(String urlParam) {
+		String requestType = "POST";
+        //根据接收内容返回数据结果
+    	String ret = "";
+    	log.info("http请求路径: {}", urlParam);
+        HttpURLConnection con = null;
+        BufferedReader buffer = null;
+        StringBuffer resultBuffer = null;
+        try {
+            URL url = new URL(urlParam);
+            //得到连接对象
+            con = (HttpURLConnection) url.openConnection();
+            //设置请求类型
+            con.setRequestMethod(requestType);
+            //设置请求需要返回的数据类型和字符集类型
+            con.setRequestProperty("Content-Type", "application/json;charset=GBK");  
+            //允许写出
+            con.setDoOutput(true);
+            //允许读入
+            con.setDoInput(true);
+            //不使用缓存
+            con.setUseCaches(false);
+            //得到响应码
+            int responseCode = con.getResponseCode();
+            if(responseCode == HttpURLConnection.HTTP_OK){
+                //得到响应流
+                InputStream inputStream = con.getInputStream();
+                //将响应流转换成字符串
+                resultBuffer = new StringBuffer();
+                String line;
+                buffer = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+                while ((line = buffer.readLine()) != null) {
+                    resultBuffer.append(line);
+                }
+                log.info("http响应结果: {}", resultBuffer);
+                ret = resultBuffer.toString();
+            }else {
+            	//ret = String.valueOf(responseCode);
+            	ret = "false";
+            }
+            con.disconnect();
+        }catch(Exception e) {
+        	ret = "false";
+        }
+        return ret;
+    }
+
+
+    public static String sendPostRequest(String urlParam, String params) {
+        String requestType = "POST";
+        //根据接收内容返回数据结果
+        String ret = "";
+        log.info("http请求路径: {}", urlParam);
+        HttpURLConnection con = null;
+        BufferedReader buffer = null;
+        StringBuffer resultBuffer = null;
+        try {
+            URL url = new URL(urlParam);
+            //得到连接对象
+            con = (HttpURLConnection) url.openConnection();
+            //设置请求类型
+            con.setRequestMethod(requestType);
+            //设置请求需要返回的数据类型和字符集类型
+            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=GBK");
+            //允许写出
+            con.setDoOutput(true);
+            //允许读入
+            con.setDoInput(true);
+            //不使用缓存
+            con.setUseCaches(false);
+
+            // 获取URLConnection对象对应的输出流
+            OutputStreamWriter out = new OutputStreamWriter( con.getOutputStream(),"UTF-8");// utf-8编码
+            // 发送请求参数
+            out.write(params);
+
+            //得到响应码
+            int responseCode = con.getResponseCode();
+            if(responseCode == HttpURLConnection.HTTP_OK){
+                //得到响应流
+                InputStream inputStream = con.getInputStream();
+                //将响应流转换成字符串
+                resultBuffer = new StringBuffer();
+                String line;
+                buffer = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+                while ((line = buffer.readLine()) != null) {
+                    resultBuffer.append(line);
+                }
+                log.info("http响应结果: {}", resultBuffer);
+                ret = resultBuffer.toString();
+            }else {
+                //ret = String.valueOf(responseCode);
+                ret = "false";
+            }
+            con.disconnect();
+        }catch(Exception e) {
+            ret = "false";
+        }
+        return ret;
+    }
+
+    public static String sendPostRequestJson(String apiUrl, String jsonData) throws IOException {
+        URL url = new URL(apiUrl);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        conn.setRequestMethod("POST");
+        conn.setRequestProperty("Content-Type", "application/json");
+        conn.setDoOutput(true);
+
+        // 发送请求数据
+        try (OutputStream os = conn.getOutputStream()) {
+            byte[] input = jsonData.getBytes("utf-8");
+            os.write(input, 0, input.length);
+        }
+
+        // 获取响应数据
+        StringBuilder response = new StringBuilder();
+        int responseCode = conn.getResponseCode();
+//        System.out.println("Sending POST request to URL: " + apiUrl);
+//        System.out.println("Post parameters: " + jsonData);
+//        System.out.println("Response Code: " + responseCode);
+
+        try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
+            String responseLine;
+            while ((responseLine = br.readLine()) != null) {
+                response.append(responseLine.trim());
+            }
+        }
+
+        conn.disconnect();
+        return response.toString();
+    }
+
+	
+
+}

+ 215 - 0
src/com/mes/util/JdbcUtils.java

@@ -0,0 +1,215 @@
+package com.mes.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class JdbcUtils {
+
+	public static final Logger log =  LoggerFactory.getLogger(JdbcUtils.class);
+	//通过上面的工具就可以获取到properties文件中的键值从而可以加载驱动 获取链接 从而 可以增删改查
+	public static Connection conn = null;
+    public static String Drivde="org.sqlite.JDBC";
+    
+    public static Connection getConn(){
+        try {
+            Class.forName(Drivde);// 加载驱动,连接sqlite的jdbc
+            conn = DriverManager.getConnection("jdbc:sqlite:mes_db.db");//连接数据库zhou.db,不存在则创建
+            log.info("连接到SQLite数据库成功!");
+            create_bw_record();//初始化结构表
+            //create_measure_data();//初始化测试数据表
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+        	close();//关闭数据库连接
+            e.printStackTrace();
+        }
+        return conn;
+    }
+    
+    public static void create_bw_record() throws SQLException {
+    	Statement statement=conn.createStatement();   //创建连接对象,是Java的一个操作数据库的重要接口
+        //设备结构数据库
+        String sqlEquipment = "CREATE TABLE if not exists bw_record("
+        		+ "id INTEGER PRIMARY KEY AUTOINCREMENT,gw VARCHAR(20),gy VARCHAR(20),message_type VARCHAR(20),sn VARCHAR(48),bw VARCHAR(1000),record_time DATETIME,"
+        		+ "info_01 VARCHAR(200),info_02 VARCHAR(200),info_03 VARCHAR(200))";
+//        statement.executeUpdate("drop table if exists bw_record");//判断是否有表tables的存在。有则删除
+        statement.executeUpdate(sqlEquipment);
+
+		// 创建 提交记录表
+		String submitRecord = "CREATE TABLE if not exists submit_record(\n" +
+				"   id INTEGER PRIMARY KEY AUTOINCREMENT, -- 自增ID\n" +
+				"   oprno VARCHAR(20),                    -- 工位号 \n" +
+				"   sn VARCHAR(48),                       -- 二维码\n" +
+				"   bw VARCHAR(1000),                     -- 报文 \n" +
+				"   record_time DATETIME,                 -- 记录时间\n" +
+				"   state CHAR(1)      -- 状态(0 ->未提交, 1 ->已提交)\n" +
+				")";
+		statement.executeUpdate(submitRecord);
+
+        log.info("表创建成功!");
+        
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (1, '第一电厂', '第一电厂', '', 1, 0,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (2, '第一电厂-设备管理部', '第一电厂-设备管理部', '第一电厂', 2, 0,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (3, '第一电厂-设备管理部-电机1', '第一电厂-设备管理部-电机1', '第一电厂-设备管理部', 3, 1,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (4, '第一电厂-设备管理部-电机2', '第一电厂-设备管理部-电机2', '第一电厂-设备管理部', 3, 1,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (5, '第一电厂-设备管理部-电机3', '第一电厂-设备管理部-发电机组-电机3', '第一电厂-设备管理部', 3, 1,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (6, '第一电厂-设备管理部-电机4', '第一电厂-设备管理部-发电机组-电机4', '第一电厂-设备管理部', 3, 1,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (7, '第一电厂-设备管理部-电机5', '第一电厂-设备管理部-发电机组-电机5', '第一电厂-设备管理部',3, 1,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (9, '第一电厂-设备管理部-电机6', '第一电厂-设备管理部-发电机组-电机6', '第一电厂-设备管理部',3, 1,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (10, '第二电厂', '第二电厂', '', 1, 0,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (11, '第二电厂-设备管理部', '第二电厂-设备管理部', '第二电厂', 2, 0,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (12, '第二电厂-设备管理部-电机1', '第二电厂-设备管理部-电机1', '第二电厂-设备管理部', 3, 1,'','','','','','')");//向数据库中插入数据
+//        statement.executeUpdate("INSERT INTO tree_structure VALUES (13, '第二电厂-设备管理部-电机2', '第二电厂-设备管理部-电机2', '第二电厂-设备管理部', 3, 1,'','','','','','')");//向数据库中插入数据
+//        log.info(sqlEquipment);
+//        ResultSet rSet=statement.executeQuery("select * from bw_record");//搜索数据库,将搜索的放入数据集ResultSet中
+//        while (rSet.next()) {            //遍历这个数据集
+//            log.info("gw:"+rSet.getString(1));//依次输出 也可以这样写 rSet.getString("name")
+//            //log.info("密码:"+rSet.getString("pwd"));
+//        }
+//        rSet.close();//关闭数据集
+        statement.close();
+    }
+    
+    //插入数据
+    public static boolean insertData(String gw, String gy, String bw, String message_type, String sn) {
+    	boolean ret = false;
+    	String record_time = DateLocalUtils.getCurrentTime();
+    	if(conn==null) {
+    		ret = false;
+    	}else {
+    		try {
+    			//创建连接对象,是Java的一个操作数据库的重要接口
+				Statement statement=conn.createStatement();
+				statement.executeUpdate("INSERT INTO bw_record (gw,gy,bw,record_time,message_type,sn) VALUES"
+						+ " ('"+gw+"', '"+gy+"', '"+bw+"', '"+record_time+"','"+message_type+"','"+sn+"')");//向数据库中插入数据
+				statement.close();
+				ret = true;
+			} catch (SQLException e) {
+				// TODO Auto-generated catch block
+				//e.printStackTrace();
+				ret = false;
+			}   
+    	}
+    	
+    	return ret;
+    }
+
+	// 向 submit_record表 插入提交记录数据
+	public static boolean insertSubmitRecord(String oprno, String sn, String bw){
+		boolean ret = false;
+		String record_time = DateLocalUtils.getCurrentTime();
+		if(conn==null) {
+			ret = false;
+		}else {
+			try {
+				Statement statement=conn.createStatement();
+				String insertSQL = "INSERT INTO submit_record (oprno, sn, bw, record_time, state)" +
+						"VALUES('" + oprno + "', '" + sn + "', '" + bw + "', '" + record_time + "', '0')";
+				statement.executeUpdate(insertSQL);
+				statement.close();
+				ret = true;
+				log.info("向submit_record表插入数据成功: " + insertSQL);
+			} catch (SQLException e) {
+				ret = false;
+				log.info("向submit_record表插入数据失败");
+			}
+		}
+		return ret;
+	}
+
+
+
+
+    
+    public static void create_measure_data() throws SQLException {
+    	Statement statement=conn.createStatement();   //创建连接对象,是Java的一个操作数据库的重要接口
+    	//statement.executeUpdate("drop table if exists measure_data");//判断是否有表tables的存在。有则删除
+    	//设备结构数据库
+        String sqlEquipment = "CREATE TABLE if not exists measure_data("
+        		+ "id INTEGER PRIMARY KEY AUTOINCREMENT,function_location VARCHAR(200),description VARCHAR(200),"
+        		+ "data_item VARCHAR(100),measure_time DATETIME,data_type INT(3)," //data_type=1电阻校准数据,2电感校准数据,3绝缘电阻校准数据
+        		+ "data_01 double(30),data_02 double(30),data_03 double(30),data_04 double(30),data_05 double(30),"
+        		+ "data_06 double(30),data_07 double(30),data_08 double(30),data_09 double(30),data_10 double(30),"
+        		+ "data_11 double(30),data_12 double(30),data_13 double(30),data_14 double(30),data_15 double(30),"
+        		+ "data_16 double(30),data_17 double(30),data_18 double(30),data_19 double(30),data_20 double(30)"
+        		+ ")";
+        statement.executeUpdate(sqlEquipment);
+//        statement.executeUpdate("INSERT INTO measure_data VALUES (1, '第一电厂-设备管理部-电机1',  '第一电厂-设备管理部-电机1', '2022-03-22 15:16:18', '2022-03-22 15:16:18',1,"
+//        		+ "0.05, 0.82, 3, 80, 130, 180, 402, 502, 809, 1103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)");//向数据库中插入数据        
+//        ResultSet rSet=statement.executeQuery("select * from measure_data");//搜索数据库,将搜索的放入数据集ResultSet中
+//        while (rSet.next()) {            //遍历这个数据集
+//            log.info("function_location:"+rSet.getString(2));//依次输出 也可以这样写 rSet.getString(“name”)
+//            log.info("data_01:"+rSet.getString(4));
+//        }
+//        rSet.close();//关闭数据集
+        statement.close();
+    }
+    
+    public static void close(){
+    	log.info("SQLite数据库连接关闭!");
+        try {
+        	if(conn!=null) {
+        		conn.close();
+        	}
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+    
+    
+  //设备结构数据库
+//    String sqlEquipment = "CREATE TABLE if not exists tree_structure(id INTEGER PRIMARY KEY AUTOINCREMENT,function_location VARCHAR(200),description VARCHAR(200),sup_fl VARCHAR(200),level INT(3)," +
+//            "isleaf INT(3))";
+//    statement.executeUpdate("drop table if exists tree_structure");//判断是否有表tables的存在。有则删除
+//    statement.executeUpdate(sqlEquipment);
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (1, '第一电厂', '第一电厂', NULL, 1, 0)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (2, '第一电厂-设备管理部', '第一电厂-设备管理部', '第一电厂', 2, 0)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (3, '第一电厂-设备管理部-发电机组', '第一电厂-设备管理部-发电机组', '第一电厂-设备管理部', 3, 0)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (4, '第一电厂-设备管理部-发电机组-电机1', '第一电厂-设备管理部-发电机组-电机1', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (5, '第一电厂-设备管理部-发电机组-电机2', '第一电厂-设备管理部-发电机组-电机2', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (6, '第二电厂', '第二电厂', NULL, 1, 0)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (7, '第二电厂-设备管理部', '第二电厂-设备管理部', '第二电厂', 2, 0)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (8, '第一电厂-设备管理部-发电机组-电机3', '第一电厂-设备管理部-发电机组-电机3', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (10, '第一电厂-设备管理部-发电机组-电机4', '第一电厂-设备管理部-发电机组-电机4', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (11, '第一电厂-设备管理部-发电机组-电机5', '第一电厂-设备管理部-发电机组-电机5', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (12, '第一电厂-设备管理部-发电机组-电机8', '第一电厂-设备管理部-发电机组-电机8', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (13, '第一电厂-设备管理部-发电机组-电机6', '第一电厂-设备管理部-发电机组-电机6', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (14, '第一电厂-设备管理部-发电机组-电机7', '第一电厂-设备管理部-发电机组-电机7', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (15, '第一电厂-设备管理部-发电机组-电机9', '第一电厂-设备管理部-发电机组-电机9', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    statement.executeUpdate("INSERT INTO tree_structure VALUES (16, '第一电厂-设备管理部-发电机组-电机10', '第一电厂-设备管理部-发电机组-电机10', '第一电厂-设备管理部-发电机组', 4, 1)");//向数据库中插入数据
+//    ResultSet rSet=statement.executeQuery("select * from tree_structure");//搜索数据库,将搜索的放入数据集ResultSet中
+    
+//    /**
+//    * 通过用户名到数据库中获取凭证密码
+//    * @param userName
+//    * @return
+//    */
+//    private static String getPasswordByUserName(String userName) {
+//    //SQL语句  
+//    String sql = "select password from users where username = " +"'" + userName+"'";
+//        Connection conn = JdbcUtils.getConn();
+//        Statement stmt=null; 
+//        ResultSet ret = null;  
+//        String password=null;
+//    try {
+//    stmt = conn.createStatement();
+//    //执行语句,得到结果集  
+//    ret = stmt.executeQuery(sql);
+//                while (ret.next()) {  
+//                //这里只查询的密码
+//                password = ret.getString(1);  
+//                }
+//                ret.close();  
+//                conn.close();//关闭连接  
+//    } catch (SQLException e1) {
+//    e1.printStackTrace();
+//    }  
+//    return password;
+//    }
+}
+ 
+

+ 115 - 0
src/com/mes/util/S7Util.java

@@ -0,0 +1,115 @@
+package com.mes.util;
+
+import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
+import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
+import com.mes.ui.DataUtil;
+import com.mes.ui.MesClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import static com.mes.ui.MesClient.*;
+
+
+public class S7Util {
+
+    private static final S7PLC s7PLC = new S7PLC(EPlcType.S1200, "192.168.20.20");
+    private static final Logger log = LoggerFactory.getLogger(S7Util.class);
+
+
+    public static void disable() {
+        try {
+            s7PLC.writeBoolean("DB100.0.2", false);
+            log.info("发送禁止设备启动命令");
+        } catch (Exception e) {
+            log.info("发送禁止设备启动命令失败");
+        }
+    }
+
+    public static void enable() {
+        try {
+            s7PLC.writeBoolean("DB100.0.2", true);
+            log.info("发送允许设备启动命令");
+        } catch (Exception e) {
+            log.info("发送允许设备启动命令失败");
+        }
+    }
+
+    public static Boolean readIsEnable() {
+        try {
+            boolean read = s7PLC.readBoolean("DB100.0.2");
+            log.info("读取设备是否允许启动 {}", read);
+            return read;
+        } catch (Exception e) {
+            log.info("读取设备是否允许启动 失败");
+            return false;
+        }
+    }
+
+    public static Boolean readIsComplete() {
+        try {
+            boolean read = s7PLC.readBoolean("DB100.0.3");
+            log.info("读取完成反馈 {}", read);
+            return read;
+        } catch (Exception e) {
+            log.info("读取完成反馈失败");
+            return false;
+        }
+    }
+
+    public static void writeIsComplete(Boolean b) {
+        try {
+            s7PLC.writeBoolean("DB100.0.3", b);
+            log.info("设置完成反馈为 {}", b);
+        } catch (Exception e) {
+            log.info("设置完成反馈失败");
+        }
+    }
+
+    public static Boolean readDeviceState() {
+        try {
+            boolean read = s7PLC.readBoolean("DB100.0.4");
+            log.info("读取设备状态 {}", read);
+            return read;
+        } catch (Exception e) {
+            log.info("读取设备状态 失败");
+            return false;
+        }
+    }
+
+    public static Boolean readIsRunning() {
+        try {
+            boolean read = s7PLC.readBoolean("DB100.0.5");
+            log.info("读取设备RUN {}", read);
+            return read;
+        } catch (Exception e) {
+            log.info("读取设备RUN 失败");
+            return false;
+        }
+    }
+
+    private static void startTimer() {
+//        new Timer().schedule(new TimerTask() {
+//            @Override
+//            public void run() {
+//
+//                if(work_status == 1 && check_quality_result && !getRunning() && getIsComplete()) {
+//                    String sn = getBarcode(product_sn.getText());
+//                    getUser();
+//                    Boolean result = DataUtil.sendQuality(sn,"OK", user20);
+//                    disable();
+//                    if(result) {
+//                        MesClient.resetScanA();
+//                        MesClient.setMenuStatus("结果提交成功,请扫下一件", 0);
+//                        MesClient.scan_type = 1;
+//                        MesClient.scanBarcode();
+//                    } else {
+//                        MesClient.setMenuStatus("结果提交失败,请重试",-1);
+//                    }
+//                }
+//            }
+//        },5000, 1000);
+    }
+}

+ 67 - 0
src/com/mes/util/UpdateQualityTimer.java

@@ -0,0 +1,67 @@
+package com.mes.util;
+
+import com.alibaba.fastjson2.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class UpdateQualityTimer {
+
+    private static final Logger log = LoggerFactory.getLogger(UpdateQualityTimer.class);
+    private static final String selectSql = "SELECT id, bw FROM submit_record WHERE state = 0";
+    private static final String updateSql = "UPDATE submit_record SET state = '1' WHERE id = ";
+
+    private static Timer timer = null;
+
+    private UpdateQualityTimer() {
+    }
+
+    public static void start() {
+        if (timer == null) {
+            timer = new Timer();
+            timer.schedule(new TimerTask() {
+                @Override
+                public void run() {
+                    try {
+                        Statement statement = JdbcUtils.conn.createStatement();
+                        ResultSet rs = statement.executeQuery(selectSql);
+                        while (rs.next()) {
+                            int id = rs.getInt("id");
+                            String bw = rs.getString("bw");
+                            // 发送请求
+                            String url = "http://" + Config.server_ip + ":8980/js/a/mes/mesProductRecord/updateQualityByTiming";
+                            String s = HttpUtils.sendPostRequestJson(url, bw);
+                            Boolean result = JSONObject.parseObject(s).getBoolean("result");
+                            if (result) {
+                                // 更改状态为 1
+                                statement.executeUpdate(updateSql + id);
+                                log.info("更新质量提交成功, 报文: {}", bw);
+
+                            } else {
+                                log.info("更新质量定时任务提交失败");
+                            }
+                        }
+                        rs.close();
+                        statement.close();
+                    } catch (SQLException | IOException e) {
+                        log.error("提交更新质量时, HTTP连接失败");
+                    }
+                }
+
+            }, 10 * 1000, 10 * 1000);
+        }
+    }
+
+    public static void stop() {
+        if (timer != null) {
+            timer.cancel();
+            timer = null;
+        }
+    }
+}

+ 60 - 0
src/com/mes/util/WorkTimer.java

@@ -0,0 +1,60 @@
+package com.mes.util;
+
+import com.mes.ui.DataUtil;
+import com.mes.ui.MesClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.awt.*;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class WorkTimer {
+    private static final Logger log = LoggerFactory.getLogger(WorkTimer.class);
+    private static Timer timer1 = null;
+
+    private WorkTimer() {
+    }
+
+    public static void start() {
+        if (timer1 == null) {
+            timer1 = new Timer();
+            timer1.schedule(new TimerTask() {
+                @Override
+                public void run() {
+                    try {
+                        // 提交结果
+                        if (MesClient.work_status == 1 && S7Util.readIsComplete()) {
+                            String sn = MesClient.getBarcode33(MesClient.product_sn.getText());
+                            DataUtil.sendQuality(sn, "OK", MesClient.user20);
+                            MesClient.resetScanA();
+                            MesClient.setMenuStatus("结果提交成功,请扫下一件", 0);
+                            MesClient.scanBarcode();
+                        }
+//                        // 禁止启动, 重置完成反馈
+//                        if (!MesClient.check_quality_result && MesClient.work_status == 0) {
+//                            S7Util.disable();
+//                            S7Util.writeIsComplete(false);
+//                        }
+
+//                        if (MesClient.work_status == 1 && S7Util.readIsRunning()) {
+//                            log.info("工件在加工");
+//                        }
+
+
+                    } catch (Exception e) {
+                        log.info("OP250工作逻辑定时器运行报错");
+                    }
+                }
+
+            }, 5000, 3000);
+        }
+    }
+
+    public static void stop() {
+        if (timer1 != null) {
+            timer1.cancel();
+            timer1 = null;
+        }
+    }
+}

+ 9 - 0
src/resources/config/config.properties

@@ -0,0 +1,9 @@
+mes.gw=OP210A
+#mes.server_ip=127.0.0.1
+mes.server_ip=192.168.21.99
+mes.tcp_port=3000
+
+mes.heart_beat_cycle=60
+
+mes.line_sn=XT
+

+ 44 - 0
src/resources/logback.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+
+    <!-- 定义日志文件的存储位置及文件名 -->
+    <property name="LOG_HOME" value="D:/Logs"/>
+    <property name="PROJECT_NAME" value="OP250"/>
+
+    <!-- 控制台输出 -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level  %logger{36} - %msg%n</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+    </appender>
+
+    <!-- 文件输出 -->
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/${PROJECT_NAME}/${PROJECT_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${PROJECT_NAME}/archived/${PROJECT_NAME}_%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 保留最近 6个月内的日志-->
+            <maxHistory>180</maxHistory>  <!-- 如果删除该项配置,则logback无法自动删除旧日志, 导致totalSizeCap也将失去作用-->
+            <!-- 滚动文件总大小不超过2GB-->
+            <totalSizeCap>1GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level  %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 根Logger -->
+    <root level="info">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE" />
+    </root>
+
+    <logger name="org.slf4j" level="ERROR"/>
+    <logger name="ch.qos.logback" level="ERROR"/>
+    <logger name="ch.qos.logback.classic.joran.action.ConfigurationAction" level="OFF"/>
+
+</configuration>