wangxichen 3 giorni fa
parent
commit
b0a77cb400
3 ha cambiato i file con 405 aggiunte e 88 eliminazioni
  1. 42 0
      src/com/mes/ui/DataUtil.java
  2. 355 77
      src/com/mes/ui/MesClient.java
  3. 8 11
      src/com/mes/util/WorkTimer.java

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

@@ -332,6 +332,48 @@ public class DataUtil {
         }
     }
 
+    // 漏点记录接口
+    public static JSONObject leakPointRecord(String sn, String leakPoints, String remark,
+                                             String oprno, String lineSn, String ucode) {
+        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 url = "http://" + mes_server_ip + ":8980/js/a/mes/mesProductRecord/leakpoint";
+
+            String params = "__ajax=json"
+                    + "&sn=" + URLEncoder.encode(sn != null ? sn : "", "UTF-8")
+                    + "&leakPoints=" + URLEncoder.encode(leakPoints != null ? leakPoints : "", "UTF-8")
+                    + "&remark=" + URLEncoder.encode(remark != null ? remark : "", "UTF-8")
+                    + "&oprno=" + URLEncoder.encode(oprno != null ? oprno : "", "UTF-8")
+                    + "&lineSn=" + URLEncoder.encode(lineSn != null ? lineSn : "", "UTF-8")
+                    + "&workNum=" + URLEncoder.encode(ucode != null ? ucode : "", "UTF-8");
+
+            // 添加sessionid
+            if (MesClient.sessionid != null && !MesClient.sessionid.isEmpty()) {
+                params += "&__sid=" + MesClient.sessionid;
+            }
+
+            log.info("漏点记录接口 params=" + params);
+            String result = doPost(url, params);
+            log.info("漏点记录接口 result=" + result);
+
+            if (result == null || result.trim().isEmpty() || result.equalsIgnoreCase("false")) {
+                return null;
+            } else {
+                return JSONObject.parseObject(result);
+            }
+        } catch (Exception e) {
+            log.error("漏点记录接口调用失败: " + e.getMessage());
+            e.printStackTrace();
+            return null;
+        }
+    }
+
     public static String doPost(String httpUrl, String param) {
         HttpURLConnection connection = null;
         InputStream is = null;

+ 355 - 77
src/com/mes/ui/MesClient.java

@@ -103,6 +103,15 @@ public class MesClient extends JFrame {
 
     public static Integer tjFlag = 0;
 
+    // 漏点相关变量
+    public static JButton[] weldButtons = new JButton[39]; // 漏点按钮
+    public static boolean[] weldClickStates = new boolean[39]; // 漏点点击状态
+    public static Timer countdownTimer = null; // OK倒计时定时器
+    public static int countdownSeconds = 5; // 倒计时秒数
+    public static JLabel countdownLabel = null; // 倒计时显示标签
+    public static TestParam pendingTestParam = null; // 等待提交的测试参数
+    public static String deviceResult = ""; // 设备判定结果
+
     public static String tjFlagText2 = "设备运行中";
 
     public static String tjFlagText3 = "设备运行结束";
@@ -336,6 +345,14 @@ public class MesClient extends JFrame {
         tjFlag = 0;
         mesStartFlag = 0;
 
+        // 重置漏点按钮
+        closeWeldButtons();
+        // 停止倒计时
+        stopCountdown();
+        // 清空待提交数据
+        pendingTestParam = null;
+        deviceResult = "";
+
 //        f_scan_data_bt_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/scan_barcode.png")));
 //        f_scan_data_bt_1.setText("扫码");
 //        MesClient.f_scan_data_bt_1.setEnabled(true);
@@ -956,26 +973,31 @@ public class MesClient extends JFrame {
         tabbedPane.setFont(new Font("宋体", Font.BOLD, 22));
         contentPane.add(tabbedPane);
 
-        //首页
+        //首页 - 使用BorderLayout布局
         JPanel indexPanelA = new JPanel();
         indexScrollPaneA = new JScrollPane(indexPanelA);
-        indexPanelA.setLayout(null);
+        indexPanelA.setLayout(new BorderLayout(10, 10));
+
+        // 顶部容器
+        JPanel topContainer = new JPanel();
+        topContainer.setLayout(new BoxLayout(topContainer, BoxLayout.Y_AXIS));
+        topContainer.setBorder(new EmptyBorder(20, 20, 10, 20));
 
-        product_sn = new JTextField();
-        product_sn.setHorizontalAlignment(SwingConstants.LEFT);
+        // 扫码区域
+        JPanel scanRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
+        product_sn = new JTextField(30);
+        product_sn.setHorizontalAlignment(SwingConstants.CENTER);
         product_sn.setEditable(true);
         product_sn.setFont(new Font("微软雅黑", Font.PLAIN, 28));
-        product_sn.setBounds(81, 70, 602, 70);
-        indexPanelA.add(product_sn);
-        product_sn.setColumns(10);
+        product_sn.setPreferredSize(new Dimension(600, 70));
         product_sn.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 scan_type = 1;
                 scanBarcode2();
             }
         });
+        scanRow.add(product_sn);
 
-//        f_scan_data_bt_1 = new JButton("扫码");
         f_scan_data_bt_1 = new JButton("启动");
         f_scan_data_bt_1.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
@@ -983,114 +1005,117 @@ public class MesClient extends JFrame {
                 scanBarcode();
             }
         });
