feat: 增强投注结果弹窗与投注网格功能

更新 HallBetResultDialog:根据成功与失败数量显示不同的结果图标与标题。
优化 HallBettingGrid:新增 place trace ID 管理机制,更好地处理投注提交流程,并防止重复扣费。
增强注单详情页面:针对临时状态中的注单自动刷新,提升用户体验。
新增多语言翻译:补充投注结果与状态相关文案,支持更完善的用户反馈。
This commit is contained in:
2026-05-26 14:50:21 +08:00
parent d768a3f6ba
commit 51b2a36cc5
11 changed files with 257 additions and 90 deletions

View File

@@ -52,6 +52,13 @@ type TimelineRow = {
time: string;
};
const TRANSIENT_TICKET_STATUSES = new Set([
"pending_confirm",
"partial_pending_confirm",
"pending_draw",
"pending_payout",
]);
type TicketItemDetailWithExtras = TicketItemDetailPayload & {
timeline?: TimelineRow[];
match_result?: {
@@ -98,17 +105,23 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) {
};
}, [fromGroupKey, groupTickets, t]);
const load = useCallback(async () => {
setLoading(true);
const load = useCallback(async (options?: { silent?: boolean }) => {
if (!options?.silent) {
setLoading(true);
}
setError(null);
try {
const row = await getTicketItemDetail(ticketNo);
setData(row);
} catch {
setData(null);
setError(t("orders.notFound"));
if (!options?.silent) {
setError(t("orders.notFound"));
}
} finally {
setLoading(false);
if (!options?.silent) {
setLoading(false);
}
}
}, [ticketNo, t]);
@@ -118,6 +131,21 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) {
});
}, [load]);
useEffect(() => {
if (!data || !TRANSIENT_TICKET_STATUSES.has(data.status)) {
return;
}
const refresh = () => void load({ silent: true });
const intervalId = window.setInterval(refresh, 12_000);
window.addEventListener("lottery-hall-refresh", refresh);
window.addEventListener("lottery-wallet-refresh", refresh);
return () => {
window.clearInterval(intervalId);
window.removeEventListener("lottery-hall-refresh", refresh);
window.removeEventListener("lottery-wallet-refresh", refresh);
};
}, [data?.status, load]);
if (loading) {
return (
<PlayerPanel