1.0.6
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user