wangxichen 4 dienas atpakaļ
vecāks
revīzija
31fcd7f3ec

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

@@ -55,6 +55,8 @@ public class MesClient extends JFrame {
     public static int mes_heart_icon_cycle = 1;
     public static String mes_line_sn = "";
     public static String mes_gwflag = "";
+    // 工件码前缀白名单(空=不校验),由 StationConfig 从 config/runtime.properties 加载
+    public static java.util.List<String> mes_barcode_prefixes = new java.util.ArrayList<String>();
 
     public static NettyClient nettyClient;
     public static boolean tcp_connect_flag = false;
@@ -301,6 +303,9 @@ public class MesClient extends JFrame {
 
         mes_gwflag = pro.getProperty("mes.gwflag");
 
+        // 加载工件码前缀白名单(可运行时改,走独立文件)
+        mes_barcode_prefixes = StationConfig.loadBarcodePrefixes();
+
         System.out.println(mes_gw + ";" + mes_gw_des + ";" + mes_server_ip + ";" + mes_tcp_port + ";" + mes_heart_beat_cycle);
     }
 
@@ -648,6 +653,16 @@ public class MesClient extends JFrame {
         });
         settingMenu.add(resetTcpMenu_1_1sd);
 
+        JMenuItem prefixConfigMenu = new JMenuItem("前缀校验配置");
+        prefixConfigMenu.setIcon(new ImageIcon(MesClient.class.getResource("/bg/menu_setting.png")));
+        prefixConfigMenu.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 20));
+        prefixConfigMenu.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                showPrefixConfigDialog();
+            }
+        });
+        settingMenu.add(prefixConfigMenu);
+
         contentPane = new JPanel();
         contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
         setContentPane(contentPane);
@@ -1305,6 +1320,21 @@ public class MesClient extends JFrame {
             return;
         }
 
+        // 前缀白名单校验(列表为空跳过;非空按 startsWith 逐个匹配,命中任一即通过)
+        if(mes_barcode_prefixes != null && !mes_barcode_prefixes.isEmpty()){
+            boolean matched = false;
+            for(String prefix : mes_barcode_prefixes){
+                if(sn.startsWith(prefix)){
+                    matched = true;
+                    break;
+                }
+            }
+            if(!matched){
+                MesClient.setMenuStatus("工件码前缀不匹配,允许的前缀:" + mes_barcode_prefixes, -1);
+                return;
+            }
+        }
+
         // 面别由配置固定,扫到的码只落本机负责的面
         String page = side();
         if(page.equals("A")){
@@ -1465,4 +1495,70 @@ public class MesClient extends JFrame {
             log.info("异步任务执行完毕");
         });
     }
