MesClient.java 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. package com.mes.ui;
  2. import com.alibaba.fastjson2.JSON;
  3. import com.alibaba.fastjson2.JSONObject;
  4. import com.google.zxing.BarcodeFormat;
  5. import com.google.zxing.client.j2se.MatrixToImageWriter;
  6. import com.google.zxing.common.BitMatrix;
  7. import com.google.zxing.qrcode.QRCodeWriter;
  8. import com.mes.component.*;
  9. import com.mes.util.DateLocalUtils;
  10. import com.mes.util.JdbcUtils;
  11. import com.mes.util.TCPClient;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import javax.swing.*;
  15. import javax.swing.border.EmptyBorder;
  16. import javax.swing.event.ChangeEvent;
  17. import javax.swing.event.ChangeListener;
  18. import java.awt.*;
  19. import java.awt.event.*;
  20. import java.awt.image.BufferedImage;
  21. import java.io.BufferedReader;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.io.InputStreamReader;
  25. import java.util.List;
  26. import java.util.Properties;
  27. import java.util.Timer;
  28. import java.util.TimerTask;
  29. public class MesClient extends JFrame {
  30. public static final Logger log = LoggerFactory.getLogger(MesClient.class);
  31. private static String Drivde = "org.sqlite.JDBC";
  32. public static int mes_auth = 0; // 权限级别 0=无权限 1=操作工人 2=管理员
  33. public static String mes_gw = ""; // 工位号
  34. public static String mes_gw_des = ""; // 工位名称
  35. public static String mes_server_ip = ""; // 服务器IP地址
  36. public static String mes_line_sn = ""; // 产线编号
  37. public static String mes_line_pos = "";
  38. //session
  39. public static String sessionid = "";
  40. // public static String preSn = "";
  41. public static volatile String preSn = "";
  42. public static JPanel contentPane;
  43. public static MesClient mesClientFrame;
  44. public static JTabbedPane tabbedPane;
  45. public static JScrollPane indexScrollPaneA;
  46. public static JScrollPane indexScrollPaneB;
  47. public static JScrollPane indexScrollPaneC;
  48. public static JScrollPane indexScrollPaneD;
  49. // public static JScrollPane searchScrollPane; // 已弃用,改为使用 WorkRecordPanel
  50. public static int isLogin = 0;
  51. public static Boolean check_quality_result = false;
  52. public static Integer work_status = 0;
  53. public static JButton heart_beat_menu;
  54. public static JButton status_menu;
  55. public static JButton user_menu;
  56. public static JFrame welcomeWin;
  57. // public static JPanel indexPanelWork; // 已弃用,改为使用 WorkRecordPanel
  58. public static JTable table;
  59. public static Object[] columnNames = { "物料名称", "绑定批次", "剩余次数", "操作" };
  60. public static Object[][] rowData = null;
  61. public static WorkJPanelOP60 workJPanelOP60;
  62. public static WorkJPanelOP60 workJPanelOP60B; // 封板正面FSW2(新增设备DB7004,C=西/D=东)
  63. public static WorkJPanelOP60Transfer workJPanelOP60Transfer;
  64. public static WorkJPanelOP70Transfer workJPanelOP70Transfer;
  65. public static WorkJPanel70Xh workJPanel70XhFront; // 正面换型台(OP070,扫码按OP070方式)
  66. public static WorkJPanelOP65 workJPanelOP65A;
  67. public static WorkJPanelOP70 workJPanelOP70A;
  68. public static WorkJPanelOP70 workJPanelOP70B;
  69. public static WorkJPanelOP70 workJPanelOP70C;
  70. public static WorkJPanel70Xh workJPanel70Xh;
  71. public static TCPClient tcpClient1 = new TCPClient("192.168.90.58",9004); // 60A
  72. public static TCPClient tcpClient2 = new TCPClient("192.168.90.60",9004); // 70ABC
  73. public static TCPClient tcpClient3 = new TCPClient("192.168.90.57",9004); // 60B
  74. public static TCPClient tcpClient4 = new TCPClient("192.168.90.59",9004); // 70EFG
  75. public static int scanFlag1 = 0;
  76. public static int scanFlag2 = 0;
  77. public static int scanFlag3 = 0;
  78. public static int scanFlag4 = 0;
  79. // 扫码手动输入开关(测试用,模拟扫码枪输入),每次启动默认关闭
  80. public static volatile boolean manualScanEnabled = false;
  81. public static void main(String[] args) {
  82. EventQueue.invokeLater(new Runnable() {
  83. @Override
  84. public void run() {
  85. try{
  86. //读文件配置
  87. readProperty();
  88. JdbcUtils.getConn();
  89. // 显示界面
  90. mesClientFrame = new MesClient();
  91. mesClientFrame.setVisible(false);
  92. welcomeWin = new LoginFarme();
  93. welcomeWin.setVisible(true);
  94. startHeartBeatTimer();
  95. upParams();
  96. }catch (Exception e){
  97. log.error(e.getMessage());
  98. }
  99. }
  100. });
  101. }
  102. //读配置文件
  103. private static void readProperty() throws IOException{
  104. String enconding = "UTF-8";
  105. InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
  106. Properties pro = new Properties();
  107. BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
  108. pro.load(br);
  109. mes_gw = pro.getProperty("mes.gw");
  110. mes_gw_des = pro.getProperty("mes.gw_des");
  111. mes_server_ip = pro.getProperty("mes.server_ip");
  112. // mes_tcp_port = Integer.parseInt(pro.getProperty("mes.tcp_port"));
  113. // mes_heart_beat_cycle = Integer.parseInt(pro.getProperty("mes.heart_beat_cycle"));
  114. mes_line_sn = pro.getProperty("mes.line_sn");
  115. mes_line_pos = pro.getProperty("mes.line_pos");
  116. // mes_gw_des = OprnoUtil.getGwDes(mes_line_sn,mes_gw);
  117. // log.info(mes_gw + ";" + mes_gw_des + ";" + mes_server_ip + ";" + mes_tcp_port + ";" + mes_heart_beat_cycle);
  118. }
  119. //启动心跳包程序
  120. public static java.util.Timer heartBeatIconTimer;
  121. public static boolean iconREDFlag = true;
  122. public static void startHeartBeatTimer() {
  123. //心跳显示图标
  124. if(heartBeatIconTimer!=null) {
  125. heartBeatIconTimer.cancel();
  126. }
  127. heartBeatIconTimer = new Timer();
  128. heartBeatIconTimer.schedule(new TimerTask() {
  129. public void run() {
  130. if(iconREDFlag) {
  131. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")));
  132. iconREDFlag = false;
  133. }else {
  134. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")));
  135. iconREDFlag = true;
  136. }
  137. heart_beat_menu.setText(DateLocalUtils.getCurrentTime());
  138. heart_beat_menu.repaint();
  139. }
  140. }, 100,1000);
  141. }
  142. public static void initWarehouseData(){
  143. resetScanA();
  144. }
  145. public static void resetScanA() {
  146. MesClient.setMenuStatus("请扫工件码",0);
  147. }
  148. public static void logoff() {
  149. mesClientFrame.setVisible(false);
  150. //退出程序 退出登录
  151. // 释放窗口资源并关闭窗口
  152. System.exit(0);
  153. }
  154. public MesClient() {
  155. setIconImage(Toolkit.getDefaultToolkit().getImage(MesClient.class.getResource("/bg/logo.png")));
  156. setTitle("MES系统客户端:OP70-OP80");
  157. // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  158. // setBounds(0, 0, 1920, 1080);
  159. setBounds(0, 0, 1024, 768);
  160. setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); // 防止默认的关闭操作
  161. // 添加窗口监听器
  162. addWindowListener(new WindowAdapter() {
  163. @Override
  164. public void windowClosing(WindowEvent e) {
  165. int choice = JOptionPane.showConfirmDialog(null, "确定要关闭窗口吗?", "关闭确认", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
  166. if (choice == JOptionPane.YES_OPTION) {
  167. // 如果用户点击“是”,则关闭窗口
  168. dispose(); // 释放窗口资源并关闭窗口
  169. System.exit(0);
  170. }
  171. }
  172. });
  173. JMenuBar menuBar = new JMenuBar();
  174. menuBar.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 26));
  175. setJMenuBar(menuBar);
  176. JMenu fileMenu = new JMenu("用户");
  177. fileMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/user.png")));
  178. fileMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  179. menuBar.add(fileMenu);
  180. JMenuItem exitMenuItem = new JMenuItem("退出");
  181. exitMenuItem.setIcon(new ImageIcon(MesClient.class.getResource("/bg/logoff.png")));
  182. exitMenuItem.setFont(new Font("微软雅黑", Font.PLAIN, 22));
  183. fileMenu.add(exitMenuItem);
  184. exitMenuItem.addMouseListener(new MouseAdapter() {
  185. @Override
  186. public void mousePressed(MouseEvent e) {//只能检测到mousePressed事件
  187. super.mouseClicked(e);
  188. //dispose();
  189. logoff();
  190. }
  191. });
  192. JMenu settingMenu = new JMenu("设置");
  193. //settingMenu.setVisible(false);
  194. settingMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/menu_setting.png")));
  195. settingMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  196. menuBar.add(settingMenu);
  197. JMenuItem resetTcpMenu_1 = new JMenuItem("刷新工件");
  198. resetTcpMenu_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/reset_logo.png")));
  199. resetTcpMenu_1.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  200. resetTcpMenu_1.addMouseListener(new MouseAdapter() {
  201. @Override
  202. public void mousePressed(MouseEvent e) {
  203. super.mouseClicked(e);
  204. resetScanA();
  205. }
  206. });
  207. // settingMenu.add(resetTcpMenu_1);
  208. // 扫码手动输入开关:开启绿色/关闭红色,开启后换型台面板显示手动输入行
  209. JMenuItem manualScanMenu = new JMenuItem();
  210. manualScanMenu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  211. refreshManualScanMenu(manualScanMenu);
  212. manualScanMenu.addActionListener(e -> {
  213. manualScanEnabled = !manualScanEnabled;
  214. log.info("扫码手动输入" + (manualScanEnabled ? "已开启" : "已关闭") + ",操作人:" + user_menu.getText());
  215. refreshManualScanMenu(manualScanMenu);
  216. if (workJPanel70XhFront != null) workJPanel70XhFront.setManualMode(manualScanEnabled);
  217. if (workJPanel70Xh != null) workJPanel70Xh.setManualMode(manualScanEnabled);
  218. });
  219. settingMenu.add(manualScanMenu);
  220. contentPane = new JPanel();
  221. contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  222. setContentPane(contentPane);
  223. contentPane.setLayout(new BorderLayout(0, 0));
  224. JToolBar toolBar = new JToolBar();
  225. contentPane.add(toolBar, BorderLayout.NORTH);
  226. JLabel equipment_statu_label = new JLabel("状态:");
  227. equipment_statu_label.setHorizontalAlignment(SwingConstants.CENTER);
  228. equipment_statu_label.setForeground(Color.BLACK);
  229. equipment_statu_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  230. equipment_statu_label.setBackground(Color.LIGHT_GRAY);
  231. toolBar.add(equipment_statu_label);
  232. status_menu = new JButton("已连接MES服务器");
  233. status_menu.setForeground(Color.GREEN);
  234. status_menu.addActionListener(new ActionListener() {
  235. public void actionPerformed(ActionEvent e) {
  236. }
  237. });
  238. status_menu.setForeground(Color.GREEN);
  239. status_menu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  240. status_menu.setBackground(Color.BLACK);
  241. toolBar.add(status_menu);
  242. JLabel space_1 = new JLabel(" ");
  243. toolBar.add(space_1);
  244. JLabel heart_beat_status_label = new JLabel("心跳:");
  245. heart_beat_status_label.setHorizontalAlignment(SwingConstants.CENTER);
  246. heart_beat_status_label.setForeground(Color.BLACK);
  247. heart_beat_status_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  248. heart_beat_status_label.setBackground(Color.LIGHT_GRAY);
  249. toolBar.add(heart_beat_status_label);
  250. heart_beat_menu = new JButton("");
  251. heart_beat_menu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")));
  252. heart_beat_menu.setForeground(Color.GREEN);
  253. heart_beat_menu.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  254. heart_beat_menu.setBackground(Color.BLACK);
  255. toolBar.add(heart_beat_menu);
  256. JLabel space_2 = new JLabel(" ");
  257. toolBar.add(space_2);
  258. JLabel user_status_label = new JLabel("登录用户:");
  259. user_status_label.setHorizontalAlignment(SwingConstants.CENTER);
  260. user_status_label.setForeground(Color.BLACK);
  261. user_status_label.setFont(new Font("微软雅黑", Font.PLAIN, 20));
  262. user_status_label.setBackground(Color.LIGHT_GRAY);
  263. toolBar.add(user_status_label);
  264. user_menu = new JButton("");
  265. user_menu.setForeground(Color.GREEN);
  266. user_menu.setFont(new Font("微软雅黑", Font.PLAIN, 22));
  267. user_menu.setBackground(Color.BLACK);
  268. toolBar.add(user_menu);
  269. JLabel space_3 = new JLabel(" ");
  270. toolBar.add(space_3);
  271. JLabel space_4 = new JLabel(" ");
  272. toolBar.add(space_4);
  273. tabbedPane = new JTabbedPane(JTabbedPane.TOP);
  274. tabbedPane.setMinimumSize(new Dimension(400, 50));
  275. tabbedPane.setFont(new Font("宋体", Font.BOLD, 22));
  276. contentPane.add(tabbedPane);
  277. JPanel indexPanelB = new JPanel();
  278. indexScrollPaneB = new JScrollPane(indexPanelB);
  279. indexPanelB.setLayout(new GridLayout(2,2, 5, 5));
  280. indexPanelB.setBackground(Color.LIGHT_GRAY);
  281. if(mes_line_pos.equals("west")){
  282. JPanel indexPanel60A = new JPanel();
  283. indexPanel60A.setLayout(null);
  284. indexPanel60A.setBackground(Color.WHITE);
  285. workJPanelOP60 = new WorkJPanelOP60("A");
  286. workJPanelOP60.setBounds(10, 10, workJPanelOP60.workWidth, workJPanelOP60.workHeight);
  287. indexPanel60A.add(workJPanelOP60);
  288. indexPanelB.add(indexPanel60A);
  289. // 封板正面FSW2(新增设备DB7004)
  290. JPanel indexPanel60B = new JPanel();
  291. indexPanel60B.setLayout(null);
  292. indexPanel60B.setBackground(Color.WHITE);
  293. workJPanelOP60B = new WorkJPanelOP60("C");
  294. workJPanelOP60B.setBounds(10, 10, workJPanelOP60B.workWidth, workJPanelOP60B.workHeight);
  295. indexPanel60B.add(workJPanelOP60B);
  296. indexPanelB.add(indexPanel60B);
  297. }else{
  298. JPanel indexPanel60A = new JPanel();
  299. indexPanel60A.setLayout(null);
  300. indexPanel60A.setBackground(Color.WHITE);
  301. workJPanelOP60 = new WorkJPanelOP60("B");
  302. workJPanelOP60.setBounds(10, 10, workJPanelOP60.workWidth, workJPanelOP60.workHeight);
  303. indexPanel60A.add(workJPanelOP60);
  304. indexPanelB.add(indexPanel60A);
  305. // 封板正面FSW2(新增设备DB7004)
  306. JPanel indexPanel60B = new JPanel();
  307. indexPanel60B.setLayout(null);
  308. indexPanel60B.setBackground(Color.WHITE);
  309. workJPanelOP60B = new WorkJPanelOP60("D");
  310. workJPanelOP60B.setBounds(10, 10, workJPanelOP60B.workWidth, workJPanelOP60B.workHeight);
  311. indexPanel60B.add(workJPanelOP60B);
  312. indexPanelB.add(indexPanel60B);
  313. }
  314. // 中转车已取消(鑫政自动线PLC点位说明_MES_20261010标注取消;正面中转车原DB7001已分配给封板反面FSW1,保留实例会干扰反面FSW1信号,故不再创建)
  315. // JPanel indexPanel60BB = new JPanel();
  316. // indexPanel60BB.setLayout(null);
  317. // indexPanel60BB.setBackground(Color.WHITE);
  318. // workJPanelOP60Transfer = new WorkJPanelOP60Transfer("A");
  319. // workJPanelOP60Transfer.setBounds(10, 10, workJPanelOP60Transfer.workWidth, workJPanelOP60Transfer.workHeight);
  320. // indexPanel60BB.add(workJPanelOP60Transfer);
  321. // indexPanelB.add(indexPanel60BB);
  322. //
  323. // JPanel indexPanel60Bc = new JPanel();
  324. // indexPanel60Bc.setLayout(null);
  325. // indexPanel60Bc.setBackground(Color.WHITE);
  326. // workJPanelOP70Transfer = new WorkJPanelOP70Transfer("B");
  327. // workJPanelOP70Transfer.setBounds(10, 10, workJPanelOP70Transfer.workWidth, workJPanelOP70Transfer.workHeight);
  328. // indexPanel60Bc.add(workJPanelOP70Transfer);
  329. // indexPanelB.add(indexPanel60Bc);
  330. // 正面换型台:集中扫码,OP60设备面板从其文本框取码(扫码按OP070方式)
  331. JPanel indexPanel60Xh = new JPanel();
  332. indexPanel60Xh.setLayout(null);
  333. indexPanel60Xh.setBackground(Color.WHITE);
  334. workJPanel70XhFront = new WorkJPanel70Xh("OP070", "C");
  335. workJPanel70XhFront.setBounds(10, 10, workJPanel70XhFront.workWidth, workJPanel70XhFront.workHeight);
  336. indexPanel60Xh.add(workJPanel70XhFront);
  337. indexPanelB.add(indexPanel60Xh);
  338. tabbedPane.addTab("OP70封板正面FSW", null, indexScrollPaneB, null);
  339. tabbedPane.setEnabledAt(0, true);
  340. JPanel indexPanelC = new JPanel();
  341. indexScrollPaneC = new JScrollPane(indexPanelC);
  342. indexPanelC.setLayout(new GridLayout(1,1, 5, 5));
  343. indexPanelC.setBackground(Color.LIGHT_GRAY);
  344. JPanel indexPanel65A = new JPanel();
  345. indexPanel65A.setLayout(null);
  346. indexPanel65A.setBackground(Color.WHITE);
  347. if (mes_line_pos.equals("west")){
  348. workJPanelOP65A = new WorkJPanelOP65("A"); //西侧改为A
  349. }else {
  350. workJPanelOP65A = new WorkJPanelOP65("B"); //东侧改为B
  351. }
  352. workJPanelOP65A.setBounds(10, 10, workJPanelOP65A.workWidth, workJPanelOP65A.workHeight);
  353. indexPanel65A.add(workJPanelOP65A);
  354. indexPanelC.add(indexPanel65A);
  355. tabbedPane.addTab("OP75封板正面打磨", null, indexScrollPaneC, null);
  356. tabbedPane.setForegroundAt(1, Color.RED);
  357. JPanel indexPanelD = new JPanel();
  358. indexScrollPaneD = new JScrollPane(indexPanelD);
  359. indexPanelD.setLayout(new GridLayout(2,2, 5, 5));
  360. indexPanelD.setBackground(Color.LIGHT_GRAY);
  361. if(mes_line_pos.equals("west")){
  362. JPanel indexPanel70A = new JPanel();
  363. indexPanel70A.setLayout(null);
  364. indexPanel70A.setBackground(Color.WHITE);
  365. workJPanelOP70A = new WorkJPanelOP70("A");
  366. workJPanelOP70A.setBounds(10, 10, workJPanelOP70A.workWidth, workJPanelOP70A.workHeight);
  367. indexPanel70A.add(workJPanelOP70A);
  368. indexPanelD.add(indexPanel70A);
  369. JPanel indexPanel70B = new JPanel();
  370. indexPanel70B.setLayout(null);
  371. indexPanel70B.setBackground(Color.WHITE);
  372. workJPanelOP70B = new WorkJPanelOP70("B");
  373. workJPanelOP70B.setBounds(10, 10, workJPanelOP70B.workWidth, workJPanelOP70B.workHeight);
  374. indexPanel70B.add(workJPanelOP70B);
  375. indexPanelD.add(indexPanel70B);
  376. // 反面3号机(原C位DB7004)已取消,不再创建面板
  377. JPanel indexPanel70D = new JPanel();
  378. indexPanel70D.setLayout(null);
  379. indexPanel70D.setBackground(Color.WHITE);
  380. workJPanel70Xh = new WorkJPanel70Xh("A"); // 反面换型台心跳/监控挂反面FSW1(DB7001),避免与正面FSW2的DB7004冲突
  381. workJPanel70Xh.setBounds(10, 10, workJPanel70Xh.workWidth, workJPanel70Xh.workHeight);
  382. indexPanel70D.add(workJPanel70Xh);
  383. indexPanelD.add(indexPanel70D);
  384. }else{
  385. JPanel indexPanel70A = new JPanel();
  386. indexPanel70A.setLayout(null);
  387. indexPanel70A.setBackground(Color.WHITE);
  388. workJPanelOP70A = new WorkJPanelOP70("D");
  389. workJPanelOP70A.setBounds(10, 10, workJPanelOP70A.workWidth, workJPanelOP70A.workHeight);
  390. indexPanel70A.add(workJPanelOP70A);
  391. indexPanelD.add(indexPanel70A);
  392. JPanel indexPanel70B = new JPanel();
  393. indexPanel70B.setLayout(null);
  394. indexPanel70B.setBackground(Color.WHITE);
  395. workJPanelOP70B = new WorkJPanelOP70("E");
  396. workJPanelOP70B.setBounds(10, 10, workJPanelOP70B.workWidth, workJPanelOP70B.workHeight);
  397. indexPanel70B.add(workJPanelOP70B);
  398. indexPanelD.add(indexPanel70B);
  399. // 反面3号机(原F位DB7004)已取消,不再创建面板
  400. JPanel indexPanel70D = new JPanel();
  401. indexPanel70D.setLayout(null);
  402. indexPanel70D.setBackground(Color.WHITE);
  403. workJPanel70Xh = new WorkJPanel70Xh("A"); // 反面换型台心跳/监控挂反面FSW1(DB7001),避免与正面FSW2的DB7004冲突
  404. workJPanel70Xh.setBounds(10, 10, workJPanel70Xh.workWidth, workJPanel70Xh.workHeight);
  405. indexPanel70D.add(workJPanel70Xh);
  406. indexPanelD.add(indexPanel70D);
  407. }
  408. tabbedPane.addTab("OP80封板反面FSW", null, indexScrollPaneD, null);
  409. // ========== 工作记录 Tab(改造:OP60/OP65/OP70子工位Tab + 所有工位) ==========
  410. // 创建工作记录的子 TabbedPane
  411. JTabbedPane workRecordTabbedPane = new JTabbedPane(JTabbedPane.TOP);
  412. workRecordTabbedPane.setFont(new Font("微软雅黑", Font.PLAIN, 14));
  413. // 定义所有子工位
  414. // OP70(封板正面FSW): A西1号机, B东1号机, C西2号机, D东2号机(C/D为新增设备)
  415. // OP75(封板正面打磨): A, B
  416. // OP80(封板反面FSW): A西1号机, B西2号机, D东1号机, E东2号机(原C/F位3号机已取消)
  417. String[][] stationGroups = {
  418. {"OP070", "A", "B", "C", "D"},
  419. {"OP075", "A", "B"},
  420. {"OP080", "A", "B", "D", "E"}
  421. };
  422. // 计算总的工位数(用于数组大小)
  423. int totalStations = 0;
  424. for (String[] group : stationGroups) {
  425. totalStations += group.length - 1; // 减去第一个元素(基础工位号)
  426. }
  427. WorkRecordPanel[] workRecordPanels = new WorkRecordPanel[totalStations + 1]; // +1 for "所有工位"
  428. int panelIndex = 0;
  429. // 为每个子工位创建 Tab
  430. for (String[] group : stationGroups) {
  431. String baseOprno = group[0]; // 如 OP060
  432. for (int i = 1; i < group.length; i++) {
  433. String station = group[i]; // 如 A, B
  434. String oprno = baseOprno + station;
  435. workRecordPanels[panelIndex] = new WorkRecordPanel(oprno, mes_line_sn);
  436. workRecordTabbedPane.addTab(oprno, null, workRecordPanels[panelIndex], "查询" + oprno + "的工作记录");
  437. panelIndex++;
  438. }
  439. }
  440. // 最后添加"所有工位"Tab(查询整条产线所有工位,不限于OP60/OP65/OP70)
  441. workRecordPanels[totalStations] = new WorkRecordPanel(null, mes_line_sn);
  442. workRecordTabbedPane.addTab("所有工位", null, workRecordPanels[totalStations], "查询整条产线所有工位的工作记录");
  443. // 切换子Tab时自动刷新数据
  444. workRecordTabbedPane.addChangeListener(e -> {
  445. int selectedIndex = workRecordTabbedPane.getSelectedIndex();
  446. if (selectedIndex >= 0 && selectedIndex < workRecordPanels.length) {
  447. workRecordPanels[selectedIndex].refreshData();
  448. }
  449. });
  450. // 将子 TabbedPane 添加到主 TabbedPane
  451. tabbedPane.addTab("工作记录", null, workRecordTabbedPane, null);
  452. tabbedPane.addChangeListener(new ChangeListener() {
  453. @Override
  454. public void stateChanged(ChangeEvent e) {
  455. JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
  456. int selectedIndex = tabbedPane.getSelectedIndex();
  457. if(selectedIndex == 1){
  458. }
  459. }
  460. });
  461. }
  462. // 按开关状态刷新菜单项文字和颜色
  463. private static void refreshManualScanMenu(JMenuItem item){
  464. item.setText("扫码手动输入:" + (manualScanEnabled ? "已开启" : "已关闭"));
  465. item.setForeground(manualScanEnabled ? new Color(0, 160, 0) : Color.RED);
  466. }
  467. public static void setMenuStatus(String msg,int error){
  468. if(error == 0){
  469. MesClient.status_menu.setForeground(Color.GREEN);
  470. }else{
  471. MesClient.status_menu.setForeground(Color.RED);
  472. }
  473. MesClient.status_menu.setText(msg);
  474. }
  475. public static void createQRCode(String s,String title) {
  476. log.info("二维码:"+s);
  477. if(s == null || s.isEmpty()){
  478. return;
  479. }
  480. s = s.trim();
  481. try {
  482. BitMatrix bitMatrix = new QRCodeWriter().encode(s, BarcodeFormat.QR_CODE, 200, 200);
  483. BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
  484. JDialog qrDialog = new JDialog(mesClientFrame, title, Dialog.ModalityType.APPLICATION_MODAL);
  485. qrDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
  486. qrDialog.setSize(250, 250);
  487. qrDialog.setLocationRelativeTo(mesClientFrame);
  488. qrDialog.setResizable(false);
  489. JLabel qrLabel = new JLabel(new ImageIcon(qrImage));
  490. qrDialog.getContentPane().add(qrLabel, BorderLayout.CENTER);
  491. qrDialog.setVisible(true);
  492. log.info("已生成二维码");
  493. } catch (Exception e) {
  494. log.error("生成二维码失败", e);
  495. }
  496. }
  497. public static String scanQrcode1(){
  498. if(scanFlag1 == 1){
  499. return "";
  500. }
  501. scanFlag1 = 1;
  502. String sn = "";
  503. try{
  504. if (tcpClient1.socket == null || !tcpClient1.socket.isConnected() || tcpClient1.socket.isClosed()) {
  505. tcpClient1.connect();
  506. }
  507. log.error("扫码枪1正在进行扫码,请勿操作",0);
  508. sn = tcpClient1.receiveResponse();
  509. if (sn == null || sn.equals("")) {
  510. sn = "";
  511. }
  512. tcpClient1.close();
  513. }catch (Exception e) {
  514. e.printStackTrace();
  515. log.error("scanQrcode1:"+sn);
  516. tcpClient1.close();
  517. }
  518. // MesClient.setMenuStatus(sn,0);
  519. scanFlag1 = 0;
  520. return sn;
  521. }
  522. public static String scanQrcode2(){
  523. if(scanFlag2 == 1){
  524. return "";
  525. }
  526. scanFlag2 = 1;
  527. String sn = "";
  528. try{
  529. if (tcpClient2.socket == null || !tcpClient2.socket.isConnected() || tcpClient2.socket.isClosed()) {
  530. tcpClient2.connect();
  531. }
  532. log.error("扫码枪2正在进行扫码,请勿操作",0);
  533. sn = tcpClient2.receiveResponse();
  534. if (sn == null || sn.equals("")) {
  535. sn = "";
  536. }
  537. tcpClient2.close();
  538. }catch (Exception e) {
  539. e.printStackTrace();
  540. log.error("scanQrcode2:"+sn);
  541. tcpClient2.close();
  542. }
  543. // MesClient.setMenuStatus(sn,0);
  544. scanFlag2 = 0;
  545. return sn;
  546. }
  547. public static String scanQrcode3(){
  548. if(scanFlag3 == 1){
  549. return "";
  550. }
  551. scanFlag3 = 1;
  552. String sn = "";
  553. try{
  554. if (tcpClient3.socket == null || !tcpClient3.socket.isConnected() || tcpClient3.socket.isClosed()) {
  555. tcpClient3.connect();
  556. }
  557. log.error("扫码枪3正在进行扫码,请勿操作",0);
  558. sn = tcpClient3.receiveResponse();
  559. if (sn == null || sn.equals("")) {
  560. sn = "";
  561. }
  562. tcpClient3.close();
  563. }catch (Exception e) {
  564. e.printStackTrace();
  565. log.error("scanQrcode3:"+sn);
  566. tcpClient3.close();
  567. }
  568. // MesClient.setMenuStatus(sn,0);
  569. scanFlag3 = 0;
  570. return sn;
  571. }
  572. public static String scanQrcode4(){
  573. if(scanFlag4 == 1){
  574. return "";
  575. }
  576. scanFlag4 = 1;
  577. String sn = "";
  578. try{
  579. if (tcpClient4.socket == null || !tcpClient4.socket.isConnected() || tcpClient4.socket.isClosed()) {
  580. tcpClient4.connect();
  581. }
  582. log.error("扫码枪4正在进行扫码,请勿操作",0);
  583. sn = tcpClient4.receiveResponse();
  584. if (sn == null || sn.equals("")) {
  585. sn = "";
  586. }
  587. tcpClient4.close();
  588. }catch (Exception e) {
  589. e.printStackTrace();
  590. log.error("scanQrcode4:"+sn);
  591. tcpClient4.close();
  592. }
  593. // MesClient.setMenuStatus(sn,0);
  594. scanFlag4 = 0;
  595. return sn;
  596. }
  597. public static Timer cjTimer3;
  598. public static void upParams() {
  599. if (cjTimer3 != null) {
  600. cjTimer3.cancel();
  601. }
  602. cjTimer3 = new Timer();
  603. cjTimer3.schedule(new TimerTask() {
  604. @Override
  605. public void run() {
  606. try {
  607. List<ParamReq> prods = JdbcUtils.getParams();
  608. if (prods.size() > 0) {
  609. // 定时上传参数
  610. JSONObject retObj = DataUtil.upParams(JSON.toJSONString(prods));
  611. if (retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
  612. // 更新sqlite已同步
  613. for (ParamReq prodReq : prods) {
  614. JdbcUtils.updateProdSync(prodReq.getId(), 1);
  615. }
  616. }
  617. }
  618. } catch (Exception e) {
  619. e.printStackTrace();
  620. }
  621. }
  622. }, 1000, 120*1000);
  623. }
  624. }