-//        f_scan_data_bt_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/scan_barcode.png")));
         f_scan_data_bt_1.setFont(new Font("微软雅黑", Font.PLAIN, 32));
-        f_scan_data_bt_1.setBounds(693, 70, 198, 70);
-        indexPanelA.add(f_scan_data_bt_1);
-        
-        JLabel lblNewLabel = new JLabel("测试压");
+        f_scan_data_bt_1.setPreferredSize(new Dimension(198, 70));
+        scanRow.add(f_scan_data_bt_1);
+
+        topContainer.add(scanRow);
+
+        // 测试参数显示区域
+        JPanel paramRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 30, 10));
+
+        JLabel lblNewLabel = new JLabel("测试压:");
         lblNewLabel.setFont(new Font("微软雅黑", Font.PLAIN, 20));
-        lblNewLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-        lblNewLabel.setBounds(137, 210, 140, 40);
-        indexPanelA.add(lblNewLabel);
-        
-        param1 = new JTextField();
+        paramRow.add(lblNewLabel);
+
+        param1 = new JTextField(12);
         param1.setEditable(false);
-        param1.setBounds(287, 210, 150, 40);
-        indexPanelA.add(param1);
-        param1.setColumns(10);
-        
-        JLabel lblNewLabel_1 = new JLabel("泄露值");
-        lblNewLabel_1.setHorizontalAlignment(SwingConstants.RIGHT);
+        param1.setFont(new Font("微软雅黑", Font.PLAIN, 18));
+        paramRow.add(param1);
+
+        JLabel lblNewLabel_1 = new JLabel("泄露值:");
         lblNewLabel_1.setFont(new Font("微软雅黑", Font.PLAIN, 20));
-        lblNewLabel_1.setBounds(447, 210, 140, 40);
-        indexPanelA.add(lblNewLabel_1);
-        
-        param2 = new JTextField();
+        paramRow.add(lblNewLabel_1);
+
+        param2 = new JTextField(12);
         param2.setEditable(false);
-        param2.setColumns(10);
-        param2.setBounds(597, 210, 150, 40);
-        indexPanelA.add(param2);
-        
-        JLabel lblNewLabel_2 = new JLabel("测电阻电压");
-        lblNewLabel_2.setHorizontalAlignment(SwingConstants.RIGHT);
-        lblNewLabel_2.setFont(new Font("微软雅黑", Font.PLAIN, 20));
-        lblNewLabel_2.setBounds(137, 288, 140, 40);
-//        indexPanelA.add(lblNewLabel_2);
-        
-        param3 = new JTextField();
-        param3.setEditable(false);
-        param3.setColumns(10);
-        param3.setBounds(287, 288, 150, 40);
-//        indexPanelA.add(param3);
-        
-        JLabel lblNewLabel_1_1 = new JLabel("电阻");
-        lblNewLabel_1_1.setHorizontalAlignment(SwingConstants.RIGHT);
-        lblNewLabel_1_1.setFont(new Font("微软雅黑", Font.PLAIN, 20));
-        lblNewLabel_1_1.setBounds(447, 288, 140, 40);
-//        indexPanelA.add(lblNewLabel_1_1);
-        
-        param4 = new JTextField();
-        param4.setEditable(false);
-        param4.setColumns(10);
-        param4.setBounds(597, 288, 150, 40);
-//        indexPanelA.add(param4);
+        param2.setFont(new Font("微软雅黑", Font.PLAIN, 18));
+        paramRow.add(param2);
 
