// ==UserScript== // @name 发票数据自动填充(支持TXT导入/粘贴+持久化) // @namespace http://tampermonkey.net/ // @version 1.2 // @description 从TXT文件或粘贴文本导入数据,自动保存进度 // @match https://inv-veri.chinatax.gov.cn/* // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function() { // 全局变量 let invoicesArray = []; let currentIndex = 0; let statusSpan; let nextBtn, prevBtn; // 初始化UI界面 function initUI() { const uiDiv = document.createElement('div'); uiDiv.style.cssText = ` position: fixed; bottom: 10px; right: 10px; background: #fff; padding: 8px; border: 1px solid #ccc; z-index: 9999; font-family: Arial, sans-serif; width: 260px; font-size: 12px; `; // 创建按钮样式 const buttonStyle = ` padding: 3px 8px; margin: 2px; font-size: 12px; line-height: 1.2; `; // 文件上传区域 const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.accept = '.txt'; fileInput.style.marginBottom = '10px'; // 文本粘贴区域 const pasteArea = document.createElement('textarea'); pasteArea.placeholder = '或直接粘贴发票数据(每行一个)...'; pasteArea.style.width = '100%'; pasteArea.style.height = '40px'; pasteArea.style.marginBottom = '10px'; // 操作按钮 const loadBtn = document.createElement('button'); loadBtn.textContent = '加载数据'; loadBtn.style.cssText = buttonStyle; const clearBtn = document.createElement('button'); clearBtn.textContent = '清空数据'; clearBtn.style.cssText = buttonStyle; // 翻页控制区域 const navDiv = document.createElement('div'); navDiv.style.marginTop = '10px'; prevBtn = document.createElement('button'); prevBtn.textContent = '上一条 (P)'; prevBtn.style.cssText = buttonStyle; nextBtn = document.createElement('button'); nextBtn.textContent = '下一条 (Z)'; nextBtn.style.cssText = buttonStyle; statusSpan = document.createElement('span'); statusSpan.style.margin = '0 10px'; // 组装UI组件 uiDiv.appendChild(fileInput); uiDiv.appendChild(pasteArea); uiDiv.appendChild(document.createElement('br')); uiDiv.appendChild(loadBtn); uiDiv.appendChild(clearBtn); navDiv.appendChild(prevBtn); navDiv.appendChild(statusSpan); navDiv.appendChild(nextBtn); uiDiv.appendChild(navDiv); document.body.appendChild(uiDiv); return { fileInput, pasteArea, loadBtn, clearBtn }; } // 保存数据到本地存储 function saveData() { localStorage.setItem('invoiceData', JSON.stringify({ data: invoicesArray, index: currentIndex })); } // 填充输入框 function fillInput(index) { const input = document.querySelector('#fpdm'); if (!input) return alert('错误:未找到发票代码输入框!'); input.value = invoicesArray[index]; input.dispatchEvent(new Event('input', { bubbles: true })); updateStatus(); saveData(); } // 更新状态显示 function updateStatus() { statusSpan.textContent = `${currentIndex + 1}/${invoicesArray.length}`; } // 加载上一条数据 function loadPrevious() { if (currentIndex > 0) { currentIndex--; fillInput(currentIndex); } else { alert('已经是第一条数据!'); } } // 加载下一条数据 function loadNext() { if (currentIndex < invoicesArray.length - 1) { currentIndex++; fillInput(currentIndex); } else { alert('已经是最后一条数据!'); } } // 加载数据(从文件或粘贴文本) function loadData(source, content) { if (!content) return alert('错误:数据为空!'); invoicesArray = content.split('\n') .map(line => line.trim()) .filter(line => line.length > 0); if (invoicesArray.length === 0) { return alert('错误:未找到有效数据!'); } currentIndex = 0; fillInput(currentIndex); } // 主函数 function main() { const { fileInput, pasteArea, loadBtn, clearBtn } = initUI(); // 设置快捷键监听 document.addEventListener('keydown', (e) => { if (!e.ctrlKey && !e.shiftKey && e.altKey) { if (e.key.toLowerCase() === 'p') loadPrevious(); if (e.key.toLowerCase() === 'z') loadNext(); } }); // 绑定按钮事件 prevBtn.addEventListener('click', loadPrevious); nextBtn.addEventListener('click', loadNext); loadBtn.addEventListener('click', () => { if (pasteArea.value.trim()) { loadData('paste', pasteArea.value.trim()); } else if (fileInput.files[0]) { fileInput.files[0].text().then(content => { loadData('file', content); }); } else { alert('请先上传文件或粘贴文本!'); } }); clearBtn.addEventListener('click', () => { invoicesArray = []; currentIndex = 0; localStorage.removeItem('invoiceData'); statusSpan.textContent = '未加载数据'; pasteArea.value = ''; fileInput.value = ''; }); // 尝试加载本地存储的数据 const savedData = localStorage.getItem('invoiceData'); if (savedData) { try { const { data, index } = JSON.parse(savedData); invoicesArray = data; currentIndex = index; updateStatus(); } catch (e) { console.error('加载本地数据失败:', e); } } else { statusSpan.textContent = '未加载数据'; } } // 页面加载完成后执行 if (document.readyState === 'complete') { main(); } else { document.addEventListener('DOMContentLoaded', main); } })();