您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
基于淘宝买家订单导出插件做的增强版,添加自动记录、订单计数等功能
// ==UserScript== // @name 淘宝买家订单导出插件增强版 // @namespace http://tampermonkey.net/ // @version 0.7 // @description 基于淘宝买家订单导出插件做的增强版,添加自动记录、订单计数等功能 // @author kubrick // @include https://buyertrade.taobao.com/trade/itemlist* // @include https://buyertrade.taobao.com/trade/itemlist* // @require https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // 创建顶部控制栏容器 function createControlBar() { const existingBar = document.getElementById('orderExportControlBar'); if (existingBar) return existingBar; const controlBar = document.createElement('div'); controlBar.id = 'orderExportControlBar'; controlBar.style.position = 'fixed'; controlBar.style.top = '10px'; controlBar.style.right = '10px'; controlBar.style.zIndex = '9999'; controlBar.style.backgroundColor = 'rgba(255, 255, 255, 0.9)'; controlBar.style.padding = '10px'; controlBar.style.borderRadius = '10px'; controlBar.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.2)'; controlBar.style.display = 'flex'; controlBar.style.flexDirection = 'column'; controlBar.style.gap = '10px'; document.body.appendChild(controlBar); return controlBar; } // 添加圆角按钮 function addButton(container, onclickFunc, color, value = "按钮", width = "120px", height = "40px") { const button = document.createElement("button"); button.textContent = value; button.style.height = height; button.style.width = width; button.style.color = "white"; button.style.background = color; button.style.border = "none"; button.style.borderRadius = "20px"; button.style.cursor = "pointer"; button.style.fontWeight = "bold"; button.style.fontSize = "14px"; button.style.transition = "all 0.3s"; button.onmouseover = function() { button.style.opacity = "0.8"; button.style.transform = "scale(1.05)"; }; button.onmouseout = function() { button.style.opacity = "1"; button.style.transform = "scale(1)"; }; button.onclick = function() { onclickFunc(); }; container.appendChild(button); return button; } // 添加订单计数显示 function addOrderCountDisplay(container) { const countDisplay = document.createElement("div"); countDisplay.id = "orderCountDisplay"; countDisplay.style.padding = "8px 15px"; countDisplay.style.backgroundColor = "#f5f5f5"; countDisplay.style.borderRadius = "20px"; countDisplay.style.textAlign = "center"; countDisplay.style.fontWeight = "bold"; countDisplay.textContent = "当前订单数: 0"; container.appendChild(countDisplay); return countDisplay; } // 更新订单计数显示 function updateOrderCount() { const countDisplay = document.getElementById("orderCountDisplay"); if (countDisplay) { countDisplay.textContent = `当前订单数: ${Object.keys(orderList).length}`; } } // 主逻辑 const orderListPage = /(http|https):\/\/buyertrade\.taobao.*?\/trade/g; if (orderListPage.test(window.location.href)) { // 创建控制栏 const controlBar = createControlBar(); // 添加订单计数显示 addOrderCountDisplay(controlBar); // 添加按钮 addButton(controlBar, autoRecordAllOrders, "#FFA500", "自动记录所有订单"); addButton(controlBar, stopRecording, "#FF5252", "停止记录"); // 新增停止按钮 addButton(controlBar, addCurrentPageOrdersToList, "#1E90FF", "添加当页订单"); addButton(controlBar, exportOrders, "#4CAF50", "下载订单数据"); addButton(controlBar, cleanOrderList, "#FF5252", "清除订单"); // 添加状态提示 const statusDisplay = document.createElement("div"); statusDisplay.id = "recordStatus"; statusDisplay.style.padding = "5px"; statusDisplay.style.fontSize = "12px"; statusDisplay.style.color = "#666"; controlBar.appendChild(statusDisplay); } let isAutoRecording = false; let stopRecordingFlag = false; // 新增停止标志 let orderList = {}; // 自动记录所有订单 function autoRecordAllOrders() { if (isAutoRecording) { updateStatus("已经在自动记录中..."); return; } isAutoRecording = true; stopRecordingFlag = false; // 重置停止标志 updateStatus("开始自动记录所有订单..."); // 开始记录第一页 recordCurrentPageAndContinue(); } // 新增:停止记录功能 function stopRecording() { if (!isAutoRecording) { updateStatus("当前没有进行中的记录任务"); return; } stopRecordingFlag = true; updateStatus("正在停止记录..."); } // 更新状态显示 function updateStatus(message) { const statusDisplay = document.getElementById("recordStatus"); if (statusDisplay) { statusDisplay.textContent = message; } console.log(message); } // 记录当前页并继续下一页 function recordCurrentPageAndContinue() { // 检查是否收到停止信号 if (stopRecordingFlag) { finishAutoRecording(); updateStatus("已手动停止记录"); return; } const orders = document.getElementsByClassName("js-order-container"); // 检查是否有订单数据 if (!orders || orders.length === 0) { finishAutoRecording(); updateStatus("没有找到订单数据"); return; } let hasValidData = false; let currentPageCount = 0; for (let order of orders) { let items = processOrder(order, null); if (!items) { continue; } hasValidData = true; currentPageCount += Object.keys(items).length; _.forEach(items, (value, key) => { orderList[key] = value; }) } updateOrderCount(); updateStatus(`已记录当前页 ${currentPageCount} 条订单,总计 ${Object.keys(orderList).length} 条`); // 检查是否有下一页 const nextPageBtn = document.querySelector(".pagination-next:not(.disabled)"); if (nextPageBtn && hasValidData && !stopRecordingFlag) { updateStatus("正在翻到下一页..."); // 保存当前滚动位置 const scrollY = window.scrollY; // 点击下一页按钮 nextPageBtn.click(); // 等待页面加载完成后继续记录 setTimeout(() => { // 恢复滚动位置 window.scrollTo(0, scrollY); recordCurrentPageAndContinue(); }, 2000); } else { finishAutoRecording(); if (!hasValidData) { updateStatus("没有有效订单数据,自动停止"); } else if (!nextPageBtn) { updateStatus("已到达最后一页,记录完成"); } } } // 完成自动记录 function finishAutoRecording() { isAutoRecording = false; stopRecordingFlag = false; updateStatus(`记录完成! 共记录 ${Object.keys(orderList).length} 条订单`); } // 添加当前页面的订单到导出列表 function addCurrentPageOrdersToList() { const orders = document.getElementsByClassName("js-order-container"); let count = 0; for (let order of orders) { let items = processOrder(order, null); if (!items) { continue; } count += Object.keys(items).length; _.forEach(items, (value, key) => { orderList[key] = value; }) } updateOrderCount(); updateStatus(`已添加 ${count} 条订单,总计 ${Object.keys(orderList).length} 条`); } // 导出csv function toCsv(header, data, filename) { if (Object.keys(data).length === 0) { updateStatus("没有订单数据可导出"); return; } let rows = ""; let row = header.join(","); rows += row + "\n"; _.forEach(data, value => { rows += _.replace(value.join(","), '#', '@') + "\n"; }) let blob = new Blob(["\ufeff" + rows], { type: 'text/csv;charset=utf-8;' }); let encodedUrl = URL.createObjectURL(blob); let url = document.createElement("a"); url.setAttribute("href", encodedUrl); url.setAttribute("download", filename + ".csv"); document.body.appendChild(url); url.click(); document.body.removeChild(url); updateStatus(`已导出 ${Object.keys(data).length} 条订单数据`); } function exportOrders() { const header = ["订单号", "下单日期", "商品明细", "商品链接", "单价", "数量", "实付款", "状态"]; toCsv(header, orderList, "淘宝订单导出_" + new Date().toLocaleDateString()); } // 清空订单 function cleanOrderList() { let count = Object.keys(orderList).length; orderList = {}; updateOrderCount(); updateStatus(`已清除 ${count} 条订单记录`); } // 处理订单-获取订单的详细信息 function processOrder(order, time) { let outputData = {}; let textContent = order.textContent; let pattern = /(\d{4}-\d{2}-\d{2})订单号: ()/; let isExist = pattern.exec(textContent); let insuranceText = "保险服务"; if (!isExist) { return null; } const date = isExist[1]; const id = order.querySelector("div[data-id]")?.getAttribute("data-id"); if (!id) return null; let index = 0; if (time != undefined && time != null) { if (date != time) { if (date < time) { return null; } return null; } } let productQuery = order.querySelector("span[data-reactid='.0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$0.0.1.0.0.1']"); let priceQuery = order.querySelector("span[data-reactid='.0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$1.0.1.1']"); let countQuery = order.querySelector("p[data-reactid='.0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$2.0.0']"); let actualPayQuery = order.querySelector("span[data-reactid='.0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$4.0.0.2.0.1']"); let itemUrlQuery = order.querySelector("a[href]"); if (!productQuery || productQuery.textContent == insuranceText) { return null; } let price = priceQuery?.textContent || "0"; let count = countQuery?.textContent || "1"; let actualPay = actualPayQuery?.textContent || "0"; let orderStatus = ""; if (index === 0) { let statusQuery = order.querySelector("span[data-reactid='.0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$5.0.0.0']"); orderStatus = statusQuery?.textContent || ""; } let itemUrl = itemUrlQuery?.href || ""; outputData[id + index] = [ id, date, productQuery.textContent.replace(/,/g, ","), itemUrl, parseFloat(price), count, actualPay, orderStatus, ]; return outputData; } })();