Просмотр исходного кода

- 新增 OP130F(93 DB7004),按正面逻辑处理;OP135 改为 A-D 四个工位
- 工位、PLC、DB 统一放进 MesClient.STATIONS 表,WorkJPanelCnc 改为通过构造参数传入
- 正面扫码码按 PLC 分成 92 和 93 两份:92 的码给 OP130A-E,93 的码给 OP130F
- OP130E 下料后暂时只上传结果、不存码(反面台2 留 TODO)
- 扫码、手动码、反面待上料码去掉 16 位长度校验,只检查非空
- JdbcUtils 复用 SQLite 连接,建表只在首次连接时执行,去掉 System.out 调试输出
- 调整 Tab 布局:「OP130正面:E-F+扫码」「反面待上料码」

wangxichen 17 часов назад
Родитель
Сommit
3df778cbf1

+ 3 - 3
src/com/mes/component/WorkJPanelBackSlot.java

@@ -158,13 +158,13 @@ public class WorkJPanelBackSlot extends JPanel {
     }
 
     private void inputSn() {
-        String input = JOptionPane.showInputDialog(null, "请输入反面待上料码(" + WorkJPanelScan.SN_LENGTH + "位)");
+        String input = JOptionPane.showInputDialog(null, "请输入反面待上料码");
         if (input == null) {
             return;
         }
         String sn = input.trim();
-        if (sn.length() != WorkJPanelScan.SN_LENGTH) {
-            JOptionPane.showMessageDialog(null, "码长度" + sn.length() + "位,应为" + WorkJPanelScan.SN_LENGTH + "位");
+        if (sn.isEmpty()) {
+            JOptionPane.showMessageDialog(null, "码不能为空");
             return;
         }
         String old = slot.getSn();

+ 28 - 16
src/com/mes/component/WorkJPanelCnc.java

@@ -20,34 +20,35 @@ import java.util.Timer;
 import java.util.TimerTask;
 
 /**
- * 总成CNC工位面板:OP130A-E 正面(PLC 92),OP135A-E 反面(PLC 93),A-E 对应 DB7000-DB7004
+ * 总成CNC工位面板(工位、PLC、DB 由 MesClient 工位表传入)
+ * 正面 OP130A-E = 92 DB7000-7004,OP130F = 93 DB7004;反面 OP135A-D = 93 DB7000-7003
  *
  * 点位 DB700X:0.0 请求上料 / 0.1 请求下料 / 0.2 运行中 / 0.3 设备状态 / 0.4 MES允许上料
  *            0.5 MES允许下料 / 0.6 心跳 / 0.7 上料到设备;1.0、1.1、2、4 为预留,不读不写
  *
- * 上料:请求上料时从 sourceSlot 取码(正面=扫码槽,反面=反面待上料码),校验通过写 0.4
+ * 上料:请求上料时从 sourceSlot 取码(正面=本 PLC 扫码码,反面=反面待上料码),校验通过写 0.4
  * 进设备:0.7 上升沿或 0.2 运行中,码从「上料」移到「加工」
- * 下料:请求下料时上传结果;正面要等反面待上料码为空,上传成功后存码给反面,再写 0.5
+ * 下料:请求下料时上传结果;OP130A-D、OP130F 要等反面待上料码为空,上传成功后存码给反面,再写 0.5
+ *      OP130E 下料后应存入反面台2(TODO 待实现),目前只上传结果、不存码
  */
 public class WorkJPanelCnc extends JPanel {
 
     public static final Logger log = LoggerFactory.getLogger(WorkJPanelCnc.class);
 
-    public static final String PLC_FRONT = "192.168.90.92"; // 正面 OP130
-    public static final String PLC_BACK = "192.168.90.93";  // 反面 OP135
+    public static final String PLC_92 = "192.168.90.92";
+    public static final String PLC_93 = "192.168.90.93";
 
-    private static final String[] DBS = {"DB7000", "DB7001", "DB7002", "DB7003", "DB7004"};
     private static final String[] CN_NO = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
 
     public String oprno;      // OP130 / OP135
-    public String pos;        // A-E
+    public String pos;        // 子工位 A-F
     public boolean front;     // true=正面
     public String plcIp;
     public String plcDb;
     public String deviceName;
 
     public SnSlot sourceSlot; // 上料取码来源
-    public SnSlot targetSlot; // 下料存码目标,反面为 null
+    public SnSlot targetSlot; // 下料存码目标:OP130A-D、OP130F=反面待上料码,OP130E 暂为 null(反面台2待实现),反面为 null
 
     public S7PLC s7PLC;
 
@@ -89,19 +90,28 @@ public class WorkJPanelCnc extends JPanel {
     public Timer oprnoTimer;
     public Timer heartTimer;
 
-    public WorkJPanelCnc(String oprno, String pos) {
+    /**
+     * @param oprno      OP130=正面 / OP135=反面
+     * @param pos        子工位
+     * @param plcIp      PLC 地址
+     * @param plcDb      DB7000-DB7004
+     * @param sourceSlot 上料取码来源
+     * @param targetSlot 下料存码目标,null=不存码
+     */
+    public WorkJPanelCnc(String oprno, String pos, String plcIp, String plcDb, SnSlot sourceSlot, SnSlot targetSlot) {
         this.setLayout(null);
         this.setBackground(Color.WHITE);
         this.oprno = oprno;
         this.pos = pos;
         this.front = "OP130".equals(oprno);
+        this.plcIp = plcIp;
+        this.plcDb = plcDb;
+        this.sourceSlot = sourceSlot;
+        this.targetSlot = targetSlot;
 
-        int idx = pos.charAt(0) - 'A';
-        plcDb = DBS[idx];
-        plcIp = front ? PLC_FRONT : PLC_BACK;
-        deviceName = "东侧" + CN_NO[front ? idx : idx + 5] + "号机";
-        sourceSlot = front ? MesClient.frontSlot : MesClient.backSlot;
-        targetSlot = front ? MesClient.backSlot : null;
+        // 设备名沿用原编号:92 DB7000-7004=一~五号机,93 DB7000-7004=六~十号机
+        int dbIdx = plcDb.charAt(plcDb.length() - 1) - '0';
+        deviceName = "东侧" + CN_NO[(PLC_93.equals(plcIp) ? 5 : 0) + dbIdx] + "号机";
 
         s7PLC = new S7PLC(EPlcType.S1500, plcIp);
         s7PLC.setReceiveTimeout(1000);
@@ -431,10 +441,12 @@ public class WorkJPanelCnc extends JPanel {
         }
     }
 
-    // 请求下料:上传结果,正面成功后存码给反面
+    // 请求下料:上传结果,有存码目标时成功后存码
     private void finishWork() {
         String sn = productSn.getText().trim();
         if (targetSlot == null) {
+            // TODO 反面台2:OP130E(front=true 且 targetSlot=null)下料后要把码存入反面台2,后续实现
+            //      目前只上传结果并放行下料,码不会传给反面
             if (upload(sn)) {
                 resetBlanking("工件结果已提交,等待下一件");
                 writeAllowBlanking(true);

+ 13 - 10
src/com/mes/component/WorkJPanelScan.java

@@ -19,13 +19,13 @@ import java.util.TimerTask;
  * 扫码面板(每台 PLC 一个,92 发 1、2 号枪,93 发 3 号枪,由 PLC 决定)
  * DB7010.0.0 请求扫码 / DB7010.0.1 扫码完成反馈 / DB7010.6(INT) 扫码枪号;0.2、2、4 为预留,不读不写
  * 枪号 0=未发;正常同一时间 92、93 只有一个非 0,PLC 收到扫码完成反馈后清零
- * 请求扫码时 PLC 给几号就触发几号枪,读到 16 位码存入正面扫码槽,正面机台请求上料时取用
+ * 请求扫码时 PLC 给几号就触发几号枪,读到码(不校验长度)存入本 PLC 的正面扫码码
+ * 92 扫的码给 OP130A-E 取,93 扫的码给 OP130F(93 DB7004)取
  */
 public class WorkJPanelScan extends JPanel {
 
     public static final Logger log = LoggerFactory.getLogger(WorkJPanelScan.class);
 
-    public static final int SN_LENGTH = 16;
 
     public String oprno = "OP130";
     public String plcIp;
@@ -65,12 +65,16 @@ public class WorkJPanelScan extends JPanel {
 
     public Timer oprnoTimer;
 
-    public WorkJPanelScan(String plcIp) {
+    /**
+     * @param plcIp PLC 地址
+     * @param slot  扫到的码存入的码槽(92 给 92 正面机,93 给 93 DB7004 正面机)
+     */
+    public WorkJPanelScan(String plcIp, SnSlot slot) {
         this.setLayout(null);
         this.setBackground(Color.WHITE);
         this.plcIp = plcIp;
         this.plcName = plcIp.substring(plcIp.lastIndexOf('.') + 1);
-        this.slot = MesClient.frontSlot;
+        this.slot = slot;
 
         s7PLC = new S7PLC(EPlcType.S1500, plcIp);
         s7PLC.setConnectTimeout(1000);
@@ -257,11 +261,11 @@ public class WorkJPanelScan extends JPanel {
         }
     }
 
-    // 提交手动码:校验长度后挂起,等下一次请求扫码时当作扫码结果
+    // 提交手动码:非空即挂起,等下一次请求扫码时当作扫码结果
     public void submitManualSn() {
         String sn = manualSnField.getText().trim();
-        if (sn.length() != SN_LENGTH) {
-            setMenuStatus("手动码需为" + SN_LENGTH + "位,当前" + sn.length() + "位", -1);
+        if (sn.isEmpty()) {
+            setMenuStatus("手动码不能为空", -1);
             return;
         }
         pendingManualSn = sn;
@@ -376,9 +380,8 @@ public class WorkJPanelScan extends JPanel {
         setMenuStatus(gunNo + "号枪扫码中...", 0);
 
         String sn = MesClient.scanQrcode(gunNo);
-        if (sn.length() != SN_LENGTH) {
-            String reason = sn.isEmpty() ? "未读到码" : "码长度" + sn.length() + "位";
-            setMenuStatus(gunNo + "号枪扫码失败(" + reason + "),重试中", -1);
+        if (sn.isEmpty()) {
+            setMenuStatus(gunNo + "号枪扫码失败(未读到码),重试中", -1);
             return;
         }
 

+ 44 - 29
src/com/mes/ui/MesClient.java

@@ -58,14 +58,26 @@ public class MesClient extends JFrame {
     // 正面扫码枪:按 scan.ips 顺序排列,DB7010.6 枪号 1 对应第一个
     public static TCPClient[] scanClients = new TCPClient[0];
 
-    // 码槽:正面扫码槽(扫码存、正面取),反面待上料码(正面下料存、反面取)
-    public static SnSlot frontSlot;
+    // 码槽:正面扫码码按 PLC 分开(本 PLC 扫码存、本 PLC 正面机取),反面待上料码(正面下料存、反面取)
+    public static SnSlot frontSlot92;
+    public static SnSlot frontSlot93;
     public static SnSlot backSlot;
 
-    // OP130A-E 正面 CNC(PLC 92),OP135A-E 反面 CNC(PLC 93)
-    public static final String[] SUB_STATIONS = {"A", "B", "C", "D", "E"};
-    public static WorkJPanelCnc[] op130Panels = new WorkJPanelCnc[SUB_STATIONS.length];
-    public static WorkJPanelCnc[] op135Panels = new WorkJPanelCnc[SUB_STATIONS.length];
+    // 工位表:工位号, 子工位, PLC, DB
+    public static final String[][] STATIONS = {
+            {"OP130", "A", WorkJPanelCnc.PLC_92, "DB7000"},
+            {"OP130", "B", WorkJPanelCnc.PLC_92, "DB7001"},
+            {"OP130", "C", WorkJPanelCnc.PLC_92, "DB7002"},
+            {"OP130", "D", WorkJPanelCnc.PLC_92, "DB7003"},
+            {"OP130", "E", WorkJPanelCnc.PLC_92, "DB7004"},
+            {"OP130", "F", WorkJPanelCnc.PLC_93, "DB7004"}, // 93 DB7004 走正面逻辑
+            {"OP135", "A", WorkJPanelCnc.PLC_93, "DB7000"},
+            {"OP135", "B", WorkJPanelCnc.PLC_93, "DB7001"},
+            {"OP135", "C", WorkJPanelCnc.PLC_93, "DB7002"},
+            {"OP135", "D", WorkJPanelCnc.PLC_93, "DB7003"},
+    };
+    public static java.util.List<WorkJPanelCnc> op130Panels = new java.util.ArrayList<>();
+    public static java.util.List<WorkJPanelCnc> op135Panels = new java.util.ArrayList<>();
     public static WorkJPanelScan workJPanelScan92; // 92 DB7010(PLC 发 1、2 号枪)
     public static WorkJPanelScan workJPanelScan93; // 93 DB7010(PLC 发 3 号枪)
     public static WorkJPanelBackSlot workJPanelBackSlot;
@@ -122,7 +134,6 @@ public class MesClient extends JFrame {
             }
         }
         scanClients = clients.toArray(new TCPClient[0]);
-        log.info("正面扫码枪 {} 把:{},端口 {}", scanClients.length, pro.getProperty("scan.ips"), scanPort);
     }
 
     //启动心跳包程序
@@ -285,43 +296,47 @@ public class MesClient extends JFrame {
         tabbedPane.setFont(new Font("宋体", Font.BOLD, 22));
         contentPane.add(tabbedPane);
 
-        // 码槽要在工位面板之前创建,面板构造时会引用
-        frontSlot = new SnSlot("正面扫码", "slot_front_scan");
+        // 码槽要在工位面板之前创建,面板构造时会引用(92 沿用原缓存 key)
+        frontSlot92 = new SnSlot("正面扫码92", "slot_front_scan");
+        frontSlot93 = new SnSlot("正面扫码93", "slot_front_scan93");
         backSlot = new SnSlot("反面待上料码", "slot_back_feeding");
 
-        for (int i = 0; i < SUB_STATIONS.length; i++) {
-            op130Panels[i] = new WorkJPanelCnc("OP130", SUB_STATIONS[i]);
-            op135Panels[i] = new WorkJPanelCnc("OP135", SUB_STATIONS[i]);
+        for (String[] s : STATIONS) {
+            boolean front = "OP130".equals(s[0]);
+            boolean on93 = WorkJPanelCnc.PLC_93.equals(s[2]);
+            boolean op130E = front && "E".equals(s[1]);
+            // 正面取本 PLC 扫码码,反面取反面待上料码
+            SnSlot source = !front ? backSlot : (on93 ? frontSlot93 : frontSlot92);
+            // 下料存码:OP130A-D、OP130F 存反面待上料码;反面不存
+            // TODO 反面台2:OP130E(92 DB7004)下料后要存入反面台2,后续实现,暂不存码
+            SnSlot target = front && !op130E ? backSlot : null;
+            WorkJPanelCnc panel = new WorkJPanelCnc(s[0], s[1], s[2], s[3], source, target);
+            (front ? op130Panels : op135Panels).add(panel);
         }
-        // 两台 PLC 的扫码都存入同一个正面扫码码
-        workJPanelScan92 = new WorkJPanelScan(WorkJPanelCnc.PLC_FRONT);
-        workJPanelScan93 = new WorkJPanelScan(WorkJPanelCnc.PLC_BACK);
+        workJPanelScan92 = new WorkJPanelScan(WorkJPanelCnc.PLC_92, frontSlot92);
+        workJPanelScan93 = new WorkJPanelScan(WorkJPanelCnc.PLC_93, frontSlot93);
         workJPanelBackSlot = new WorkJPanelBackSlot();
 
         // 每页 4 格,布局与原来一致
         tabbedPane.addTab("OP130正面:A-D", null,
-                gridTab(op130Panels[0], op130Panels[1], op130Panels[2], op130Panels[3]), null);
-        tabbedPane.addTab("OP130正面:E+扫码", null, gridTab(op130Panels[4], workJPanelScan92, workJPanelScan93), null);
+                gridTab(op130Panels.get(0), op130Panels.get(1), op130Panels.get(2), op130Panels.get(3)), null);
+        tabbedPane.addTab("OP130正面:E-F+扫码", null,
+                gridTab(op130Panels.get(4), op130Panels.get(5), workJPanelScan92, workJPanelScan93), null);
         tabbedPane.addTab("OP135反面:A-D", null,
-                gridTab(op135Panels[0], op135Panels[1], op135Panels[2], op135Panels[3]), null);
-        tabbedPane.addTab("OP135反面:E+待上料码", null, gridTab(op135Panels[4], workJPanelBackSlot), null);
+                gridTab(op135Panels.get(0), op135Panels.get(1), op135Panels.get(2), op135Panels.get(3)), null);
+        tabbedPane.addTab("反面待上料码", null, gridTab(workJPanelBackSlot), null);
         tabbedPane.setEnabledAt(0, true);
 
         // ========== 工作记录 Tab:每个子工位一个Tab + 所有工位 ==========
         JTabbedPane workRecordTabbedPane = new JTabbedPane(JTabbedPane.TOP);
         workRecordTabbedPane.setFont(new Font("微软雅黑", Font.PLAIN, 14));
 
-        String[] baseOprnos = {"OP130", "OP135"};
-        int stationCount = baseOprnos.length * SUB_STATIONS.length;
+        int stationCount = STATIONS.length;
         WorkRecordPanel[] workRecordPanels = new WorkRecordPanel[stationCount + 1]; // +1 for "所有工位"
-        int panelIndex = 0;
-        for (String base : baseOprnos) {
-            for (String sub : SUB_STATIONS) {
-                String oprno = base + sub;
-                workRecordPanels[panelIndex] = new WorkRecordPanel(oprno, mes_line_sn);
-                workRecordTabbedPane.addTab(oprno, null, workRecordPanels[panelIndex], "查询" + oprno + "的工作记录");
-                panelIndex++;
-            }
+        for (int i = 0; i < stationCount; i++) {
+            String oprno = STATIONS[i][0] + STATIONS[i][1];
+            workRecordPanels[i] = new WorkRecordPanel(oprno, mes_line_sn);
+            workRecordTabbedPane.addTab(oprno, null, workRecordPanels[i], "查询" + oprno + "的工作记录");
         }
 
         // 最后添加"所有工位"Tab

+ 17 - 27
src/com/mes/util/JdbcUtils.java

@@ -2,13 +2,10 @@ package com.mes.util;
 
 import com.alibaba.fastjson2.JSON;
 import com.mes.ui.CacheData;
-import com.mes.ui.ParamReq;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.sql.*;
-import java.util.ArrayList;
-import java.util.List;
 
 public class JdbcUtils {
 
@@ -17,13 +14,21 @@ public class JdbcUtils {
 	public static Connection conn = null;
     public static String Drivde="org.sqlite.JDBC";
     
-    public static Connection getConn(){
+    private static boolean tableInited = false;
+
+    // 复用已打开的连接,只在首次连接时建表、打日志
+    public static synchronized Connection getConn(){
         try {
+            if (conn != null && !conn.isClosed()) {
+                return conn;
+            }
             Class.forName(Drivde);// 加载驱动,连接sqlite的jdbc
             conn = DriverManager.getConnection("jdbc:sqlite:mes_db.db");//连接数据库zhou.db,不存在则创建
-            log.info("连接到SQLite数据库成功!");
-            create_bw_record();//初始化结构表
-            //create_measure_data();//初始化测试数据表
+            if (!tableInited) {
+                create_bw_record();//初始化结构表
+                tableInited = true;
+                log.info("连接到SQLite数据库成功!");
+            }
         } catch (Exception e) {
             // TODO Auto-generated catch block
         	close();//关闭数据库连接
@@ -60,10 +65,7 @@ public class JdbcUtils {
 				"   record_time DATETIME,                 -- 记录时间\n" +
 				"   UNIQUE (sn)                 -- 唯一索引\n" +
 				")";
-		System.err.println(cache);
 		statement.executeUpdate(cache);
-
-        log.info("表创建成功!");
         
 //        statement.executeUpdate("INSERT INTO tree_structure VALUES (1, '第一电厂', '第一电厂', '', 1, 0,'','','','','','')");//向数据库中插入数据
 //        statement.executeUpdate("INSERT INTO tree_structure VALUES (2, '第一电厂-设备管理部', '第一电厂-设备管理部', '第一电厂', 2, 0,'','','','','','')");//向数据库中插入数据
@@ -87,39 +89,27 @@ public class JdbcUtils {
         statement.close();
     }
 
-	public static CacheData getCache(String key) {
+	// 共用一个连接,读完不再关闭连接(原来每次 close 后又重连,日志刷屏)
+	public static synchronized CacheData getCache(String key) {
 		//SQL语句
 		String sql = "select id,sn,content from cache where sn = '"+key+"' order by id asc limit 1";
 		Connection conn = JdbcUtils.getConn();
-		Statement stmt=null;
-		ResultSet ret = null;
-		String password=null;
-		List<ParamReq> prods = new ArrayList<>();
 		String content = "";
-		try {
-			stmt = conn.createStatement();
-			//执行语句,得到结果集
-			ret = stmt.executeQuery(sql);
-			System.out.println(sql);
+		try (Statement stmt = conn.createStatement(); ResultSet ret = stmt.executeQuery(sql)) {
 			while (ret.next()) {
 				content = ret.getString(3);
 			}
-			System.out.println("content:"+content);
-			ret.close();
-			conn.close();//关闭连接
 		} catch (SQLException e1) {
-			e1.printStackTrace();
+			log.error("读取缓存{}失败:{}", key, e1.getMessage());
 		}
-		System.out.println("content2:"+content);
 		if(content == null || content.trim().isEmpty()){
 			return null;
 		}
 		content = CommonUtils.base64Decode(content);
-		System.out.println("content3:"+content);
 		return JSON.parseObject(content,CacheData.class);
 	}
 
-	public static Boolean setCache(String key,String value) {
+	public static synchronized Boolean setCache(String key,String value) {
 		String record_time = DateLocalUtils.getCurrentTime();
 		Connection conn = JdbcUtils.getConn();
 		if(value == null || value.trim().isEmpty()) {