// ==UserScript== // @name 闲管家一键上架助手 // @namespace http://tampermonkey.net/ // @version 1.31 // @description 在商品页面复制商品信息并在闲鱼管家后台上架页面插入“一键填充”按钮,添加下载商品详情图片的功能。包括选品功能,可在闲鱼商详页导出猜你喜欢的数据到Excel,支持动态数据 // @author 九旬 wx:728396024 mail:728396024@qq.com // @match https://h5.m.goofish.com/item?id=* // @match https://www.goofish.com/item* // @match https://goofish.pro/* // @match https://www.goofish.pro/* // @icon https://www.google.com/s2/favicons?sz=64&domain=goofish.pro // @grant GM_setValue // @grant GM_getValue // @require https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/523617/%E9%97%B2%E7%AE%A1%E5%AE%B6%E4%B8%80%E9%94%AE%E4%B8%8A%E6%9E%B6%E5%8A%A9%E6%89%8B.user.js // @updateURL https://update.greasyfork.icu/scripts/523617/%E9%97%B2%E7%AE%A1%E5%AE%B6%E4%B8%80%E9%94%AE%E4%B8%8A%E6%9E%B6%E5%8A%A9%E6%89%8B.meta.js // ==/UserScript== (function () { "use strict"; // 使用 unsafeWindow 访问原始 window 对象 const unsafeWindow = window.unsafeWindow || window; interceptRequests(); function showToast(message, type = "success") { Swal.fire({ toast: true, position: "top-end", icon: type, title: message, showConfirmButton: false, timer: 1500, }); } function downloadImage(url, fileName) { fetch(url) .then(response => response.blob()) .then(blob => { const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = `${fileName}.jpg`; a.click(); URL.revokeObjectURL(a.href); }) .catch(error => console.error("图片下载失败:", error)); } // 生成随机数 function getRandomNumber(min, max) { const randomInt = Math.floor(Math.random() * (max / 10 - min / 10 + 1)) + min / 10; return randomInt * 10; } // 获取价格,适配不同格式,比如 1~10、10 function getPrice(priceStr) { // 移除特殊字符 "¥" 和 "\n" const cleanedStr = priceStr.replace(/[¥\n]/g, ""); // 使用正则表达式提取所有数字 const numbers = cleanedStr.match(/\d+(\.\d+)?/g); if (numbers === null) { return null; // 如果没有匹配到数字,返回null } // 将提取出的字符串数字转换为浮点数 const prices = numbers.map(Number); // 找出最大值 const maxPrice = Math.max(...prices); return maxPrice; } // 商品页面逻辑 if (window.location.href.includes("https://www.goofish.com/item")) { setTimeout(() => { const button = document.createElement("button"); let goofishImages = document.querySelectorAll("div.slick-slide:not(.slick-cloned)").length; button.innerHTML = `复制商品信息 & 下载图片( ${goofishImages} )`; button.style.position = "fixed"; button.style.bottom = "20px"; button.style.left = "20px"; button.style.zIndex = 1000; button.style.padding = "10px 20px"; button.style.backgroundColor = "#28a745"; button.style.color = "white"; button.style.border = "none"; button.style.borderRadius = "5px"; button.style.cursor = "pointer"; document.body.appendChild(button); button.addEventListener("click", () => { copyGoods(); downloadImages(); }); }, 1500); // 复制商品信息 function copyGoods() { const detailTextElements = document.querySelectorAll("[class*='desc']")[1]; const priceElements = document.querySelectorAll("[class*='price']")[0]; if (detailTextElements && priceElements) { const detailText = detailTextElements.innerText; const indexOfFirstNewLine = detailText.indexOf(" "); let productName, productDescription; if (indexOfFirstNewLine !== -1) { productName = detailText.slice(0, indexOfFirstNewLine).trim(); productDescription = detailText.trim(); } else { productName = detailText.trim(); productDescription = ""; } // 裁剪商品标题到30个中文字以内 const maxTitleLength = 30; productName = productName.slice(0, maxTitleLength); const productPrice = getPrice(priceElements.innerText.trim()); GM_setValue("productName", productName); // GM_setValue("productDescription", productDescription); GM_setValue("productPrice", productPrice); console.log("商品信息已存储"); console.log("商品名:", productName); // console.log("商品详情:", productDescription); console.log("商品价格:", productPrice); showToast("商品信息已复制"); } else { console.error("未找到商品详情或价格元素"); showToast("未找到商品详情或价格元素", "error"); } } // 下载商品图片 function downloadImages() { // 获取所有 class 为 slick-slide 且不包含 slick-cloned 的 div 元素 const goofishImageDivs = document.querySelectorAll("div.slick-slide:not(.slick-cloned)"); // 遍历这些 div 元素,获取其中的 img 标签 const goofishImages = Array.from(goofishImageDivs).map(div => div.querySelector("img")); // 过滤掉可能不存在 img 标签的 div const filteredGoofishImages = goofishImages.filter(img => img !== null); filteredGoofishImages.forEach((img, index) => { setTimeout(() => { let src = img.src.replace(/_webp$/, ""); // 去掉_webp并下载jpg格式 downloadImage(src, `${index + 1}`); }, index * 100); // 每个下载任务之间延迟100毫秒 }); showToast("图片正在开始"); } } // 闲鱼管家上架页面逻辑 if (window.location.hostname.includes("goofish.pro")) { const button = document.createElement("button"); button.innerText = "一键填充"; button.style.position = "fixed"; button.style.bottom = "10px"; button.style.left = "150px"; button.style.zIndex = 1000; button.style.padding = "10px 20px"; button.style.backgroundColor = "#28a745"; button.style.color = "white"; button.style.border = "none"; button.style.borderRadius = "5px"; button.style.cursor = "pointer"; document.body.appendChild(button); button.addEventListener("click", () => { // 检查当前页面是否是商品添加页面 if (!window.location.href.includes("/sale/product/add")) { window.location.href = "https://goofish.pro/sale/product/add?from=%2Fon-sale"; setTimeout(() => fillProductInfo(), 1500); return; } else { fillProductInfo(); } }); } function fillProductInfo() { // 从 Tampermonkey 存储中获取商品信息 const productName = GM_getValue("productName", ""); const productDescription = GM_getValue("productDescription", "") || productName; let prict = GM_getValue("productPrice"); let productPrice = 100; if (prict < 2) { productPrice = 1.9; } else { productPrice = parseFloat(GM_getValue("productPrice", "100")) - 0.1; } if (!productName || !productDescription || isNaN(productPrice)) { showToast("请先去闲鱼详情页复制商品信息", "warning"); return; } console.log("读取到的商品名:", productName); console.log("读取到的商品详情:", productDescription); console.log("读取到的商品价格:", productPrice); // 选择类目 const categoryElements = document.querySelectorAll(".release-history"); if (categoryElements.length > 0) { categoryElements[0].click(); } else { console.error("未找到类目选择元素"); showToast("请选择商品分类", "error"); } setTimeout(() => { // 选择店铺 const shopList = document.querySelectorAll("ul.auth-list li"); if (shopList.length > 1) { // 默认选择第一个店铺 const unSelectedIconElements = document.querySelector(".un-selected-icon"); if (unSelectedIconElements) { unSelectedIconElements.click(); } } else { console.error("请先创建闲鱼店铺"); showToast("请先创建闲鱼店铺", "error"); } setTimeout(() => { // 填充商品名 const inputElement = document.querySelector('input[placeholder="请输入商品标题,最多允许输入30个汉字"]'); if (inputElement) { inputElement.value = productName; const event = new Event("input", { bubbles: true }); inputElement.dispatchEvent(event); } else { console.error("未找到商品标题输入框"); showToast("未找到商品标题输入框", "error"); } // 填充商品描述 const descriptionElements = document.querySelector('textarea[placeholder="请输入商品描述"]'); if (descriptionElements) { descriptionElements.value = productDescription; const event = new Event("input", { bubbles: true }); descriptionElements.dispatchEvent(event); } else { console.error("未找到商品描述输入框"); showToast("未找到商品描述输入框", "error"); } // 搜索一个价格 0=原价 1=售价 const inputElements = document.querySelectorAll('input[placeholder="¥ 0.00"]'); // 填充原价 if (inputElements[0]) { inputElements[0].value = getRandomNumber(200, 500); const event = new Event("input", { bubbles: true }); inputElements[0].dispatchEvent(event); } else { console.error("未找到价格输入框"); showToast("未找到价格输入框", "error"); } // 填充价格 if (inputElements[1]) { inputElements[1].value = productPrice.toFixed(2); const event = new Event("input", { bubbles: true }); inputElements[1].dispatchEvent(event); } else { console.error("未找到价格输入框"); showToast("未找到价格输入框", "error"); } // // 填充库存 // const productStore = 1; // if (inputElements.length > 5) { // inputElements[6].value = productStore; // const event = new Event("input", { bubbles: true }); // inputElements[6].dispatchEvent(event); // } else { // console.error("未找到库存输入框"); // showToast("未找到库存输入框", "error"); // } // const expressFeeItem = document.querySelector(".express_fee-item"); // const radioElements = expressFeeItem.querySelectorAll(".el-radio")[0]; // const isSelet = radioElements.querySelector('input[type="radio"]').value; // console.log(isSelet); // if (radioElements.length) { // radioElements[0].click(); // 包邮 // } else { // console.error("未找到发布商品时机的单选框"); // showToast("未找到发布商品时机的单选框", "error"); // } showToast("商品信息已填充"); }, 500); }, 500); } // 闲鱼详情页:提取并显示想要人数、浏览量和转化率 if (window.location.href.includes("https://www.goofish.com/item")) { setTimeout(() => { // const spanElement = document.querySelector("#ice-container > div.content-container--gIWgkNkm > div.item-container--yLJD5VZj > div.item-main-container--jhpFKlaS > div.item-main-info--rA5Bmpa5 > div.tips--JYdXhSNh > div.want--mVAXJTGv"); const spanElement = document.querySelectorAll("[class*='want']")[0]; if (spanElement) { const textContent = spanElement.textContent.trim(); // 初始化变量 let wantText = "0人想要"; let viewText = "0浏览"; // 检查字符串内容并进行拆分和处理 if (textContent.includes("人想要") && textContent.includes("浏览")) { // 如果同时包含 "人想要" 和 "浏览" [wantText, viewText] = textContent.split(" "); } else if (textContent.includes("浏览")) { // 只有 "浏览" viewText = textContent; } // 提取数字部分并转换为整数 const wantNumber = parseInt(wantText.replace("人想要", "").trim(), 10) || 0; const viewNumber = parseInt(viewText.replace("浏览", "").trim(), 10) || 0; let rate = 0; if (wantNumber != 0 || viewNumber != 0) { rate = wantNumber / viewNumber; } const conversionRate = (rate * 100).toFixed(0); const conversionRateText = conversionRate + "%"; const statsDiv = document.createElement("div"); statsDiv.style.position = "fixed"; statsDiv.style.bottom = "63px"; statsDiv.style.left = "20px"; statsDiv.style.backgroundColor = "#93ab9b"; statsDiv.style.borderRadius = "6px"; statsDiv.style.color = "white"; statsDiv.style.padding = "10px"; statsDiv.style.zIndex = "1000"; statsDiv.style.fontSize = "14px"; const conversionRateSpan = document.createElement("b"); conversionRateSpan.textContent = conversionRateText; conversionRateSpan.style.backgroundColor = conversionRate > 7 ? "green" : "red"; statsDiv.style.backgroundColor = conversionRate > 7 ? "#93ab9b" : "rgb(211 131 131)"; conversionRateSpan.style.padding = "2px 4px"; conversionRateSpan.setAttribute("id", "conversion-rate"); statsDiv.innerHTML = ` 想要数 : ${wantNumber}
浏览量 : ${viewNumber}
转化率 : `; statsDiv.appendChild(conversionRateSpan); document.body.appendChild(statsDiv); if (conversionRate < 7) { console.log(`转化率太低了 ${conversionRate}%`); } } else { console.error("无法找到目标 span 元素"); } }, 1000); } // 拦截并处理接口请求 function interceptRequests() { // 覆盖原生的 XMLHttpRequest const originalXHR = unsafeWindow.XMLHttpRequest; unsafeWindow.XMLHttpRequest = function () { const xhr = new originalXHR(); // 保存原始的 open 方法 const originalOpen = xhr.open; xhr.open = function (method, url, ...rest) { this._url = url; // 保存请求 URL return originalOpen.apply(this, [method, url, ...rest]); }; // 保存原始的 send 方法 const originalSend = xhr.send; xhr.send = function (...args) { this.addEventListener("load", function () { // 拦截商品详情接口,获取详情文本内容 if (this._url.includes("h5api.m.goofish.com/h5/mtop.taobao.idle.pc.detail")) { try { const data = JSON.parse(this.responseText); console.log("接收到的数据:", data); if (data?.data?.itemDO?.desc) { let productDescription = data.data.itemDO.desc; const goodsId = new URL(location.href).searchParams.get("id"); // productDescription += `\n \n[钉子]发的是百 度 网 盘 链 接,永不失效,售出不退。 // [钉子]任何情况,不要申请退款,私信沟通给你处理,小店经营不易。 // [钉子]所有文件均获取自网络公开渠道,仅供学习和交流使用,所有版权归版权人所有,如版权方认为侵犯了您的版权,请及时联系小店删除。`; // productDescription += `\n${goodsId}`; GM_setValue("productDescription", productDescription); console.log("商品详情:", productDescription); } } catch (error) { console.error("解析 XHR 响应时发生错误:", error); } } // 拦截商品详情接口,获取详情文本内容 if (this._url.includes("h5api.m.goofish.com/h5/mtop.taobao.idle.item.web.recommend.list")) { try { const data = JSON.parse(this.responseText); console.log("接收到的数据:", data); // 检查 data.data.cardList 是否为数组 if (data && Array.isArray(data.data?.cardList)) { // 提取有效的数据 const tempData = data.data.cardList.filter(item => { if (item && item.cardData && item.cardData.itemId) { const price = parseInt(item.cardData.price); return price > 0; } return false; }); // 合并到全局数组 window.collectedData window.collectedData.push(...tempData); console.log("新数据已追加:", data.data.cardList); // 去重:使用一个 Set 来追踪已经存在的 itemId const uniqueItems = []; const itemIdSet = new Set(); // 遍历 window.collectedData,添加未重复的 item for (const item of window.collectedData) { const itemId = item.cardData?.itemId; if (itemId && !itemIdSet.has(itemId)) { uniqueItems.push(item); itemIdSet.add(itemId); } } // 更新 window.collectedData 为去重后的结果 window.collectedData = uniqueItems; console.log("去重后的数据:", window.collectedData); // 更新数据计数 updateDataCount(); } } catch (error) { console.error("解析 XHR 响应时发生错误:", error); } } }); return originalSend.apply(this, args); }; return xhr; }; } // 自动写入类目(暂定为电子资料) // if (window.location.hostname.includes("goofish.pro")) { // // 要写入的键 // const key = "goods_select"; // // 要写入的值(注意是一个字符串) // const value = JSON.stringify([ // { // name: "电子资料", // id: [99, "eebfcb1cd9bfce8e212e21d79c0262e7", "eebfcb1cd9bfce8e212e21d79c0262e7", "3cdbae6d47df9251a7f7e02f36b0b49a"], // item_biz_type: 2, // }, // ]); // // 检查localStorage中是否已经存在该键 // if (!localStorage.getItem(key)) { // // 将键值对写入localStorage // // localStorage.setItem(key, value); // // console.log(`已写入localStorage: ${key} = ${value}`); // } else { // console.log(`localStorage中已存在: ${key} = ${localStorage.getItem(key)}`); // } // } repleaceUrl(); // 避免闲管家的域名混用,带www和不带www的,因为两者的cookie不同,导致登录状态是不共享的 function repleaceUrl() { // 获取当前页面的 URL const currentUrl = window.location.href; // 判断是否是以 'https://www.goofish.pro/' 开头 if (currentUrl.startsWith("https://www.goofish.pro/")) { // 使用正则表达式替换 'www.' 为 '' const newUrl = currentUrl.replace("https://www.", "https://"); // 跳转到新的 URL window.location.replace(newUrl); } } // 闲鱼商详页导出猜你喜欢的数据到Excel,支持动态数据 if (window.location.href.includes("https://www.goofish.com/item?")) { exportGoodsList(); } // 更新商品数量显示 function updateDataCount() { const countElement = document.getElementById("data-count"); if (countElement) { countElement.innerText = window.collectedData.length; } } function exportGoodsList() { setTimeout(() => { insertDownloadButton(); }, 0); // 全局数组,用于存储商品数据,确保全局数据存储在 window 对象上 if (!window.collectedData) { window.collectedData = []; } interceptRequests(); // 插入下载按钮到页面 function insertDownloadButton() { const button = document.createElement("button"); button.innerHTML = `导出 [猜你喜欢] 商品 (0)`; button.style.position = "fixed"; button.style.width = "240px"; button.style.left = "50%"; button.style.marginLeft = "-120px"; button.style.bottom = "20px"; button.style.zIndex = 9999; button.style.padding = "10px 20px"; button.style.backgroundColor = "rgb(40, 167, 69)"; button.style.color = "#FFFFFF"; button.style.border = "none"; button.style.borderRadius = "5px"; button.style.cursor = "pointer"; button.addEventListener("click", downloadExcel); document.body.appendChild(button); } // 时间戳转换成日期格式 function timestampToFormattedDate(timestamp) { if (!timestamp) return ""; var date = new Date(parseInt(timestamp)); var year = date.getFullYear(); // 获取年份 var month = date.getMonth() + 1; // 获取月份,月份是从0开始的,所以需要加1 var day = date.getDate(); // 获取日期 // 月份和日期如果是单数,需要在前面补0 month = month < 10 ? "0" + month : month; day = day < 10 ? "0" + day : day; return `${year}-${month}-${day}`; } // 下载Excel文件 function downloadExcel() { if (window.collectedData.length === 0) { alert("没有数据可导出"); return; } // 创建Excel工作簿 const workbook = XLSX.utils.book_new(); const worksheetData = window.collectedData .map(item => { console.log(111, item.cardData?.trackEventParamInfo?.args?.publishTime); return { //商品ID: item.cardData.itemId || '', //链接: `https://www.goofish.com/item?id=` + item.cardData.itemId, 链接: { f: `HYPERLINK("https://www.goofish.com/item?id=${item.cardData.itemId}", "https://www.goofish.com/item?id=${item.cardData.itemId}")`, }, 标题: { f: `HYPERLINK("https://www.goofish.com/item?id=${item.cardData.itemId}", "${item.cardData.title}")`, }, 想要数: parseInt(item.cardData.clickParam.args.wantNum, 10) || "", 价格: parseInt(item.cardData.price) - 0.1 || "", 城市: item.cardData.area || "", 发布日期: timestampToFormattedDate(item.cardData?.clickParam?.args?.publishTime), }; }) .sort((a, b) => b.想要数 - a.想要数); // 将数据转化为工作表 const worksheet = XLSX.utils.json_to_sheet(worksheetData); XLSX.utils.book_append_sheet(workbook, worksheet, "猜你喜欢"); // 生成Excel并触发下载 const workbookOut = XLSX.write(workbook, { bookType: "xlsx", type: "array" }); const blob = new Blob([workbookOut], { type: "application/octet-stream" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "猜你喜欢商品.xlsx"; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } } })();