// ==UserScript==
// @name 抖音联盟榜单
// @name:zh-CN 抖音联盟榜单
// @namespace 抖音联盟榜单
// @description 抖音联盟榜单爆款榜排名列表展示销量信息
// @description:zh-CN 抖音联盟榜单爆款榜排名列表展示销量信息
// @include https://buyin.jinritemai.com/*
// @version 1.2.0
// @grant GM_xmlhttpRequest
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-start
// @license MPL-2.0
// @icon https://lf1-fe.ecombdstatic.com/obj/eden-cn/upelogps/bitbug_favicon.ico
// @downloadURL https://update.greasyfork.icu/scripts/534149/%E6%8A%96%E9%9F%B3%E8%81%94%E7%9B%9F%E6%A6%9C%E5%8D%95.user.js
// @updateURL https://update.greasyfork.icu/scripts/534149/%E6%8A%96%E9%9F%B3%E8%81%94%E7%9B%9F%E6%A6%9C%E5%8D%95.meta.js
// ==/UserScript==
(async() => {
'use strict';
// 默认配置
const defaultConfig = {
enableSaleYesterday: true,
enableSaleDayBeforeYesterday: true,
targetScript: "garfish_6ae3fa27.js",
injectScript: "54128_764752b0c7.js"
};
// 配置管理
function getConfig() {
return {
enableSaleYesterday: GM_getValue('enableSaleYesterday', defaultConfig.enableSaleYesterday),
enableSaleDayBeforeYesterday: GM_getValue('enableSaleDayBeforeYesterday', defaultConfig.enableSaleDayBeforeYesterday),
targetScript: GM_getValue('targetScript', defaultConfig.targetScript),
injectScript: GM_getValue('injectScript', defaultConfig.injectScript)
};
}
// 设置界面组件
function createSettingsPanel() {
const config = getConfig();
const container = document.createElement('div');
const shadow = container.attachShadow({ mode: 'open' });
shadow.innerHTML = `
`;
// 事件绑定
shadow.getElementById('tm-save').addEventListener('click', saveSettings);
shadow.getElementById('tm-cancel').addEventListener('click', hideSettings);
// 关闭处理
document.addEventListener('click', (e) => !container.contains(e.target) && hideSettings());
document.addEventListener('keyup', (e) => e.key === 'Escape' && hideSettings());
return container;
}
// 设置面板控制
let settingsPanel = null;
function showSettings() {
if (!document.body) return setTimeout(showSettings, 100);
if (!settingsPanel) settingsPanel = createSettingsPanel();
document.body.appendChild(settingsPanel);
}
function hideSettings() {
settingsPanel?.remove();
settingsPanel = null;
}
// 保存配置
function saveSettings() {
const shadow = settingsPanel.shadowRoot;
const newConfig = {
enableSaleYesterday: shadow.getElementById('tm-sale-yesterday').checked,
enableSaleDayBeforeYesterday: shadow.getElementById('tm-sale-before-yesterday').checked,
targetScript: shadow.getElementById('tm-target-script').value.trim(),
injectScript: shadow.getElementById('tm-inject-script').value.trim()
};
// 配置验证
if (!newConfig.targetScript || !newConfig.injectScript) {
alert('脚本配置不能为空');
return;
}
// 保存配置
GM_setValue('enableSaleYesterday', newConfig.enableSaleYesterday);
GM_setValue('enableSaleDayBeforeYesterday', newConfig.enableSaleDayBeforeYesterday);
GM_setValue('targetScript', newConfig.targetScript);
GM_setValue('injectScript', newConfig.injectScript);
// 刷新页面使配置生效
if (confirm('需要刷新页面才能应用新配置,是否立即刷新?')) {
window.location.reload();
} else {
hideSettings();
}
}
// 初始化系统
function init() {
GM_registerMenuCommand('打开设置', showSettings);
}
// 启动逻辑
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
// 核心注入逻辑
new MutationObserver(async (mutations, observer) => {
const config = getConfig();
const targetScript = mutations
.flatMap(e => [...e.addedNodes])
.find(n => n.tagName === 'SCRIPT' && n.src?.includes(config.targetScript));
if (targetScript) {
observer.disconnect();
targetScript.remove();
try {
const originalText = await fetch(targetScript.src).then(r => r.text());
const modifiedText = modifyScript(originalText, config);
const newScript = document.createElement('script');
newScript.textContent = modifiedText;
document.head.appendChild(newScript);
} catch (e) {
console.error('脚本加载失败:', e);
}
}
}).observe(document, { childList: true, subtree: true });
// 脚本修改函数(修正正则版)
function modifyScript(scriptText, config) {
const injectionTemplates = [];
// 生成需要注入的列配置
if (config.enableSaleYesterday) {
injectionTemplates.push(`{
title: "昨日销量",
key: "7",
align: "right",
className: __CLASS_NAME_PLACEHOLDER__,
render: e => (0, _.jsx)("div", {
children: [JSON.stringify(e.board_data.axis.slice(-1)[0].y)]
})
}`);
}
if (config.enableSaleDayBeforeYesterday) {
injectionTemplates.push(`{
title: "前日销量",
key: "8",
align: "right",
className: __CLASS_NAME_PLACEHOLDER__,
render: e => (0, _.jsx)("div", {
children: [JSON.stringify(e.board_data.axis.slice(-2)[0].y)]
})
}`);
}
// 修正后的正则表达式
const targetRegex = /execScript\((\w+),\w+\=\{\}.*?\{/;
const replaceRegex = /(?<=,)\.{3}\w+===\w+\.\w+\.hot_rec/g;
// const replaceRegex = /(?<=,)(\.\.\.\w+===(\w+\.\w+\.hot_rec))(?![\w.])(?:\s*\|\|\s*\.\.\.\w+===(\w+\.\w+\.hot_rec))*/g;
return scriptText.replace(targetRegex, (match, codeVar) => `
${match}
// 注入检测逻辑
const isMatchJs = arguments[2]?.includes('/${config.injectScript}');
if (isMatchJs) {
// 获取样式类名
const cssMatch = ${codeVar}.match(/className:\\s*(\\w+)\\.topVertical/);
const className = cssMatch ? \`\${cssMatch[1]}.topVertical\` : '';
// 替换目标代码
${codeVar} = arguments[0].replace(
${replaceRegex},
// 不管有没有追加数据这里末尾都加个逗号
match => {
const injection = ${(JSON.stringify(injectionTemplates))}
.map(tpl => tpl.replace(/__CLASS_NAME_PLACEHOLDER__/g, className))
.join(',');
return injection ? \`\${injection},\${match}\` : match;
// return injection ? \`\${injection},\${match}\` : match;
}
);
// alert(${replaceRegex}.test(${codeVar}))
}
`);
}
})();