TEMU卖家中心导出库存价格

TEMU卖家中心导出库存价格, 屏蔽弹窗

// ==UserScript==
// @name         TEMU卖家中心导出库存价格
// @namespace    http://tampermonkey.net/
// @version      0.7.10
// @description  TEMU卖家中心导出库存价格, 屏蔽弹窗
// @author       HimekoEx
// @license      GPL-3.0
// @match        *://*.kuajingmaihuo.com/*
// @match        *://*.agentseller.temu.com/*
// @match        *://*.agentseller-us.temu.com/*
// @icon         https://bstatic.cdnfe.com/static/files/sc/favicon.ico
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    // 排除特定URL
    const excludedUrlPrefix = 'https://seller.kuajingmaihuo.com/settle/seller-login';
    if (window.location.href.startsWith(excludedUrlPrefix)) {
        console.log('当前URL被排除, 脚本终止执行');
        return;
    }

    console.log('TEMU卖家中心导出库存价格...脚本启动');

    // 添加菜单级别的开关变量, 并从本地存储中获取上次的状态
    var removeDivsEnabled = GM_getValue('removeDivsEnabled', false);
    console.log('屏蔽弹窗:', removeDivsEnabled);

    // 切换 removeDivs 开关状态的函数, 并保存状态到本地存储
    function toggleRemoveDivs() {
        removeDivsEnabled = !removeDivsEnabled;
        GM_setValue('removeDivsEnabled', removeDivsEnabled);
        console.log('屏蔽弹窗 toggle:', removeDivsEnabled);
        location.reload();
    }

    function updateMenuCommand() {
        // 添加菜单命令, 用于切换开关状态
        GM_registerMenuCommand(removeDivsEnabled ? "屏蔽弹窗 ON" : "屏蔽弹窗 OFF", toggleRemoveDivs);
    }

    // 更新菜单状态, 确保与开关状态一致
    updateMenuCommand();

    // 拦截fetch请求
    const originalFetch = window.unsafeWindow.fetch;
    window.unsafeWindow.fetch = async function (...args) {
        const response = await originalFetch.apply(this, args);
        let url = args[0]; // 获取 fetch 的第一个参数
    
        // 如果 url 是 Request 对象, 提取实际的 URL
        if (url instanceof Request) {
            url = url.url;
        }

        // 确保 url 是字符串, 再调用 includes
        if (typeof url === 'string' && url.includes('/bg-visage-mms/product/skc/pageQuery')) {
            const clone = response.clone();
            clone.json().then(data => {
                console.log('拦截到的fetch响应:', data);
                // 如有需要, 可以将拦截到的数据存储在localStorage中
                localStorage.setItem('interceptedFetchData', JSON.stringify(data));
            }).catch(err => {
                console.error('解析fetch响应失败:', err);
            });
        }
        return response;
    };

    // 拦截XMLHttpRequest
    const originalOpen = window.unsafeWindow.XMLHttpRequest.prototype.open;
    window.unsafeWindow.XMLHttpRequest.prototype.open = function (...args) {
        this._url = args[1];
        originalOpen.apply(this, args);
    };

    const originalSend = window.unsafeWindow.XMLHttpRequest.prototype.send;
    window.unsafeWindow.XMLHttpRequest.prototype.send = function (...args) {
        this.addEventListener('load', function () {
            if (this._url.includes('/bg-visage-mms/product/skc/pageQuery')) {
                console.log('XMLHttpRequest加载事件URL:', this._url);
                const response = this.responseText;
                try {
                    const data = JSON.parse(response);
                    console.log('拦截到的XMLHttpRequest响应:', data);
                    // 如有需要, 可以将拦截到的数据存储在localStorage中
                    localStorage.setItem('interceptedXHRData', JSON.stringify(data));
                } catch (e) {
                    console.error('解析XMLHttpRequest响应失败:', e);
                }
            }
        });
        originalSend.apply(this, args);
    };

    // 删除特定div的函数
    function removeDivs() {
        if (!removeDivsEnabled) return; // 如果开关关闭, 则不执行操作

        const selectors = [
            'body > div[data-testid="beast-core-modal-mask"]',
            'body > div[data-testid="beast-core-modal"]',
            'body > div.MDL_mask_5-114-0',
            'body > div.MDL_outerWrapper_5-114-0',
            'body > div.MDL_mask_5-113-0',
            'body > div.MDL_outerWrapper_5-113-0',
            'div.sold-out-goods-list_container__1zO49',
        ];

        selectors.forEach(selector => {
            const elements = document.querySelectorAll(selector);
            elements.forEach(element => element.remove());
        });
    }

    // 等待页面完全加载
    window.addEventListener('load', () => {
        console.log('页面已完全加载');
        removeDivs();

        // 如果在初始加载后动态加载元素, 使用MutationObserver
        const observer = new MutationObserver(() => {
            removeDivs();
        });

        observer.observe(document.body, { childList: true, subtree: true });

        // 5秒后停止观察
        setTimeout(() => {
            observer.disconnect();
            console.log('停止观察DOM变动');
        }, 5000);

        // 检查页面URL并在特定页面添加按钮
        const productListUrlPrefix = 'https://seller.kuajingmaihuo.com/goods/product/list'
        if (window.location.href.startsWith(productListUrlPrefix)) {
            console.log('在指定页面, 3秒后添加按钮');
            setTimeout(addButton, 3000);
        }
    });

    // 添加按钮的函数
    function addButton() {
        const parentDiv = document.querySelector('div.hooks_dividerLeftBlock__1d8oE');
        if (parentDiv) {
            const button = document.createElement('button');
            button.className = 'BTN_outerWrapper_5-113-0 BTN_primary_5-113-0 BTN_medium_5-113-0 BTN_outerWrapperBtn_5-113-0';
            button.setAttribute('data-testid', 'beast-core-button');
            button.setAttribute('type', 'button');
            button.style.marginLeft = '0px';
            button.style.marginRight = '8px';

            const buttonContent = document.createElement('div');
            buttonContent.className = 'product-migrate_btnContent__NRxKq';
            buttonContent.textContent = '导出库存&价格';

            button.appendChild(buttonContent);
            parentDiv.appendChild(button);

            // 添加按钮点击事件
            button.addEventListener('click', exportData);
            console.log('按钮已添加');
        } else {
            console.error('未找到目标父div, 无法添加按钮');
        }
    }

    // 导出数据的函数
    function exportData() {
        const data = localStorage.getItem('interceptedFetchData') || localStorage.getItem('interceptedXHRData');
        if (data) {
            const span = document.querySelector('span.elli_outerWrapper_5-109-0.elli_limitWidth_5-109-0');
            const fileName = span ? span.textContent.trim() : '库存价格数据';
            const blob = new Blob([data], { type: 'application/json' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `${fileName}.json`;
            a.click();
            URL.revokeObjectURL(url);
            console.log('数据已导出');

            // 清空存储的json数据
            localStorage.removeItem('interceptedFetchData');
            localStorage.removeItem('interceptedXHRData');
            console.log('存储的数据已清空');
        } else {
            console.error('没有找到要导出的数据');
        }
    }
})();