+
+    /** 前缀校验配置(密码保护) */
+    private static void showPrefixConfigDialog() {
+        // 先验证密码 503833
+        JPasswordField pwdField = new JPasswordField(15);
+        pwdField.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 18));
+        int pwdOk = JOptionPane.showConfirmDialog(mesClientFrame, pwdField, "请输入设置密码", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+        if (pwdOk != JOptionPane.OK_OPTION) return;
+        String pwd = new String(pwdField.getPassword());
+        if (!"503833".equals(pwd)) {
+            JOptionPane.showMessageDialog(mesClientFrame, "密码错误", "提示", JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+
+        // 密码正确,显示前缀列表配置界面
+        final DefaultListModel<String> listModel = new DefaultListModel<String>();
+        for (String p : mes_barcode_prefixes) listModel.addElement(p);
+        final JList<String> prefixList = new JList<String>(listModel);
+        prefixList.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 16));
+        JScrollPane scrollPane = new JScrollPane(prefixList);
+        scrollPane.setPreferredSize(new Dimension(300, 150));
+
+        JButton addBtn = new JButton("添加");
+        addBtn.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 16));
+        addBtn.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                String newPrefix = JOptionPane.showInputDialog(mesClientFrame, "输入新前缀:");
+                if (newPrefix != null && !newPrefix.trim().isEmpty()) {
+                    String t = newPrefix.trim();
+                    if (!listModel.contains(t)) listModel.addElement(t);
+                }
+            }
+        });
+
+        JButton delBtn = new JButton("删除");
+        delBtn.setFont(new Font("Microsoft YaHei UI", Font.PLAIN, 16));
+        delBtn.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                int idx = prefixList.getSelectedIndex();
+                if (idx >= 0) listModel.remove(idx);
+            }
+        });
+
+        JPanel btnPanel = new JPanel();
+        btnPanel.add(addBtn);
+        btnPanel.add(delBtn);
+
+        JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
+        mainPanel.add(new JLabel("工件码前缀白名单(为空则不校验):"), BorderLayout.NORTH);
+        mainPanel.add(scrollPane, BorderLayout.CENTER);
+        mainPanel.add(btnPanel, BorderLayout.SOUTH);
+
+        int ok = JOptionPane.showConfirmDialog(mesClientFrame, mainPanel, "前缀校验配置", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+        if (ok == JOptionPane.OK_OPTION) {
+            java.util.List<String> newList = new java.util.ArrayList<String>();
+            for (int i = 0; i < listModel.size(); i++) newList.add(listModel.getElementAt(i));
+            try {
+                StationConfig.saveBarcodePrefixes(newList);
+                mes_barcode_prefixes = newList;
+                String msg = newList.isEmpty() ? "已清空前缀,不再校验" : "前缀已更新:" + newList;
+                JOptionPane.showMessageDialog(mesClientFrame, msg, "提示", JOptionPane.INFORMATION_MESSAGE);
+            } catch (IOException ex) {
+                JOptionPane.showMessageDialog(mesClientFrame, "保存失败:" + ex.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
+            }
+        }
+    }
 }

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

@@ -0,0 +1,79 @@
+package com.mes.ui;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * 运行时可写配置:工件码前缀白名单
+ * 与只读的 config.properties 分离,走 config/runtime.properties
+ */
+public class StationConfig {
+
+    private static final String RUNTIME_CONFIG_PATH = "config/runtime.properties";
+    private static final String BARCODE_PREFIX_KEY = "mes.barcode_prefix";
+
+    /** 读前缀列表,空列表表示不校验 */
+    public static List<String> loadBarcodePrefixes() {
+        List<String> list = new ArrayList<String>();
+        File file = new File(RUNTIME_CONFIG_PATH);
+        if (!file.exists()) return list;
+        Properties pro = new Properties();
+        BufferedReader br = null;
+        try {
+            br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
+            pro.load(br);
+            String v = pro.getProperty(BARCODE_PREFIX_KEY);
+            if (v == null) return list;
+            for (String s : v.split(",")) {
+                String t = s.trim();
+                if (!t.isEmpty() && !list.contains(t)) list.add(t);
+            }
+        } catch (Exception ignored) {
+        } finally {
+            if (br != null) try { br.close(); } catch (Exception ignored) {}
+        }
+        return list;
+    }
+
+    /** 保存前缀列表,保留文件其他 key */
+    public static void saveBarcodePrefixes(List<String> prefixes) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        if (prefixes != null) {
+            for (String p : prefixes) {
+                if (p == null || p.trim().isEmpty()) continue;
+                if (sb.length() > 0) sb.append(",");
+                sb.append(p.trim());
+            }
+        }
+        File file = new File(RUNTIME_CONFIG_PATH);
+        Properties pro = new Properties();
+        if (file.exists()) {
+            BufferedReader br = null;
+            try {
+                br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
+                pro.load(br);
+            } finally {
+                if (br != null) try { br.close(); } catch (Exception ignored) {}
+            }
+        }
+        pro.setProperty(BARCODE_PREFIX_KEY, sb.toString());
+        File parent = file.getParentFile();
+        if (parent != null && !parent.exists()) parent.mkdirs();
+        BufferedWriter bw = null;
+        try {
+            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
+            pro.store(bw, "runtime station config");
+        } finally {
+            if (bw != null) try { bw.close(); } catch (Exception ignored) {}
+        }
+    }
+}

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

@@ -4,4 +4,4 @@ mes.server_ip=192.168.114.99
 mes.tcp_port=3000
 mes.heart_beat_cycle=60
 mes.line_sn=XT
-mes.gwflag=A
+mes.gwflag=A