This commit is contained in:
2026-02-10 14:02:36 +08:00
parent 887aa55930
commit ebdc516a55
7 changed files with 133 additions and 16 deletions

View File

@@ -16,6 +16,8 @@
</style>
<script src="/iframe/js/xlsx.full.min.js" language="JavaScript"></script>
<script src="/iframe/js/jsQR.min.js" language="JavaScript"></script>
<script src="/iframe/js/qrcode.min.js" language="JavaScript"></script>
<script src="/iframe/js/mqtt.min.js" language="JavaScript"></script>
</head>
<body class="bg-gray-100 font-sans text-sm">
<div id="fixed-window" class="bg-gray-50 flex flex-col overflow-hidden mx-auto">
@@ -124,6 +126,8 @@
let importList = [];
let videoStream = null;
let currentScanData = null;
let mqttClient = null;
const myDeviceId = Math.random().toString(36).substring(2, 10);
function renderList() {
if (importList.length === 0) {
@@ -156,9 +160,12 @@
try {
const devices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = devices.filter(device => device.kind === 'videoinput');
cameraSelect.innerHTML = videoDevices.map(d =>
let options = videoDevices.map(d =>
`<option value="${d.deviceId}">${d.label || '摄像头 ' + d.deviceId.slice(0, 5)}</option>`
).join('');
options += `<option value="WEBSOCKET_MODE">WebSocket 远程扫码</option>`;
cameraSelect.innerHTML = options;
} catch (e) {
eda.sys_Message.showToastMessage('无法获取摄像头列表: ' + e.message, ESYS_ToastMessageType.ERROR);
}
@@ -168,11 +175,12 @@
stopCamera();
qrDialog.classList.add('hidden');
document.getElementById('res-cid').textContent = currentScanData.lcscId;
document.getElementById('res-pm').textContent = currentScanData.name;
document.getElementById('res-qty').textContent = currentScanData.quantity;
currentScanData = null;
if (currentScanData) {
document.getElementById('res-cid').textContent = currentScanData.lcscId;
document.getElementById('res-pm').textContent = currentScanData.name;
document.getElementById('res-qty').textContent = currentScanData.quantity;
currentScanData = null;
}
};
function stopCamera() {
@@ -180,16 +188,68 @@
videoStream.getTracks().forEach(track => track.stop());
videoStream = null;
}
qrVideo.parentElement.classList.remove('scanning');
if (mqttClient) {
console.log("正在断开 MQTT 远程连接...");
mqttClient.end(true); // 强制关闭连接
mqttClient = null;
}
qrVideo.style.display = 'block';
const oldQr = document.getElementById('remote-qr-canvas');
if (oldQr) oldQr.remove();
if(qrVideo.parentElement) {
qrVideo.parentElement.classList.remove('scanning');
}
}
document.getElementById('btn-start-camera').onclick = async () => {
stopCamera();
const deviceId = cameraSelect.value;
async function startRemoteMode() {
if (mqttClient) {
mqttClient.end(true);
}
const broker = 'wss://test.mosquitto.org:8081';
const topic = `leye/scan/${myDeviceId}`;
mqttClient = mqtt.connect(broker);
mqttClient.on('connect', () => {
mqttClient.subscribe(topic);
eda.sys_Message.showToastMessage('MQTT 远程模式启动', ESYS_ToastMessageType.SUCCESS);
const scanUrl = `https://leye.dragon.edu.kg/scan.html?id=${myDeviceId}`;
qrVideo.style.display = 'none';
let qrCanvas = document.getElementById('remote-qr-canvas') || createQrCanvas();
QRCode.toCanvas(qrCanvas, scanUrl, { width: 250 });
});
mqttClient.on('message', (t, message) => {
try {
const msg = JSON.parse(message.toString());
if (msg.type === 'SCAN_RESULT') {
parseQrData(msg.content);
eda.sys_Message.showToastMessage('远程扫码成功', ESYS_ToastMessageType.INFO);
}
} catch (e) {
console.error("MQTT数据解析失败", e);
}
});
}
function createQrCanvas() {
const canvas = document.createElement('canvas');
canvas.id = 'remote-qr-canvas';
canvas.className = "absolute inset-0 w-full h-full p-4 bg-white";
qrVideo.parentElement.appendChild(canvas);
return canvas;
}
async function startLocalCamera(deviceId) {
const constraints = {
video: deviceId ? { deviceId: { exact: deviceId } } : { facingMode: 'environment' }
};
try {
videoStream = await navigator.mediaDevices.getUserMedia(constraints);
qrVideo.srcObject = videoStream;
@@ -199,6 +259,17 @@
} catch (e) {
eda.sys_Message.showToastMessage('启动摄像头失败', ESYS_ToastMessageType.ERROR);
}
}
document.getElementById('btn-start-camera').onclick = async () => {
stopCamera();
const mode = cameraSelect.value;
if (mode === "WEBSOCKET_MODE") {
startRemoteMode();
} else {
startLocalCamera(mode);
}
};
document.getElementById('btn-scan').onclick = () => {
@@ -429,7 +500,6 @@
let successCount = 0;
let failCount = 0;
const SERVER = await eda.sys_Storage.getExtensionUserConfig('server-host') || 'http://localhost:21816';
for (const item of toSave) {
try {