+        topContainer.add(paramRow);
 
+        // 结果显示区域
+        JPanel resultRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
         result = new JLabel("等待结果") {
             @Override
             protected void paintComponent(Graphics g) {
                 Graphics2D g2 = (Graphics2D) g.create();
                 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
-                // 设置圆角背景和边框颜色
-                g2.setColor(new Color(255, 255, 255)); // 背景颜色
-                g2.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20); // 圆角矩形,圆角半径为20
-
-                g2.setColor(new Color(255, 255, 255)); // 边框颜色
-                g2.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 20, 20); // 绘制边框
-
+                g2.setColor(new Color(255, 255, 255));
+                g2.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20);
+                g2.setColor(new Color(255, 255, 255));
+                g2.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
                 g2.dispose();
                 super.paintComponent(g);
             }
         };
-//        result.setForeground(Color.GREEN);
-//        result.setForeground(Color.RED);
         result.setForeground(Color.GRAY);
         result.setHorizontalAlignment(SwingConstants.CENTER);
         result.setFont(new Font("微软雅黑", Font.BOLD, 50));
-//        result.setBounds(290, 392, 356, 89);
-        result.setBounds(290, 332, 356, 89);
-        indexPanelA.add(result);
+        result.setPreferredSize(new Dimension(356, 89));
+        resultRow.add(result);
+
+        topContainer.add(resultRow);
+
+        // 倒计时标签
+        JPanel countdownRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
+        countdownLabel = new JLabel("");
+        countdownLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
+        countdownLabel.setForeground(new Color(255, 140, 0));
+        countdownLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        countdownLabel.setVisible(false);
+        countdownRow.add(countdownLabel);
+
+        topContainer.add(countdownRow);
+
+        indexPanelA.add(topContainer, BorderLayout.NORTH);
+
+        // 中间面板:漏点按钮
+        JPanel centerPanel = new JPanel();
+        centerPanel.setLayout(new BorderLayout(10, 10));
+        centerPanel.setBorder(new EmptyBorder(10, 20, 10, 20));
+
+        JPanel weldPanel = new JPanel();
+        weldPanel.setLayout(new GridLayout(5, 8, 10, 10));
+        weldPanel.setOpaque(false);
+        addWeldButtonsToPanel(weldPanel, 0, weldButtons.length);
+        centerPanel.add(weldPanel, BorderLayout.CENTER);
+
+        indexPanelA.add(centerPanel, BorderLayout.CENTER);
+
+        // 底部面板:OK/NG按钮
+        JPanel bottomPanel = new JPanel();
+        bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 10));
+        bottomPanel.setBorder(new EmptyBorder(10, 10, 20, 10));
 
         finish_ok_bt = new JButton("OK");
         finish_ok_bt.setEnabled(false);
         finish_ok_bt.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
-
+                handleOkButton();
             }
         });
         finish_ok_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ok_bg.png")));
         finish_ok_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32));
-        finish_ok_bt.setBounds(185, 291, 240, 80);
-        finish_ok_bt.setEnabled(false);
-//        indexPanelA.add(finish_ok_bt);
+        finish_ok_bt.setPreferredSize(new Dimension(240, 80));
+        bottomPanel.add(finish_ok_bt);
 
         finish_ng_bt = new JButton("NG");
         finish_ng_bt.setEnabled(false);
         finish_ng_bt.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
-
+                handleNgButton();
             }
         });
         finish_ng_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ng_bg.png")));
         finish_ng_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32));
-        finish_ng_bt.setBounds(508, 291, 240, 80);
-        finish_ng_bt.setEnabled(false);
-//        indexPanelA.add(finish_ng_bt);
+        finish_ng_bt.setPreferredSize(new Dimension(240, 80));
+        bottomPanel.add(finish_ng_bt);
+
+        indexPanelA.add(bottomPanel, BorderLayout.SOUTH);
 
         centerPanelChildren(indexPanelA, 1024, 550);
-        tabbedPane.addTab("工作面板", new ImageIcon(MesClient.class.getResource("/bg/a_side.png")), indexPanelA, null);
+        tabbedPane.addTab("工作面板", new ImageIcon(MesClient.class.getResource("/bg/a_side.png")), indexScrollPaneA, null);
         tabbedPane.setEnabledAt(0, true);
 
         // 漏点位置图:保持原图尺寸,通过滚动条查看完整工程图。
