feat: 接入公开币种目录并统一多币种金额与语言初始化处理

This commit is contained in:
2026-05-21 15:14:00 +08:00
parent 626914feb6
commit 6b18e25766
27 changed files with 277 additions and 94 deletions

View File

@@ -2,20 +2,40 @@
* 与后端约定:金额存最小货币单位(如 NPR 2 位小数 → 分);展示时除以 10^decimals。
*/
import { usePlayerSessionStore } from "@/stores/player-session-store";
const DEFAULT_DECIMAL_PLACES = 2;
export function getCurrencyDecimalPlaces(currencyCode: string): number {
const code = currencyCode.trim().toUpperCase();
const row = usePlayerSessionStore
.getState()
.currencies.find((item) => item.code === code);
const decimals = row?.decimal_places;
if (typeof decimals === "number" && Number.isFinite(decimals) && decimals >= 0) {
return decimals;
}
return DEFAULT_DECIMAL_PLACES;
}
export function formatMinorAsCurrency(
minor: number | string,
currencyCode: string,
decimalPlaces = DEFAULT_DECIMAL_PLACES,
decimalPlaces?: number,
): string {
const resolvedDecimalPlaces =
typeof decimalPlaces === "number" && Number.isFinite(decimalPlaces) && decimalPlaces >= 0
? decimalPlaces
: getCurrencyDecimalPlaces(currencyCode);
const n = typeof minor === "string" ? Number(minor) : minor;
if (!Number.isFinite(n)) return `${currencyCode}`;
const divisor = 10 ** decimalPlaces;
const divisor = 10 ** resolvedDecimalPlaces;
const major = n / divisor;
return `${currencyCode} ${major.toLocaleString(undefined, {
minimumFractionDigits: decimalPlaces,
maximumFractionDigits: decimalPlaces,
minimumFractionDigits: resolvedDecimalPlaces,
maximumFractionDigits: resolvedDecimalPlaces,
})}`;
}
@@ -24,13 +44,22 @@ export function formatMinorAsCurrency(
*/
export function parseDecimalInputToMinor(
raw: string,
decimalPlaces = DEFAULT_DECIMAL_PLACES,
decimalPlacesOrCurrencyCode?: number | string,
): number | null {
const decimalPlaces =
typeof decimalPlacesOrCurrencyCode === "string"
? getCurrencyDecimalPlaces(decimalPlacesOrCurrencyCode)
: typeof decimalPlacesOrCurrencyCode === "number" &&
Number.isFinite(decimalPlacesOrCurrencyCode) &&
decimalPlacesOrCurrencyCode >= 0
? decimalPlacesOrCurrencyCode
: decimalPlacesOrCurrencyCode;
const resolvedDecimalPlaces = decimalPlaces ?? DEFAULT_DECIMAL_PLACES;
const cleaned = raw.replace(/,/g, "").trim();
if (cleaned === "") return null;
const n = Number(cleaned);
if (!Number.isFinite(n) || n < 0) return null;
const factor = 10 ** decimalPlaces;
const factor = 10 ** resolvedDecimalPlaces;
const minor = Math.round(n * factor);
if (!Number.isSafeInteger(minor)) return null;
return minor;