// ==UserScript==
// @name 炼丹炉-品牌排行
// @namespace http://tampermonkey.net/
// @version 0.1.2
// @description 炼丹炉扩展工具
// @author siji-Xian
// @match *://www.huo1818.com/app/jd/market/rank/brand?*
// @icon https://cdn.zhiyitech.cn/material/4efba8e6ba2cf8883526fce8b21eac28
// @license MIT
// @require https://cdn.jsdelivr.net/npm/xlsx@0.17.1/dist/xlsx.full.min.js
// @require https://greasyfork.org/scripts/455576-qmsg/code/Qmsg.js?version=1122361
// ==/UserScript==
(function () {
"use strict";
var new_element = document.createElement("link");
new_element.setAttribute("rel", "stylesheet");
new_element.setAttribute("href", "https://qmsg.refrain.xyz/message.min.css");
document.body.appendChild(new_element);
const button = document.createElement("div");
button.textContent = "导出数据";
Object.assign(button.style, {
height: "34px",
lineHeight: "var(--line-height, 34px)",
alignItems: "center",
color: "white",
background: "linear-gradient(90deg, rgba(0, 239, 253), rgba(64, 166, 254))",
borderRadius: "5px",
marginLeft: "10px",
fontSize: "13px",
padding: "0 10px",
cursor: "pointer",
fontWeight: "500",
});
button.addEventListener("click", urlClick);
function appendDoc() {
const likeComment = document.querySelector(".fuui-row._title_1u19s_8");
if (likeComment) {
likeComment.append(button);
return;
}
setTimeout(appendDoc, 1000);
}
appendDoc();
//message.js
let loadingMsg = null;
//目标数据
let target_data = null;
(function listen() {
var origin = {
open: XMLHttpRequest.prototype.open,
send: XMLHttpRequest.prototype.send,
};
XMLHttpRequest.prototype.open = function (a, b) {
this.addEventListener("load", replaceFn);
origin.open.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function (a, b) {
origin.send.apply(this, arguments);
};
function replaceFn(obj) {
if (
this?.responseURL?.slice(0, 36) ==
"https://www.huo1818.com/backend-api/huo1818-olap-jd/industry/rank/brand-list"
) {
target_data = JSON.parse(obj?.target?.response);
}
}
})();
//query参数获取
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return false;
}
var myHeaders = new Headers();
myHeaders.append("authority", "www.huo1818.com");
myHeaders.append("accept", "*/*");
myHeaders.append("accept-language", "zh-CN,zh;q=0.9");
myHeaders.append("client", "web");
myHeaders.append("group", "2");
myHeaders.append("authorization", localStorage.getItem("__t"));
myHeaders.append("name", "%E5%93%81%E7%89%8C%E6%8E%92%E8%A1%8C-%E8%A1%8C%E4%B8%9A%E5%88%86%E6%9E%90-%E7%82%BC%E4%B8%B9%E7%82%89");
myHeaders.append("project", "huo");
myHeaders.append("sec-ch-ua", "\"Google Chrome\";v=\"119\", \"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"");
myHeaders.append("sec-ch-ua-mobile", "?0");
myHeaders.append("sec-ch-ua-platform", "\"macOS\"");
myHeaders.append("sec-fetch-dest", "empty");
myHeaders.append("sec-fetch-mode", "cors");
myHeaders.append("sec-fetch-site", "same-origin");
myHeaders.append("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
const getRequestOptions = {
method: "GET",
headers: myHeaders,
redirect: "follow",
};
async function fetchFun(url, data, requestOptions = getRequestOptions) {
const params = new URLSearchParams(data).toString();
try {
const response = await fetch(`${url}?${params}`, requestOptions);
if (response.ok) {
const result = await response.json();
return result;
} else {
throw new Error(`Fetch failed: ${response.status}`);
}
} catch (error) {
loadingMsg.close();
Qmsg.error({
content: `网络请求错误: ${error.message}`,
timeout: 5000,
});
throw error;
}
}
async function getData(date) {
const targetPromise = await fetchFun(
"https://www.huo1818.com/backend-api/huo1818-olap-jd/industry/rank/brand-list",
{
orderField:'saleVolume',
orderType:'desc',
pageNo:getQueryVariable("pageNo"),
pageSize:20,
date,
dateGroupType:"MONTH_GROUP",
categoryId:getQueryVariable("catId"),
}
);
return {date,value:targetPromise};
}
function exportToExcel(dataArray, sheetNames, headerAliases, fileName = "output.xlsx") {
const workbook = XLSX.utils.book_new();
// 遍历每个 Sheet
dataArray.forEach((sheetData, index) => {
// 获取当前 Sheet 的字段名数组
const headers = Object.keys(sheetData.value[0]);
// 创建工作表
const sheet = XLSX.utils.json_to_sheet(sheetData.value, { header: headers});
// 替换表头别名
headers.forEach((header, columnIndex) => {
if (headerAliases[header]) {
sheet[XLSX.utils.encode_cell({ r: 0, c: columnIndex })].v = headerAliases[header];
}
});
// 使用提供的 Sheet 名称或默认名称
const sheetName = sheetNames[index] || `Sheet${index + 1}`;
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(workbook, sheet, sheetName);
});
// 将工作簿保存为 Excel 文件
XLSX.writeFile(workbook, fileName);
loadingMsg.close();
}
let contrast = {
"brandId":"品牌ID",
"brandName":"品牌名称",
"saleVolume":"销量",
"saleVolumeMomRatio":"销量环比",
"saleAmount":"销售额",
"saleAmountMomRatio":"销售额环比",
"shopCount":"热销店铺数",
"saleSkuCount":"动销SKU数"
};
async function urlClick() {
loadingMsg = Qmsg.loading("正在导出,请勿重复点击!");
let dates = ['202211','202212','202301','202302','202303','202304','202305','202306','202307','202308','202309','202310','202311'];
let fetchData = [];
async function fetchDataWithDelay() {
for (const date of dates) {
let result = await getData(date);
fetchData.push(result);
// 设置定时器,增加网络请求间隔,例如每隔500毫秒
await delay(500);
}
}
// 延迟函数
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 调用包含定时器的数据获取函数
await fetchDataWithDelay(); // 使用 await 确保 fetchDataWithDelay 执行完毕
let data = fetchData.map(v => {
return {
date: v.date,
value: v.value.result.data.map(t=>{
return {...t,saleAmount:t.saleAmount/100}
})
};
});
let fileName = '品牌排行' + document.querySelectorAll(".fuui-select-display--single-text")[0].innerHTML + "-" + document.querySelectorAll(".fuui-select-display--single-text")[1].innerHTML + "-" + document.querySelectorAll(".fuui-select-display--single-text")[2].innerHTML;
loadingMsg = Qmsg.loading("正在导出,请勿重复点击!");
exportToExcel(data, dates, contrast, `${fileName}.xlsx`);
}
})();