// ==UserScript==
// @name 聚水潭商品打印+
// @namespace http://tampermonkey.net/
// @version 4.2
// @description ☑️辅助码;☑️扫码直接打印;☑️查看库存及订单信息;🖱设置焦点到输入框
// @author ShiShiBits
// @match https://www.erp321.com/app/wms/print/V2/SkuPrintNV.aspx
// @grant none
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
// ================= 专业配置 =================
const CONFIG = {
// 复选框配置
checkboxes: [
{ selector: '#skuInputPrint', expected: true },
{ selector: '#printMode', expected: true },
{ selector: '#sku_id', expected: false },
{ selector: '#multi_other_code', expected: true }
],
// 输入框配置
inputs: [
{ selector: '#multiSearchCode', needFocus: true }
],
// 系统参数
maxRetry: 30, // 最大重试次数
checkInterval: 400, // 检查间隔(ms)
delay: 150 // 操作延迟(ms)
};
// ================= 状态管理器 =================
let retryCount = 0;
const successMap = new Map();
const focusMap = new Map();
// ================= 核心控制引擎 =================
const FormController = {
init() {
this.setupObserver();
this.initialCheck();
this.startRetryMechanism();
},
setupObserver() {
new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.type === 'childList') {
this.handleNewNodes(mutation.addedNodes);
}
});
}).observe(document, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['id', 'checked', 'class']
});
},
initialCheck() {
setTimeout(() => {
this.batchCheck();
this.processInputs();
}, CONFIG.delay * 2);
},
batchCheck() {
CONFIG.checkboxes.forEach(config => {
if (!successMap.get(config.selector)) {
this.processCheckbox(config);
}
});
},
processInputs() {
CONFIG.inputs.forEach(inputConfig => {
if (!focusMap.get(inputConfig.selector)) {
this.focusInput(inputConfig);
}
});
},
handleNewNodes(nodes) {
nodes.forEach(node => {
if (node.nodeType === 1) {
// 处理复选框
CONFIG.checkboxes.forEach(config => {
if (node.matches(config.selector)) {
this.processCheckbox(config);
}
});
// 处理输入框
CONFIG.inputs.forEach(inputConfig => {
if (node.matches(inputConfig.selector)) {
this.focusInput(inputConfig);
}
});
}
});
},
// ======== 修复的复选框处理逻辑 ========
processCheckbox(config) {
try {
const { selector, expected } = config;
const checkbox = document.querySelector(selector);
// 元素存在性验证
if (!checkbox) {
successMap.set(selector, false);
return;
}
// 状态验证
if (checkbox.checked === expected) {
if (!successMap.get(selector)) {
console.log(`[CHECKBOX] ${selector} 状态已正确`);
successMap.set(selector, true);
}
return;
}
// 执行操作流程
this.triggerNativeAction(checkbox, expected);
this.scheduleStateUpdate(checkbox, expected);
this.finalVerification(checkbox, config);
} catch (error) {
console.error(`[ERROR] 处理 ${config.selector} 时发生异常:`, error);
successMap.set(config.selector, false);
}
},
triggerNativeAction(checkbox, expected) {
// 确保状态变化
if (checkbox.checked !== expected) {
checkbox.click();
}
// 触发必要事件
['click', 'change', 'input'].forEach(type => {
checkbox.dispatchEvent(new Event(type, { bubbles: true }));
});
},
scheduleStateUpdate(checkbox, expected) {
setTimeout(() => {
if (checkbox.checked !== expected) {
checkbox.checked = expected;
this.triggerFrameworkEvents(checkbox);
}
}, CONFIG.delay);
},
triggerFrameworkEvents(checkbox) {
// React支持
const reactProps = Object.keys(checkbox).find(k => k.startsWith('__reactProps'));
if (reactProps?.onChange) {
const event = new Event('change', { bubbles: true });
Object.defineProperty(event, 'target', { value: checkbox });
reactProps.onChange(event);
}
// Vue支持
const vueProps = Object.keys(checkbox).find(k => k.startsWith('__vue__'));
if (vueProps?.$emit) {
vueProps.$emit('input', checkbox.checked);
vueProps.$emit('change', checkbox.checked);
}
},
finalVerification(checkbox, config) {
setTimeout(() => {
const success = checkbox.checked === config.expected;
successMap.set(config.selector, success);
console.log(`[CHECKBOX] ${config.selector}: ${success ? '成功 ✔️' : '失败 ✖️'}`);
// 失败时自动重试
if (!success && retryCount < CONFIG.maxRetry) {
this.processCheckbox(config);
}
}, CONFIG.delay * 2);
},
// 输入框聚焦方法
focusInput(inputConfig) {
try {
const { selector, needFocus } = inputConfig;
if (!needFocus) return;
const input = document.querySelector(selector);
if (!input) return;
input.focus({ preventScroll: true });
this.triggerFrameworkEvents(input);
focusMap.set(selector, true);
console.log(`[FOCUS] ${selector} 聚焦成功`);
// 修复方法调用方式
this.addFocusProtection(input);
} catch (error) {
console.error(`[FOCUS-ERROR] ${inputConfig.selector} 处理异常:`, error);
}
},
// 新增焦点保护方法 (修复位置)
addFocusProtection(input) {
// 保存原始方法引用
const originalBlur = input.blur.bind(input);
// 重写blur方法
input.blur = (...args) => {
console.log('[FOCUS-PROTECT] 检测到失焦操作');
// 取消默认行为
// return false;
return originalBlur(...args);
};
// 使用箭头函数保持this指向
const checkFocus = () => {
if (document.activeElement !== input) {
console.log('[FOCUS-CHECK] 重新聚焦输入框');
input.focus({ preventScroll: true });
}
};
// 添加自动重聚焦定时器
let checkCount = 0;
const timer = setInterval(() => {
if (checkCount++ < 5) {
checkFocus();
} else {
clearInterval(timer);
console.log('[FOCUS-PROTECT] 结束自动聚焦保护');
input.blur = originalBlur; // 恢复原始方法
}
}, 2000);
},
startRetryMechanism() {
const timer = setInterval(() => {
if (retryCount++ < CONFIG.maxRetry) {
this.batchCheck();
this.processInputs();
} else {
clearInterval(timer);
console.log('[SYSTEM] 终止重试,最终状态:', {
checkboxes: Array.from(successMap),
inputs: Array.from(focusMap)
});
}
}, CONFIG.checkInterval);
}
};
// ================= 启动系统 =================
FormController.init();
})();