Merge remote-tracking branch 'origin/0.8.X' into 0.8.X

This commit is contained in:
2025-08-23 16:52:40 +08:00
5 changed files with 512 additions and 255 deletions

View File

@@ -9,13 +9,13 @@
清空所有 清空所有
</el-button> </el-button>
</el-tooltip> </el-tooltip>
<el-tooltip content="仅对完整配置的二维码进行打印预览" placement="top" <!-- <el-tooltip content="仅对完整配置的二维码进行打印预览" placement="top"
:disabled="drawerBarcodeData.length === 0 || !isAllValid"> :disabled="drawerBarcodeData.length === 0 || !isAllValid">
<el-button type="success" icon="el-icon-printer" @click="handlePrintPreview" <el-button type="success" icon="el-icon-printer" @click="handlePrintPreview"
:disabled="drawerBarcodeData.length === 0 || !isAllValid" class="btn-print"> :disabled="drawerBarcodeData.length === 0 || !isAllValid" class="btn-print">
打印预览 打印预览
</el-button> </el-button>
</el-tooltip> </el-tooltip> -->
<el-button type="primary" icon="el-icon-plus" @click="handleAdd"> <el-button type="primary" icon="el-icon-plus" @click="handleAdd">
添加二维码 添加二维码
</el-button> </el-button>
@@ -74,7 +74,15 @@
<el-row :gutter="8"> <el-row :gutter="8">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="操作类型" :error="getError(cfg, 'ioType')" class="form-item"> <el-form-item label="操作类型" :error="getError(cfg, 'ioType')" class="form-item">
<el-select v-model="cfg.ioType" placeholder="请选择操作类型" class="form-select"> <el-select
v-model="cfg.ioType"
placeholder="请选择操作类型"
class="form-select"
@change="(value) => {
const prefix = value == 'in' ? '入库' : value == 'out' ? '出库' : value == 'transfer' ? '移库' : ''
cfg.text = prefix + '二维码' + new Date().getTime()
}"
>
<el-option label="入库" value="in" /> <el-option label="入库" value="in" />
<el-option label="出库" value="out" /> <el-option label="出库" value="out" />
<el-option label="移库" value="transfer" /> <el-option label="移库" value="transfer" />
@@ -82,7 +90,11 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="单据" :error="getError(cfg, 'stockIoId')" class="form-item"> <el-form-item
:label="cfg.ioType == 'in' ? '入库单据号' : cfg.ioType == 'out' ? '出库单据号' : cfg.ioType == 'transfer' ? '移库单据号' : '单据号'"
:error="getError(cfg, 'stockIoId')"
class="form-item"
>
<el-select clearable filterable size="mini" v-model="cfg.stockIoId" placeholder="请选择挂载单据" <el-select clearable filterable size="mini" v-model="cfg.stockIoId" placeholder="请选择挂载单据"
class="form-select" :disabled="!cfg.ioType"> class="form-select" :disabled="!cfg.ioType">
<el-option v-for="item in masterList.filter(i => i.ioType === cfg.ioType)" <el-option v-for="item in masterList.filter(i => i.ioType === cfg.ioType)"

View File

