diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..f585128
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+devicetodb2
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..2c096c3
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e79da7e
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..4b661a5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..2cd32ab
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getSystemLookAndFeel
+ release
+ doInBackground
+ btnPrint
+ 波特率
+ mem
+ serialPort
+ onRecCom
+ chkRead
+ 11
+ resultData
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1759031074613
+
+
+ 1759031074613
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No facets are configured
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+ device-to-db2
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+ Maven: com.fazecast:jSerialComm:2.10.4
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 0000000..e69de29
diff --git a/.mvn/maven.config b/.mvn/maven.config
new file mode 100644
index 0000000..e69de29
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..2503105
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,111 @@
+
+
+ 4.0.0
+
+ unizk
+ device-to-db2
+ 1.0.0
+
+ device-to-db2
+
+ http://www.example.com
+
+
+ UTF-8
+ 8
+ 8
+
+
+
+
+
+
+ com.fazecast
+ jSerialComm
+ 2.10.4
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.9.0
+
+
+
+ com.google.zxing
+ core
+ 3.5.3
+ compile
+
+
+
+ com.google.zxing
+ javase
+ 3.5.3
+ compile
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.14
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.34
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ 8
+ 8
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.6.0
+
+
+
+
+ unizk.Demo1
+
+
+
+ jar-with-dependencies
+
+
+
+ ${project.artifactId}-${project.version}
+ true
+ ${project.basedir}/target
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..13c38bb
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,8 @@
+USB烧录器接线:
+
+烧录器的TXD接主板的RX2,烧录器的RXD接主板的TX2,GND接GND
+
+
+device-to-db2运行:
+
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\Demo1.java
\ No newline at end of file
diff --git a/run.bat b/run.bat
new file mode 100644
index 0000000..130ae57
--- /dev/null
+++ b/run.bat
@@ -0,0 +1,6 @@
+@echo off
+chcp 65001 >nul
+title 云理疗设备入库系统
+echo 正在启动程序...
+start javaw -jar "%~dp0target\device-to-db2-1.0.0-jar-with-dependencies.jar"
+exit
diff --git a/src/main/java/unizk/Demo1.java b/src/main/java/unizk/Demo1.java
new file mode 100644
index 0000000..9776519
--- /dev/null
+++ b/src/main/java/unizk/Demo1.java
@@ -0,0 +1,678 @@
+package unizk;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fazecast.jSerialComm.SerialPort;
+import com.fazecast.jSerialComm.SerialPortDataListener;
+import com.fazecast.jSerialComm.SerialPortEvent;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.WriterException;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+import unizk.utils.AESUtil;
+import unizk.utils.HttpUtil;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import java.awt.image.BufferedImage;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.awt.print.Paper;
+import java.util.concurrent.CompletableFuture;
+
+public class Demo1 extends JFrame {
+ private JComboBox portComboBox;
+ private JTextField baudRateField;
+ private JButton connectButton;
+ private JButton sendCommandButton;
+ private JButton printBtn;
+ private JTextArea logArea;
+ private SerialPort selectedPort;
+ private final Object portLock = new Object();
+ private StringBuilder resultData = new StringBuilder();
+ private String printMsg;
+ private String DEVICE_ID;
+ private String warehousingUrl = "https://369.peaktcm.com/api/equipment/warehousing";
+
+ // 添加打印机选择组件
+ private JComboBox printerComboBox;
+ private JCheckBox showPrintDialogCheckBox;
+
+ public Demo1() {
+ setTitle("云理疗设备入库系统");
+ setSize(800, 500);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ // 顶部面板:串口设置
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+
+ topPanel.add(new JLabel("串口:"));
+ portComboBox = new JComboBox<>();
+ refreshPorts();
+ topPanel.add(portComboBox);
+
+ topPanel.add(new JLabel("波特率:"));
+ baudRateField = new JTextField("115200", 10);
+ topPanel.add(baudRateField);
+
+ connectButton = new JButton("打开串口");
+ connectButton.addActionListener(e -> toggleConnect());
+ topPanel.add(connectButton);
+
+ sendCommandButton = new JButton("设备入库");
+ sendCommandButton.addActionListener(e -> sendCommand());
+ sendCommandButton.setEnabled(false);
+ topPanel.add(sendCommandButton);
+
+ JButton refreshButton = new JButton("刷新串口");
+ refreshButton.addActionListener(e -> refreshPorts());
+ topPanel.add(refreshButton);
+
+ add(topPanel, BorderLayout.NORTH);
+
+ // 中间面板:打印机设置 + 日志
+ JPanel centerPanel = new JPanel(new BorderLayout());
+
+ // 打印机设置面板
+ JPanel printerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ printerPanel.setBorder(BorderFactory.createTitledBorder("打印设置"));
+
+ printerPanel.add(new JLabel("打印机:"));
+ printerComboBox = new JComboBox<>();
+ loadPrinters();
+ printerPanel.add(printerComboBox);
+
+ JButton refreshPrinterBtn = new JButton("刷新打印机");
+ refreshPrinterBtn.addActionListener(e -> loadPrinters());
+ printerPanel.add(refreshPrinterBtn);
+
+ printBtn = new JButton("打印二维码");
+ printBtn.addActionListener(e -> printQRCode(printMsg,DEVICE_ID));
+ printBtn.setEnabled(false);
+ printerPanel.add(printBtn);
+
+ /*showPrintDialogCheckBox = new JCheckBox("显示打印对话框", true);
+ printerPanel.add(showPrintDialogCheckBox);*/
+
+ centerPanel.add(printerPanel, BorderLayout.NORTH);
+
+ // 日志区域
+ logArea = new JTextArea();
+ logArea.setEditable(false);
+ centerPanel.add(new JScrollPane(logArea), BorderLayout.CENTER);
+
+ add(centerPanel, BorderLayout.CENTER);
+
+ // 初始化
+ log("请选择串口并点击【打开串口】");
+ }
+
+ private void refreshPorts() {
+ portComboBox.removeAllItems();
+ SerialPort[] ports = SerialPort.getCommPorts();
+ for (SerialPort port : ports) {
+ portComboBox.addItem(port.getSystemPortName() + " - " + port.getDescriptivePortName());
+ }
+ if (ports.length == 0) {
+ portComboBox.addItem("未找到串口");
+ }
+ }
+
+ /**
+ * 加载系统打印机列表
+ */
+ private void loadPrinters() {
+ printerComboBox.removeAllItems();
+ PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
+ for (PrintService service : printServices) {
+ printerComboBox.addItem(service.getName());
+ }
+ if (printServices.length == 0) {
+ printerComboBox.addItem("未找到打印机");
+ }
+ }
+
+ private void toggleConnect() {
+ if (selectedPort != null && selectedPort.isOpen()) {
+ selectedPort.closePort();
+ selectedPort.removeDataListener();
+ selectedPort = null;
+ connectButton.setText("打开串口");
+ sendCommandButton.setEnabled(false);
+ log("串口已关闭");
+ } else {
+ int selectedIndex = portComboBox.getSelectedIndex();
+ if (selectedIndex < 0) return;
+
+ SerialPort[] ports = SerialPort.getCommPorts();
+ if (selectedIndex >= ports.length) {
+ JOptionPane.showMessageDialog(this, "无效的串口选择");
+ return;
+ }
+
+ selectedPort = ports[selectedIndex];
+ int baudRate;
+ try {
+ baudRate = Integer.parseInt(baudRateField.getText().trim());
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(this, "波特率格式错误");
+ return;
+ }
+
+ if (selectedPort.openPort()) {
+ selectedPort.setBaudRate(baudRate);
+ selectedPort.setNumDataBits(8);
+ selectedPort.setNumStopBits(1);
+ selectedPort.setParity(SerialPort.NO_PARITY);
+ selectedPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
+
+ // 添加监听器
+ selectedPort.addDataListener(new SerialPortDataListener() {
+ @Override
+ public int getListeningEvents() {
+ return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
+ }
+
+ @Override
+ public void serialEvent(SerialPortEvent event) {
+ if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) return;
+
+ synchronized (portLock) {
+ byte[] newData = new byte[selectedPort.bytesAvailable()];
+ int len = selectedPort.readBytes(newData, newData.length);
+ String data = new String(newData, 0, len, StandardCharsets.UTF_8);
+ log("收到: " + data.trim());
+ resultData.append(data.trim());
+ }
+ }
+ });
+
+ connectButton.setText("关闭串口");
+ sendCommandButton.setEnabled(true);
+ log("串口 " + selectedPort.getSystemPortName() + " 打开成功,波特率: " + baudRate);
+ } else {
+ JOptionPane.showMessageDialog(this, "无法打开串口");
+ }
+ }
+ log("-----reslut1==="+resultData.toString());
+ }
+
+ private void sendCommand() {
+ if (selectedPort == null || !selectedPort.isOpen()) {
+ log("串口未打开");
+ return;
+ }
+
+ // 清空之前的数据
+ resultData.setLength(0);
+
+ // 禁用按钮,防止重复点击
+ sendCommandButton.setEnabled(false);
+ log("正在发送命令...");
+
+ // 使用 SwingWorker 在后台线程执行串口操作
+ SwingWorker worker = new SwingWorker() {
+ @Override
+ protected String doInBackground() throws Exception {
+ String command = "$05||*05\r\n";
+ byte[] commandBytes = command.getBytes(StandardCharsets.US_ASCII);
+
+ // 发送命令
+ publish("selectedPort="+selectedPort.getNumDataBits());
+ int bytesWritten = selectedPort.writeBytes(commandBytes, commandBytes.length);
+ publish("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
+
+ // 设置超时时间(毫秒)
+ long timeout = 10000; // 10秒
+ long startTime = System.currentTimeMillis();
+ StringBuilder response = new StringBuilder();
+
+ // 循环读取,直到超时或收到完整响应
+ while (System.currentTimeMillis() - startTime < timeout) {
+ synchronized (portLock) {
+ if (selectedPort.bytesAvailable() > 0) {
+ byte[] buffer = new byte[selectedPort.bytesAvailable()];
+ int len = selectedPort.readBytes(buffer, buffer.length);
+ String data = new String(buffer, 0, len, StandardCharsets.UTF_8);
+ response.append(data);
+
+ // 假设设备以换行符结束响应,可提前退出
+ if (data.contains("\r\n")) {
+ break;
+ }
+ }
+ }
+ // 小延迟避免 CPU 占用过高
+ Thread.sleep(10);
+ }
+
+ if (response.length() == 0) {
+ return "ERROR_TIMEOUT";
+ }
+ return response.toString().trim();
+ }
+
+ @Override
+ protected void process(List chunks) {
+ for (String message : chunks) {
+ log(message);
+ }
+ }
+
+ @Override
+ protected void done() {
+ log("-----reslut2===" + resultData.toString());
+ String qrContent = resultData.toString().trim();
+ if (!qrContent.contains("*")){
+ JOptionPane.showMessageDialog( null,"获取设备信息失败,请重试");
+ sendCommandButton.setEnabled(true);
+ return;
+ }
+ String[] split = qrContent.split("\\|");
+ String un = null,mu = null;
+ for (String s : split) {
+ if (s.startsWith("MU")){
+ mu = s.substring(2);
+ }
+ if (s.startsWith("UN")){
+ un = s;
+ }
+ }
+ if (mu == null || un == null){
+ JOptionPane.showMessageDialog( null,"获取设备信息失败,请重试");
+ sendCommandButton.setEnabled(true);
+ return;
+ }
+ String encrypt;
+ try {
+ encrypt = AESUtil.encrypt(mu);
+ } catch (Exception e) {
+ log("数据加密出错!");
+ return;
+ }
+ Map header = new HashMap<>();
+ header.put("s-key",encrypt);
+ Map param = new HashMap<>();
+ param.put("mu",mu);
+ param.put("un",un);
+ log("准备执行设备入库请求");
+ String s = null;
+ try {
+ s = HttpUtil.doGet(warehousingUrl, header, param);
+ }catch (Exception e){
+ log("http请求超时...");
+ JOptionPane.showMessageDialog( null,"请求超时,请检查网络是否正常!");
+ return;
+ }
+ log("入库返回数据:"+ s);
+ JSONObject jsonObject = JSONObject.parseObject(s);
+ Integer rescode = jsonObject.getInteger("rescode");
+ if (rescode != 200){
+ JOptionPane.showMessageDialog( null,"入库失败,请稍后重试");
+ sendCommandButton.setEnabled(true);
+ return;
+ }
+ JSONObject data = jsonObject.getJSONObject("data");
+ String deviceId = data.getString("deviceId");
+ String muid = data.getString("muid");
+ printMsg = deviceId + "|" + muid + "||1.0";
+ DEVICE_ID = deviceId;
+ JOptionPane.showMessageDialog( null,"入库成功!请打印二维码");
+ printBtn.setEnabled(true);
+ // 重新启用按钮
+ sendCommandButton.setEnabled(true);
+
+/* try {
+ String result = get(); // 获取 doInBackground 的返回值
+ log("result=" + result);
+
+ if ("ERROR_TIMEOUT".equals(result)) {
+ log("设备无响应,通信超时(10秒)");
+ JOptionPane.showMessageDialog(Demo1.this,
+ "设备未响应,请检查连接或设备是否正常运行。",
+ "通信超时", JOptionPane.WARNING_MESSAGE);
+ } else {
+ log("响应: " + result);
+
+ // 如果 resultData 不为空,打印二维码
+ String qrContent = resultData.toString().trim();
+ if (!qrContent.isEmpty()) {
+ log("准备打印二维码,内容: " + qrContent);
+ printQRCode(qrContent);
+ } else {
+ log("没有数据可打印");
+ }
+ }
+ } catch (Exception e) {
+ log("通信异常: " + e.getMessage());
+ e.printStackTrace();
+ }*/
+ }
+ };
+
+ // 启动后台任务
+ worker.execute();
+ }
+
+ /**
+ * 打印二维码
+ * @param content 二维码内容
+ */
+ private void printQRCode(String content,String deviceID) {
+ if (content == null || content.length() == 0){
+ JOptionPane.showMessageDialog( this,"打印内容不能为空!");
+ return;
+ }
+ try {
+ // 1. 生成二维码图片
+ BufferedImage qrImage = generateQRCode(content, 200, 200);
+ log("二维码生成成功,尺寸: 20x20");
+
+ // 2. 获取选中的打印机
+ String printerName = (String) printerComboBox.getSelectedItem();
+ if (printerName == null || printerName.equals("未找到打印机")) {
+ int choice = JOptionPane.showConfirmDialog(this,
+ "未选择有效打印机,是否使用默认打印机继续?",
+ "打印机提示",
+ JOptionPane.YES_NO_OPTION);
+ if (choice != JOptionPane.YES_OPTION) {
+ log("用户取消打印");
+ return;
+ }
+ printerName = null; // 使用默认打印机
+ }
+
+ // 3. 执行打印
+// boolean showDialog = showPrintDialogCheckBox.isSelected();
+ if (false) {
+ printQRCodeWithDialog(qrImage, printerName);
+ } else {
+ printQRCodeDirectly(qrImage, printerName,deviceID);
+ }
+
+ } catch (WriterException e) {
+ log("生成二维码失败: " + e.getMessage());
+ JOptionPane.showMessageDialog(this,
+ "生成二维码失败: " + e.getMessage(),
+ "二维码生成错误",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (PrinterException e) {
+ log("打印失败: " + e.getMessage());
+ JOptionPane.showMessageDialog(this,
+ "打印失败: " + e.getMessage() + "\n请检查打印机是否连接正常。",
+ "打印错误",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (Exception e) {
+ log("打印过程异常: " + e.getMessage());
+ e.printStackTrace();
+ JOptionPane.showMessageDialog(this,
+ "打印过程异常: " + e.getMessage(),
+ "异常",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ /**
+ * 生成二维码图片
+ */
+ private BufferedImage generateQRCode(String content, int width, int height) throws WriterException {
+ QRCodeWriter qrCodeWriter = new QRCodeWriter();
+ BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height);
+ return MatrixToImageWriter.toBufferedImage(bitMatrix);
+ }
+
+
+ /**
+ * 优化后的,解决标签打印机驱动返回可打印区域异常的问题
+ * @param qrImage
+ * @param printerName
+ * @param serialNumber
+ * @throws PrinterException
+ */
+
+ private void printQRCodeDirectly(BufferedImage qrImage, String printerName, String serialNumber) throws PrinterException {
+ PrinterJob job = PrinterJob.getPrinterJob();
+
+ // 1. 选择打印机
+ if (printerName != null && !printerName.isEmpty()) {
+ PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
+ for (PrintService service : printServices) {
+ if (service.getName().equals(printerName)) {
+ job.setPrintService(service);
+ break;
+ }
+ }
+ }
+
+ // 2. 【核心修复】:强制设置纸张属性,绕过标签打印机驱动的异常边距
+ // 假设你的标签纸是 40mm x 30mm,你可以根据实际情况修改这两个数字
+ double labelWidthMM = 50.0;
+ double labelHeightMM = 30.0;
+
+ // 将毫米转换为 Java 打印使用的磅 (1 inch = 25.4 mm = 72 points)
+ double widthInPoints = (labelWidthMM / 25.4) * 72;
+ double heightInPoints = (labelHeightMM / 25.4) * 72;
+
+ // 创建自定义纸张对象
+ Paper paper = new Paper();
+ paper.setSize(widthInPoints, heightInPoints);
+ // 强制将页边距设为0,让可打印区域等于纸张物理大小
+ paper.setImageableArea(0, 0, widthInPoints, heightInPoints);
+
+ // 获取默认页面格式并应用我们自定义的纸张
+ PageFormat pageFormat = job.defaultPage();
+ pageFormat.setPaper(paper);
+ pageFormat.setOrientation(PageFormat.PORTRAIT); // 纵向打印
+
+ // 3. 设置打印内容
+ job.setPrintable(new Printable() {
+ @Override
+ public int print(Graphics graphics, PageFormat pf, int pageIndex) throws PrinterException {
+ if (pageIndex > 0) return NO_SUCH_PAGE;
+
+ Graphics2D g2d = (Graphics2D) graphics;
+ // 使用我们强制设置的无边界坐标
+ g2d.translate(pf.getImageableX(), pf.getImageableY());
+
+ double imgWidth = pf.getImageableWidth();
+ double imgHeight = pf.getImageableHeight();
+
+ // 4. 绘制文字(序列号)
+ String text = "序列号:" + serialNumber;
+ g2d.setColor(Color.BLACK);
+ g2d.setFont(new Font("SansSerif", Font.PLAIN, 8));
+
+ FontMetrics fm = g2d.getFontMetrics();
+ int textWidth = fm.stringWidth(text);
+ int textHeight = fm.getHeight();
+
+ int textX = (int) ((imgWidth - textWidth) / 2);
+// int textY = textHeight + 2;
+ int textY = 7 + fm.getAscent();
+ g2d.drawString(text, textX, textY);
+
+ // 5. 绘制二维码
+ int qrWidth = qrImage.getWidth();
+ int qrHeight = qrImage.getHeight();
+// double availableHeight = imgHeight - textHeight - 5;
+ double availableHeight = imgHeight - (textHeight + 2);
+
+ if (qrWidth > imgWidth || qrHeight > availableHeight) {
+ double scaleX = imgWidth / qrWidth * 0.95;
+ double scaleY = availableHeight / qrHeight * 0.95;
+ double scale = Math.min(scaleX, scaleY);
+ qrWidth = (int) (qrWidth * scale);
+ qrHeight = (int) (qrHeight * scale);
+ }
+
+ int qrX = (int) ((imgWidth - qrWidth) / 2);
+// int qrY = textY + 5;
+ int qrY = textY + fm.getDescent() + 1;
+ g2d.drawImage(qrImage, qrX, qrY, qrWidth, qrHeight, null);
+
+ return PAGE_EXISTS;
+ }
+ }, pageFormat); // 注意:这里把修改后的 pageFormat 传给了 setPrintable
+
+ // 6. 执行打印
+ job.print();
+ log("直接打印任务已提交(无对话框)");
+ }
+
+ /**
+ * 打印二维码(显示打印对话框)
+ */
+ private void printQRCodeWithDialog(BufferedImage qrImage, String printerName) throws PrinterException {
+ PrinterJob job = PrinterJob.getPrinterJob();
+
+ // 选择打印机
+ if (printerName != null && !printerName.isEmpty()) {
+ PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
+ for (PrintService service : printServices) {
+ if (service.getName().equals(printerName)) {
+ job.setPrintService(service);
+ break;
+ }
+ }
+ }
+
+ // 设置打印内容
+ job.setPrintable(new Printable() {
+ @Override
+ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
+ if (pageIndex > 0) {
+ return NO_SUCH_PAGE;
+ }
+
+ Graphics2D g2d = (Graphics2D) graphics;
+ g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
+
+ // 计算二维码在页面中的位置(居中)
+ double pageWidth = pageFormat.getImageableWidth();
+ double pageHeight = pageFormat.getImageableHeight();
+ int qrWidth = qrImage.getWidth();
+ int qrHeight = qrImage.getHeight();
+
+ // 如果二维码太大,按比例缩放
+ if (qrWidth > pageWidth || qrHeight > pageHeight) {
+ double scaleX = pageWidth / qrWidth * 0.9;
+ double scaleY = pageHeight / qrHeight * 0.9;
+ double scale = Math.min(scaleX, scaleY);
+ int newWidth = (int) (qrWidth * scale);
+ int newHeight = (int) (qrHeight * scale);
+ int x = (int) ((pageWidth - newWidth) / 2);
+ int y = (int) ((pageHeight - newHeight) / 2);
+ g2d.drawImage(qrImage, x, y, newWidth, newHeight, null);
+ } else {
+ int x = (int) ((pageWidth - qrWidth) / 2);
+ int y = (int) ((pageHeight - qrHeight) / 2);
+ g2d.drawImage(qrImage, x, y, null);
+ }
+
+ // 添加底部文字说明
+ /* g2d.setFont(new Font("宋体", Font.PLAIN, 12));
+ String content = "设备信息: " + resultData.toString().substring(0, Math.min(20, resultData.length()));
+ g2d.drawString(content, 10, (int) pageHeight - 20);*/
+
+ return PAGE_EXISTS;
+ }
+ });
+
+ // 显示打印对话框
+ if (job.printDialog()) {
+ job.print();
+ log("✅ 打印任务已提交(显示对话框)");
+ } else {
+ log("ℹ️ 用户取消打印");
+ }
+ }
+
+ /**
+ * 直接打印(不显示对话框)
+ */
+ private void printQRCodeDirectly(BufferedImage qrImage, String printerName) throws PrinterException {
+ PrinterJob job = PrinterJob.getPrinterJob();
+
+ // 选择打印机
+ if (printerName != null && !printerName.isEmpty()) {
+ PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
+ for (PrintService service : printServices) {
+ if (service.getName().equals(printerName)) {
+ job.setPrintService(service);
+ break;
+ }
+ }
+ }
+
+ // 设置打印内容
+ job.setPrintable(new Printable() {
+ @Override
+ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
+ if (pageIndex > 0) {
+ return NO_SUCH_PAGE;
+ }
+
+ Graphics2D g2d = (Graphics2D) graphics;
+ g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
+
+ double pageWidth = pageFormat.getImageableWidth();
+ double pageHeight = pageFormat.getImageableHeight();
+ int qrWidth = qrImage.getWidth();
+ int qrHeight = qrImage.getHeight();
+
+ if (qrWidth > pageWidth || qrHeight > pageHeight) {
+ double scaleX = pageWidth / qrWidth * 0.9;
+ double scaleY = pageHeight / qrHeight * 0.9;
+ double scale = Math.min(scaleX, scaleY);
+ int newWidth = (int) (qrWidth * scale);
+ int newHeight = (int) (qrHeight * scale);
+ int x = (int) ((pageWidth - newWidth) / 2);
+ int y = (int) ((pageHeight - newHeight) / 2);
+ g2d.drawImage(qrImage, x, y, newWidth, newHeight, null);
+ } else {
+ int x = (int) ((pageWidth - qrWidth) / 2);
+ int y = (int) ((pageHeight - qrHeight) / 2);
+ g2d.drawImage(qrImage, x, y, null);
+ }
+
+ return PAGE_EXISTS;
+ }
+ });
+
+ // 直接打印
+ job.print();
+ log("直接打印任务已提交(无对话框)");
+ }
+
+ private void log(String message) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ String format = LocalDateTime.now().format(formatter);
+ logArea.append("[" + format + "] " + message + "\n");
+ logArea.setCaretPosition(logArea.getDocument().getLength());
+ }
+
+ public static void main(String[] args) {
+ // 使用 SwingUtilities 确保线程安全
+ SwingUtilities.invokeLater(() -> {
+ try {
+ // 设置系统外观
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ new Demo1().setVisible(true);
+ });
+ }
+}
diff --git a/src/main/java/unizk/HubForm.java b/src/main/java/unizk/HubForm.java
new file mode 100644
index 0000000..06c1956
--- /dev/null
+++ b/src/main/java/unizk/HubForm.java
@@ -0,0 +1,397 @@
+package unizk;
+
+import com.fazecast.jSerialComm.*;
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class HubForm extends JFrame {
+ private JComboBox cmbCom;
+ private JComboBox cmbBaud;
+ private JTextArea memPrinted;
+ private JTextArea memo1;
+ private JButton btnPrint;
+
+ private SerialPort serialPort;
+ private String comResult = "";
+ private boolean chkRead = false;
+ private int hubQty = 0;
+
+ public HubForm() {
+ initComponents();
+ loadSettings();
+ }
+
+ private void initComponents() {
+ setTitle("Hub Form");
+ setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ // Main panel
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ // GroupBox 1 (Serial Settings)
+ JPanel groupBox1 = new JPanel(new GridBagLayout());
+ groupBox1.setBorder(BorderFactory.createTitledBorder("Serial Settings"));
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.insets = new Insets(5, 5, 5, 5);
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+
+ // COM Port selection
+ gbc.gridx = 0; gbc.gridy = 0;
+ groupBox1.add(new JLabel("COM Port:"), gbc);
+
+ gbc.gridx = 1; gbc.gridy = 0;
+ cmbCom = new JComboBox<>();
+ groupBox1.add(cmbCom, gbc);
+
+ // Baud Rate selection
+ gbc.gridx = 0; gbc.gridy = 1;
+ groupBox1.add(new JLabel("Baud Rate:"), gbc);
+
+ gbc.gridx = 1; gbc.gridy = 1;
+ cmbBaud = new JComboBox<>(new String[]{"115200"});
+ cmbBaud.setSelectedItem("115200");
+ groupBox1.add(cmbBaud, gbc);
+
+ // Print button
+ gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 2;
+ btnPrint = new JButton("Print");
+ groupBox1.add(btnPrint, gbc);
+
+ mainPanel.add(groupBox1, BorderLayout.NORTH);
+
+ // Text areas
+ JPanel textPanel = new JPanel(new GridLayout(1, 2, 10, 0));
+
+ memPrinted = new JTextArea(15, 30);
+ memPrinted.setEditable(false);
+ JScrollPane scroll1 = new JScrollPane(memPrinted);
+ scroll1.setBorder(BorderFactory.createTitledBorder("Output"));
+
+ memo1 = new JTextArea(15, 30);
+ memo1.setEditable(false);
+ JScrollPane scroll2 = new JScrollPane(memo1);
+ scroll2.setBorder(BorderFactory.createTitledBorder("Data"));
+
+ textPanel.add(scroll1);
+ textPanel.add(scroll2);
+
+ mainPanel.add(textPanel, BorderLayout.CENTER);
+ add(mainPanel);
+
+ // Event listeners
+ btnPrint.addActionListener(e -> btnPrintClick());
+ addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ closeSerialPort();
+ }
+ });
+
+ pack();
+ setLocationRelativeTo(null);
+ }
+
+ private void loadSettings() {
+ // Load hub quantity from settings (simplified)
+ Properties props = new Properties();
+ try {
+ props.load(new FileInputStream("app.ini"));
+ hubQty = Integer.parseInt(props.getProperty("hubqty", "1")) - 1;
+ } catch (Exception e) {
+ hubQty = 0;
+ }
+
+ // Get available COM ports
+ getComPorts();
+ }
+
+ private void getComPorts() {
+ cmbCom.removeAllItems();
+ SerialPort[] ports = SerialPort.getCommPorts();
+
+ for (SerialPort port : ports) {
+ cmbCom.addItem(port.getSystemPortName());
+ }
+
+ if (cmbCom.getItemCount() == 1) {
+ cmbCom.setSelectedIndex(0);
+ }
+ }
+
+ private void btnPrintClick() {
+ String selectedCom = (String) cmbCom.getSelectedItem();
+ btnPrint.setEnabled(false);
+
+ if (selectedCom == null || selectedCom.isEmpty()) {
+ JOptionPane.showMessageDialog(this, "Please select COM port", "Information",
+ JOptionPane.ERROR_MESSAGE);
+ btnPrint.setEnabled(true);
+ return;
+ }
+
+ try {
+ int baudRate = 115200;
+
+ // Open serial port
+ if (!openSerialPort(selectedCom, baudRate)) {
+ memPrinted.append("Failed to open serial port\n");
+ btnPrint.setEnabled(true);
+ return;
+ }
+
+ // Read MUID
+ String muid = readMUID();
+ if (muid == null || muid.isEmpty()) {
+ memPrinted.append("Failed to read MUID\n");
+ closeSerialPort();
+ btnPrint.setEnabled(true);
+ return;
+ }
+
+ // Parse device information
+ DeviceInfo deviceInfo = parseDeviceInfo(muid);
+ if (deviceInfo == null) {
+ memPrinted.append("Failed to parse device information\n");
+ closeSerialPort();
+ btnPrint.setEnabled(true);
+ return;
+ }
+
+ // Submit to server and print
+ submitToServerAndPrint(deviceInfo);
+
+ } catch (Exception ex) {
+ memPrinted.append("Error: " + ex.getMessage() + "\n");
+ ex.printStackTrace();
+ } finally {
+ closeSerialPort();
+ btnPrint.setEnabled(true);
+ }
+ }
+
+ private boolean openSerialPort(String portName, int baudRate) {
+ try {
+ serialPort = SerialPort.getCommPort(portName);
+ serialPort.setBaudRate(baudRate);
+ serialPort.setNumDataBits(8);
+ serialPort.setNumStopBits(1);
+ serialPort.setParity(SerialPort.NO_PARITY);
+ serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1000, 0);
+
+ if (serialPort.openPort()) {
+ memPrinted.append("Successfully opened port: " + portName + "\n");
+
+ // Set up data listener
+ serialPort.addDataListener(new SerialPortDataListener() {
+ @Override
+ public int getListeningEvents() {
+ return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
+ }
+
+ @Override
+ public void serialEvent(SerialPortEvent event) {
+ if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
+ return;
+ }
+ onRecCom();
+ }
+ });
+
+ return true;
+ } else {
+ memPrinted.append("Failed to open port: " + portName + "\n");
+ return false;
+ }
+
+ } catch (Exception e) {
+ memPrinted.append("Error opening serial port: " + e.getMessage() + "\n");
+ return false;
+ }
+ }
+
+ private void closeSerialPort() {
+ if (serialPort != null && serialPort.isOpen()) {
+ serialPort.removeDataListener();
+ serialPort.closePort();
+ memPrinted.append("Serial port closed\n");
+ }
+ }
+
+ private String readMUID() {
+ int retryCount = 0;
+ final int maxRetries = 3;
+
+ while (retryCount < maxRetries) {
+ retryCount++;
+ chkRead = true;
+ comResult = "";
+
+ try {
+ // Send command
+ String command = "$05||*05\r\n";
+ byte[] commandBytes = command.getBytes();
+ int bytesWritten = serialPort.writeBytes(commandBytes, commandBytes.length);
+
+ if (bytesWritten == -1) {
+ memPrinted.append("Failed to write command\n");
+ continue;
+ }
+
+ memPrinted.append("Command sent: " + command);
+
+ // Wait for response with timeout
+ long startTime = System.currentTimeMillis();
+ while (chkRead && (System.currentTimeMillis() - startTime) < 2000) {
+ Thread.sleep(10);
+ }
+
+ String response = comResult.trim();
+ memPrinted.append("Serial response: " + response + "\n");
+
+ // Validate response
+ if (response.contains("$05|") && response.contains("\r")) {
+ // Extract and validate CRC
+ int pos5 = response.indexOf("$05|");
+ String data = response.substring(pos5);
+ int pos13 = data.indexOf("\r");
+
+ if (pos13 > 0) {
+ data = data.substring(0, pos13);
+ String trimmedData = data.trim();
+
+ int crcPos = trimmedData.indexOf("*");
+ if (crcPos > 0) {
+ String dataPart = trimmedData.substring(2, crcPos - 1);
+ String receivedCrc = trimmedData.substring(crcPos + 1, crcPos + 3);
+
+ // TODO: Implement CRC validation
+ // if (getCRCForNmea(dataPart).equals(receivedCrc)) {
+ return data;
+ // }
+ }
+ }
+ }
+
+ memPrinted.append("Retry " + retryCount + " - Invalid response\n");
+
+ } catch (Exception e) {
+ memPrinted.append("Error reading MUID: " + e.getMessage() + "\n");
+ }
+ }
+
+ memPrinted.append("Failed to read MUID after " + maxRetries + " attempts\n");
+ return null;
+ }
+
+ private void onRecCom() {
+ if (!chkRead) return;
+
+ try {
+ byte[] buffer = new byte[1024];
+ int bytesRead = serialPort.readBytes(buffer, buffer.length);
+
+ if (bytesRead > 0) {
+ String data = new String(buffer, 0, bytesRead);
+ comResult += data.toUpperCase();
+ memPrinted.append("comResult="+comResult);
+
+ if (comResult.endsWith("\r") || comResult.contains("\r\n")) {
+ memPrinted.append("串口连接成功");
+ chkRead = false;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private DeviceInfo parseDeviceInfo(String data) {
+ try {
+ // Example data: "$05|MU00220051045504DC00002942|UN01|HWUN01-B1.0|SWA1.0.12|CF2|*3C"
+ String[] parts = data.split("\\|");
+
+ DeviceInfo info = new DeviceInfo();
+
+ for (String part : parts) {
+ if (part.startsWith("MU")) {
+ info.muId = part;
+ } else if (part.startsWith("UN")) {
+ info.unId = "UN" + part.substring(2);
+ } else if (part.startsWith("HW")) {
+ info.hw = part.substring(2);
+ } else if (part.startsWith("SW")) {
+ info.sw = part.substring(2);
+ } else if (part.startsWith("BT")) {
+ info.bt = part.substring(2);
+ } else if (part.startsWith("CF")) {
+ info.cf = part.substring(2);
+ }
+ }
+
+ return info;
+
+ } catch (Exception e) {
+ memPrinted.append("Error parsing device info: " + e.getMessage() + "\n");
+ return null;
+ }
+ }
+
+ private void submitToServerAndPrint(DeviceInfo deviceInfo) {
+ // TODO: Implement HTTP submission to server
+ // This would involve sending the device info to a web service
+ // and handling the response
+
+ memPrinted.append("Submitting device info to server...\n");
+ memPrinted.append("MU: " + deviceInfo.muId + "\n");
+ memPrinted.append("UN: " + deviceInfo.unId + "\n");
+ memPrinted.append("HW: " + deviceInfo.hw + "\n");
+ memPrinted.append("SW: " + deviceInfo.sw + "\n");
+ memPrinted.append("BT: " + deviceInfo.bt + "\n");
+ memPrinted.append("CF: " + deviceInfo.cf + "\n");
+
+ // Simulate successful response
+ String sbxlh = "SB123456789";
+ String responseMsg = "Device registered successfully";
+
+ memPrinted.append("Device serial: " + sbxlh + " | " + deviceInfo.muId +
+ " | " + deviceInfo.bt + "QRv1.0 (" + responseMsg + ")\n");
+
+ // Print QR codes
+ for (int i = 0; i <= hubQty; i++) {
+ printQRCode(sbxlh, sbxlh + "|" + deviceInfo.muId + "|" + deviceInfo.bt + "QRv1.0");
+ }
+ }
+
+ private void printQRCode(String sbxlh, String qrData) {
+ // TODO: Implement QR code printing
+ memPrinted.append("Printing QR Code: " + qrData + "\n");
+ }
+
+ // Helper class to store device information
+ private static class DeviceInfo {
+ String muId;
+ String unId;
+ String hw;
+ String sw;
+ String bt;
+ String cf;
+ }
+
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(() -> {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ new HubForm().setVisible(true);
+ });
+ }
+}
diff --git a/src/main/java/unizk/HubForm2.java b/src/main/java/unizk/HubForm2.java
new file mode 100644
index 0000000..6c6a512
--- /dev/null
+++ b/src/main/java/unizk/HubForm2.java
@@ -0,0 +1,342 @@
+/*
+package unizk;
+
+
+import com.fazecast.jSerialComm.SerialPort;
+import okhttp3.OkHttpClient;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class HubForm2 extends JFrame {
+ private JComboBox cmbCom;
+ private JComboBox cmbBaud;
+ private JButton btnPrint;
+ private JTextArea memPrinted;
+
+ private SerialPort serialPort;
+ private StringBuilder comResult = new StringBuilder();
+ private volatile boolean chkRead = true;
+ private int hubQty = 1; // 默认1,从配置读取时减1
+
+ // 网络配置(示例)
+ private static final String F_WEB_HOST = "http://yourserver.com";
+ private static final String SUBMIT_PUTSTORE = "/pc/device/submitputstore";
+ private static String F_LOGIN_TOKEN_NAME = "Authorization";
+ private static String F_LOGIN_TOKEN_VALUE = "Bearer your_token_here";
+
+ private final OkHttpClient client = new OkHttpClient();
+
+ public HubForm2() {
+ initializeUI();
+ loadSettings();
+ scanSerialPorts();
+ }
+
+ private void initializeUI() {
+ setTitle("Hub 通信工具");
+ setSize(600, 500);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ JPanel topPanel = new JPanel(new GridLayout(2, 4, 5, 5));
+ topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+
+ topPanel.add(new JLabel("串口:"));
+ cmbCom = new JComboBox<>();
+ topPanel.add(cmbCom);
+
+ topPanel.add(new JLabel("波特率:"));
+ cmbBaud = new JComboBox<>(new String[]{"9600", "115200"});
+ cmbBaud.setSelectedItem("115200");
+ topPanel.add(cmbBaud);
+
+ btnPrint = new JButton("开始打印");
+ btnPrint.addActionListener(e -> btnPrintClick());
+ topPanel.add(btnPrint);
+
+ add(topPanel, BorderLayout.NORTH);
+
+ memPrinted = new JTextArea();
+ memPrinted.setFont(new Font("Monospaced", Font.PLAIN, 12));
+ memPrinted.setEditable(false);
+ add(new JScrollPane(memPrinted), BorderLayout.CENTER);
+ }
+
+ private void loadSettings() {
+ // 模拟从 ini 文件读取 hubqty
+ // 实际可用 Properties 加载 app.ini
+ hubQty = getSettingAsInt("setting", "hubqty", 1) - 1;
+ }
+
+ private int getSettingAsInt(String section, String key, int defaultValue) {
+ // 这里简化处理,实际应读取 app.ini
+ return defaultValue;
+ }
+
+ private void scanSerialPorts() {
+ SerialPort[] ports = SerialPort.getCommPorts();
+ cmbCom.removeAllItems();
+ for (SerialPort port : ports) {
+ cmbCom.addItem(port.getSystemPortName());
+ }
+ if (ports.length == 1) {
+ cmbCom.setSelectedIndex(0);
+ }
+ }
+
+ // === 按钮点击事件 ===
+ private void btnPrintClick() {
+ String selectedPortName = (String) cmbCom.getSelectedItem();
+ if (selectedPortName == null || selectedPortName.isEmpty()) {
+ JOptionPane.showMessageDialog(this, "请选择串口号!", "错误", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ btnPrint.setEnabled(false);
+ memPrinted.append("正在连接串口: " + selectedPortName + "\n");
+
+ // 打开串口
+ if (serialPort == null || !serialPort.isOpen()) {
+ serialPort = SerialPort.getCommPort(selectedPortName);
+ serialPort.setBaudRate(Integer.parseInt((String) cmbBaud.getSelectedItem()));
+ serialPort.setNumDataBits(8);
+ serialPort.setNumStopBits(1);
+ serialPort.setParity(SerialPort.NO_PARITY);
+ serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
+
+ // 设置数据接收监听
+ serialPort.addDataListener((SerialPortEvent event) -> {
+ if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE || !chkRead) return;
+
+ byte[] newData = new byte[serialPort.bytesAvailable()];
+ serialPort.readBytes(newData, newData.length);
+
+ String dataStr = new String(newData, StandardCharsets.UTF_8);
+ comResult.append(dataStr.toUpperCase());
+
+ // 检查是否收到回车符(\r)
+ if (dataStr.contains("\r")) {
+ chkRead = false;
+ }
+ });
+
+ try {
+ if (!serialPort.openPort()) {
+ memPrinted.append("无法打开串口!\n");
+ btnPrint.setEnabled(true);
+ return;
+ }
+ } catch (Exception ex) {
+ memPrinted.append("打开串口异常: " + ex.getMessage() + "\n");
+ btnPrint.setEnabled(true);
+ return;
+ }
+ }
+
+ // 尝试最多3次读取设备信息
+ String comResultStr = null;
+ for (int i = 1; i <= 3; i++) {
+ chkRead = true;
+ comResult.setLength(0); // 清空
+
+ serialPort.flushIOStreams();
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ignored) {}
+
+ // 发送指令
+ String command = "$05||*05\r\n";
+ serialPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
+
+ // 等待最多2秒
+ long startTime = System.currentTimeMillis();
+ while (chkRead && (System.currentTimeMillis() - startTime < 2000)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ignored) {}
+ }
+
+ comResultStr = comResult.toString().trim();
+ memPrinted.append("第 " + i + " 次响应: " + comResultStr + "\n");
+
+ if (comResultStr.contains("$05|") && comResultStr.contains("\r")) {
+
+ break; // 成功收到
+ } else {
+ if (i == 3) {
+ memPrinted.append("三次均未收到有效响应!\n");
+ serialPort.closePort();
+ btnPrint.setEnabled(true);
+ return;
+ }
+ }
+ }
+
+ // === 解析响应并 CRC 校验 ===
+ String raw = extractBetween(comResultStr, "$05|", "\r");
+ if (raw == null) {
+ memPrinted.append("解析失败:未找到有效数据段\n");
+ serialPort.closePort();
+ btnPrint.setEnabled(true);
+ return;
+ }
+
+ String dataPart = extractBetween(raw, "", "*");
+ String crcReceived = raw.substring(raw.lastIndexOf("*") + 1, raw.lastIndexOf("*") + 3);
+
+ String crcCalculated = calculateNmeaCrc(dataPart);
+ if (!crcCalculated.equalsIgnoreCase(crcReceived)) {
+ memPrinted.append("CRC 校验失败!计算值: " + crcCalculated + ", 实际值: " + crcReceived + "\n");
+ serialPort.closePort();
+ btnPrint.setEnabled(true);
+ return;
+ }
+
+ // === 提取字段 ===
+ String muId = getDataDict(raw, "MU");
+ String unId = getDataDict(raw, "UN");
+ String hw = getDataDict(raw, "HW");
+ String sw = getDataDict(raw, "SW");
+ String bt = getDataDict(raw, "BT");
+ String cf = getDataDict(raw, "CF");
+
+ if (muId.isEmpty()) {
+ memPrinted.append("未获取到 MU ID!\n");
+ btnPrint.setEnabled(true);
+ return;
+ }
+ if (unId.isEmpty()) {
+ memPrinted.append("未获取到 UN ID!\n");
+ btnPrint.setEnabled(true);
+ return;
+ }
+
+ unId = "UN" + unId;
+
+ // === 提交到服务器(最多重试3次)===
+ boolean success = false;
+ for (int i = 1; i <= 3; i++) {
+ try {
+ RequestBody formBody = new MultipartBody.Builder()
+ .setType(MultipartBody.FORM)
+ .addFormDataPart("un", unId)
+ .addFormDataPart("mu", "MU" + muId)
+ .addFormDataPart("hw", hw)
+ .addFormDataPart("sw", sw)
+ .addFormDataPart("bt", bt)
+ .addFormDataPart("cf", cf)
+ .build();
+
+ Request request = new Request.Builder()
+ .url(F_WEB_HOST + SUBMIT_PUTSTORE)
+ .header("JSON", "true")
+ .header(F_LOGIN_TOKEN_NAME, F_LOGIN_TOKEN_VALUE)
+ .post(formBody)
+ .build();
+
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) {
+ memPrinted.append("HTTP 请求失败: " + response.code() + "\n");
+ continue;
+ }
+
+ String responseBody = response.body().string();
+ JSONObject json = new JSONObject(responseBody);
+
+ if (json.optBoolean("success", false)) {
+ JSONObject data = json.optJSONObject("data");
+ if (data != null) {
+ String sbxlh = data.optString("sbxlh");
+ String muid = data.optString("muid");
+ String msg = json.optString("resmsg", "");
+ String qrText = sbxlh + "|" + muid + "|" + bt + "V1.0(" + msg + ")";
+
+ memPrinted.append("设备编码: " + sbxlh + " | " + muid + " | " + bt + "\n");
+ // 模拟打印二维码
+ for (int j = 0; j <= hubQty; j++) {
+ printQRCode(sbxlh, qrText);
+ }
+ }
+ success = true;
+ break;
+ } else {
+ int rescode = json.optInt("rescode", 0);
+ if (rescode == 403) {
+ refreshToken();
+ memPrinted.append("Token 过期,已刷新,第 " + i + " 次重试...\n");
+ continue;
+ } else {
+ memPrinted.append("提交失败: " + responseBody + "\n");
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ memPrinted.append("网络请求异常: " + e.getMessage() + "\n");
+ }
+ }
+
+ if (!success) {
+ memPrinted.append("提交失败,已达最大重试次数。\n");
+ }
+
+ serialPort.closePort();
+ btnPrint.setEnabled(true);
+ }
+
+ // === 工具方法 ===
+
+ private String extractBetween(String src, String start, String end) {
+ int s = src.indexOf(start);
+ if (s == -1) return null;
+ s += start.length();
+ int e = src.indexOf(end, s);
+ if (e == -1) return null;
+ return src.substring(s, e);
+ }
+
+ private String getDataDict(String data, String prefix) {
+ Pattern pattern = Pattern.compile("\\|" + prefix + "([^|]+)");
+ Matcher matcher = pattern.matcher(data);
+ return matcher.find() ? matcher.group(1).trim() : "";
+ }
+
+ private String calculateNmeaCrc(String sentence) {
+ int crc = 0;
+ for (char c : sentence.toCharArray()) {
+ crc ^= (int) c;
+ }
+ return String.format("%02X", crc);
+ }
+
+ private void printQRCode(String sbxlh, String qrText) {
+ memPrinted.append("打印二维码: " + qrText + "\n");
+ // 实际调用打印机 SDK
+ }
+
+ private void refreshToken() {
+ // 模拟刷新 Token
+ F_LOGIN_TOKEN_VALUE = "Bearer new_token_123";
+ memPrinted.append("Token 已刷新\n");
+ }
+
+ // === 主函数 ===
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(() -> {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel());
+ } catch (Exception ignored) {}
+ new HubForm().setVisible(true);
+ });
+ }
+}
+*/
diff --git a/src/main/java/unizk/HubForm3.java b/src/main/java/unizk/HubForm3.java
new file mode 100644
index 0000000..ae5534d
--- /dev/null
+++ b/src/main/java/unizk/HubForm3.java
@@ -0,0 +1,311 @@
+package unizk;
+
+import com.fazecast.jSerialComm.SerialPort;
+import com.fazecast.jSerialComm.SerialPortDataListener;
+import com.fazecast.jSerialComm.SerialPortEvent;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+public class HubForm3 extends JFrame {
+ private JComboBox portComboBox;
+ private JTextField baudRateField;
+ private JButton connectButton;
+ private JButton sendCommandButton;
+ private JTextArea logArea;
+ private SerialPort selectedPort;
+ private final Object portLock = new Object();
+ private StringBuilder comResult = new StringBuilder();
+ private volatile boolean chkRead = true;
+
+ public HubForm3() {
+// setTitle("云理疗设备入库系统");
+ setSize(800, 400);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ // 顶部面板:串口设置
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout(new FlowLayout());
+
+ topPanel.add(new JLabel("串口:"));
+ portComboBox = new JComboBox<>();
+ refreshPorts();
+ topPanel.add(portComboBox);
+
+ topPanel.add(new JLabel("波特率:"));
+ baudRateField = new JTextField("115200", 10);
+ topPanel.add(baudRateField);
+
+ connectButton = new JButton("打开串口");
+ connectButton.addActionListener(e -> toggleConnect());
+ topPanel.add(connectButton);
+
+ sendCommandButton = new JButton("获取设备信息");
+ sendCommandButton.addActionListener(e -> sendCommand());
+ sendCommandButton.setEnabled(false);
+ topPanel.add(sendCommandButton);
+
+ JButton refreshButton = new JButton("刷新串口");
+ refreshButton.addActionListener(e -> refreshPorts());
+ topPanel.add(refreshButton);
+
+ add(topPanel, BorderLayout.NORTH);
+
+ // 中间:日志显示
+ logArea = new JTextArea();
+ logArea.setEditable(false);
+ add(new JScrollPane(logArea), BorderLayout.CENTER);
+
+ // 初始化
+ log("请选择串口并点击【打开串口】");
+ }
+
+ private void refreshPorts() {
+ portComboBox.removeAllItems();
+ SerialPort[] ports = SerialPort.getCommPorts();
+ for (SerialPort port : ports) {
+ portComboBox.addItem(port.getSystemPortName() + " - " + port.getDescriptivePortName());
+ }
+ if (ports.length == 0) {
+ portComboBox.addItem("未找到串口");
+ }
+ }
+
+ private void toggleConnect() {
+ log("进入toggleConnect");
+ if (selectedPort != null && selectedPort.isOpen()) {
+ selectedPort.closePort();
+ selectedPort.removeDataListener();
+ selectedPort = null;
+ connectButton.setText("打开串口");
+ sendCommandButton.setEnabled(false);
+ log("串口已关闭");
+ } else {
+ int selectedIndex = portComboBox.getSelectedIndex();
+ if (selectedIndex < 0) return;
+
+ SerialPort[] ports = SerialPort.getCommPorts();
+ if (selectedIndex >= ports.length) {
+ JOptionPane.showMessageDialog(this, "无效的串口选择");
+ return;
+ }
+
+ selectedPort = ports[selectedIndex];
+ int baudRate;
+ try {
+ baudRate = Integer.parseInt(baudRateField.getText().trim());
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(this, "波特率格式错误");
+ return;
+ }
+
+ if (selectedPort.openPort()) {
+ selectedPort.setBaudRate(baudRate);
+ selectedPort.setNumDataBits(8);
+ selectedPort.setNumStopBits(1);
+ selectedPort.setParity(SerialPort.NO_PARITY);
+ selectedPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
+
+ // 添加监听器
+ selectedPort.addDataListener(new SerialPortDataListener() {
+ @Override
+ public int getListeningEvents() {
+ return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
+ }
+
+ @Override
+ public void serialEvent(SerialPortEvent event) {
+ if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE || !chkRead) return;
+
+ log("99999999");
+
+ byte[] newData = new byte[selectedPort.bytesAvailable()];
+ selectedPort.readBytes(newData, newData.length);
+
+ String dataStr = new String(newData, StandardCharsets.UTF_8);
+ comResult.append(dataStr.toUpperCase());
+
+ // 检查是否收到回车符(\r)
+ if (dataStr.contains("\r")) {
+ log("检查收到回车符");
+ chkRead = false;
+ }
+ }
+ });
+
+ connectButton.setText("关闭串口");
+ sendCommandButton.setEnabled(true);
+// log("串口 " + selectedPort.getSystemPortName() + " 打开成功,波特率: " + baudRate);
+ log("ababababab");
+ } else {
+ JOptionPane.showMessageDialog(this, "无法打开串口");
+ }
+ }
+
+ logArea.append("尝试最多3次读取设备信息");
+ // 尝试最多3次读取设备信息
+ String comResultStr = null;
+ for (int i = 1; i <= 3; i++) {
+ chkRead = true;
+ comResult.setLength(0); // 清空
+
+ selectedPort.flushIOBuffers();
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ignored) {}
+
+ // 发送指令
+ String command = "$05||*05\r\n";
+ selectedPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
+
+ // 等待最多2秒
+ long startTime = System.currentTimeMillis();
+ while (chkRead && (System.currentTimeMillis() - startTime < 2000)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ignored) {}
+ }
+
+ comResultStr = comResult.toString().trim();
+ log("第 " + i + " 次响应: " + comResultStr + "\n");
+
+ if (comResultStr.contains("$05|") && comResultStr.contains("\r")) {
+ log("收到响应:"+comResultStr);
+ break; // 成功收到
+ } else {
+ if (i == 3) {
+ log("三次均未收到有效响应!\n");
+ selectedPort.closePort();
+// btnPrint.setEnabled(true);
+ return;
+ }
+ }
+ }
+ }
+
+ /*private void sendCommand() {
+ if (selectedPort == null || !selectedPort.isOpen()) {
+ log("串口未打开");
+ return;
+ }
+
+ String command = "$05||*05\\r\\n"; // 根据设备协议修改命令
+ synchronized (portLock) {
+ int bytesWritten = selectedPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
+ log("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
+ }
+ }*/
+
+ private void sendCommand() {
+ if (selectedPort == null || !selectedPort.isOpen()) {
+ log("串口未打开");
+ return;
+ }
+
+ // 禁用按钮,防止重复点击
+ sendCommandButton.setEnabled(false);
+ log("正在发送命令...");
+
+ // 使用 SwingWorker 在后台线程执行串口操作
+ SwingWorker worker = new SwingWorker() {
+ @Override
+ protected String doInBackground() throws Exception {
+ String command = "$05||*05\r\n";
+ byte[] commandBytes = command.getBytes(StandardCharsets.US_ASCII);
+
+ // 发送命令
+ publish("selectedPort="+selectedPort.getNumDataBits());
+ int bytesWritten = selectedPort.writeBytes(commandBytes, commandBytes.length);
+ publish("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
+
+ // 设置超时时间(毫秒)
+ long timeout = 10000; // 10秒
+ long startTime = System.currentTimeMillis();
+ StringBuilder response = new StringBuilder();
+
+ // 循环读取,直到超时或收到完整响应(可根据协议优化)
+ while (System.currentTimeMillis() - startTime < timeout) {
+ synchronized (portLock) {
+ if (selectedPort.bytesAvailable() > 0) {
+ byte[] buffer = new byte[selectedPort.bytesAvailable()];
+ int len = selectedPort.readBytes(buffer, buffer.length);
+ String data = new String(buffer, 0, len, StandardCharsets.UTF_8);
+ response.append(data);
+
+ // 假设设备以换行符结束响应,可提前退出
+ if (data.contains("\r\n")) {
+ break;
+ }
+ }
+ }
+ // 小延迟避免 CPU 占用过高
+ Thread.sleep(10);
+ }
+
+ if (response.length() == 0) {
+ return "ERROR_TIMEOUT";
+ }
+ return response.toString().trim();
+ }
+
+ @Override
+ protected void process(List chunks) {
+ for (String message : chunks) {
+ log(message); // 调用你的 log 方法(操作 JTextArea)
+ }
+ }
+
+ @Override
+ protected void done() {
+ // 重新启用按钮
+ sendCommandButton.setEnabled(true);
+
+ try {
+ String result = get(); // 获取 doInBackground 的返回值
+ if ("ERROR_TIMEOUT".equals(result)) {
+ log("❌ 设备无响应,通信超时(10秒)");
+ JOptionPane.showMessageDialog(HubForm3.this,
+ "设备未响应,请检查连接或设备是否正常运行。",
+ "通信超时", JOptionPane.WARNING_MESSAGE);
+ } else {
+ log("✅ 响应: " + result);
+ }
+ } catch (Exception e) {
+ log("❌ 通信异常: " + e.getMessage());
+ }
+ }
+
+ };
+
+ // 启动后台任务
+ worker.execute();
+ }
+
+ private void log(String message) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ String format = LocalDateTime.now().format(formatter);
+ logArea.append("[" + format + "] " + message + "\n");
+ logArea.setCaretPosition(logArea.getDocument().getLength());
+ }
+
+ public static void main(String[] args) {
+ // 使用 SwingUtilities 确保线程安全
+ SwingUtilities.invokeLater(() -> {
+ try {
+ // 设置系统外观
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ new HubForm3().setVisible(true);
+ });
+ }
+}
diff --git a/src/main/java/unizk/PrintDemo.java b/src/main/java/unizk/PrintDemo.java
new file mode 100644
index 0000000..2e81839
--- /dev/null
+++ b/src/main/java/unizk/PrintDemo.java
@@ -0,0 +1,230 @@
+package unizk;
+
+import com.fazecast.jSerialComm.SerialPort;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.WriterException;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @Author hao
+ * @Date 2026/7/28 15:51
+ * @Version 1.0
+ **/
+public class PrintDemo extends JFrame {
+ private JComboBox portComboBox;
+ private JTextField baudRateField;
+ private JButton connectButton;
+ private JButton printButton;
+ private JTextArea logArea;
+ private SerialPort selectedPort;
+ private final Object portLock = new Object();
+ private StringBuilder resultData = new StringBuilder();
+
+ // 添加打印机选择组件
+ private JComboBox printerComboBox;
+ private JCheckBox showPrintDialogCheckBox;
+
+ public PrintDemo() {
+ setTitle("云理疗设备入库系统");
+ setSize(800, 500);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ // 顶部面板:串口设置
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+
+
+ add(topPanel, BorderLayout.NORTH);
+
+ // 中间面板:打印机设置 + 日志
+ JPanel centerPanel = new JPanel(new BorderLayout());
+
+ // 打印机设置面板
+ JPanel printerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ printerPanel.setBorder(BorderFactory.createTitledBorder("打印设置"));
+
+ printerPanel.add(new JLabel("打印机:"));
+ printerComboBox = new JComboBox<>();
+ loadPrinters();
+ printerPanel.add(printerComboBox);
+
+ JButton refreshPrinterBtn = new JButton("刷新打印机");
+ refreshPrinterBtn.addActionListener(e -> loadPrinters());
+ printerPanel.add(refreshPrinterBtn);
+
+ printButton = new JButton("打印");
+ printButton.addActionListener(e -> printQRCode("hello"));
+ printerPanel.add(printButton);
+
+ /*showPrintDialogCheckBox = new JCheckBox("显示打印对话框", true);
+ printerPanel.add(showPrintDialogCheckBox);*/
+
+ centerPanel.add(printerPanel, BorderLayout.NORTH);
+
+ // 日志区域
+ logArea = new JTextArea();
+ logArea.setEditable(false);
+ centerPanel.add(new JScrollPane(logArea), BorderLayout.CENTER);
+
+ add(centerPanel, BorderLayout.CENTER);
+
+ // 初始化
+ log("请选择打印机打印");
+ }
+
+ private void log(String message) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ String format = LocalDateTime.now().format(formatter);
+ logArea.append("[" + format + "] " + message + "\n");
+ logArea.setCaretPosition(logArea.getDocument().getLength());
+ }
+
+ private void loadPrinters() {
+ printerComboBox.removeAllItems();
+ PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
+ for (PrintService service : printServices) {
+ printerComboBox.addItem(service.getName());
+ }
+ if (printServices.length == 0) {
+ printerComboBox.addItem("未找到打印机");
+ }
+ }
+
+
+ private void printQRCode(String content) {
+ try {
+ // 1. 生成二维码图片
+ BufferedImage qrImage = generateQRCode(content, 300, 300);
+ log("二维码生成成功,尺寸: 300x300");
+
+ // 2. 获取选中的打印机
+ String printerName = (String) printerComboBox.getSelectedItem();
+ if (printerName == null || printerName.equals("未找到打印机")) {
+ int choice = JOptionPane.showConfirmDialog(this,
+ "未选择有效打印机,是否使用默认打印机继续?",
+ "打印机提示",
+ JOptionPane.YES_NO_OPTION);
+ if (choice != JOptionPane.YES_OPTION) {
+ log("用户取消打印");
+ return;
+ }
+ printerName = null; // 使用默认打印机
+ }
+
+ // 3. 执行打印
+// boolean showDialog = showPrintDialogCheckBox.isSelected();
+ printQRCodeDirectly(qrImage, printerName);
+
+ } catch (WriterException e) {
+ log("生成二维码失败: " + e.getMessage());
+ JOptionPane.showMessageDialog(this,
+ "生成二维码失败: " + e.getMessage(),
+ "二维码生成错误",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (PrinterException e) {
+ log("打印失败: " + e.getMessage());
+ JOptionPane.showMessageDialog(this,
+ "打印失败: " + e.getMessage() + "\n请检查打印机是否连接正常。",
+ "打印错误",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (Exception e) {
+ log("打印过程异常: " + e.getMessage());
+ e.printStackTrace();
+ JOptionPane.showMessageDialog(this,
+ "打印过程异常: " + e.getMessage(),
+ "异常",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ /**
+ * 生成二维码图片
+ */
+ private BufferedImage generateQRCode(String content, int width, int height) throws WriterException {
+ QRCodeWriter qrCodeWriter = new QRCodeWriter();
+ BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height);
+ return MatrixToImageWriter.toBufferedImage(bitMatrix);
+ }
+
+ private void printQRCodeDirectly(BufferedImage qrImage, String printerName) throws PrinterException {
+ PrinterJob job = PrinterJob.getPrinterJob();
+
+ // 选择打印机
+ if (printerName != null && !printerName.isEmpty()) {
+ PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
+ for (PrintService service : printServices) {
+ if (service.getName().equals(printerName)) {
+ job.setPrintService(service);
+ break;
+ }
+ }
+ }
+
+ // 设置打印内容
+ job.setPrintable(new Printable() {
+ @Override
+ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
+ if (pageIndex > 0) {
+ return NO_SUCH_PAGE;
+ }
+
+ Graphics2D g2d = (Graphics2D) graphics;
+ g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
+
+ double pageWidth = pageFormat.getImageableWidth();
+ double pageHeight = pageFormat.getImageableHeight();
+ int qrWidth = qrImage.getWidth();
+ int qrHeight = qrImage.getHeight();
+
+ if (qrWidth > pageWidth || qrHeight > pageHeight) {
+ double scaleX = pageWidth / qrWidth * 0.9;
+ double scaleY = pageHeight / qrHeight * 0.9;
+ double scale = Math.min(scaleX, scaleY);
+ int newWidth = (int) (qrWidth * scale);
+ int newHeight = (int) (qrHeight * scale);
+ int x = (int) ((pageWidth - newWidth) / 2);
+ int y = (int) ((pageHeight - newHeight) / 2);
+ g2d.drawImage(qrImage, x, y, newWidth, newHeight, null);
+ } else {
+ int x = (int) ((pageWidth - qrWidth) / 2);
+ int y = (int) ((pageHeight - qrHeight) / 2);
+ g2d.drawImage(qrImage, x, y, null);
+ }
+
+ return PAGE_EXISTS;
+ }
+ });
+
+ // 直接打印
+ job.print();
+ log("直接打印任务已提交(无对话框)");
+ }
+
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(() -> {
+ try {
+ // 设置系统外观
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ new PrintDemo().setVisible(true);
+ });
+ }
+
+}
diff --git a/src/main/java/unizk/SerialDeviceInfoApp.java b/src/main/java/unizk/SerialDeviceInfoApp.java
new file mode 100644
index 0000000..adca2d9
--- /dev/null
+++ b/src/main/java/unizk/SerialDeviceInfoApp.java
@@ -0,0 +1,265 @@
+package unizk;
+
+import com.fazecast.jSerialComm.SerialPort;
+import com.fazecast.jSerialComm.SerialPortDataListener;
+import com.fazecast.jSerialComm.SerialPortEvent;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+public class SerialDeviceInfoApp extends JFrame {
+ private JComboBox portComboBox;
+ private JTextField baudRateField;
+ private JButton connectButton;
+ private JButton sendCommandButton;
+ private JTextArea logArea;
+ private SerialPort selectedPort;
+ private final Object portLock = new Object();
+ private StringBuilder resultData = new StringBuilder();
+
+ public SerialDeviceInfoApp() {
+ setTitle("云理疗设备入库系统");
+ setSize(800, 400);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ // 顶部面板:串口设置
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout(new FlowLayout());
+
+ topPanel.add(new JLabel("串口:"));
+ portComboBox = new JComboBox<>();
+ refreshPorts();
+ topPanel.add(portComboBox);
+
+ topPanel.add(new JLabel("波特率:"));
+ baudRateField = new JTextField("115200", 10);
+ topPanel.add(baudRateField);
+
+ connectButton = new JButton("打开串口");
+ connectButton.addActionListener(e -> toggleConnect());
+ topPanel.add(connectButton);
+
+ sendCommandButton = new JButton("获取设备信息");
+ sendCommandButton.addActionListener(e -> sendCommand());
+ sendCommandButton.setEnabled(false);
+ topPanel.add(sendCommandButton);
+
+ JButton refreshButton = new JButton("刷新串口");
+ refreshButton.addActionListener(e -> refreshPorts());
+ topPanel.add(refreshButton);
+
+ add(topPanel, BorderLayout.NORTH);
+
+ // 中间:日志显示
+ logArea = new JTextArea();
+ logArea.setEditable(false);
+ add(new JScrollPane(logArea), BorderLayout.CENTER);
+
+ // 初始化
+ log("请选择串口并点击【打开串口】");
+ }
+
+ private void refreshPorts() {
+ portComboBox.removeAllItems();
+ SerialPort[] ports = SerialPort.getCommPorts();
+ for (SerialPort port : ports) {
+ portComboBox.addItem(port.getSystemPortName() + " - " + port.getDescriptivePortName());
+ }
+ if (ports.length == 0) {
+ portComboBox.addItem("未找到串口");
+ }
+ }
+
+ private void toggleConnect() {
+ if (selectedPort != null && selectedPort.isOpen()) {
+ selectedPort.closePort();
+ selectedPort.removeDataListener();
+ selectedPort = null;
+ connectButton.setText("打开串口");
+ sendCommandButton.setEnabled(false);
+ log("串口已关闭");
+ } else {
+ int selectedIndex = portComboBox.getSelectedIndex();
+ if (selectedIndex < 0) return;
+
+ SerialPort[] ports = SerialPort.getCommPorts();
+ if (selectedIndex >= ports.length) {
+ JOptionPane.showMessageDialog(this, "无效的串口选择");
+ return;
+ }
+
+ selectedPort = ports[selectedIndex];
+ int baudRate;
+ try {
+ baudRate = Integer.parseInt(baudRateField.getText().trim());
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(this, "波特率格式错误");
+ return;
+ }
+
+ if (selectedPort.openPort()) {
+ selectedPort.setBaudRate(baudRate);
+ selectedPort.setNumDataBits(8);
+ selectedPort.setNumStopBits(1);
+ selectedPort.setParity(SerialPort.NO_PARITY);
+ selectedPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
+
+ // 添加监听器
+ selectedPort.addDataListener(new SerialPortDataListener() {
+ @Override
+ public int getListeningEvents() {
+ return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
+ }
+
+ @Override
+ public void serialEvent(SerialPortEvent event) {
+ if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) return;
+
+ synchronized (portLock) {
+ byte[] newData = new byte[selectedPort.bytesAvailable()];
+ int len = selectedPort.readBytes(newData, newData.length);
+ String data = new String(newData, 0, len, StandardCharsets.UTF_8);
+ log("收到: " + data.trim());
+ resultData.append(data.trim());
+ }
+ }
+ });
+
+ connectButton.setText("关闭串口");
+ sendCommandButton.setEnabled(true);
+ log("串口 " + selectedPort.getSystemPortName() + " 打开成功,波特率: " + baudRate);
+ } else {
+ JOptionPane.showMessageDialog(this, "无法打开串口");
+ }
+ }
+ log("-----reslut1==="+resultData.toString());
+ }
+
+ /*private void sendCommand() {
+ if (selectedPort == null || !selectedPort.isOpen()) {
+ log("串口未打开");
+ return;
+ }
+
+ String command = "$05||*05\\r\\n"; // 根据设备协议修改命令
+ synchronized (portLock) {
+ int bytesWritten = selectedPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
+ log("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
+ }
+ }*/
+
+ private void sendCommand() {
+ if (selectedPort == null || !selectedPort.isOpen()) {
+ log("串口未打开");
+ return;
+ }
+
+ // 禁用按钮,防止重复点击
+ sendCommandButton.setEnabled(false);
+ log("正在发送命令...");
+
+ // 使用 SwingWorker 在后台线程执行串口操作
+ SwingWorker worker = new SwingWorker() {
+ @Override
+ protected String doInBackground() throws Exception {
+ String command = "$05||*05\r\n";
+ byte[] commandBytes = command.getBytes(StandardCharsets.US_ASCII);
+
+ // 发送命令
+ publish("selectedPort="+selectedPort.getNumDataBits());
+ int bytesWritten = selectedPort.writeBytes(commandBytes, commandBytes.length);
+ publish("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
+
+ // 设置超时时间(毫秒)
+ long timeout = 10000; // 10秒
+ long startTime = System.currentTimeMillis();
+ StringBuilder response = new StringBuilder();
+
+ // 循环读取,直到超时或收到完整响应(可根据协议优化)
+ while (System.currentTimeMillis() - startTime < timeout) {
+ synchronized (portLock) {
+ if (selectedPort.bytesAvailable() > 0) {
+ byte[] buffer = new byte[selectedPort.bytesAvailable()];
+ int len = selectedPort.readBytes(buffer, buffer.length);
+ String data = new String(buffer, 0, len, StandardCharsets.UTF_8);
+ response.append(data);
+
+ // 假设设备以换行符结束响应,可提前退出
+ if (data.contains("\r\n")) {
+ break;
+ }
+ }
+ }
+ // 小延迟避免 CPU 占用过高
+ Thread.sleep(10);
+ }
+
+ if (response.length() == 0) {
+ return "ERROR_TIMEOUT";
+ }
+ return response.toString().trim();
+ }
+
+ @Override
+ protected void process(List chunks) {
+ for (String message : chunks) {
+ log(message); // 调用你的 log 方法(操作 JTextArea)
+ }
+ }
+
+ @Override
+ protected void done() {
+ log("-----reslut2==="+resultData.toString());
+ // 重新启用按钮
+ sendCommandButton.setEnabled(true);
+
+ /* try {
+ String result = get(); // 获取 doInBackground 的返回值
+ log("result=" + result);
+ if ("ERROR_TIMEOUT".equals(result)) {
+ log("❌ 设备无响应,通信超时(10秒)");
+ JOptionPane.showMessageDialog(SerialDeviceInfoApp.this,
+ "设备未响应,请检查连接或设备是否正常运行。",
+ "通信超时", JOptionPane.WARNING_MESSAGE);
+ } else {
+ log("✅ 响应: " + result);
+ }
+ } catch (Exception e) {
+ log("❌ 通信异常: " + e.getMessage());
+ }*/
+ }
+
+ };
+
+ // 启动后台任务
+ worker.execute();
+ }
+
+ private void log(String message) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ String format = LocalDateTime.now().format(formatter);
+ logArea.append("[" + format + "] " + message + "\n");
+ logArea.setCaretPosition(logArea.getDocument().getLength());
+ }
+
+ public static void main(String[] args) {
+ // 使用 SwingUtilities 确保线程安全
+ SwingUtilities.invokeLater(() -> {
+ try {
+ // 设置系统外观
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ new SerialDeviceInfoApp().setVisible(true);
+ });
+ }
+}
diff --git a/src/main/java/unizk/utils/AESUtil.java b/src/main/java/unizk/utils/AESUtil.java
new file mode 100644
index 0000000..ce100bf
--- /dev/null
+++ b/src/main/java/unizk/utils/AESUtil.java
@@ -0,0 +1,60 @@
+package unizk.utils;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+
+public class AESUtil {
+
+ private static final String ALGORITHM = "AES";
+ private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; // 模式:CBC + 填充
+
+ // 注意:密钥必须是 16/24/32 字节,对应 128/192/256 位
+ private static final String SECRET_KEY = "Unizk.&jkzy@2025"; // 16 字节 = 128 位
+ private static final String IV = "2vCnQxrSXMlLzsen"; // 初始化向量,16 字节
+
+ /**
+ * AES 加密
+ */
+ public static String encrypt(String plainText) throws Exception {
+ // 创建密钥
+ SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), ALGORITHM);
+
+ // 创建初始化向量
+ IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes("UTF-8"));
+
+ // 获取 Cipher 实例
+ Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+ cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
+
+ // 执行加密
+ byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
+
+ // Base64 编码返回
+ return Base64.getEncoder().encodeToString(encrypted);
+ }
+
+ /**
+ * AES 解密
+ */
+ public static String decrypt(String encryptedText) throws Exception {
+ SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
+ IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
+
+ Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+ cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
+
+ // Base64 解码
+ byte[] decoded = Base64.getDecoder().decode(encryptedText);
+ byte[] decrypted = cipher.doFinal(decoded);
+
+ return new String(decrypted, StandardCharsets.UTF_8);
+ }
+
+}
+
diff --git a/src/main/java/unizk/utils/HttpUtil.java b/src/main/java/unizk/utils/HttpUtil.java
new file mode 100644
index 0000000..bf5f151
--- /dev/null
+++ b/src/main/java/unizk/utils/HttpUtil.java
@@ -0,0 +1,241 @@
+package unizk.utils;
+
+import com.alibaba.fastjson2.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+public class HttpUtil {
+
+ private static final String URL_CONCATENATION = "url-concatenation";
+ private static final String FORM_URLENCODED = "form-urlencoded";
+ private static final String JSON_BODY = "json";
+
+ public static final String STATUS_CODE = "code";
+ public static final String RESPONSE = "res";
+
+ // 私有构造器防止实例化
+ private HttpUtil() {}
+
+ /**
+ * GET 请求(带 headers 和 params)
+ */
+ public static String doGet(String url, Map headers, Map params) {
+ return doHttpRequest(url, headers, params, HttpMethod.GET, URL_CONCATENATION);
+ }
+
+ /**
+ * POST 请求 - 默认以 JSON 格式发送 body
+ */
+ public static String doPost(String url, Map headers, Map params) {
+ return doHttpRequest(url, headers, params, HttpMethod.POST, JSON_BODY);
+ }
+
+ /**
+ * POST 请求 - 使用 URL 拼接方式传递参数
+ */
+ public static String doPostWithUrlParams(String url, Map headers, Map params) {
+ return doHttpRequest(url, headers, params, HttpMethod.POST, URL_CONCATENATION);
+ }
+
+ /**
+ * POST 请求 - 使用 application/x-www-form-urlencoded 格式
+ */
+ public static String doPostFormUrlencoded(String url, Map headers, Map params) {
+ return doHttpRequest(url, headers, params, HttpMethod.POST, FORM_URLENCODED);
+ }
+
+ /**
+ * POST 请求 - 发送原始 JSON 字符串(适合复杂结构)
+ */
+ public static String doPostJson(String url, Map headers, JSONObject jsonObject) {
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ HttpPost post = new HttpPost(url);
+ addHeaders(post, headers);
+
+ StringEntity entity = new StringEntity(
+ jsonObject.toString(),
+ ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
+ );
+ post.setEntity(entity);
+
+ try (CloseableHttpResponse response = httpClient.execute(post)) {
+ if (response.getEntity() == null){
+ return null;
+ }
+ return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("HTTP POST JSON request error", e);
+ }
+ }
+
+
+ public static byte[] postRtnBytes(String url, Map headers, JSONObject jsonObject){
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ HttpPost request = new HttpPost(url);
+ StringEntity entity = new StringEntity(
+ jsonObject.toString(),
+ ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
+ );
+ request.setEntity(entity);
+
+ try (CloseableHttpResponse response = httpClient.execute(request)) {
+ int statusCode = response.getStatusLine().getStatusCode(); // HTTP 状态码
+ if (statusCode == 200) {
+ // 获取响应体输入流
+ InputStream inputStream = response.getEntity().getContent();
+
+ // 将输入流读取为 byte[]
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ int nRead;
+ byte[] data = new byte[4096];
+ while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
+ buffer.write(data, 0, nRead);
+ }
+ buffer.flush();
+
+ return buffer.toByteArray(); // 返回 byte[] 缓冲区
+ } else {
+ throw new IOException("HTTP error: " + statusCode);
+ }
+ }
+ }catch (IOException e){
+ throw new RuntimeException("HTTP POST JSON request error", e);
+ }
+ }
+
+
+ /**
+ * 返回状态码
+ * @param url
+ * @param headers
+ * @param jsonObject
+ * @return
+ */
+ public static JSONObject postJsonCarryStatusCode(String url, Map headers, JSONObject jsonObject) {
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ HttpPost post = new HttpPost(url);
+ addHeaders(post, headers);
+
+ StringEntity entity = new StringEntity(
+ jsonObject.toString(),
+ ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
+ );
+ post.setEntity(entity);
+
+ try (CloseableHttpResponse response = httpClient.execute(post)) {
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (response.getEntity() != null){
+ String data = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+ return JSONObject.of(HttpUtil.STATUS_CODE,statusCode,HttpUtil.RESPONSE,data);
+ }
+ return JSONObject.of(HttpUtil.STATUS_CODE,statusCode,HttpUtil.RESPONSE,null);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("HTTP POST JSON request error", e);
+ }
+ }
+
+ /**
+ * 通用 HTTP 请求方法
+ */
+ private static String doHttpRequest(String url, Map headers,
+ Map params, HttpMethod method, String paramType) {
+ List pairList = new ArrayList<>();
+ if (params != null && !params.isEmpty()) {
+ for (Map.Entry entry : params.entrySet()) {
+ pairList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+ }
+ }
+
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setConnectTimeout(5000) // 连接超时 5秒
+ .setSocketTimeout(10000) // 读取超时 10秒
+ .setConnectionRequestTimeout(2000) // 从连接池获取连接超时 2秒
+ .build();
+ try (CloseableHttpClient client = HttpClients.createDefault()) {
+ HttpRequestBase request = createHttpRequest(url, method, params, pairList, paramType);
+ addHeaders(request, headers);
+ request.setConfig(requestConfig);
+
+ try (CloseableHttpResponse response = client.execute(request)) {
+ HttpEntity entity = response.getEntity();
+ return entity == null ? null : EntityUtils.toString(entity, StandardCharsets.UTF_8);
+ }
+ } catch (IOException | URISyntaxException e) {
+ throw new RuntimeException("HTTP request error: " + url, e);
+ }
+ }
+
+ /**
+ * 构建 HTTP 请求对象(GET / POST)
+ */
+ private static HttpRequestBase createHttpRequest(String url, HttpMethod method,
+ Map params,
+ List pairList,
+ String paramType) throws URISyntaxException {
+ if (method == HttpMethod.GET) {
+ URIBuilder uriBuilder = new URIBuilder(url);
+ if (paramType.equals(URL_CONCATENATION) && params != null && !params.isEmpty()) {
+ for (Map.Entry entry : params.entrySet()) {
+ uriBuilder.addParameter(entry.getKey(), entry.getValue());
+ }
+ }
+ return new HttpGet(uriBuilder.build());
+ } else if (method == HttpMethod.POST) {
+ HttpPost post = new HttpPost(url);
+
+ if (paramType.equals(FORM_URLENCODED)) {
+ post.setEntity(new UrlEncodedFormEntity(pairList, StandardCharsets.UTF_8));
+ } else if (paramType.equals(JSON_BODY)) {
+ JSONObject json = new JSONObject(params);
+ StringEntity entity = new StringEntity(
+ json.toString(),
+ ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
+ );
+ post.setEntity(entity);
+ }
+
+ return post;
+ }
+ throw new IllegalArgumentException("Unsupported HTTP method: " + method);
+ }
+
+ /**
+ * 添加请求头
+ */
+ private static void addHeaders(HttpRequestBase request, Map headers) {
+ if (headers != null && !headers.isEmpty()) {
+ for (Map.Entry entry : headers.entrySet()) {
+ request.addHeader(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ // 枚举类型定义
+ public enum HttpMethod {
+ GET, POST
+ }
+}
+
diff --git a/target/classes/unizk/Demo1$1.class b/target/classes/unizk/Demo1$1.class
new file mode 100644
index 0000000..8b745f4
Binary files /dev/null and b/target/classes/unizk/Demo1$1.class differ
diff --git a/target/classes/unizk/Demo1$2.class b/target/classes/unizk/Demo1$2.class
new file mode 100644
index 0000000..60b2929
Binary files /dev/null and b/target/classes/unizk/Demo1$2.class differ
diff --git a/target/classes/unizk/Demo1$3.class b/target/classes/unizk/Demo1$3.class
new file mode 100644
index 0000000..2c87a91
Binary files /dev/null and b/target/classes/unizk/Demo1$3.class differ
diff --git a/target/classes/unizk/Demo1$4.class b/target/classes/unizk/Demo1$4.class
new file mode 100644
index 0000000..2e625ba
Binary files /dev/null and b/target/classes/unizk/Demo1$4.class differ
diff --git a/target/classes/unizk/Demo1$5.class b/target/classes/unizk/Demo1$5.class
new file mode 100644
index 0000000..495968d
Binary files /dev/null and b/target/classes/unizk/Demo1$5.class differ
diff --git a/target/classes/unizk/Demo1.class b/target/classes/unizk/Demo1.class
new file mode 100644
index 0000000..f1c7bee
Binary files /dev/null and b/target/classes/unizk/Demo1.class differ
diff --git a/target/classes/unizk/HubForm$1.class b/target/classes/unizk/HubForm$1.class
new file mode 100644
index 0000000..c17de91
Binary files /dev/null and b/target/classes/unizk/HubForm$1.class differ
diff --git a/target/classes/unizk/HubForm$2.class b/target/classes/unizk/HubForm$2.class
new file mode 100644
index 0000000..fc79fa7
Binary files /dev/null and b/target/classes/unizk/HubForm$2.class differ
diff --git a/target/classes/unizk/HubForm$DeviceInfo.class b/target/classes/unizk/HubForm$DeviceInfo.class
new file mode 100644
index 0000000..9a79208
Binary files /dev/null and b/target/classes/unizk/HubForm$DeviceInfo.class differ
diff --git a/target/classes/unizk/HubForm.class b/target/classes/unizk/HubForm.class
new file mode 100644
index 0000000..86ffb69
Binary files /dev/null and b/target/classes/unizk/HubForm.class differ
diff --git a/target/classes/unizk/HubForm3$1.class b/target/classes/unizk/HubForm3$1.class
new file mode 100644
index 0000000..0b5a0c9
Binary files /dev/null and b/target/classes/unizk/HubForm3$1.class differ
diff --git a/target/classes/unizk/HubForm3$2.class b/target/classes/unizk/HubForm3$2.class
new file mode 100644
index 0000000..8172482
Binary files /dev/null and b/target/classes/unizk/HubForm3$2.class differ
diff --git a/target/classes/unizk/HubForm3.class b/target/classes/unizk/HubForm3.class
new file mode 100644
index 0000000..1c9cf62
Binary files /dev/null and b/target/classes/unizk/HubForm3.class differ
diff --git a/target/classes/unizk/PrintDemo$1.class b/target/classes/unizk/PrintDemo$1.class
new file mode 100644
index 0000000..66f1cf4
Binary files /dev/null and b/target/classes/unizk/PrintDemo$1.class differ
diff --git a/target/classes/unizk/PrintDemo.class b/target/classes/unizk/PrintDemo.class
new file mode 100644
index 0000000..1c4458e
Binary files /dev/null and b/target/classes/unizk/PrintDemo.class differ
diff --git a/target/classes/unizk/SerialDeviceInfoApp$1.class b/target/classes/unizk/SerialDeviceInfoApp$1.class
new file mode 100644
index 0000000..322232e
Binary files /dev/null and b/target/classes/unizk/SerialDeviceInfoApp$1.class differ
diff --git a/target/classes/unizk/SerialDeviceInfoApp$2.class b/target/classes/unizk/SerialDeviceInfoApp$2.class
new file mode 100644
index 0000000..2a4a1fa
Binary files /dev/null and b/target/classes/unizk/SerialDeviceInfoApp$2.class differ
diff --git a/target/classes/unizk/SerialDeviceInfoApp.class b/target/classes/unizk/SerialDeviceInfoApp.class
new file mode 100644
index 0000000..0725b5d
Binary files /dev/null and b/target/classes/unizk/SerialDeviceInfoApp.class differ
diff --git a/target/classes/unizk/utils/AESUtil.class b/target/classes/unizk/utils/AESUtil.class
new file mode 100644
index 0000000..de6f958
Binary files /dev/null and b/target/classes/unizk/utils/AESUtil.class differ
diff --git a/target/classes/unizk/utils/HttpUtil$HttpMethod.class b/target/classes/unizk/utils/HttpUtil$HttpMethod.class
new file mode 100644
index 0000000..0c3b3e7
Binary files /dev/null and b/target/classes/unizk/utils/HttpUtil$HttpMethod.class differ
diff --git a/target/classes/unizk/utils/HttpUtil.class b/target/classes/unizk/utils/HttpUtil.class
new file mode 100644
index 0000000..58b3d6e
Binary files /dev/null and b/target/classes/unizk/utils/HttpUtil.class differ
diff --git a/target/device-to-db2-1.0.0-jar-with-dependencies.jar b/target/device-to-db2-1.0.0-jar-with-dependencies.jar
new file mode 100644
index 0000000..22ab871
Binary files /dev/null and b/target/device-to-db2-1.0.0-jar-with-dependencies.jar differ
diff --git a/target/device-to-db2-1.0.0.jar b/target/device-to-db2-1.0.0.jar
new file mode 100644
index 0000000..264e8a4
Binary files /dev/null and b/target/device-to-db2-1.0.0.jar differ
diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..2377fd1
--- /dev/null
+++ b/target/maven-archiver/pom.properties
@@ -0,0 +1,3 @@
+artifactId=device-to-db2
+groupId=unizk
+version=1.0.0
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..8ec1ea4
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,21 @@
+unizk\HubForm$1.class
+unizk\Demo1$4.class
+unizk\SerialDeviceInfoApp.class
+unizk\Demo1$3.class
+unizk\Demo1$2.class
+unizk\HubForm3$2.class
+unizk\HubForm$2.class
+unizk\HubForm$DeviceInfo.class
+unizk\utils\HttpUtil.class
+unizk\Demo1.class
+unizk\SerialDeviceInfoApp$2.class
+unizk\HubForm3$1.class
+unizk\SerialDeviceInfoApp$1.class
+unizk\HubForm3.class
+unizk\utils\HttpUtil$HttpMethod.class
+unizk\Demo1$1.class
+unizk\PrintDemo.class
+unizk\Demo1$5.class
+unizk\HubForm.class
+unizk\utils\AESUtil.class
+unizk\PrintDemo$1.class
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..ceffc99
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,8 @@
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\Demo1.java
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\utils\HttpUtil.java
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\HubForm2.java
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\PrintDemo.java
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\SerialDeviceInfoApp.java
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\utils\AESUtil.java
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\HubForm.java
+D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\HubForm3.java