wangxichen 1 هفته پیش
والد
کامیت
95208264f7

+ 4 - 13
src/com/mes/component/PlcSignalMonitor.java

@@ -29,8 +29,6 @@ public class PlcSignalMonitor {
     private JLabel signal_allowBlanking;
     private JLabel signal_heart;
     private JLabel signal_toDevice;
-    private JLabel signal_toTransfer;
-    private JLabel signal_transferToDevice;
     
     /**
      * 构造函数
@@ -146,9 +144,8 @@ public class PlcSignalMonitor {
             {"MES允许上料", plcDb + ".0.4", "MES→PLC"},  //
             {"MES允许下料", plcDb + ".0.5", "MES→PLC"},  //
             {"心跳信号", plcDb + ".0.6", "MES→PLC"},
-            {"上料到设备", plcDb + ".0.7", "PLC→MES"},   //
-            {"上料到中转车", plcDb + ".1.0", "PLC→MES"},  //
-            {"中转车上料到设备", plcDb + ".1.1", "PLC→MES"}  //
+            {"上料到设备", plcDb + ".0.7", "PLC→MES"}
+            // 中转车已取消,.1.0 / .1.1 改为预留
         };
         
         JPanel panel = new JPanel(new GridLayout(signals.length + 1, 4, 5, 5));
@@ -169,13 +166,11 @@ public class PlcSignalMonitor {
         signal_allowBlanking = createStatusLabel();
         signal_heart = createStatusLabel();
         signal_toDevice = createStatusLabel();
-        signal_toTransfer = createStatusLabel();
-        signal_transferToDevice = createStatusLabel();
         
         JLabel[] statusLabels = {
             signal_feeding, signal_blanking, signal_running, signal_deviceStatus,
             signal_allowFeeding, signal_allowBlanking, signal_heart,
-            signal_toDevice, signal_toTransfer, signal_transferToDevice
+            signal_toDevice
         };
         
         // 添加信号行
@@ -229,8 +224,6 @@ public class PlcSignalMonitor {
             boolean allowBlanking = s7PLC.readBoolean(plcDb + ".0.5");
             boolean heart = s7PLC.readBoolean(plcDb + ".0.6");
             boolean toDevice = s7PLC.readBoolean(plcDb + ".0.7");
-            boolean toTransfer = s7PLC.readBoolean(plcDb + ".1.0");
-            boolean transferToDevice = s7PLC.readBoolean(plcDb + ".1.1");
             
             // 在EDT线程中更新UI
             SwingUtilities.invokeLater(() -> {
@@ -242,8 +235,6 @@ public class PlcSignalMonitor {
                 updateStatusLabel(signal_allowBlanking, allowBlanking);
                 updateStatusLabel(signal_heart, heart);
                 updateStatusLabel(signal_toDevice, toDevice);
-                updateStatusLabel(signal_toTransfer, toTransfer);
-                updateStatusLabel(signal_transferToDevice, transferToDevice);
             });
             
         } catch (Exception e) {
@@ -265,7 +256,7 @@ public class PlcSignalMonitor {
         JLabel[] labels = {
             signal_feeding, signal_blanking, signal_running, signal_deviceStatus,
             signal_allowFeeding, signal_allowBlanking, signal_heart,
-            signal_toDevice, signal_toTransfer, signal_transferToDevice
+            signal_toDevice
         };
         
         for (JLabel label : labels) {

+ 5 - 12
src/com/mes/component/PlcSignalMonitor02.java

@@ -9,7 +9,7 @@ import java.awt.*;
 
 /**
  * PLC信号监控组件02
- * 精简版监控面板,仅显示请求扫码、扫码完成、中转车上料到设备三个核心状态
+ * 扫码工位精简版监控面板,仅显示请求扫码、扫码完成反馈(中转车已取消)
  */
 public class PlcSignalMonitor02 {
 
@@ -23,7 +23,6 @@ public class PlcSignalMonitor02 {
     // 核心信号标签(用于对话框中的实时更新)
     private JLabel signal_requestScan;
     private JLabel signal_scanComplete;
-    private JLabel signal_transferToDevice;
 
     /**
      * 构造函数
@@ -104,11 +103,10 @@ public class PlcSignalMonitor02 {
      * 创建信号详情面板
      */
     private JPanel createSignalDetailPanel() {
-        // 注意:这里的地址和方向(.0.0 / .0.1 / .1.1 等)请根据你实际的 PLC 变量表进行修改
+        // 扫码点位:.0.0 请求扫码 / .0.1 扫码完成反馈,.0.2 及以后为预留
         String[][] signals = {
                 {"请求扫码", plcDb + ".0.0", "PLC→MES"},
-                {"扫码完成", plcDb + ".0.1", "MES→PLC"},
-                {"中转车上料到设备", plcDb + ".0.2", "PLC→MES"}
+                {"扫码完成反馈", plcDb + ".0.1", "MES→PLC"}
         };
 
         JPanel panel = new JPanel(new GridLayout(signals.length + 1, 4, 5, 5));
@@ -123,12 +121,10 @@ public class PlcSignalMonitor02 {
         // 初始化核心信号标签
         signal_requestScan = createStatusLabel();
         signal_scanComplete = createStatusLabel();
-        signal_transferToDevice = createStatusLabel();
 
         JLabel[] statusLabels = {
                 signal_requestScan,
-                signal_scanComplete,
-                signal_transferToDevice
+                signal_scanComplete
         };
 
         // 添加信号行
@@ -176,13 +172,11 @@ public class PlcSignalMonitor02 {
             // 读取核心信号 (注意地址要和 createSignalDetailPanel 中保持一致)
             boolean requestScan = s7PLC.readBoolean(plcDb + ".0.0");
             boolean scanComplete = s7PLC.readBoolean(plcDb + ".0.1");
-            boolean transferToDevice = s7PLC.readBoolean(plcDb + ".1.1");
 
             // 在EDT线程中更新UI
             SwingUtilities.invokeLater(() -> {
                 updateStatusLabel(signal_requestScan, requestScan);
                 updateStatusLabel(signal_scanComplete, scanComplete);
-                updateStatusLabel(signal_transferToDevice, transferToDevice);
             });
 
         } catch (Exception e) {
@@ -203,8 +197,7 @@ public class PlcSignalMonitor02 {
     private void showConnectionError() {
         JLabel[] labels = {
                 signal_requestScan,
-                signal_scanComplete,
-                signal_transferToDevice
+                signal_scanComplete
         };
 
         for (JLabel label : labels) {

+ 28 - 25
src/com/mes/component/WorkJPanelOP20.java

@@ -76,6 +76,9 @@ public class WorkJPanelOP20 extends JPanel {
     public String deviceIp2 = "80.20.10.43";
     public String deviceIp3 = "80.21.10.42";
     public String deviceIp4 = "80.21.10.43";
+    // FSW3 机床IP 按现有规律暂定,待现场确认
+    public String deviceIp5 = "80.20.10.44"; // 西侧 FSW3
+    public String deviceIp6 = "80.21.10.44"; // 东侧 FSW3
 
     public S7Connector s7Connector;
 
@@ -88,6 +91,10 @@ public class WorkJPanelOP20 extends JPanel {
 
     public String plcDb = "";
 
+    public String plcIp = ""; // 当前连接的 PLC IP
+
+    public JLabel ipLabel; // 界面显示 PLC/DB/机床IP
+
     public String plcDb2 = "DB7003";
 
     public String preSn = ""; // 扫码内容
@@ -152,46 +159,33 @@ public class WorkJPanelOP20 extends JPanel {
         }
 
         if(MesClient.mes_line_pos.equals("east")){ // 东侧
+            plcIp = plcIp2;
             s7PLC = new S7PLC(EPlcType.S1500, plcIp2);
             isScan = 2;
             log.info("IP:"+plcIp2);
-
-            if(pos.equals("C")){
-                deviceIp = deviceIp3;
-            }else{
-                deviceIp = deviceIp4;
-            }
         }else{
+            plcIp = plcIp1;
             s7PLC = new S7PLC(EPlcType.S1500, plcIp1);
             isScan = 1;
             log.info("IP:"+plcIp1);
-            if(pos.equals("A")){
-                deviceIp = deviceIp1;
-            }else{
-                deviceIp = deviceIp2;
-            }
         }
 
         s7PLC.setConnectTimeout(800);
         s7PLC.setReceiveTimeout(800);
 
+        // 子工位 -> DB块 / 机床IP / 设备名(西侧 A/B/E,东侧 C/D/F,E/F 为新增 FSW3)
+        switch (pos) {
+            case "A": plcDb = "DB7000"; deviceIp = deviceIp1; fswDeviceName = "西侧反面1号机"; break;
+            case "B": plcDb = "DB7001"; deviceIp = deviceIp2; fswDeviceName = "西侧反面2号机"; break;
+            case "E": plcDb = "DB7004"; deviceIp = deviceIp5; fswDeviceName = "西侧反面3号机"; break;
+            case "C": plcDb = "DB7000"; deviceIp = deviceIp3; fswDeviceName = "东侧反面1号机"; break;
+            case "D": plcDb = "DB7001"; deviceIp = deviceIp4; fswDeviceName = "东侧反面2号机"; break;
+            case "F": plcDb = "DB7004"; deviceIp = deviceIp6; fswDeviceName = "东侧反面3号机"; break;
+            default: log.error("未知子工位:" + pos); break;
+        }
 
         log.info("deviceIp:"+deviceIp);
 
-        if(pos.equals("A")){
-            plcDb = "DB7000";
-            fswDeviceName = "西侧正面1号机";
-        }else if(pos.equals("B")){
-            plcDb = "DB7001";
-            fswDeviceName = "西侧正面2号机";
-        }else if(pos.equals("C")){
-            plcDb = "DB7000";
-            fswDeviceName = "东侧正面1号机";
-        }else if(pos.equals("D")){
-            plcDb = "DB7001";
-            fswDeviceName = "东侧正面2号机";
-        }
-
         s7PLCFSW = new S7PLC(EPlcType.SINUMERIK_828D, deviceIp);
 
         s7PLCFSW.setConnectTimeout(800);
@@ -212,6 +206,13 @@ public class WorkJPanelOP20 extends JPanel {
         oprnoLabel2.setBounds(0, 12, workWidth / 5, 40);
         this.add(oprnoLabel2);
 
+        // 底部显示 PLC/DB/机床IP,机床离线时变红
+        ipLabel = new JLabel("PLC " + plcIp + " | " + plcDb + " | 机床 " + deviceIp);
+        ipLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
+        ipLabel.setForeground(Color.DARK_GRAY);
+        ipLabel.setBounds(5, 230, workWidth*2/3 + 55, 26);
+        this.add(ipLabel);
+
         status_menu = new JButton("等待请求扫码");
         status_menu.setBounds(workWidth/5, 0, workWidth*4/5, 40);
         status_menu.setForeground(Color.GREEN);
@@ -460,9 +461,11 @@ public class WorkJPanelOP20 extends JPanel {
                     if(fswOnline){
                         oprnoLabel.setForeground(Color.BLACK);
                         oprnoLabel2.setForeground(Color.BLACK);
+                        ipLabel.setForeground(Color.DARK_GRAY);
                     }else{
                         oprnoLabel.setForeground(Color.RED);
                         oprnoLabel2.setForeground(Color.RED);
+                        ipLabel.setForeground(Color.RED);
                     }
 
                     try{

+ 0 - 713
src/com/mes/component/WorkJPanelOP20Old.java

@@ -1,713 +0,0 @@
-package com.mes.component;
-
-import com.alibaba.fastjson2.JSONObject;
-import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
-import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
-import com.mes.ui.DataUtil;
-import com.mes.ui.MesClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public class WorkJPanelOP20Old extends JPanel {
-
-    public static final Logger log =  LoggerFactory.getLogger(WorkJPanelOP20Old.class);
-
-    public String oprno = "OP020";
-
-    public String pos = "A";
-
-    public String lastSn = ""; // 最近的码
-
-    public String lineSn = "";
-
-    public JLabel feedinglabel;
-
-    public JLabel feedingmeslabel;
-
-    public JLabel runlabel; //运行反馈,
-
-    public JLabel blankinglabel; // 下料反馈
-
-    public JLabel blankingmeslabel; // 下料MES反馈
-
-    public JLabel feedingtodevicelabel; // 上料到设备
-
-    public JLabel feedingtotransferlabel; // 上料到中转车
-
-    public JLabel transfertodevicelabel; // 上料到中转车
-
-    public JButton scanBtn;
-
-    public JTextField productSn;
-
-    public JTextField productSnFeeding;
-
-    public JButton status_menu;
-
-    public JButton resetBtn;
-
-    public JButton resetFeedingBtn;
-
-    public ImageIcon imageGreen;
-
-    public ImageIcon imageGray;
-
-    public String plcIp1 = "192.168.90.81"; // plc1 西侧
-    public String plcIp2 = "192.168.90.82"; // plc2 东侧
-
-    public S7PLC s7PLC = null;
-
-    public Integer workWidth = 470;
-    public Integer workHeight = 300;
-
-    public String plcDb = "DB7000";
-
-    public Integer tjFeedingFlag = 0; // 上料状态标识
-    public Integer tjFlag = 0; // 1=可加工 2=设备运行中 3=加工结束
-    public Integer tjStatus = 0; // 提交标识
-    public Integer zztjStatus = 0;
-    public Boolean toDevice = false;
-    public Boolean toTransfer = false;
-    public Boolean transferToDevice = false;
-
-    public static Boolean plcHeart = false;
-
-    public Integer isLocal = 1; // 0=正式 1=本地
-
-    public Integer isScan = 2; // 1=西侧 2=东测
-
-    public WorkJPanelOP20Old(String position){
-        this.setLayout(null);
-        this.setBackground(Color.WHITE);
-        this.pos = position;
-        this.lineSn = MesClient.mes_line_sn;
-
-        if(MesClient.mes_line_pos.equals("east")){ // 东侧
-            s7PLC = new S7PLC(EPlcType.S1500, plcIp2);
-            isScan = 2;
-            if(position.equals("C")){
-                plcDb = "DB7000";
-            }else{
-                plcDb = "DB7001";
-            }
-        }else{
-            s7PLC = new S7PLC(EPlcType.S1500, plcIp1);
-            isScan = 1;
-            if(position.equals("A")){
-                plcDb = "DB7000";
-            }else{
-                plcDb = "DB7001";
-            }
-        }
-
-
-        JLabel oprnoLabel = new JLabel(oprno+pos);
-        oprnoLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        oprnoLabel.setForeground(Color.BLACK);
-        oprnoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 20));
-        oprnoLabel.setBounds(0, 0, workWidth/5, 40);
-        this.add(oprnoLabel);
-
-        status_menu = new JButton("等待请求扫码");
-        status_menu.setBounds(workWidth/5, 0, workWidth*4/5, 40);
-        status_menu.setForeground(Color.GREEN);
-        status_menu.setForeground(Color.GREEN);
-        status_menu.setFont(new Font("微软雅黑", Font.PLAIN, 16));
-        status_menu.setBackground(Color.BLACK);
-        this.add(status_menu);
-
-        JLabel oprnoLabelFeeding = new JLabel("上料");
-        oprnoLabelFeeding.setHorizontalAlignment(SwingConstants.CENTER);
-        oprnoLabelFeeding.setForeground(Color.BLACK);
-        oprnoLabelFeeding.setFont(new Font("微软雅黑", Font.PLAIN, 20));
-        oprnoLabelFeeding.setBounds(0, 50, workWidth/5, 40);
-        this.add(oprnoLabelFeeding);
-
-        productSnFeeding = new JTextField("");
-        productSnFeeding.setHorizontalAlignment(SwingConstants.CENTER);
-        productSnFeeding.setForeground(Color.BLACK);
-        productSnFeeding.setFont(new Font("微软雅黑", Font.PLAIN, 16));
-        productSnFeeding.setEditable(false);
-        productSnFeeding.setBounds(workWidth/5, 50, workWidth*3/5, 40);
-        productSnFeeding.addMouseListener(new MouseAdapter() {
-            public void mouseClicked(MouseEvent e) {
-                String sn = productSnFeeding.getText().trim();
-                if(!sn.isEmpty()){
-                    MesClient.createQRCode(productSnFeeding.getText(),oprno+pos);
-                }
-            }
-        });
-        this.add(productSnFeeding);
-
-        JLabel oprnoLabelWork = new JLabel("加工");
-        oprnoLabelWork.setHorizontalAlignment(SwingConstants.CENTER);
-        oprnoLabelWork.setForeground(Color.BLACK);
-        oprnoLabelWork.setFont(new Font("微软雅黑", Font.PLAIN, 20));
-        oprnoLabelWork.setBounds(0, 100, workWidth/5, 40);
-        this.add(oprnoLabelWork);
-
-        productSn = new JTextField("");
-        productSn.setHorizontalAlignment(SwingConstants.CENTER);
-        productSn.setForeground(Color.BLACK);
-        productSn.setFont(new Font("微软雅黑", Font.PLAIN, 16));
-        productSn.setEditable(false);
-        productSn.setBounds(workWidth/5, 100, workWidth*3/5, 40);
-        productSn.addMouseListener(new MouseAdapter() {
-            public void mouseClicked(MouseEvent e) {
-                String sn = productSn.getText().trim();
-                if(!sn.isEmpty()){
-                    MesClient.createQRCode(productSn.getText(),oprno+pos);
-                }
-            }
-        });
-        this.add(productSn);
-
-        resetFeedingBtn = new JButton("刷新");
-        resetFeedingBtn.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                int choice = JOptionPane.showConfirmDialog(null, "确定刷新上料工件吗?", "操作确认", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
-                if (choice == JOptionPane.YES_OPTION) {
-                    resetFeeding();
-                }
-            }
-        });
-        resetFeedingBtn.setFont(new Font("微软雅黑", Font.PLAIN, 22));
-        resetFeedingBtn.setBounds(workWidth*4/5 + 10, 50, workWidth/5 - 10, 40);
-        this.add(resetFeedingBtn);
-
-        resetBtn = new JButton("刷新");
-        resetBtn.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                int choice = JOptionPane.showConfirmDialog(null, "确定刷新加工工件吗?", "操作确认", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
-                if (choice == JOptionPane.YES_OPTION) {
-                    resetBlanking();
-                }
-            }
-        });
-        resetBtn.setFont(new Font("微软雅黑", Font.PLAIN, 22));
-        resetBtn.setBounds(workWidth*4/5 + 10, 100, workWidth/5 - 10, 40);
-        this.add(resetBtn);
-
-        imageGreen = new ImageIcon(MesClient.class.getResource("/bg/green_dot.png"));
-        imageGreen.setImage(imageGreen.getImage().getScaledInstance(20, 20, Image.SCALE_SMOOTH));
-
-        imageGray = new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png"));
-        imageGray.setImage(imageGray.getImage().getScaledInstance(20, 20, Image.SCALE_SMOOTH));
-
-        feedinglabel = new JLabel("请求扫码");
-        feedinglabel.setHorizontalAlignment(SwingConstants.LEFT);
-        feedinglabel.setIcon(imageGreen);
-        feedinglabel.setForeground(Color.BLACK);
-        feedinglabel.setBounds(0, 150, workWidth/3, 30);
-        this.add(feedinglabel);
-
-        feedingmeslabel = new JLabel("MES扫码反馈");
-        feedingmeslabel.setHorizontalAlignment(SwingConstants.LEFT);
-        feedingmeslabel.setIcon(imageGreen);
-        feedingmeslabel.setForeground(Color.BLACK);
-        feedingmeslabel.setBounds(workWidth/3, 150, workWidth/3, 30);
-        feedingmeslabel.addMouseListener(new MouseAdapter() {
-            public void mouseClicked(MouseEvent e) {
-                boolean ret = readAllowFeeding();
-                int choice = JOptionPane.showConfirmDialog(null, "确定修改MES扫码反馈结果为"+(ret?"false":"true")+"吗?", "操作确认", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
-                if (choice == JOptionPane.YES_OPTION) {
-                    writeAllowFeeding(!ret);
-                }
-            }
-        });
-        this.add(feedingmeslabel);
-
-        runlabel = new JLabel("设备运行中");
-        runlabel.setHorizontalAlignment(SwingConstants.LEFT);
-        runlabel.setIcon(imageGreen);
-        runlabel.setForeground(Color.BLACK);
-        runlabel.setBounds(workWidth*2/3, 150, workWidth/3, 30);
-        this.add(runlabel);
-
-        blankinglabel = new JLabel("下料请求");
-        blankinglabel.setHorizontalAlignment(SwingConstants.LEFT);
-        blankinglabel.setIcon(imageGreen);
-        blankinglabel.setForeground(Color.BLACK);
-        blankinglabel.setBounds(0, 190, workWidth/3, 30);
-        this.add(blankinglabel);
-
-        blankingmeslabel = new JLabel("MES下料反馈");
-        blankingmeslabel.setHorizontalAlignment(SwingConstants.LEFT);
-        blankingmeslabel.setIcon(imageGreen);
-        blankingmeslabel.setForeground(Color.BLACK);
-        blankingmeslabel.setBounds(workWidth/3, 190, workWidth/3, 30);
-        this.add(blankingmeslabel);
-        blankingmeslabel.addMouseListener(new MouseAdapter() {
-            public void mouseClicked(MouseEvent e) {
-                boolean ret = readAllowBlanking();
-                int choice = JOptionPane.showConfirmDialog(null, "确定修改MES下料反馈结果为"+(ret?"false":"true")+"吗?", "操作确认", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
-                if (choice == JOptionPane.YES_OPTION) {
-                    writeAllowBlanking(!ret);
-                }
-            }
-        });
-
-        feedingtodevicelabel = new JLabel("上料到设备");
-        feedingtodevicelabel.setHorizontalAlignment(SwingConstants.LEFT);
-        feedingtodevicelabel.setIcon(imageGreen);
-        feedingtodevicelabel.setForeground(Color.BLACK);
-        feedingtodevicelabel.setBounds(workWidth*2/3, 190, workWidth/3, 30);
-        this.add(feedingtodevicelabel);
-
-        feedingtotransferlabel = new JLabel("上料到中转车");
-        feedingtotransferlabel.setHorizontalAlignment(SwingConstants.LEFT);
-        feedingtotransferlabel.setIcon(imageGreen);
-        feedingtotransferlabel.setForeground(Color.BLACK);
-        feedingtotransferlabel.setBounds(0, 230, workWidth/3, 30);
-        this.add(feedingtotransferlabel);
-
-        transfertodevicelabel = new JLabel("中转车上料到设备");
-        transfertodevicelabel.setHorizontalAlignment(SwingConstants.LEFT);
-        transfertodevicelabel.setIcon(imageGreen);
-        transfertodevicelabel.setForeground(Color.BLACK);
-        transfertodevicelabel.setBounds(workWidth/3, 230, workWidth/3, 30);
-        this.add(transfertodevicelabel);
-
-
-        startOprnoTimer();
-        heartData();
-
-        resetScanA();
-
-    }
-
-    public void setMenuStatus(String msg,int error){
-        if(error == 0){
-            this.status_menu.setForeground(Color.GREEN);
-        }else{
-            this.status_menu.setForeground(Color.RED);
-        }
-        this.status_menu.setText(msg);
-    }
-
-    // 定时任务 -----------------------------------------------------------------------------------------------------
-
-    public Timer cjTimerText2;
-    public void heartData() {
-        if(cjTimerText2!=null) {
-            cjTimerText2.cancel();
-        }
-        cjTimerText2 = new Timer();
-        cjTimerText2.schedule(new TimerTask() {
-            public void run() {
-                if(MesClient.isLogin == 1 && isLocal == 0){
-                    plcHeart = !plcHeart;
-                    writeBoolean(plcDb+".0.6",plcHeart);
-                }
-            }
-        }, 1000,1000);
-    }
-
-    public Timer oprnoTimer;
-    public void startOprnoTimer() {
-
-        //心跳显示图标
-        if(oprnoTimer!=null) {
-            oprnoTimer.cancel();
-        }
-        oprnoTimer = new Timer();
-        oprnoTimer.schedule(new TimerTask() {
-            public void run() {
-                try{
-
-                    if(MesClient.isLogin == 1){
-                        Boolean retFeeding = readFeeding();
-                        feedinglabel.setIcon(retFeeding?imageGreen:imageGray);
-
-                        transferToDevice = readFeedingTransferToDevice();
-                        transfertodevicelabel.setIcon(transferToDevice?imageGreen:imageGray);
-
-                        Boolean retFeedingAllow = readAllowFeeding();
-                        feedingmeslabel.setIcon(retFeedingAllow?imageGreen:imageGray);
-
-                        if(!retFeeding && retFeedingAllow){
-                            writeAllowFeeding(false);
-                        }
-
-                        Boolean retBlanking = readBlanking();
-                        blankinglabel.setIcon(retBlanking?imageGreen:imageGray);
-
-                        Boolean retAllowBlanking = readAllowBlanking();
-                        blankingmeslabel.setIcon(retAllowBlanking?imageGreen:imageGray);
-
-                        toDevice = readFeedingToDevice();
-                        feedingtodevicelabel.setIcon(toDevice?imageGreen:imageGray);
-
-                        toTransfer = readFeedingToTransfer();
-                        feedingtotransferlabel.setIcon(toTransfer?imageGreen:imageGray);
-
-                        transferToDevice = readFeedingTransferToDevice();
-                        transfertodevicelabel.setIcon(transferToDevice?imageGreen:imageGray);
-
-                        Boolean retRunning = readRunning();
-                        runlabel.setIcon(retRunning?imageGreen:imageGray);
-
-                        if(retBlanking && productSn.getText().isEmpty()){
-                            writeAllowBlanking(true);
-                        }
-
-                        if(tjFeedingFlag == 0){
-                            if(retFeeding){
-                                barCode();
-                            }
-                        }else if(tjFeedingFlag == 1){
-//                            if(toDevice){ // 去设备
-//
-//                            }
-                            if(tjFlag == 0 && retRunning){
-                                tjFlag = 1;
-                                productSn.setText(productSnFeeding.getText());
-//                                resetBtn.setEnabled(false);
-                                resetFeeding();
-                            }
-                            if(toTransfer){ // 去中转台
-                                int transferSn = readTransferNo();
-                                int transferFloor = readTransferFloor();
-                                if(transferSn > 0 && transferFloor > 0){
-                                    if(zztjStatus == 0) {
-                                        zztjStatus = 1;
-                                        JSONObject retObj = DataUtil.saveSn(oprno+pos,productSnFeeding.getText().trim(),transferSn,transferFloor,MesClient.user_menu.getText());
-                                        if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
-                                            resetFeeding();
-                                        }else{
-                                            if(retObj.get("result")==null){
-                                                setMenuStatus("请求失败,请重试",-1);
-                                            }else{
-                                                if(retObj.get("result").toString().equalsIgnoreCase("false")){
-                                                    setMenuStatus(retObj.getString("message"),-1);
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-
-                        if(tjFlag == 0 && !retBlanking){
-                            writeAllowBlanking(false);
-                        }
-
-                        if(tjFlag == 1){
-                            if(toDevice){ // 去设备
-                                if(retRunning){
-                                    tjFlag = 2;
-                                    setMenuStatus("工件加工中", 0);
-                                    // 运行中清除下料反馈
-                                    writeAllowBlanking(false);
-                                }
-                            }
-                        }else if(tjFlag == 2){
-                            if(retBlanking){
-                                tjFlag = 3;
-                                setMenuStatus("工件加工结束,结果上传中", 0);
-
-                                if(tjStatus == 0){
-                                    tjStatus = 1;
-
-                                    // 异步执行上传任务,防止阻塞
-                                    ExecutorService executor = Executors.newCachedThreadPool();
-                                    executor.submit(() -> {
-                                        // 你的异步任务代码
-                                        log.info("["+oprno+pos+"]质量上传任务开始");
-                                        try {
-                                            JSONObject retObj = DataUtil.sendQuality(productSn.getText(),oprno+pos,"OK",MesClient.user_menu.getText());
-                                            if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
-                                                resetBlanking();
-                                            }else{
-                                                if(retObj.get("result")==null){
-                                                    setMenuStatus("请求失败,请重试",-1);
-                                                }else{
-                                                    if(retObj.get("result").toString().equalsIgnoreCase("false")){
-                                                        setMenuStatus(retObj.getString("message"),-1);
-                                                    }
-                                                }
-                                            }
-                                        } catch (Exception e) {
-                                            Thread.currentThread().interrupt();
-                                        }
-                                        log.info("["+oprno+pos+"]质量上传任务结束");
-                                    });
-                                    // 关闭ExecutorService,不再接受新任务,等待已提交的任务完成
-                                    executor.shutdown();
-                                }
-                            }
-                        }
-                    }
-                }catch (Exception e) {
-                    log.error(e.getMessage());
-                }
-            }
-        }, 100,3000);
-    }
-
-    public void barCode(){
-        if(!productSnFeeding.getText().isEmpty()){
-            return;
-        }
-        String sn = readQrcode();
-        if(sn.equals("")){
-            if(productSnFeeding.getText().isEmpty()){
-                productSnFeeding.setText("空结果");
-                this.setMenuStatus("扫码结果为空", -1);
-            }
-        }else{
-            productSnFeeding.setText(sn);
-            lastSn = sn;
-            // 查询工件质量
-            JSONObject retObj = DataUtil.checkQuality(sn,oprno+pos,MesClient.user_menu.getText());
-            if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
-                tjFeedingFlag = 1;//可加工
-                setMenuStatus("工件可以加工", 0);
-                writeAllowFeeding(true);
-//                resetFeedingBtn.setEnabled(false);
-            }else{
-                writeAllowFeeding(false);
-                resetFeedingBtn.setEnabled(true);
-                if(retObj.get("result")==null){
-                    setMenuStatus("请求失败,请重试",-1);
-                }else{
-                    if(retObj.get("result").toString().equalsIgnoreCase("false")){
-                        setMenuStatus(retObj.getString("message"),-1);
-                    }
-                }
-            }
-        }
-    }
-
-    public void resetBlanking() {
-        tjFlag = 0;
-        tjStatus = 0;
-        productSn.setText("");
-        setMenuStatus("工件结果已提交,等待下一件",0);
-        resetBtn.setEnabled(true);
-    }
-
-    public void resetFeeding() {
-        zztjStatus = 0;
-        productSnFeeding.setText("");
-        tjFeedingFlag = 0;
-        setMenuStatus("等待请求扫码",0);
-        resetFeedingBtn.setEnabled(true);
-        writeAllowFeeding(false);
-    }
-
-    public void resetScanA() {
-        tjFeedingFlag = 0;
-        tjFlag = 0;
-        tjStatus = 0;
-        productSn.setText("");
-        productSnFeeding.setText("");
-        setMenuStatus("等待请求扫码",0);
-        resetBtn.setEnabled(true);
-        resetFeedingBtn.setEnabled(true);
-        writeAllowFeeding(false);
-        writeAllowBlanking(false);
-    }
-    // 与设备交互-----------------------------------------------------------------------------------------
-
-    // 请求扫码
-    public boolean readFeeding(){
-        if(isLocal == 1){
-            return false;
-        }else{
-            return readBoolean(plcDb+".0.0");
-        }
-    }
-
-    // 读取上料到设备
-    public boolean readFeedingToDevice(){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return readBoolean(plcDb+".0.7");
-        }
-    }
-
-    // 读取上料到中转车
-    public boolean readFeedingToTransfer(){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return readBoolean(plcDb+".1.0");
-        }
-    }
-
-    // 读取中转车上料到设备
-    public boolean readFeedingTransferToDevice(){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return readBoolean(plcDb+".1.1");
-        }
-    }
-
-    // 读取下料信号
-    public boolean readBlanking(){
-        if(isLocal == 1){
-            return false;
-        }else{
-            return readBoolean(plcDb+".0.1");
-        }
-    }
-
-    // 读取设备运行信号
-    public boolean readRunning(){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return readBoolean(plcDb+".0.2");
-        }
-    }
-
-    // 读取设备通讯状态
-    public boolean readDeviceStatus(){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return readBoolean(plcDb+".0.3");
-        }
-    }
-
-    // 读取MES允许上料信号
-    public boolean readAllowFeeding(){
-        if(isLocal == 1){
-            return false;
-        }else{
-            return readBoolean(plcDb+".0.4");
-        }
-    }
-
-    // 写入MES允许上料信号
-    public boolean writeAllowFeeding(Boolean b){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return writeBoolean(plcDb+".0.4",b);
-        }
-    }
-
-    // 读取MES允许下料信号
-    public boolean readAllowBlanking(){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return readBoolean(plcDb+".0.5");
-        }
-    }
-
-    // 写入MES允许下料信号
-    public boolean writeAllowBlanking(Boolean b){
-        if(isLocal == 1){
-            return true;
-        }else{
-            return writeBoolean(plcDb+".0.5",b);
-        }
-    }
-
-    // 读取中转车号
-    public int readTransferNo(){
-        if(isLocal == 1){
-            return 1;
-        }else{
-            return s7PLC.readInt16(plcDb+".2.0");
-        }
-    }
-
-    // 读取中转车层数
-    public int readTransferFloor(){
-        if(isLocal == 1){
-            return 1;
-        }else{
-            return s7PLC.readInt16(plcDb+".4.0");
-        }
-    }
-
-    // 控制扫码枪读取二维码
-    public String readQrcode(){
-//        String sn = "5001040043561010006";
-        String sn = "";
-        if(isLocal == 1){
-            return "";
-        }else{
-            try{
-                if(transferToDevice){ // 中转车上料到设备
-                    int transferSn = readTransferNo();
-                    int transferFloor = readTransferFloor();
-                    JSONObject retObj = DataUtil.getSn(oprno+pos,transferSn,transferFloor,MesClient.user_menu.getText());
-                    if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) {
-                        sn = retObj.getString("data");
-                        this.setMenuStatus("允许工件加工",0);
-//                        writeAllowFeeding(true);
-                    }else{
-                        writeAllowFeeding(false);
-                        if(retObj.get("result")==null){
-                            this.setMenuStatus("请求失败,请重试",-1);
-                        }else{
-                            if(retObj.get("result").toString().equalsIgnoreCase("false")){
-                                this.setMenuStatus(retObj.getString("message"),-1);
-                            }
-                        }
-                    }
-                }else{
-                    if(isScan == 1){
-                        if(pos.equals("A") || pos.equals("B")){
-                            sn = MesClient.scanQrcode2();
-                        }else{
-                            sn = MesClient.scanQrcode1();
-                        }
-                    }else{
-                        if(pos.equals("A") || pos.equals("B")){
-                            sn = MesClient.scanQrcode4();
-                        }else{
-                            sn = MesClient.scanQrcode3();
-                        }
-                    }
-                }
-            }catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-
-        return sn;
-    }
-
-    public boolean readBoolean(String db){
-        boolean permit;
-        try {
-            permit = s7PLC.readBoolean(db);
-            log.info("<"+this.oprno+this.pos+">读取"+db+"-->成功,结果:{}", permit ? "true" : "false");
-        } catch (Exception e) {
-            log.error("<"+this.oprno+this.pos+">读取"+db+"-->失败", e);
-            return false;
-        }
-        return permit;
-    }
-
-    public boolean writeBoolean(String db, boolean permit){
-        try {
-            s7PLC.writeBoolean(db,permit);
-            log.info("<"+this.oprno+this.pos+">写入"+db+"-->成功,写入内容:{}", permit ? "true" : "false");
-        } catch (Exception e) {
-            log.error("<"+this.oprno+this.pos+">写入"+db+"-->失败,写入内容:{}", permit ? "true" : "false");
-            log.error(e.getMessage(), e);
-            return false;
-        }
-        return true;
-    }
-}

+ 27 - 23
src/com/mes/component/WorkJPanelOP30.java

@@ -77,6 +77,9 @@ public class WorkJPanelOP30 extends JPanel {
     public String deviceIp2 = "80.20.10.43";
     public String deviceIp3 = "80.21.10.42";
     public String deviceIp4 = "80.21.10.43";
+    // FSW3 机床IP 按现有规律暂定,待现场确认
+    public String deviceIp5 = "80.20.10.44"; // 西侧 FSW3
+    public String deviceIp6 = "80.21.10.44"; // 东侧 FSW3
 
     public S7PLC s7PLC = null;
 
@@ -87,6 +90,10 @@ public class WorkJPanelOP30 extends JPanel {
 
     public String plcDb = "";
 
+    public String plcIp = ""; // 当前连接的 PLC IP
+
+    public JLabel ipLabel; // 界面显示 PLC/DB/机床IP
+
     public String plcDb2 = "DB7010";
 
     public String preSn = ""; // 扫码内容
@@ -148,41 +155,29 @@ public class WorkJPanelOP30 extends JPanel {
 
 
         if(MesClient.mes_line_pos.equals("east")){ // 东侧
+            plcIp = plcIp2;
             s7PLC = new S7PLC(EPlcType.S1500, plcIp2);
             isScan = 2;
             log.info("IP:"+plcIp2);
-
-            if(pos.equals("C")){
-                deviceIp = deviceIp3;
-            }else{
-                deviceIp = deviceIp4;
-            }
         }else{
+            plcIp = plcIp1;
             s7PLC = new S7PLC(EPlcType.S1500, plcIp1);
             isScan = 1;
             log.info("IP:"+plcIp1);
-            if(pos.equals("A")){
-                deviceIp = deviceIp1;
-            }else{
-                deviceIp = deviceIp2;
-            }
         }
 
         s7PLC.setConnectTimeout(800);
         s7PLC.setReceiveTimeout(800);
 
-        if(pos.equals("A")){
-            plcDb = "DB7010";
-            fswDeviceName = "西侧反面1号机";
-        }else if(pos.equals("B")){
-            plcDb = "DB7011";
-            fswDeviceName = "西侧反面2号机";
-        }else if(pos.equals("C")){
-            plcDb = "DB7010";
-            fswDeviceName = "东侧反面1号机";
-        }else if(pos.equals("D")){
-            plcDb = "DB7011";
-            fswDeviceName = "东侧反面2号机";
+        // 子工位 -> DB块 / 机床IP / 设备名(西侧 A/B/E,东侧 C/D/F,E/F 为新增 FSW3)
+        switch (pos) {
+            case "A": plcDb = "DB7010"; deviceIp = deviceIp1; fswDeviceName = "西侧正面1号机"; break;
+            case "B": plcDb = "DB7011"; deviceIp = deviceIp2; fswDeviceName = "西侧正面2号机"; break;
+            case "E": plcDb = "DB7014"; deviceIp = deviceIp5; fswDeviceName = "西侧正面3号机"; break;
+            case "C": plcDb = "DB7010"; deviceIp = deviceIp3; fswDeviceName = "东侧正面1号机"; break;
+            case "D": plcDb = "DB7011"; deviceIp = deviceIp4; fswDeviceName = "东侧正面2号机"; break;
+            case "F": plcDb = "DB7014"; deviceIp = deviceIp6; fswDeviceName = "东侧正面3号机"; break;
+            default: log.error("未知子工位:" + pos); break;
         }
 
         s7PLCFSW = new S7PLC(EPlcType.SINUMERIK_828D, deviceIp);
@@ -203,6 +198,13 @@ public class WorkJPanelOP30 extends JPanel {
         oprnoLabel2.setBounds(0, 12, workWidth / 5, 40);
         this.add(oprnoLabel2);
 
+        // 底部显示 PLC/DB/机床IP,机床离线时变红
+        ipLabel = new JLabel("PLC " + plcIp + " | " + plcDb + " | 机床 " + deviceIp);
+        ipLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
+        ipLabel.setForeground(Color.DARK_GRAY);
+        ipLabel.setBounds(5, 230, workWidth*2/3 + 55, 26);
+        this.add(ipLabel);
+
         status_menu = new JButton("等待请求扫码");
         status_menu.setBounds(workWidth/5, 0, workWidth*4/5, 40);
         status_menu.setForeground(Color.GREEN);
@@ -444,9 +446,11 @@ public class WorkJPanelOP30 extends JPanel {
                     if(fswOnline){
                         oprnoLabel.setForeground(Color.BLACK);
                         oprnoLabel2.setForeground(Color.BLACK);
+                        ipLabel.setForeground(Color.DARK_GRAY);
                     }else{
                         oprnoLabel.setForeground(Color.RED);
                         oprnoLabel2.setForeground(Color.RED);
+                        ipLabel.setForeground(Color.RED);
                     }
 
                     try{

+ 19 - 2
src/com/mes/component/WorkJPanelScan.java

@@ -6,6 +6,7 @@ import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
 import com.mes.ui.CacheData;
 import com.mes.ui.MesClient;
 import com.mes.util.JdbcUtils;
+import com.mes.util.TCPClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,6 +69,10 @@ public class WorkJPanelScan extends JPanel {
 
     public String plcDb = "DB7013";
 
+    public String plcIp = ""; // 当前连接的 PLC IP
+
+    public JLabel ipLabel; // 界面显示 PLC/DB/扫码枪IP
+
     public Integer tjFeedingFlag = 0; // 上料状态标识
     public Integer tjFlag = 0; // 1=可加工 2=设备运行中 3=加工结束
     public Integer tjStatus = 0; // 提交标识
@@ -80,7 +85,7 @@ public class WorkJPanelScan extends JPanel {
     public Integer isScan = 1; // 1=西侧 2=东测
 
     public JButton signalBtn; // 信号监控按钮
-    public PlcSignalMonitor signalMonitor; // 信号监控组件
+    public PlcSignalMonitor02 signalMonitor; // 信号监控组件(扫码精简版)
 
     public CacheData cacheData = null;
     public String cacheName = "";
@@ -115,9 +120,11 @@ public class WorkJPanelScan extends JPanel {
 
 
         if(MesClient.mes_line_pos.equals("east")){ // 东侧
+            plcIp = plcIp2;
             s7PLC = new S7PLC(EPlcType.S1500, plcIp2);
             isScan = 2;
         }else{
+            plcIp = plcIp1;
             s7PLC = new S7PLC(EPlcType.S1500, plcIp1);
             isScan = 1;
         }
@@ -209,11 +216,21 @@ public class WorkJPanelScan extends JPanel {
 //        resetScanA();
 
         // 信号监控按钮
-        signalMonitor = new PlcSignalMonitor(s7PLC, plcDb, oprno + pos, MesClient.mesClientFrame);
+        signalMonitor = new PlcSignalMonitor02(s7PLC, plcDb, oprno + pos, MesClient.mesClientFrame);
         signalBtn = signalMonitor.createSignalButton();
         signalBtn.setBounds(workWidth*2/3 + 63, 230, 90, 26);
         this.add(signalBtn);
 
+        // 底部显示 PLC/DB/扫码枪IP,扫码枪选择与 readQrcode 保持一致
+        TCPClient scanner = oprno.equals("OP040")
+                ? (isScan == 1 ? MesClient.tcpClient2 : MesClient.tcpClient1)
+                : (isScan == 1 ? MesClient.tcpClient4 : MesClient.tcpClient3);
+        ipLabel = new JLabel("PLC " + plcIp + " | " + plcDb + " | 扫码枪 " + scanner.serverIP + ":" + scanner.serverPort);
+        ipLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
+        ipLabel.setForeground(Color.DARK_GRAY);
+        ipLabel.setBounds(5, 230, workWidth*2/3 + 55, 26);
+        this.add(ipLabel);
+
         formatElementUI();
     }
 

+ 0 - 56
src/com/mes/ui/DataUtil.java

@@ -131,62 +131,6 @@ public class DataUtil {
         }
     }
 
-    public static JSONObject getSn(String oprno,int transferSn,int transferFloor,String user){
-        try{
-            String enconding = "UTF-8";
-            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
-            Properties pro = new Properties();
-            BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
-            pro.load(br);
-            String mes_server_ip = pro.getProperty("mes.server_ip");
-            String lineSn = pro.getProperty("mes.line_sn").trim();
-            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesTransfer/getSn";
-            String params = "__ajax=json&oprno="+oprno+"&lineSn="+lineSn+"&transferSn="+transferSn+"&transferFloor="+transferFloor+"&ucode="+user;
-            log.info("url="+url);
-            log.info("params="+params);
-            String result = doPost(url,params);
-            log.info("result="+result);
-
-            if(result.equalsIgnoreCase("false")) {
-                return null;
-            }else {
-                JdbcUtils.insertData(oprno, "100000", params, "MQDW", "");
-                return JSONObject.parseObject(result);
-            }
-        }catch (Exception e){
-            log.info("e="+e.getMessage());
-            return null;
-        }
-    }
-
-    public static JSONObject saveSn(String oprno,String sn,int transferSn,int transferFloor,String user){
-        try{
-            String enconding = "UTF-8";
-            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
-            Properties pro = new Properties();
-            BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
-            pro.load(br);
-            String mes_server_ip = pro.getProperty("mes.server_ip");
-            String lineSn = pro.getProperty("mes.line_sn").trim();
-            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesTransfer/saveSn";
-            String params = "__ajax=json&oprno="+oprno+"&lineSn="+lineSn+"&sn="+sn+"&transferSn="+transferSn+"&transferFloor="+transferFloor+"&ucode="+user;
-            log.info("url="+url);
-            log.info("params="+params);
-            String result = doPost(url,params);
-            log.info("result="+result);
-
-            if(result.equalsIgnoreCase("false")) {
-                return null;
-            }else {
-                JdbcUtils.insertData(oprno, "100000", params, "MQDW", "");
-                return JSONObject.parseObject(result);
-            }
-        }catch (Exception e){
-            log.info("e="+e.getMessage());
-            return null;
-        }
-    }
-
     public static JSONObject deviceAlarm(String oprno,String sn,String content,String user){
         try{
             String enconding = "UTF-8";

+ 35 - 91
src/com/mes/ui/MesClient.java

@@ -93,6 +93,7 @@ public class MesClient extends JFrame {
     public static WorkJPanelOP10 workJPanelOP10A;
     public static WorkJPanelOP20 workJPanelOP20A;
     public static WorkJPanelOP20 workJPanelOP20C;
+    public static WorkJPanelOP20 workJPanelOP20E; // FSW3
 
 
     public static WorkJPanelScan workJPanelScanA;
@@ -103,6 +104,7 @@ public class MesClient extends JFrame {
 
     public static WorkJPanelOP30 workJPanelOP30A;
     public static WorkJPanelOP30 workJPanelOP30C;
+    public static WorkJPanelOP30 workJPanelOP30E; // FSW3
 
     public static void main(String[] args) {
         EventQueue.invokeLater(new Runnable() {
@@ -374,54 +376,20 @@ public class MesClient extends JFrame {
         indexPanelB.setLayout(new GridLayout(2,2, 5, 5));
         indexPanelB.setBackground(Color.LIGHT_GRAY);
 
-        if(mes_line_pos.equals("east")){
-            JPanel indexPanel20A = new JPanel();
-            indexPanel20A.setLayout(null);
-            indexPanel20A.setBackground(Color.WHITE);
-            workJPanelOP20A = new WorkJPanelOP20("C");
-            workJPanelOP20A.setBounds(10, 10, workJPanelOP20A.workWidth, workJPanelOP20A.workHeight);
-            indexPanel20A.add(workJPanelOP20A);
-            indexPanelB.add(indexPanel20A);
-
-            JPanel indexPanel20C = new JPanel();
-            indexPanel20C.setLayout(null);
-            indexPanel20C.setBackground(Color.WHITE);
-            workJPanelOP20C = new WorkJPanelOP20("D");
-            workJPanelOP20C.setBounds(10, 10, workJPanelOP20C.workWidth, workJPanelOP20C.workHeight);
-            indexPanel20C.add(workJPanelOP20C);
-            indexPanelB.add(indexPanel20C);
-
-
-        }else{
-            JPanel indexPanel20A = new JPanel();
-            indexPanel20A.setLayout(null);
-            indexPanel20A.setBackground(Color.WHITE);
-            workJPanelOP20A = new WorkJPanelOP20("A");
-            workJPanelOP20A.setBounds(10, 10, workJPanelOP20A.workWidth, workJPanelOP20A.workHeight);
-            indexPanel20A.add(workJPanelOP20A);
-            indexPanelB.add(indexPanel20A);
-
-            JPanel indexPanel20C = new JPanel();
-            indexPanel20C.setLayout(null);
-            indexPanel20C.setBackground(Color.WHITE);
-            workJPanelOP20C = new WorkJPanelOP20("B");
-            workJPanelOP20C.setBounds(10, 10, workJPanelOP20C.workWidth, workJPanelOP20C.workHeight);
-            indexPanel20C.add(workJPanelOP20C);
-            indexPanelB.add(indexPanel20C);
+        // FSW 子工位:西侧 A/B/E,东侧 C/D/F(E/F 为新增 FSW3)
+        String[] fswPos = mes_line_pos.equals("east") ? new String[]{"C", "D", "F"} : new String[]{"A", "B", "E"};
 
-        }
-
-        JPanel indexPanel20Ca = new JPanel();
-        indexPanel20Ca.setLayout(null);
-        indexPanel20Ca.setBackground(Color.WHITE);
+        // OP40 反面FSW:FSW1=DB7000 FSW2=DB7001 FSW3=DB7004,扫码 DB7003
+        workJPanelOP20A = new WorkJPanelOP20(fswPos[0]);
+        indexPanelB.add(wrapCell(workJPanelOP20A, workJPanelOP20A.workWidth, workJPanelOP20A.workHeight));
+        workJPanelOP20C = new WorkJPanelOP20(fswPos[1]);
+        indexPanelB.add(wrapCell(workJPanelOP20C, workJPanelOP20C.workWidth, workJPanelOP20C.workHeight));
+        workJPanelOP20E = new WorkJPanelOP20(fswPos[2]);
+        indexPanelB.add(wrapCell(workJPanelOP20E, workJPanelOP20E.workWidth, workJPanelOP20E.workHeight));
         workJPanelScanA = new WorkJPanelScan("A");
-        workJPanelScanA.setBounds(10, 10, workJPanelScanA.workWidth, workJPanelScanA.workHeight);
-        indexPanel20Ca.add(workJPanelScanA);
-        indexPanelB.add(indexPanel20Ca);
-
-
+        indexPanelB.add(wrapCell(workJPanelScanA, workJPanelScanA.workWidth, workJPanelScanA.workHeight));
 
-        tabbedPane.addTab("OP40正面FSW", null, indexScrollPaneB, null);
+        tabbedPane.addTab("OP40反面FSW", null, indexScrollPaneB, null);
 
         JPanel indexPanelC = new JPanel();
         indexScrollPaneC = new JScrollPane(indexPanelC);
@@ -459,49 +427,15 @@ public class MesClient extends JFrame {
         indexPanelD.setBackground(Color.LIGHT_GRAY);
         tabbedPane.setForegroundAt(2, Color.RED);
 
-        if(mes_line_pos.equals("east")){
-            JPanel indexPanel30A = new JPanel();
-            indexPanel30A.setLayout(null);
-            indexPanel30A.setBackground(Color.WHITE);
-            workJPanelOP30A = new WorkJPanelOP30("C");
-            workJPanelOP30A.setBounds(10, 10, workJPanelOP30A.workWidth, workJPanelOP30A.workHeight);
-            indexPanel30A.add(workJPanelOP30A);
-            indexPanelD.add(indexPanel30A);
-
-            JPanel indexPanel30C = new JPanel();
-            indexPanel30C.setLayout(null);
-            indexPanel30C.setBackground(Color.WHITE);
-            workJPanelOP30C = new WorkJPanelOP30("D");
-            workJPanelOP30C.setBounds(10, 10, workJPanelOP30C.workWidth, workJPanelOP30C.workHeight);
-            indexPanel30C.add(workJPanelOP30C);
-            indexPanelD.add(indexPanel30C);
-
-
-        }else{
-            JPanel indexPanel30A = new JPanel();
-            indexPanel30A.setLayout(null);
-            indexPanel30A.setBackground(Color.WHITE);
-            workJPanelOP30A = new WorkJPanelOP30("A");
-            workJPanelOP30A.setBounds(10, 10, workJPanelOP30A.workWidth, workJPanelOP30A.workHeight);
-            indexPanel30A.add(workJPanelOP30A);
-            indexPanelD.add(indexPanel30A);
-
-            JPanel indexPanel30C = new JPanel();
-            indexPanel30C.setLayout(null);
-            indexPanel30C.setBackground(Color.WHITE);
-            workJPanelOP30C = new WorkJPanelOP30("B");
-            workJPanelOP30C.setBounds(10, 10, workJPanelOP30C.workWidth, workJPanelOP30C.workHeight);
-            indexPanel30C.add(workJPanelOP30C);
-            indexPanelD.add(indexPanel30C);
-        }
-
-        JPanel indexPanel20Caa = new JPanel();
-        indexPanel20Caa.setLayout(null);
-        indexPanel20Caa.setBackground(Color.WHITE);
+        // OP50 正面FSW:FSW1=DB7010 FSW2=DB7011 FSW3=DB7014,扫码 DB7013
+        workJPanelOP30A = new WorkJPanelOP30(fswPos[0]);
+        indexPanelD.add(wrapCell(workJPanelOP30A, workJPanelOP30A.workWidth, workJPanelOP30A.workHeight));
+        workJPanelOP30C = new WorkJPanelOP30(fswPos[1]);
+        indexPanelD.add(wrapCell(workJPanelOP30C, workJPanelOP30C.workWidth, workJPanelOP30C.workHeight));
+        workJPanelOP30E = new WorkJPanelOP30(fswPos[2]);
+        indexPanelD.add(wrapCell(workJPanelOP30E, workJPanelOP30E.workWidth, workJPanelOP30E.workHeight));
         workJPanelScanB = new WorkJPanelScan("B");
-        workJPanelScanB.setBounds(10, 10, workJPanelScanB.workWidth, workJPanelScanB.workHeight);
-        indexPanel20Caa.add(workJPanelScanB);
-        indexPanelD.add(indexPanel20Caa);
+        indexPanelD.add(wrapCell(workJPanelScanB, workJPanelScanB.workWidth, workJPanelScanB.workHeight));
 
         tabbedPane.addTab("OP50正面FSW", null, indexScrollPaneD, null);
 
@@ -519,14 +453,14 @@ public class MesClient extends JFrame {
 
         // 定义所有子工位
         // OP035: A, B
-        // OP040: A, B, C, D
+        // OP040: A, B, C, D, E, F(E=西侧FSW3 F=东侧FSW3)
         // OP045: A, B
-        // OP050: A, B, C, D
+        // OP050: A, B, C, D, E, F
         String[][] stationGroups = {
             {"OP035", "A", "B"},
-            {"OP040", "A", "B", "C", "D"},
+            {"OP040", "A", "B", "C", "D", "E", "F"},
             {"OP045", "A", "B"},
-            {"OP050", "A", "B", "C", "D"}
+            {"OP050", "A", "B", "C", "D", "E", "F"}
         };
         
         // 计算总的工位数(用于数组大小)
@@ -577,6 +511,16 @@ public class MesClient extends JFrame {
         });
     }
 
+    // 白底容器包一层工位面板,放进 GridLayout 单元格
+    private static JPanel wrapCell(JPanel work, int w, int h) {
+        JPanel cell = new JPanel();
+        cell.setLayout(null);
+        cell.setBackground(Color.WHITE);
+        work.setBounds(10, 10, w, h);
+        cell.add(work);
+        return cell;
+    }
+
     public static void setMenuStatus(String msg,int error){
         if(error == 0){
             MesClient.status_menu.setForeground(Color.GREEN);

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

@@ -1,7 +1,7 @@
 #mes.server_ip=127.0.0.1
 mes.server_ip=192.168.17.170
 mes.line_sn=CZ060
-#90.2 OP10A
+#90.2 OP10A 061
 #mes.line_pos=west
-#90.1 OP10B
+#90.1 OP10B 060
 mes.line_pos=east