@@ -147,6 +147,7 @@ export default {
duration: 1500 duration: 1500
}); });
// 解析成功后禁用输入框 // 解析成功后禁用输入框
this.handleSubmit();
// this.$refs.textarea.disabled = true; // this.$refs.textarea.disabled = true;
console.log(this.$refs.textarea.disabled, '禁用输入框'); console.log(this.$refs.textarea.disabled, '禁用输入框');
} else { } else {
@@ -184,8 +185,6 @@ export default {
message: '操作成功', message: '操作成功',
duration: 2000 duration: 2000
}); });
// 提交成功后重置表单,方便下一次操作
this.handleReset();
}) })
.catch(err => { .catch(err => {
this.$message.error({ this.$message.error({
@@ -195,6 +194,8 @@ export default {
}) })
.finally(() => { .finally(() => {
this.isSubmitting = false; this.isSubmitting = false;
// 提交成功后重置表单,方便下一次操作
this.handleReset();
}); });
}, },
handleReset() { handleReset() {

View File

@@ -0,0 +1,262 @@
//package org.example;
//
//import java.io.File;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.io.OutputStream;
//import java.util.ArrayList;
//
//import org.glassfish.tyrus.server.Server;
//
//import MvCodeReaderCtrlWrapper.*;
//import MvCodeReaderCtrlWrapper.MvCodeReaderCtrlDefine.*;
//
//public class Back {
// static HttpRequestUtil http = null;
//
// // 保存所有读取到的设备列表
// private static ArrayList<MV_CODEREADER_DEVICE_INFO> allDevices = new ArrayList<>();
//
// // 保存正在监听的设备列表
// private static final ArrayList<MV_CODEREADER_DEVICE_INFO> activeDevices = new ArrayList<>();
// private static byte[] pdata;
//
// // 获取所有读取到的设备列表JSON推送给前端
// public static String getAllDevicesJson() {
// org.json.JSONObject obj = new org.json.JSONObject();
// obj.put("type", "allDevices");
// org.json.JSONArray arr = new org.json.JSONArray();
//
// for (MV_CODEREADER_DEVICE_INFO camInfo : allDevices) {
// org.json.JSONObject dev = new org.json.JSONObject();
// dev.put("id", camInfo.stGigEInfo.chSerialNumber); // 序列号
// dev.put("name", camInfo.stGigEInfo.chUserDefinedName != null ?
// camInfo.stGigEInfo.chUserDefinedName : camInfo.stGigEInfo.chModelName);
// dev.put("model", camInfo.stGigEInfo.chModelName); // 型号
// dev.put("manufacturer", camInfo.stGigEInfo.chManufacturerName); // 制造商
// dev.put("ip", getIpAddress(camInfo.stGigEInfo.nCurrentIp)); // IP地址
// dev.put("version", camInfo.stGigEInfo.chDeviceVersion); // 设备版本
// dev.put("isActive", isDeviceActive(camInfo)); // 是否正在监听
// arr.put(dev);
// }
//
// obj.put("devices", arr);
// obj.put("totalCount", allDevices.size()); // 设备总数
// obj.put("activeCount", activeDevices.size()); // 活跃设备数
// return obj.toString();
// }
//
// // 检查设备是否正在监听
// private static boolean isDeviceActive(MV_CODEREADER_DEVICE_INFO device) {
// for (MV_CODEREADER_DEVICE_INFO active : activeDevices) {
// if (active.stGigEInfo.chSerialNumber.equals(device.stGigEInfo.chSerialNumber)) {
// return true;
// }
// }
// return false;
// }
//
// // 将IP整数转换为字符串格式
// private static String getIpAddress(int ipInt) {
// return ((ipInt & 0xff000000) >> 24) + "." +
// ((ipInt & 0x00ff0000) >> 16) + "." +
// ((ipInt & 0x0000ff00) >> 8) + "." +
// (ipInt & 0x000000ff);
// }
//
// public static void saveDataToFile(byte[] dataToSave, int dataSize, String fileName) {
// OutputStream os = null;
//
// try {
// // 创建保存目录
// File tempFile = new File("saveImg");
// if (!tempFile.exists()) {
// tempFile.mkdirs();
// }
//
// os = new FileOutputStream("saveImg/" + fileName);
// os.write(dataToSave, 0, dataSize);
// System.out.println("图像保存成功: " + fileName);
// } catch (IOException e) {
// e.printStackTrace();
// } finally {
// // 关闭文件流
// try {
// if (os != null) {
// os.close();
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
//
// // 回调函数, 当扫码枪扫码后触发
// private static void printImgCBInfo(byte[] pdata, MV_CODEREADER_IMAGE_OUT_INFO_EX2 stOutInfo) {
// Main.pdata = pdata;
// if (null == stOutInfo) {
// System.out.println("stOutInfo is null");
// return;
// }
//
// System.out.print("/**CBpstOutInfo***************************************/\n");
//
// System.out.printf("获取一帧: nEventID[%d], nChannelID[%d], nWidth[%d], nHeight[%d], nFrameNum[%d], nTriggerIndex[%d], nFrameLen[%d], "
// + " nCodeNumber[%d] \r\n",
// stOutInfo.nEventID, stOutInfo.nChannelID, stOutInfo.nWidth, stOutInfo.nHeight, stOutInfo.nFrameNum,
// stOutInfo.nTriggerIndex, stOutInfo.nFrameLen, stOutInfo.pstCodeListEx.nCodeNum);
//
// System.out.print("解码状态: bIsGetCode[" + stOutInfo.bIsGetCode + "]\r\n");
//
// System.out.print("像素类型: MvCodeReaderGvspPixelType[" + stOutInfo.enPixelType + "]\r\n");
//
// // 打印解码信息
// for (int a = 0; a < stOutInfo.pstCodeListEx.nCodeNum; a++) {
// org.json.JSONObject obj = new org.json.JSONObject();
// obj.put("type", "scanMessage");
// // 解析码中的数据用下划线分割第一个为物料类型第二个为物料id
// String code = stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).chCode;
//// String[] parts = code.split("__");
//// if (parts.length >= 2) {
//// String itemType = parts[0];
//// String itemId = parts[1];
//// obj.put("itemType", itemType);
//// obj.put("itemId", itemId);
//// } else {
//// obj.put("rawCode", code);
//// obj.put("error", "格式不正确");
//// }
// // 直接将解析出的数据返回到页面上
//// WsServer.broadcast(code);
// // 发送http请求存储信息
// try {
// String s = HttpRequestUtil.postJson("http://140.143.206.120:8080/wms/stockIoDetail", code);
// System.out.println("返回值" + s);
// System.out.println("明细记录创建成功" + code);
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
//
//
// System.out.printf("解码信息: TheCodeID[%d], CodeString[%s], nCodeLen[%d], nAngle[%d], nBarType[%d],"
// + "sAlgoCost[%d], nIDRScore[%d], n1DIsGetQuality[%d]\r\n",
// a, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).chCode, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nLen,
// stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nAngle, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nBarType,
// stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).sAlgoCost, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nIDRScore,
// stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).n1DIsGetQuality);
// }
// }
//
// private static void PrintDeviceInfo(MV_CODEREADER_DEVICE_INFO stCamInfo) {
// if (stCamInfo.nTLayerType == MvCodeReaderCtrlDefine.MV_CODEREADER_GIGE_DEVICE) {
// System.out.print("IP地址: " + getIpAddress(stCamInfo.stGigEInfo.nCurrentIp) + "\r\n");
// System.out.printf("设备信息: 自定义名称:[%s], 序列号:[%s], 型号:[%s] \r\n\r\n",
// stCamInfo.stGigEInfo.chUserDefinedName,
// stCamInfo.stGigEInfo.chSerialNumber,
// stCamInfo.stGigEInfo.chModelName);
// }
// }
//
//
// public static void main(String[] args) throws InterruptedException {
// System.out.print(" ***************程序开始****************** \r\n");
//
//// String strVersion = MvCodeReaderCtrl.MV_CODEREADER_GetSDKVersion();
//// System.out.print("SDK版本: " + strVersion + "\r\n");
////
//// // 枚举所有设备
//// allDevices = MvCodeReaderCtrl.MV_CODEREADER_EnumDevices();
//// if (allDevices == null || allDevices.isEmpty()) {
//// System.out.print("未发现任何设备!\r\n");
//// } else {
//// System.out.print("发现" + allDevices.size() + "个设备:\r\n");
//// for (MV_CODEREADER_DEVICE_INFO device : allDevices) {
//// PrintDeviceInfo(device);
//// }
//// }
////
//// ArrayList<Handle> handleList = new ArrayList<>();
//// // 尝试打开并启动所有发现的设备
//// for (int i = 0; i < allDevices.size(); i++) {
//// MV_CODEREADER_DEVICE_INFO camInfo = allDevices.get(i);
//// System.out.print("处理设备 " + i + ": " + camInfo.stGigEInfo.chSerialNumber + "\r\n");
////
//// Handle handle = null;
//// try {
//// handle = MvCodeReaderCtrl.MV_CODEREADER_CreateHandle(camInfo);
//// } catch (ParameterException e) {
//// System.out.print("创建句柄失败: " + e.getMessage() + "\r\n");
//// continue;
//// }
////
//// if (handle == null) {
//// System.out.print("创建句柄失败 for device " + i + "!\r\n");
//// continue;
//// }
////
//// int nRet = MvCodeReaderCtrl.MV_CODEREADER_OpenDevice(handle);
//// if (nRet != 0) {
//// System.out.print("打开设备失败 for device " + i + "! 错误码[" + String.format("0x%x", nRet) + "]\r\n");
//// continue;
//// }
////
//// nRet = MvCodeReaderCtrl.MV_CODEREADER_RegisterImageCallBackEx2(handle, new ImageCallBack() {
//// @Override
//// public int OnImageCallBack(byte[] pdata, MV_CODEREADER_IMAGE_OUT_INFO_EX2 stOutInfo) {
//// printImgCBInfo(pdata, stOutInfo);
//// return 0;
//// }
//// });
////
//// if (nRet != 0) {
//// System.out.print("注册回调失败 for device " + i + "! 错误码[" + String.format("0x%x", nRet) + "]\r\n");
//// MvCodeReaderCtrl.MV_CODEREADER_CloseDevice(handle);
//// continue;
//// }
////
//// nRet = MvCodeReaderCtrl.MV_CODEREADER_StartGrabbing(handle);
//// if (nRet != 0) {
//// System.out.print("启动抓取失败 for device " + i + "! 错误码[" + String.format("0x%x", nRet) + "]\r\n");
//// MvCodeReaderCtrl.MV_CODEREADER_CloseDevice(handle);
//// continue;
//// }
////
//// // 如果所有步骤都成功,添加到活跃设备列表
//// handleList.add(handle);
//// activeDevices.add(camInfo);
//// System.out.print("设备 " + i + " 启动成功,开始监听!\r\n");
//// }
////
//// System.out.println("所有设备处理完毕。活跃设备数量: " + activeDevices.size() + "\r\n");
//
// // 输入自己的身份并保存每次请求时将其附加在json中createBy字段
//
//// 改为监听键盘输入,当监听到一个以##开头,!!结尾的字符串时,提取中间的部分
// http = new HttpRequestUtil();
// System.out.println("http请求工具创建完成");
// // 启动WebSocket服务器用于向前端推送设备列表和扫描结果
// Server server = new Server("localhost", 9000, "/", null, WsServer.class);
// try {
// server.start();
// System.out.println("WebSocket服务器已启动端口9000");
// System.out.println("按Enter键退出程序...");
// System.in.read(); // 阻塞主线程直到回车
// } catch (Exception e) {
// System.out.println("WebSocket服务器错误: " + e.getMessage());
// e.printStackTrace();
// } finally {
// // 停止所有设备
// System.out.println("停止所有设备...");
// for (Handle handle : handleList) {
// MvCodeReaderCtrl.MV_CODEREADER_StopGrabbing(handle);
// MvCodeReaderCtrl.MV_CODEREADER_CloseDevice(handle);
// }
// server.stop();
// System.out.println("程序已退出");
// }
// }
//
// public static byte[] getPdata() {
// return pdata;
// }
//}

View File

@@ -1,259 +1,241 @@
package org.example; package org.example;
import java.io.File; import java.awt.AWTException;
import java.io.FileOutputStream; import java.awt.Robot;
import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import org.glassfish.tyrus.server.Server; import org.json.JSONException;
import org.json.JSONObject;
import MvCodeReaderCtrlWrapper.*;
import MvCodeReaderCtrlWrapper.MvCodeReaderCtrlDefine.*;
public class Main { public class Main {
static HttpRequestUtil http = null; static HttpRequestUtil http = null;
private static String userIdentity;
// 保存所有读取到的设备列表 // 存储扫码枪输入的字符
private static ArrayList<MV_CODEREADER_DEVICE_INFO> allDevices = new ArrayList<>(); private static final BlockingQueue<Character> inputQueue = new ArrayBlockingQueue<>(4096);
// 扫码枪结束符回车的ASCII值
// 保存正在监听的设备列表 private static final int ENTER_ASCII = 13; // \r的ASCII值
private static final ArrayList<MV_CODEREADER_DEVICE_INFO> activeDevices = new ArrayList<>(); private static final int NEWLINE_ASCII = 10; // \n的ASCII值
private static byte[] pdata; private static volatile boolean isExit = false;
// 获取所有读取到的设备列表JSON推送给前端
public static String getAllDevicesJson() {
org.json.JSONObject obj = new org.json.JSONObject();
obj.put("type", "allDevices");
org.json.JSONArray arr = new org.json.JSONArray();
for (MV_CODEREADER_DEVICE_INFO camInfo : allDevices) {
org.json.JSONObject dev = new org.json.JSONObject();
dev.put("id", camInfo.stGigEInfo.chSerialNumber); // 序列号
dev.put("name", camInfo.stGigEInfo.chUserDefinedName != null ?
camInfo.stGigEInfo.chUserDefinedName : camInfo.stGigEInfo.chModelName);
dev.put("model", camInfo.stGigEInfo.chModelName); // 型号
dev.put("manufacturer", camInfo.stGigEInfo.chManufacturerName); // 制造商
dev.put("ip", getIpAddress(camInfo.stGigEInfo.nCurrentIp)); // IP地址
dev.put("version", camInfo.stGigEInfo.chDeviceVersion); // 设备版本
dev.put("isActive", isDeviceActive(camInfo)); // 是否正在监听
arr.put(dev);
}
obj.put("devices", arr);
obj.put("totalCount", allDevices.size()); // 设备总数
obj.put("activeCount", activeDevices.size()); // 活跃设备数
return obj.toString();
}
// 检查设备是否正在监听
private static boolean isDeviceActive(MV_CODEREADER_DEVICE_INFO device) {
for (MV_CODEREADER_DEVICE_INFO active : activeDevices) {
if (active.stGigEInfo.chSerialNumber.equals(device.stGigEInfo.chSerialNumber)) {
return true;
}
}
return false;
}
// 将IP整数转换为字符串格式
private static String getIpAddress(int ipInt) {
return ((ipInt & 0xff000000) >> 24) + "." +
((ipInt & 0x00ff0000) >> 16) + "." +
((ipInt & 0x0000ff00) >> 8) + "." +
(ipInt & 0x000000ff);
}
public static void saveDataToFile(byte[] dataToSave, int dataSize, String fileName) {
OutputStream os = null;
try {
// 创建保存目录
File tempFile = new File("saveImg");
if (!tempFile.exists()) {
tempFile.mkdirs();
}
os = new FileOutputStream("saveImg/" + fileName);
os.write(dataToSave, 0, dataSize);
System.out.println("图像保存成功: " + fileName);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭文件流
try {
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 回调函数, 当扫码枪扫码后触发
private static void printImgCBInfo(byte[] pdata, MV_CODEREADER_IMAGE_OUT_INFO_EX2 stOutInfo) {
Main.pdata = pdata;
if (null == stOutInfo) {
System.out.println("stOutInfo is null");
return;
}
System.out.print("/**CBpstOutInfo***************************************/\n");
System.out.printf("获取一帧: nEventID[%d], nChannelID[%d], nWidth[%d], nHeight[%d], nFrameNum[%d], nTriggerIndex[%d], nFrameLen[%d], "
+ " nCodeNumber[%d] \r\n",
stOutInfo.nEventID, stOutInfo.nChannelID, stOutInfo.nWidth, stOutInfo.nHeight, stOutInfo.nFrameNum,
stOutInfo.nTriggerIndex, stOutInfo.nFrameLen, stOutInfo.pstCodeListEx.nCodeNum);
System.out.print("解码状态: bIsGetCode[" + stOutInfo.bIsGetCode + "]\r\n");
System.out.print("像素类型: MvCodeReaderGvspPixelType[" + stOutInfo.enPixelType + "]\r\n");
// 打印解码信息
for (int a = 0; a < stOutInfo.pstCodeListEx.nCodeNum; a++) {
org.json.JSONObject obj = new org.json.JSONObject();
obj.put("type", "scanMessage");
// 解析码中的数据用下划线分割第一个为物料类型第二个为物料id
String code = stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).chCode;
// String[] parts = code.split("__");
// if (parts.length >= 2) {
// String itemType = parts[0];
// String itemId = parts[1];
// obj.put("itemType", itemType);
// obj.put("itemId", itemId);
// } else {
// obj.put("rawCode", code);
// obj.put("error", "格式不正确");
// }
// 直接将解析出的数据返回到页面上
// WsServer.broadcast(code);
// 发送http请求存储信息
try {
String s = HttpRequestUtil.postJson("http://140.143.206.120:8080/wms/stockIoDetail", code);
System.out.println("返回值" + s);
System.out.println("明细记录创建成功" + code);
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.printf("解码信息: TheCodeID[%d], CodeString[%s], nCodeLen[%d], nAngle[%d], nBarType[%d],"
+ "sAlgoCost[%d], nIDRScore[%d], n1DIsGetQuality[%d]\r\n",
a, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).chCode, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nLen,
stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nAngle, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nBarType,
stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).sAlgoCost, stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).nIDRScore,
stOutInfo.pstCodeListEx.stBcrInfoEx.get(a).n1DIsGetQuality);
}
}
private static void PrintDeviceInfo(MV_CODEREADER_DEVICE_INFO stCamInfo) {
if (stCamInfo.nTLayerType == MvCodeReaderCtrlDefine.MV_CODEREADER_GIGE_DEVICE) {
System.out.print("IP地址: " + getIpAddress(stCamInfo.stGigEInfo.nCurrentIp) + "\r\n");
System.out.printf("设备信息: 自定义名称:[%s], 序列号:[%s], 型号:[%s] \r\n\r\n",
stCamInfo.stGigEInfo.chUserDefinedName,
stCamInfo.stGigEInfo.chSerialNumber,
stCamInfo.stGigEInfo.chModelName);
}
}
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
System.out.print(" ***************程序开始****************** \r\n"); System.out.print(" ***************程序开始****************** \r\n");
String strVersion = MvCodeReaderCtrl.MV_CODEREADER_GetSDKVersion(); lockEnglishInputMethod();
System.out.print("SDK版本: " + strVersion + "\r\n");
// 枚举所有设备 // 使用BufferedReader获取用户身份避免关闭System.in
allDevices = MvCodeReaderCtrl.MV_CODEREADER_EnumDevices(); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
if (allDevices == null || allDevices.isEmpty()) {
System.out.print("未发现任何设备!\r\n");
} else {
System.out.print("发现" + allDevices.size() + "个设备:\r\n");
for (MV_CODEREADER_DEVICE_INFO device : allDevices) {
PrintDeviceInfo(device);
}
}
ArrayList<Handle> handleList = new ArrayList<>();
// 尝试打开并启动所有发现的设备
for (int i = 0; i < allDevices.size(); i++) {
MV_CODEREADER_DEVICE_INFO camInfo = allDevices.get(i);
System.out.print("处理设备 " + i + ": " + camInfo.stGigEInfo.chSerialNumber + "\r\n");
Handle handle = null;
try {
handle = MvCodeReaderCtrl.MV_CODEREADER_CreateHandle(camInfo);
} catch (ParameterException e) {
System.out.print("创建句柄失败: " + e.getMessage() + "\r\n");
continue;
}
if (handle == null) {
System.out.print("创建句柄失败 for device " + i + "!\r\n");
continue;
}
int nRet = MvCodeReaderCtrl.MV_CODEREADER_OpenDevice(handle);
if (nRet != 0) {
System.out.print("打开设备失败 for device " + i + "! 错误码[" + String.format("0x%x", nRet) + "]\r\n");
continue;
}
nRet = MvCodeReaderCtrl.MV_CODEREADER_RegisterImageCallBackEx2(handle, new ImageCallBack() {
@Override
public int OnImageCallBack(byte[] pdata, MV_CODEREADER_IMAGE_OUT_INFO_EX2 stOutInfo) {
printImgCBInfo(pdata, stOutInfo);
return 0;
}
});
if (nRet != 0) {
System.out.print("注册回调失败 for device " + i + "! 错误码[" + String.format("0x%x", nRet) + "]\r\n");
MvCodeReaderCtrl.MV_CODEREADER_CloseDevice(handle);
continue;
}
nRet = MvCodeReaderCtrl.MV_CODEREADER_StartGrabbing(handle);
if (nRet != 0) {
System.out.print("启动抓取失败 for device " + i + "! 错误码[" + String.format("0x%x", nRet) + "]\r\n");
MvCodeReaderCtrl.MV_CODEREADER_CloseDevice(handle);
continue;
}
// 如果所有步骤都成功,添加到活跃设备列表
handleList.add(handle);
activeDevices.add(camInfo);
System.out.print("设备 " + i + " 启动成功,开始监听!\r\n");
}
System.out.println("所有设备处理完毕。活跃设备数量: " + activeDevices.size() + "\r\n");
http = new HttpRequestUtil();
System.out.println("http请求工具创建完成");
// 启动WebSocket服务器用于向前端推送设备列表和扫描结果
Server server = new Server("localhost", 9000, "/", null, WsServer.class);
try { try {
server.start(); System.out.print("请输入您的身份标识admin: ");
System.out.println("WebSocket服务器已启动端口9000"); userIdentity = reader.readLine().trim();
System.out.println("按Enter键退出程序..."); while (userIdentity.isEmpty()) {
System.in.read(); // 阻塞主线程直到回车 System.out.print("身份标识不能为空,请重新输入: ");
} catch (Exception e) { userIdentity = reader.readLine().trim();
System.out.println("WebSocket服务器错误: " + e.getMessage());
e.printStackTrace();
} finally {
// 停止所有设备
System.out.println("停止所有设备...");
for (Handle handle : handleList) {
MvCodeReaderCtrl.MV_CODEREADER_StopGrabbing(handle);
MvCodeReaderCtrl.MV_CODEREADER_CloseDevice(handle);
} }
server.stop(); System.out.println("已保存身份信息: " + userIdentity + "\n");
System.out.println("程序已退出"); } catch (IOException e) {
System.out.println("读取用户身份时出错: " + e.getMessage());
System.exit(1);
}
// 启动输入监听和数据处理线程
startRawInputListener();
startScanDataProcessor();
// 初始化HTTP请求工具
http = new HttpRequestUtil();
System.out.println("HTTP请求工具创建完成");
System.out.println("提示1. 使用扫码枪扫描JSON数据2. 输入 'exit' 并回车退出程序\n");
// 主线程阻塞直到isExit被标记为true
while (!isExit) {
Thread.sleep(100);
}
// 程序退出清理
System.out.println("\n开始停止所有服务...");
isExit = true;
System.out.println("程序已正常退出");
}
/**
* 输入监听线程:记录所有接收的字符
*/
private static void startRawInputListener() {
Thread inputThread = new Thread(() -> {
try {
int byteData;
while (!isExit && (byteData = System.in.read()) != -1) {
char c = (char) byteData;
// 打印每个接收的字符含ASCII值用于调试
System.out.printf("[接收字符] 内容: '%c' ASCII: %d%n",
(c == '\r' ? '\\' + 'r' : c == '\n' ? '\\' + 'n' : c),
(int) c);
inputQueue.put(c);
}
} catch (IOException e) {
if (!isExit) {
System.out.println("输入监听异常: " + e.getMessage());
e.printStackTrace();
}
} catch (InterruptedException e) {
System.out.println("输入监听线程被中断");
Thread.currentThread().interrupt();
}
});
inputThread.setDaemon(true);
inputThread.start();
}
/**
* 数据处理线程:通过回车符判断扫码结束
*/
private static void startScanDataProcessor() {
Thread processorThread = new Thread(() -> {
StringBuilder inputBuffer = new StringBuilder();
try {
while (!isExit) {
// 取出队列中的字符
char c = inputQueue.take();
int ascii = (int) c;
// 判断是否为结束符(回车或换行)
if (ascii == ENTER_ASCII || ascii == NEWLINE_ASCII) {
// 缓冲区不为空时才处理(避免空输入)
if (inputBuffer.length() > 0) {
String scanInput = inputBuffer.toString().trim();
System.out.println("===== 扫码原始数据(完整) =====");
System.out.println(scanInput);
System.out.println("================================\n");
// 检查退出命令
if ("exit".equalsIgnoreCase(scanInput)) {
isExit = true;
System.out.println("\n已接收到退出指令程序将关闭...");
break;
}
// 校验JSON格式
if (isValidJson(scanInput)) {
System.out.println("JSON格式校验通过开始处理...");
sendDataToServer(scanInput);
} else {
System.out.println("错误输入不是有效JSON格式\n");
}
// 清空缓冲区,准备下一次扫码
inputBuffer.setLength(0);
}
} else {
// 非结束符则添加到缓冲区
inputBuffer.append(c);
}
}
} catch (InterruptedException e) {
System.out.println("数据处理线程被中断");
Thread.currentThread().interrupt();
}
});
processorThread.setDaemon(true);
processorThread.start();
}
/**
* 校验字符串是否为有效JSON
*/
private static boolean isValidJson(String input) {
try {
new JSONObject(input);
return true;
} catch (JSONException e) {
System.out.println("JSON解析失败原因: " + e.getMessage());
return false;
} }
} }
public static byte[] getPdata() { /**
return pdata; * 锁定英文输入法Windows系统专用
*/
private static void lockEnglishInputMethod() {
try {
String powerShellCmd = "powershell -Command \"$im = Get-WinUserLanguageList | Where-Object LanguageTag -eq 'en-US'; " +
"if ($im) { Set-WinUserLanguageList -LanguageList $im -Force; Write-Host 'Success' }\"";
Process process = Runtime.getRuntime().exec(powerShellCmd);
process.waitFor();
if (process.exitValue() == 0) {
System.out.println("英文输入法已锁定en-US");
} else {
System.out.println("PowerShell切换输入法失败尝试备选方案Ctrl+空格)");
sendKeyStroke(0x11, 0x20);
}
} catch (Exception e) {
System.out.println("设置英文输入法异常: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 发送键盘组合键(用于输入法切换备选方案)
*/
private static void sendKeyStroke(int modifier, int key) {
try {
Robot robot = new Robot();
robot.keyPress(modifier);
robot.keyPress(key);
robot.keyRelease(key);
robot.keyRelease(modifier);
System.out.println("已尝试Ctrl+空格切换输入法");
} catch (AWTException e) {
System.out.println("发送键盘事件失败: " + e.getMessage());
}
}
/**
* 处理JSON数据并发送POST请求
*/
private static void sendDataToServer(String jsonInput) {
try {
JSONObject json = new JSONObject(jsonInput);
json.put("createBy", userIdentity);
String finalJson = json.toString(2);
System.out.println("最终发送的JSON数据: ");
System.out.println(finalJson + "\n");
// 取消注释以下代码以启用HTTP请求
String response = HttpRequestUtil.postJson(
"http://140.143.206.120:8080/wms/stockIoDetail",
finalJson
);
if (response == null || response.isEmpty()) {
System.out.println("服务器无响应,请检查接口连接\n");
} else {
System.out.println("服务器返回结果: ");
String formattedResponse = isJson(response) ? new JSONObject(response).toString(2) : response;
System.out.println(formattedResponse + "\n");
}
} catch (JSONException e) {
System.out.println("JSON处理异常: " + e.getMessage() + "\n");
} catch (Exception e) {
System.out.println("发送请求异常: " + e.getMessage() + "\n");
}
}
/**
* 判断字符串是否为JSON格式
*/
private static boolean isJson(String str) {
if (str == null || str.isEmpty()) return false;
str = str.trim();
return (str.startsWith("{") && str.endsWith("}")) || (str.startsWith("[") && str.endsWith("]"));
} }
} }

View File

@@ -18,13 +18,13 @@ public class WsServer {
sessions.add(session); sessions.add(session);
System.out.println("WebSocket连接已建立: " + session.getId()); System.out.println("WebSocket连接已建立: " + session.getId());
// 推送所有扫码枪列表给前端(使用修改后的方法名) // 推送所有扫码枪列表给前端(使用修改后的方法名)
String deviceListJson = Main.getAllDevicesJson(); // String deviceListJson = Main.getAllDevicesJson();
try { // try {
System.out.println("发送设备列表到前端: " + deviceListJson); // System.out.println("发送设备列表到前端: " + deviceListJson);
session.getBasicRemote().sendText(deviceListJson); // session.getBasicRemote().sendText(deviceListJson);
} catch (IOException e) { // } catch (IOException e) {
e.printStackTrace(); // e.printStackTrace();
} // }
} }
@OnMessage @OnMessage
@@ -32,8 +32,8 @@ public class WsServer {
System.out.println("收到消息: " + message); System.out.println("收到消息: " + message);
// 可以根据前端需求,在这里处理命令(比如刷新设备列表) // 可以根据前端需求,在这里处理命令(比如刷新设备列表)
if ("refreshDevices".equals(message)) { if ("refreshDevices".equals(message)) {
String deviceListJson = Main.getAllDevicesJson(); // String deviceListJson = Main.getAllDevicesJson();
session.getBasicRemote().sendText(deviceListJson); // session.getBasicRemote().sendText(deviceListJson);
} else { } else {
session.getBasicRemote().sendText("服务器已收到: " + message); session.getBasicRemote().sendText("服务器已收到: " + message);
} }