Greasy Fork

Greasy Fork is available in English.

店小蜜价格助手

5倍价格

当前为 2025-11-03 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         店小蜜价格助手
// @namespace    http://tampermonkey.net/
// @version      1.8.0
// @description  5倍价格
// @author       Rayu
// @match        https://www.dianxiaomi.com/web/shopeeSite/edit*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- 配置项 ---
    const HIGHLIGHT_COLOR = 'yellow';
    const MULTIPLE_THRESHOLD = 5;
    const INCLUDE_EQUAL = true;
    const DEBOUNCE_DELAY = 300;

    let debounceTimer;
    let skuElementsMap = new Map();

    function cleanName(name) {
        return name ? name.replace(/\s+/g, ' ').trim() : '';
    }

    /**
     * 获取两个主题的信息
     * @returns {Object} { theme1: {name, checkboxes}, theme2: {name, checkboxes} }
     */
    function getThemesInfo() {
        const themeBoxes = document.querySelectorAll('#skuAttrInfo .theme-box');
        const themes = [];

        themeBoxes.forEach(box => {
            const headerTextEl = box.querySelector('.theme-box-header .theme-value-text');
            const themeName = headerTextEl ? cleanName(headerTextEl.title || headerTextEl.textContent) : '';
            const checkboxes = Array.from(box.querySelectorAll('.checkbox-group input[type="checkbox"]:checked'));

            if (themeName && checkboxes.length > 0) {
                themes.push({ name: themeName, checkboxes: checkboxes });
            }
        });

        return themes.length >= 2 ? { theme1: themes[0], theme2: themes[1] } : null;
    }

    /**
     * 获取 SKU 数据
     */
    function getSkuData() {
        const skuData = [];
        skuElementsMap.clear();

        const headerRow = document.querySelector('#skuDataInfo thead tr');
        let theme1ColIndex = -1;
        let theme2ColIndex = -1;
        let priceColIndex = -1;

        if (headerRow) {
            const headers = headerRow.querySelectorAll('th');
            let themeColCount = 0;
            headers.forEach((th, index) => {
                const text = cleanName(th.textContent);
                if (text.includes('价格')) {
                    priceColIndex = index;
                } else if (themeColCount === 0 && (text.includes('顏色') || text.includes('重量') || text.includes('尺寸') || text.includes('款式') || text.includes('规格'))) {
                    theme1ColIndex = index;
                    themeColCount++;
                } else if (themeColCount === 1 && (text.includes('顏色') || text.includes('重量') || text.includes('尺寸') || text.includes('款式') || text.includes('规格'))) {
                    theme2ColIndex = index;
                    themeColCount++;
                }
            });
        }

        if (theme1ColIndex === -1 || theme2ColIndex === -1 || priceColIndex === -1) {
            console.error('[Shopee Price Highlighter & Filter] Could not find theme or price columns.');
            return [];
        }

        const dataRows = document.querySelectorAll('#skuDataInfo tbody tr');
        dataRows.forEach((row) => {
            const cells = row.querySelectorAll('td');
            if (cells.length === 0) return;

            const theme1Cell = cells[theme1ColIndex];
            const theme2Cell = cells[theme2ColIndex];
            const priceCell = cells[priceColIndex];

            const theme1Value = cleanName(theme1Cell ? theme1Cell.textContent : '');
            const theme2Value = cleanName(theme2Cell ? theme2Cell.textContent : '');
            const priceInput = priceCell ? priceCell.querySelector('input.g-form-component') : null;

            if (!theme1Value || !theme2Value || !priceInput) return;

            const price = parseFloat(priceInput.value);
            if (!isNaN(price) && price > 0) {
                const combinedName = `${theme1Value} ${theme2Value}`;
                const data = {
                    combinedName: combinedName,
                    theme1Value: theme1Value,
                    theme2Value: theme2Value,
                    price: price,
                    priceInput: priceInput
                };
                skuData.push(data);
                skuElementsMap.set(combinedName, data);
            }
        });

        console.log(`[Shopee Price Highlighter & Filter] Found ${skuData.length} valid SKUs.`);
        return skuData;
    }

    /**
     * 高亮价格
     */
    function highlightPrices() {
        console.log('[Shopee Price Highlighter & Filter] Executing price highlight...');
        const skuData = getSkuData();
        if (skuData.length === 0) return;

        const validPrices = skuData.map(s => s.price).filter(price => !isNaN(price) && price > 0);
        if (validPrices.length === 0) {
            skuData.forEach(sku => { sku.priceInput.style.backgroundColor = ''; });
            return;
        }

        const minPrice = Math.min(...validPrices);
        const thresholdPrice = minPrice * MULTIPLE_THRESHOLD;

        console.log(`[Shopee Price Highlighter & Filter] Min Price: ${minPrice}, Threshold: ${thresholdPrice} (${MULTIPLE_THRESHOLD}x)`);

        skuData.forEach(sku => {
            sku.priceInput.style.backgroundColor = '';
            if (!isNaN(sku.price)) {
                if (INCLUDE_EQUAL) {
                    if (sku.price >= thresholdPrice) {
                        sku.priceInput.style.backgroundColor = HIGHLIGHT_COLOR;
                    }
                } else {
                    if (sku.price > thresholdPrice) {
                        sku.priceInput.style.backgroundColor = HIGHLIGHT_COLOR;
                    }
                }
            }
        });
    }

    function setCheckboxState(checkboxInput, checked) {
        if (!checkboxInput || checkboxInput.checked === checked) return;

        checkboxInput.checked = checked;
        const event = new Event('change', { bubbles: true });
        checkboxInput.dispatchEvent(event);

        console.log(`[Shopee Price Highlighter & Filter] Checkbox for "${cleanName(checkboxInput.value)}" set to ${checked}`);
    }

    /**
     * 移除最低价选项
     */
    function removeLowestPriceSku() {
        const themesInfo = getThemesInfo();
        if (!themesInfo) {
            alert('无法识别变种主题结构');
            return;
        }

        // 判断哪个主题选项更多
        const { theme1, theme2 } = themesInfo;
        let targetTheme, otherTheme;

        if (theme1.checkboxes.length >= theme2.checkboxes.length) {
            targetTheme = theme1;
            otherTheme = theme2;
        } else {
            targetTheme = theme2;
            otherTheme = theme1;
        }

        if (targetTheme.checkboxes.length <= 1) {
            alert(`${targetTheme.name}至少需要保留一个选项`);
            return;
        }

        // 计算每个目标选项的最低价格(代表价格)
        const optionPrices = new Map();

        targetTheme.checkboxes.forEach(checkbox => {
            const optionName = cleanName(checkbox.value);
            let minPriceForOption = Infinity;

            otherTheme.checkboxes.forEach(otherCheckbox => {
                const otherOptionName = cleanName(otherCheckbox.value);

                // 根据主题顺序组合
                let combinedName;
                if (targetTheme === theme1) {
                    combinedName = `${optionName} ${otherOptionName}`;
                } else {
                    combinedName = `${otherOptionName} ${optionName}`;
                }

                const skuData = skuElementsMap.get(combinedName);
                if (skuData && skuData.price < minPriceForOption) {
                    minPriceForOption = skuData.price;
                }
            });

            if (minPriceForOption !== Infinity) {
                optionPrices.set(checkbox, minPriceForOption);
            }
        });

        // 找到最低价的选项
        let lowestCheckbox = null;
        let lowestPrice = Infinity;

        optionPrices.forEach((price, checkbox) => {
            if (price < lowestPrice) {
                lowestPrice = price;
                lowestCheckbox = checkbox;
            }
        });

        if (lowestCheckbox) {
            const optionName = cleanName(lowestCheckbox.value);
            setCheckboxState(lowestCheckbox, false);
            console.log(`[Shopee Price Highlighter & Filter] Removed lowest price option in ${targetTheme.name}: ${optionName} (代表价格: ${lowestPrice})`);
            setTimeout(highlightPrices, DEBOUNCE_DELAY);
        }
    }

    /**
     * 移除最高价选项
     */
    function removeHighestPriceSku() {
        const themesInfo = getThemesInfo();
        if (!themesInfo) {
            alert('无法识别变种主题结构');
            return;
        }

        const { theme1, theme2 } = themesInfo;
        let targetTheme, otherTheme;

        if (theme1.checkboxes.length >= theme2.checkboxes.length) {
            targetTheme = theme1;
            otherTheme = theme2;
        } else {
            targetTheme = theme2;
            otherTheme = theme1;
        }

        if (targetTheme.checkboxes.length <= 1) {
            alert(`${targetTheme.name}至少需要保留一个选项`);
            return;
        }

        const optionPrices = new Map();

        targetTheme.checkboxes.forEach(checkbox => {
            const optionName = cleanName(checkbox.value);
            let minPriceForOption = Infinity;

            otherTheme.checkboxes.forEach(otherCheckbox => {
                const otherOptionName = cleanName(otherCheckbox.value);

                let combinedName;
                if (targetTheme === theme1) {
                    combinedName = `${optionName} ${otherOptionName}`;
                } else {
                    combinedName = `${otherOptionName} ${optionName}`;
                }

                const skuData = skuElementsMap.get(combinedName);
                if (skuData && skuData.price < minPriceForOption) {
                    minPriceForOption = skuData.price;
                }
            });

            if (minPriceForOption !== Infinity) {
                optionPrices.set(checkbox, minPriceForOption);
            }
        });

        let highestCheckbox = null;
        let highestPrice = -Infinity;

        optionPrices.forEach((price, checkbox) => {
            if (price > highestPrice) {
                highestPrice = price;
                highestCheckbox = checkbox;
            }
        });

        if (highestCheckbox) {
            const optionName = cleanName(highestCheckbox.value);
            setCheckboxState(highestCheckbox, false);
            console.log(`[Shopee Price Highlighter & Filter] Removed highest price option in ${targetTheme.name}: ${optionName} (代表价格: ${highestPrice})`);
            setTimeout(highlightPrices, DEBOUNCE_DELAY);
        }
    }

    // --- MutationObserver ---
    const observerCallback = function(mutationsList, observer) {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(() => {
            highlightPrices();
        }, DEBOUNCE_DELAY);
    };

    let observerRetryCount = 0;
    const maxObserverRetries = 10;
    const observerRetryInterval = 500;

    function initializeObserver() {
        const targetNode = document.getElementById('skuDataInfo');
        if (targetNode) {
            const config = {
                childList: true,
                subtree: true,
                attributes: true,
                attributeFilter: ['value']
            };

            const observer = new MutationObserver(observerCallback);
            observer.observe(targetNode, config);

            const skuAttrInfoNode = document.getElementById('skuAttrInfo');
            if (skuAttrInfoNode) {
                const attrConfig = {
                    childList: true,
                    subtree: true,
                    attributes: true,
                    attributeFilter: ['checked']
                };
                const attrObserver = new MutationObserver(observerCallback);
                attrObserver.observe(skuAttrInfoNode, attrConfig);
                console.log('[Shopee Price Highlighter & Filter] MutationObserver started for both sections.');
            }

            console.log('[Shopee Price Highlighter & Filter] MutationObserver initialized.');
            highlightPrices();
        } else if (observerRetryCount < maxObserverRetries) {
            observerRetryCount++;
            console.warn(`[Shopee Price Highlighter & Filter] Retrying observer init (${observerRetryCount}/${maxObserverRetries})...`);
            setTimeout(initializeObserver, observerRetryInterval);
        } else {
            console.error('[Shopee Price Highlighter & Filter] Failed to initialize observer.');
        }
    }

    /**
     * 添加功能按钮
     */
    let addButtonsRetryCount = 0;
    const maxAddButtonsRetries = 10;
    const addButtonsRetryInterval = 500;

    function addFilterButtons() {
        if (document.getElementById('skuFilterButtons')) {
            console.log('[Shopee Price Highlighter & Filter] Filter buttons already exist.');
            return;
        }

        const targetElementForButtons = document.querySelector("#skuDataInfo > div.form-card-content > div > div > div.mb-20.flex-justify-between");

        if (targetElementForButtons) {
            const buttonContainer = document.createElement('div');
            buttonContainer.id = 'skuFilterButtons';
            buttonContainer.style.cssText = 'display: flex; gap: 10px; align-items: center;';

            const createButton = (text, onClickHandler) => {
                const button = document.createElement('button');
                button.className = 'ant-btn ant-btn-default css-1oz1bg8';
                button.textContent = text;
                button.style.backgroundColor = '#e6f7ff';
                button.style.borderColor = '#91d5ff';
                button.style.color = '#1890ff';
                button.style.minWidth = 'unset';
                button.style.padding = '4px 12px';
                button.style.height = '32px';
                button.addEventListener('click', onClickHandler);
                return button;
            };

            buttonContainer.appendChild(createButton('移除最低价', removeLowestPriceSku));
            buttonContainer.appendChild(createButton('移除最高价', removeHighestPriceSku));

            targetElementForButtons.appendChild(buttonContainer);

            console.log('[Shopee Price Highlighter & Filter] Filter buttons added successfully.');
            addButtonsRetryCount = 0;
        } else if (addButtonsRetryCount < maxAddButtonsRetries) {
            addButtonsRetryCount++;
            console.warn(`[Shopee Price Highlighter & Filter] Retrying button addition (${addButtonsRetryCount}/${maxAddButtonsRetries})...`);
            setTimeout(addFilterButtons, addButtonsRetryInterval);
        } else {
            console.error('[Shopee Price Highlighter & Filter] Failed to add filter buttons.');
        }
    }

    // --- 启动脚本 ---
    function init() {
        initializeObserver();
        addFilterButtons();
        setTimeout(addFilterButtons, 1500);
        setTimeout(highlightPrices, 1500);
        setTimeout(addFilterButtons, 4000);
        setTimeout(highlightPrices, 4000);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();