@@ -1707,4 +1732,257 @@ public class MesClient extends JFrame {
         }
         MesClient.status_menu.setText(msg);
     }
+
+    // ==================== 漏点相关方法 ====================
+
+    /**
+     * 添加漏点按钮到面板
+     */
+    private void addWeldButtonsToPanel(JPanel panel, int start, int end) {
+        for (int i = start; i < end; i++) {
+            if (i >= weldButtons.length) break;
+            int index = i;
+
+            weldButtons[i] = new JButton(getPointLabel(i));
+            weldButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 13));
+            weldButtons[i].setEnabled(false);
+
+            weldButtons[i].addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    JButton btn = (JButton) e.getSource();
+                    if (weldClickStates[index]) {
+                        btn.setBackground(null);
+                        weldClickStates[index] = false;
+                    } else {
+                        btn.setBackground(Color.GREEN);
+                        weldClickStates[index] = true;
+                    }
+                }
+            });
+            panel.add(weldButtons[i]);
+        }
+    }
+
+    /**
+     * 获取漏点标签(A1-A9, B1-B16, C1-C2, D1-D12)
+     */
+    private static String getPointLabel(int index) {
+        if (index < 9) return "A" + (index + 1);
+        if (index < 25) return "B" + (index - 8);
+        if (index < 27) return "C" + (index - 24);
+        return "D" + (index - 26);
+    }
+
+    /**
+     * 关闭漏点按钮
+     */
+    public static void closeWeldButtons() {
+        for (int i = 0; i < weldButtons.length; i++) {
+            if (weldButtons[i] != null) {
+                weldClickStates[i] = false;
+                weldButtons[i].setBackground(null);
+                weldButtons[i].setEnabled(false);
+            }
+        }
+    }
+
+    /**
+     * 启用漏点按钮
+     */
+    public static void enableWeldButtons() {
+        for (int i = 0; i < weldButtons.length; i++) {
+            if (weldButtons[i] != null) {
+                weldButtons[i].setEnabled(true);
+                weldClickStates[i] = false;
+            }
+        }
+    }
+
+    /**
+     * 获取选中的漏点位置
+     */
+    public static String getSelectedLeakPoints() {
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for (int i = 0; i < weldClickStates.length; i++) {
+            if (weldClickStates[i]) {
+                if (!first) {
+                    sb.append(",");
+                }
+                sb.append(getPointLabel(i));
+                first = false;
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 设备判OK后,启动倒计时
+     */
+    public static void startOkCountdown(TestParam testParam) {
+        pendingTestParam = testParam;
+        deviceResult = "OK";
+        countdownSeconds = 5;
+
+        // 显示倒计时标签
+        countdownLabel.setText("5秒后自动提交OK...");
+        countdownLabel.setVisible(true);
+
+        // 启用NG按钮,允许改判
+        finish_ng_bt.setEnabled(true);
+        finish_ok_bt.setEnabled(false);
+
+        // 启动定时器
+        if (countdownTimer != null) {
+            countdownTimer.cancel();
+        }
+        countdownTimer = new Timer();
+        countdownTimer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                SwingUtilities.invokeLater(() -> {
+                    countdownSeconds--;
+                    if (countdownSeconds > 0) {
+                        countdownLabel.setText(countdownSeconds + "秒后自动提交OK...");
+                    } else {
+                        // 倒计时结束,自动提交OK
+                        stopCountdown();
+                        submitOkResult();
+                    }
+                });
+            }
+        }, 1000, 1000);
+    }
+
+    /**
+     * 停止倒计时
+     */
+    public static void stopCountdown() {
+        if (countdownTimer != null) {
+            countdownTimer.cancel();
+            countdownTimer = null;
+        }
+        if (countdownLabel != null) {
+            countdownLabel.setVisible(false);
+        }
+    }
+
+    /**
+     * 自动提交OK结果
+     */
+    private static void submitOkResult() {
+        if (pendingTestParam == null) {
+            return;
+        }
+
+        pendingTestParam.setResult("OK");
+        if (MesClient.mes_enable) {
+            JSONObject retObj = DataUtil.qmResultData(pendingTestParam);
+            if (retObj != null && retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
+                resetScanA();
+                setMenuStatus("测试结果上传成功,请扫下一件", 0);
+            } else {
+                setMenuStatus("测试结果上传失败,请重试", -1);
+            }
+        } else {
+            resetScanA();
+        }
+    }
+
+    /**
+     * 设备判NG后,等待人工选漏点
+     */
+    public static void showNgLeakSelection(TestParam testParam) {
+        pendingTestParam = testParam;
+        deviceResult = "NG";
+
+        // 启用漏点按钮
+        enableWeldButtons();
+
+        // 启用NG按钮
+        finish_ng_bt.setEnabled(true);
+        finish_ok_bt.setEnabled(false);
+
+        setMenuStatus("设备判定NG,请选择漏点位置", 1);
+    }
+
+    /**
+     * OK按钮处理
+     */
+    private static void handleOkButton() {
+        // OK按钮在倒计时时不启用,这里预留逻辑
+    }
+
+    /**
+     * NG按钮处理
+     */
+    private static void handleNgButton() {
+        if (pendingTestParam == null) {
+            return;
+        }
+
+        String leakPoints = getSelectedLeakPoints();
+
+        // 如果是设备判OK,工人改判NG
+        if (deviceResult.equals("OK")) {
+            // 停止倒计时
+            stopCountdown();
+
+            if (leakPoints.isEmpty()) {
+                setMenuStatus("请至少选择1个漏点位置", -1);
+                return;
+            }
+
+            // 提交NG + 漏点
+            submitNgWithLeakPoints(leakPoints, true);
+        }
+        // 如果是设备判NG
+        else if (deviceResult.equals("NG")) {
+            if (leakPoints.isEmpty()) {
+                setMenuStatus("请至少选择1个漏点位置", -1);
+                return;
+            }
+
+            // 提交NG + 漏点
+            submitNgWithLeakPoints(leakPoints, false);
+        }
+    }
+
+    /**
+     * 提交NG结果 + 漏点记录
+     */
+    private static void submitNgWithLeakPoints(String leakPoints, boolean isManualOverride) {
+        if (pendingTestParam == null) {
+            return;
+        }
+
+        // 1. 先提交测试结果
+        pendingTestParam.setResult("NG");
+        JSONObject retObj = DataUtil.qmResultData(pendingTestParam);
+
+        if (retObj != null && retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
+            // 2. 再提交漏点记录
+            String remark = isManualOverride ? "人工发现" : "设备NG";
+            JSONObject leakRet = DataUtil.leakPointRecord(
+                    pendingTestParam.getSn(),
+                    leakPoints,
+                    remark,
+                    pendingTestParam.getOprno(),
+                    pendingTestParam.getLineSn(),
+                    pendingTestParam.getUcode()
+            );
+
+            if (leakRet != null && leakRet.get("result") != null && leakRet.get("result").toString().equalsIgnoreCase("true")) {
+                resetScanA();
+                setMenuStatus("结果上传成功(含漏点记录),请扫下一件", 0);
+            } else {
+                log.warn("漏点记录提交失败,但测试结果已提交");
+                resetScanA();
+                setMenuStatus("测试结果已提交,漏点记录失败", 1);
+            }
+        } else {
+            setMenuStatus("测试结果上传失败,请重试", -1);
+        }
+    }
 }

