|
|
@@ -0,0 +1,178 @@
|
|
|
+package com.mes.ui;
|
|
|
+
|
|
|
+import com.mes.util.JdbcUtils;
|
|
|
+
|
|
|
+import javax.swing.*;
|
|
|
+import javax.swing.table.DefaultTableModel;
|
|
|
+import java.awt.*;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 本地工作记录(计件)面板
|
|
|
+ * 数据全部来自本地 SQLite 的 work_record 表,不依赖 MES 服务器
|
|
|
+ */
|
|
|
+public class WorkRecordPanel extends JPanel {
|
|
|
+
|
|
|
+ private static final String[] COLUMNS = {"工件码", "结果", "完成时间"};
|
|
|
+ private static final int LIMIT = 2000;
|
|
|
+
|
|
|
+ private static final Font FONT_BAR = new Font("微软雅黑", Font.PLAIN, 18);
|
|
|
+ private static final Font FONT_BTN = new Font("微软雅黑", Font.PLAIN, 16);
|
|
|
+ private static final Font FONT_SUM = new Font("微软雅黑", Font.BOLD, 20);
|
|
|
+ private static final Font FONT_CELL = new Font("微软雅黑", Font.PLAIN, 16);
|
|
|
+
|
|
|
+ private static final SimpleDateFormat FMT_DAY = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ private static final SimpleDateFormat FMT_TIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ private final JTextField fromField = new JTextField(15);
|
|
|
+ private final JTextField toField = new JTextField(15);
|
|
|
+ private final JTextField hoursField = new JTextField("8", 3);
|
|
|
+ private final JLabel sumLabel = new JLabel();
|
|
|
+ private final DefaultTableModel model = new DefaultTableModel(COLUMNS, 0) {
|
|
|
+ @Override
|
|
|
+ public boolean isCellEditable(int row, int column) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ public WorkRecordPanel() {
|
|
|
+ setLayout(new BorderLayout(0, 0));
|
|
|
+ setToday();
|
|
|
+ add(buildToolBar(), BorderLayout.NORTH);
|
|
|
+ add(new JScrollPane(buildTable()), BorderLayout.CENTER);
|
|
|
+ add(buildSumBar(), BorderLayout.SOUTH);
|
|
|
+ reload();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 今日 00:00:00 ~ 23:59:59
|
|
|
+ private void setToday() {
|
|
|
+ String day = FMT_DAY.format(new Date());
|
|
|
+ fromField.setText(day + " 00:00:00");
|
|
|
+ toField.setText(day + " 23:59:59");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 本班:从当前往前推 N 小时,N 取输入框的值,非法则用 8
|
|
|
+ private void setLastHours() {
|
|
|
+ int hours = 8;
|
|
|
+ try {
|
|
|
+ hours = Integer.parseInt(hoursField.getText().trim());
|
|
|
+ } catch (NumberFormatException ignore) {
|
|
|
+ hoursField.setText("8");
|
|
|
+ }
|
|
|
+ if (hours <= 0) {
|
|
|
+ hours = 8;
|
|
|
+ hoursField.setText("8");
|
|
|
+ }
|
|
|
+
|
|
|
+ Calendar c = Calendar.getInstance();
|
|
|
+ toField.setText(FMT_TIME.format(c.getTime()));
|
|
|
+ c.add(Calendar.HOUR_OF_DAY, -hours);
|
|
|
+ fromField.setText(FMT_TIME.format(c.getTime()));
|
|
|
+ }
|
|
|
+
|
|
|
+ private JPanel buildToolBar() {
|
|
|
+ JPanel bar = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 8));
|
|
|
+
|
|
|
+ JLabel fromLabel = new JLabel("开始:");
|
|
|
+ fromLabel.setFont(FONT_BAR);
|
|
|
+ fromField.setFont(FONT_BAR);
|
|
|
+ fromField.setToolTipText("支持 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss,留空为不限");
|
|
|
+ fromField.addActionListener(e -> reload());
|
|
|
+
|
|
|
+ JLabel toLabel = new JLabel("结束:");
|
|
|
+ toLabel.setFont(FONT_BAR);
|
|
|
+ toField.setFont(FONT_BAR);
|
|
|
+ toField.setToolTipText("支持 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss,留空为不限");
|
|
|
+ toField.addActionListener(e -> reload());
|
|
|
+
|
|
|
+ bar.add(fromLabel);
|
|
|
+ bar.add(fromField);
|
|
|
+ bar.add(toLabel);
|
|
|
+ bar.add(toField);
|
|
|
+ bar.add(button("查询", e -> reload()));
|
|
|
+ bar.add(button("今日", e -> {
|
|
|
+ setToday();
|
|
|
+ reload();
|
|
|
+ }));
|
|
|
+ bar.add(button("本班", e -> {
|
|
|
+ setLastHours();
|
|
|
+ reload();
|
|
|
+ }));
|
|
|
+ hoursField.setFont(FONT_BAR);
|
|
|
+ hoursField.setHorizontalAlignment(SwingConstants.CENTER);
|
|
|
+ hoursField.setToolTipText("本班时长(小时),回车即按该时长查询");
|
|
|
+ hoursField.addActionListener(e -> {
|
|
|
+ setLastHours();
|
|
|
+ reload();
|
|
|
+ });
|
|
|
+ bar.add(hoursField);
|
|
|
+ JLabel hoursLabel = new JLabel("小时");
|
|
|
+ hoursLabel.setFont(FONT_BAR);
|
|
|
+ bar.add(hoursLabel);
|
|
|
+
|
|
|
+ bar.add(button("全部", e -> {
|
|
|
+ fromField.setText("");
|
|
|
+ toField.setText("");
|
|
|
+ reload();
|
|
|
+ }));
|
|
|
+ return bar;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计件汇总条放底部,避免顶部工具条被挤换行
|
|
|
+ private JPanel buildSumBar() {
|
|
|
+ JPanel bar = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 6));
|
|
|
+ sumLabel.setFont(FONT_SUM);
|
|
|
+ sumLabel.setForeground(new Color(0, 102, 0));
|
|
|
+ bar.add(sumLabel);
|
|
|
+ return bar;
|
|
|
+ }
|
|
|
+
|
|
|
+ private JButton button(String text, java.awt.event.ActionListener listener) {
|
|
|
+ JButton bt = new JButton(text);
|
|
|
+ bt.setFont(FONT_BTN);
|
|
|
+ bt.setMargin(new Insets(4, 8, 4, 8));
|
|
|
+ bt.addActionListener(listener);
|
|
|
+ return bt;
|
|
|
+ }
|
|
|
+
|
|
|
+ private JTable buildTable() {
|
|
|
+ JTable table = new JTable(model);
|
|
|
+ table.setRowHeight(32);
|
|
|
+ table.setFont(FONT_CELL);
|
|
|
+ table.getTableHeader().setFont(FONT_BAR);
|
|
|
+ table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
|
|
+ int[] widths = {500, 100, 220};
|
|
|
+ for (int i = 0; i < widths.length; i++) {
|
|
|
+ table.getColumnModel().getColumn(i).setPreferredWidth(widths[i]);
|
|
|
+ }
|
|
|
+ return table;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 按当前时间范围重新加载计件汇总和明细 */
|
|
|
+ public void reload() {
|
|
|
+ String from = fromField.getText().trim();
|
|
|
+ String to = toField.getText().trim();
|
|
|
+
|
|
|
+ model.setRowCount(0);
|
|
|
+ for (Object[] row : JdbcUtils.getWorkRecords(from, to, LIMIT)) {
|
|
|
+ model.addRow(row);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 汇总:合计 + 各工位计件数
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ int total = 0;
|
|
|
+ int totalOk = 0;
|
|
|
+ List<Object[]> counts = JdbcUtils.countWorkRecords(from, to);
|
|
|
+ for (Object[] c : counts) {
|
|
|
+ int cnt = (Integer) c[1];
|
|
|
+ int ok = (Integer) c[2];
|
|
|
+ total += cnt;
|
|
|
+ totalOk += ok;
|
|
|
+ sb.append(" ").append(c[0]).append(": ").append(cnt).append("件(OK ").append(ok).append(")");
|
|
|
+ }
|
|
|
+ sumLabel.setText("计件合计: " + total + "件 OK " + totalOk + "件" + sb);
|
|
|
+ }
|
|
|
+}
|