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

@@ -17,9 +17,12 @@ import {
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { PlayerPanel } from "@/components/layout/player-panel";
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
import { formatMinorAsCurrency } from "@/lib/money";
import { formatLotteryInstant } from "@/lib/player-datetime";
import { playLabel } from "@/lib/play-labels";
import { resolvePlayerCurrency } from "@/lib/player-currency";
import { usePlayerSessionStore } from "@/stores/player-session-store";
import type { DrawResultListItem } from "@/types/api/draw-results";
import type { TicketDrawMyMatchPayload, TicketItemListRow } from "@/types/api/ticket-items";
@@ -31,6 +34,7 @@ type WinningCheckResult = {
export function CheckWinningScreen() {
const { t } = useTranslation("player");
useCurrencyCatalog();
const [ticketNo, setTicketNo] = useState("");
const [latestDraw, setLatestDraw] = useState<DrawResultListItem | null>(null);
const [recent, setRecent] = useState<string[]>([]);
@@ -197,9 +201,11 @@ function WinningResultDialog({
onCheckAnother: () => void;
}) {
const { t } = useTranslation("player");
const profile = usePlayerSessionStore((state) => state.profile);
const totalWin = (data?.match.total_win_minor ?? 0) + (data?.match.total_jackpot_win_minor ?? 0);
const isWon = totalWin > 0 || (data?.match.winning_ticket_count ?? 0) > 0;
const firstTicket = useMemo(() => data?.tickets[0] ?? null, [data]);
const currency = firstTicket?.currency_code ?? resolvePlayerCurrency(profile);
if (!data) return null;
@@ -250,7 +256,7 @@ function WinningResultDialog({
{t("results.check.amount")}
</p>
<p className="mt-2 font-mono text-lg font-black text-[#0a8f3e]">
{formatMinorAsCurrency(totalWin, firstTicket?.currency_code ?? "NPR")}
{formatMinorAsCurrency(totalWin, currency)}
</p>
</div>
</div>

View File

@@ -18,11 +18,14 @@ import {
import { Skeleton } from "@/components/ui/skeleton";
import { JackpotResultsStrip } from "@/features/results/jackpot-results-strip";
import { TwentyThreeResultsGrid } from "@/features/results/twenty-three-results-grid";
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
import { getPlayerBearerTokenPayload } from "@/lib/lottery-auth";
import { formatLotteryInstant } from "@/lib/player-datetime";
import { formatMinorAsCurrency } from "@/lib/money";
import { norm4d } from "@/lib/norm-4d";
import { resolvePlayerCurrency } from "@/lib/player-currency";
import { cn } from "@/lib/utils";
import { usePlayerSessionStore } from "@/stores/player-session-store";
import type { DrawResultDetailPayload } from "@/types/api/draw-results";
type DrawResultDetailScreenProps = {
@@ -32,6 +35,8 @@ type DrawResultDetailScreenProps = {
/** §4.6 开奖结果详情23 分区 + [< >] 切换 + 本人命中高亮 + Jackpot */
export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps) {
const { t } = useTranslation("player");
const profile = usePlayerSessionStore((state) => state.profile);
useCurrencyCatalog();
const [data, setData] = useState<DrawResultDetailPayload | null>(null);
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
@@ -135,7 +140,7 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
);
}
const currency = "NPR";
const currency = data.jackpot?.currency_code ?? resolvePlayerCurrency(profile);
const showMyPayout =
myTotals &&
myTotals.hasBets &&

View File

@@ -20,7 +20,10 @@ import {
import { PlayerPanel } from "@/components/layout/player-panel";
import { JackpotResultsStrip } from "@/features/results/jackpot-results-strip";
import { TwentyThreeResultsGrid } from "@/features/results/twenty-three-results-grid";
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
import { formatLotteryInstant } from "@/lib/player-datetime";
import { resolvePlayerCurrency } from "@/lib/player-currency";
import { usePlayerSessionStore } from "@/stores/player-session-store";
import type { DrawResultListItem } from "@/types/api/draw-results";
const RESULTS_PAGE_SIZE = 10;
@@ -32,6 +35,8 @@ const MONTH_OPTIONS = Array.from({ length: 12 }, (_, value) => ({
export function DrawResultsListScreen() {
const { t } = useTranslation("player");
const profile = usePlayerSessionStore((state) => state.profile);
useCurrencyCatalog();
const [items, setItems] = useState<DrawResultListItem[] | null>(null);
const [error, setError] = useState<string | null>(null);
const [date, setDate] = useState("");
@@ -46,6 +51,7 @@ 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 jackpotCurrency = featured?.jackpot?.currency_code ?? resolvePlayerCurrency(profile);
const fetchList = useCallback(async (targetPage = 1, append = false) => {
setError(null);
@@ -104,7 +110,7 @@ export function DrawResultsListScreen() {
return (
<PlayerPanel title={t("results.title")} subtitle={t("results.subtitle")} eyebrow={t("brand.name")}>
<div className="space-y-4">
<JackpotResultsStrip currencyCode="NPR" />
<JackpotResultsStrip currencyCode={jackpotCurrency} />
<div className="rounded-xl border border-[#e6edf8] bg-[#f8fbff] p-3">
<p className="mb-2 text-xs font-bold text-[#32518d]">