Sfoglia il codice sorgente

新增生产类型,智界和尚界

setting 1 giorno fa
parent
commit
2c4594d77f

+ 179 - 10
src/com/mes/ui/MesClient.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.mes.component.MesRadio;
 import com.mes.component.MesWebView;
+import com.mes.component.ProductTypePanel;
 import com.mes.netty.NettyClient;
 import com.mes.util.*;
 
@@ -41,6 +42,16 @@ public class MesClient extends JFrame {
     public static String mes_serial_port = "COM1"; // 称重仪串口号
     public static int mes_serial_baud = 9600; // 称重仪波特率
 
+    //新增字段
+    public static ProductTypePanel productTypePanel;
+    public static JLabel productTypeCurrentLabel;
+    public static final int PRODUCT_SN_LENGTH = 32;
+    public static final String PREFIX_ZJ = "000020021815-01000016";  //智界
+    public static final String PREFIX_SJ = "000020022029-01000016";  //尚界
+    public static final String PRODUCT_TYPE_SWITCH_PASSWORD = "503833";
+    public static final String PRODUCT_TYPE_ZJ = ProductTypePanel.TYPE_ZJ;
+    public static final String PRODUCT_TYPE_SJ = ProductTypePanel.TYPE_SJ;
+
     //TCP连接
     public static NettyClient nettyClient;
     //TCP连接状态
@@ -69,6 +80,7 @@ public class MesClient extends JFrame {
 
     public static int scan_type = 0;
     public static JButton finish_ok_bt;
+//    public static JButton finish_ng_bt;
     public static JButton batch_sn_bt;
     public static JTextField product_sn;
     public static JButton f_scan_data_bt_1;
@@ -88,24 +100,30 @@ public class MesClient extends JFrame {
     public static JTable table;
     public static Object[] columnNames = { "物料名称", "绑定批次", "剩余次数", "操作" };
     public static Object[][] rowData = null;
-    public static Timer cjTimer;
-    public static Timer cjTimer2;
+    public static Timer cjTimer; //串口定时器
+    public static Timer cjTimer2; //串口定时器2
     private static final String TARGET_DEVICE_ADDRESS = "001135390238";
     public static void main(String[] args) {
+        //EventQueue.invokeLater(new Runnable() )是SwingUtilities类中的一个静态方法,
+        // 用于在事件调度线程中执行指定的Runnable。
+        //事件调度线程是Swing的核心线程,负责处理所有Swing组件的事件。
         EventQueue.invokeLater(new Runnable() {
             @Override
             public void run() {
                 try{
 
-                    //读文件配置
+                    //读文件配置(新增串口号和波特率)
                     readProperty();
+                    //检查串口连接(定时器定时检查串口连接)
                     checkComPort();
                     // 显示界面
                     mesClientFrame = new MesClient();
                     mesClientFrame.setVisible(false);
 
+                    //连接数据库
                     JdbcUtils.getConn();
 
+                    //显示登录界面
                     welcomeWin = new LoginFarme();
                     welcomeWin.setVisible(true);
 
@@ -119,17 +137,23 @@ public class MesClient extends JFrame {
     }
 
     public static void initComPort() {
+        //
         try {
             if (serialPortUtils != null) {
                 serialPortUtils.closeSerialPort();
                 serialPortUtils = null;
             }
+            //初始化串口
             serialPortUtils = new SerialPortUtils();
+            //创建串口参数配置
             paramConfig = new ParamConfig(mes_serial_port, mes_serial_baud, 0, 8, 1);
+            //初始化串口
             serialPortUtils.init(paramConfig);
             System.out.println("初始化称重串口: " + mes_serial_port + ", 波特率: " + mes_serial_baud);
         } catch (Throwable e) {
+            //串口连接失败标志
             com_connect_flag = false;
+            //打印错误信息
             System.err.println("称重串口初始化失败: " + e.getMessage());
             e.printStackTrace();
         }
@@ -137,23 +161,28 @@ public class MesClient extends JFrame {
 
     // 串口断开时定时重连
     public static void checkComPort() {
+        //如果定时器不为空,则取消定时器
         if (MesClient.cjTimer2 != null) {
-            MesClient.cjTimer2.cancel();
+            MesClient.cjTimer2.cancel(); 
         }
+        //创建新的定时器
         MesClient.cjTimer2 = new Timer();
+        //定时器执行任务
         MesClient.cjTimer2.schedule(new TimerTask() {
+            @Override
             public void run() {
                 try {
+                    //如果串口连接标志为false,则重连串口
                     if (!com_connect_flag) {
                         System.out.println("称重串口断开,正在重连");
-                        initComPort();
+                        initComPort(); //重连串口
                     }
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
-        }, 2000, 2000);
-        initComPort();
+        }, 2000, 2000); //线程本身并不阻塞
+        initComPort(); //初始化串口
     }
 
 
@@ -164,7 +193,7 @@ public class MesClient extends JFrame {
         Properties pro = new Properties();
         BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
         pro.load(br);
-        mes_gw =  pro.getProperty("mes.gw");
+        mes_gw =  pro.getProperty("mes.gw"); 
 
 //        mes_gw_des = pro.getProperty("mes.gw_des");
         mes_server_ip = pro.getProperty("mes.server_ip");
@@ -278,6 +307,7 @@ public class MesClient extends JFrame {
     }
 
     public static void initWarehouseData(){
+        loadProductTypeFromDb(); //新增
         resetScanA();
     }
 
@@ -302,7 +332,8 @@ public class MesClient extends JFrame {
 
         MesClient.f_scan_data_bt_1.setEnabled(true);
 //		DataUtil.stopWork(sessionid);
-        setMenuStatus("请扫工件码",0);
+        updateProductTypePanelEnabled(true);
+        MesClient.setMenuStatus("当前生产类型:" + getProductTypeName() + ",请扫工件码",0); //修改
 //		product_result_text.setText("");
 //		work_status_text.setText("");
 //        MesClient.setMenuStatus("涂胶已超过10分钟,已失效",-1);
@@ -378,6 +409,7 @@ public class MesClient extends JFrame {
         //弹窗扫工件码
         String scanBarcode = JOptionPane.showInputDialog(null, scanBarcodeTitle);
         if(scanBarcode!=null&&!scanBarcode.equalsIgnoreCase("")) {
+            scanBarcode = scanBarcode.trim(); //生产类型新增
             //获取用户
             getUser();
             //获取扫码内容36位
@@ -392,6 +424,21 @@ public class MesClient extends JFrame {
             //刷新界面
             mesClientFrame.repaint();
 
+            //生产类型新增
+            String validateMsg = validateProductSnMessage(scanBarcode);
+            if (validateMsg != null) {
+                check_quality_result = false;
+                work_status = 0;
+                MesClient.finish_ok_bt.setEnabled(false);
+//                MesClient.finish_ng_bt.setEnabled(false);
+                MesClient.f_scan_data_bt_1.setEnabled(true);
+                updateProductTypePanelEnabled(true);
+                MesClient.setMenuStatus(validateMsg, -1);
+
+                return;
+            }
+            updateProductTypePanelEnabled(false);
+
             if(!tcp_connect_flag) {
                 JOptionPane.showMessageDialog(mesClientFrame,"设备未连接Mes服务器","提示窗口", JOptionPane.INFORMATION_MESSAGE);
                 return;
@@ -676,6 +723,7 @@ public class MesClient extends JFrame {
         finish_ok_bt.setBounds(578, 405, 212, 92);
         indexPanelA.add(finish_ok_bt);
 
+        //重量输入框(由串口定时器定时获取重量)
         weight_text = new JTextField();
         weight_text.setHorizontalAlignment(SwingConstants.CENTER);
         weight_text.setFont(new Font("微软雅黑", Font.PLAIN, 28));
@@ -685,6 +733,7 @@ public class MesClient extends JFrame {
         weight_text.setText("");
         indexPanelA.add(weight_text);
 
+        //包装码输入框
         batch_sn_text = new JTextField();
         batch_sn_text.setEditable(false);
         batch_sn_text.setHorizontalAlignment(SwingConstants.CENTER);
@@ -744,6 +793,7 @@ public class MesClient extends JFrame {
         batch_sn_bt.setBounds(693, 192, 198, 70);
         indexPanelA.add(batch_sn_bt);
 
+        //重量标签
         lblNewLabel = new JLabel("重量");
         lblNewLabel.setEnabled(false);
         lblNewLabel.setHorizontalAlignment(SwingConstants.RIGHT);
@@ -780,6 +830,7 @@ public class MesClient extends JFrame {
         is_js_btn.setBounds(693, 300, 198, 70);
         indexPanelA.add(is_js_btn);
 
+        //称重按钮,触发称重操作
         finish_ok_bt_1 = new JButton("称重");
         finish_ok_bt_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ok_bg.png")));
         finish_ok_bt_1.addActionListener(new ActionListener() {
@@ -789,8 +840,11 @@ public class MesClient extends JFrame {
                     return;
                 }
                 new Thread(() -> serialPortUtils.requestWeight()).start();
-            }
+            } 
         });
+
+
+
         finish_ok_bt_1.setFont(new Font("微软雅黑", Font.PLAIN, 40));
         finish_ok_bt_1.setEnabled(true);
         finish_ok_bt_1.setBounds(207, 405, 212, 92);
@@ -803,6 +857,46 @@ public class MesClient extends JFrame {
 
         indexPanelC = new JPanel(new BorderLayout());
 
+        //新增的面板
+        JPanel indexPanelProductType = new JPanel();
+        indexPanelProductType.setLayout(null);
+        JScrollPane productTypeScrollPane = new JScrollPane(indexPanelProductType);
+
+        JLabel productTypeTitle = new JLabel("生产类型设置");
+        productTypeTitle.setFont(new Font("微软雅黑", Font.BOLD, 28));
+        productTypeTitle.setForeground(new Color(64, 64, 64));
+        productTypeTitle.setHorizontalAlignment(SwingConstants.CENTER);
+        productTypeTitle.setBounds(81, 80, 810, 50);
+        indexPanelProductType.add(productTypeTitle);
+
+        JLabel productTypeHint = new JLabel("请选择当前生产的工件类型,切换后将保存到本地并用于扫码校验");
+        productTypeHint.setFont(new Font("微软雅黑", Font.PLAIN, 20));
+        productTypeHint.setForeground(new Color(140, 140, 140));
+        productTypeHint.setHorizontalAlignment(SwingConstants.CENTER);
+        productTypeHint.setBounds(81, 140, 810, 40);
+        indexPanelProductType.add(productTypeHint);
+
+        productTypePanel = new ProductTypePanel(PRODUCT_TYPE_SWITCH_PASSWORD);
+        productTypePanel.setBounds(276, 210, 420, 72);
+        productTypePanel.setOnChangeListener(() -> {
+            if (work_status == 0) {
+                saveProductTypeToDb();
+                setMenuStatus("当前生产类型:" + getProductTypeName() + ",请扫工件码", 0);
+            }
+            refreshProductTypeCurrentLabel();
+        });
+        indexPanelProductType.add(productTypePanel);
+
+        productTypeCurrentLabel = new JLabel();
+        productTypeCurrentLabel.setFont(new Font("微软雅黑", Font.PLAIN, 22));
+        productTypeCurrentLabel.setForeground(new Color(64, 64, 64));
+        productTypeCurrentLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        productTypeCurrentLabel.setBounds(81, 310, 810, 40);
+        refreshProductTypeCurrentLabel();
+        indexPanelProductType.add(productTypeCurrentLabel);
+
+        tabbedPane.addTab("生产类型", new ImageIcon(MesClient.class.getResource("/bg/menu_setting.png")), productTypeScrollPane, null);
+
         tabbedPane.addTab("开班点检", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), indexPanelC, null);
 
 
@@ -827,6 +921,81 @@ public class MesClient extends JFrame {
         });
     }
 
+    private static String validateProductSnMessage(String sn) {
+        if (sn == null || sn.isEmpty()) {
+            return "工件码为空,请重试";
+        }
+        if (sn.length() != PRODUCT_SN_LENGTH) {
+            return "工件码长度须为32位,当前" + sn.length() + "位";
+        }
+        String prefix = getProductSnPrefix();
+        if (!sn.startsWith(prefix)) {
+            return "工件码前缀与当前类型(" + getProductTypeName() + ")不匹配,当前工件码为" + getProductTypeNameBySn(sn);
+        }
+        return null;
+    }
+
+    private static void updateProductTypePanelEnabled(boolean enabled) {
+        if (productTypePanel != null) {
+            productTypePanel.setEnabled(enabled);
+        }
+    }
+    public static void loadProductTypeFromDb() {
+        if (productTypePanel == null) {
+            return;
+        }
+        String savedType = JdbcUtils.getClientConfig(
+                JdbcUtils.getProductTypeConfigKey(mes_gw),
+                PRODUCT_TYPE_ZJ
+        );
+        if (PRODUCT_TYPE_SJ.equals(savedType)) {
+            productTypePanel.setResult(PRODUCT_TYPE_SJ);
+        } else {
+            productTypePanel.setResult(PRODUCT_TYPE_ZJ);
+        }
+        refreshProductTypeCurrentLabel();
+    }
+
+    public static void refreshProductTypeCurrentLabel() {
+        if (productTypeCurrentLabel != null) {
+            productTypeCurrentLabel.setText("当前选择:" + getProductTypeName() + "(前缀 " + getProductSnPrefix() + ")");
+        }
+    }
+
+    public static void saveProductTypeToDb() {
+        if (productTypePanel == null) {
+            return;
+        }
+        JdbcUtils.saveClientConfig(
+                JdbcUtils.getProductTypeConfigKey(mes_gw),
+                productTypePanel.getResult()
+        );
+    }
+
+    public static String getProductSnPrefix() {
+        if (productTypePanel != null && PRODUCT_TYPE_SJ.equals(productTypePanel.getResult())) {
+            return PREFIX_SJ;
+        }
+        return PREFIX_ZJ;
+    }
+
+    public static String getProductTypeName() {
+        if (productTypePanel != null) {
+            return productTypePanel.getTypeName();
+        }
+        return "智界";
+    }
+
+    private static String getProductTypeNameBySn(String sn) {
+        if (sn.startsWith(PREFIX_SJ)) {
+            return "尚界";
+        }
+        if (sn.startsWith(PREFIX_ZJ)) {
+            return "智界";
+        }
+        return "未知";
+    }
+
     public static void setMenuStatus(String msg,int error){
         if(error == 0){
             MesClient.status_menu.setForeground(Color.GREEN);

+ 92 - 7
src/com/mes/util/JdbcUtils.java

@@ -1,15 +1,17 @@
 package com.mes.util;
 
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
+import com.sun.org.slf4j.internal.Logger;
+import com.sun.org.slf4j.internal.LoggerFactory;
+
+import java.sql.*;
 
 public class JdbcUtils {
+//    public static final Logger log =  LoggerFactory.getLogger(JdbcUtils.class);
 	//通过上面的工具就可以获取到properties文件中的键值从而可以加载驱动 获取链接 从而 可以增删改查
 	public static Connection conn = null;
     public static String Drivde="org.sqlite.JDBC";
-    
+    //新增字段
+    public static String DATABASE_URL="jdbc:sqlite:mes_db.db";
     public static Connection getConn(){
         try {
             Class.forName(Drivde);// 加载驱动,连接sqlite的jdbc
@@ -102,9 +104,67 @@ public class JdbcUtils {
 //            System.out.println("data_01:"+rSet.getString(4));
 //        }
 //        rSet.close();//关闭数据集
+
+        //新增表
+        String clientConfig = "CREATE TABLE if not exists client_config("
+                + "config_key VARCHAR(100) PRIMARY KEY,"
+                + "config_value VARCHAR(500),"
+                + "update_time DATETIME"
+                + ")";
+        statement.executeUpdate(clientConfig);
+
         statement.close();
     }
-    
+
+    //新增方法
+    public static void saveClientConfig(String key, String value) {
+        try {
+            if (conn == null || conn.isClosed()) {
+                openConnection();
+            }
+            String sql = "INSERT INTO client_config (config_key, config_value, update_time) VALUES (?, ?, ?) "
+                    + "ON CONFLICT(config_key) DO UPDATE SET config_value = excluded.config_value, update_time = excluded.update_time";
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, key);
+            ps.setString(2, value);
+            ps.setString(3, DateLocalUtils.getCurrentTime());
+            ps.executeUpdate();
+            ps.close();
+//            log.info("保存本地配置: {}={}", key, value);
+        } catch (SQLException e) {
+//            log.info("保存本地配置失败: {}", e.getMessage());
+        }
+    }
+
+    //新增方法
+    public static String getClientConfig(String key, String defaultValue) {
+        try {
+            if (conn == null || conn.isClosed()) {
+                openConnection();
+            }
+            String sql = "SELECT config_value FROM client_config WHERE config_key = ?";
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, key);
+            ResultSet rs = ps.executeQuery();
+            if (rs.next()) {
+                String value = rs.getString("config_value");
+                rs.close();
+                ps.close();
+                return value;
+            }
+            rs.close();
+            ps.close();
+        } catch (SQLException e) {
+//            log.info("读取本地配置失败: {}", e.getMessage());
+        }
+        return defaultValue;
+    }
+
+    //新增方法
+    public static String getProductTypeConfigKey(String gw) {
+        return "product_type_" + gw;
+    }
+
     public static void close(){
     	System.out.println("SQLite数据库连接关闭!");
         try {
@@ -115,7 +175,32 @@ public class JdbcUtils {
             e.printStackTrace();
         }
     }
-    
+    public static void openConnection() {
+        try {
+            Class.forName(Drivde);// 加载驱动,连接sqlite的jdbc
+            conn = DriverManager.getConnection(DATABASE_URL);
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            // 如果连接失败,尝试重连
+            reconnect();
+        }
+    }
+
+    private static void reconnect() {
+        try {
+            // 关闭旧连接
+            if (conn != null && !conn.isClosed()) {
+                conn.close();
+            }
+            // 重新建立连接
+            conn = DriverManager.getConnection(DATABASE_URL);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            // 如果重连失败,可以进一步处理异常,比如记录日志、通知管理员等
+        }
+    }
     
   //设备结构数据库
 //    String sqlEquipment = "CREATE TABLE if not exists tree_structure(id INTEGER PRIMARY KEY AUTOINCREMENT,function_location VARCHAR(200),description VARCHAR(200),sup_fl VARCHAR(200),level INT(3)," +

+ 21 - 1
src/com/mes/util/ParamConfig.java

@@ -24,7 +24,11 @@ public class ParamConfig {
         this.dataBit = dataBit;
         this.stopBit = stopBit;
     }
-
+    
+    /**
+     * 获取串口号
+     * @return 串口号
+     */
     public String getSerialNumber() {
         return serialNumber;
     }
@@ -33,6 +37,10 @@ public class ParamConfig {
         this.serialNumber = serialNumber;
     }
 
+    /**
+     * 获取波特率
+     * @return 波特率
+     */
     public int getBaudRate() {
         return baudRate;
     }
@@ -41,6 +49,10 @@ public class ParamConfig {
         this.baudRate = baudRate;
     }
 
+    /**
+     * 获取校验位
+     * @return 校验位
+     */
     public int getCheckoutBit() {
         return checkoutBit;
     }
@@ -49,6 +61,10 @@ public class ParamConfig {
         this.checkoutBit = checkoutBit;
     }
 
+    /**
+     * 获取数据位
+     * @return 数据位
+     */
     public int getDataBit() {
         return dataBit;
     }
@@ -57,6 +73,10 @@ public class ParamConfig {
         this.dataBit = dataBit;
     }
 
+    /**
+     * 获取停止位
+     * @return 停止位
+     */
     public int getStopBit() {
         return stopBit;
     }

+ 21 - 4
src/com/mes/util/SerialPortUtils.java

@@ -16,19 +16,26 @@ public class SerialPortUtils {
             "w([wnt])([+-]?\\d+\\.\\d+)\\s*(kg|lb)?",
             Pattern.CASE_INSENSITIVE);
 
+    //串口对象
     private SerialPort serialPort;
+    //接收缓冲区
     private final StringBuilder receiveBuffer = new StringBuilder();
 
+    //初始化串口(串口连接的核心)
     public void init(ParamConfig paramConfig) {
-        closeSerialPort();
+        //关闭串口
+        closeSerialPort(); 
+        //获取串口
         serialPort = SerialPort.getCommPort(paramConfig.getSerialNumber());
+        //设置串口参数(波特率、数据位、停止位、校验位)
         serialPort.setComPortParameters(
                 paramConfig.getBaudRate(),
-                paramConfig.getDataBit(),
+                paramConfig.getDataBit(), 
                 paramConfig.getStopBit(),
                 paramConfig.getCheckoutBit());
+        //设置串口超时时间
         serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
-
+        //打开串口
         if (!serialPort.openPort()) {
             MesClient.com_connect_flag = false;
             System.err.println("打开串口失败: " + paramConfig.getSerialNumber());
@@ -40,7 +47,7 @@ public class SerialPortUtils {
             public int getListeningEvents() {
                 return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
             }
-
+            //串口数据可用时,读取数据
             @Override
             public void serialEvent(SerialPortEvent event) {
                 if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
@@ -50,6 +57,7 @@ public class SerialPortUtils {
             }
         });
 
+        //串口连接成功标志
         MesClient.com_connect_flag = true;
         System.out.println("称重串口连接成功: " + paramConfig.getSerialNumber());
     }
@@ -163,13 +171,22 @@ public class SerialPortUtils {
         serialPort.writeBytes(bytes, bytes.length);
     }
 
+    /**
+     * 关闭串口
+     */
     public void closeSerialPort() {
+        //清空接收缓冲区
         receiveBuffer.setLength(0);
+        //如果串口不为空
         if (serialPort != null) {
+            //如果串口打开
             if (serialPort.isOpen()) {
+                //移除数据监听
                 serialPort.removeDataListener();
+                //关闭串口
                 serialPort.closePort();
             }
+            //串口置空
             serialPort = null;
         }
     }