+ 8 - 11
src/com/mes/util/WorkTimer.java

@@ -113,19 +113,16 @@ public class WorkTimer {
                         testParam.setCreateTime(testDate);
                         JdbcUtils.insertTestRecord(testParam);
 
-                        if(MesClient.mes_enable){ // MES开启
-                            JSONObject retObj = DataUtil.qmResultData(testParam);
-                            if(retObj != null && retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
-                                MesClient.resetScanA();
-                                MesClient.setMenuStatus("测试结果上传成功,请扫下一件",0);
-                            }else{
-                                MesClient.setMenuStatus("测试结果上传失败,请重试",-1);
-                                return;
-                            }
-                        }else{
-                            MesClient.resetScanA();
+                        // 根据设备判定结果分支处理
+                        if (lastRet.equals("OK")) {
+                            // 设备判OK:启动5秒倒计时,允许人工改判
+                            MesClient.startOkCountdown(testParam);
+                        } else {
+                            // 设备判NG:等待人工选漏点
+                            MesClient.showNgLeakSelection(testParam);
                         }
 
+                        // 打印标签(仅设备判OK时)
                         if(MesClient.configParam.getPrintLabel().equals("是") && lastRet.equals("OK")){
                             PrintUtil.printLabel(testParam.getSn(),testParam.getParam1()+testParam.getParam2(),testParam.getParam3()+testParam.getParam4(),testDate);
                         }