dzc hai 1 semana
pai
achega
54f3a88b7f

+ 0 - 1
.classpath

@@ -16,7 +16,6 @@
 	<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"/>

+ 864 - 0
_field_comment_GAP_REPORT.md

@@ -0,0 +1,864 @@
+# Java class-field Chinese comment gap report
+
+Scanned 55 .java files under src. Rule: class member fields/constants need Chinese in // trailing or /** */ / // above.
+
+## Summary: 71/385 fields have Chinese comments; **314 missing**.
+
+### Files with good / partial coverage (already have some Chinese comments)
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\ProtocolParam.java` — 1/2 commented, 1 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\XDecoder.java` — 3/4 commented, 1 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\LoginFarme.java` — 2/6 commented, 4 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\MesClient.java` — 16/132 commented, 116 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ATEQ.java` — 20/24 commented, 4 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\DCW.java` — 4/5 commented, 1 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\DateLocalUtils.java` — 3/5 commented, 2 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\IR.java` — 4/5 commented, 1 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\InsulationParam.java` — 4/7 commented, 3 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\JdbcUtils.java` — 1/4 commented, 3 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\SerialPortUtils.java` — 1/11 commented, 10 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\QmCurUtil.java` — 4/5 commented, 1 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtDecoderServer.java` — 2/5 commented, 3 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtEncoderServer.java` — 2/3 commented, 1 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtNettyClient.java` — 3/9 commented, 6 missing
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtNettyClientHandler.java` — 1/7 commented, 6 missing
+
+### Files with fields but zero Chinese comments
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\component\CallFromJs.java` — 0/1
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\component\MesRadio.java` — 0/3
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\component\MesWebView.java` — 0/3
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\MesMsgUtils.java` — 0/13
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\NettyClient.java` — 0/3
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\NettyClientHandler.java` — 0/3
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\BindMaterialResp.java` — 0/6
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\ConfigParam.java` — 0/27
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\DataUtil.java` — 0/1
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\ExportUtil.java` — 0/1
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\LockUtil.java` — 0/4
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\PrintExample.java` — 0/2
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\QmData.java` — 0/5
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\TableCellEditorButton.java` — 0/2
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\CommonQmDevice.java` — 0/7
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\Config.java` — 0/9
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\HttpUtils.java` — 0/1
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\PrintUtil.java` — 0/1
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\SerialAteqUtil.java` — 0/4
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\SerialUtil.java` — 0/4
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\TaskConetnt.java` — 0/3
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\TaskParam.java` — 0/8
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\TestParam.java` — 0/15
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\WorkTimer.java` — 0/3
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\QmResultUtil.java` — 0/21
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtUtil.java` — 0/1
+
+### Files with no class-level fields detected
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\component\MyDialog.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\CenterRenderer.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\CustomPrintExample.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\MesRevice.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\OprnoUtil.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\TableCellRendererButton.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\Test.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\Test2.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\TextPrinterExample.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\Base64Utils.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\CommonUtils.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\DataUtils.java`
+- `C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ErrorMsg.java`
+
+---
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\component\CallFromJs.java
+Coverage: 0/1
+
+- L8: `public static final Logger log =  LoggerFactory.getLogger(CallFromJs.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\component\MesRadio.java
+Coverage: 0/3
+
+- L13: `public static final Logger log =  LoggerFactory.getLogger(MesRadio.class);`
+  - 建议注释: 日志记录器
+- L15: `private String result = "";`
+  - 建议注释: 测试/业务结果
+- L16: `private Integer i = 0;`
+  - 建议注释: 内部计数器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\component\MesWebView.java
+Coverage: 0/3
+
+- L19: `public static final Logger log =  LoggerFactory.getLogger(MesWebView.class);`
+  - 建议注释: 日志记录器
+- L21: `public static WebEngine engine = null;`
+  - 建议注释: JavaFX Web引擎
+- L23: `public static WebView webView = null;`
+  - 建议注释: JavaFX Web视图
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\MesMsgUtils.java
+Coverage: 0/13
+
+- L5: `public static int SYNR_LEN = 46;`
+  - 建议注释: SYNR报文长度
+- L6: `public static int AXTW_LEN = 46;`
+  - 建议注释: AXTW报文长度
+- L7: `public static int ACLW_LEN = 46;`
+  - 建议注释: ACLW报文长度
+- L8: `public static int MCJW_LEN = 96;`
+  - 建议注释: MCJW报文长度
+- L9: `public static int AQDW_LEN = 96;`
+  - 建议注释: AQDW报文长度
+- L10: `public static int MBDW_LEN = 96;`
+  - 建议注释: MBDW报文长度
+- L11: `public static int MJBW_LEN = 96;`
+  - 建议注释: MJBW报文长度
+- L12: `public static int MQDW_LEN = 96;`
+  - 建议注释: MQDW报文长度
+- L13: `public static int MKSW_LEN = 96;`
+  - 建议注释: MKSW报文长度
+- L14: `public static int MSBW_LEN = 96;`
+  - 建议注释: MSBW报文长度
+- L15: `public static int MCSW_LEN = 96;`
+  - 建议注释: MCSW报文长度
+- L16: `public static int AQRW_LEN = 96;`
+  - 建议注释: AQRW报文长度
+- L18: `public static String MSG_TYPE[] = { /         "SYNR", /         "AXTW", /         "ACLW", /         "MCJW", /         "AQDW", /         "MBDW", /         "MJBW", /         "MQDW", /         "MKSW", /         "MSBW", /         "MCSW", /         "AQRW", /     };`
+  - 建议注释: 报文类型列表
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\NettyClient.java
+Coverage: 0/3
+
+- L17: `public static final Logger log =  LoggerFactory.getLogger(NettyClientHandler.class);`
+  - 建议注释: 日志记录器
+- L18: `public SocketChannel socketChannel;`
+  - 建议注释: Socket通道
+- L19: `public static ChannelFuture future;`
+  - 建议注释: 通道Future
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\NettyClientHandler.java
+Coverage: 0/3
+
+- L17: `public static final Logger log =  LoggerFactory.getLogger(NettyClientHandler.class);`
+  - 建议注释: 日志记录器
+- L19: `private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");`
+  - 建议注释: 日期时间格式化器
+- L20: `public static byte[] responseByte;`
+  - 建议注释: 响应字节缓存
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\ProtocolParam.java
+Coverage: 1/2
+
+- L9: `public static final Logger log =  LoggerFactory.getLogger(ProtocolParam.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\netty\XDecoder.java
+Coverage: 3/4
+
+- L15: `public static final Logger log =  LoggerFactory.getLogger(XDecoder.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\BindMaterialResp.java
+Coverage: 0/6
+
+- L4: `private String materialId;`
+  - 建议注释: 物料ID
+- L5: `private String materialTitle;`
+  - 建议注释: 物料名称
+- L6: `private String craft;`
+  - 建议注释: 工艺
+- L7: `private String batchSn;`
+  - 建议注释: 批次号
+- L8: `private String lastTimes;`
+  - 建议注释: 剩余可用次数
+- L9: `private String type;`
+  - 建议注释: 类型
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\ConfigParam.java
+Coverage: 0/27
+
+- L4: `public Integer id;`
+  - 建议注释: 主键ID
+- L5: `public String programNo;`
+  - 建议注释: 程序号
+- L6: `public String startMode;`
+  - 建议注释: 启动模式
+- L7: `public String serialPort;`
+  - 建议注释: 串口号/设备地址
+- L8: `public String baudRate;`
+  - 建议注释: 波特率/端口
+- L9: `public String dataBits;`
+  - 建议注释: 数据位
+- L10: `public String checkBit;`
+  - 建议注释: 校验位
+- L11: `public String stopBit;`
+  - 建议注释: 停止位
+- L12: `public String leakage;`
+  - 建议注释: 泄漏检测配置
+- L13: `public String printLabel;`
+  - 建议注释: 是否打印标签
+- L14: `public String printName;`
+  - 建议注释: 打印机名称
+- L15: `public String labelName;`
+  - 建议注释: 标签模板名
+- L16: `public String labelx;`
+  - 建议注释: 标签X坐标
+- L17: `public String labely;`
+  - 建议注释: 标签Y坐标
+- L18: `public String labelLineSpace;`
+  - 建议注释: 标签行间距
+- L19: `public String labelFont;`
+  - 建议注释: 标签字体
+- L20: `public String productSnPre;`
+  - 建议注释: 产品条码前缀
+- L21: `public String productSnLength;`
+  - 建议注释: 产品条码长度
+- L22: `public String device;`
+  - 建议注释: 设备类型
+- L23: `public String ngTime;`
+  - 建议注释: NG判定时间
+- L24: `public String ngNumber;`
+  - 建议注释: NG数量阈值
+- L25: `public String ngUpgradeTime;`
+  - 建议注释: NG升级时间
+- L26: `public String oprno;`
+  - 建议注释: 工序号
+- L27: `public String oprnoTitle;`
+  - 建议注释: 工序名称
+- L28: `public String lineSn;`
+  - 建议注释: 产线编号
+- L29: `public String task;`
+  - 建议注释: 任务标识
+- L30: `public String stationNo;`
+  - 建议注释: 工位号
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\DataUtil.java
+Coverage: 0/1
+
+- L22: `public static final Logger log =  LoggerFactory.getLogger(DataUtil.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\ExportUtil.java
+Coverage: 0/1
+
+- L17: `public static final Logger log =  LoggerFactory.getLogger(ExportUtil.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\LockUtil.java
+Coverage: 0/4
+
+- L10: `private FileChannel channel;`
+  - 建议注释: 文件通道
+- L12: `private FileLock lock;`
+  - 建议注释: 文件锁
+- L14: `private File file;`
+  - 建议注释: 锁文件
+- L16: `private static LockUtil instance = null;`
+  - 建议注释: 单例实例
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\LoginFarme.java
+Coverage: 2/6
+
+- L19: `public static JTextField userNameTxt;`
+  - 建议注释: 用户名输入框
+- L20: `public static JPasswordField userPasswordTxt;`
+  - 建议注释: 密码输入框
+- L21: `static JButton loginButton = new JButton("用户密码登录");`
+  - 建议注释: 密码登录按钮
+- L22: `static JButton scanLoginButton = new JButton("扫  码  登  录");`
+  - 建议注释: 扫码登录按钮
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\MesClient.java
+Coverage: 16/132
+
+- L34: `public static final Logger log =  LoggerFactory.getLogger(MesClient.class);`
+  - 建议注释: 日志记录器
+- L36: `private static String Drivde = "org.sqlite.JDBC";`
+  - 建议注释: JDBC驱动类名
+- L44: `public static int mes_heart_icon_cycle = 1;`
+  - 建议注释: 心跳图标切换周期(秒)
+- L55: `public static String sessionid = "";`
+  - 建议注释: 会话ID
+- L57: `public static JPanel contentPane;`
+  - 建议注释: 主内容面板
+- L58: `public static MesClient mesClientFrame;`
+  - 建议注释: 主窗口实例
+- L59: `public static JTabbedPane tabbedPane;`
+  - 建议注释: 选项卡面板
+- L60: `public static JScrollPane indexScrollPaneA;`
+  - 建议注释: 首页滚动面板
+- L61: `public static JScrollPane searchScrollPane;`
+  - 建议注释: 查询滚动面板
+- L62: `public static JScrollPane searchScrollPaneD;`
+  - 建议注释: 查询面板D滚动容器
+- L63: `public static JScrollPane searchScrollPaneDj;`
+  - 建议注释: 点检滚动面板
+- L64: `public static JScrollPane searchScrollPaneTask;`
+  - 建议注释: 任务滚动面板
+- L66: `public static Boolean check_quality_result = false;`
+  - 建议注释: 质量结果校验标志
+- L67: `public static Integer work_status = 0;`
+  - 建议注释: 当前作业状态
+- L69: `public static JButton heart_beat_menu;`
+  - 建议注释: 心跳状态菜单按钮
+- L70: `public static JButton status_menu;`
+  - 建议注释: 状态菜单按钮
+- L71: `public static JButton user_menu;`
+  - 建议注释: 用户菜单按钮
+- L73: `public static int scan_type = 0;`
+  - 建议注释: 扫码类型
+- L74: `public static JButton finish_ok_bt;`
+  - 建议注释: OK完成按钮
+- L75: `public static JButton finish_ng_bt;`
+  - 建议注释: NG完成按钮
+- L76: `public static JTextField product_sn;`
+  - 建议注释: 产品条码输入框
+- L77: `public static JButton f_scan_data_bt_1;`
+  - 建议注释: 扫码操作按钮
+- L79: `public static String user20 = "";`
+  - 建议注释: 当前登录用户工号
+- L82: `public static JFrame welcomeWin;`
+  - 建议注释: 欢迎/登录窗口
+- L84: `public static JPanel indexPanelB;`
+  - 建议注释: 首页面板B
+- L85: `public static MesWebView jfxPanel = null;`
+  - 建议注释: 内嵌Web视图1
+- L86: `public static JPanel indexPanelC;`
+  - 建议注释: 首页面板C
+- L87: `public static JPanel indexPanelD;`
+  - 建议注释: 首页面板D
+- L88: `public static MesWebView jfxPanel2 = null;`
+  - 建议注释: 内嵌Web视图2
+- L89: `public static MesWebView jfxPanel3 = null;`
+  - 建议注释: 内嵌Web视图3
+- L90: `public static MesRadio mesRadioHj;`
+  - 建议注释: 单选组件
+- L92: `public static JLabel curTaskName;`
+  - 建议注释: 当前任务名称标签
+- L94: `public static JTable table;`
+  - 建议注释: 气密结果表格
+- L95: `public static Object[] columnNames = {"工件码", "测试日期", "压力", "泄露值","结果"};`
+  - 建议注释: 结果表列名
+- L103: `public static Object[][] rowData = new Object[12][5];`
+  - 建议注释: 结果表行数据
+- L104: `public static JLabel pageLabel;`
+  - 建议注释: 分页页码标签
+- L109: `public static JTable bindTable;`
+  - 建议注释: 物料绑定表格
+- L110: `public static Object[] bindColumnNames = { "物料名称", "绑定批次", "剩余次数", "操作" };`
+  - 建议注释: 绑定表列名
+- L111: `public static Object[][] bindRowData = null;`
+  - 建议注释: 绑定表行数据
+- L113: `public static JTable table2;`
+  - 建议注释: 任务列表表格
+- L114: `public static Object[] columnNames2 = { "任务名称" };`
+  - 建议注释: 任务表列名
+- L115: `public static Object[][] rowData2 = {{""},{""},{""}};`
+  - 建议注释: 任务表行数据
+- L117: `public static JTable materialTable;`
+  - 建议注释: 物料表格
+- L118: `public static Object[] materialColumnNames = { "物料名称", "绑定批次", "剩余次数", "操作" };`
+  - 建议注释: 物料表列名
+- L119: `public static Object[][] materialRowData = null;`
+  - 建议注释: 物料表行数据
+- L121: `public static Integer tjFlag = 0;`
+  - 建议注释: 提交/运行状态标志
+- L123: `public static String tjFlagText2 = "设备运行中";`
+  - 建议注释: 状态文案:设备运行中
+- L125: `public static String tjFlagText3 = "设备运行结束";`
+  - 建议注释: 状态文案:设备运行结束
+- L127: `public static String tjFlagText4 = "结果已上传MES,请扫下一件";`
+  - 建议注释: 状态文案:结果已上传
+- L129: `public static String tjFlagText5 = "已扫码,等待设备运行";`
+  - 建议注释: 状态文案:已扫码等待运行
+- L131: `public static String tjFlagTextErr = "结果上传MES失败,请重试";`
+  - 建议注释: 状态文案:上传失败
+- L133: `public static CommonQmDevice commonQmDevice;`
+  - 建议注释: 气密设备统一入口
+- L134: `public static SerialPortUtils serialPortUtils;`
+  - 建议注释: 串口工具实例
+- L135: `public static Integer mesTjFlag = 0;`
+  - 建议注释: MES提交标志
+- L136: `public static Integer workstop = 0;`
+  - 建议注释: 作业停止标志
+- L137: `public static String lastQmPressure = "";`
+  - 建议注释: 最近一次压力值
+- L138: `public static String lastQmLeak = "";`
+  - 建议注释: 最近一次泄漏值
+- L139: `public static JTextField printSn2;`
+  - 建议注释: 补打条码输入框
+- L140: `public static JTextField printTitle2;`
+  - 建议注释: 补打标题输入框
+- L141: `public static JTextField printValue2;`
+  - 建议注释: 补打数值输入框
+- L142: `public static JButton printBtn2;`
+  - 建议注释: 补打按钮
+- L143: `public static ConfigParam configParam;`
+  - 建议注释: 工位配置参数
+- L144: `public static Integer isConfigEdit = 0;`
+  - 建议注释: 配置是否可编辑标志
+- L145: `public static Integer mesStartFlag = 0;`
+  - 建议注释: MES流程启动标志
+- L147: `public static List<TaskParam> taskParamList = new ArrayList<>();`
+  - 建议注释: 任务参数列表
+- L148: `public static TaskParam curTaskParam = null;`
+  - 建议注释: 当前选中任务参数
+- L193: `public static Timer cjTimerText;`
+  - 建议注释: 扫码框焦点保持定时器
+- L208: `public static java.util.Timer dateBeatTimer;`
+  - 建议注释: 日期/心跳显示定时器
+- L274: `public static java.util.Timer heartBeatIconTimer;`
+  - 建议注释: 心跳图标闪烁定时器
+- L275: `public static boolean iconREDFlag = true;`
+  - 建议注释: 心跳图标切换标志
+- L374: `public static JTextField param1;`
+  - 建议注释: 参数1显示/输入
+- L375: `public static JTextField param2;`
+  - 建议注释: 参数2显示/输入
+- L376: `public static JTextField param3;`
+  - 建议注释: 参数3显示/输入
+- L377: `public static JTextField param4;`
+  - 建议注释: 参数4显示/输入
+- L378: `public static JLabel result;`
+  - 建议注释: 测试/业务结果
+- L379: `public static JTextField programNo;`
+  - 建议注释: 程序号
+- L380: `public static JTextField serialPort;`
+  - 建议注释: 串口号/设备地址
+- L381: `public static JTextField baudRate;`
+  - 建议注释: 波特率/端口
+- L382: `public static JTextField printName;`
+  - 建议注释: 打印机名称
+- L383: `public static JTextField labelName;`
+  - 建议注释: 标签模板名
+- L384: `public static JTextField labelx;`
+  - 建议注释: 标签X坐标
+- L385: `public static JTextField labely;`
+  - 建议注释: 标签Y坐标
+- L386: `public static JTextField labelLineSpace;`
+  - 建议注释: 标签行间距
+- L387: `public static JTextField labelFont;`
+  - 建议注释: 标签字体
+- L388: `public static JTextField stationNo;`
+  - 建议注释: 工位号
+- L389: `public static JComboBox stopBit;`
+  - 建议注释: 停止位
+- L390: `public static JComboBox checkBit;`
+  - 建议注释: 校验位
+- L391: `public static JComboBox dataBits;`
+  - 建议注释: 数据位
+- L392: `public static JComboBox printLabel;`
+  - 建议注释: 是否打印标签
+- L393: `public static JComboBox leakage;`
+  - 建议注释: 泄漏检测配置
+- L394: `public static JComboBox startMode;`
+  - 建议注释: 启动模式
+- L395: `public static JButton saveBtn;`
+  - 建议注释: 保存配置按钮
+- L396: `public static JTextField productSnLength;`
+  - 建议注释: 产品条码长度
+- L397: `public static JTextField productSnPre;`
+  - 建议注释: 产品条码前缀
+- L398: `public static JComboBox device;`
+  - 建议注释: 设备类型
+- L399: `public static JTextField ngTime;`
+  - 建议注释: NG判定时间
+- L400: `public static JTextField ngNumber;`
+  - 建议注释: NG数量阈值
+- L401: `public static JTextField ngUpgradeTime;`
+  - 建议注释: NG升级时间
+- L402: `public static JTextField oprno;`
+  - 建议注释: 工序号
+- L403: `public static JTextField oprnoTitle;`
+  - 建议注释: 工序名称
+- L404: `public static JTextField lineSn;`
+  - 建议注释: 产线编号
+- L406: `public static JLabel taskName;`
+  - 建议注释: 任务名称标签
+- L407: `public static JTextField taskMaxNumA;`
+  - 建议注释: 任务A最大数量
+- L408: `public static JTextField taskMaxFoutA;`
+  - 建议注释: 任务A最大一次输出
+- L409: `public static JTextField taskMinFoutA;`
+  - 建议注释: 任务A最小一次输出
+- L410: `public static JTextField taskMaxSoutA;`
+  - 建议注释: 任务A最大二次输出
+- L411: `public static JTextField taskMinSoutA;`
+  - 建议注释: 任务A最小二次输出
+- L412: `public static JTextField taskMaxNumB;`
+  - 建议注释: 任务B最大数量
+- L413: `public static JTextField taskMaxFoutB;`
+  - 建议注释: 任务B最大一次输出
+- L414: `public static JTextField taskMinFoutB;`
+  - 建议注释: 任务B最小一次输出
+- L415: `public static JTextField taskMaxSoutB;`
+  - 建议注释: 任务B最大二次输出
+- L416: `public static JTextField taskMinSoutB;`
+  - 建议注释: 任务B最小二次输出
+- L417: `public static JComboBox taskLeakage;`
+  - 建议注释: 任务泄漏参数
+- L419: `public static JTextField barcodeSpec;`
+  - 建议注释: 条码规格
+- L420: `public static JTextField barcodeSpecStart;`
+  - 建议注释: 条码规格起始位置
+- L421: `public static JTextField barcodeLength;`
+  - 建议注释: 条码长度
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\PrintExample.java
+Coverage: 0/2
+
+- L9: `private JButton printButton;`
+  - 建议注释: 按钮控件
+- L39: `private Component component;`
+  - 建议注释: component(待补充中文注释)
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\QmData.java
+Coverage: 0/5
+
+- L4: `private String sn;`
+  - 建议注释: 序列号/工件码
+- L5: `private String createTime;`
+  - 建议注释: 创建时间
+- L6: `private String param1;`
+  - 建议注释: 参数1显示/输入
+- L7: `private String param2;`
+  - 建议注释: 参数2显示/输入
+- L8: `private String result;`
+  - 建议注释: 测试/业务结果
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\ui\TableCellEditorButton.java
+Coverage: 0/2
+
+- L13: `public static final Logger log =  LoggerFactory.getLogger(TableCellEditorButton.class);`
+  - 建议注释: 日志记录器
+- L14: `private JButton btn;`
+  - 建议注释: btn(待补充中文注释)
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ATEQ.java
+Coverage: 20/24
+
+- L10: `private static final Logger log = LoggerFactory.getLogger(ATEQ.class);`
+  - 建议注释: 日志记录器
+- L119: `public final Boolean isKeyExist;                  //`
+  - 建议注释: 按键是否存在
+- L203: `public final Boolean isTestLeak;`
+  - 建议注释: 是否测试泄漏
+- L204: `public final Boolean isReferLeak;`
+  - 建议注释: 是否参考泄漏
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\CommonQmDevice.java
+Coverage: 0/7
+
+- L17: `public static final Logger log = LoggerFactory.getLogger(CommonQmDevice.class);`
+  - 建议注释: 日志记录器
+- L18: `public String device;`
+  - 建议注释: 设备类型
+- L19: `public SerialPortUtils serialPortUtils;`
+  - 建议注释: 串口工具实例
+- L20: `public YtNettyClient ytClient;`
+  - 建议注释: 英泰气密Netty客户端
+- L21: `public boolean isOnline;`
+  - 建议注释: 设备在线状态
+- L22: `ConfigParam configParam;`
+  - 建议注释: 工位配置参数
+- L23: `public Timer workTimer;`
+  - 建议注释: 作业/轮询定时器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\Config.java
+Coverage: 0/9
+
+- L16: `private static final Logger log = LoggerFactory.getLogger(Config.class);`
+  - 建议注释: 日志记录器
+- L18: `public static final String line_sn;`
+  - 建议注释: 产线编号
+- L19: `public static final String gw_1;`
+  - 建议注释: 工位号
+- L20: `public static final String gw_des_1;`
+  - 建议注释: 工位描述
+- L22: `public static final String server_ip;`
+  - 建议注释: 服务器IP
+- L23: `public static final Integer tcp_port;`
+  - 建议注释: TCP端口
+- L24: `public static final Integer heart_beat_cycle;`
+  - 建议注释: 心跳周期(秒)
+- L25: `public static final Integer heart_icon_cycle = 1;`
+  - 建议注释: 心跳图标周期
+- L27: `public static final String portName;`
+  - 建议注释: 串口名
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\DCW.java
+Coverage: 4/5
+
+- L5: `public String description = "直流耐压";`
+  - 建议注释: 描述
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\DateLocalUtils.java
+Coverage: 3/5
+
+- L8: `public static SimpleDateFormat DATA_FORMAT1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");`
+  - 建议注释: 日期格式(含毫秒)
+- L9: `public static SimpleDateFormat DATA_FORMAT11 = new SimpleDateFormat("yyyyMMddHHmmss");`
+  - 建议注释: 日期格式(紧凑)
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\HttpUtils.java
+Coverage: 0/1
+
+- L13: `public static final Logger log =  LoggerFactory.getLogger(HttpUtils.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\IR.java
+Coverage: 4/5
+
+- L5: `public String description = "绝缘电阻";`
+  - 建议注释: 描述
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\InsulationParam.java
+Coverage: 4/7
+
+- L5: `public String type;`
+  - 建议注释: 类型
+- L6: `public String description;`
+  - 建议注释: 描述
+- L11: `public String result;`
+  - 建议注释: 测试/业务结果
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\JdbcUtils.java
+Coverage: 1/4
+
+- L18: `public static final Logger log =  LoggerFactory.getLogger(JdbcUtils.class);`
+  - 建议注释: 日志记录器
+- L21: `public static String Drivde="org.sqlite.JDBC";`
+  - 建议注释: JDBC驱动类名
+- L22: `public static String DATABASE_URL="jdbc:sqlite:mes_db.db";`
+  - 建议注释: SQLite数据库URL
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\PrintUtil.java
+Coverage: 0/1
+
+- L19: `public static final Logger log =  LoggerFactory.getLogger(PrintUtil.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\SerialAteqUtil.java
+Coverage: 0/4
+
+- L13: `private static final Logger log = LoggerFactory.getLogger(SerialUtil.class);`
+  - 建议注释: 日志记录器
+- L15: `public static SerialPort serialPort;`
+  - 建议注释: 串口号/设备地址
+- L16: `private static final byte[] buffer = new byte[1024* 5];`
+  - 建议注释: 串口接收缓冲区
+- L17: `private static int bufferEnd = 0;`
+  - 建议注释: 缓冲区有效数据末尾下标
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\SerialPortUtils.java
+Coverage: 1/11
+
+- L21: `public static final Logger log =  LoggerFactory.getLogger(SerialPortUtils.class);`
+  - 建议注释: 日志记录器
+- L22: `public SerialPort serialPort;`
+  - 建议注释: 串口号/设备地址
+- L23: `public String portName;`
+  - 建议注释: 串口名
+- L24: `public boolean isOpen;`
+  - 建议注释: 串口是否已打开
+- L26: `public String oprno;`
+  - 建议注释: 工序号
+- L27: `public String oprnoName;`
+  - 建议注释: 工序名称
+- L28: `public StringBuilder dataBuilder ;`
+  - 建议注释: 串口数据拼接缓冲
+- L29: `private static final byte[] buffer = new byte[1024* 5];`
+  - 建议注释: 串口接收缓冲区
+- L30: `private static int bufferEnd = 0;`
+  - 建议注释: 缓冲区有效数据末尾下标
+- L31: `public String device;`
+  - 建议注释: 设备类型
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\SerialUtil.java
+Coverage: 0/4
+
+- L13: `private static final Logger log = LoggerFactory.getLogger(SerialUtil.class);`
+  - 建议注释: 日志记录器
+- L15: `public SerialPort serialPort;`
+  - 建议注释: 串口号/设备地址
+- L16: `private final byte[] buffer = new byte[1024 * 5];`
+  - 建议注释: 串口接收缓冲区
+- L17: `private int bufferEnd = 0;`
+  - 建议注释: 缓冲区有效数据末尾下标
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\TaskConetnt.java
+Coverage: 0/3
+
+- L5: `public String taskProgramNo;`
+  - 建议注释: 任务程序号
+- L6: `public String taskLabelName;`
+  - 建议注释: 任务标签名
+- L7: `public String taskLeakage;`
+  - 建议注释: 任务泄漏参数
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\TaskParam.java
+Coverage: 0/8
+
+- L5: `public Integer id;`
+  - 建议注释: 主键ID
+- L6: `public String title;`
+  - 建议注释: 标题
+- L7: `public String barcodeSpec;`
+  - 建议注释: 条码规格
+- L8: `public String barcodeSpecStart;`
+  - 建议注释: 条码规格起始位置
+- L9: `public String barcodeLength;`
+  - 建议注释: 条码长度
+- L10: `public String taskProgramNo;`
+  - 建议注释: 任务程序号
+- L11: `public String taskLabelName;`
+  - 建议注释: 任务标签名
+- L12: `public String taskLeakage;`
+  - 建议注释: 任务泄漏参数
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\TestParam.java
+Coverage: 0/15
+
+- L5: `public Integer id;`
+  - 建议注释: 主键ID
+- L6: `public String sn;`
+  - 建议注释: 序列号/工件码
+- L7: `public String ucode;`
+  - 建议注释: 唯一码
+- L8: `public String lineSn;`
+  - 建议注释: 产线编号
+- L9: `public String oprno;`
+  - 建议注释: 工序号
+- L10: `public String oprnoTitle;`
+  - 建议注释: 工序名称
+- L11: `public String createTime;`
+  - 建议注释: 创建时间
+- L12: `public String param1;`
+  - 建议注释: 参数1显示/输入
+- L13: `public String param2;`
+  - 建议注释: 参数2显示/输入
+- L14: `public String param3;`
+  - 建议注释: 参数3显示/输入
+- L15: `public String param4;`
+  - 建议注释: 参数4显示/输入
+- L16: `public String param5;`
+  - 建议注释: param5(待补充中文注释)
+- L17: `public String result;`
+  - 建议注释: 测试/业务结果
+- L18: `public String remark;`
+  - 建议注释: 备注
+- L19: `public String deviceType;`
+  - 建议注释: 设备类型
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\WorkTimer.java
+Coverage: 0/3
+
+- L14: `private static final Logger log = LoggerFactory.getLogger(WorkTimer.class);`
+  - 建议注释: 日志记录器
+- L17: `private static Timer stopTimer = null;`
+  - 建议注释: 停止作业定时器
+- L18: `private static Timer workTimer = null;`
+  - 建议注释: 作业/轮询定时器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\QmCurUtil.java
+Coverage: 4/5
+
+- L7: `public static final Logger log =  LoggerFactory.getLogger(QmCurUtil.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\QmResultUtil.java
+Coverage: 0/21
+
+- L12: `public static final Logger log = LoggerFactory.getLogger(QmResultUtil.class);`
+  - 建议注释: 日志记录器
+- L14: `public final String num;`
+  - 建议注释: 序号
+- L15: `public final String testDate;`
+  - 建议注释: 测试日期
+- L16: `public final String sn;`
+  - 建议注释: 序列号/工件码
+- L17: `public final String resultType;`
+  - 建议注释: 结果类型
+- L18: `public final String result;`
+  - 建议注释: 测试/业务结果
+- L19: `public final String programNumber;`
+  - 建议注释: 程序编号
+- L20: `public final String pressureValue;`
+  - 建议注释: 压力值
+- L21: `public final String leakValue;`
+  - 建议注释: 泄漏值
+- L22: `public final String pressureUnit;`
+  - 建议注释: 压力单位
+- L23: `public final String leakUnit;`
+  - 建议注释: 泄漏单位
+- L247: `String num = "";`
+  - 建议注释: 序号
+- L248: `String testDate = "";`
+  - 建议注释: 测试日期
+- L249: `String sn = "";`
+  - 建议注释: 序列号/工件码
+- L250: `String resultType = "";`
+  - 建议注释: 结果类型
+- L251: `String result = "";`
+  - 建议注释: 测试/业务结果
+- L252: `String programNumber = "";`
+  - 建议注释: 程序编号
+- L253: `String pressureValue = "";`
+  - 建议注释: 压力值
+- L254: `String leakValue = "";`
+  - 建议注释: 泄漏值
+- L255: `String pressureUnit = "";`
+  - 建议注释: 压力单位
+- L256: `String leakUnit = "";`
+  - 建议注释: 泄漏单位
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtDecoderServer.java
+Coverage: 2/5
+
+- L19: `private final ByteBuf msgin = Unpooled.buffer();`
+  - 建议注释: 入站消息缓冲
+- L20: `private final Charset charset = Charset.forName("UTF-8");`
+  - 建议注释: 字符集
+- L22: `private static final Logger logger = LoggerFactory.getLogger(YtDecoderServer.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtEncoderServer.java
+Coverage: 2/3
+
+- L15: `private static final Logger logger = LoggerFactory.getLogger(YtEncoderServer.class);`
+  - 建议注释: 日志记录器
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtNettyClient.java
+Coverage: 3/9
+
+- L16: `public static final Logger log =  LoggerFactory.getLogger(YtNettyClientHandler.class);`
+  - 建议注释: 日志记录器
+- L17: `public static SocketChannel socketChannel;`
+  - 建议注释: Socket通道
+- L18: `public static ChannelFuture future;`
+  - 建议注释: 通道Future
+- L24: `public static String ip;`
+  - 建议注释: 服务器IP
+- L25: `public static int port;`
+  - 建议注释: 服务器端口
+- L27: `private static volatile boolean inited = false;`
+  - 建议注释: 是否已初始化
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtNettyClientHandler.java
+Coverage: 1/7
+
+- L20: `public static final Logger log = LoggerFactory.getLogger(YtNettyClientHandler.class);`
+  - 建议注释: 日志记录器
+- L24: `private static final double LEAK_OK_MAX = 2.5;`
+  - 建议注释: 泄漏合格上限
+- L26: `private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");`
+  - 建议注释: 日期时间格式化器
+- L27: `public static byte[] responseByte;`
+  - 建议注释: 响应字节缓存
+- L29: `private int timeoutNum = 0;`
+  - 建议注释: 当前超时次数
+- L30: `private int timeoutNumMax = 3;`
+  - 建议注释: 最大允许超时次数
+
+## C:\Users\dzc\IdeaProjects\mes-199-0Y7A-New\OP022\src\com\mes\util\ytnetty\YtUtil.java
+Coverage: 0/1
+
+- L9: `public static final Logger log =  LoggerFactory.getLogger(YtUtil.class);`
+  - 建议注释: 日志记录器

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2572 - 0
_field_comment_report_v2.json


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

@@ -1,6 +1,5 @@
 package com.mes.component;
 
-import com.mes.netty.ProtocolParam;
 import javafx.application.Platform;
 import javafx.beans.value.ObservableValue;
 import javafx.concurrent.Worker;

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

@@ -1,90 +0,0 @@
-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;
-    }
-
-
-}

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

@@ -1,67 +0,0 @@
-package com.mes.netty;
-
-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(MesClient.mes_server_ip,MesClient.mes_tcp_port);
-
-        //连接
-        future = bootstrap.connect();
-        log.info("客户端正在连接服务端...");
-        //客户端断线重连逻辑
-        future.addListener((ChannelFutureListener) future1 -> {
-            if (future1.isSuccess()) {
-                //tcp连接成功
-                MesClient.tcp_connect_flag = true;
-                //设置TCP请求状态
-                MesClient.connect_request_flag = false;
-                log.info("连接Netty服务端成功");
-                future.channel().writeAndFlush(msg);
-            } else {
-                //tcp连接失败
-                MesClient.tcp_connect_flag = false;
-                MesClient.connect_request_flag = true;
-                log.info("连接失败,进行断线重连");
-                future1.channel().eventLoop().schedule(() -> run(msg), 10, TimeUnit.SECONDS);
-            }
-            //设置tcp连接状态
-            MesClient.setTcpStatus();
-        });
-        socketChannel = (SocketChannel) future.channel();
-
-    }
-}

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

@@ -1,87 +0,0 @@
-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.error("close tcp, ip:" + channel.remoteAddress());
-        MesClient.tcp_connect_flag = false;
-        MesClient.setTcpStatus();
-        // 关闭通道
-        channel.close();
-    }
-
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        log.info("msg:"+msg);
-
-        String mes_msg = formatResult(msg.toString());
-        if(mes_msg == null || mes_msg.isEmpty()){ // error msg
-            return;
-        }
-
-        String msg_type = ProtocolParam.getMsgType(mes_msg);
-        log.info("msg_type="+msg_type);
-
-        String processMsgRet = MesMsgUtils.processMsg(mes_msg, msg_type);
-        log.info("processMsgRet="+processMsgRet);
-        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.error("length:" + msg.length() + " content:" + msg);
-        String msgType = msg.substring(0,2).trim();
-        if(msgType.equals("OK")){
-            return msg.substring(3,msg.length());
-        }else{
-            return "";
-        }
-    }
-
-}

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

