// ==UserScript== // @name 多功能复制工具 - 订单/标题/表格/JSON // @namespace https://github.com/你的github用户名 或 http://tampermonkey.net/ // @version 1.0 // @description Tampermonkey 菜单提供多个复制功能:订单编号、页面标题、.stat-value 值、bootstrap-table 表格数据(排除首尾列,支持 tab 分隔和 JSON 格式) // @author lanbinbin // @match *://*/* // @icon https://www.google.com/s2/favicons?sz=64&domain=grok.com // @grant GM_registerMenuCommand // @grant GM_setClipboard // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/565111/%E5%A4%9A%E5%8A%9F%E8%83%BD%E5%A4%8D%E5%88%B6%E5%B7%A5%E5%85%B7%20-%20%E8%AE%A2%E5%8D%95%E6%A0%87%E9%A2%98%E8%A1%A8%E6%A0%BCJSON.user.js // @updateURL https://update.greasyfork.icu/scripts/565111/%E5%A4%9A%E5%8A%9F%E8%83%BD%E5%A4%8D%E5%88%B6%E5%B7%A5%E5%85%B7%20-%20%E8%AE%A2%E5%8D%95%E6%A0%87%E9%A2%98%E8%A1%A8%E6%A0%BCJSON.meta.js // ==/UserScript== (function() { 'use strict'; // 原有的功能:复制订单编号 GM_registerMenuCommand("复制订单编号", function() { // 你原本的复制订单编号的代码 // 例如: let orderNo = document.querySelector('#order-id')?.textContent || ''; if (orderNo) { GM_setClipboard(orderNo.trim()); alert('已复制订单编号:' + orderNo); } else { alert('找不到订单编号'); } },"o"); // 新增的功能:复制页面标题 GM_registerMenuCommand("复制标题", function() { const title = document.title.trim(); console.log(title); GM_setClipboard(title); alert('已复制页面标题:\n' + title); },"t"); GM_registerMenuCommand("复制所有 stat-value", () => { const elements = document.querySelectorAll('.stat-value'); if (elements.length === 0) { alert('没有找到任何 class="stat-value"'); return; } // 把所有内容用换行符拼接 const allValues = Array.from(elements) .map(el => el.textContent.trim()) .filter(text => text.length > 0) .join('\n'); GM_setClipboard(allValues); alert(`已复制 ${elements.length} 条内容到剪贴板:\n\n${allValues}`); },"y"); GM_registerMenuCommand('复制表格数据(排除操作列)', () => { const tableId = 'bootstrap-table'; const maxWaitSeconds = 12; // 最多等待 12 秒 const checkInterval = 400; // 每 400ms 检查一次 let attempts = 0; const maxAttempts = Math.floor(maxWaitSeconds * 1000 / checkInterval); function tryCopyTable() { attempts++; const table = document.getElementById(tableId); if (!table) { if (attempts >= maxAttempts) { alert(`未找到 id="${tableId}" 的表格`); return; } setTimeout(tryCopyTable, checkInterval); return; } // 优先找 tbody 里的行 let rows = table.querySelectorAll('tbody tr'); // 如果 tbody 里没行,尝试找所有不含 th 的 tr if (rows.length === 0) { rows = table.querySelectorAll('tr:not(:has(th))'); } // 还没有数据行,继续等待 if (rows.length === 0) { if (attempts >= maxAttempts) { alert('表格中没有找到任何数据行(已等待足够时间)'); return; } setTimeout(tryCopyTable, checkInterval); return; } // 开始处理数据 const result = []; rows.forEach(row => { // 获取所有 td const cells = row.querySelectorAll('td'); // 如果这一行没有 td,或者 td 数量太少,跳过 if (cells.length <= 1) return; // 去掉最后一列(操作列) const dataCells = Array.from(cells).slice(0, -1); // 提取文本 const rowData = dataCells .map(cell => { // 优先使用 data-value 属性(bootstrap-table 常用) let text = cell.getAttribute('data-value') || cell.textContent; text = (text || '').trim().replace(/\s+/g, ' '); return text; }) .filter(text => text.length > 0) .join('\t'); if (rowData.trim()) { result.push(rowData); } }); if (result.length === 0) { alert('没有提取到任何有效数据'); return; } const textToCopy = result.join('\n'); GM_setClipboard(textToCopy); alert(`已复制 ${result.length} 行数据(已排除最后一列)\n可粘贴到 Excel 或文本编辑器`); console.log('复制的内容:\n' + textToCopy); } // 开始执行 tryCopyTable(); },"i"); GM_registerMenuCommand('复制表格为 JSON', () => { const tableId = 'bootstrap-table'; const maxWaitSeconds = 12; const checkInterval = 400; let attempts = 0; const maxAttempts = Math.floor(maxWaitSeconds * 1000 / checkInterval); function tryExtractAndCopy() { attempts++; const table = document.getElementById(tableId); if (!table) { if (attempts >= maxAttempts) { alert(`未找到 id="${tableId}" 的表格`); return; } setTimeout(tryExtractAndCopy, checkInterval); return; } // 尝试获取表头 const thead = table.querySelector('thead'); let headers = []; if (thead) { const headerCells = thead.querySelectorAll('th'); headers = Array.from(headerCells) .slice(0, -1) // 排除最后一列(操作列) .map(th => { let text = th.textContent.trim(); // 清理不适合做 key 的字符 text = text.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '_'); return text || `col${headers.length + 1}`; }); } // 如果没有表头或表头为空,使用默认列名 if (headers.length === 0) { // 可以在这里设置默认列名,或者等看到第一行有多少列再决定 headers = Array(10).fill().map((_, i) => `col${i + 1}`); } // 获取数据行 let rows = table.querySelectorAll('tbody tr'); if (rows.length === 0) { rows = table.querySelectorAll('tr:not(:has(th))'); } if (rows.length === 0) { if (attempts >= maxAttempts) { alert('表格中没有找到任何数据行'); return; } setTimeout(tryExtractAndCopy, checkInterval); return; } // 开始收集数据 const data = []; rows.forEach(row => { const cells = row.querySelectorAll('td'); if (cells.length <= 1) return; // 排除最后一列 const dataCells = Array.from(cells).slice(0, -1); const rowObj = {}; dataCells.forEach((cell, index) => { let value = cell.getAttribute('data-value') || cell.textContent.trim(); value = value.replace(/\s+/g, ' '); // 如果值看起来像数字,尝试转为 number if (/^-?\d+(\.\d+)?$/.test(value)) { value = parseFloat(value); } const key = headers[index] || `col${index + 1}`; rowObj[key] = value; }); data.push(rowObj); }); if (data.length === 0) { alert('没有提取到任何有效数据'); return; } // 转为美观的 JSON 字符串 const jsonString = JSON.stringify(data, null, 2); // 复制到剪贴板 GM_setClipboard(jsonString); alert(`已复制 ${data.length} 条记录的 JSON 数据到剪贴板\n(可粘贴到编辑器查看)`); // 在控制台也输出,便于调试 console.log('已复制的 JSON 数据:'); console.log(jsonString); } // 开始执行 tryExtractAndCopy(); },"a"); GM_registerMenuCommand('复制表格为 JSON (col1/col2)', () => { const tableId = 'bootstrap-table'; const maxWaitSeconds = 12; const checkInterval = 400; let attempts = 0; const maxAttempts = Math.floor(maxWaitSeconds * 1000 / checkInterval); function tryExtractAndCopy() { attempts++; const table = document.getElementById(tableId); if (!table) { if (attempts >= maxAttempts) { alert(`未找到 id="${tableId}" 的表格`); return; } setTimeout(tryExtractAndCopy, checkInterval); return; } // 获取数据行 let rows = table.querySelectorAll('tbody tr'); if (rows.length === 0) { rows = table.querySelectorAll('tr:not(:has(th))'); } if (rows.length === 0) { if (attempts >= maxAttempts) { alert('表格中没有找到任何数据行'); return; } setTimeout(tryExtractAndCopy, checkInterval); return; } // 收集数据 const data = []; rows.forEach(row => { const cells = row.querySelectorAll('td'); // 至少要有 3 列才处理(去掉首尾后至少剩 1 列才有意义) if (cells.length < 3) return; // 去掉第一列和最后一列 const dataCells = Array.from(cells).slice(1, -1); const rowObj = {}; dataCells.forEach((cell, index) => { let value = cell.getAttribute('data-value') || cell.textContent.trim(); value = value.replace(/\s+/g, ' '); // 尝试转为数字(可选,根据你的数据决定是否保留) if (/^-?\d+(\.\d+)?$/.test(value)) { value = parseFloat(value); } else if (/^\d{4}-\d{2}-\d{2}/.test(value)) { // 日期格式保持字符串 value = value; } // key 使用 col1, col2, col3 ... const key = `col${index + 1}`; rowObj[key] = value; }); // 只有当有实际数据时才加入 if (Object.keys(rowObj).length > 0) { data.push(rowObj); } }); if (data.length === 0) { alert('没有提取到任何有效数据'); return; } // 转为格式化的 JSON const jsonString = JSON.stringify(data, null, 2); // 复制到剪贴板 GM_setClipboard(jsonString); alert(`已复制 ${data.length} 条记录(JSON 格式,key 为 col1/col2...)`); // 在控制台输出查看 console.log('已复制的 JSON 数据:'); console.log(jsonString); } // 开始执行 tryExtractAndCopy(); },"b"); })();