返回 DeepSeek-Reasonix
money.ts
根目录 / desktop / frontend / src / lib / money.ts
1 const DEFAULT_CURRENCY_SYMBOL = "\u00A5";
2
3 export function currencySymbol(currency?: string): string {
4 const value = (currency || DEFAULT_CURRENCY_SYMBOL).trim();
5 const lower = value.toLowerCase();
6
7 if (/^(cny|rmb|yuan|renminbi|cnh)$/.test(lower)) return DEFAULT_CURRENCY_SYMBOL;
8 if (/^(usd|dollar|dollars|us dollar|us dollars|us\$)$/.test(lower)) return "$";
9 if (/^(eur|euro|euros)$/.test(lower)) return "\u20AC";
10 if (/^(gbp|pound|pounds|sterling)$/.test(lower)) return "\u00A3";
11 if (/^(jpy|yen)$/.test(lower)) return DEFAULT_CURRENCY_SYMBOL;
12 if (value === "\uFFE5" || value === "\u00A5") return DEFAULT_CURRENCY_SYMBOL;
13 // contains, not equals \u2014 keep multi-char symbols (A$, HK$) off the \u00A5 default.
14 if (/\p{Sc}/u.test(value)) return value;
15 if (/^[a-z]{3}$/i.test(value)) return `${value.toUpperCase()} `;
16
17 return DEFAULT_CURRENCY_SYMBOL;
18 }
19
20 export function formatMoney(amount?: number, currency?: string, empty: "zero" | "dash" = "zero"): string {
21 const symbol = currencySymbol(currency);
22 if (typeof amount !== "number" || amount <= 0) {
23 return empty === "dash" ? "-" : `${symbol}0.0000`;
24 }
25 return `${symbol}${amount < 1 ? amount.toFixed(4) : amount.toFixed(2)}`;
26 }
27
28 interface MoneyFormatOptions {
29 locale?: string;
30 empty?: "zero" | "dash";
31 }
32
33 function isoCurrencyCode(currency?: string): string | null {
34 const value = (currency || "").trim();
35 if (!/^[a-z]{3}$/i.test(value)) return null;
36 const code = value.toUpperCase();
37 try {
38 new Intl.NumberFormat("en", { style: "currency", currency: code }).format(0);
39 return code;
40 } catch {
41 return null;
42 }
43 }
44
45 export function formatMoneyLocalized(amount?: number, currency?: string, options: MoneyFormatOptions = {}): string {
46 const empty = options.empty ?? "zero";
47 if (typeof amount !== "number" || amount <= 0) {
48 return empty === "dash" ? "-" : formatMoney(0, currency, empty);
49 }
50
51 const code = isoCurrencyCode(currency);
52 if (!code) return formatMoney(amount, currency, empty);
53
54 const digits = amount < 1 ? 4 : 2;
55 return new Intl.NumberFormat(options.locale, {
56 style: "currency",
57 currency: code,
58 minimumFractionDigits: digits,
59 maximumFractionDigits: digits,
60 }).format(amount);
61 }
62
62 lines TYPESCRIPT