|
|
@@ -0,0 +1,403 @@
|
|
|
+package com.mes.ui;
|
|
|
+
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import javax.swing.*;
|
|
|
+import javax.swing.table.DefaultTableCellRenderer;
|
|
|
+import javax.swing.table.DefaultTableModel;
|
|
|
+import javax.swing.table.TableColumn;
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.event.ComponentAdapter;
|
|
|
+import java.awt.event.ComponentEvent;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 工作记录面板组件
|
|
|
+ * 支持分页查询和展示工作记录数据
|
|
|
+ */
|
|
|
+public class WorkRecordPanel extends JPanel {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(WorkRecordPanel.class);
|
|
|
+
|
|
|
+ // 表格列名
|
|
|
+ private static final String[] COLUMN_NAMES = {"工件码", "工位号", "工位结果", "作业人员", "日期"};
|
|
|
+
|
|
|
+ // 分页配置
|
|
|
+ private static final int PAGE_SIZE = 20;
|
|
|
+
|
|
|
+ // 查询条件
|
|
|
+ private String oprno; // 工位号(null或空则查全部)
|
|
|
+ private String lineSn; // 产线编号
|
|
|
+ private boolean isAllStation; // 是否是"所有工位"模式
|
|
|
+
|
|
|
+ // 分页状态
|
|
|
+ private int pageNo = 1;
|
|
|
+ private long totalCount = 0;
|
|
|
+ private int totalPages = 0;
|
|
|
+
|
|
|
+ // UI组件
|
|
|
+ private JTable table;
|
|
|
+ private DefaultTableModel tableModel;
|
|
|
+ private JLabel pageLabel;
|
|
|
+ private JButton btnPrevious;
|
|
|
+ private JButton btnNext;
|
|
|
+ private JButton btnRefresh;
|
|
|
+ private JButton btnSearch;
|
|
|
+ private JLabel statusLabel;
|
|
|
+ private JTextField snSearchField; // 工件码搜索框
|
|
|
+ private JTextField oprnoSearchField; // 工位号搜索框(仅"所有工位"模式)
|
|
|
+ private JLabel snLabel;
|
|
|
+ private JLabel oprnoLabel;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造函数
|
|
|
+ * @param oprno 工位号(如OP150A查询该工位,null或空则查所有工位)
|
|
|
+ * @param lineSn 产线编号
|
|
|
+ */
|
|
|
+ public WorkRecordPanel(String oprno, String lineSn) {
|
|
|
+ this.oprno = oprno;
|
|
|
+ this.lineSn = lineSn;
|
|
|
+ this.isAllStation = (oprno == null || oprno.isEmpty());
|
|
|
+ initUI();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化UI
|
|
|
+ */
|
|
|
+ private void initUI() {
|
|
|
+ setLayout(null);
|
|
|
+ setBackground(Color.WHITE);
|
|
|
+
|
|
|
+ // 顶部控制区
|
|
|
+ JPanel topPanel = new JPanel();
|
|
|
+ topPanel.setLayout(null);
|
|
|
+ topPanel.setBounds(0, 0, 1200, 50);
|
|
|
+ topPanel.setBackground(new Color(248, 248, 248));
|
|
|
+ add(topPanel);
|
|
|
+
|
|
|
+ int xPos = 10;
|
|
|
+
|
|
|
+ // 状态标签
|
|
|
+ String displayOprno = isAllStation ? "所有工位" : oprno;
|
|
|
+ statusLabel = new JLabel("工位:" + displayOprno);
|
|
|
+ statusLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ statusLabel.setBounds(xPos, 10, 160, 30);
|
|
|
+ topPanel.add(statusLabel);
|
|
|
+ xPos += 165;
|
|
|
+
|
|
|
+ // 工件码搜索
|
|
|
+ snLabel = new JLabel("工件码:");
|
|
|
+ snLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ snLabel.setBounds(xPos, 10, 50, 30);
|
|
|
+ topPanel.add(snLabel);
|
|
|
+ xPos += 52;
|
|
|
+
|
|
|
+ snSearchField = new JTextField();
|
|
|
+ snSearchField.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ snSearchField.setBounds(xPos, 10, 200, 30);
|
|
|
+ snSearchField.addActionListener(e -> doSearch()); // 回车搜索
|
|
|
+ topPanel.add(snSearchField);
|
|
|
+ xPos += 210;
|
|
|
+
|
|
|
+ // 工位号搜索(仅"所有工位"模式显示)
|
|
|
+ if (isAllStation) {
|
|
|
+ oprnoLabel = new JLabel("工位:");
|
|
|
+ oprnoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ oprnoLabel.setBounds(xPos, 10, 40, 30);
|
|
|
+ topPanel.add(oprnoLabel);
|
|
|
+ xPos += 42;
|
|
|
+
|
|
|
+ oprnoSearchField = new JTextField();
|
|
|
+ oprnoSearchField.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ oprnoSearchField.setBounds(xPos, 10, 100, 30);
|
|
|
+ oprnoSearchField.addActionListener(e -> doSearch()); // 回车搜索
|
|
|
+ topPanel.add(oprnoSearchField);
|
|
|
+ xPos += 110;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询按钮
|
|
|
+ btnSearch = new JButton("查询");
|
|
|
+ btnSearch.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ btnSearch.setBounds(xPos, 10, 70, 30);
|
|
|
+ btnSearch.addActionListener(e -> doSearch());
|
|
|
+ topPanel.add(btnSearch);
|
|
|
+ xPos += 80;
|
|
|
+
|
|
|
+ // 刷新按钮
|
|
|
+ btnRefresh = new JButton("刷新");
|
|
|
+ btnRefresh.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ btnRefresh.setBounds(xPos, 10, 70, 30);
|
|
|
+ btnRefresh.addActionListener(e -> {
|
|
|
+ clearSearchFields();
|
|
|
+ refreshData();
|
|
|
+ });
|
|
|
+ topPanel.add(btnRefresh);
|
|
|
+ xPos += 80;
|
|
|
+
|
|
|
+ // 上一页按钮
|
|
|
+ btnPrevious = new JButton("上一页");
|
|
|
+ btnPrevious.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ btnPrevious.setBounds(xPos, 10, 80, 30);
|
|
|
+ btnPrevious.addActionListener(e -> {
|
|
|
+ if (pageNo > 1) {
|
|
|
+ pageNo--;
|
|
|
+ loadData();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ topPanel.add(btnPrevious);
|
|
|
+ xPos += 85;
|
|
|
+
|
|
|
+ // 页码显示
|
|
|
+ pageLabel = new JLabel("0/0");
|
|
|
+ pageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ pageLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
|
|
+ pageLabel.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
|
|
|
+ pageLabel.setBounds(xPos, 10, 70, 30);
|
|
|
+ topPanel.add(pageLabel);
|
|
|
+ xPos += 75;
|
|
|
+
|
|
|
+ // 下一页按钮
|
|
|
+ btnNext = new JButton("下一页");
|
|
|
+ btnNext.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ btnNext.setBounds(xPos, 10, 80, 30);
|
|
|
+ btnNext.addActionListener(e -> {
|
|
|
+ if (pageNo < totalPages) {
|
|
|
+ pageNo++;
|
|
|
+ loadData();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ topPanel.add(btnNext);
|
|
|
+
|
|
|
+ // 表格面板
|
|
|
+ JPanel tablePanel = new JPanel();
|
|
|
+ tablePanel.setBounds(0, 50, 1200, 518);
|
|
|
+ tablePanel.setLayout(new GridLayout(1, 1, 0, 0));
|
|
|
+ add(tablePanel);
|
|
|
+
|
|
|
+ // 创建表格模型
|
|
|
+ tableModel = new DefaultTableModel(COLUMN_NAMES, 0) {
|
|
|
+ @Override
|
|
|
+ public boolean isCellEditable(int row, int column) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 创建表格
|
|
|
+ table = new JTable(tableModel);
|
|
|
+ table.setRowHeight(32);
|
|
|
+ table.setFont(new Font("微软雅黑", Font.PLAIN, 13));
|
|
|
+ table.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 14));
|
|
|
+ table.getTableHeader().setReorderingAllowed(false);
|
|
|
+
|
|
|
+ // 设置列宽
|
|
|
+ setColumnWidths();
|
|
|
+
|
|
|
+ // 设置居中渲染器
|
|
|
+ DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
|
|
|
+ centerRenderer.setHorizontalAlignment(JLabel.CENTER);
|
|
|
+ for (int i = 0; i < table.getColumnCount(); i++) {
|
|
|
+ table.getColumnModel().getColumn(i).setCellRenderer(centerRenderer);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加滚动面板
|
|
|
+ JScrollPane scrollPane = new JScrollPane(table);
|
|
|
+ tablePanel.add(scrollPane);
|
|
|
+
|
|
|
+ // 添加组件大小变化监听器
|
|
|
+ addComponentListener(new ComponentAdapter() {
|
|
|
+ @Override
|
|
|
+ public void componentResized(ComponentEvent e) {
|
|
|
+ int w = getWidth();
|
|
|
+ int h = getHeight();
|
|
|
+
|
|
|
+ // 调整顶部面板宽度
|
|
|
+ topPanel.setBounds(0, 0, w, 50);
|
|
|
+
|
|
|
+ // 调整表格面板
|
|
|
+ if (h > 50) {
|
|
|
+ tablePanel.setBounds(0, 50, w, h - 50);
|
|
|
+ }
|
|
|
+
|
|
|
+ topPanel.revalidate();
|
|
|
+ tablePanel.revalidate();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置列宽
|
|
|
+ */
|
|
|
+ private void setColumnWidths() {
|
|
|
+ TableColumn column;
|
|
|
+ // 工件码
|
|
|
+ column = table.getColumnModel().getColumn(0);
|
|
|
+ column.setPreferredWidth(260);
|
|
|
+ // 工位号
|
|
|
+ column = table.getColumnModel().getColumn(1);
|
|
|
+ column.setPreferredWidth(90);
|
|
|
+ // 工位结果
|
|
|
+ column = table.getColumnModel().getColumn(2);
|
|
|
+ column.setPreferredWidth(70);
|
|
|
+ // 作业人员
|
|
|
+ column = table.getColumnModel().getColumn(3);
|
|
|
+ column.setPreferredWidth(100);
|
|
|
+ // 日期
|
|
|
+ column = table.getColumnModel().getColumn(4);
|
|
|
+ column.setPreferredWidth(150);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清空搜索框
|
|
|
+ */
|
|
|
+ private void clearSearchFields() {
|
|
|
+ snSearchField.setText("");
|
|
|
+ if (oprnoSearchField != null) {
|
|
|
+ oprnoSearchField.setText("");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行搜索
|
|
|
+ */
|
|
|
+ private void doSearch() {
|
|
|
+ pageNo = 1;
|
|
|
+ loadData();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 刷新数据(重置到第一页)
|
|
|
+ */
|
|
|
+ public void refreshData() {
|
|
|
+ pageNo = 1;
|
|
|
+ loadData();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加载数据
|
|
|
+ */
|
|
|
+ public void loadData() {
|
|
|
+ // 获取搜索条件
|
|
|
+ String searchSn = snSearchField.getText().trim();
|
|
|
+ String searchOprno = oprno; // 默认使用构造函数传入的工位号
|
|
|
+
|
|
|
+ // 如果是"所有工位"模式,检查是否有工位号搜索条件
|
|
|
+ if (isAllStation && oprnoSearchField != null) {
|
|
|
+ String inputOprno = oprnoSearchField.getText().trim();
|
|
|
+ if (!inputOprno.isEmpty()) {
|
|
|
+ searchOprno = inputOprno;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ final String finalSearchOprno = searchOprno;
|
|
|
+ final String finalSearchSn = searchSn;
|
|
|
+
|
|
|
+ // 在后台线程中执行数据加载
|
|
|
+ SwingWorker<WorkRecordResp, Void> worker = new SwingWorker<WorkRecordResp, Void>() {
|
|
|
+ @Override
|
|
|
+ protected WorkRecordResp doInBackground() throws Exception {
|
|
|
+ // 更新状态
|
|
|
+ SwingUtilities.invokeLater(() -> {
|
|
|
+ statusLabel.setText("正在加载...");
|
|
|
+ setButtonsEnabled(false);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 调用接口查询数据
|
|
|
+ return DataUtil.getWorkRecordList(finalSearchOprno, finalSearchSn, pageNo, PAGE_SIZE);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void done() {
|
|
|
+ try {
|
|
|
+ WorkRecordResp resp = get();
|
|
|
+ updateUI(resp, finalSearchOprno);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("加载工作记录失败: {}", e.getMessage());
|
|
|
+ updateUIError("加载失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ worker.execute();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置按钮启用状态
|
|
|
+ */
|
|
|
+ private void setButtonsEnabled(boolean enabled) {
|
|
|
+ btnSearch.setEnabled(enabled);
|
|
|
+ btnRefresh.setEnabled(enabled);
|
|
|
+ btnPrevious.setEnabled(enabled && pageNo > 1);
|
|
|
+ btnNext.setEnabled(enabled && pageNo < totalPages);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新UI显示数据
|
|
|
+ */
|
|
|
+ private void updateUI(WorkRecordResp resp, String queryOprno) {
|
|
|
+ // 清空表格
|
|
|
+ tableModel.setRowCount(0);
|
|
|
+
|
|
|
+ if (resp == null || !resp.isResult()) {
|
|
|
+ String msg = resp != null ? resp.getMessage() : "请求失败";
|
|
|
+ updateUIError(msg);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新分页信息
|
|
|
+ totalCount = resp.getCount();
|
|
|
+ totalPages = (int) Math.ceil((double) totalCount / PAGE_SIZE);
|
|
|
+ if (totalPages == 0) totalPages = 1;
|
|
|
+
|
|
|
+ // 更新页码显示
|
|
|
+ pageLabel.setText(pageNo + "/" + totalPages);
|
|
|
+
|
|
|
+ // 更新按钮状态
|
|
|
+ setButtonsEnabled(true);
|
|
|
+
|
|
|
+ // 更新状态标签
|
|
|
+ String oprnoDisplay;
|
|
|
+ if (isAllStation) {
|
|
|
+ oprnoDisplay = (queryOprno == null || queryOprno.isEmpty()) ? "所有工位" : queryOprno;
|
|
|
+ } else {
|
|
|
+ oprnoDisplay = oprno;
|
|
|
+ }
|
|
|
+ statusLabel.setText("工位:" + oprnoDisplay + " 共" + totalCount + "条");
|
|
|
+
|
|
|
+ // 填充表格数据
|
|
|
+ List<WorkRecordData> list = resp.getList();
|
|
|
+ if (list != null && !list.isEmpty()) {
|
|
|
+ for (WorkRecordData data : list) {
|
|
|
+ Object[] row = {
|
|
|
+ data.getSn(),
|
|
|
+ data.getOprno(),
|
|
|
+ data.getContent(),
|
|
|
+ data.getUpdateBy(),
|
|
|
+ data.getUpdateDate()
|
|
|
+ };
|
|
|
+ tableModel.addRow(row);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 刷新表格
|
|
|
+ table.repaint();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新UI显示错误信息
|
|
|
+ */
|
|
|
+ private void updateUIError(String message) {
|
|
|
+ statusLabel.setText("错误: " + message);
|
|
|
+ pageLabel.setText("0/0");
|
|
|
+ setButtonsEnabled(true);
|
|
|
+ btnPrevious.setEnabled(false);
|
|
|
+ btnNext.setEnabled(false);
|
|
|
+ tableModel.setRowCount(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前工位号
|
|
|
+ */
|
|
|
+ public String getOprno() {
|
|
|
+ return oprno;
|
|
|
+ }
|
|
|
+}
|