在接口中切換貨幣
1)原則
1.首先是意義,然後是UI。將帳戶貨幣(會計真理)與顯示貨幣(便利)和交易貨幣(實際貨幣轉換)分開。
2.零歧義。在出現混淆風險時顯示代碼+符號('US$'、'CA$'、'MXN'、'R$')。對於₴/₸/₼-始終在詳細信息中添加代碼。
3.課程誠實。可以看出:課程來源,最新更新的時刻,是否包括傭金/sprad。
4.輸入穩定性。貨幣轉換不得未經明確同意(尤其是在利率/存款形式中)「跳躍」輸入值。
5.格式本地化。分隔符,空格,貨幣符號-沿著用戶的位置;精確度按貨幣計算。
2)開關型號
顯示(僅顯示):所有結算均以帳戶貨幣進行,UI以所選貨幣顯示等效值。用於目錄、配置文件、分析。
混合體(soft convert):以選定貨幣顯示+以帳戶貨幣確認交易(我們同時顯示兩者)。
運營(硬轉換):用戶更改交易貨幣(存款/退款/利率)。我們需要明確的課程,傭金,固定時間。
規則:默認情況下,僅顯示,「硬」轉換僅在相應的流(結帳、結帳、資金轉移)中啟用。
3)主計長及住宿
上限/配置文件面板中的貨幣開關(圖標「₴/€/$」或貨幣代碼)。
選擇器:按代碼/名稱/符號搜索;精選/常用貨幣-頂部。
在表單內(存款/押金):緊湊的選擇器位於總和字段右側,旁邊是「XXX中的等效≈」提示。
移動模式:帶有列表和過濾輸入的底頁。
html
<button aria-haspopup="listbox" aria-expanded="false" class="currency-switch">UAH</button>
<ul role="listbox" class="currency-menu" hidden>
<li role="option" aria-selected="true">UAH — ₴</li>
<li role="option">USD — US$</li>
<li role="option">EUR — €</li>
<li role="option">TRY — ₺</li>
</ul>
4)格式和精度
次要單位:將金額存儲在整個最小單位(便士,美分,satoshi)中。
貨幣十進制:- 0: JPY, KRW, CLP
- 2: USD, EUR, UAH, TRY
- 3+:某些貨幣ZAR (2)、KWD (3)、加密貨幣(4-8)
- 加密貨幣:顯示多達8個符號(動態精度,但具有可讀性的下限)。
- 表數字:'font-variant-numeric: tabular-nums;'用於對齊欄。
js const fmt = (amountMinor, currency, locale) => {
const fraction = { JPY:0, KRW:0, KWD:3 }[currency]?? 2;
return new Intl.NumberFormat(locale, { style:'currency', currency, minimumFractionDigits:fraction, maximumFractionDigits:fraction })
.format(amountMinor / 10fraction);
};
fmt(200000, 'UAH', 'uk-UA'); // 2 000,00 ₴
5)課程和更新
來源:捕獲課程提供商(內部定價/銀行/FX-API)。
緩存:以合理的頻率(例如,每60-300秒)更新課程+按需增量更新。
提交時間:在完成操作時顯示「N分鐘後更新」和提交時間。
Sprad/傭金: 顯示一個明確的字符串:"匯率1 USD=36.60 UAH(包括sprad 1.5%)».
四舍五入:銀行或常規-選擇一個並記錄在政治中。
6) UX文本和解釋
等效項:"≈ 52.10-在顏色柔和的金額旁邊實時更新。
法律條款: 「實際路線和傭金將記錄在確認步驟中。」
長代碼:使用tooltips/次要字符串:「US$-美元」。
籃子裏的轉換:不要在沒有解釋的情況下改變「總數」;顯示重新計票的行。
7)可用性(A11y)
貨幣選擇器中的'role='listbox/option'。
鍵盤支持:箭頭,Enter, Type-ahead,按代碼/名稱。
閱讀SR:「顯示貨幣:UAH-烏克蘭格裏夫納」。
顏色≠唯一的意義載體(總是有代碼/文本)。
RTL:阿拉伯語行中"dir="ltr"中的數字/代碼。
8)表演和緩存
課程在具有TTL的存儲器+localStorage中(例如5分鐘)。
Butch更新:用包重新計算等效項(requestAnimationFrame, debowns 100-200 ms)。
在匯率波動<閾值(例如,0.1%)時,不要觸發多余的列表繼電器。
9) iGaming的細節
帳戶貨幣-基本報告(存款,資產負債表,歷史記錄)。
利率貨幣:通常=帳戶貨幣;如果另一個設置為-顯示雙塊:「註銷X XXX至USD(≈ Y YYY至UAH)」。
結算中的固定:在結算時按匯率而不是費率轉換獲勝-這必須在優惠券/歷史細節中可見。
存款/提取:PSP/銀行的課程和傭金-單獨一行;ETA方法。
負責任的遊戲限制:以帳戶貨幣確定;如果UI是其他貨幣-顯示兩個值。
比賽和獎品:確定獎金的貨幣;顯示時,等效項為指示性,帶有標記。
10)反模式
貨幣轉換時輸入字段中值的「神奇」變化-未經明確同意。
使用一個沒有國家代碼的「$」字符。
隱藏傭金是最新的(沒有關於sprad的行)。
混合本地和貨幣(格式為「UAH」的「en-US」)。
JPY/KRW的「2個標誌」或所有cryptocurrency的「8個標誌」的硬精度。
按照當前匯率「追溯」重新計算歷史交易-沒有標記「重新計算」。
11)設計系統令牌(示例)
json
{
"currency": {
"default": "UAH",
"displayList": ["UAH","USD","EUR","TRY","PLN","BRL","MXN"],
"fractions": { "JPY":0, "KRW":0, "KWD":3, "BTC":8 },
"showCodeWithSymbol": ["USD","CAD","AUD","NZD"],
"approxPrefix": "≈ "
},
"format": {
"tabularNums": true,
"grouping": "locale",
"negative": "−"
},
"fx": {
"ttlSec": 300,
"changeThresholdPct": 0.1,
"showSpread": true
}
}
12)Snippets
貨幣開關(React、上下文+Intl)
tsx import { createContext, useContext, useState, useMemo } from 'react';
type Cur = 'UAH' 'USD' 'EUR' 'TRY';
const CurrencyCtx = createContext<{cur:Cur,set:(c:Cur)=>void, rate:(from:Cur,to:Cur)=>number}>({cur:'UAH',set:()=>{},rate:()=>1});
export function CurrencyProvider({children}:{children:React.ReactNode}){
const [cur, set] = useState<Cur>('UAH');
// fx: получить из кэша/апи; здесь — заглушка const table = { UAH:{USD:0.027,EUR:0.025,TRY:0.89,UAH:1}, USD:{UAH:36.6,EUR:0.93,TRY:33.0,USD:1}, EUR:{UAH:39.2,USD:1.07,TRY:35.4,EUR:1}, TRY:{UAH:1.12,USD:0.030,EUR:0.028,TRY:1} };
const rate = (from:Cur,to:Cur)=> table[from][to];
const value = useMemo(()=>({cur, set, rate}),[cur]);
return <CurrencyCtx.Provider value={value}>{children}</CurrencyCtx.Provider>;
}
export function useCurrency(){ return useContext(CurrencyCtx); }
export function Money({minor, iso}:{minor:number, iso:Cur}){
const { cur, rate } = useCurrency();
const fraction = { JPY:0, KRW:0, KWD:3 }[cur as any]?? 2;
const v = (minor/10fraction) rate(iso, cur);
return <span style={{fontVariantNumeric:'tabular-nums'}}>{new Intl.NumberFormat(undefined,{style:'currency',currency:cur, minimumFractionDigits:fraction, maximumFractionDigits:fraction}).format(v)}</span>;
}
雙重顯示(操作轉換)
html
<div class="amount">
<label>Сумма депозита</label>
<div class="row">
<input type="number" inputmode="decimal" aria-describedby="fxnote">
<select aria-label="Валюта операции">
<option>USD</option><option>EUR</option><option>UAH</option>
</select>
</div>
<small id="fxnote">≈ 2 000,00 ₴ · Курс будет зафиксирован на следующем шаге</small>
</div>
13)度量標準
FX latency:從貨幣切換到更新所有字段的時間(目標≤ 150毫秒)。
Correctness rate:以「不正確金額」(<0.2%)向劄幌申請的比例。
Display vs account mismatch:用戶混淆貨幣的事件(通過減少提示)。
CTR課程提示:點擊查看有關課程/傭金的更多信息。
轉換中的Abandon結賬:與「突然」金額變化有關的故障率。
14) QA支票清單
含義和透明度
- 任何地方都可以看到帳戶和/或交易的貨幣。
- 顯示了$的國家代碼(US$, CA$等)。
- 有關於課程、更新日期和sprad/傭金的行。
格式和準確性
- 貨幣十進制(JPY=0, KWD=3, crypto=最多8)。
- 數字/貨幣區域對應於UI語言。
- 歷史操作未按「當前課程」重新計算而沒有標記。
行為行為
- 貨幣轉換不會在沒有確認的情況下改變輸入。
- 「≈」等效項以平穩和快速的方式更新。
- 鍵盤貨幣選擇器可用,Type-ahead工作。
iGaming特點
- 優惠券:註銷/贏利及其貨幣已簽名,固定匯率已註明。
- 在結帳處:PSP/銀行傭金可單獨看到。
- 限制:顯示兩個值(帳戶和顯示)。
RTL/A11y
- 在RTL中正確讀取代碼/和數(數字為'dir='ltr')。
- 對比度和焦點指標對應於AA。
15)設計系統中的文檔
組件:「CurrencySwitch」,「Money」,「FxNote」,「DualAmount」。
精度/四舍五入策略和單個格式化功能。
規則: 「何時只顯示」,「何時進行硬轉換」,「如何顯示sprad。」
貨幣目錄:代碼、符號、位、區域字符沖突。
Do/Do n't Gallery: 「$not code」、自動噴射輸入、隱藏傭金。
簡短的摘要
貨幣轉換不僅僅是「₴/€/$」選擇器。這是一種清晰的貨幣模型(帳戶貨幣vs映射vs手術),具有傭金的誠實路線,正確的本地格式以及精益的輸入字段行為。記錄設計系統中的規則,自動化課程的格式和緩存-用戶將自信地處理金額,而不必懷疑數字,而不必在「隱形」sprads上虧損。