Greasy Fork is available in English.
Wargaming商店阿根廷区将ARS货币价值转换为CNY并附代充折扣显示
当前为
// ==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();
}
})();