WorkRecordPanel.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. package com.mes.ui;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import javax.swing.*;
  5. import javax.swing.table.DefaultTableCellRenderer;
  6. import javax.swing.table.DefaultTableModel;
  7. import javax.swing.table.TableColumn;
  8. import java.awt.*;
  9. import java.awt.event.ComponentAdapter;
  10. import java.awt.event.ComponentEvent;
  11. import java.util.List;
  12. /**
  13. * 工作记录面板组件
  14. * 支持分页查询和展示工作记录数据
  15. * 适配 auto2 (OP040) 工位
  16. */
  17. public class WorkRecordPanel extends JPanel {
  18. private static final Logger log = LoggerFactory.getLogger(WorkRecordPanel.class);
  19. // 表格列名
  20. private static final String[] COLUMN_NAMES = {"工件码", "工位号", "工位结果", "作业人员", "日期"};
  21. // 分页配置
  22. private static final int PAGE_SIZE = 20;
  23. // 查询条件
  24. private String oprno; // 工位号(null或空则查全部)
  25. private String lineSn; // 产线编号
  26. private boolean isAllStation; // 是否是"所有工位"模式
  27. // 分页状态
  28. private int pageNo = 1;
  29. private long totalCount = 0;
  30. private int totalPages = 0;
  31. // UI组件
  32. private JTable table;
  33. private DefaultTableModel tableModel;
  34. private JLabel pageLabel;
  35. private JButton btnPrevious;
  36. private JButton btnNext;
  37. private JButton btnRefresh;
  38. private JButton btnSearch;
  39. private JLabel statusLabel;
  40. private JTextField snSearchField; // 工件码搜索框
  41. private JTextField oprnoSearchField; // 工位号搜索框(仅"所有工位"模式)
  42. private JLabel snLabel;
  43. private JLabel oprnoLabel;
  44. /**
  45. * 构造函数
  46. * @param oprno 工位号(如OP040A查询该工位,null或空则查所有工位)
  47. * @param lineSn 产线编号
  48. */
  49. public WorkRecordPanel(String oprno, String lineSn) {
  50. this.oprno = oprno;
  51. this.lineSn = lineSn;
  52. this.isAllStation = (oprno == null || oprno.isEmpty());
  53. initUI();
  54. }
  55. /**
  56. * 初始化UI
  57. */
  58. private void initUI() {
  59. setLayout(null);
  60. setBackground(Color.WHITE);
  61. // 顶部控制区
  62. JPanel topPanel = new JPanel();
  63. topPanel.setLayout(null);
  64. topPanel.setBounds(0, 0, 1200, 50);
  65. topPanel.setBackground(new Color(248, 248, 248));
  66. add(topPanel);
  67. int xPos = 10;
  68. // 状态标签
  69. String displayOprno = isAllStation ? "所有工位" : oprno;
  70. statusLabel = new JLabel("工位:" + displayOprno);
  71. statusLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  72. statusLabel.setBounds(xPos, 10, 160, 30);
  73. topPanel.add(statusLabel);
  74. xPos += 165;
  75. // 工件码搜索
  76. snLabel = new JLabel("工件码:");
  77. snLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  78. snLabel.setBounds(xPos, 10, 50, 30);
  79. topPanel.add(snLabel);
  80. xPos += 52;
  81. snSearchField = new JTextField();
  82. snSearchField.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  83. snSearchField.setBounds(xPos, 10, 200, 30);
  84. snSearchField.addActionListener(e -> doSearch()); // 回车搜索
  85. topPanel.add(snSearchField);
  86. xPos += 210;
  87. // 工位号搜索(仅"所有工位"模式显示)
  88. if (isAllStation) {
  89. oprnoLabel = new JLabel("工位:");
  90. oprnoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  91. oprnoLabel.setBounds(xPos, 10, 40, 30);
  92. topPanel.add(oprnoLabel);
  93. xPos += 42;
  94. oprnoSearchField = new JTextField();
  95. oprnoSearchField.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  96. oprnoSearchField.setBounds(xPos, 10, 100, 30);
  97. oprnoSearchField.addActionListener(e -> doSearch()); // 回车搜索
  98. topPanel.add(oprnoSearchField);
  99. xPos += 110;
  100. }
  101. // 查询按钮
  102. btnSearch = new JButton("查询");
  103. btnSearch.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  104. btnSearch.setBounds(xPos, 10, 70, 30);
  105. btnSearch.addActionListener(e -> doSearch());
  106. topPanel.add(btnSearch);
  107. xPos += 80;
  108. // 刷新按钮
  109. btnRefresh = new JButton("刷新");
  110. btnRefresh.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  111. btnRefresh.setBounds(xPos, 10, 70, 30);
  112. btnRefresh.addActionListener(e -> {
  113. clearSearchFields();
  114. refreshData();
  115. });
  116. topPanel.add(btnRefresh);
  117. xPos += 80;
  118. // 上一页按钮
  119. btnPrevious = new JButton("上一页");
  120. btnPrevious.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  121. btnPrevious.setBounds(xPos, 10, 80, 30);
  122. btnPrevious.addActionListener(e -> {
  123. if (pageNo > 1) {
  124. pageNo--;
  125. loadData();
  126. }
  127. });
  128. topPanel.add(btnPrevious);
  129. xPos += 85;
  130. // 页码显示
  131. pageLabel = new JLabel("0/0");
  132. pageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  133. pageLabel.setHorizontalAlignment(SwingConstants.CENTER);
  134. pageLabel.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
  135. pageLabel.setBounds(xPos, 10, 70, 30);
  136. topPanel.add(pageLabel);
  137. xPos += 75;
  138. // 下一页按钮
  139. btnNext = new JButton("下一页");
  140. btnNext.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  141. btnNext.setBounds(xPos, 10, 80, 30);
  142. btnNext.addActionListener(e -> {
  143. if (pageNo < totalPages) {
  144. pageNo++;
  145. loadData();
  146. }
  147. });
  148. topPanel.add(btnNext);
  149. // 表格面板
  150. JPanel tablePanel = new JPanel();
  151. tablePanel.setBounds(0, 50, 1200, 518);
  152. tablePanel.setLayout(new GridLayout(1, 1, 0, 0));
  153. add(tablePanel);
  154. // 创建表格模型
  155. tableModel = new DefaultTableModel(COLUMN_NAMES, 0) {
  156. @Override
  157. public boolean isCellEditable(int row, int column) {
  158. return false;
  159. }
  160. };
  161. // 创建表格
  162. table = new JTable(tableModel);
  163. table.setRowHeight(32);
  164. table.setFont(new Font("微软雅黑", Font.PLAIN, 13));
  165. table.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 14));
  166. table.getTableHeader().setReorderingAllowed(false);
  167. // 设置列宽
  168. setColumnWidths();
  169. // 设置居中渲染器
  170. DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
  171. centerRenderer.setHorizontalAlignment(JLabel.CENTER);
  172. for (int i = 0; i < table.getColumnCount(); i++) {
  173. table.getColumnModel().getColumn(i).setCellRenderer(centerRenderer);
  174. }
  175. // 添加滚动面板
  176. JScrollPane scrollPane = new JScrollPane(table);
  177. tablePanel.add(scrollPane);
  178. // 添加组件大小变化监听器
  179. addComponentListener(new ComponentAdapter() {
  180. @Override
  181. public void componentResized(ComponentEvent e) {
  182. int w = getWidth();
  183. int h = getHeight();
  184. // 调整顶部面板宽度
  185. topPanel.setBounds(0, 0, w, 50);
  186. // 调整表格面板
  187. if (h > 50) {
  188. tablePanel.setBounds(0, 50, w, h - 50);
  189. }
  190. topPanel.revalidate();
  191. tablePanel.revalidate();
  192. }
  193. });
  194. }
  195. /**
  196. * 设置列宽
  197. */
  198. private void setColumnWidths() {
  199. TableColumn column;
  200. // 工件码
  201. column = table.getColumnModel().getColumn(0);
  202. column.setPreferredWidth(260);
  203. // 工位号
  204. column = table.getColumnModel().getColumn(1);
  205. column.setPreferredWidth(90);
  206. // 工位结果
  207. column = table.getColumnModel().getColumn(2);
  208. column.setPreferredWidth(70);
  209. // 作业人员
  210. column = table.getColumnModel().getColumn(3);
  211. column.setPreferredWidth(100);
  212. // 日期
  213. column = table.getColumnModel().getColumn(4);
  214. column.setPreferredWidth(150);
  215. }
  216. /**
  217. * 清空搜索框
  218. */
  219. private void clearSearchFields() {
  220. snSearchField.setText("");
  221. if (oprnoSearchField != null) {
  222. oprnoSearchField.setText("");
  223. }
  224. }
  225. /**
  226. * 执行搜索
  227. */
  228. private void doSearch() {
  229. pageNo = 1;
  230. loadData();
  231. }
  232. /**
  233. * 刷新数据(重置到第一页)
  234. */
  235. public void refreshData() {
  236. pageNo = 1;
  237. loadData();
  238. }
  239. /**
  240. * 加载数据
  241. */
  242. public void loadData() {
  243. // 获取搜索条件
  244. String searchSn = snSearchField.getText().trim();
  245. String searchOprno = oprno; // 默认使用构造函数传入的工位号
  246. // 如果是"所有工位"模式,检查是否有工位号搜索条件
  247. if (isAllStation && oprnoSearchField != null) {
  248. String inputOprno = oprnoSearchField.getText().trim();
  249. if (!inputOprno.isEmpty()) {
  250. searchOprno = inputOprno;
  251. }
  252. }
  253. final String finalSearchOprno = searchOprno;
  254. final String finalSearchSn = searchSn;
  255. // 在后台线程中执行数据加载
  256. SwingWorker<WorkRecordResp, Void> worker = new SwingWorker<WorkRecordResp, Void>() {
  257. @Override
  258. protected WorkRecordResp doInBackground() throws Exception {
  259. // 更新状态
  260. SwingUtilities.invokeLater(() -> {
  261. statusLabel.setText("正在加载...");
  262. setButtonsEnabled(false);
  263. });
  264. // 调用接口查询数据
  265. return DataUtil.getWorkRecordList(finalSearchOprno, finalSearchSn, pageNo, PAGE_SIZE);
  266. }
  267. @Override
  268. protected void done() {
  269. try {
  270. WorkRecordResp resp = get();
  271. updateUI(resp, finalSearchOprno);
  272. } catch (Exception e) {
  273. log.error("加载工作记录失败: {}", e.getMessage());
  274. updateUIError("加载失败: " + e.getMessage());
  275. }
  276. }
  277. };
  278. worker.execute();
  279. }
  280. /**
  281. * 设置按钮启用状态
  282. */
  283. private void setButtonsEnabled(boolean enabled) {
  284. btnSearch.setEnabled(enabled);
  285. btnRefresh.setEnabled(enabled);
  286. btnPrevious.setEnabled(enabled && pageNo > 1);
  287. btnNext.setEnabled(enabled && pageNo < totalPages);
  288. }
  289. /**
  290. * 更新UI显示数据
  291. */
  292. private void updateUI(WorkRecordResp resp, String queryOprno) {
  293. // 清空表格
  294. tableModel.setRowCount(0);
  295. if (resp == null || !resp.isResult()) {
  296. String msg = resp != null ? resp.getMessage() : "请求失败";
  297. updateUIError(msg);
  298. return;
  299. }
  300. // 更新分页信息
  301. totalCount = resp.getCount();
  302. totalPages = (int) Math.ceil((double) totalCount / PAGE_SIZE);
  303. if (totalPages == 0) totalPages = 1;
  304. // 更新页码显示
  305. pageLabel.setText(pageNo + "/" + totalPages);
  306. // 更新按钮状态
  307. setButtonsEnabled(true);
  308. // 更新状态标签
  309. String oprnoDisplay;
  310. if (isAllStation) {
  311. oprnoDisplay = (queryOprno == null || queryOprno.isEmpty()) ? "所有工位" : queryOprno;
  312. } else {
  313. oprnoDisplay = oprno;
  314. }
  315. statusLabel.setText("工位:" + oprnoDisplay + " 共" + totalCount + "条");
  316. // 填充表格数据
  317. List<WorkRecordData> list = resp.getList();
  318. if (list != null && !list.isEmpty()) {
  319. for (WorkRecordData data : list) {
  320. Object[] row = {
  321. data.getSn(),
  322. data.getOprno(),
  323. data.getContent(),
  324. data.getUpdateBy(),
  325. data.getUpdateDate()
  326. };
  327. tableModel.addRow(row);
  328. }
  329. }
  330. // 刷新表格
  331. table.repaint();
  332. }
  333. /**
  334. * 更新UI显示错误信息
  335. */
  336. private void updateUIError(String message) {
  337. statusLabel.setText("错误: " + message);
  338. pageLabel.setText("0/0");
  339. setButtonsEnabled(true);
  340. btnPrevious.setEnabled(false);
  341. btnNext.setEnabled(false);
  342. tableModel.setRowCount(0);
  343. }
  344. /**
  345. * 获取当前工位号
  346. */
  347. public String getOprno() {
  348. return oprno;
  349. }
  350. }