61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
import { formatMoney } from "@vmall/shared";
|
|
import type { Currency } from "@vmall/shared";
|
|
|
|
export function usePrice() {
|
|
const { currency } = usePrefs();
|
|
const { locale } = useI18n();
|
|
const { $api } = useNuxtApp();
|
|
const currencies = useState<Currency[]>("mall-currencies", () => []);
|
|
const cache = useState<Map<string, number>>("mall-price-cache", () => new Map());
|
|
const currencyRequest = useState<Promise<Currency[]> | null>("mall-currency-request", () => null);
|
|
|
|
async function ensureCurrencies(): Promise<Currency[]> {
|
|
if (currencies.value.length > 0) return currencies.value;
|
|
if (!currencyRequest.value) {
|
|
currencyRequest.value = $api.listCurrencies().then((list) => {
|
|
currencies.value = list;
|
|
return list;
|
|
}).finally(() => {
|
|
currencyRequest.value = null;
|
|
});
|
|
}
|
|
return currencyRequest.value;
|
|
}
|
|
|
|
function exponentFor(code: string): number {
|
|
return currencies.value.find((item) => item.code === code)?.exponent ?? 2;
|
|
}
|
|
|
|
async function convertAmount(amountMinor: number, from: string, to = currency.value): Promise<number> {
|
|
if (from === to) return amountMinor;
|
|
const key = `${amountMinor}:${from}:${to}`;
|
|
const cached = cache.value.get(key);
|
|
if (cached !== undefined) return cached;
|
|
const converted = await $api.convert(amountMinor, from, to);
|
|
cache.value.set(key, converted.amount_minor);
|
|
return converted.amount_minor;
|
|
}
|
|
|
|
async function formatPrice(amountMinor: number, from: string, to = currency.value): Promise<string> {
|
|
await ensureCurrencies();
|
|
const amount = await convertAmount(amountMinor, from, to);
|
|
return formatMoney(amount, to, exponentFor(to), locale.value);
|
|
}
|
|
|
|
async function formatAmount(amountMinor: number, code: string): Promise<string> {
|
|
await ensureCurrencies();
|
|
return formatMoney(amountMinor, code, exponentFor(code), locale.value);
|
|
}
|
|
|
|
return {
|
|
currency,
|
|
currencies,
|
|
cache,
|
|
ensureCurrencies,
|
|
exponentFor,
|
|
convertAmount,
|
|
formatPrice,
|
|
formatAmount,
|
|
};
|
|
}
|