Greasy Fork

Greasy Fork is available in English.

Wargaming商店阿根廷区 ARS 转 CNY 货币转换器

Wargaming商店阿根廷区将ARS货币价值转换为CNY并附代充折扣显示

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

// ==UserScript==
// @name         Wargaming商店阿根廷区 ARS 转 CNY 货币转换器
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Wargaming商店阿根廷区将ARS货币价值转换为CNY并附代充折扣显示
// @author       SundayRX
// @match        https://wargaming.net/shop/*
// @grant        GM_xmlhttpRequest
// @connect      api.exchangerate-api.com
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 配置
    const CONFIG = {
        // 汇率API端点
        exchangeRateAPI: 'https://api.exchangerate-api.com/v4/latest/ARS',
        // 备用汇率(如果API不可用)
        fallbackExchangeRate: 0.005, // 1 ARS = 0.005 CNY(示例值)
        // 打折
        discount:0.87, //代冲折扣(自行修改)
        // 更新间隔(毫秒)
        updateInterval: 600000, // 10分钟
        // 高亮样式
        highlightStyle: `
            .ars-to-cny-conversion {
                background-color: #ffffcc;
                border-radius: 3px;
                padding: 2px 4px;
                margin-left: 5px;
                font-weight: bold;
                font-size: 0.9em;
                color: #d32f2f;
            }
            .ars-to-cny-processed {
                display: inline-flex;
                align-items: center;
            }
        `,
        // 是否显示原始ARS值
        showOriginalValue: true
    };

    let exchangeRate = CONFIG.fallbackExchangeRate;
    let isProcessing = false;
    let observer = null;

    // 初始化脚本
    function init() {
        console.log('ARS转CNY转换器已加载');

        // 添加样式
        addStyles();

        // 获取汇率
        fetchExchangeRate();

        // 设置定期更新汇率
        setInterval(fetchExchangeRate, CONFIG.updateInterval);

        // 初始转换
        convertPageARSValues();

        // 监听DOM变化
        observeDOMChanges();
    }

    // 添加样式到页面
    function addStyles() {
        const style = document.createElement('style');
        style.textContent = CONFIG.highlightStyle;
        document.head.appendChild(style);
    }

    // 获取汇率
    function fetchExchangeRate() {
        GM_xmlhttpRequest({
            method: 'GET',
            url: CONFIG.exchangeRateAPI,
            onload: function(response) {
                try {
                    const data = JSON.parse(response.responseText);
                    if (data && data.rates && data.rates.CNY) {
                        exchangeRate = data.rates.CNY;
                        console.log(`汇率已更新: 1 ARS = ${exchangeRate} CNY`);

                        // 更新页面上的转换值
                        updateConvertedValues();
                    } else {
                        console.warn('无法从API获取汇率,使用备用汇率');
                    }
                } catch (e) {
                    console.warn('解析汇率API响应失败:', e);
                }
            },
            onerror: function(error) {
                console.warn('获取汇率失败:', error, '使用备用汇率');
            }
        });
    }

    // 转换页面中的ARS值
    function convertPageARSValues() {
        if (isProcessing) return;
        isProcessing = true;

        // 暂停DOM监听器,避免重复处理
        if (observer) {
            observer.disconnect();
        }

        // 查找所有价格元素
        const priceElements = findPriceElements();

        // 处理价格元素
        priceElements.forEach(processPriceElement);

        // 重新启动DOM监听器
        if (observer) {
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }

        isProcessing = false;
    }

    // 查找所有价格元素
    function findPriceElements() {
        const elements = [];
        const seenElements = new Set(); // 用于去重

        // 使用更精确的选择器,避免重复匹配
        const selectors = [
            // '.product-price_old:not(.ars-to-cny-processed)',
            // '[data-qa="original_product_price"]:not(.ars-to-cny-processed)',
            '.product-price_wrap > span:not(.ars-to-cny-processed)',
            '[data-qa="product_price"] > span:not(.ars-to-cny-processed)'
        ];

        selectors.forEach(selector => {
            const foundElements = document.querySelectorAll(selector);
            foundElements.forEach(element => {
                // 检查元素是否包含ARS货币值且未被见过
                if (containsARSValue(element.textContent) &&
                    !seenElements.has(element)) {
                    elements.push(element);
                    seenElements.add(element);
                }
            });
        });

        return elements;
    }

    // 检查文本是否包含ARS货币值
    function containsARSValue(text) {
        // 改进的正则表达式,匹配带有千位分隔符的数字
        const arsRegex = /([\d,]+(?:\.\d+)?)\s*(ARS|阿根廷比索|pesos argentinos)/i;
        return arsRegex.test(text);
    }

    // 处理价格元素
    function processPriceElement(element) {
        if (element.classList.contains('ars-to-cny-processed')) {
            return;
        }

        const originalText = element.textContent.trim();
        const arsValue = extractARSValue(originalText);

        if (arsValue !== null) {
            const cnyValue = arsValue * exchangeRate;
            const formattedCNY = formatCurrency(cnyValue, 'CNY');

            // 检查是否已经存在转换元素
            const existingConversion = findExistingConversion(element);
            if (existingConversion) {
                // 如果已存在,更新它
                existingConversion.textContent = `≈${formattedCNY}`;
                existingConversion.title = `${formatNumber(arsValue)} ARS ≈ ${formattedCNY}`;
            } else {
                // 如果不存在,创建新的转换元素
                const conversionElement = document.createElement('span');
                conversionElement.className = 'ars-to-cny-conversion';
                conversionElement.textContent = `≈${formattedCNY}`;
                conversionElement.title = `${formatNumber(arsValue)} ARS ≈ ${formattedCNY}`;

                // 插入到价格元素后面
                element.parentNode.insertBefore(conversionElement, element.nextSibling);
            }

            // 标记元素为已处理
            element.classList.add('ars-to-cny-processed');
        }
    }

    // 查找已存在的转换元素
    function findExistingConversion(element) {
        // 检查相邻的兄弟元素
        let sibling = element.nextElementSibling;
        while (sibling) {
            if (sibling.classList && sibling.classList.contains('ars-to-cny-conversion')) {
                return sibling;
            }
            sibling = sibling.nextElementSibling;
        }

        // 检查父元素的兄弟元素(针对某些特殊布局)
        const parent = element.parentElement;
        if (parent && parent.nextElementSibling) {
            const nextSibling = parent.nextElementSibling;
            if (nextSibling.classList && nextSibling.classList.contains('ars-to-cny-conversion')) {
                return nextSibling;
            }
        }

        return null;
    }

    // 从文本中提取ARS数值
    function extractARSValue(text) {
        // 改进的正则表达式,匹配带有千位分隔符的数字
        const arsRegex = /([\d,]+(?:\.\d+)?)\s*(ARS|阿根廷比索|pesos argentinos)/i;
        const match = text.match(arsRegex);

        if (match && match[1]) {
            // 移除所有逗号,然后转换为数字
            const numericValue = match[1].replace(/,/g, '');
            return parseFloat(numericValue);
        }

        return null;
    }

    // 格式化货币值
    function formatCurrency(value, currency) {
        if (currency === 'CNY') {
            const fixValue=value*CONFIG.discount;
            return `${value.toFixed(2)}\(${fixValue.toFixed(2)}\)CNY`;
        }
        return value.toFixed(2);
    }

    // 格式化数字(添加千位分隔符)
    function formatNumber(num) {
        return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }

    // 更新已转换的值
    function updateConvertedValues() {
        const convertedElements = document.querySelectorAll('.ars-to-cny-conversion');
        convertedElements.forEach(element => {
            // 查找相邻的价格元素
            const priceElement = findAdjacentPriceElement(element);
            if (priceElement) {
                const originalText = priceElement.textContent.trim();
                const arsValue = extractARSValue(originalText);

                if (arsValue !== null) {
                    const cnyValue = arsValue * exchangeRate;
                    const formattedCNY = formatCurrency(cnyValue, 'CNY');

                    element.textContent = `≈${formattedCNY}`;
                    element.title = `${formatNumber(arsValue)} ARS ≈ ${formattedCNY}`;
                }
            }
        });
    }

    // 查找相邻的价格元素
    function findAdjacentPriceElement(conversionElement) {
        // 检查前一个兄弟元素
        let sibling = conversionElement.previousElementSibling;
        while (sibling) {
            if (sibling.classList && sibling.classList.contains('ars-to-cny-processed')) {
                return sibling;
            }
            sibling = sibling.previousElementSibling;
        }

        // 检查父元素的前一个兄弟元素
        const parent = conversionElement.parentElement;
        if (parent && parent.previousElementSibling) {
            const prevSibling = parent.previousElementSibling;
            if (prevSibling.classList && prevSibling.classList.contains('ars-to-cny-processed')) {
                return prevSibling;
            }
        }

        return null;
    }

    // 监听DOM变化
    function observeDOMChanges() {
        observer = new MutationObserver(function(mutations) {
            let shouldConvert = false;

            mutations.forEach(function(mutation) {
                if (mutation.type === 'childList') {
                    mutation.addedNodes.forEach(function(node) {
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            // 检查新添加的元素是否包含价格元素
                            const priceSelectors = [
                                // '.product-price_old:not(.ars-to-cny-processed)',
                                // '[data-qa="original_product_price"]:not(.ars-to-cny-processed)',
                                '.product-price_wrap > span:not(.ars-to-cny-processed)',
                                '[data-qa="product_price"] > span:not(.ars-to-cny-processed)'
                            ];

                            const priceElements = node.querySelectorAll ?
                                node.querySelectorAll(priceSelectors.join(', ')) : [];

                            if (priceElements.length > 0) {
                                shouldConvert = true;
                            }

                            // 检查元素本身是否是价格元素
                            if (node.matches && node.matches(priceSelectors.join(', '))) {
                                shouldConvert = true;
                            }
                        }
                    });
                }
            });

            if (shouldConvert && !isProcessing) {
                // 使用防抖,避免频繁处理
                clearTimeout(window.arsToCnyTimeout);
                window.arsToCnyTimeout = setTimeout(() => {
                    convertPageARSValues();
                }, 500);
            }
        });

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

    // 页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();