MesClient.java 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. package com.mes.ui;
  2. import com.alibaba.fastjson2.JSONObject;
  3. import com.fazecast.jSerialComm.SerialPort;
  4. import com.fazecast.jSerialComm.SerialPortEvent;
  5. import com.mes.component.MesRadio;
  6. import com.mes.component.MesWebView;
  7. import com.mes.laser.LaserFlowManager;
  8. import com.mes.netty.NettyClient;
  9. import com.mes.util.DateLocalUtils;
  10. import com.mes.util.JdbcUtils;
  11. import javafx.embed.swing.JFXPanel;
  12. import javax.swing.*;
  13. import javax.swing.border.EmptyBorder;
  14. import javax.swing.event.ChangeEvent;
  15. import javax.swing.event.ChangeListener;
  16. import java.awt.*;
  17. import java.awt.event.ActionEvent;
  18. import java.awt.event.ActionListener;
  19. import java.awt.event.MouseAdapter;
  20. import java.awt.event.MouseEvent;
  21. import java.io.BufferedReader;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.io.InputStreamReader;
  25. import java.time.LocalDateTime;
  26. import java.util.List;
  27. import java.util.Properties;
  28. import java.util.Timer;
  29. import java.util.TimerTask;
  30. import java.util.concurrent.ExecutorService;
  31. import java.util.concurrent.Executors;
  32. public class MesClient extends JFrame {
  33. private static String Drivde = "org.sqlite.JDBC";
  34. public static int mes_auth = 0; // 权限级别 0=无权限 1=操作工人 2=管理员
  35. public static String mes_gw = ""; // 工位号
  36. public static String mes_gw_des = ""; // 工位名称
  37. public static String mes_server_ip = ""; // 服务器IP地址
  38. public static int mes_tcp_port = 3000; // TCP服务端口
  39. public static int mes_heart_beat_cycle = 10; // 心跳周期
  40. public static int mes_heart_icon_cycle = 1;
  41. public static String mes_line_sn = ""; // 产线编号
  42. //TCP连接
  43. public static NettyClient nettyClient;
  44. //TCP连接状态
  45. public static boolean tcp_connect_flag = false;
  46. //TCP连接请求
  47. public static boolean connect_request_flag = false;
  48. //session
  49. public static String sessionid = "";
  50. public static JPanel contentPane;
  51. public static MesClient mesClientFrame;
  52. public static JTabbedPane tabbedPane;
  53. public static JScrollPane indexScrollPaneA;
  54. public static JScrollPane searchScrollPane;
  55. public static JScrollPane searchScrollPaneDj;
  56. public static Boolean check_quality_result = false;
  57. public static Integer work_status = 0;
  58. public static JButton heart_beat_menu;
  59. public static JButton status_menu;
  60. public static JButton user_menu;
  61. public static int scan_type = 0;
  62. public static JButton finish_ok_bt;
  63. public static JButton finish_ng_bt;
  64. public static JTextField product_sn;
  65. public static JButton f_scan_data_bt_1;
  66. public static JTextField batch_sn; // 物料批次码
  67. public static JButton batch_sn_btn;
  68. public static String user20 = "";
  69. public static JFrame welcomeWin;
  70. public static JPanel indexPanelB;
  71. public static MesWebView jfxPanel = null;
  72. public static JPanel indexPanelC;
  73. public static MesWebView jfxPanel2 = null;
  74. public static MesRadio mesRadioHj;
  75. public static JTable table;
  76. public static Object[] columnNames = { "物料名称", "绑定批次", "剩余次数", "操作" };
  77. public static Object[][] rowData = null;
  78. public static Boolean checkState = false; // 点检状态 false=未点检 true=已点检
  79. public static SerialPort serialPort; // 串口对象
  80. // 镭雕相关
  81. public static JButton laser_get_code_bt; // 获取镭雕码按钮
  82. public static JButton laser_reset_bt; // 人工复位按钮
  83. public static LaserFlowManager laserFlowManager;
  84. public static void main(String[] args) {
  85. if (LockUtil.getInstance().isAppActive() == true){
  86. // JOptionPane.showMessageDialog(null, "已有一个程序在运行,程序退出");
  87. return;
  88. }else{
  89. // 设置支持高DPI
  90. System.setProperty("sun.java2d.uiScale", "1.0");
  91. System.setProperty("sun.java2d.dpiaware", "true");
  92. EventQueue.invokeLater(new Runnable() {
  93. @Override
  94. public void run() {
  95. try{
  96. //读文件配置
  97. readProperty();
  98. // 显示界面
  99. mesClientFrame = new MesClient();
  100. mesClientFrame.setVisible(false);
  101. JdbcUtils.getConn();
  102. welcomeWin = new LoginFarme();
  103. welcomeWin.setVisible(true);
  104. getMaterailData();
  105. serialPort = ModbusRtu.connect();
  106. checkTimer();
  107. // 启动镭雕流程管理器(含本地HTTP服务,接收镭雕软件完成上报)
  108. initLaserFlow();
  109. }catch (Exception e){
  110. e.printStackTrace();
  111. }
  112. }
  113. });
  114. }
  115. }
  116. public static java.util.Timer checkTimer;
  117. public static void checkTimer() {
  118. if(checkTimer!=null) {
  119. checkTimer.cancel();
  120. }
  121. checkTimer = new java.util.Timer();
  122. checkTimer.schedule(new TimerTask() {
  123. public void run() {
  124. if(!MesClient.sessionid.isEmpty()){
  125. getCheckResult();
  126. }
  127. }
  128. }, 100,3*1000);
  129. }
  130. //读配置文件
  131. private static void readProperty() throws IOException{
  132. String enconding = "UTF-8";
  133. InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
  134. Properties pro = new Properties();
  135. BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
  136. pro.load(br);
  137. mes_gw = pro.getProperty("mes.gw");
  138. // mes_gw_des = pro.getProperty("mes.gw_des");
  139. mes_server_ip = pro.getProperty("mes.server_ip");
  140. mes_tcp_port = Integer.parseInt(pro.getProperty("mes.tcp_port"));
  141. mes_heart_beat_cycle = Integer.parseInt(pro.getProperty("mes.heart_beat_cycle"));
  142. mes_line_sn = pro.getProperty("mes.line_sn");
  143. mes_gw_des = OprnoUtil.getGwDes(mes_line_sn,mes_gw);
  144. System.out.println(mes_gw + ";" + mes_gw_des + ";" + mes_server_ip + ";" + mes_tcp_port + ";" + mes_heart_beat_cycle);
  145. }
  146. // 初始化TCP
  147. public static void initTcpConnection() {
  148. try {
  149. if(nettyClient==null) {
  150. //初始化TCP连接
  151. nettyClient = new NettyClient();
  152. //TCP连接状态
  153. tcp_connect_flag = false;
  154. //设置TCP请求状态
  155. connect_request_flag = true;
  156. DataUtil.synrTcp(nettyClient,mes_gw);
  157. }
  158. } catch (Exception e) {
  159. // TODO Auto-generated catch block
  160. e.printStackTrace();
  161. }
  162. }
  163. //启动心跳包程序
  164. public static java.util.Timer heartBeatTimer;
  165. public static java.util.Timer heartBeatIconTimer;
  166. public static boolean iconREDFlag = true;
  167. public static void startHeartBeatTimer() {
  168. if(heartBeatTimer!=null) {
  169. heartBeatTimer.cancel();
  170. }
  171. heartBeatTimer = new java.util.Timer();
  172. heartBeatTimer.schedule(new TimerTask() {
  173. public void run() {
  174. if(nettyClient!=null&&tcp_connect_flag) {
  175. //System.out.println("发送心跳报文");
  176. DataUtil.heartBeat(nettyClient,mes_gw);
  177. heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
  178. }
  179. }
  180. }, 100,mes_heart_beat_cycle*1000);
  181. //心跳显示图标
  182. if(heartBeatIconTimer!=null) {
  183. heartBeatIconTimer.cancel();
  184. }
  185. heartBeatIconTimer = new Timer();
  186. heartBeatIconTimer.schedule(new TimerTask() {
  187. public void run() {
  188. if(tcp_connect_flag) {
  189. if(iconREDFlag) {
  190. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
  191. iconREDFlag = false;
  192. }else {
  193. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")));
  194. iconREDFlag = true;
  195. }
  196. heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
  197. heart_beat_menu.repaint();
  198. }else {
  199. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
  200. heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
  201. heart_beat_menu.repaint();
  202. //若未连接则尝试连接
  203. if(nettyClient!=null&&!tcp_connect_flag){
  204. System.out.println("TCP已断开");
  205. //TCP重新同步连接
  206. if(!connect_request_flag) {
  207. //System.out.println("TCP重新同步连接");
  208. //设置TCP请求状态,只重新同步连接一次
  209. connect_request_flag = true;
  210. DataUtil.synrTcp(nettyClient,mes_gw);
  211. }
  212. }
  213. }
  214. }
  215. }, 100,mes_heart_icon_cycle*1000);
  216. }
  217. //设置tcp连接状态显示
  218. public static void setTcpStatus() {
  219. if(tcp_connect_flag) {
  220. status_menu.setText("已连接MES服务器");
  221. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
  222. heart_beat_menu.repaint();
  223. }else {
  224. status_menu.setText("未连接MES服务器");
  225. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
  226. heart_beat_menu.repaint();
  227. }
  228. }
  229. public static void initWarehouseData(){
  230. resetScanA();
  231. }
  232. public static void resetScanA() {
  233. work_status = 0;
  234. check_quality_result = false;
  235. MesClient.finish_ok_bt.setEnabled(false);
  236. MesClient.finish_ng_bt.setEnabled(false);
  237. product_sn.setText("");
  238. batch_sn.setText("");
  239. // MesClient.f_scan_data_bt_1.setEnabled(true);
  240. MesClient.setMenuStatus("请扫工件码",0);
  241. updateMaterailData();
  242. getCheckResult();
  243. // 注释掉换班检查,避免自动退出
  244. // shiftUserCheck();
  245. }
  246. public static int userLoginHours;//用户登录所处小时
  247. //换班用户信息检查(已注释,避免早上8点自动关闭)
  248. /*
  249. private static void shiftUserCheck() {
  250. LocalDateTime now = LocalDateTime.now();
  251. // 判断时间范围
  252. if (userLoginHours >= 8 && userLoginHours < 20) {
  253. int hour = now.getHour();
  254. if (hour >= 20 || hour < 8) {
  255. logoff();
  256. }
  257. } else {
  258. int hour = now.getHour();
  259. if (hour >= 8 && hour < 20) {
  260. logoff();
  261. }
  262. }
  263. }
  264. */
  265. public static void resetScanB() {
  266. }
  267. //获取用户20位
  268. public static void getUser() {
  269. user20 = user_menu.getText().toString();
  270. String space_tmp1 = "";
  271. if(user20.length()<20) {
  272. for(int i=0;i<20-user20.length();i++) {
  273. space_tmp1 = space_tmp1 + " ";
  274. }
  275. }
  276. user20 = user20 + space_tmp1;
  277. }
  278. //获取barcode内容36位
  279. public static String getBarcode(String barcodeTmp) {
  280. String barcodeRet = barcodeTmp;
  281. if(barcodeTmp.equalsIgnoreCase("")) {
  282. return "";
  283. }else {
  284. if(barcodeTmp.length()<36) {
  285. String space = "";
  286. for(int i=0;i<36-barcodeTmp.length();i++) {
  287. space = space + " ";
  288. }
  289. barcodeRet = barcodeTmp + space;
  290. }
  291. }
  292. return barcodeRet;
  293. }
  294. public static void setMenuStatus(String msg,int error){
  295. if(error == 0){
  296. MesClient.status_menu.setForeground(Color.GREEN);
  297. }else{
  298. MesClient.status_menu.setForeground(Color.RED);
  299. }
  300. MesClient.status_menu.setText(msg);
  301. }
  302. public static void scanBarcode() {
  303. String scanBarcodeTitle = "";
  304. switch(scan_type) {
  305. case 1:
  306. product_sn.setText("");
  307. scanBarcodeTitle = "请扫工件码";
  308. break;
  309. case 2:
  310. batch_sn.setText("");
  311. scanBarcodeTitle = "请扫物料批次码";
  312. break;
  313. }
  314. //弹窗扫工件码
  315. String scanBarcode = JOptionPane.showInputDialog(null, scanBarcodeTitle);
  316. if(scanBarcode!=null&&!scanBarcode.equalsIgnoreCase("")) {
  317. //获取用户
  318. getUser();
  319. //获取扫码内容36位
  320. String barcode36 = getBarcode(scanBarcode);//处理36为码
  321. //工位号
  322. String gw = "";
  323. switch(scan_type) {
  324. case 1:
  325. product_sn.setText(scanBarcode);
  326. break;
  327. case 2:
  328. batch_sn.setText(scanBarcode);
  329. break;
  330. }
  331. //刷新界面
  332. mesClientFrame.repaint();
  333. if(!tcp_connect_flag) {
  334. MesClient.setMenuStatus("设备未连接Mes服务器",1);
  335. // JOptionPane.showMessageDialog(mesClientFrame,"设备未连接Mes服务器","提示窗口", JOptionPane.INFORMATION_MESSAGE);
  336. return;
  337. }
  338. // if(!product_sn.getText().isEmpty() && !batch_sn.getText().isEmpty()){
  339. // finish_ok_bt.setEnabled(true);
  340. // finish_ng_bt.setEnabled(true);
  341. // }
  342. if(!product_sn.getText().isEmpty()){
  343. // 扫码后自动提交OK
  344. String sn = getBarcode(product_sn.getText());
  345. if(!sn.isEmpty()){
  346. String qret = "OK";
  347. Boolean sendret = DataUtil.sendCreate(nettyClient,sn,qret,user20);
  348. if(!sendret){
  349. MesClient.setMenuStatus("消息发送失败,请重试",1);
  350. return;
  351. }
  352. // 提交成功后,弹出新的扫码框
  353. SwingUtilities.invokeLater(new Runnable() {
  354. @Override
  355. public void run() {
  356. scan_type = 1;
  357. scanBarcode();
  358. }
  359. });
  360. }
  361. }
  362. // 查询工件质量
  363. // Boolean sendret = DataUtil.checkQuality(nettyClient,barcode36,user20);
  364. // if(!sendret){
  365. // JOptionPane.showMessageDialog(mesClientFrame,"消息发送失败,请重试","提示窗口", JOptionPane.INFORMATION_MESSAGE);
  366. // return;
  367. // }
  368. }else {
  369. JOptionPane.showMessageDialog(mesClientFrame,"请扫工件码","提示窗口", JOptionPane.INFORMATION_MESSAGE);
  370. return;
  371. }
  372. }
  373. // 复用op040既有建档提交逻辑(原finish_ok_bt/finish_ng_bt里的sendCreate调用抽出来)
  374. // sn: 用于提交的编码(客户编码),qret: OK/NG
  375. public static boolean submitLaserResult(String sn, String qret){
  376. if(sn == null || sn.isEmpty()){
  377. setMenuStatus("客户编码为空,无法提交",1);
  378. return false;
  379. }
  380. getUser();
  381. String snPad = getBarcode(sn);
  382. Boolean sendret = DataUtil.sendCreate(nettyClient, snPad, qret, user20);
  383. if(!sendret){
  384. setMenuStatus("结果提交MES失败,请重试",1);
  385. return false;
  386. }
  387. return true;
  388. }
  389. // 初始化镭雕流程管理器
  390. public static void initLaserFlow(){
  391. laserFlowManager = new LaserFlowManager(new LaserFlowManager.UiCallback() {
  392. @Override
  393. public void onStatus(String msg, boolean error) {
  394. SwingUtilities.invokeLater(() -> setMenuStatus(msg, error ? 1 : 0));
  395. }
  396. @Override
  397. public void onLockButton(boolean lock) {
  398. SwingUtilities.invokeLater(() -> {
  399. if(laser_get_code_bt != null){
  400. laser_get_code_bt.setEnabled(!lock);
  401. }
  402. });
  403. }
  404. @Override
  405. public void onCodeReceived(String code) {
  406. SwingUtilities.invokeLater(() -> product_sn.setText(code));
  407. }
  408. @Override
  409. public boolean onSubmitResult(String customerSn, String qret) {
  410. return submitLaserResult(customerSn, qret);
  411. }
  412. });
  413. laserFlowManager.startCompleteServer();
  414. }
  415. public static void logoff() {
  416. // welcomeWin.setVisible(true);
  417. mesClientFrame.setVisible(false);
  418. if(laserFlowManager != null){
  419. laserFlowManager.stopCompleteServer();
  420. }
  421. nettyClient = null;
  422. // if(heartBeatTimer!=null) {
  423. // heartBeatTimer.cancel();
  424. // }
  425. // if(heartBeatIconTimer!=null) {
  426. // heartBeatIconTimer.cancel();
  427. // }
  428. tcp_connect_flag = false;
  429. connect_request_flag = false;
  430. }
  431. public MesClient() {
  432. setIconImage(Toolkit.getDefaultToolkit().getImage(MesClient.class.getResource("/bg/logo.png")));
  433. setTitle("MES系统客户端:"+mes_gw + "- " + mes_gw_des);
  434. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  435. setBounds(0, 0, 1024, 768);
  436. // 确保标题栏正确显示
  437. validate();
  438. JMenuBar menuBar = new JMenuBar();
  439. menuBar.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 26));
  440. setJMenuBar(menuBar);
  441. JMenu fileMenu = new JMenu("用户");
  442. fileMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/user.png")));
  443. fileMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  444. menuBar.add(fileMenu);
  445. JMenuItem exitMenuItem = new JMenuItem("退出");
  446. exitMenuItem.setIcon(new ImageIcon(MesClient.class.getResource("/bg/logoff.png")));
  447. exitMenuItem.setFont(new Font("微软雅黑", Font.PLAIN, 22));
  448. fileMenu.add(exitMenuItem);
  449. exitMenuItem.addMouseListener(new MouseAdapter() {
  450. @Override
  451. public void mousePressed(MouseEvent e) {//只能检测到mousePressed事件
  452. super.mouseClicked(e);
  453. //dispose();
  454. logoff();
  455. }
  456. });
  457. JMenu settingMenu = new JMenu("设置");
  458. //settingMenu.setVisible(false);
  459. settingMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/menu_setting.png")));
  460. settingMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  461. menuBar.add(settingMenu);
  462. JMenuItem resetTcpMenu = new JMenuItem("\u91CD\u8FDEMES");
  463. resetTcpMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/reset_logo.png")));
  464. resetTcpMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  465. resetTcpMenu.addMouseListener(new MouseAdapter() {
  466. @Override
  467. public void mousePressed(MouseEvent e) {
  468. super.mouseClicked(e);
  469. //重连mes
  470. nettyClient.future.channel().close();
  471. }
  472. });
  473. settingMenu.add(resetTcpMenu);
  474. JMenuItem resetTcpMenu_1 = new JMenuItem("刷新工件");
  475. resetTcpMenu_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/reset_logo.png")));
  476. resetTcpMenu_1.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  477. resetTcpMenu_1.addMouseListener(new MouseAdapter() {
  478. @Override
  479. public void mousePressed(MouseEvent e) {
  480. super.mouseClicked(e);
  481. resetScanA();
  482. }
  483. });
  484. settingMenu.add(resetTcpMenu_1);
  485. contentPane = new JPanel();
  486. contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  487. setContentPane(contentPane);
  488. contentPane.setLayout(new BorderLayout(0, 0));
  489. JToolBar toolBar = new JToolBar();
  490. contentPane.add(toolBar, BorderLayout.NORTH);
  491. JLabel equipment_statu_label = new JLabel("状态:");
  492. equipment_statu_label.setHorizontalAlignment(SwingConstants.CENTER);
  493. equipment_statu_label.setForeground(Color.BLACK);
  494. equipment_statu_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  495. equipment_statu_label.setBackground(Color.LIGHT_GRAY);
  496. toolBar.add(equipment_statu_label);
  497. status_menu = new JButton("设备未连接MES服务器");
  498. if(tcp_connect_flag) {
  499. status_menu.setText("已连接MES服务器");
  500. status_menu.setForeground(Color.GREEN);
  501. }else {
  502. status_menu.setText("未连接MES服务器");
  503. status_menu.setForeground(Color.DARK_GRAY);
  504. }
  505. status_menu.addActionListener(new ActionListener() {
  506. public void actionPerformed(ActionEvent e) {
  507. }
  508. });
  509. status_menu.setForeground(Color.GREEN);
  510. status_menu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  511. status_menu.setBackground(Color.BLACK);
  512. toolBar.add(status_menu);
  513. JLabel space_1 = new JLabel(" ");
  514. toolBar.add(space_1);
  515. JLabel heart_beat_status_label = new JLabel("心跳:");
  516. heart_beat_status_label.setHorizontalAlignment(SwingConstants.CENTER);
  517. heart_beat_status_label.setForeground(Color.BLACK);
  518. heart_beat_status_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  519. heart_beat_status_label.setBackground(Color.LIGHT_GRAY);
  520. toolBar.add(heart_beat_status_label);
  521. heart_beat_menu = new JButton("2024-02-20 23:20:10");
  522. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")));
  523. heart_beat_menu.setForeground(Color.GREEN);
  524. heart_beat_menu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  525. heart_beat_menu.setBackground(Color.BLACK);
  526. toolBar.add(heart_beat_menu);
  527. JLabel space_2 = new JLabel(" ");
  528. toolBar.add(space_2);
  529. JLabel user_status_label = new JLabel("登录用户:");
  530. user_status_label.setHorizontalAlignment(SwingConstants.CENTER);
  531. user_status_label.setForeground(Color.BLACK);
  532. user_status_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  533. user_status_label.setBackground(Color.LIGHT_GRAY);
  534. toolBar.add(user_status_label);
  535. user_menu = new JButton("JinJuShi");
  536. user_menu.setForeground(Color.GREEN);
  537. user_menu.setFont(new Font("微软雅黑", Font.PLAIN, 22));
  538. user_menu.setBackground(Color.BLACK);
  539. toolBar.add(user_menu);
  540. JLabel space_3 = new JLabel(" ");
  541. toolBar.add(space_3);
  542. JLabel space_4 = new JLabel(" ");
  543. toolBar.add(space_4);
  544. tabbedPane = new JTabbedPane(JTabbedPane.TOP);
  545. tabbedPane.setMinimumSize(new Dimension(400, 50));
  546. tabbedPane.setFont(new Font("宋体", Font.BOLD, 22));
  547. contentPane.add(tabbedPane);
  548. //首页
  549. JPanel indexPanelA = new JPanel();
  550. indexScrollPaneA = new JScrollPane(indexPanelA);
  551. indexPanelA.setLayout(null);
  552. // 镭雕:获取镭雕码 / 复位按钮,放在扫码框(回显框)上方
  553. laser_get_code_bt = new JButton("获取镭雕码");
  554. laser_get_code_bt.addActionListener(new ActionListener() {
  555. public void actionPerformed(ActionEvent e) {
  556. laserFlowManager.startLaserFlow(mes_gw, mes_line_sn);
  557. }
  558. });
  559. laser_get_code_bt.setFont(new Font("微软雅黑", Font.PLAIN, 24));
  560. laser_get_code_bt.setBounds(81, 40, 300, 50);
  561. indexPanelA.add(laser_get_code_bt);
  562. // 镭雕:人工复位按钮(完成信号超时或异常时使用,强制解锁并作废当前请求)
  563. laser_reset_bt = new JButton("复位");
  564. laser_reset_bt.addActionListener(new ActionListener() {
  565. public void actionPerformed(ActionEvent e) {
  566. laserFlowManager.manualReset();
  567. }
  568. });
  569. laser_reset_bt.setFont(new Font("微软雅黑", Font.PLAIN, 24));
  570. laser_reset_bt.setBounds(400, 40, 150, 50);
  571. indexPanelA.add(laser_reset_bt);
  572. product_sn = new JTextField();
  573. product_sn.setHorizontalAlignment(SwingConstants.CENTER);
  574. product_sn.setEditable(false);
  575. product_sn.setFont(new Font("微软雅黑", Font.PLAIN, 28));
  576. product_sn.setBounds(81, 100, 602, 70);
  577. indexPanelA.add(product_sn);
  578. product_sn.setColumns(10);
  579. // 原扫码按钮不再需要,隐藏但保留逻辑(scanBarcode等方法仍被其他流程复用)
  580. f_scan_data_bt_1 = new JButton("扫码");
  581. f_scan_data_bt_1.addActionListener(new ActionListener() {
  582. public void actionPerformed(ActionEvent e) {
  583. scan_type = 1;
  584. scanBarcode();
  585. }
  586. });
  587. f_scan_data_bt_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/scan_barcode.png")));
  588. f_scan_data_bt_1.setFont(new Font("微软雅黑", Font.PLAIN, 32));
  589. f_scan_data_bt_1.setBounds(693, 100, 198, 70);
  590. f_scan_data_bt_1.setVisible(false);
  591. indexPanelA.add(f_scan_data_bt_1);
  592. JLabel batch_label = new JLabel("绑定物料批次码");
  593. batch_label.setHorizontalAlignment(SwingConstants.CENTER);
  594. batch_label.setForeground(Color.BLACK);
  595. batch_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  596. batch_label.setBackground(Color.LIGHT_GRAY);
  597. batch_label.setBounds(81, 140, 602, 70);
  598. // indexPanelA.add(batch_label);
  599. batch_sn = new JTextField();
  600. batch_sn.setHorizontalAlignment(SwingConstants.CENTER);
  601. batch_sn.setEditable(false);
  602. batch_sn.setFont(new Font("微软雅黑", Font.PLAIN, 28));
  603. batch_sn.setBounds(81, 210, 602, 70);
  604. // indexPanelA.add(batch_sn);
  605. batch_sn.setColumns(10);
  606. batch_sn_btn = new JButton("扫码");
  607. batch_sn_btn.addActionListener(new ActionListener() {
  608. public void actionPerformed(ActionEvent e) {
  609. scan_type = 2;
  610. scanBarcode();
  611. }
  612. });
  613. batch_sn_btn.setIcon(new ImageIcon(MesClient.class.getResource("/bg/scan_barcode.png")));
  614. batch_sn_btn.setFont(new Font("微软雅黑", Font.PLAIN, 32));
  615. batch_sn_btn.setBounds(693, 210, 198, 70);
  616. // indexPanelA.add(batch_sn_btn);
  617. // String[] hjtitles = new String[]{"焊机1","焊机2","焊机3"};
  618. // String[] hjvals = new String[]{"HJ001","HJ002","HJ003"};
  619. // mesRadioHj = new MesRadio(hjtitles,hjvals);
  620. // mesRadioHj.setSize(500,50);
  621. // mesRadioHj.setBounds(190,170,500,50);
  622. // indexPanelA.add(mesRadioHj);
  623. finish_ok_bt = new JButton("OK");
  624. finish_ok_bt.setEnabled(false);
  625. finish_ok_bt.addActionListener(new ActionListener() {
  626. public void actionPerformed(ActionEvent e) {
  627. String sn = getBarcode(product_sn.getText());
  628. // String batchsn = getBarcode(batch_sn.getText());
  629. if(sn.isEmpty()){
  630. MesClient.setMenuStatus("请扫工件码",1);
  631. return;
  632. }
  633. // if(batchsn.isEmpty()){
  634. // MesClient.setMenuStatus("请扫物料批次码",1);
  635. // return;
  636. // }
  637. getUser();
  638. String qret = "OK";
  639. Boolean sendret = DataUtil.sendCreate(nettyClient,sn,qret,user20);
  640. if(!sendret){
  641. MesClient.setMenuStatus("消息发送失败,请重试",1);
  642. // JOptionPane.showMessageDialog(mesClientFrame,"消息发送失败,请重试","提示窗口", JOptionPane.INFORMATION_MESSAGE);
  643. return;
  644. }
  645. }
  646. });
  647. finish_ok_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ok_bg.png")));
  648. finish_ok_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32));
  649. finish_ok_bt.setBounds(185, 341, 240, 80);
  650. finish_ok_bt.setEnabled(false);
  651. // 镭雕工位不需要手动点OK,完成信号收到后自动提交,隐藏但保留逻辑复用
  652. finish_ok_bt.setVisible(false);
  653. indexPanelA.add(finish_ok_bt);
  654. finish_ng_bt = new JButton("NG");
  655. finish_ng_bt.setEnabled(false);
  656. finish_ng_bt.addActionListener(new ActionListener() {
  657. public void actionPerformed(ActionEvent e) {
  658. String sn = getBarcode(product_sn.getText());
  659. // String batchsn = getBarcode(batch_sn.getText());
  660. if(sn.isEmpty()){
  661. MesClient.setMenuStatus("请扫工件码",1);
  662. return;
  663. }
  664. // if(batchsn.isEmpty()){
  665. // MesClient.setMenuStatus("请扫物料批次码",1);
  666. // return;
  667. // }
  668. getUser();
  669. String qret = "NG";
  670. Boolean sendret = DataUtil.sendCreate(nettyClient,sn,qret,user20);
  671. if(!sendret){
  672. MesClient.setMenuStatus("消息发送失败,请重试",1);
  673. // JOptionPane.showMessageDialog(mesClientFrame,"消息发送失败,请重试","提示窗口", JOptionPane.INFORMATION_MESSAGE);
  674. return;
  675. }
  676. }
  677. });
  678. finish_ng_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ng_bg.png")));
  679. finish_ng_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32));
  680. finish_ng_bt.setBounds(508, 341, 240, 80);
  681. finish_ng_bt.setEnabled(false);
  682. // 镭雕工位不需要手动点NG,隐藏但保留逻辑复用
  683. finish_ng_bt.setVisible(false);
  684. indexPanelA.add(finish_ng_bt);
  685. // ===== 调试面板:供应商真实接口未接通前,用于模拟镭雕软件回传的各阶段信号 =====
  686. JLabel debugTitle = new JLabel("调试面板(模拟镭雕软件信号)");
  687. debugTitle.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  688. debugTitle.setForeground(Color.GRAY);
  689. debugTitle.setBounds(760, 40, 260, 30);
  690. indexPanelA.add(debugTitle);
  691. JTextField debugSteelSnInput = new JTextField();
  692. debugSteelSnInput.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  693. debugSteelSnInput.setBounds(760, 80, 220, 40);
  694. debugSteelSnInput.setToolTipText("输入测试用钢印码,留空则自动生成");
  695. indexPanelA.add(debugSteelSnInput);
  696. JButton debugSimGetCodeBtn = new JButton("模拟获取镭雕码");
  697. debugSimGetCodeBtn.addActionListener(new ActionListener() {
  698. public void actionPerformed(ActionEvent e) {
  699. laserFlowManager.simulateGetCode(debugSteelSnInput.getText());
  700. }
  701. });
  702. debugSimGetCodeBtn.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  703. debugSimGetCodeBtn.setBounds(760, 130, 220, 50);
  704. indexPanelA.add(debugSimGetCodeBtn);
  705. JButton debugSimOkBtn = new JButton("模拟完成信号(OK)");
  706. debugSimOkBtn.addActionListener(new ActionListener() {
  707. public void actionPerformed(ActionEvent e) {
  708. laserFlowManager.simulateComplete("OK", "");
  709. }
  710. });
  711. debugSimOkBtn.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  712. debugSimOkBtn.setBounds(760, 190, 220, 50);
  713. indexPanelA.add(debugSimOkBtn);
  714. JButton debugSimNgBtn = new JButton("模拟完成信号(NG)");
  715. debugSimNgBtn.addActionListener(new ActionListener() {
  716. public void actionPerformed(ActionEvent e) {
  717. laserFlowManager.simulateComplete("NG", "模拟打码失败");
  718. }
  719. });
  720. debugSimNgBtn.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  721. debugSimNgBtn.setBounds(760, 250, 220, 50);
  722. indexPanelA.add(debugSimNgBtn);
  723. JButton debugGenSnBtn = new JButton("测试生成客户编码");
  724. debugGenSnBtn.addActionListener(new ActionListener() {
  725. public void actionPerformed(ActionEvent e) {
  726. laserFlowManager.manualGenCustomerSn(debugSteelSnInput.getText());
  727. }
  728. });
  729. debugGenSnBtn.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  730. debugGenSnBtn.setBounds(760, 310, 220, 50);
  731. indexPanelA.add(debugGenSnBtn);
  732. // ===== 调试面板结束 =====
  733. JButton modbusBtn = new JButton("关");
  734. modbusBtn.addActionListener(new ActionListener() {
  735. public void actionPerformed(ActionEvent e) {
  736. ModbusRtu.closeDevice(serialPort);
  737. }
  738. });
  739. modbusBtn.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  740. modbusBtn.setBounds(208, 241, 160, 60);
  741. // indexPanelA.add(modbusBtn);
  742. JButton modbusBtn2 = new JButton("开");
  743. modbusBtn2.addActionListener(new ActionListener() {
  744. public void actionPerformed(ActionEvent e) {
  745. ModbusRtu.openDevice(serialPort);
  746. }
  747. });
  748. modbusBtn2.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  749. modbusBtn2.setBounds(388, 241, 160, 60);
  750. // indexPanelA.add(modbusBtn2);
  751. JButton modbusBtn3 = new JButton("查询");
  752. modbusBtn3.addActionListener(new ActionListener() {
  753. public void actionPerformed(ActionEvent e) {
  754. ModbusRtu.readCoil(serialPort,0);
  755. }
  756. });
  757. modbusBtn3.setFont(new Font("微软雅黑", Font.PLAIN, 16));
  758. modbusBtn3.setBounds(568, 241, 160, 60);
  759. // indexPanelA.add(modbusBtn3);
  760. tabbedPane.addTab("工作面板", new ImageIcon(MesClient.class.getResource("/bg/a_side.png")), indexScrollPaneA, null);
  761. tabbedPane.setEnabledAt(0, true);
  762. // searchScrollPane = new JScrollPane((Component) null);
  763. indexPanelC = new JPanel();
  764. searchScrollPaneDj = new JScrollPane(indexPanelC);
  765. indexPanelC.setLayout(null);
  766. tabbedPane.addTab("开班点检", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), searchScrollPaneDj, null);
  767. indexPanelB = new JPanel();
  768. searchScrollPane = new JScrollPane(indexPanelB);
  769. indexPanelB.setLayout(null);
  770. tabbedPane.addTab("工作记录", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), searchScrollPane, null);
  771. tabbedPane.addChangeListener(new ChangeListener() {
  772. @Override
  773. public void stateChanged(ChangeEvent e) {
  774. JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
  775. int selectedIndex = tabbedPane.getSelectedIndex();
  776. System.out.println("selectedIndex:"+selectedIndex);
  777. if(selectedIndex == 0){
  778. // 创建一个单线程的ExecutorService
  779. ExecutorService executorService = Executors.newSingleThreadExecutor();
  780. // 提交一个异步任务
  781. executorService.submit(() -> {
  782. System.out.println("异步线程正在运行...");
  783. // 在这里执行异步操作
  784. getCheckResult();
  785. });
  786. // 关闭ExecutorService,以优雅的方式
  787. executorService.shutdown();
  788. }
  789. }
  790. });
  791. // 确保窗口布局正确
  792. pack();
  793. setSize(1024, 768);
  794. validate();
  795. repaint();
  796. }
  797. // 获取开班点检状态
  798. public static void getCheckResult(){
  799. try{
  800. JSONObject retObj = DataUtil.getCheckResult();
  801. if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) { // 已点检
  802. MesClient.checkState = true;
  803. }else{ // 未点检
  804. MesClient.checkState = false;
  805. }
  806. }catch (Exception e){
  807. e.printStackTrace();
  808. MesClient.checkState = false;
  809. }
  810. MesClient.formatDeviceState();
  811. }
  812. // 格式化设备启动状态
  813. public static void formatDeviceState(){
  814. try{
  815. if(MesClient.checkState){ // 检查物料是否已绑定
  816. if(rowData == null){
  817. ModbusRtu.openDevice(serialPort);
  818. }else{
  819. // 判断物料是否可启动
  820. int flag = 0;
  821. int i = 0;
  822. for (Object object:rowData){
  823. Integer times = Integer.valueOf(String.valueOf(rowData[i][2]));
  824. if(times < 1){
  825. flag = 1;
  826. }
  827. i++;
  828. }
  829. if(flag == 1){ // 不能启动
  830. ModbusRtu.closeDevice(serialPort);
  831. }else{
  832. // 可启动
  833. ModbusRtu.openDevice(serialPort);
  834. }
  835. }
  836. }else{
  837. //不能启动
  838. ModbusRtu.closeDevice(serialPort);
  839. }
  840. }catch (Exception e){
  841. e.printStackTrace();
  842. }
  843. }
  844. public static void getMaterailData(){
  845. JSONObject retObj = DataUtil.getBindMaterail();
  846. if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
  847. java.util.List<BindMaterialResp> arrs = retObj.getList("data",BindMaterialResp.class);
  848. int i = 0;
  849. rowData = new Object[arrs.size()][7];
  850. for (BindMaterialResp bindMaterialResp:arrs){
  851. rowData[i][0] = bindMaterialResp.getMaterialTitle();
  852. rowData[i][1] = bindMaterialResp.getBatchSn();
  853. rowData[i][2] = bindMaterialResp.getLastTimes();
  854. rowData[i][3] = "";
  855. rowData[i][4] = bindMaterialResp.getCraft();
  856. rowData[i][5] = bindMaterialResp.getMaterialId();
  857. rowData[i][6] = bindMaterialResp.getType();
  858. i++;
  859. }
  860. bindBatchPanel();
  861. }
  862. }
  863. public static void updateMaterailData(){
  864. JSONObject retObj = DataUtil.getBindMaterail();
  865. if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
  866. List<BindMaterialResp> arrs = retObj.getList("data",BindMaterialResp.class);
  867. int i = 0;
  868. for (BindMaterialResp bindMaterialResp:arrs){
  869. rowData[i][0] = bindMaterialResp.getMaterialTitle();
  870. rowData[i][1] = bindMaterialResp.getBatchSn();
  871. rowData[i][2] = bindMaterialResp.getLastTimes();
  872. rowData[i][3] = "";
  873. rowData[i][4] = bindMaterialResp.getCraft();
  874. rowData[i][5] = bindMaterialResp.getMaterialId();
  875. rowData[i][6] = bindMaterialResp.getType();
  876. i++;
  877. }
  878. MesClient.table.repaint();
  879. }
  880. }
  881. // 绑定物料批次码
  882. public static void scanBatchSn(BindMaterialResp bindMaterialResp) {
  883. //弹窗扫工件码
  884. String scanBarcodeTitle = "请扫物料:"+bindMaterialResp.getMaterialTitle();
  885. String scanBarcode = JOptionPane.showInputDialog(null, scanBarcodeTitle);
  886. if(scanBarcode!=null&&!scanBarcode.equalsIgnoreCase("")) {
  887. JSONObject retObj = DataUtil.saveBindMaterail(scanBarcode,bindMaterialResp.getCraft(),bindMaterialResp.getMaterialId(),bindMaterialResp.getType());
  888. if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
  889. MesClient.setMenuStatus("扫物料:"+bindMaterialResp.getMaterialTitle()+"成功",0);
  890. updateMaterailData();
  891. }else{
  892. if(retObj.get("result")==null){
  893. MesClient.setMenuStatus("请求失败,请重试",-1);
  894. }else{
  895. if(retObj.get("result").toString().equalsIgnoreCase("false")){
  896. MesClient.setMenuStatus(retObj.getString("message"),-1);
  897. }
  898. }
  899. }
  900. }
  901. }
  902. public static void bindBatchPanel(){
  903. JPanel indexPanelBB = new JPanel();
  904. JPanel panel = new JPanel();
  905. panel.setBounds(0, 0, 990, 550);
  906. // panel.setBounds(81, 50, 810, 479);
  907. indexPanelBB.add(panel);
  908. panel.setLayout(new GridLayout(0, 1, 0, 0));
  909. table = new JTable(rowData, columnNames){
  910. public boolean isCellEditable(int row, int column) {
  911. if(column == 3){
  912. return true;
  913. }
  914. return false;
  915. }
  916. };
  917. table.setRowHeight(40);
  918. table.setEnabled(true);
  919. table.setFont(new Font("微软雅黑", Font.PLAIN, 14));
  920. table.getColumnModel().getColumn(3).setCellRenderer(new TableCellRendererButton());
  921. table.getColumnModel().getColumn(3).setCellEditor(new TableCellEditorButton());
  922. JScrollPane scrollPane = new JScrollPane(table);
  923. panel.add(scrollPane);
  924. JScrollPane indexScrollPaneB = new JScrollPane(indexPanelBB);
  925. indexPanelBB.setLayout(null);
  926. tabbedPane.addTab("绑定物料", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), indexScrollPaneB, null);
  927. }
  928. }