diff --git a/src/components/LanguageSelector.vue b/src/components/LanguageSelector.vue new file mode 100644 index 0000000..4c913cb --- /dev/null +++ b/src/components/LanguageSelector.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue index 8df3d4c..d7735e0 100644 --- a/src/components/NavBar.vue +++ b/src/components/NavBar.vue @@ -29,7 +29,7 @@ :max-height="400" direction="left" > - + @@ -50,6 +50,13 @@ {{ $t('navbar.item.dashboard') }} + + + {{ $t('navbar.item.language') }} + + + + +
+ +
+
diff --git a/src/components/PageFooter.vue b/src/components/PageFooter.vue index b150bd0..68f49f4 100644 --- a/src/components/PageFooter.vue +++ b/src/components/PageFooter.vue @@ -26,17 +26,7 @@
@@ -46,14 +36,10 @@ diff --git a/src/components/SiderBar.vue b/src/components/SiderBar.vue new file mode 100644 index 0000000..58bde63 --- /dev/null +++ b/src/components/SiderBar.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/TradeVisual.vue b/src/components/TradeVisual.vue new file mode 100644 index 0000000..d8234ff --- /dev/null +++ b/src/components/TradeVisual.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/components/TransactionDetailPanel.vue b/src/components/TransactionDetailPanel.vue new file mode 100644 index 0000000..9b3a91b --- /dev/null +++ b/src/components/TransactionDetailPanel.vue @@ -0,0 +1,423 @@ + + + + + diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 9616bfe..b9f2ae9 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -1,6 +1,99 @@ { "dashboard": { - "title": "Dashboard" + "title": "Dashboard", + "subtitle": "Real-time monitoring of the settlement window and target block", + "forecast": { + "title": "Settlement Window Forecast", + "desc": "Stay ahead of settlement and plan your funding with confidence", + "refresh": "Refresh", + "active": "Active", + "windowId": "Pending Window ID", + "settlementBlock": "Target Settlement Block", + "blocksRemaining": "Blocks Remaining", + "blocksUnit": "blocks", + "reached": "Target block reached", + "lastUpdated": { + "label": "Last updated at {time}", + "justNow": "just now", + "minutesAgo": "{minutes} minutes ago", + "hoursAgo": "{hours} hours ago", + "daysAgo": "{days} days ago" + }, + "msg": { + "fetchFailed": "Failed to fetch settlement window forecast" + } + }, + "overview": { + "msg": { + "fetchFailed": "Failed to fetch dashboard overview" + } + }, + "accountBalances": { + "title": "Account Balances", + "desc": "See the available assets in your account at a glance", + "balance": "Balance", + "empty": "No account balances" + }, + "cumulativeTradeCount": { + "title": "Total Trades", + "desc": "Track the total trading activity linked to your account", + "label": "Trades" + }, + "asset": "Asset Address", + "settlementNetAmounts": { + "title": "Settlement Net Amounts", + "desc": "See how your funds will change after this settlement", + "payable": "Payable Amount", + "receivable": "Receivable Amount", + "amount": "Net Amount", + "empty": "No net settlement obligations", + "msg": { + "fetchFailed": "Failed to fetch net settlement positions" + } + }, + "cumulativeTradeAmounts": { + "title": "Total Trade Amounts", + "desc": "Review the total value of trades linked to your account", + "amount": "Cumulative Gross Amount", + "empty": "No cumulative gross trade amounts", + "msg": { + "fetchFailed": "Failed to fetch settlement asset requirements" + } + }, + "liquidityBufferDebts": { + "title": "Liquidity Buffer Balance", + "desc": "Keep track of funding support that is still to be repaid", + "required": "Debt Amount", + "available": "Available Balance", + "borrow": "Debt Amount", + "amount": "Debt Amount", + "empty": "No liquidity buffer balance", + "msg": { + "fetchFailed": "Failed to fetch liquidity shortfalls" + } + } + }, + "account": { + "title": "Account", + "subtitle": "View your account and organization profile", + "profileCardTitle": "Profile", + "organizationCardTitle": "Organization", + "actions": { + "copy": "Copy" + }, + "msg": { + "copySuccess": "{label} copied", + "copyFailed": "Copy failed" + }, + "fields": { + "displayName": "Display Name", + "role": "Role", + "accountId": "Account ID", + "organizationCode": "Organization Code", + "organizationId": "Organization ID", + "organizationName": "Organization Name", + "walletAddress": "Wallet Address" + } }, "footer": { "product": "Product", @@ -224,7 +317,8 @@ }, "item": { "logout": "Logout", - "dashboard": "Dashboard" + "dashboard": "Dashboard", + "language": "Language" } }, "notFound": { @@ -243,5 +337,145 @@ "failedVerify": "Failed to verify.", "success": "Login success" } + }, + "menu": { + "dashboard": "Dashboard", + "account": "Account", + "records": "Records", + "send": "Send", + "transactions": "Transactions", + "verify": "Verify" + }, + "send": { + "title": "Send Transaction", + "subtitle": "Choose a counterparty and assets to submit a netting settlement transaction", + "form": { + "title": "Transaction Details", + "desc": "The transaction will enter the next settlement window once submitted", + "counterparty": "Counterparty", + "counterpartyPlaceholder": "Search and select an organization", + "counterpartyEmpty": "No tradable organizations available", + "youSend": "You Send", + "youReceive": "You Receive", + "asset": "Asset", + "amount": "Amount", + "amountPlaceholder": "Enter an amount", + "submit": "Submit Transaction", + "reset": "Reset" + }, + "visual": { + "title": "Transaction Preview", + "desc": "See the counterparties and asset flow at a glance", + "you": "Initiator (You)", + "counterparty": "Recipient", + "counterpartyPlaceholder": "Select a counterparty", + "send": "Send", + "receive": "Receive" + }, + "msg": { + "fetchOrganizationsFailed": "Failed to fetch tradable organizations", + "submitFailed": "Failed to submit transaction, please try again later", + "validation": { + "counterparty": "Please select a counterparty", + "sendAmount": "Please enter a valid send amount", + "receiveAmount": "Please enter a valid receive amount" + } + }, + "errors": { + "4001": "The receiving organization does not exist or is unavailable", + "4002": "You cannot trade with your own organization" + }, + "success": { + "title": "Transaction Submitted", + "desc": "The transaction has been submitted to the settlement window", + "transactionId": "Transaction ID", + "again": "Send Another", + "viewDetail": "View Transaction Details" + }, + "failure": { + "title": "Transaction Failed", + "close": "Close", + "retry": "Retry" + } + }, + "transactions": { + "title": "Transactions", + "subtitle": "View all platform transactions and track settlement status in real time", + "filter": { + "all": "All Transactions", + "related": "Related to Me" + }, + "table": { + "id": "Transaction ID", + "createdBy": "Submitted By", + "sender": "Sender", + "send": "Sent Asset", + "receiver": "Receiver", + "receive": "Received Asset", + "status": "Status", + "chainId": "Chain", + "windowId": "Settlement Window", + "createdAt": "Created At", + "settledAt": "Settled At", + "operation": "Action" + }, + "status": { + "submitted": "Submitted", + "settled": "Settled", + "failed": "Failed" + }, + "action": { + "view": "View" + }, + "empty": "No transactions yet", + "msg": { + "fetchFailed": "Failed to fetch transactions" + } + }, + "transactionDetail": { + "title": "Transaction Detail", + "subtitle": "View the full details and settlement status of this transaction", + "back": "Back to Transactions", + "parties": "Parties", + "progress": "Transaction Progress", + "basicInfo": "Basic Information", + "hashInfo": "On-chain Hashes", + "copy": "Copy", + "copySuccess": "{label} copied", + "copyFailed": "Copy failed", + "notFound": "Transaction not found or not accessible", + "steps": { + "submitted": "Submitted", + "settled": "Settled", + "failed": "Settlement Failed" + }, + "fields": { + "id": "Transaction ID", + "status": "Status", + "createdBy": "Submitted By", + "sender": "Sender", + "receiver": "Receiver", + "send": "Send", + "receive": "Receive", + "chainId": "Chain", + "windowId": "Settlement Window", + "createdAt": "Created At", + "settledAt": "Settled At", + "failureReason": "Failure Reason", + "submissionHash": "Submission Hash", + "settlementHash": "Settlement Hash" + }, + "msg": { + "fetchFailed": "Failed to fetch transaction detail" + } + }, + "verify": { + "title": "Verify Transaction", + "subtitle": "Enter an on-chain transaction hash to verify whether it truly exists", + "placeholder": "Enter transaction hash (starting with 0x)", + "button": "Verify", + "invalidHash": "Please enter a valid transaction hash", + "failDescription": "No matching transaction found, verification failed", + "stamp": "Verified" } } diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 91f2c94..2ab6f0d 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -1,6 +1,99 @@ { "dashboard": { - "title": "仪表板" + "title": "仪表板", + "subtitle": "实时监控净额结算窗口与目标结算区块", + "forecast": { + "title": "结算窗口预测", + "desc": "掌握本轮结算进度,提前做好资金安排", + "refresh": "刷新", + "active": "活跃中", + "windowId": "待结算窗口 ID", + "settlementBlock": "目标结算区块", + "blocksRemaining": "剩余区块数", + "blocksUnit": "个区块", + "reached": "已到达目标区块", + "lastUpdated": { + "label": "最后更新于 {time}", + "justNow": "刚刚", + "minutesAgo": "{minutes} 分钟前", + "hoursAgo": "{hours} 小时前", + "daysAgo": "{days} 天前" + }, + "msg": { + "fetchFailed": "获取结算窗口预测失败" + } + }, + "overview": { + "msg": { + "fetchFailed": "获取仪表板概览失败" + } + }, + "accountBalances": { + "title": "账户余额", + "desc": "实时掌握账户中各项资产的可用余额", + "balance": "余额", + "empty": "当前无账户余额" + }, + "cumulativeTradeCount": { + "title": "累计交易笔数", + "desc": "了解账户累计参与的交易规模", + "label": "交易笔数" + }, + "asset": "资产地址", + "settlementNetAmounts": { + "title": "结算净额", + "desc": "一目了然地了解本轮结算后的资金变化", + "payable": "应付数量", + "receivable": "应收数量", + "amount": "净额", + "empty": "当前没有净结算义务", + "msg": { + "fetchFailed": "获取净结算头寸失败" + } + }, + "cumulativeTradeAmounts": { + "title": "累计交易金额", + "desc": "汇总查看账户参与的累计交易金额", + "amount": "累计原始金额", + "empty": "当前没有累计原始交易金额", + "msg": { + "fetchFailed": "获取结算资产需求失败" + } + }, + "liquidityBufferDebts": { + "title": "流动性缓冲欠款", + "desc": "及时了解待归还的流动性支持金额", + "required": "欠款金额", + "available": "当前余额", + "borrow": "欠款金额", + "amount": "欠款金额", + "empty": "当前没有流动性缓冲欠款", + "msg": { + "fetchFailed": "获取流动性缺口失败" + } + } + }, + "account": { + "title": "账户中心", + "subtitle": "查看当前账户与所属机构信息", + "profileCardTitle": "账户资料", + "organizationCardTitle": "机构信息", + "actions": { + "copy": "复制" + }, + "msg": { + "copySuccess": "{label} 已复制", + "copyFailed": "复制失败" + }, + "fields": { + "displayName": "显示名称", + "role": "角色", + "accountId": "账户 ID", + "organizationCode": "机构代码", + "organizationId": "机构 ID", + "organizationName": "机构名称", + "walletAddress": "钱包地址" + } }, "footer": { "product": "产品", @@ -224,7 +317,8 @@ }, "item": { "logout": "注销", - "dashboard": "仪表板" + "dashboard": "仪表板", + "language": "语言" } }, "notFound": { @@ -241,5 +335,145 @@ "failedVerify": "验证失败。", "success": "登录成功" } + }, + "menu": { + "dashboard": "仪表板", + "account": "帐户", + "records": "交易记录", + "send": "发起交易", + "transactions": "交易", + "verify": "验证" + }, + "send": { + "title": "发起交易", + "subtitle": "选择交易对象与资产,提交一笔净额结算交易", + "form": { + "title": "交易信息", + "desc": "交易提交后将进入下一个结算窗口,等待净额结算完成", + "counterparty": "交易对象", + "counterpartyPlaceholder": "搜索并选择机构", + "counterpartyEmpty": "暂无可交易机构", + "youSend": "您发送", + "youReceive": "您收到", + "asset": "资产", + "amount": "数量", + "amountPlaceholder": "请输入数量", + "submit": "提交交易", + "reset": "重置" + }, + "visual": { + "title": "交易预览", + "desc": "交易双方与资产流向一目了然", + "you": "发起方(我方)", + "counterparty": "接收方", + "counterpartyPlaceholder": "请选择交易对象", + "send": "发送", + "receive": "接收" + }, + "msg": { + "fetchOrganizationsFailed": "获取可交易机构列表失败", + "submitFailed": "提交交易失败,请稍后重试", + "validation": { + "counterparty": "请选择交易对象", + "sendAmount": "请输入有效的发送数量", + "receiveAmount": "请输入有效的接收数量" + } + }, + "errors": { + "4001": "接收方机构不存在或不可用", + "4002": "不能与当前所属机构进行交易" + }, + "success": { + "title": "交易提交成功", + "desc": "交易已提交到结算窗口,等待结算完成", + "transactionId": "交易 ID", + "again": "继续填写下一个", + "viewDetail": "查看交易详情" + }, + "failure": { + "title": "交易提交失败", + "close": "关闭", + "retry": "重试" + } + }, + "transactions": { + "title": "交易", + "subtitle": "查看平台全部交易记录,实时追踪结算状态", + "filter": { + "all": "全部交易", + "related": "与我相关" + }, + "table": { + "id": "交易 ID", + "createdBy": "提交机构", + "sender": "发送方", + "send": "发送资产", + "receiver": "接收方", + "receive": "接收资产", + "status": "状态", + "chainId": "区块链网络", + "windowId": "结算窗口", + "createdAt": "创建时间", + "settledAt": "结算时间", + "operation": "操作" + }, + "status": { + "submitted": "已提交", + "settled": "已结算", + "failed": "结算失败" + }, + "action": { + "view": "查看" + }, + "empty": "暂无交易记录", + "msg": { + "fetchFailed": "获取交易记录失败" + } + }, + "transactionDetail": { + "title": "交易详情", + "subtitle": "查看该笔交易的完整信息与结算状态", + "back": "返回交易列表", + "parties": "交易双方", + "progress": "交易进度", + "basicInfo": "基本信息", + "hashInfo": "链上哈希", + "copy": "复制", + "copySuccess": "{label} 已复制", + "copyFailed": "复制失败", + "notFound": "交易记录不存在或无权查看", + "steps": { + "submitted": "已提交", + "settled": "已结算", + "failed": "结算失败" + }, + "fields": { + "id": "交易 ID", + "status": "状态", + "createdBy": "提交机构", + "sender": "发送方", + "receiver": "接收方", + "send": "发送", + "receive": "接收", + "chainId": "区块链网络", + "windowId": "结算窗口", + "createdAt": "创建时间", + "settledAt": "结算时间", + "failureReason": "失败原因", + "submissionHash": "提交交易哈希", + "settlementHash": "结算交易哈希" + }, + "msg": { + "fetchFailed": "获取交易详情失败" + } + }, + "verify": { + "title": "交易验证", + "subtitle": "输入链上交易哈希,验证该交易是否真实存在", + "placeholder": "请输入交易哈希(0x开头)", + "button": "验证", + "invalidHash": "请输入有效的交易哈希", + "failDescription": "未找到对应交易,验证失败", + "stamp": "验证通过" } } diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index 9feb361..78d90ea 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -1,6 +1,99 @@ { "dashboard": { - "title": "儀表板" + "title": "儀表板", + "subtitle": "即時監控淨額結算窗口與目標結算區塊", + "forecast": { + "title": "結算窗口預測", + "desc": "掌握本輪結算進度,提前做好資金安排", + "refresh": "刷新", + "active": "活躍中", + "windowId": "待結算窗口 ID", + "settlementBlock": "目標結算區塊", + "blocksRemaining": "剩餘區塊數", + "blocksUnit": "個區塊", + "reached": "已到達目標區塊", + "lastUpdated": { + "label": "最後更新於 {time}", + "justNow": "剛剛", + "minutesAgo": "{minutes} 分鐘前", + "hoursAgo": "{hours} 小時前", + "daysAgo": "{days} 天前" + }, + "msg": { + "fetchFailed": "獲取結算窗口預測失敗" + } + }, + "overview": { + "msg": { + "fetchFailed": "獲取儀表板概覽失敗" + } + }, + "accountBalances": { + "title": "帳戶餘額", + "desc": "即時掌握帳戶中各項資產的可用餘額", + "balance": "餘額", + "empty": "目前無帳戶餘額" + }, + "cumulativeTradeCount": { + "title": "累計交易筆數", + "desc": "了解帳戶累計參與的交易規模", + "label": "交易筆數" + }, + "asset": "資產地址", + "settlementNetAmounts": { + "title": "結算淨額", + "desc": "一目了然地了解本輪結算後的資金變化", + "payable": "應付數量", + "receivable": "應收數量", + "amount": "淨額", + "empty": "目前沒有淨結算義務", + "msg": { + "fetchFailed": "獲取淨結算頭寸失敗" + } + }, + "cumulativeTradeAmounts": { + "title": "累計交易金額", + "desc": "彙總查看帳戶參與的累計交易金額", + "amount": "累計原始金額", + "empty": "目前沒有累計原始交易金額", + "msg": { + "fetchFailed": "獲取結算資產需求失敗" + } + }, + "liquidityBufferDebts": { + "title": "流動性緩衝欠款", + "desc": "及時了解待歸還的流動性支援金額", + "required": "欠款金額", + "available": "目前餘額", + "borrow": "欠款金額", + "amount": "欠款金額", + "empty": "目前沒有流動性緩衝欠款", + "msg": { + "fetchFailed": "獲取流動性缺口失敗" + } + } + }, + "account": { + "title": "帳戶中心", + "subtitle": "檢視目前帳戶與所屬機構資訊", + "profileCardTitle": "帳戶資料", + "organizationCardTitle": "機構資訊", + "actions": { + "copy": "複製" + }, + "msg": { + "copySuccess": "{label} 已複製", + "copyFailed": "複製失敗" + }, + "fields": { + "displayName": "顯示名稱", + "role": "角色", + "accountId": "帳戶 ID", + "organizationCode": "機構代碼", + "organizationId": "機構 ID", + "organizationName": "機構名稱", + "walletAddress": "錢包地址" + } }, "footer": { "product": "產品", @@ -224,7 +317,8 @@ }, "item": { "logout": "註銷", - "dashboard": "儀表板" + "dashboard": "儀表板", + "language": "語言" } }, "notFound": { @@ -241,5 +335,145 @@ "failedVerify": "驗證失敗。", "success": "登入成功" } + }, + "menu": { + "dashboard": "儀表板", + "account": "帳戶", + "records": "交易記錄", + "send": "發起交易", + "transactions": "交易", + "verify": "驗證" + }, + "send": { + "title": "發起交易", + "subtitle": "選擇交易對象與資產,提交一筆淨額結算交易", + "form": { + "title": "交易資訊", + "desc": "交易提交後將進入下一個結算窗口,等待淨額結算完成", + "counterparty": "交易對象", + "counterpartyPlaceholder": "搜尋並選擇機構", + "counterpartyEmpty": "暫無可交易機構", + "youSend": "您發送", + "youReceive": "您收到", + "asset": "資產", + "amount": "數量", + "amountPlaceholder": "請輸入數量", + "submit": "提交交易", + "reset": "重置" + }, + "visual": { + "title": "交易預覽", + "desc": "交易雙方與資產流向一目了然", + "you": "發起方(我方)", + "counterparty": "接收方", + "counterpartyPlaceholder": "請選擇交易對象", + "send": "發送", + "receive": "接收" + }, + "msg": { + "fetchOrganizationsFailed": "獲取可交易機構列表失敗", + "submitFailed": "提交交易失敗,請稍後重試", + "validation": { + "counterparty": "請選擇交易對象", + "sendAmount": "請輸入有效的發送數量", + "receiveAmount": "請輸入有效的接收數量" + } + }, + "errors": { + "4001": "接收方機構不存在或不可用", + "4002": "不能與當前所屬機構進行交易" + }, + "success": { + "title": "交易提交成功", + "desc": "交易已提交到結算窗口,等待結算完成", + "transactionId": "交易 ID", + "again": "繼續填寫下一個", + "viewDetail": "查看交易詳情" + }, + "failure": { + "title": "交易提交失敗", + "close": "關閉", + "retry": "重試" + } + }, + "transactions": { + "title": "交易", + "subtitle": "查看平台全部交易記錄,即時追蹤結算狀態", + "filter": { + "all": "全部交易", + "related": "與我相關" + }, + "table": { + "id": "交易 ID", + "createdBy": "提交機構", + "sender": "發送方", + "send": "發送資產", + "receiver": "接收方", + "receive": "接收資產", + "status": "狀態", + "chainId": "區塊鏈網路", + "windowId": "結算窗口", + "createdAt": "建立時間", + "settledAt": "結算時間", + "operation": "操作" + }, + "status": { + "submitted": "已提交", + "settled": "已結算", + "failed": "結算失敗" + }, + "action": { + "view": "查看" + }, + "empty": "暫無交易記錄", + "msg": { + "fetchFailed": "獲取交易記錄失敗" + } + }, + "transactionDetail": { + "title": "交易詳情", + "subtitle": "查看該筆交易的完整信息與結算狀態", + "back": "返回交易列表", + "parties": "交易雙方", + "progress": "交易進度", + "basicInfo": "基本信息", + "hashInfo": "鏈上哈希", + "copy": "複製", + "copySuccess": "{label} 已複製", + "copyFailed": "複製失敗", + "notFound": "交易記錄不存在或無權查看", + "steps": { + "submitted": "已提交", + "settled": "已結算", + "failed": "結算失敗" + }, + "fields": { + "id": "交易 ID", + "status": "狀態", + "createdBy": "提交機構", + "sender": "發送方", + "receiver": "接收方", + "send": "發送", + "receive": "接收", + "chainId": "區塊鏈網路", + "windowId": "結算窗口", + "createdAt": "建立時間", + "settledAt": "結算時間", + "failureReason": "失敗原因", + "submissionHash": "提交交易哈希", + "settlementHash": "結算交易哈希" + }, + "msg": { + "fetchFailed": "獲取交易詳情失敗" + } + }, + "verify": { + "title": "交易驗證", + "subtitle": "輸入鏈上交易哈希,驗證該交易是否真實存在", + "placeholder": "請輸入交易哈希(0x開頭)", + "button": "驗證", + "invalidHash": "請輸入有效的交易哈希", + "failDescription": "未找到對應交易,驗證失敗", + "stamp": "驗證通過" } } diff --git a/src/layouts/AppLayout.vue b/src/layouts/AppLayout.vue index eeeb97d..78a1d9e 100644 --- a/src/layouts/AppLayout.vue +++ b/src/layouts/AppLayout.vue @@ -1,4 +1,61 @@ + + + + diff --git a/src/router/index.js b/src/router/index.js index d68fd4d..79fd08c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -36,6 +36,31 @@ const routes = computed(() => [ meta: { title: t('dashboard.title') }, component: () => import('@/views/DashboardView.vue'), }, + { + path: 'send', + meta: { title: t('send.title') }, + component: () => import('@/views/SendView.vue'), + }, + { + path: 'transactions', + meta: { title: t('transactions.title') }, + component: () => import('@/views/TransactionsView.vue'), + }, + { + path: 'transactions/:id', + meta: { title: t('transactionDetail.title') }, + component: () => import('@/views/TransactionDetailView.vue'), + }, + { + path: 'verify', + meta: { title: t('verify.title') }, + component: () => import('@/views/VerifyView.vue'), + }, + { + path: 'account', + meta: { title: t('account.title') }, + component: () => import('@/views/AccountView.vue'), + }, ], }, ]) diff --git a/src/utils/assets.js b/src/utils/assets.js new file mode 100644 index 0000000..e2c153e --- /dev/null +++ b/src/utils/assets.js @@ -0,0 +1,81 @@ +// 可交易资产的元数据映射 +export const ASSETS = { + USDC: { code: 'USDC', name: 'Mock USDC', symbol: 'mUSDC', decimals: 6 }, + BOND: { code: 'BOND', name: 'Mock Bond', symbol: 'mBOND', decimals: 0 }, +} + +export const ASSET_OPTIONS = Object.values(ASSETS).map((asset) => ({ + label: `${asset.name} (${asset.symbol})`, + value: asset.code, +})) + +export function getAssetDecimals(code) { + if (!code) { + return 0 + } + const normalizedCode = String(code).trim() + if (!normalizedCode) { + return 0 + } + + if (ASSETS[normalizedCode]) { + return ASSETS[normalizedCode].decimals + } + + const upperCode = normalizedCode.toUpperCase() + if (ASSETS[upperCode]) { + return ASSETS[upperCode].decimals + } + + const matchedBySymbol = Object.values(ASSETS).find( + (asset) => + String(asset.symbol).toUpperCase() === upperCode || + String(asset.code).toUpperCase() === upperCode, + ) + return matchedBySymbol?.decimals ?? 0 +} + +// 将人类可读数量转换为对应 ERC-20 代币的最小单位整数 +export function toBaseUnits(amount, code) { + const decimals = getAssetDecimals(code) + return Math.round(Number(amount) * 10 ** decimals) +} + +// 将最小单位整数转换为人类可读字符串(按资产 decimals 处理) +export function fromBaseUnits(amount, code) { + if (amount === null || amount === undefined || amount === '') { + return '-' + } + + const normalized = String(amount).trim() + if (!/^-?\d+$/.test(normalized)) { + return Number(amount).toLocaleString() + } + + const negative = normalized.startsWith('-') + const unsigned = negative ? normalized.slice(1) : normalized + const decimals = getAssetDecimals(code) + + if (decimals <= 0) { + return `${negative ? '-' : ''}${groupInteger(unsigned)}` + } + + const padded = unsigned.padStart(decimals + 1, '0') + const integerPart = padded.slice(0, -decimals) + const fractionPart = padded.slice(-decimals).replace(/0+$/, '') + const groupedInteger = groupInteger(integerPart) + + if (!fractionPart) { + return `${negative ? '-' : ''}${groupedInteger}` + } + return `${negative ? '-' : ''}${groupedInteger}.${fractionPart}` +} + +export function formatAssetAmount(amount, code) { + return fromBaseUnits(amount, code) +} + +function groupInteger(value) { + const sanitized = value.replace(/^0+(?=\d)/, '') || '0' + return sanitized.replace(/\B(?=(\d{3})+(?!\d))/g, ',') +} diff --git a/src/utils/i18n.js b/src/utils/i18n.js index 0f17ce5..eb6180e 100644 --- a/src/utils/i18n.js +++ b/src/utils/i18n.js @@ -20,9 +20,7 @@ export const useLocale = () => { } // 国际化翻译函数 - const t = (key) => { - return i18n.t(key) - } + const t = (...args) => i18n.t(...args) // 当前tdesign语言配置 const tdesignLang = computed(() => { diff --git a/src/views/AccountView.vue b/src/views/AccountView.vue new file mode 100644 index 0000000..95fd0ca --- /dev/null +++ b/src/views/AccountView.vue @@ -0,0 +1,330 @@ + + + + + diff --git a/src/views/DashboardView.vue b/src/views/DashboardView.vue index 1580f1c..7c2a60a 100644 --- a/src/views/DashboardView.vue +++ b/src/views/DashboardView.vue @@ -1 +1,838 @@ - + + + + + diff --git a/src/views/SendView.vue b/src/views/SendView.vue new file mode 100644 index 0000000..c6c5d68 --- /dev/null +++ b/src/views/SendView.vue @@ -0,0 +1,444 @@ + + + + + diff --git a/src/views/TransactionDetailView.vue b/src/views/TransactionDetailView.vue new file mode 100644 index 0000000..7639867 --- /dev/null +++ b/src/views/TransactionDetailView.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/views/TransactionsView.vue b/src/views/TransactionsView.vue new file mode 100644 index 0000000..1a1420c --- /dev/null +++ b/src/views/TransactionsView.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/src/views/VerifyView.vue b/src/views/VerifyView.vue new file mode 100644 index 0000000..75a28a4 --- /dev/null +++ b/src/views/VerifyView.vue @@ -0,0 +1,159 @@ + + + + +