From 626914feb64f9a0616bb86ce408656a9f2df8919 Mon Sep 17 00:00:00 2001 From: kang Date: Wed, 20 May 2026 17:56:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=A4=9A=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E6=96=87=E6=A1=88=E6=8E=A5=E5=85=A5=E5=B9=B6=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E5=A4=A7=E5=8E=85=E4=B8=8E=E9=92=B1=E5=8C=85=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 补充大厅下注结果、快速填单、查中奖、分页与通用操作多语言文案 - 移除多处界面默认文案回退,统一改用 i18n 配置输出 - 优化大厅快速填单、开奖结果入口与注单筛选区域视觉交互 - 重构钱包转入转出弹窗与流水卡片样式,增强金额与状态信息展示 --- src/features/hall/hall-bet-preview-dialog.tsx | 14 +- src/features/hall/hall-bet-result-dialog.tsx | 38 +++-- src/features/hall/hall-betting-grid.tsx | 144 +++++++++--------- src/features/hall/hall-screen.tsx | 2 +- src/features/hall/jackpot-burst-overlay.tsx | 15 +- src/features/hall/use-jackpot-burst-live.ts | 5 +- src/features/orders/ticket-item-status.tsx | 8 +- .../orders/ticket-order-detail-screen.tsx | 8 +- .../orders/ticket-orders-list-screen.tsx | 46 +++--- src/features/results/check-winning-screen.tsx | 44 +++--- .../results/draw-results-list-screen.tsx | 64 +++----- .../results/jackpot-results-strip.tsx | 2 +- src/features/rules/play-rules-screen.tsx | 94 +++++------- src/features/wallet/wallet-logs-block.tsx | 59 ++++--- src/features/wallet/wallet-screen.tsx | 8 +- .../wallet/wallet-transfer-dialogs.tsx | 72 ++++----- src/features/wallet/wallet-transfer-forms.tsx | 82 +++++----- src/i18n/locales/en/player.json | 75 ++++++++- src/i18n/locales/ne/player.json | 82 +++++++++- src/i18n/locales/zh/player.json | 75 ++++++++- 20 files changed, 578 insertions(+), 359 deletions(-) diff --git a/src/features/hall/hall-bet-preview-dialog.tsx b/src/features/hall/hall-bet-preview-dialog.tsx index 8739221..3e5600e 100644 --- a/src/features/hall/hall-bet-preview-dialog.tsx +++ b/src/features/hall/hall-bet-preview-dialog.tsx @@ -82,15 +82,15 @@ function SubmittingPanel() { - {t("hall.preview.processingTitle", { defaultValue: "正在提交下注" })} + {t("hall.preview.processingTitle")} - {t("hall.preview.processingDescription", { defaultValue: "请勿关闭页面或返回上一页。" })} + {t("hall.preview.processingDescription")}
- {t("hall.preview.processingProgress", { defaultValue: "正在处理注单..." })} + {t("hall.preview.processingProgress")}
@@ -143,7 +143,7 @@ export function HallBetPreviewDialog({ onClick={() => onOpenChange(false)} disabled={placing} className="absolute right-3 top-3 inline-flex size-9 items-center justify-center rounded-full text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-700 disabled:opacity-50" - aria-label={t("actions.close", { defaultValue: "关闭" })} + aria-label={t("actions.close")} > @@ -193,10 +193,10 @@ export function HallBetPreviewDialog({ No. - {t("hall.result.number", { defaultValue: "号码" })} + {t("hall.result.number")} - {t("orders.play", { defaultValue: "玩法" })} + {t("orders.play")} {t("hall.preview.amount")} @@ -283,7 +283,7 @@ export function HallBetPreviewDialog({ ) : (
- {t("hall.preview.noWarnings", { defaultValue: "当前预览未发现明显风险。" })} + {t("hall.preview.noWarnings")}
)} diff --git a/src/features/hall/hall-bet-result-dialog.tsx b/src/features/hall/hall-bet-result-dialog.tsx index b8864d1..b706bbf 100644 --- a/src/features/hall/hall-bet-result-dialog.tsx +++ b/src/features/hall/hall-bet-result-dialog.tsx @@ -47,7 +47,7 @@ export function HallBetResultDialog({ type="button" onClick={() => onOpenChange(false)} className="absolute right-3 top-3 inline-flex size-9 items-center justify-center rounded-full text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-700" - aria-label={t("actions.close", { defaultValue: "关闭" })} + aria-label={t("actions.close")} > @@ -56,11 +56,11 @@ export function HallBetResultDialog({ - {t("hall.result.title", { defaultValue: "下注结果" })} + {t("hall.result.title")} {data ? ( - {t("hall.result.draw", { defaultValue: "期号" })}{" "} + {t("hall.result.draw")}{" "} {data.draw.draw_id} ) : null} @@ -73,20 +73,20 @@ export function HallBetResultDialog({
{!data ? (

- {t("hall.result.empty", { defaultValue: "暂无结果。" })} + {t("hall.result.empty")}

) : ( <>

- {t("hall.result.successCount", { defaultValue: "成功注项" })} + {t("hall.result.successCount")}

{totalSuccess}

- {t("hall.result.failureCount", { defaultValue: "失败注项" })} + {t("hall.result.failureCount")}

{totalFailure}

@@ -98,7 +98,7 @@ export function HallBetResultDialog({ - {t("hall.result.actual", { defaultValue: "实扣金额" })} + {t("hall.result.actual")}
@@ -108,11 +108,11 @@ export function HallBetResultDialog({

- {t("hall.result.orderNo", { defaultValue: "订单号" })}:{" "} + {t("hall.result.orderNo")}:{" "} {data.order_no}

- {t("hall.result.balanceAfter", { defaultValue: "剩余余额" })}:{" "} + {t("hall.result.balanceAfter")}:{" "} {formatMinorAsCurrency(data.balance_after, currencyCode)} @@ -121,9 +121,7 @@ export function HallBetResultDialog({

- {t("hall.result.items", { - defaultValue: "成功注项明细", - })} + {t("hall.result.items")}

@@ -131,13 +129,13 @@ export function HallBetResultDialog({ @@ -171,12 +169,12 @@ export function HallBetResultDialog({ {totalFailure === 0 ? (
- {t("hall.result.noFailures", { defaultValue: "本次提交没有失败注项。" })} + {t("hall.result.noFailures")}
) : (

- {t("hall.result.failedItems", { defaultValue: "失败注项明细" })} + {t("hall.result.failedItems")}

{failedItems.map((item, index) => (
- {item.fail_reason_text ?? item.fail_reason_code ?? t("hall.result.failed", { defaultValue: "失败" })} + {item.fail_reason_text ?? item.fail_reason_code ?? t("hall.result.failed")}
))} @@ -208,7 +206,7 @@ export function HallBetResultDialog({ render={} > - {t("hall.result.viewBets", { defaultValue: "查看注单" })} + {t("hall.result.viewBets")}
diff --git a/src/features/hall/hall-betting-grid.tsx b/src/features/hall/hall-betting-grid.tsx index 3979903..f7ba13a 100644 --- a/src/features/hall/hall-betting-grid.tsx +++ b/src/features/hall/hall-betting-grid.tsx @@ -625,19 +625,13 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } removed ? t("hall.playConfig.playClosedDraftCleared", { playCode: evt.play_code, - defaultValue: "{{playCode}} 已关闭,相关草稿金额已清除。", }) : t("hall.playConfig.playClosed", { playCode: evt.play_code, - defaultValue: "{{playCode}} 已关闭。", }), ); } else { - toast.message( - t("hall.playConfig.updated", { - defaultValue: "玩法配置已更新,已刷新下注表格。", - }), - ); + toast.message(t("hall.playConfig.updated")); } }; @@ -645,12 +639,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } void loadCatalog(); setPreviewOpen(false); setPreviewData(null); - toast.message( - evt.message ?? - t("hall.playConfig.oddsUpdated", { - defaultValue: "赔率已更新,请重新预览注单。", - }), - ); + toast.message(evt.message ?? t("hall.playConfig.oddsUpdated")); }; channel.listen(".play.toggle", onPlayToggle); @@ -840,7 +829,6 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } t("hall.placePartialFailed", { success: data.summary.success_count ?? 0, failed: data.summary.failure_count ?? 0, - defaultValue: "{{success}} 个成功,{{failed}} 个失败", }), ); } @@ -947,7 +935,6 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }

{t("results.jackpotGap", { count: jackpot.draws_since_last_burst, - defaultValue: "距上次爆池 {{count}} 期", })}

) : null} @@ -970,49 +957,74 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } ) : ( <> -
-
-
-

- {t("hall.quickFill.title", { defaultValue: "快速填单" })} +

+
+
+

+ {t("hall.quickFill.title")}

-

- {t("hall.quickFill.description", { - defaultValue: "收藏号码、最近号码可一键填入当前行。", - })} +

+ {t("hall.quickFill.description")}

-
- +
{activeRow?.number ? ( ) : null} +
-
-

- {t("hall.quickFill.favorites", { defaultValue: "收藏" })} -

-
- {favoriteChips.length > 0 ? ( - favoriteChips.map((number) => ( +
+ {favoriteChips.length > 0 ? ( +
+ + {t("hall.quickFill.favorites")} + + {favoriteChips.map((number) => ( - )) - ) : ( - - {t("hall.quickFill.emptyFavorites", { defaultValue: "暂无收藏" })} - - )} -
-
+ ))} +
+ ) : null} -
-

- {t("hall.quickFill.history", { defaultValue: "最近 20 个历史号码" })} -

-
+
+ + {t("hall.quickFill.history")} + {historyChips.length > 0 ? ( historyChips.map((number) => ( )) ) : ( - - {t("hall.quickFill.emptyHistory", { defaultValue: "暂无历史号码" })} + + {t("hall.quickFill.emptyHistory")} )}
@@ -1122,7 +1128,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } : ""} - {t("hall.table.amountPlaceholder", { defaultValue: "金额" })} + {t("hall.table.amountPlaceholder")} ))} @@ -1177,7 +1183,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } inputMode="decimal" placeholder={ status === "sold_out" - ? t("hall.table.soldOut", { defaultValue: "售罄" }) + ? t("hall.table.soldOut") : "-" } onFocus={() => setActiveRowId(row.id)} @@ -1192,11 +1198,11 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } /> {status === "sold_out" ? (

- {t("hall.table.soldOut", { defaultValue: "售罄" })} + {t("hall.table.soldOut")}

) : status === "warning" ? (

- {t("hall.table.warning", { defaultValue: "接近售罄" })} + {t("hall.table.warning")}

) : null} @@ -1227,13 +1233,13 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } className="flex h-10 w-full items-center justify-center gap-1.5 border-t border-[#edf2f9] bg-white text-xs font-bold text-[#1d57b7] hover:bg-[#f7faff] disabled:text-slate-300" > - {t("hall.table.addRow", { defaultValue: "添加一行" })} + {t("hall.table.addRow")}
- {t("hall.table.draftTotal", { defaultValue: "投注金额" })} + {t("hall.table.draftTotal")} {formatMinorAsCurrency(debouncedSummary.actual, currencyCode)} @@ -1254,12 +1260,12 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } > {previewLoading - ? t("hall.table.previewing", { defaultValue: "预览中..." }) + ? t("hall.table.previewing") : !isBettable ? t("hall.closed.title") : availableMinor < debouncedSummary.actual - ? t("hall.table.insufficientBalance", { defaultValue: "余额不足" }) - : t("hall.table.submitBet", { defaultValue: "提交下注" })} + ? t("hall.table.insufficientBalance") + : t("hall.table.submitBet")} )} diff --git a/src/features/hall/hall-screen.tsx b/src/features/hall/hall-screen.tsx index beec26d..8028d85 100644 --- a/src/features/hall/hall-screen.tsx +++ b/src/features/hall/hall-screen.tsx @@ -47,7 +47,7 @@ export function HallScreen() { href="/rules" className="shrink-0 rounded-full border border-[#e4eaf4] bg-[#f8fafc] px-3 py-1.5 text-xs font-bold text-[#0b3f96] hover:bg-[#f1f6ff]" > - {tp("nav.rules", { defaultValue: "规则" })} + {tp("nav.rules")} @@ -66,11 +66,10 @@ export function JackpotBurstOverlay({ event, onClose }: JackpotBurstOverlayProps

- {t("hall.jackpotBurst.title", { defaultValue: "Jackpot 爆池" })} + {t("hall.jackpotBurst.title")}

{t("hall.jackpotBurst.subtitle", { - defaultValue: "期号 {{drawNo}} 触发奖池派发", drawNo: event.draw_no, })}

@@ -80,26 +79,26 @@ export function JackpotBurstOverlay({ event, onClose }: JackpotBurstOverlayProps {event.first_prize_number || "----"}

- {t("hall.jackpotBurst.number", { defaultValue: "头奖号码" })} + {t("hall.jackpotBurst.number")}

- {t("hall.jackpotBurst.amount", { defaultValue: "爆池金额" })} + {t("hall.jackpotBurst.amount")} {amount}
- {t("hall.jackpotBurst.winners", { defaultValue: "中奖人数" })} + {t("hall.jackpotBurst.winners")} {event.winner_count}
- {t("hall.jackpotBurst.triggerLabel", { defaultValue: "触发方式" })} + {t("hall.jackpotBurst.triggerLabel")} {triggerLabel(event.trigger_type, t)}
diff --git a/src/features/hall/use-jackpot-burst-live.ts b/src/features/hall/use-jackpot-burst-live.ts index b889c76..9df9029 100644 --- a/src/features/hall/use-jackpot-burst-live.ts +++ b/src/features/hall/use-jackpot-burst-live.ts @@ -14,11 +14,8 @@ function notifyBrowser(event: JackpotBurstEvent, t: TFunction<"player">): void { const currency = event.currency_code.toUpperCase(); const amount = formatMinorAsCurrency(event.total_payout_amount, currency); - const title = t("hall.jackpotBurst.notificationTitle", { - defaultValue: "Jackpot 爆池", - }); + const title = t("hall.jackpotBurst.notificationTitle"); const body = t("hall.jackpotBurst.notificationBody", { - defaultValue: "期号 {{drawNo}} 派发 {{amount}}", drawNo: event.draw_no, amount, }); diff --git a/src/features/orders/ticket-item-status.tsx b/src/features/orders/ticket-item-status.tsx index 6152010..e10deed 100644 --- a/src/features/orders/ticket-item-status.tsx +++ b/src/features/orders/ticket-item-status.tsx @@ -8,17 +8,17 @@ export function ticketStatusDisplay( ): { label: string; dotClass: string; ring?: boolean } { const total = winMinor + jackpotMinor; if (status === "success") { - return { label: t?.("ticketStatus.success") ?? "待开奖", dotClass: "bg-sky-500" }; + return { label: t?.("ticketStatus.success") ?? status, dotClass: "bg-sky-500" }; } if (status === "pending_payout") { - return { label: t?.("ticketStatus.pending_payout") ?? "已中奖待派彩", dotClass: "bg-amber-500" }; + return { label: t?.("ticketStatus.pending_payout") ?? status, dotClass: "bg-amber-500" }; } if (status === "settled_win" && total > 0) { - return { label: t?.("ticketStatus.settled_win") ?? "已派彩", dotClass: "bg-emerald-500" }; + return { label: t?.("ticketStatus.settled_win") ?? status, dotClass: "bg-emerald-500" }; } if (status === "settled_lose" || status === "settled_win") { return { - label: t?.("ticketStatus.settled_lose") ?? "未中奖", + label: t?.("ticketStatus.settled_lose") ?? status, dotClass: "bg-background", ring: true, }; diff --git a/src/features/orders/ticket-order-detail-screen.tsx b/src/features/orders/ticket-order-detail-screen.tsx index 22ea945..720ca49 100644 --- a/src/features/orders/ticket-order-detail-screen.tsx +++ b/src/features/orders/ticket-order-detail-screen.tsx @@ -264,7 +264,7 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) { ) : null} {!hasSettlement ? (

- {t("orders.matchPendingSettlement", { defaultValue: "已开奖,等待系统结算后显示中奖结果。" })} + {t("orders.matchPendingSettlement")}

) : null}
@@ -272,7 +272,7 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) {

{t("orders.drawNumbers")}

- {t("orders.drawPendingMatch", { defaultValue: "本期开奖号码尚未发布,暂不能判断是否中奖。" })} + {t("orders.drawPendingMatch")}

)} @@ -310,7 +310,7 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) { {matchResult && hasSettlement ? (

- {t("orders.matchResult", { defaultValue: "匹配结果" })} + {t("orders.matchResult")}

{matchResult.matched @@ -332,7 +332,7 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) { {timeline.length > 0 ? (

- {t("orders.timeline", { defaultValue: "时间线" })} + {t("orders.timeline")}

{timeline.map((row) => ( diff --git a/src/features/orders/ticket-orders-list-screen.tsx b/src/features/orders/ticket-orders-list-screen.tsx index b2e350e..9fcea7b 100644 --- a/src/features/orders/ticket-orders-list-screen.tsx +++ b/src/features/orders/ticket-orders-list-screen.tsx @@ -83,7 +83,7 @@ export function TicketOrdersListScreen() { }, []); const dateLabel = useMemo(() => { - if (!fromDate && !toDate) return t("orders.dateRange", { defaultValue: "日期范围" }); + if (!fromDate && !toDate) return t("orders.dateRange"); if (fromDate && toDate) return `${formatCompactDate(fromDate)} ~ ${formatCompactDate(toDate)}`; return `${fromDate ? formatCompactDate(fromDate) : "..." } ~ ${toDate ? formatCompactDate(toDate) : "..."}`; }, [formatCompactDate, fromDate, t, toDate]); @@ -156,20 +156,20 @@ export function TicketOrdersListScreen() { containerClassName="max-w-[720px]" >
-
-
+
+
-

+

{drawNoFilter ? t("orders.filteredIssue") : t("orders.totalRecords")}

-

+

{drawNoFilter || total}

-
+
{t("orders.betNow")} @@ -177,7 +177,7 @@ export function TicketOrdersListScreen() {
-
-
+
+
setQueryDrawNo(e.target.value)} placeholder={t("orders.drawNo")} aria-label={t("orders.drawNo")} - className="h-8 border-0 bg-transparent px-0 text-sm shadow-none focus-visible:ring-0" + className="h-7 border-0 bg-transparent px-0 text-sm shadow-none focus-visible:ring-0" />
-
+
setQueryNumber(e.target.value)} placeholder={t("orders.number")} aria-label={t("orders.number")} - className="h-8 border-0 bg-transparent px-0 text-sm shadow-none focus-visible:ring-0" + className="h-7 border-0 bg-transparent px-0 text-sm shadow-none focus-visible:ring-0" />
@@ -222,7 +222,7 @@ export function TicketOrdersListScreen() {
@@ -271,10 +271,10 @@ export function TicketOrdersListScreen() { ) : !isMobile && lastPage > 1 ? (
@@ -420,7 +420,7 @@ export function TicketOrdersListScreen() { disabled={loading || page <= 1} onClick={() => void fetchPage(Math.max(1, page - 1), false)} > - {t("actions.previous", { defaultValue: "上一页" })} + {t("actions.previous")} {visiblePages.map((p) => (
) : (

- {t("orders.noMore", { defaultValue: "没有更多注单" })} + {t("orders.noMore")}

)} diff --git a/src/features/results/check-winning-screen.tsx b/src/features/results/check-winning-screen.tsx index d8dde61..447d82b 100644 --- a/src/features/results/check-winning-screen.tsx +++ b/src/features/results/check-winning-screen.tsx @@ -78,14 +78,14 @@ export function CheckWinningScreen() { setResult(next); setRecent((current) => [normalizedTicketNo, ...current.filter((x) => x !== normalizedTicketNo)].slice(0, 5)); } catch { - setError(t("results.check.loadFailed", { defaultValue: "查询失败,请稍后重试。" })); + setError(t("results.check.loadFailed")); } finally { setLoading(false); } }, [latestDraw, normalizedTicketNo, t]); return ( - +
@@ -93,28 +93,28 @@ export function CheckWinningScreen() {

- {t("results.check.enterTicket", { defaultValue: "输入你的票号或号码" })} + {t("results.check.enterTicket")}

- {t("results.check.description", { defaultValue: "系统会按最新已发布期号查询你的注单和中奖情况。" })} + {t("results.check.description")}

{latestDraw ? (

- {t("results.check.latestDraw", { drawNo: latestDraw.draw_no, defaultValue: "最新期号 {{drawNo}}" })} + {t("results.check.latestDraw", { drawNo: latestDraw.draw_no })}

) : null} {error ?

{error}

: null} @@ -124,7 +124,7 @@ export function CheckWinningScreen() { onClick={() => void runCheck()} className="h-12 w-full rounded-xl bg-[#e5002c] text-base font-black text-white hover:bg-[#d10028]" > - {loading ? t("actions.loading", { defaultValue: "查询中..." }) : t("results.check.submit", { defaultValue: "立即查询" })} + {loading ? t("results.check.loading") : t("results.check.submit")}
@@ -132,18 +132,18 @@ export function CheckWinningScreen() {

- {t("results.check.recent", { defaultValue: "最近查询" })} + {t("results.check.recent")}

{recent.length > 0 ? ( ) : null}
{recent.length === 0 ? (

- {t("results.check.noRecent", { defaultValue: "暂无查询记录。" })} + {t("results.check.noRecent")}

) : ( recent.map((row) => ( @@ -213,7 +213,7 @@ function WinningResultDialog({ type="button" onClick={() => onOpenChange(false)} className="absolute right-3 top-3 z-10 inline-flex size-9 items-center justify-center rounded-full text-slate-500 hover:bg-slate-100" - aria-label={t("actions.close", { defaultValue: "关闭" })} + aria-label={t("actions.close")} > @@ -224,11 +224,11 @@ function WinningResultDialog({
{isWon - ? t("results.check.winTitle", { defaultValue: "恭喜,你中奖了" }) - : t("results.check.noWinTitle", { defaultValue: "未查询到中奖" })} + ? t("results.check.winTitle") + : t("results.check.noWinTitle")} - {t("results.check.ticketNumber", { defaultValue: "票号 / 号码" })} + {t("results.check.ticketNumber")} @@ -239,15 +239,15 @@ function WinningResultDialog({

- {t("results.check.match", { defaultValue: "匹配" })} + {t("results.check.match")}

- {firstTicket ? playLabel(firstTicket.play_code, t) : isWon ? t("orders.hit", { defaultValue: "命中" }) : "—"} + {firstTicket ? playLabel(firstTicket.play_code, t) : isWon ? t("orders.hit") : "—"}

- {t("results.check.amount", { defaultValue: "中奖金额" })} + {t("results.check.amount")}

{formatMinorAsCurrency(totalWin, firstTicket?.currency_code ?? "NPR")} @@ -257,11 +257,11 @@ function WinningResultDialog({

- {t("results.check.drawInfo", { defaultValue: "开奖信息" })} + {t("results.check.drawInfo")}

-

{t("results.check.issueNo", { defaultValue: "期号" })}

+

{t("results.check.issueNo")}

{data.draw.draw_no}

@@ -283,7 +283,7 @@ function WinningResultDialog({ className="h-12 rounded-xl bg-[#07459f] text-base font-black text-white hover:bg-[#063b88]" render={} > - {t("results.check.viewBetDetails", { defaultValue: "查看注单详情" })} + {t("results.check.viewBetDetails")}
diff --git a/src/features/results/draw-results-list-screen.tsx b/src/features/results/draw-results-list-screen.tsx index 1c5de96..7d06a2c 100644 --- a/src/features/results/draw-results-list-screen.tsx +++ b/src/features/results/draw-results-list-screen.tsx @@ -27,7 +27,7 @@ const RESULTS_PAGE_SIZE = 10; const MONTH_OPTIONS = Array.from({ length: 12 }, (_, value) => ({ value, - label: `${value + 1}月`, + labelKey: `calendar.months.${value + 1}`, })); export function DrawResultsListScreen() { @@ -46,7 +46,6 @@ export function DrawResultsListScreen() { const businessDate = /^\d{4}-\d{2}-\d{2}$/.test(date) ? date : undefined; const quickYears = useMemo(() => buildYearOptions(calendarMonth), [calendarMonth]); const featured = items?.[0] ?? null; - const olderDraw = items?.[1] ?? null; const fetchList = useCallback(async (targetPage = 1, append = false) => { setError(null); @@ -121,7 +120,10 @@ export function DrawResultsListScreen() { className="h-10 flex-1 justify-start rounded-lg border-[#dce7f7] bg-white px-3 text-left text-sm font-semibold text-[#32518d] hover:bg-[#f8fbff]" > - {date || t("results.selectBusinessDate", { defaultValue: "选择日期" })} + {date || + t("results.selectBusinessDate", { + defaultValue: "选择日期", + })} } /> @@ -139,7 +141,7 @@ export function DrawResultsListScreen() { {MONTH_OPTIONS.map((month) => ( - {month.label} + {t(month.labelKey)} ))} @@ -183,7 +185,7 @@ export function DrawResultsListScreen() { size="icon" variant="outline" className="h-10 w-10 rounded-lg border-[#dce7f7] bg-white text-[#7890b8] hover:bg-[#f8fbff] hover:text-[#32518d]" - aria-label={t("actions.clear", { defaultValue: "清除" })} + aria-label={t("actions.clear")} onClick={() => setDate("")} > @@ -226,44 +228,28 @@ export function DrawResultsListScreen() {
{featured ? (
-
- -
-

+

+
+

+ {t("results.detailTitle")} +

+

{featured.draw_no}

{t("results.drawTime", { - time: formatLotteryInstant(featured.draw_time_iso ?? featured.draw_time ?? null), + time: formatLotteryInstant( + featured.draw_time_iso ?? featured.draw_time ?? null, + ), })}

- {olderDraw ? ( - - {t("results.previous")} - - ) : ( - - )} + + {t("results.openDetail", { defaultValue: "查看详情" })} +
@@ -323,12 +309,12 @@ export function DrawResultsListScreen() { onClick={() => void fetchList(page + 1, true)} > {loadingMore - ? t("actions.loading", { defaultValue: "加载中..." }) - : t("actions.loadMore", { defaultValue: "加载更多" })} + ? t("actions.loading") + : t("actions.loadMore")} ) : items && items.length > 0 ? (

- {t("results.noMore", { defaultValue: "没有更多开奖结果" })} + {t("results.noMore")}

) : null}
diff --git a/src/features/results/jackpot-results-strip.tsx b/src/features/results/jackpot-results-strip.tsx index b90af0c..dc4c312 100644 --- a/src/features/results/jackpot-results-strip.tsx +++ b/src/features/results/jackpot-results-strip.tsx @@ -56,7 +56,7 @@ export function JackpotResultsStrip({

{gap !== null ? (

- {t("results.jackpotGap", { count: gap, defaultValue: "距上次爆池 {{count}} 期" })} + {t("results.jackpotGap", { count: gap })}

) : null}
diff --git a/src/features/rules/play-rules-screen.tsx b/src/features/rules/play-rules-screen.tsx index c3af729..11d1f23 100644 --- a/src/features/rules/play-rules-screen.tsx +++ b/src/features/rules/play-rules-screen.tsx @@ -14,69 +14,63 @@ import { import { PlayerPanel } from "@/components/layout/player-panel"; const prizeRows = [ - { label: "rules.prizes.first", defaultValue: "头奖", count: "1" }, - { label: "rules.prizes.second", defaultValue: "二奖", count: "1" }, - { label: "rules.prizes.third", defaultValue: "三奖", count: "1" }, - { label: "rules.prizes.starter", defaultValue: "特别奖", count: "10" }, - { label: "rules.prizes.consolation", defaultValue: "安慰奖", count: "10" }, + { label: "rules.prizes.first", count: "1" }, + { label: "rules.prizes.second", count: "1" }, + { label: "rules.prizes.third", count: "1" }, + { label: "rules.prizes.starter", count: "10" }, + { label: "rules.prizes.consolation", count: "10" }, ] as const; const playSections = [ { title: "rules.sections.dimensions.title", - titleDefault: "什么是 2D、3D、4D", items: [ - ["rules.sections.dimensions.d4", "4D:按完整 4 位号码判断,例如 1234。"], - ["rules.sections.dimensions.d3", "3D:按下注后三位与开奖号码后三位匹配,例如 234 可命中 1234。"], - ["rules.sections.dimensions.d2", "2D:按下注后二位与开奖号码后二位匹配,例如 34 可命中 1234。"], + "rules.sections.dimensions.d4", + "rules.sections.dimensions.d3", + "rules.sections.dimensions.d2", ], }, { title: "rules.sections.bigSmall.title", - titleDefault: "Big vs Small", items: [ - ["rules.sections.bigSmall.big", "Big:覆盖全部 23 个奖项,命中头奖、二奖、三奖、特别奖或安慰奖任一组即中奖。"], - ["rules.sections.bigSmall.small", "Small:只覆盖头奖、二奖、三奖;命中特别奖或安慰奖不中奖。"], + "rules.sections.bigSmall.big", + "rules.sections.bigSmall.small", ], }, { title: "rules.sections.positions.title", - titleDefault: "位置类玩法", items: [ - ["rules.sections.positions.d4", "4A / 4B / 4C 分别对应头奖、二奖、三奖;4D 命中特别奖任一组;4E 命中安慰奖任一组。"], - ["rules.sections.positions.d3", "3A / 3B / 3C 分别匹配头奖、二奖、三奖后三位;3ABC 命中头/二/三任一后三位。"], - ["rules.sections.positions.d2", "2A / 2B / 2C 分别匹配头奖、二奖、三奖后二位;2ABC 命中头/二/三任一后二位。"], + "rules.sections.positions.d4", + "rules.sections.positions.d3", + "rules.sections.positions.d2", ], }, { title: "rules.sections.box.title", - titleDefault: "包号类玩法", items: [ - ["rules.sections.box.straight", "Straight:顺序完全一致才中奖。"], - ["rules.sections.box.box", "Box:系统展开不重复排列组合,中奖按命中的展开号码结算。"], - ["rules.sections.box.ibox", "iBox:每个排列都按单注金额下注,总扣款 = 单注金额 × 组合数 × (1 - 回水率)。"], - ["rules.sections.box.mbox", "mBox:总输入金额平摊到所有组合,不能整除的尾差不扣除,相当于退回玩家钱包。"], - ["rules.sections.box.roll", "Roll:用 R 表示滚动位,每个 R 覆盖 0-9;组合数 = 10 的滚动位数次方。"], - ["rules.sections.box.half", "Half Box:一期仅预留数据结构,前台不开放下注。"], + "rules.sections.box.straight", + "rules.sections.box.box", + "rules.sections.box.ibox", + "rules.sections.box.mbox", + "rules.sections.box.roll", + "rules.sections.box.half", ], }, { title: "rules.sections.attributes.title", - titleDefault: "Head / Tail、单双、数字大小", items: [ - ["rules.sections.attributes.headTail", "Head / Tail:只看头奖首位数字;5-9 为 Head,0-4 为 Tail。"], - ["rules.sections.attributes.oddEven", "单双:按号码末位判断,1/3/5/7/9 为单,0/2/4/6/8 为双,可叠加 2D / 3D / 4D 维度。"], - ["rules.sections.attributes.digitSize", "Big Digit / Small Digit:按指定位数字判断,5-9 为大,0-4 为小;多位分别下注时独立结算。"], + "rules.sections.attributes.headTail", + "rules.sections.attributes.oddEven", + "rules.sections.attributes.digitSize", ], }, { title: "rules.sections.wallet.title", - titleDefault: "Jackpot、回水、封盘与售罄", items: [ - ["rules.sections.wallet.rebate", "回水 / 佣金:下注时锁定到注单赔率快照,结算不会受之后配置变化影响。"], - ["rules.sections.wallet.jackpot", "Jackpot:命中规则与后台奖池配置相关;爆池、蓄水和派彩以系统记录为准。"], - ["rules.sections.wallet.close", "封盘:到达封盘时间后大厅不可继续编辑或提交注单。"], - ["rules.sections.wallet.soldOut", "售罄:号码赔付池额度不足时,预览会提示风险,提交时额度不足会整单拒绝。"], + "rules.sections.wallet.rebate", + "rules.sections.wallet.jackpot", + "rules.sections.wallet.close", + "rules.sections.wallet.soldOut", ], }, ] as const; @@ -86,10 +80,8 @@ export function PlayRulesScreen() { return ( @@ -102,12 +94,10 @@ export function PlayRulesScreen() {
- {t("rules.quick.title", { defaultValue: "开奖结构" })} + {t("rules.quick.title")}

- {t("rules.quick.description", { - defaultValue: "每期开奖 23 组 4 位号码,结算以下注时锁定的赔率快照为准。", - })} + {t("rules.quick.description")}

@@ -115,19 +105,19 @@ export function PlayRulesScreen() {

23

- {t("rules.quick.totalPrizes", { defaultValue: "奖项组数" })} + {t("rules.quick.totalPrizes")}

15

- {t("rules.quick.cooldown", { defaultValue: "冷静期分钟" })} + {t("rules.quick.cooldown")}

1

- {t("rules.quick.snapshot", { defaultValue: "赔率快照" })} + {t("rules.quick.snapshot")}

@@ -140,7 +130,7 @@ export function PlayRulesScreen() { className="flex items-center justify-between rounded-xl border border-[#e6edf7] bg-white px-3 py-2 text-sm" > - {t(row.label, { defaultValue: row.defaultValue })} + {t(row.label)} {row.count}
@@ -154,17 +144,17 @@ export function PlayRulesScreen() { - {t(section.title, { defaultValue: section.titleDefault })} + {t(section.title)}
    - {section.items.map(([item, defaultValue]) => ( + {section.items.map((item) => (
  • - {t(item, { defaultValue })} + {t(item)}
  • ))}
@@ -178,24 +168,20 @@ export function PlayRulesScreen() {

- {t("rules.footer.config", { - defaultValue: "下注大厅的玩法列、启用状态、限额和赔率来自后台生效玩法配置。", - })} + {t("rules.footer.config")}

- {t("rules.footer.phaseTwo", { - defaultValue: "5D / 6D 属于二期扩展,一期前后端均不提供可用入口。", - })} + {t("rules.footer.phaseTwo")}

- {t("rules.footer.backBet", { defaultValue: "返回下注大厅" })} + {t("rules.footer.backBet")}
diff --git a/src/features/wallet/wallet-logs-block.tsx b/src/features/wallet/wallet-logs-block.tsx index 8f73f08..366a542 100644 --- a/src/features/wallet/wallet-logs-block.tsx +++ b/src/features/wallet/wallet-logs-block.tsx @@ -152,12 +152,12 @@ export function WalletLogsBlock({ onClick={onLoadMore} > {loadingMore - ? t("actions.loading", { defaultValue: "加载中..." }) - : t("actions.loadMore", { defaultValue: "加载更多" })} + ? t("actions.loading") + : t("actions.loadMore")} ) : (

- {t("wallet.noMoreLogs", { defaultValue: "没有更多流水" })} + {t("wallet.noMoreLogs")}

)} @@ -179,29 +179,50 @@ export function LogRow({ const { t } = useTranslation("player"); const ccy = item.currency_code || currency; const isIn = item.direction === "in"; + const statusTone = item.status === "posted" + ? "border-emerald-200 bg-emerald-50 text-emerald-700" + : item.status === "pending_reconcile" + ? "border-amber-200 bg-amber-50 text-amber-700" + : item.status === "reversed" + ? "border-slate-200 bg-slate-50 text-slate-600" + : "border-blue-200 bg-blue-50 text-blue-700"; + return ( -
  • -
    -
    - - {logTypeLabel(item.type, t)}{" "} - - {isIn ? "+" : "−"} - {formatMinorAsCurrency(item.amount_abs, ccy)} - - -

    - {formatLocalDateTime(item.created_at)}{" "} - - · {txnStatusLabel(item.status, t)} - +

  • +
    +
    +
    + +

    + {logTypeLabel(item.type, t)} +

    +
    +

    + {formatLocalDateTime(item.created_at)}

    {item.ref_id ? ( -

    +

    {item.ref_id}

    ) : null}
    + +
    +

    + {isIn ? "+" : "−"} + {formatMinorAsCurrency(item.amount_abs, ccy)} +

    + + {txnStatusLabel(item.status, t)} + +
    +
    + +
    + {t("wallet.balanceAfter")} + + {formatMinorAsCurrency(item.balance_after, ccy)} +
  • ); diff --git a/src/features/wallet/wallet-screen.tsx b/src/features/wallet/wallet-screen.tsx index 90f126f..c3a00b5 100644 --- a/src/features/wallet/wallet-screen.tsx +++ b/src/features/wallet/wallet-screen.tsx @@ -194,8 +194,8 @@ export function WalletScreen() { lotteryMinor={Number(balance?.balance ?? 0)} onSuccess={refreshAll} triggerVariant="hall" - triggerLabel={t("wallet.transferIn")} - triggerClassName="h-12 rounded-lg text-base font-bold" + triggerLabel={t("wallet.transferIn", { defaultValue: "Transfer In" })} + triggerClassName="h-14 rounded-2xl text-base font-black" />
    diff --git a/src/features/wallet/wallet-transfer-dialogs.tsx b/src/features/wallet/wallet-transfer-dialogs.tsx index 38b17e3..e8a9c35 100644 --- a/src/features/wallet/wallet-transfer-dialogs.tsx +++ b/src/features/wallet/wallet-transfer-dialogs.tsx @@ -26,15 +26,13 @@ type BaseProps = { }; const defaultInTrigger = - "!bg-[#52c41a] !text-white shadow-none hover:!bg-[#52c41a]/90"; + "!bg-[#0b3f96] !text-white shadow-[0_8px_18px_rgba(11,63,150,0.18)] hover:!bg-[#08357f]"; const defaultOutTrigger = "flex-1"; -/** 高保真稿:蓝底白字 */ const hallInTrigger = - "rounded-lg border-0 !bg-[#1677ff] !text-white shadow-sm hover:!bg-[#1677ff]/90"; -/** 高保真稿:白底红框红字 */ + "rounded-2xl border border-[#d7e5fb] !bg-[#0b3f96] !text-white shadow-[0_10px_24px_rgba(11,63,150,0.22)] hover:!bg-[#08357f]"; const hallOutTrigger = - "rounded-lg !border-2 !border-[#ff4d4f] !bg-white !text-[#ff4d4f] shadow-sm hover:!bg-red-50 dark:!bg-card dark:hover:!bg-red-950/30"; + "rounded-2xl border border-[#ffc7d2] !bg-white !text-[#e5002c] shadow-[0_8px_22px_rgba(216,20,53,0.08)] hover:!bg-[#fff5f7]"; export function TransferInDialog({ currency, @@ -71,24 +69,26 @@ export function TransferInDialog({ {resolvedTriggerLabel} - - - {t("wallet.transferInTitle")} - + + + {t("wallet.transferInTitle")} + {t("wallet.dialogInDescription", { currency })} - setOpen(false)} - onSuccess={async () => { - await onSuccess(); - setOpen(false); - }} - /> +
    + setOpen(false)} + onSuccess={async () => { + await onSuccess(); + setOpen(false); + }} + /> +
    ); @@ -134,24 +134,26 @@ export function TransferOutDialog({ {resolvedTriggerLabel} - - - {t("wallet.transferOutTitle")} - + + + {t("wallet.transferOutTitle")} + {t("wallet.dialogOutDescription")} - setOpen(false)} - onSuccess={async () => { - await onSuccess(); - setOpen(false); - }} - /> +
    + setOpen(false)} + onSuccess={async () => { + await onSuccess(); + setOpen(false); + }} + /> +
    ); diff --git a/src/features/wallet/wallet-transfer-forms.tsx b/src/features/wallet/wallet-transfer-forms.tsx index 6146d79..cf6a99d 100644 --- a/src/features/wallet/wallet-transfer-forms.tsx +++ b/src/features/wallet/wallet-transfer-forms.tsx @@ -121,17 +121,10 @@ export function TransferInPanel({ )} ) : ( -
    - +
    +
    ); return ( <> -
    -
    -

    +

    +
    +

    {t("wallet.mainBalance")}{" "} - {t("wallet.mainPending")} + {t("wallet.mainPending")}

    -

    +

    {t("wallet.lotteryBalance")}{" "} - + {formatMinorAsCurrency(lotteryMinor, currency)}

    -
    - +
    + setAmountText(ev.target.value)} disabled={submitting} autoComplete="off" - className="h-11 rounded-lg border-[#dce7f7] bg-white text-base" + className="h-13 rounded-2xl border-[#d7e5fb] bg-white px-4 text-lg font-bold tabular-nums text-[#101a33] shadow-inner focus-visible:ring-[#0b3f96]/20" /> -

    +

    {t("wallet.afterInPreview", { amount: formatMinorAsCurrency(previewAfter, currency), })}

    {localError ? ( -

    {localError}

    +

    {localError}

    ) : null}
    {footer} @@ -270,17 +272,10 @@ export function TransferOutPanel({ )} ) : ( -
    - +
    +
    ); return ( <> -
    -
    -

    +

    +
    +

    {t("wallet.lotteryAvailable")}{" "} - + {formatMinorAsCurrency(availableMinor, currency)}

    -
    +
    - +
    {localError ? ( -

    {localError}

    +

    {localError}

    ) : null}
    {footer} diff --git a/src/i18n/locales/en/player.json b/src/i18n/locales/en/player.json index d54c80f..bcf22d4 100644 --- a/src/i18n/locales/en/player.json +++ b/src/i18n/locales/en/player.json @@ -9,8 +9,12 @@ "clear": "Clear", "cancel": "Cancel", "confirm": "Confirm", + "close": "Close", "loading": "Loading...", "loadMore": "Load More", + "previous": "Previous", + "next": "Next", + "done": "Done", "processing": "Processing...", "deleteRow": "Delete row {{row}}" }, @@ -102,6 +106,13 @@ "changedBeforeSubmit": "Your draft changed before submission. Close the preview and try again.", "placeFailed": "Submission failed", "placeSuccess": "Bet submitted. Order {{orderNo}}, deducted {{amount}}.", + "placePartialFailed": "{{success}} succeeded, {{failed}} failed", + "playConfig": { + "playClosedDraftCleared": "{{playCode}} is closed. Related draft amounts have been cleared.", + "playClosed": "{{playCode}} is closed.", + "updated": "Play configuration updated. The betting table has been refreshed.", + "oddsUpdated": "Odds updated. Please preview the ticket again." + }, "jackpotBurst": { "title": "Jackpot Burst", "subtitle": "Issue {{drawNo}} triggered a pool payout", @@ -145,13 +156,28 @@ "sealedHint": "Closed: this table is locked. Please wait for the next issue.", "previewing": "Previewing...", "submitBet": "Submit Bet", + "insufficientBalance": "Insufficient balance", "amountPlaceholder": "Amount", "filledPlayCount": "{{count}} plays filled", "tapToFill": "Tap to enter amounts", "rowActual": "Actual", "editRow": "Edit row {{row}}", "scrollHint": "This table is wide: swipe or scroll horizontally, then enter your stake in each play column on the right (e.g. Big/Small, position plays).", - "noPlaysInCategory": "No open play types in this tab, so there are no amount fields. Try 2D / 3D / 4D, or ask an admin to enable plays for this category." + "noPlaysInCategory": "No open play types in this tab, so there are no amount fields. Try 2D / 3D / 4D, or ask an admin to enable plays for this category.", + "soldOut": "Sold out", + "warning": "Almost sold out" + }, + "quickFill": { + "title": "Quick fill", + "description": "Fill the current row with favorite or recent numbers in one tap.", + "clearAll": "Clear all", + "favorite": "Favorite number", + "unfavorite": "Remove favorite", + "favorites": "Favorites", + "tapHold": "Hold to remove", + "emptyFavorites": "No favorites yet", + "history": "Recent 20 numbers", + "emptyHistory": "No recent numbers" }, "preview": { "title": "Confirm bet", @@ -183,6 +209,24 @@ "warningsTitle": "Payout pool warning", "warningsDescription": "The following numbers have high payout pool usage for this issue. Betting is still allowed, but the order may be rejected as sold out if capacity is insufficient." }, + "result": { + "title": "Bet result", + "draw": "Issue", + "empty": "No result yet.", + "successCount": "Successful lines", + "failureCount": "Failed lines", + "actual": "Actual deduction", + "orderNo": "Order No.", + "balanceAfter": "Remaining balance", + "items": "Successful line details", + "number": "Number", + "actualDeduct": "Deducted", + "noFailures": "No ticket lines failed in this submission.", + "failedItems": "Failed line details", + "failed": "Failed", + "viewBets": "View tickets", + "continueBetting": "Continue betting" + }, "amountInput": { "limit": "Limit {{min}} - {{max}}", "placeholder": "e.g. 100.00" @@ -280,6 +324,7 @@ "flowsTitle": "Wallet logs", "totalRecords": "{{total}} records", "emptyLogs": "No wallet logs", + "balanceAfter": "Balance after", "flow": { "all": "All", "transfer_in": "Transfer in", @@ -322,7 +367,9 @@ "betNow": "Bet Now", "empty": "No bet records yet.", "dateRange": "Date range", + "status": "Status", "statusFilter": "Status filter", + "noMore": "No more tickets", "submitBet": "Submit Bet", "stake": "Stake", "deduction": "Deduction", @@ -364,8 +411,10 @@ "subtitle": "Latest draw history", "detailTitle": "Result Detail", "businessDate": "Business Date", + "selectBusinessDate": "Select date", "empty": "No results yet.", "detail": "Detail", + "openDetail": "Open detail", "loadFailed": "Failed to load", "unavailable": "This result is unavailable or does not exist.", "noData": "No data", @@ -376,10 +425,32 @@ "regular": "Regular: {{amount}}", "jackpot": "Jackpot: {{amount}}", "hitPending": "Your ticket has hit a result cell in this issue. The amount summary will show after payout is completed.", - "hitHint": "If you win, numbers matched by your tickets are highlighted in gold (login required).", + "hitHint": "If you win, numbers matched by your tickets are highlighted in gold.", "viewMyWinning": "View my winning status", "jackpotLabel": "Jackpot", "jackpotGap": "{{count}} draws since last burst", + "noMore": "No more results", + "check": { + "title": "Check My Winnings", + "loadFailed": "Query failed. Please try again later.", + "enterTicket": "Enter your ticket number or number", + "description": "The system checks your tickets and winnings against the latest published draw.", + "ticketNumber": "Ticket No. / Number", + "placeholder": "Enter ticket number or number", + "latestDraw": "Latest issue {{drawNo}}", + "loading": "Checking...", + "submit": "Check now", + "recent": "Recent checks", + "noRecent": "No recent checks.", + "winTitle": "Congratulations, you won", + "noWinTitle": "No winning result found", + "match": "Match", + "amount": "Winning amount", + "drawInfo": "Draw info", + "issueNo": "Issue No.", + "viewBetDetails": "View bet details", + "checkAnother": "Check another ticket" + }, "tier": { "first": "First prize", "second": "Second prize", diff --git a/src/i18n/locales/ne/player.json b/src/i18n/locales/ne/player.json index 63dafe1..ba79f05 100644 --- a/src/i18n/locales/ne/player.json +++ b/src/i18n/locales/ne/player.json @@ -9,8 +9,12 @@ "clear": "हटाउनुहोस्", "cancel": "रद्द", "confirm": "पुष्टि", + "close": "बन्द", "loading": "लोड हुँदैछ...", "loadMore": "थप लोड गर्नुहोस्", + "previous": "अघिल्लो", + "next": "अर्को", + "done": "पूरा भयो", "processing": "प्रक्रिया हुँदैछ...", "deleteRow": "{{row}} नम्बर पंक्ति हटाउनुहोस्" }, @@ -102,6 +106,13 @@ "changedBeforeSubmit": "पेश गर्नु अघि ड्राफ्ट परिवर्तन भयो। पूर्वावलोकन बन्द गरी फेरि प्रयास गर्नुहोस्।", "placeFailed": "पेश गर्न असफल", "placeSuccess": "बेट पेश भयो। अर्डर {{orderNo}}, कट्टा {{amount}}।", + "placePartialFailed": "{{success}} सफल, {{failed}} असफल", + "playConfig": { + "playClosedDraftCleared": "{{playCode}} बन्द छ। सम्बन्धित ड्राफ्ट रकम हटाइएको छ।", + "playClosed": "{{playCode}} बन्द छ।", + "updated": "प्ले कन्फिगरेसन अपडेट भयो। बेटिङ तालिका रिफ्रेस गरियो।", + "oddsUpdated": "Odds अपडेट भयो। कृपया टिकट फेरि पूर्वावलोकन गर्नुहोस्।" + }, "jackpotBurst": { "title": "Jackpot Burst", "subtitle": "इश्यू {{drawNo}} मा पूल payout ट्रिगर भयो", @@ -145,13 +156,28 @@ "sealedHint": "बन्द: यो तालिका लक छ। कृपया अर्को इश्यू पर्खनुहोस्।", "previewing": "पूर्वावलोकन...", "submitBet": "बेट पेश गर्नुहोस्", + "insufficientBalance": "ब्यालेन्स अपुग", "amountPlaceholder": "रकम", "filledPlayCount": "{{count}} प्ले भरियो", "tapToFill": "रकम लेख्न ट्याप गर्नुहोस्", "rowActual": "वास्तविक", "editRow": "पंक्ति {{row}} सम्पादन गर्नुहोस्", "scrollHint": "तालिका फराकिलो छ: दायाँतिर स्क्रोल गर्नुहोस्, दायाँका प्रत्येक खेल स्तम्भमा बेट रकम लेख्नुहोस्।", - "noPlaysInCategory": "यस ट्याबमा खुला खेल प्रकार छैन। २D / ३D / ४D प्रयास गर्नुहोस् वा व्यवस्थापकले खेल खोल्नुपर्छ।" + "noPlaysInCategory": "यस ट्याबमा खुला खेल प्रकार छैन। २D / ३D / ४D प्रयास गर्नुहोस् वा व्यवस्थापकले खेल खोल्नुपर्छ।", + "soldOut": "Sold out", + "warning": "लगभग sold out" + }, + "quickFill": { + "title": "छिटो भर्ने", + "description": "मनपर्ने वा पछिल्ला नम्बरहरू एक ट्यापमा हालको पंक्तिमा भर्नुहोस्।", + "clearAll": "सबै हटाउनुहोस्", + "favorite": "नम्बर मनपर्नेमा राख्नुहोस्", + "unfavorite": "मनपर्नेबाट हटाउनुहोस्", + "favorites": "मनपर्ने", + "tapHold": "हटाउन होल्ड गर्नुहोस्", + "emptyFavorites": "मनपर्ने छैन", + "history": "पछिल्ला 20 नम्बर", + "emptyHistory": "इतिहास नम्बर छैन" }, "preview": { "title": "बेट पुष्टि गर्नुहोस्", @@ -176,9 +202,31 @@ "backEdit": "सम्पादनमा फर्कनुहोस्", "submitting": "पेश हुँदैछ...", "confirmSubmit": "पेश पुष्टि", + "processingTitle": "बेट पेश हुँदैछ", + "processingDescription": "कृपया पृष्ठ बन्द नगर्नुहोस् वा पछाडि नजानुहोस्।", + "processingProgress": "टिकट प्रक्रिया हुँदैछ...", + "noWarnings": "यस पूर्वावलोकनमा स्पष्ट जोखिम भेटिएन।", "warningsTitle": "भुक्तानी पूल चेतावनी", "warningsDescription": "यी नम्बरहरूमा यस इश्यूमा भुक्तानी पूल प्रयोग उच्च छ। बेट अझै गर्न सकिन्छ, तर क्षमता अपुग भए अर्डर sold out हुन सक्छ।" }, + "result": { + "title": "बेट नतिजा", + "draw": "इश्यू", + "empty": "नतिजा छैन।", + "successCount": "सफल लाइनहरू", + "failureCount": "असफल लाइनहरू", + "actual": "वास्तविक कट्टा", + "orderNo": "अर्डर नं.", + "balanceAfter": "बाँकी ब्यालेन्स", + "items": "सफल लाइन विवरण", + "number": "नम्बर", + "actualDeduct": "कट्टा", + "noFailures": "यस पेशमा असफल टिकट लाइन छैन।", + "failedItems": "असफल लाइन विवरण", + "failed": "असफल", + "viewBets": "टिकट हेर्नुहोस्", + "continueBetting": "बेट जारी राख्नुहोस्" + }, "amountInput": { "limit": "सीमा {{min}} - {{max}}", "placeholder": "जस्तै 100.00" @@ -276,6 +324,7 @@ "flowsTitle": "वालेट लग", "totalRecords": "{{total}} रेकर्ड", "emptyLogs": "वालेट लग छैन", + "balanceAfter": "पछि बाँकी ब्यालेन्स", "flow": { "all": "सबै", "transfer_in": "ट्रान्सफर इन", @@ -317,6 +366,10 @@ "totalRecords": "कुल रेकर्ड", "betNow": "अहिले बेट", "empty": "अहिलेसम्म बेट रेकर्ड छैन।", + "dateRange": "मिति दायरा", + "status": "स्थिति", + "statusFilter": "स्थिति फिल्टर", + "noMore": "थप टिकट छैन", "submitBet": "बेट पेश गर्नुहोस्", "stake": "बेट", "deduction": "कट्टा", @@ -353,8 +406,10 @@ "subtitle": "हालका ड्र इतिहास", "detailTitle": "नतिजा विवरण", "businessDate": "व्यावसायिक मिति", + "selectBusinessDate": "मिति छान्नुहोस्", "empty": "अहिलेसम्म नतिजा छैन।", "detail": "विवरण", + "openDetail": "विवरण खोल्नुहोस्", "loadFailed": "लोड असफल", "unavailable": "यो नतिजा उपलब्ध छैन वा अस्तित्वमा छैन।", "noData": "डेटा छैन", @@ -365,10 +420,32 @@ "regular": "सामान्य: {{amount}}", "jackpot": "Jackpot: {{amount}}", "hitPending": "तपाईंको टिकटले यस इश्यूको नतिजा सेल हिट गरेको छ। भुक्तानी पूरा भएपछि रकम देखिनेछ।", - "hitHint": "तपाईं जित्नुभयो भने, तपाईंका टिकटसँग मिलेका नम्बरहरू सुनौलो रंगमा देखिन्छन् (लगइन आवश्यक)।", + "hitHint": "तपाईं जित्नुभयो भने, तपाईंका टिकटसँग मिलेका नम्बरहरू सुनौलो रंगमा देखिन्छन्।", "viewMyWinning": "मेरो जित स्थिति हेर्नुहोस्", "jackpotLabel": "Jackpot", "jackpotGap": "पछिल्लो burst देखि {{count}} draw", + "noMore": "थप नतिजा छैन", + "check": { + "title": "मेरो जित जाँच", + "loadFailed": "जाँच असफल भयो। कृपया पछि प्रयास गर्नुहोस्।", + "enterTicket": "टिकट नम्बर वा नम्बर लेख्नुहोस्", + "description": "सिस्टमले पछिल्लो प्रकाशित ड्र अनुसार तपाईंको टिकट र जित जाँच गर्छ।", + "ticketNumber": "टिकट नं. / नम्बर", + "placeholder": "टिकट नम्बर वा नम्बर लेख्नुहोस्", + "latestDraw": "पछिल्लो इश्यू {{drawNo}}", + "loading": "जाँच हुँदैछ...", + "submit": "अहिले जाँच गर्नुहोस्", + "recent": "हालका जाँच", + "noRecent": "हालका जाँच छैनन्।", + "winTitle": "बधाई छ, तपाईं जित्नुभयो", + "noWinTitle": "जित नतिजा भेटिएन", + "match": "मिलान", + "amount": "जित रकम", + "drawInfo": "ड्र जानकारी", + "issueNo": "इश्यू नं.", + "viewBetDetails": "बेट विवरण हेर्नुहोस्", + "checkAnother": "अर्को टिकट जाँच गर्नुहोस्" + }, "tier": { "first": "पहिलो पुरस्कार", "second": "दोस्रो पुरस्कार", @@ -450,6 +527,7 @@ }, "ticketStatus": { "success": "ड्र पर्खँदै", + "pending_payout": "जितेको, भुक्तानी बाँकी", "settled_win": "भुक्तानी भयो", "settled_lose": "जितेन", "unknown": "{{status}}" diff --git a/src/i18n/locales/zh/player.json b/src/i18n/locales/zh/player.json index c2b58c8..bda96c5 100644 --- a/src/i18n/locales/zh/player.json +++ b/src/i18n/locales/zh/player.json @@ -9,8 +9,12 @@ "clear": "清除", "cancel": "取消", "confirm": "确认", + "close": "关闭", "loading": "加载中...", "loadMore": "加载更多", + "previous": "上一页", + "next": "下一页", + "done": "完成", "processing": "处理中...", "deleteRow": "删除第 {{row}} 行" }, @@ -102,6 +106,13 @@ "changedBeforeSubmit": "提交前数据已变化,请关闭预览后重试。", "placeFailed": "提交失败", "placeSuccess": "下注成功,订单号 {{orderNo}},实扣 {{amount}}。", + "placePartialFailed": "{{success}} 个成功,{{failed}} 个失败", + "playConfig": { + "playClosedDraftCleared": "{{playCode}} 已关闭,相关草稿金额已清除。", + "playClosed": "{{playCode}} 已关闭。", + "updated": "玩法配置已更新,已刷新下注表格。", + "oddsUpdated": "赔率已更新,请重新预览注单。" + }, "jackpotBurst": { "title": "Jackpot 爆池", "subtitle": "期号 {{drawNo}} 触发奖池派发", @@ -145,13 +156,28 @@ "sealedHint": "已封盘:当前表格不可编辑,请等待下一期。", "previewing": "预览中...", "submitBet": "提交下注", + "insufficientBalance": "余额不足", "amountPlaceholder": "金额", "filledPlayCount": "已填写 {{count}} 个玩法", "tapToFill": "点击填写玩法金额", "rowActual": "实扣", "editRow": "编辑第 {{row}} 行", "scrollHint": "表格较宽:请向右滑动,在右侧各玩法列(如 Big / Small、位置玩法等)输入下注金额。", - "noPlaysInCategory": "当前分类没有已开放的玩法,无法填写金额。请尝试切换 2D / 3D / 4D,或在后台开放对应玩法。" + "noPlaysInCategory": "当前分类没有已开放的玩法,无法填写金额。请尝试切换 2D / 3D / 4D,或在后台开放对应玩法。", + "soldOut": "售罄", + "warning": "接近售罄" + }, + "quickFill": { + "title": "快速填单", + "description": "收藏号码、最近号码可一键填入当前行。", + "clearAll": "批量清空", + "favorite": "收藏号码", + "unfavorite": "取消收藏", + "favorites": "收藏", + "tapHold": "长按取消", + "emptyFavorites": "暂无收藏", + "history": "最近 20 个历史号码", + "emptyHistory": "暂无历史号码" }, "preview": { "title": "确认下注", @@ -183,6 +209,24 @@ "warningsTitle": "赔付池预警", "warningsDescription": "以下号码本期赔付池占用较高,仍允许下注;若实际占用不足将售罄拒单。" }, + "result": { + "title": "下注结果", + "draw": "期号", + "empty": "暂无结果。", + "successCount": "成功注项", + "failureCount": "失败注项", + "actual": "实扣金额", + "orderNo": "订单号", + "balanceAfter": "剩余余额", + "items": "成功注项明细", + "number": "号码", + "actualDeduct": "实扣", + "noFailures": "本次提交没有失败注项。", + "failedItems": "失败注项明细", + "failed": "失败", + "viewBets": "查看注单", + "continueBetting": "继续下注" + }, "amountInput": { "limit": "限额 {{min}} - {{max}}", "placeholder": "例如 100.00" @@ -280,6 +324,7 @@ "flowsTitle": "资金流水", "totalRecords": "共 {{total}} 条记录", "emptyLogs": "暂无流水", + "balanceAfter": "变更后余额", "flow": { "all": "全部", "transfer_in": "转入", @@ -322,7 +367,9 @@ "betNow": "立即下注", "empty": "暂无下注记录。", "dateRange": "日期范围", + "status": "状态", "statusFilter": "状态筛选", + "noMore": "没有更多注单", "submitBet": "提交下注", "stake": "下注", "deduction": "实扣", @@ -364,8 +411,10 @@ "subtitle": "最新开奖历史", "detailTitle": "开奖详情", "businessDate": "业务日期", + "selectBusinessDate": "选择日期", "empty": "暂无开奖结果。", "detail": "详情", + "openDetail": "查看详情", "loadFailed": "加载失败", "unavailable": "该期开奖结果不可用或不存在", "noData": "无数据", @@ -376,10 +425,32 @@ "regular": "常规:{{amount}}", "jackpot": "Jackpot:{{amount}}", "hitPending": "您的注单已命中本期开奖号码中的格子;派彩完成后将显示金额汇总。", - "hitHint": "如果您中奖,与注单匹配的号码将以金色高亮显示(需登录)。", + "hitHint": "如果您中奖,与注单匹配的号码将以金色高亮显示。", "viewMyWinning": "查看我的中奖情况", "jackpotLabel": "Jackpot", "jackpotGap": "距上次爆池 {{count}} 期", + "noMore": "没有更多开奖结果", + "check": { + "title": "查我的中奖", + "loadFailed": "查询失败,请稍后重试。", + "enterTicket": "输入你的票号或号码", + "description": "系统会按最新已发布期号查询你的注单和中奖情况。", + "ticketNumber": "票号 / 号码", + "placeholder": "请输入票号或号码", + "latestDraw": "最新期号 {{drawNo}}", + "loading": "查询中...", + "submit": "立即查询", + "recent": "最近查询", + "noRecent": "暂无查询记录。", + "winTitle": "恭喜,你中奖了", + "noWinTitle": "未查询到中奖", + "match": "匹配", + "amount": "中奖金额", + "drawInfo": "开奖信息", + "issueNo": "期号", + "viewBetDetails": "查看注单详情", + "checkAnother": "查询另一张票" + }, "tier": { "first": "头奖", "second": "二奖",
    No. - {t("hall.result.number", { defaultValue: "号码" })} + {t("hall.result.number")} - {t("orders.play", { defaultValue: "玩法" })} + {t("orders.play")} - {t("hall.result.actualDeduct", { defaultValue: "实扣" })} + {t("hall.result.actualDeduct")}