@@ -1,103 +0,0 @@
-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);
-    }
-
-    /**
-     * 结果区前缀:5位格式为「工位号3位+状态2位」(如130QN),4位格式为 RS+状态(如RSQN)
-     */
-    public static String getLx(String msg){
-        String five = getFiveCharResultBlock(msg);
-        if(five != null){
-            return five.substring(0, 3).trim();
-        }
-        if(msg.length() < 72){
-            return "";
-        }
-        return msg.substring(70,72);
-    }
-
-    // 获取结果
-    public static String getResult(String msg){
-        String five = getFiveCharResultBlock(msg);
-        if(five != null){
-            return five.substring(3, 5).trim();
-        }
-        if(msg.length() < 74){
-            return "";
-        }
-        return msg.substring(72,74);
-    }
-
-    private static String getFiveCharResultBlock(String msg){
-        if(msg == null || msg.length() < 75){
-            return null;
-        }
-        String five = msg.substring(70, 75);
-        String code = five.substring(3, 5);
-        // 5位结果:xxxCC;4位 RSXX 紧跟 DA 时 five 末位是 D,code 不会命中
-        if(code.equals("QN") || code.equals("QD") || code.equals("UD")
-                || code.equals("NE") || code.equals("NN") || code.equals("OK")
-                || code.equals("NG") || code.equals("MT") || code.equals("BM")){
-            return five;
-        }
-        return null;
-    }
-
-    // 获取日期
-    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);
-    }
-
-}

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

