(function () { var reader = new ReaderClient(); var pollingTimer = null; var isReading = false; var isConnecting = false; var lastUid = ""; var seenUids = new Map(); function getEl(id) { return document.getElementById(id); } function getValue(id, fallback) { var el = getEl(id); if (!el || el.value == null || el.value === "") { return fallback; } return String(el.value).trim(); } function setStatus(text, color) { var statusEl = getEl("readerStatusTag"); if (!statusEl) return; statusEl.textContent = text; statusEl.style.color = color || "#64748b"; } function showConnectButton(show) { var button = getEl("btnConnect"); if (!button) return; button.style.display = show ? "inline-flex" : "none"; } function normalizeHexKey(value) { return String(value || "") .trim() .toUpperCase() .replace(/[^0-9A-F]/g, ""); } function applyReaderConfig() { reader.wsUrl = getValue("wsUrlText", "ws://127.0.0.1:6689"); reader.keyType = getValue("keyTypeInput", "0"); reader.key = normalizeHexKey(getValue("keyInput", "FFFFFFFFFFFF")); reader.blockAddress = getValue("blockAddressInput", "1"); reader.numberOfBlocksRead = getValue("numberOfBlocksReadInput", "1"); reader.readDataType = getValue("readDataTypeInput", "0"); reader.readSecurityStatus = getValue("readSecurityStatusInput", "0"); reader.iso15693BlockAddress = getValue("iso15693BlockAddressInput", "0"); reader.iso15693NumberOfBlocks = getValue("iso15693NumberOfBlocksInput", "7"); } function getDedupeMode() { return getValue("dedupeMode", "session"); } function getDedupeTimeMs() { var raw = getValue("dedupeTime", "5000"); var timeMs = parseInt(raw, 10); if (!timeMs || timeMs < 0) { return 5000; } return timeMs; } function clearDedupeHistory() { seenUids.clear(); lastUid = ""; } function checkDuplicate(uid) { var dedupeMode = getDedupeMode(); if (dedupeMode === "none") { return { isDup: false }; } if (dedupeMode === "session") { if (seenUids.has(uid)) { return { isDup: true }; } return { isDup: false }; } if (dedupeMode === "time") { var info = seenUids.get(uid); var dedupeTimeMs = getDedupeTimeMs(); if (info && Date.now() - info.time < dedupeTimeMs) { return { isDup: true }; } return { isDup: false }; } return { isDup: false }; } function recordUid(uid, protocol) { seenUids.set(uid, { protocol: protocol, time: Date.now() }); } // 功能说明:通过桥接 API 写入 Vue data,兼容 ss-inp 组件并触发联动查询 by xu 20260416 function setNfcValue(uid) { if (typeof window.ss && typeof window.ss.dom && typeof window.ss.dom.set === "function") { window.ss.dom.set('kah', uid); } if (typeof window.selBaseInfoByKah === "function") { window.selBaseInfoByKah(uid); } } function stopPolling() { if (pollingTimer) { clearInterval(pollingTimer); pollingTimer = null; } isReading = false; } function handleDisconnect(message) { stopPolling(); clearDedupeHistory(); reader.connected = false; reader.handle = null; setStatus(message || "读卡器未连接", "#ef4444"); showConnectButton(true); } async function readUidBothProtocols() { var protocols = ["ISO14443A", "ISO15693"]; for (var i = 0; i < protocols.length; i++) { try { var uid = await reader.readUid(protocols[i]); if (uid) { return { uid: uid, protocol: protocols[i] }; } } catch (err) { var msg = err && err.message ? err.message : String(err || ""); if ( msg.indexOf("未读取到 UID") === -1 && msg.indexOf("标签已到读卡位") === -1 && msg.indexOf("卡片已到读卡位") === -1 ) { throw err; } } } return null; } async function pollOnce() { if (isReading || !reader.connected) { return; } isReading = true; try { applyReaderConfig(); var result = await readUidBothProtocols(); if (result && result.uid) { var dupCheck = checkDuplicate(result.uid); if (dupCheck.isDup) { return; } recordUid(result.uid, result.protocol); lastUid = result.uid; setNfcValue(result.uid); } } catch (err) { var msg = err && err.message ? err.message : "读卡失败"; if (msg.indexOf("连接") !== -1 || msg.indexOf("断开") !== -1 || msg.indexOf("超时") !== -1) { handleDisconnect("读卡器连接已断开"); } } finally { isReading = false; } } function startPolling() { if (pollingTimer || !reader.connected) { return; } var interval = parseInt(getValue("pollingInterval", "1000"), 10); if (!interval || interval < 100) { interval = 1000; } pollOnce(); pollingTimer = setInterval(pollOnce, interval); } async function connectReader(isManual) { if (isConnecting) { return; } isConnecting = true; setStatus("读卡器连接中...", "#64748b"); showConnectButton(false); try { applyReaderConfig(); clearDedupeHistory(); await reader.selectDevice(); setStatus("读卡器连接成功", "#16a34a"); showConnectButton(false); startPolling(); } catch (err) { stopPolling(); var msg = err && err.message ? err.message : "读卡器连接失败"; setStatus(msg, "#ef4444"); showConnectButton(true); if (isManual) { alert(msg); } } finally { isConnecting = false; } } function bindEvents() { var button = getEl("btnConnect"); if (button) { button.addEventListener("click", function () { connectReader(true); }); } var dedupeModeEl = getEl("dedupeMode"); if (dedupeModeEl) { dedupeModeEl.addEventListener("change", function () { clearDedupeHistory(); }); } } function init() { bindEvents(); setStatus("读卡器连接中...", "#64748b"); showConnectButton(false); connectReader(false); } window.addEventListener("load", init); })();