feat: Improve currency exchange rate fetching in BillingManager by adding a primary source from the Central Bank of Russia and a fallback to an alternative API, along with updates to currency formatting for better precision.
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m17s

This commit is contained in:
2025-12-06 14:50:45 +07:00
parent ad75ca8ff5
commit fee74c377f
+29 -6
View File
@@ -116,8 +116,28 @@ function BillingManager() {
const fetchExchangeRates = async () => { const fetchExchangeRates = async () => {
setRatesLoading(true); setRatesLoading(true);
try { try {
const response = await axios.get('https://api.exchangerate-api.com/v4/latest/USD'); // Основной источник: ЦБ РФ (base = RUB)
const rates = response.data.rates; const cbr = await axios.get('https://www.cbr-xml-daily.ru/latest.js');
const rubPerUsd = cbr.data && cbr.data.rates?.USD ? 1 / Number(cbr.data.rates.USD) : null;
const rubPerEur = cbr.data && cbr.data.rates?.EUR ? 1 / Number(cbr.data.rates.EUR) : null;
if (rubPerUsd) {
const eurPerUsd = rubPerEur ? rubPerUsd / rubPerEur : 1;
setExchangeRates({
USD: 1,
EUR: eurPerUsd, // сколько EUR за 1 USD
RUB: rubPerUsd // сколько RUB за 1 USD
});
return;
}
} catch (error) {
console.warn('ЦБ недоступен, пробуем резервный источник:', error?.message);
}
try {
// Резервный источник: open.er-api
const response = await axios.get('https://open.er-api.com/v6/latest/USD');
const rates = response.data?.rates || {};
setExchangeRates({ setExchangeRates({
USD: 1, USD: 1,
EUR: rates.EUR || 1, EUR: rates.EUR || 1,
@@ -125,7 +145,8 @@ function BillingManager() {
}); });
} catch (error) { } catch (error) {
console.error('Ошибка при загрузке курсов валют:', error); console.error('Ошибка при загрузке курсов валют:', error);
setExchangeRates({ USD: 1, EUR: 0.85, RUB: 95 }); // Фолбек на разумные значения
setExchangeRates({ USD: 1, EUR: 1.05, RUB: 95 });
} finally { } finally {
setRatesLoading(false); setRatesLoading(false);
} }
@@ -233,11 +254,12 @@ function BillingManager() {
} }
function formatCurrency(amount, currency = 'USD') { function formatCurrency(amount, currency = 'USD') {
if (!amount) return '—'; if (amount === undefined || amount === null || amount === '') return '—';
return new Intl.NumberFormat('ru-RU', { return new Intl.NumberFormat('ru-RU', {
style: 'currency', style: 'currency',
currency: currency, currency: currency,
maximumFractionDigits: 0 minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount); }).format(amount);
} }
@@ -246,7 +268,8 @@ function BillingManager() {
return new Intl.NumberFormat('ru-RU', { return new Intl.NumberFormat('ru-RU', {
style: 'currency', style: 'currency',
currency: 'RUB', currency: 'RUB',
maximumFractionDigits: 0 minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(rubAmount); }).format(rubAmount);
} }