抖音联盟榜单

抖音联盟榜单爆款榜排名列表展示销量信息

// ==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
// ==/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 = `
            <style>
                .tm-settings-container {
                    position: fixed;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    background: white;
                    padding: 25px;
                    border-radius: 8px;
                    box-shadow: 0 0 15px rgba(0,0,0,0.2);
                    z-index: 9999;
                    font-family: Arial, sans-serif;
                    min-width: 400px;
                }
                .tm-settings-section {
                    margin: 20px 0;
                }
                .tm-settings-title {
                    font-size: 18px;
                    margin-bottom: 15px;
                    color: #333;
                    border-bottom: 1px solid #eee;
                    padding-bottom: 10px;
                }
                .tm-settings-row {
                    margin: 15px 0;
                }
                .tm-settings-label {
                    display: block;
                    margin-bottom: 8px;
                    font-weight: 500;
                    color: #555;
                }
                .tm-settings-input {
                    width: 100%;
                    padding: 8px;
                    border: 1px solid #ddd;
                    border-radius: 4px;
                    box-sizing: border-box;
                }
                .tm-settings-checkbox {
                    margin-right: 8px;
                }
                .tm-settings-buttons {
                    margin-top: 25px;
                    display: flex;
                    gap: 10px;
                    justify-content: flex-end;
                }
                .tm-settings-button {
                    padding: 8px 20px;
                    border-radius: 4px;
                    cursor: pointer;
                    transition: all 0.2s;
                    font-size: 14px;
                }
                .tm-settings-save {
                    background: #007bff;
                    color: white;
                    border: none;
                }
                .tm-settings-save:hover {
                    background: #0056b3;
                }
                .tm-settings-cancel {
                    background: #f8f9fa;
                    border: 1px solid #ddd;
                }
                .tm-settings-cancel:hover {
                    background: #e9ecef;
                }
            </style>
            <div class="tm-settings-container">
                <div class="tm-settings-section">
                    <h3 class="tm-settings-title">销量显示设置</h3>
                    <div class="tm-settings-row">
                        <label class="tm-settings-label">
                            <input type="checkbox" 
                                   class="tm-settings-checkbox"
                                   id="tm-sale-yesterday" 
                                   ${config.enableSaleYesterday ? 'checked' : ''}>
                            显示昨日销量
                        </label>
                    </div>
                    <div class="tm-settings-row">
                        <label class="tm-settings-label">
                            <input type="checkbox" 
                                   class="tm-settings-checkbox"
                                   id="tm-sale-before-yesterday" 
                                   ${config.enableSaleDayBeforeYesterday ? 'checked' : ''}>
                            显示前日销量
                        </label>
                    </div>
                </div>

                <div class="tm-settings-section">
                    <h3 class="tm-settings-title">高级设置</h3>
                    <div class="tm-settings-row">
                        <label class="tm-settings-label">
                            目标脚本匹配:
                            <input type="text" 
                                   class="tm-settings-input"
                                   id="tm-target-script" 
                                   value="${config.targetScript}"
                                   placeholder="输入目标脚本文件名">
                        </label>
                    </div>
                    <div class="tm-settings-row">
                        <label class="tm-settings-label">
                            注入脚本匹配:
                            <input type="text" 
                                   class="tm-settings-input"
                                   id="tm-inject-script" 
                                   value="${config.injectScript}"
                                   placeholder="输入注入脚本路径">
                        </label>
                    </div>
                </div>

                <div class="tm-settings-buttons">
                    <button class="tm-settings-button tm-settings-cancel" id="tm-cancel">取消</button>
                    <button class="tm-settings-button tm-settings-save" id="tm-save">保存设置</button>
                </div>
            </div>
        `;

        // 事件绑定
        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}))
            }
        `);
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址