@@ -1,172 +0,0 @@
-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();
-    }
-}

+ 148 - 191
src/com/mes/ui/DataUtil.java

@@ -1,12 +1,11 @@
 package com.mes.ui;
 
 import com.alibaba.fastjson2.JSONObject;
-import com.mes.netty.NettyClient;
+import com.mes.util.Base64Utils;
 import com.mes.util.DateLocalUtils;
+import com.mes.util.ErrorMsg;
 import com.mes.util.JdbcUtils;
 import com.mes.util.TestParam;
-import com.mes.util.Base64Utils;
-import java.util.Base64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -15,155 +14,126 @@ import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLEncoder;
+import java.util.Base64;
 import java.util.Properties;
 
 public class DataUtil {
 
-    public static final Logger log =  LoggerFactory.getLogger(DataUtil.class);
+    public static final Logger log = LoggerFactory.getLogger(DataUtil.class);
 
-    public static Boolean synrTcp(NettyClient nettyClient){
-        try{
-            //TCP连接后,直接先发同步报文
-            String start = "aaaabbbbbABW";
-            String msgType = "SYNR";
-            String gw = "GW"+DataUtil.rightPad(MesClient.getEffectiveOprno(), 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);
+    private static String getMesRecordApiUrl(String action) {
+        return "http://" + MesClient.mes_server_ip + ":8980/js/a/mes/mesProductRecord/" + action;
+    }
 
-            nettyClient.run(synr_str);
+    private static String buildCommonParams() throws UnsupportedEncodingException {
+        return "__ajax=json"
+                + "&oprno=" + URLEncoder.encode(MesClient.getEffectiveOprno().trim(), "UTF-8")
+                + "&lineSn=" + URLEncoder.encode(MesClient.getEffectiveLineSn().trim(), "UTF-8");
+    }
 
-            return true;
-        }catch (Exception e){
-            return false;
+    private static JSONObject parseJsonResponse(String result) {
+        if (result == null || result.trim().isEmpty() || result.equalsIgnoreCase("false")) {
+            return null;
+        }
+        try {
+            return JSONObject.parseObject(result);
+        } catch (Exception e) {
+            log.error("解析JSON响应失败: {}, 原始响应: {}", e.getMessage(), result);
+            return null;
         }
     }
 
-    public static Boolean heartBeat(NettyClient nettyClient){
-        try{
-            //TCP连接后,直接先发同步报文
-            String start = "aaaabbbbbABW";
-            String msgType = "AXTW";
-            String gw = "GW"+DataUtil.rightPad(MesClient.getEffectiveOprno(), 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);
+    /** 质量检查(替代 TCP AQDW) */
+    public static Boolean checkQuality(String sn, String user) {
+        try {
+            String url = getMesRecordApiUrl("checkQuality");
+            String params = buildCommonParams()
+                    + "&sn=" + URLEncoder.encode(sn, "UTF-8")
+                    + "&userCode=" + URLEncoder.encode(user != null ? user : "", "UTF-8");
+            String result = doPost(url, params);
+            JSONObject obj = parseJsonResponse(result);
+            if (obj == null) {
+                return false;
+            }
 
+            String checkret = obj.getString("data");
+            boolean success = "true".equalsIgnoreCase(String.valueOf(obj.get("result")));
+            if (success || "UD".equalsIgnoreCase(checkret)) {
+                MesClient.beginTestAfterScan();
+            } else {
+                MesClient.check_quality_result = false;
+                String lmsg = obj.getString("message");
+                if (lmsg == null || lmsg.isEmpty()) {
+                    lmsg = ErrorMsg.getErrorMsg(checkret != null ? checkret : "NE", "");
+                }
+                MesClient.setMenuStatus(lmsg, -1);
+            }
             return true;
-        }catch (Exception e){
+        } catch (Exception e) {
+            log.error("质量检查失败", 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){
+    public static Boolean startWork(String sn, String user) {
+        try {
+            String url = getMesRecordApiUrl("createProduct");
+            String params = buildCommonParams()
+                    + "&sn=" + URLEncoder.encode(sn, "UTF-8")
+                    + "&ucode=" + URLEncoder.encode(user != null ? user : "", "UTF-8");
+            JSONObject obj = parseJsonResponse(doPost(url, params));
+            return obj != null && "true".equalsIgnoreCase(String.valueOf(obj.get("result")));
+        } catch (Exception e) {
+            log.error("开工失败", 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(String sn, String user) {
+        return bindWarehouse(sn, user, user, "400001");
     }
 
-    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){
+    public static Boolean bindWarehouse(String sn, String wsn, String user, String craft) {
+        try {
+            String url = getMesRecordApiUrl("bindWarehouse");
+            String params = buildCommonParams()
+                    + "&sn=" + URLEncoder.encode(sn, "UTF-8")
+                    + "&wsn=" + URLEncoder.encode(wsn, "UTF-8")
+                    + "&ucode=" + URLEncoder.encode(user != null ? user : "", "UTF-8")
+                    + "&craft=" + URLEncoder.encode(craft != null ? craft : "", "UTF-8");
+            JSONObject obj = parseJsonResponse(doPost(url, params));
+            return obj != null && "true".equalsIgnoreCase(String.valueOf(obj.get("result")));
+        } catch (Exception e) {
+            log.error("物料绑定失败", 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){
+    public static Boolean unBindWarehouse(String sn, String wsn, String user, String craft) {
+        try {
+            String url = getMesRecordApiUrl("unBindWarehouse");
+            String params = buildCommonParams()
+                    + "&sn=" + URLEncoder.encode(sn, "UTF-8")
+                    + "&wsn=" + URLEncoder.encode(wsn, "UTF-8")
+                    + "&ucode=" + URLEncoder.encode(user != null ? user : "", "UTF-8")
+                    + "&craft=" + URLEncoder.encode(craft != null ? craft : "", "UTF-8");
+            JSONObject obj = parseJsonResponse(doPost(url, params));
+            return obj != null && "true".equalsIgnoreCase(String.valueOf(obj.get("result")));
+        } catch (Exception e) {
+            log.error("物料解绑失败", e);
             return false;
         }
     }
 
-    public static Boolean sendQuality(String sn,String result,String user){
-        try{
+    public static Boolean sendQuality(String sn, String result, String user) {
+        try {
             String msgType = "MQDW";
-            String craft = "100000";
-            String lx = "";
-            String paramNums = "00";
-            String params = "";
-
-            String gw = "GW"+rightPad(MesClient.getEffectiveOprno(), 6);
-            String start = "aaaabbbbbABW";
-            String gy = "GY" + rightPad(craft, 6);
-            String reslx = "LX" + rightPad(lx, 2);
-            String id = MesClient.getEffectiveLineSn() + 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("message="+aqdw_str);
-            JdbcUtils.insertData(gw, gy, aqdw_str, msgType, sn);
-            JdbcUtils.insertSubmitRecord(gw, sn, aqdw_str);
+            String gw = "GW" + rightPad(MesClient.getEffectiveOprno(), 6);
+            String gy = "GY100000";
+            JdbcUtils.insertData(gw, gy, "HTTP qmresult sn=" + sn + " result=" + result, msgType, sn);
+            JdbcUtils.insertSubmitRecord(gw, sn, "HTTP qmresult");
             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 gw = "GW"+rightPad(MesClient.getEffectiveOprno(), 6);
-            String start = "aaaabbbbbABW";
-            String gy = "GY" + rightPad(craft, 6);
-            String reslx = "LX" + rightPad(lx, 2);
-            String id = MesClient.getEffectiveLineSn() + 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("message="+aqdw_str);
-            JdbcUtils.insertData(gw, gy, aqdw_str, msgType, sn);
-            nettyClient.future.channel().writeAndFlush(aqdw_str);
-            return true;
-        }catch (Exception e){
+        } catch (Exception e) {
             return false;
         }
     }
@@ -174,116 +144,106 @@ public class DataUtil {
         }
 
         String strret = str;
-        if(str.length() > size){
-            strret = str.substring(0,size);
+        if (str.length() > size) {
+            strret = str.substring(0, size);
         }
-        return String.format("%-"+size+"s", strret);
+        return String.format("%-" + size + "s", strret);
     }
 
     public static JSONObject getBindMaterail() {
-        try{
+        try {
             String mes_server_ip = MesClient.mes_server_ip;
             String oprno = MesClient.getEffectiveOprno().trim();
             String lineSn = MesClient.getEffectiveLineSn().trim();
-            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesLineProcessMaterial/materials";
-            String params = "__ajax=json&oprno="+oprno+"&lineSn="+lineSn;
-            log.info("params="+params);
-            String result = doPost(url,params);
-            log.info("result="+result);
+            String url = "http://" + mes_server_ip + ":8980/js/a/mes/mesLineProcessMaterial/materials";
+            String params = "__ajax=json&oprno=" + oprno + "&lineSn=" + lineSn;
+            log.info("params=" + params);
+            String result = doPost(url, params);
+            log.info("result=" + result);
 
-            if(result.equalsIgnoreCase("false")) {
+            if (result.equalsIgnoreCase("false")) {
                 return null;
-            }else {
+            } else {
                 return JSONObject.parseObject(result);
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             return null;
         }
     }
 
-    public static JSONObject saveBindMaterail(String batchSn,String craft,String materialId,String type) {
-        try{
+    public static JSONObject saveBindMaterail(String batchSn, String craft, String materialId, String type) {
+        try {
             String mes_server_ip = MesClient.mes_server_ip;
             String oprno = MesClient.getEffectiveOprno().trim();
             String lineSn = MesClient.getEffectiveLineSn().trim();
-            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesMaterialPrebind/bind";
-            String params = "__ajax=json&oprno="+oprno+"&lineSn="+lineSn+"&batchSn="+batchSn+"&craft="+craft+"&materialId="+materialId+"&type="+type;
-            log.info("params="+params);
-            String result = doPost(url,params);
-            log.info("result="+result);
+            String url = "http://" + mes_server_ip + ":8980/js/a/mes/mesMaterialPrebind/bind";
+            String params = "__ajax=json&oprno=" + oprno + "&lineSn=" + lineSn + "&batchSn=" + batchSn + "&craft=" + craft + "&materialId=" + materialId + "&type=" + type;
+            log.info("params=" + params);
+            String result = doPost(url, params);
+            log.info("result=" + result);
 
-            if(result.equalsIgnoreCase("false")) {
+            if (result.equalsIgnoreCase("false")) {
                 return null;
-            }else {
+            } else {
                 return JSONObject.parseObject(result);
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             return null;
         }
     }
 
     // 上传气密结果
     public static JSONObject qmResultData(TestParam testParam) {
-        try{
+        try {
             String enconding = "UTF-8";
             InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
             Properties pro = new Properties();
             BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
             pro.load(br);
             String mes_server_ip = pro.getProperty("mes.server_ip");
-            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesProductRecord/qmresult";
-            // 根据服务器端代码,对特定参数进行Base64编码
+            String url = "http://" + mes_server_ip + ":8980/js/a/mes/mesProductRecord/qmresult";
             String testPressureBase64 = Base64Utils.getBase64(testParam.getParam1() != null ? testParam.getParam1() : "");
             String leakValBase64 = Base64Utils.getBase64(testParam.getParam3() != null ? testParam.getParam3() : "");
             String testTimeBase64 = Base64Utils.getBase64(testParam.getCreateTime() != null ? testParam.getCreateTime() : "");
             String titleBase64 = Base64Utils.getBase64(testParam.getOprnoTitle() != null ? testParam.getOprnoTitle() : "");
-            // 注意:sn(序列号)和workNum(测试人员)不应该Base64编码
-            
+
             log.info("服务器端需要Base64编码的参数: testPressure='{}'->'{}', leakVal='{}'->'{}', testTime='{}'->'{}', title='{}'->'{}'"
                     , testParam.getParam1(), testPressureBase64, testParam.getParam3(), leakValBase64
                     , testParam.getCreateTime(), testTimeBase64, testParam.getOprnoTitle(), titleBase64);
-            
-            String params = "__ajax=json&oprno="+URLEncoder.encode(testParam.getOprno() != null ? testParam.getOprno() : "", "UTF-8")
-                    +"&lineSn="+URLEncoder.encode(testParam.getLineSn() != null ? testParam.getLineSn() : "", "UTF-8")
-                    +"&sn="+URLEncoder.encode(testParam.getSn() != null ? testParam.getSn() : "", "UTF-8")
-                    +"&workNum="+URLEncoder.encode(testParam.getUcode() != null ? testParam.getUcode() : "", "UTF-8")
-                    +"&cxm="+URLEncoder.encode(testParam.getParam5() != null ? testParam.getParam5() : "", "UTF-8")
-                    +"&result="+URLEncoder.encode(testParam.getResult() != null ? testParam.getResult() : "", "UTF-8")
-                    +"&testPressure="+URLEncoder.encode(testPressureBase64, "UTF-8")
-                    +"&testPressureUnit="+URLEncoder.encode(testParam.getParam2() != null ? testParam.getParam2() : "", "UTF-8")
-                    +"&leakVal="+URLEncoder.encode(leakValBase64, "UTF-8")
-                    +"&leakValUnit="+URLEncoder.encode(testParam.getParam4() != null ? testParam.getParam4() : "", "UTF-8")
-                    +"&testTime="+URLEncoder.encode(testTimeBase64, "UTF-8")
-                    +"&title="+URLEncoder.encode(titleBase64, "UTF-8")
-                    +"&remark="+URLEncoder.encode(testParam.getRemark() != null ? testParam.getRemark() : "", "UTF-8")
-                    +"&deviceType="+URLEncoder.encode(testParam.getDeviceType() != null ? testParam.getDeviceType() : "", "UTF-8")
-                    // 添加服务器端期望的参数
-                    +"&cq="+URLEncoder.encode("", "UTF-8")
-                    +"&by="+URLEncoder.encode("", "UTF-8")
-                    +"&cs="+URLEncoder.encode("", "UTF-8")
-                    +"&leakRate="+URLEncoder.encode("", "UTF-8")
-                    +"&leakRateUnit="+URLEncoder.encode("", "UTF-8")
-                    +"&type="+URLEncoder.encode("", "UTF-8");
-            
-            // 添加sessionid
-//            if (MesClient.sessionid != null && !MesClient.sessionid.isEmpty()) {
-//                params += "&__sid=" + MesClient.sessionid;
-//            }
-            log.info("params="+params);
-            String result = doPost(url,params);
-            log.info("result="+result);
-            
-            // 检查result是否为null或空
-            if(result == null || result.trim().isEmpty()) {
+
+            String params = "__ajax=json&oprno=" + URLEncoder.encode(testParam.getOprno() != null ? testParam.getOprno() : "", "UTF-8")
+                    + "&lineSn=" + URLEncoder.encode(testParam.getLineSn() != null ? testParam.getLineSn() : "", "UTF-8")
+                    + "&sn=" + URLEncoder.encode(testParam.getSn() != null ? testParam.getSn() : "", "UTF-8")
+                    + "&workNum=" + URLEncoder.encode(testParam.getUcode() != null ? testParam.getUcode() : "", "UTF-8")
+                    + "&cxm=" + URLEncoder.encode(testParam.getParam5() != null ? testParam.getParam5() : "", "UTF-8")
+                    + "&result=" + URLEncoder.encode(testParam.getResult() != null ? testParam.getResult() : "", "UTF-8")
+                    + "&testPressure=" + URLEncoder.encode(testPressureBase64, "UTF-8")
+                    + "&testPressureUnit=" + URLEncoder.encode(testParam.getParam2() != null ? testParam.getParam2() : "", "UTF-8")
+                    + "&leakVal=" + URLEncoder.encode(leakValBase64, "UTF-8")
+                    + "&leakValUnit=" + URLEncoder.encode(testParam.getParam4() != null ? testParam.getParam4() : "", "UTF-8")
+                    + "&testTime=" + URLEncoder.encode(testTimeBase64, "UTF-8")
+                    + "&title=" + URLEncoder.encode(titleBase64, "UTF-8")
+                    + "&remark=" + URLEncoder.encode(testParam.getRemark() != null ? testParam.getRemark() : "", "UTF-8")
+                    + "&deviceType=" + URLEncoder.encode(testParam.getDeviceType() != null ? testParam.getDeviceType() : "", "UTF-8")
+                    + "&cq=" + URLEncoder.encode("", "UTF-8")
+                    + "&by=" + URLEncoder.encode("", "UTF-8")
+                    + "&cs=" + URLEncoder.encode("", "UTF-8")
+                    + "&leakRate=" + URLEncoder.encode("", "UTF-8")
+                    + "&leakRateUnit=" + URLEncoder.encode("", "UTF-8")
+                    + "&type=" + URLEncoder.encode("", "UTF-8");
+
+            log.info("params=" + params);
+            String result = doPost(url, params);
+            log.info("result=" + result);
+
+            if (result == null || result.trim().isEmpty()) {
                 log.error("HTTP请求返回结果为空,请检查服务器连接和参数格式");
-                log.info("压力值: '{}', 压力单位: '{}', 泄漏值: '{}', 泄漏单位: '{}'", 
-                    testParam.getParam1(), testParam.getParam2(), testParam.getParam3(), testParam.getParam4());
                 return null;
             }
 
-            if(result.equalsIgnoreCase("false")) {
+            if (result.equalsIgnoreCase("false")) {
                 return null;
-            }else {
+            } else {
                 try {
                     return JSONObject.parseObject(result);
                 } catch (Exception e) {
@@ -291,7 +251,7 @@ public class DataUtil {
                     return null;
                 }
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             log.error("qmResultData方法执行异常: {}", e.getMessage());
             e.printStackTrace();
             return null;
@@ -330,7 +290,6 @@ public class DataUtil {
                 result = sbf.toString();
             } else {
                 log.error("HTTP请求失败,响应码: " + responseCode);
-                // 尝试读取错误响应内容以获取更多信息
                 try {
                     is = connection.getErrorStream();
                     if (is != null) {
@@ -373,7 +332,9 @@ public class DataUtil {
                     e.printStackTrace();
                 }
             }
-            connection.disconnect();
+            if (connection != null) {
+                connection.disconnect();
+            }
         }
         return result;
     }
@@ -383,12 +344,8 @@ public class DataUtil {
             return "";
         }
         try {
-            // 简单清理:去除多余空格,保持数据格式规范
             str = str.trim().replaceAll("\\s+", "");
-            
-            // 使用最简单的标准Base64编码
             return Base64.getEncoder().encodeToString(str.getBytes("UTF-8"));
-
         } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
             return "";

+ 1 - 3
src/com/mes/ui/LoginFarme.java

@@ -176,9 +176,7 @@ public class LoginFarme extends JFrame {
                     // 获取等于所处时间-当前小时
                     LocalDateTime now = LocalDateTime.now();
                     MesClient.userLoginHours = now.getHour();
-                    //初始化tcp连接,发送同步报文
-                    MesClient.initTcpConnection();
-                    //启动timer心跳包
+                    //启动timer心跳显示
                     MesClient.startHeartBeatTimer();
 
                     //1操作工人,2管理员

+ 27 - 101
src/com/mes/ui/MesClient.java

@@ -3,7 +3,6 @@ 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 com.mes.util.CommonQmDevice;
 import org.slf4j.Logger;
@@ -39,18 +38,10 @@ public class MesClient extends JFrame {
     public static String mes_gw = "OP280A"; // 工位号
     public static String mes_gw_des = ""; // 工位名称
     public static String mes_server_ip = ""; // 服务器IP地址
-    public static int mes_tcp_port = 3000; // TCP服务端口
     public static int mes_heart_beat_cycle = 10; // 心跳周期
     public static int mes_heart_icon_cycle = 1;
     public static String mes_line_sn = ""; // 产线编号
 
-    //TCP连接
-    public static NettyClient nettyClient;
-    //TCP连接状态
-    public static boolean tcp_connect_flag = false;
-    //TCP连接请求
-    public static boolean connect_request_flag = false;
-
     //session
     public static String sessionid = "";
 
@@ -235,7 +226,6 @@ public class MesClient extends JFrame {
         BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
         pro.load(br);
         mes_server_ip = pro.getProperty("mes.server_ip");
-        mes_tcp_port = Integer.parseInt(pro.getProperty("mes.tcp_port"));
         mes_heart_beat_cycle = Integer.parseInt(pro.getProperty("mes.heart_beat_cycle"));
         String gw = pro.getProperty("mes.gw");
         if (gw != null && !gw.trim().isEmpty()) {
@@ -247,97 +237,47 @@ public class MesClient extends JFrame {
         }
         mes_gw_des = OprnoUtil.getGwDes(mes_line_sn, mes_gw);
 
-        log.info(mes_gw + ";" + mes_line_sn + ";" + mes_server_ip + ";" + mes_tcp_port + ";" + mes_heart_beat_cycle);
-    }
-
-    // 初始化TCP
-    public static void initTcpConnection() {
-        try {
-            if(nettyClient==null) {
-                //初始化TCP连接
-                nettyClient = new NettyClient();
-                //TCP连接状态
-                tcp_connect_flag = false;
-                //设置TCP请求状态
-                connect_request_flag = true;
-
-                DataUtil.synrTcp(nettyClient);
-            }
-        } catch (Exception e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
+        log.info(mes_gw + ";" + mes_line_sn + ";" + mes_server_ip + ";" + mes_heart_beat_cycle);
     }
 
-    //启动心跳包程序
+    // 启动心跳显示(仅刷新时间/图标,不发 HTTP)
     public static java.util.Timer heartBeatTimer;
     public static java.util.Timer heartBeatIconTimer;
     public static boolean iconREDFlag = true;
     public static void startHeartBeatTimer() {
-        if(heartBeatTimer!=null) {
+        if (heartBeatTimer != null) {
             heartBeatTimer.cancel();
+            heartBeatTimer = null;
         }
-        heartBeatTimer = new java.util.Timer();
-        heartBeatTimer.schedule(new TimerTask() {
-            public void run() {
-                if(nettyClient!=null&&tcp_connect_flag) {
-                    //log.info("发送心跳报文");
-                    DataUtil.heartBeat(nettyClient);
-
-                    heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
-                }
-            }
-        }, 100,mes_heart_beat_cycle*1000);
 
-        //心跳显示图标
-        if(heartBeatIconTimer!=null) {
+        // 心跳显示图标
+        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.repaint();
-                }else {
+                if (iconREDFlag) {
                     heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
-                    heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
-                    heart_beat_menu.repaint();
-
-                    //若未连接则尝试连接
-                    if(nettyClient!=null&&!tcp_connect_flag){
-                        log.info("TCP已断开");
-                        //TCP重新同步连接
-                        if(!connect_request_flag) {
-                            //log.info("TCP重新同步连接");
-                            //设置TCP请求状态,只重新同步连接一次
-                            connect_request_flag = true;
-
-                            DataUtil.synrTcp(nettyClient);
-                        }
-
-                    }
+                    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.repaint();
             }
-        }, 100,mes_heart_icon_cycle*1000);
+        }, 100, mes_heart_icon_cycle * 1000);
+    }
+
+    public static void setHttpStatus() {
+        heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")));
+        heart_beat_menu.repaint();
     }
 
-    //设置tcp连接状态显示
+    /** @deprecated 保留兼容,请使用 setHttpStatus */
     public static void setTcpStatus() {
-        if(tcp_connect_flag) {
-            heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
-            heart_beat_menu.repaint();
-        }else {
-            heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
-            heart_beat_menu.repaint();
-        }
+        setHttpStatus();
     }
 
     public static void initWarehouseData(){
@@ -742,7 +682,7 @@ public class MesClient extends JFrame {
             if(MesClient.mes_enable){
                 getUser();
                 // 查询工件质量
-                Boolean sendret = DataUtil.checkQuality(nettyClient,scanBarcode,user20);
+                Boolean sendret = DataUtil.checkQuality(scanBarcode, user20);
                 if(!sendret){
                     MesClient.setMenuStatus("消息发送失败,请重试",-1);
                     return;
@@ -924,15 +864,6 @@ public class MesClient extends JFrame {
         mesClientFrame.setVisible(false);
         //退出程序 退出登录
         System.exit(0);
-        nettyClient = null;
-//        if(heartBeatTimer!=null) {
-//            heartBeatTimer.cancel();
-//        }
-//        if(heartBeatIconTimer!=null) {
-//            heartBeatIconTimer.cancel();
-//        }
-        tcp_connect_flag = false;
-        connect_request_flag = false;
     }
 
     public MesClient() {
@@ -975,8 +906,8 @@ public class MesClient extends JFrame {
             @Override
             public void mousePressed(MouseEvent e) {
                 super.mouseClicked(e);
-                //重连mes
-                nettyClient.future.channel().close();
+                // MES 已改为按需 HTTP,无需重连长连接
+                setMenuStatus("MES已就绪", 0);
             }
         });
 //        settingMenu.add(resetTcpMenu);
@@ -1008,14 +939,9 @@ public class MesClient extends JFrame {
         equipment_statu_label.setBackground(Color.LIGHT_GRAY);
         toolBar.add(equipment_statu_label);
 
-        status_menu = new JButton("设备未连接MES服务器");
-        if(tcp_connect_flag) {
-            MesClient.setMenuStatus("已连接MES服务器",0);
-            status_menu.setForeground(Color.GREEN);
-        }else {
-            MesClient.setMenuStatus("请扫工件码",-1);
-            status_menu.setForeground(Color.DARK_GRAY);
-        }
+        status_menu = new JButton("请扫工件码");
+        MesClient.setMenuStatus("请扫工件码", -1);
+        status_menu.setForeground(Color.DARK_GRAY);
         status_menu.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
             }

+ 1 - 2
src/com/mes/ui/MesRevice.java

@@ -1,6 +1,5 @@
 package com.mes.ui;
 
-import com.mes.netty.ProtocolParam;
 import com.mes.component.MyDialog;
 import com.mes.util.ErrorMsg;
 
@@ -16,7 +15,7 @@ public class MesRevice {
                 MesClient.beginTestAfterScan();
             }else {
                 MesClient.check_quality_result = false;
-                String lmsg = ErrorMsg.getErrorMsg(processMsgRet, ProtocolParam.getLx(mes_msg));
+                String lmsg = ErrorMsg.getErrorMsg(processMsgRet, "");
                 MesClient.setMenuStatus(lmsg,-1);
             }
         }catch (Exception e){

+ 15 - 16
src/com/mes/util/CommonQmDevice.java

@@ -2,7 +2,7 @@ package com.mes.util;
 
 import com.mes.ui.ConfigParam;
 import com.mes.ui.MesClient;
-import com.mes.util.ytnetty.YtNettyClient;
+import com.mes.util.ytnetty.YtTcpClient;
 import com.mes.util.ytnetty.YtUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -11,13 +11,13 @@ import java.util.Timer;
 import java.util.TimerTask;
 
 /**
- * 气密仪统一入口:innomatec/ateq 走串口,INNTAI(中皖英泰)走网口 TCP。
+ * 气密仪统一入口:innomatec/ateq 走串口,INNTAI(中皖英泰)走网口 TCP(原生 Socket)
  */
 public class CommonQmDevice {
     public static final Logger log = LoggerFactory.getLogger(CommonQmDevice.class);
     public String device;
     public SerialPortUtils serialPortUtils;
-    public YtNettyClient ytClient;
+    public YtTcpClient ytClient;
     public boolean isOnline;
     ConfigParam configParam;
     public Timer workTimer;
@@ -51,8 +51,8 @@ public class CommonQmDevice {
                 MesClient.serialPortUtils = null;
                 String ip = configParam.getSerialPort();
                 String port = configParam.getBaudRate();
-                ytClient = new YtNettyClient();
-                ytClient.run(ip, Integer.parseInt(port));
+                YtTcpClient.run(ip, Integer.parseInt(port));
+                ytClient = YtTcpClient.getInstance();
                 workTimerTask();
                 log.info("INNTAI气密仪TCP连接 {}:{}", ip, port);
             } catch (Exception e) {
@@ -70,7 +70,7 @@ public class CommonQmDevice {
     public boolean isOnline() {
         isOnline = false;
         if (isInntai()) {
-            isOnline = YtNettyClient.getTcpOnline() == 1;
+            isOnline = YtTcpClient.getTcpOnline() == 1;
         } else if (serialPortUtils != null) {
             isOnline = serialPortUtils.isOpen;
         }
@@ -94,9 +94,9 @@ public class CommonQmDevice {
         workTimer.schedule(new TimerTask() {
             public void run() {
                 try {
-                    if (MesClient.work_status == 1 && YtNettyClient.future != null
-                            && YtNettyClient.future.channel() != null) {
-                        YtNettyClient.future.channel().writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getCurDataCommon()));
+                    YtTcpClient client = YtTcpClient.getInstance();
+                    if (MesClient.work_status == 1 && client != null && client.isConnected()) {
+                        client.send(YtUtil.getCurDataCommon());
                     }
                 } catch (Exception e) {
                     log.error("INNTAI实时查询失败", e);
@@ -108,13 +108,13 @@ public class CommonQmDevice {
     public boolean start() {
         try {
             if (isInntai()) {
-                if (YtNettyClient.future == null || YtNettyClient.future.channel() == null
-                        || YtNettyClient.getTcpOnline() != 1) {
+                YtTcpClient client = YtTcpClient.getInstance();
+                if (client == null || !client.isConnected()) {
                     MesClient.setMenuStatus("INNTAI气密仪未连接,请检查IP/端口后重试", 1);
                     return false;
                 }
                 log.info("INNTAI点击启动");
-                YtNettyClient.future.channel().writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getStartCommon()));
+                client.send(YtUtil.getStartCommon());
             } else {
                 if (serialPortUtils == null) {
                     MesClient.setMenuStatus("成品气密仪连接失败,请检查设备后重试", 1);
@@ -132,15 +132,14 @@ public class CommonQmDevice {
     public boolean changeProgram() {
         try {
             if (isInntai()) {
-                if (YtNettyClient.future == null || YtNettyClient.future.channel() == null
-                        || YtNettyClient.getTcpOnline() != 1) {
+                YtTcpClient client = YtTcpClient.getInstance();
+                if (client == null || !client.isConnected()) {
                     MesClient.setMenuStatus("INNTAI气密仪未连接,请检查IP/端口后重试", 1);
                     return false;
                 }
                 String programNo = MesClient.configParam.getProgramNo();
                 log.info("INNTAI切换程序 {}", programNo);
-                YtNettyClient.future.channel().writeAndFlush(
-                        YtUtil.getSendByteBuf(YtUtil.getSelectProgramCommon(programNo)));
+                client.send(YtUtil.getSelectProgramCommon(programNo));
             } else {
                 if (serialPortUtils == null) {
                     MesClient.setMenuStatus("成品气密仪连接失败,请检查设备后重试", 1);

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

@@ -20,7 +20,6 @@ public class Config {
     public static final String gw_des_1;
 
     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;
 
@@ -40,7 +39,6 @@ public class Config {
         gw_1 = prop.getProperty("mes.gw_1");
         gw_des_1 = OprnoUtil.getGwDes(line_sn, gw_1);
         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"));
         portName = prop.getProperty("portName1");
 

+ 0 - 111
src/com/mes/util/ytnetty/YtDecoderServer.java

@@ -1,111 +0,0 @@
-package com.mes.util.ytnetty;
-
-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.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-public class YtDecoderServer extends ByteToMessageDecoder {
-
-    private static final byte START_CHAR = (byte) 0x02; // 假设的起始字符
-    private static final byte END_CHAR = (byte) 0x03; // 假设的结束字符
-    private final ByteBuf msgin = Unpooled.buffer();
-    private final Charset charset = Charset.forName("UTF-8");
-
-    private static final Logger logger = LoggerFactory.getLogger(YtDecoderServer.class);
-
-
-    @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
-        logger.info(Thread.currentThread() + "收到了一次数据包,长度是:" + in.readableBytes());
-        String content = ByteBufUtil.hexDump(in).toUpperCase();
-        logger.info("接收包内容:" + in.toString(charset));
-        logger.info("接收包内容2:" +   content);
-
-        String content2 = hexStringToAscii(ByteBufUtil.hexDump(in)).toLowerCase();
-
-        while (in.isReadable()) {
-            byte b = in.readByte();
-            if (b == START_CHAR) {
-                // 当遇到起始字符时,重置消息StringBuilder
-                msgin.clear();
-            } else if (b == END_CHAR) {
-                // 当遇到结束字符时,将消息加入到解码列表中
-                String content3 = ByteBufUtil.hexDump(msgin).toUpperCase();
-                logger.info("接收信息:" + msgin.toString(charset));
-                logger.info("接收信息2:" + content3);
-//                out.add(content3);
-                out.add(content3);
-            } else {
-                // 正常的消息字符,追加到StringBuilder
-                msgin.writeByte(b);
-            }
-        }
-    }
-
-    /**
-     * 计算16进制字符串的BCC校验码
-     * @param hexData 16进制字符串
-     * @return BCC校验码
-     */
-    public static byte calculateBCC(String hexData) {
-        byte bcc = 0; // 初始化BCC校验码为0
-        for (int i = 0; i < hexData.length(); i += 2) { // 每次处理两个字符(1个字节)
-            String byteStr = hexData.substring(i, i + 2); // 获取当前16进制字节
-            int byteValue = Integer.parseInt(byteStr, 16); // 将16进制字符串转换为整数
-            bcc ^= byteValue; // 执行异或操作
-        }
-        return bcc; // 返回计算后的BCC校验码
-    }
-
-    // 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();
-    }
-
-    public static String hexStringToString(String str) {
-        StringBuilder name = new StringBuilder();
-        String[] split = str.split("\\\\x");
-        name.append(split[0]);
-        for (int i = 1; i < split.length; i++) {
-            if (!split[i].isEmpty() && split.length > i + 2 && split[i].length() == 2 && split[i + 1].length() == 2 && split[i+2].length() >= 2) {
-                String name16 = split[i] + split[i + 1] + split[i + 2].substring(0, 2);
-                // name16 = name16.replace(" ", "");
-                byte[] baKeyword = new byte[name16.length() / 2];
-                for (int j = 0; j < baKeyword.length; j++) {
-                    try {
-                        baKeyword[j] = (byte) (0xff & Integer.parseInt(name16.substring(j * 2, j * 2 + 2), 16));
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-                try {
-                    name16 = new String(baKeyword, StandardCharsets.UTF_8);
-                } catch (Exception e1) {
-                    e1.printStackTrace();
-                }
-                name.append(name16);
-                name.append(split[i + 2].substring(2));
-                i = i + 2;
-            }else {
-                name.append("\\\\x" + split[i]);
-            }
-        }
-        return name.toString();
-    }
-
-}

+ 0 - 60
src/com/mes/util/ytnetty/YtEncoderServer.java

@@ -1,60 +0,0 @@
-package com.mes.util.ytnetty;
-
-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.MessageToByteEncoder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class YtEncoderServer extends MessageToByteEncoder<String> {
-
-    private static final String START_CHAR = "02"; // 假设的起始字符
-    private static final String END_CHAR = "03"; // 假设的结束字符
-    private static final Logger logger = LoggerFactory.getLogger(YtEncoderServer.class);
-
-    @Override
-    protected void encode(ChannelHandlerContext channelHandlerContext, String message, ByteBuf out) throws Exception {
-        //String message 16禁止字符串
-        String contstr = START_CHAR + message + END_CHAR;
-        System.out.println("contstr:"+contstr);
-        String bcc = String.format("%02x",calculateBCC(contstr));
-
-        String allstr = contstr+bcc;
-        System.out.println("allstr:"+allstr);
-
-        ByteBuf bccbf = Unpooled.wrappedBuffer(allstr.getBytes("UTF-8"));
-        out.writeBytes(bccbf);
-
-//        String content2 = hexStringToAscii(ByteBufUtil.hexDump(buf));
-        bccbf.release(); // 释放ByteBuf资源
-    }
-
-    // 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();
-    }
-
-    /**
-     * 计算16进制字符串的BCC校验码
-     * @param hexData 16进制字符串
-     * @return BCC校验码
-     */
-    public static byte calculateBCC(String hexData) {
-        byte bcc = 0; // 初始化BCC校验码为0
-        for (int i = 0; i < hexData.length(); i += 2) { // 每次处理两个字符(1个字节)
-            String byteStr = hexData.substring(i, i + 2); // 获取当前16进制字节
-            int byteValue = Integer.parseInt(byteStr, 16); // 将16进制字符串转换为整数
-            bcc ^= byteValue; // 执行异或操作
-        }
-        return bcc; // 返回计算后的BCC校验码
-    }
-}

+ 134 - 0
src/com/mes/util/ytnetty/YtMessageHandler.java

@@ -0,0 +1,134 @@
+package com.mes.util.ytnetty;
+
+import com.mes.ui.MesClient;
+import com.mes.util.DateLocalUtils;
+import com.mes.util.TestParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.awt.*;
+
+/**
+ * INNTAI 气密仪消息处理(不依赖 Netty)。
+ */
+public class YtMessageHandler {
+
+    private static final Logger log = LoggerFactory.getLogger(YtMessageHandler.class);
+
+    private static final double LEAK_OK_MIN = -10.0;
+    private static final double LEAK_OK_MAX = 2.5;
+
+    private YtMessageHandler() {
+    }
+
+    public static void handleMessage(String msg) {
+        log.info("message:" + msg);
+        String code = YtUtil.getCode(msg);
+        log.info("code:" + code);
+        try {
+            if (MesClient.configParam != null && !isInntaiDevice(MesClient.configParam.getDevice())) {
+                return;
+            }
+            switch (code) {
+                case "4353":
+                    handleFinalResult(msg);
+                    break;
+                case "5253":
+                    handleRealtime(msg);
+                    break;
+                case "5453":
+                case "4F4B":
+                case "4552":
+                    break;
+                default:
+                    break;
+            }
+        } catch (Exception e) {
+            log.error("处理INNTAI消息失败", e);
+        }
+    }
+
+    private static void handleFinalResult(String msg) {
+        if (MesClient.work_status != 1 || MesClient.mesTjFlag == 1) {
+            log.info("忽略4353:未在测试中或本轮已提交");
+            return;
+        }
+        MesClient.mesTjFlag = 1;
+        String sn = MesClient.product_sn.getText().trim();
+        QmResultUtil qmResultUtil = new QmResultUtil(msg);
+        log.info("INNTAI最终结果 {}", qmResultUtil);
+
+        MesClient.param1.setText(qmResultUtil.pressureValue);
+        MesClient.param2.setText(qmResultUtil.leakValue);
+
+        if ("OK".equals(qmResultUtil.result)) {
+            MesClient.result.setText("OK");
+            MesClient.result.setForeground(Color.GREEN);
+        } else {
+            MesClient.result.setText("NG");
+            MesClient.result.setForeground(Color.RED);
+        }
+
+        TestParam testParam = new TestParam();
+        testParam.setSn(sn);
+        testParam.setOprno(MesClient.getEffectiveOprno());
+        testParam.setOprnoTitle(MesClient.configParam != null ? MesClient.configParam.getOprnoTitle() : "");
+        testParam.setLineSn(MesClient.getEffectiveLineSn());
+        testParam.setUcode(MesClient.user_menu != null ? MesClient.user_menu.getText().trim() : "");
+        testParam.setParam1(qmResultUtil.pressureValue);
+        testParam.setParam2(qmResultUtil.pressureUnit);
+        testParam.setParam3(qmResultUtil.leakValue);
+        testParam.setParam4(qmResultUtil.leakUnit);
+        testParam.setParam5(MesClient.configParam != null && MesClient.configParam.getProgramNo() != null
+                ? MesClient.configParam.getProgramNo() : "");
+        testParam.setResult(qmResultUtil.result);
+        testParam.setDeviceType(MesClient.configParam != null ? MesClient.configParam.getDevice() : "INNTAI");
+        testParam.setRemark("");
+        testParam.setCreateTime(DateLocalUtils.getCurrentTime());
+        MesClient.afterTestSaveAndUpload(testParam);
+    }
+
+    private static void handleRealtime(String msg) {
+        if (MesClient.work_status != 1 || MesClient.workstop == 1) {
+            return;
+        }
+        QmCurUtil qmCurUtil = new QmCurUtil(msg);
+        log.info("qmCurUtil:" + qmCurUtil);
+        if (qmCurUtil.isRunningStep()) {
+            if (MesClient.mesStartFlag == 0 || MesClient.mesTjFlag == 1) {
+                MesClient.mesStartFlag = 1;
+                MesClient.mesTjFlag = 0;
+                log.info("本轮测试已开始,step={}", qmCurUtil.step);
+            }
+            if (MesClient.result != null && !"等待结果".equals(MesClient.result.getText())) {
+                MesClient.result.setText("等待结果");
+                MesClient.result.setForeground(Color.GRAY);
+            }
+        }
+        MesClient.setMenuStatus("当前步骤:" + qmCurUtil.step, 0);
+        MesClient.param1.setText(qmCurUtil.pressureValue);
+        MesClient.param2.setText(qmCurUtil.leakValue);
+        if (qmCurUtil.pressureValue != null && !qmCurUtil.pressureValue.trim().isEmpty()) {
+            MesClient.lastQmPressure = qmCurUtil.pressureValue.trim();
+        }
+        if (qmCurUtil.leakValue != null && !qmCurUtil.leakValue.trim().isEmpty()) {
+            MesClient.lastQmLeak = qmCurUtil.leakValue.trim();
+        }
+
+        if (MesClient.mesStartFlag == 1 && MesClient.mesTjFlag == 0 && qmCurUtil.isEndStep()) {
+            MesClient.workstop = 1;
+            YtTcpClient client = YtTcpClient.getInstance();
+            if (client != null) {
+                client.send(YtUtil.getResultCommon());
+            }
+        }
+    }
+
+    static boolean isInntaiDevice(String device) {
+        if (device == null) {
+            return false;
+        }
+        String d = device.trim();
+        return "INNTAI".equalsIgnoreCase(d) || "中皖英泰".equals(d);
+    }
+}

+ 0 - 79
src/com/mes/util/ytnetty/YtNettyClient.java

@@ -1,79 +0,0 @@
-package com.mes.util.ytnetty;
-
-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.timeout.IdleStateHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.TimeUnit;
-
-public class YtNettyClient {
-
-    public static final Logger log =  LoggerFactory.getLogger(YtNettyClientHandler.class);
-    public static SocketChannel socketChannel;
-    public static ChannelFuture future;
-    //配置线程组
-    public static EventLoopGroup group = new NioEventLoopGroup();
-    //创建服务启动器
-    public static Bootstrap bootstrap = new Bootstrap();
-
-    public static String ip;
-    public static int port;
-    public static int tcpOnline = 0; // 0不在线 1=在线
-    private static volatile boolean inited = false;
-
-    public static void run(String inip, int inport) {
-        try{
-            ip = inip;
-            port = inport;
-            if (!inited) {
-                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("decoder", new YtDecoderServer())
-                                        .addLast("encoder",new YtEncoderServer())
-                                        .addLast(new IdleStateHandler(60, 90, 120, TimeUnit.SECONDS))
-                                        .addLast(new YtNettyClientHandler());
-                            }
-                        });
-                inited = true;
-            }
-            bootstrap.remoteAddress(ip,port);
-            doConnect();
-        }catch (Exception e){
-            e.printStackTrace();
-        }
-
-    }
-
-    public static void doConnect() throws InterruptedException {
-        tcpOnline = 0;
-        //连接
-        future = bootstrap.connect();
-        log.info("客户端正在连接服务端...");
-        //客户端断线重连逻辑
-        future.addListener((ChannelFutureListener) future1 -> {
-            if (future1.isSuccess()) {
-                log.info("客户端连接服务端成功...");
-                tcpOnline = 1;
-            } else {
-                future1.channel().eventLoop().schedule(() -> run(ip,port), 10, TimeUnit.SECONDS);
-            }
-        });
-        socketChannel = (SocketChannel) future.channel();
-    }
-
-    public static int getTcpOnline(){
-        return tcpOnline;
-    }
-}
-
-
-

+ 0 - 245
src/com/mes/util/ytnetty/YtNettyClientHandler.java

@@ -1,245 +0,0 @@
-package com.mes.util.ytnetty;
-
-import com.mes.ui.MesClient;
-import com.mes.util.DateLocalUtils;
-import com.mes.util.TestParam;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.handler.timeout.IdleState;
-import io.netty.handler.timeout.IdleStateEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.awt.*;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-public class YtNettyClientHandler extends ChannelInboundHandlerAdapter {
-
-    public static final Logger log = LoggerFactory.getLogger(YtNettyClientHandler.class);
-
-    /** 泄露值合格区间(含边界) */
-    private static final double LEAK_OK_MIN = -10.0;
-    private static final double LEAK_OK_MAX = 2.5;
-
-    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-    public static byte[] responseByte;
-
-    private int timeoutNum = 0;
-    private int timeoutNumMax = 3;
-
-    @Override
-    public void channelActive(ChannelHandlerContext ctx) throws Exception {
-        log.info("mes connecting:" + sdf.format(new Date()));
-    }
-
-    @Override
-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
-        Channel channel = ctx.channel();
-        log.error("close tcp, ip:" + channel.remoteAddress());
-        YtNettyClient.tcpOnline = 0;
-
-        System.out.println("3s 之后尝试重新连接服务器...");
-        Thread.sleep(3 * 1000);
-        YtNettyClient.doConnect();
-    }
-
-    @Override
-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
-        IdleState state = ((IdleStateEvent) evt).state();
-        if (state.equals(IdleState.READER_IDLE)) {
-            System.out.println("客户端read超时" + (timeoutNum++) + "次");
-
-            if (timeoutNum > timeoutNumMax) {
-                System.out.println("超时次数上限,关闭这个不活跃的连接");
-                ctx.channel().close();
-            }
-        }
-        if (state.equals(IdleState.ALL_IDLE)) {
-            sendHeartbeatPacket(ctx);
-        }
-    }
-
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
-        timeoutNum = 0;
-        log.info("message:" + message);
-        String msg = message + "";
-        String code = YtUtil.getCode(msg);
-        log.info("code:" + code);
-        log.info("msg:" + msg);
-        try {
-            if (MesClient.configParam != null && !isInntaiDevice(MesClient.configParam.getDevice())) {
-                return;
-            }
-            switch (code) {
-                case "4353": // 最终结果 CS
-                    if (MesClient.work_status != 1 || MesClient.mesTjFlag == 1) {
-                        log.info("忽略4353:未在测试中或本轮已提交");
-                        break;
-                    }
-                    MesClient.mesTjFlag = 1;
-                    String sn = MesClient.product_sn.getText().trim();
-                    QmResultUtil qmResultUtil = new QmResultUtil(msg);
-                    log.info("INNTAI最终结果 {}", qmResultUtil);
-
-                    MesClient.param1.setText(qmResultUtil.pressureValue);
-                    MesClient.param2.setText(qmResultUtil.leakValue);
-
-                    if ("OK".equals(qmResultUtil.result)) {
-                        MesClient.result.setText("OK");
-                        MesClient.result.setForeground(Color.GREEN);
-                    } else {
-                        MesClient.result.setText("NG");
-                        MesClient.result.setForeground(Color.RED);
-                    }
-
-                    TestParam testParam = new TestParam();
-                    testParam.setSn(sn);
-                    testParam.setOprno(MesClient.getEffectiveOprno());
-                    testParam.setOprnoTitle(MesClient.configParam != null ? MesClient.configParam.getOprnoTitle() : "");
-                    testParam.setLineSn(MesClient.getEffectiveLineSn());
-                    testParam.setUcode(MesClient.user_menu != null ? MesClient.user_menu.getText().trim() : "");
-                    testParam.setParam1(qmResultUtil.pressureValue);
-                    testParam.setParam2(qmResultUtil.pressureUnit);
-                    testParam.setParam3(qmResultUtil.leakValue);
-                    testParam.setParam4(qmResultUtil.leakUnit);
-                    testParam.setParam5(MesClient.configParam != null && MesClient.configParam.getProgramNo() != null
-                            ? MesClient.configParam.getProgramNo() : "");
-                    testParam.setResult(qmResultUtil.result);
-                    testParam.setDeviceType(MesClient.configParam != null ? MesClient.configParam.getDevice() : "INNTAI");
-                    testParam.setRemark("");
-                    testParam.setCreateTime(DateLocalUtils.getCurrentTime());
-                    MesClient.afterTestSaveAndUpload(testParam);
-                    break;
-                case "5253": // 实时结果
-                    if (MesClient.work_status != 1 || MesClient.workstop == 1) {
-                        break;
-                    }
-                    QmCurUtil qmCurUtil = new QmCurUtil(msg);
-                    log.info("qmCurUtil:" + qmCurUtil.toString());
-                    // 仅中间步骤开启本轮
-                    if (qmCurUtil.isRunningStep()) {
-                        if (MesClient.mesStartFlag == 0 || MesClient.mesTjFlag == 1) {
-                            MesClient.mesStartFlag = 1;
-                            MesClient.mesTjFlag = 0;
-                            log.info("本轮测试已开始,step={}", qmCurUtil.step);
-                        }
-                        // 测试中不显示OK/NG
-                        if (MesClient.result != null
-                                && !"等待结果".equals(MesClient.result.getText())) {
-                            MesClient.result.setText("等待结果");
-                            MesClient.result.setForeground(Color.GRAY);
-                        }
-                    }
-                    MesClient.setMenuStatus("当前步骤:" + qmCurUtil.step, 0);
-                    // 实时只刷压强/泄漏数值,不刷OK/NG
-                    MesClient.param1.setText(qmCurUtil.pressureValue);
-                    MesClient.param2.setText(qmCurUtil.leakValue);
-                    if (qmCurUtil.pressureValue != null && !qmCurUtil.pressureValue.trim().isEmpty()) {
-                        MesClient.lastQmPressure = qmCurUtil.pressureValue.trim();
-                    }
-                    if (qmCurUtil.leakValue != null && !qmCurUtil.leakValue.trim().isEmpty()) {
-                        MesClient.lastQmLeak = qmCurUtil.leakValue.trim();
-                    }
-
-                    // 气密仪结束步:才判定并显示OK/NG、提交
-                    if (MesClient.mesStartFlag == 1 && MesClient.mesTjFlag == 0 && qmCurUtil.isEndStep()) {
-//                        finishByLeakRange();
-                        MesClient.workstop = 1;
-                        ctx.writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getResultCommon()));
-                    }
-                    break;
-                case "5453":
-                case "4F4B":
-                case "4552":
-                    break;
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * 测试结束:按泄露值 [-4, 8] 判定 OK/NG,显示并提交。
-     * 不再使用气密仪 4353 自带判定结果。
-     */
-    private void finishByLeakRange() {
-        String sn = MesClient.product_sn.getText().trim();
-        if (sn.isEmpty()) {
-            log.info("结束判定跳过:工件码为空");
-            return;
-        }
-        String pressureValue = MesClient.lastQmPressure != null ? MesClient.lastQmPressure.trim() : "";
-        String leakValue = MesClient.lastQmLeak != null ? MesClient.lastQmLeak.trim() : "";
-        if (leakValue.isEmpty()) {
-            log.info("结束判定跳过:泄露值尚未收到");
-            return;
-        }
-
-        MesClient.mesTjFlag = 1;
-
-        boolean ok = isLeakOk(leakValue);
-        String lastRet = ok ? "OK" : "NG";
-        log.info("测试结束判定:leak={}, 区间[{}, {}], result={}",
-                leakValue, LEAK_OK_MIN, LEAK_OK_MAX, lastRet);
-
-        String pressureUnit = "kPa";
-        MesClient.param1.setText(pressureValue + pressureUnit);
-        MesClient.param2.setText(leakValue);
-        if (ok) {
-            MesClient.result.setText("OK");
-            MesClient.result.setForeground(Color.GREEN);
-        } else {
-            MesClient.result.setText("NG");
-            MesClient.result.setForeground(Color.RED);
-        }
-
-        TestParam testParam = new TestParam();
-        testParam.setSn(sn);
-        testParam.setParam1(pressureValue);
-        testParam.setParam2(pressureUnit);
-        testParam.setParam3(leakValue);
-        testParam.setParam4("");
-        testParam.setResult(lastRet);
-        testParam.setRemark(ok ? "" : "泄露值超限(" + LEAK_OK_MIN + "~" + LEAK_OK_MAX + ")");
-        testParam.setOprno(MesClient.getEffectiveOprno());
-        testParam.setOprnoTitle(MesClient.configParam != null ? MesClient.configParam.getOprnoTitle() : "");
-        testParam.setLineSn(MesClient.getEffectiveLineSn());
-        testParam.setUcode(MesClient.user_menu != null ? MesClient.user_menu.getText().trim() : "");
-        testParam.setParam5(MesClient.configParam != null && MesClient.configParam.getProgramNo() != null
-                ? MesClient.configParam.getProgramNo() : "");
-        testParam.setDeviceType(MesClient.configParam != null ? MesClient.configParam.getDevice() : "INNTAI");
-        testParam.setCreateTime(DateLocalUtils.getCurrentTime());
-        MesClient.afterTestSaveAndUpload(testParam);
-    }
-
-    /** 泄露值在 [-4, 8](含边界)为 OK,否则 NG */
-    static boolean isLeakOk(String leakValue) {
-        try {
-            double v = Double.parseDouble(leakValue.trim());
-            return v >= LEAK_OK_MIN && v <= LEAK_OK_MAX;
-        } catch (Exception e) {
-            log.warn("泄露值无法解析为数字: {}", leakValue);
-            return false;
-        }
-    }
-
-    static boolean isInntaiDevice(String device) {
-        if (device == null) {
-            return false;
-        }
-        String d = device.trim();
-        return "INNTAI".equalsIgnoreCase(d) || "中皖英泰".equals(d);
-    }
-
-    @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-        System.out.println("exceptionCaught");
-    }
-
-    private void sendHeartbeatPacket(ChannelHandlerContext ctx) {
-        ctx.writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getStateCommon()));
-    }
-}

+ 165 - 0
src/com/mes/util/ytnetty/YtTcpClient.java

@@ -0,0 +1,165 @@
+package com.mes.util.ytnetty;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * INNTAI 气密仪 TCP 客户端(原生 Socket,不依赖 Netty)。
+ */
+public class YtTcpClient {
+
+    private static final Logger log = LoggerFactory.getLogger(YtTcpClient.class);
+
+    public static volatile int tcpOnline = 0;
+    private static volatile YtTcpClient instance;
+
+    private String ip;
+    private int port;
+    private Socket socket;
+    private OutputStream out;
+    private Thread readerThread;
+    private final AtomicBoolean running = new AtomicBoolean(false);
+    private final AtomicBoolean reconnectScheduled = new AtomicBoolean(false);
+
+    public static void run(String ip, int port) {
+        if (instance == null) {
+            synchronized (YtTcpClient.class) {
+                if (instance == null) {
+                    instance = new YtTcpClient();
+                }
+            }
+        }
+        instance.connect(ip, port);
+    }
+
+    public static int getTcpOnline() {
+        return tcpOnline;
+    }
+
+    public static YtTcpClient getInstance() {
+        return instance;
+    }
+
+    public void connect(String ip, int port) {
+        this.ip = ip;
+        this.port = port;
+        doConnect();
+    }
+
+    public void doConnect() {
+        tcpOnline = 0;
+        closeSocket();
+        running.set(true);
+        new Thread(() -> {
+            try {
+                socket = new Socket(ip, port);
+                socket.setTcpNoDelay(true);
+                socket.setKeepAlive(true);
+                out = socket.getOutputStream();
+                tcpOnline = 1;
+                log.info("INNTAI设备连接成功 {}:{}", ip, port);
+                startReader();
+            } catch (IOException e) {
+                log.error("INNTAI设备连接失败 {}:{}", ip, port, e);
+                scheduleReconnect();
+            }
+        }, "YtTcpClient-Connect").start();
+    }
+
+    private void startReader() {
+        readerThread = new Thread(() -> {
+            try {
+                InputStream in = socket.getInputStream();
+                StringBuilder frame = new StringBuilder();
+                boolean inFrame = false;
+                byte[] buf = new byte[1024];
+                while (running.get() && socket != null && !socket.isClosed()) {
+                    int n = in.read(buf);
+                    if (n <= 0) {
+                        break;
+                    }
+                    for (int i = 0; i < n; i++) {
+                        byte b = buf[i];
+                        if (b == 0x02) {
+                            frame.setLength(0);
+                            inFrame = true;
+                        } else if (b == 0x03 && inFrame) {
+                            YtMessageHandler.handleMessage(frame.toString());
+                            inFrame = false;
+                        } else if (inFrame) {
+                            frame.append(String.format("%02X", b & 0xFF));
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                if (running.get()) {
+                    log.error("INNTAI读取异常", e);
+                }
+            } finally {
+                tcpOnline = 0;
+                if (running.get()) {
+                    scheduleReconnect();
+                }
+            }
+        }, "YtTcpClient-Reader");
+        readerThread.setDaemon(true);
+        readerThread.start();
+    }
+
+    public void send(String hexCommand) {
+        if (tcpOnline != 1 || out == null) {
+            return;
+        }
+        try {
+            out.write(YtUtil.getSendBytes(hexCommand));
+            out.flush();
+        } catch (IOException e) {
+            log.error("INNTAI发送失败", e);
+            tcpOnline = 0;
+        }
+    }
+
+    public boolean isConnected() {
+        return tcpOnline == 1 && socket != null && socket.isConnected() && !socket.isClosed();
+    }
+
+    private void scheduleReconnect() {
+        if (!running.get() || !reconnectScheduled.compareAndSet(false, true)) {
+            return;
+        }
+        new Thread(() -> {
+            try {
+                Thread.sleep(3000);
+            } catch (InterruptedException ignored) {
+                Thread.currentThread().interrupt();
+            }
+            reconnectScheduled.set(false);
+            if (running.get()) {
+                doConnect();
+            }
+        }, "YtTcpClient-Reconnect").start();
+    }
+
+    public void shutdown() {
+        running.set(false);
+        closeSocket();
+        tcpOnline = 0;
+    }
+
+    private void closeSocket() {
+        try {
+            if (socket != null) {
+                socket.close();
+            }
+        } catch (IOException ignored) {
+        }
+        socket = null;
+        out = null;
+    }
+}

+ 4 - 8
src/com/mes/util/ytnetty/YtUtil.java

@@ -1,7 +1,5 @@
 package com.mes.util.ytnetty;
 
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -108,16 +106,14 @@ public class YtUtil {
     }
 
     /**
-     * 将字符串消息转为ByteBuf
-     * 16进制字符串转二进制
-     * @param hex 字符串消息
+     * 将16进制命令转为字节数组
      */
-    public static ByteBuf getSendByteBuf(String hex) {
+    public static byte[] getSendBytes(String hex) {
         byte[] bytes = new byte[hex.length() / 2];
         for (int i = 0; i < hex.length(); i += 2) {
             int value = Integer.parseInt(hex.substring(i, i + 2), 16);
-            bytes[i/2] = (byte)(value & 0xFF);
+            bytes[i / 2] = (byte) (value & 0xFF);
         }
-        return Unpooled.wrappedBuffer(bytes);
+        return bytes;
     }
 }

+ 3 - 3
src/resources/config/config.properties

@@ -1,7 +1,7 @@
 mes.gw=OP022A
-mes.server_ip=127.0.0.1
-#mes.server_ip=192.168.16.99
-mes.tcp_port=3000
+#mes.server_ip=127.0.0.1
+mes.server_ip=192.168.16.99
+# mes.tcp_port 已废弃,MES 通信已全部改用 HTTP (8980)
 mes.heart_beat_cycle=60
 mes.line_sn=XT
 portName1=COM3