feat: 增强注单处理逻辑并优化用户反馈体验

新增注单错误处理逻辑,支持已退款及待确认状态的异常场景处理。
更新 HallBetResultDialog:针对部分失败与已退款订单显示对应提示信息。
优化注单分组逻辑,新增订单状态处理,提升整体订单管理能力。
新增订单状态与用户通知相关多语言翻译,进一步提升用户体验。
This commit is contained in:
2026-05-26 16:32:53 +08:00
parent 51b2a36cc5
commit ab81da3199
19 changed files with 373 additions and 142 deletions

View File

@@ -721,6 +721,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
const removed = clearAmountsForPlay(evt.play_code);
setPreviewOpen(false);
setPreviewData(null);
clearPlaceTraceId();
toast.warning(
removed
? t("hall.playConfig.playClosedDraftCleared", {
@@ -739,6 +740,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
void loadCatalog();
setPreviewOpen(false);
setPreviewData(null);
clearPlaceTraceId();
toast.message(evt.message ?? t("hall.playConfig.oddsUpdated"));
};
@@ -855,7 +857,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
const playCode = String(item?.play_code ?? "");
if (!Number.isInteger(clientLineNo) || clientLineNo <= 0 || playCode.trim() === "") return;
const entry = entries[clientLineNo - 1];
if (!entry) return;
if (!entry || entry.play.play_code !== playCode) return;
cleanupPairs.add(`${entry.rowId}::${entry.amountKey}`);
});
@@ -929,6 +931,11 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
toast.error(payload.cleanup_hint ?? t("hall.ticketError.2002"));
return;
}
if (e instanceof LotteryApiBizError && code === 2008) {
setPreviewOpen(false);
setPreviewData(null);
clearPlaceTraceId();
}
toast.error(mapTicketBetError(code, msg, t));
} finally {
setPreviewLoading(false);
@@ -1010,8 +1017,14 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
toast.error(payload.cleanup_hint ?? t("hall.ticketError.2002"));
setPreviewOpen(false);
setPreviewData(null);
clearPlaceTraceId();
return;
}
if (e instanceof LotteryApiBizError && (code === 2008 || code === 2009)) {
setPreviewOpen(false);
setPreviewData(null);
clearPlaceTraceId();
}
toast.error(mapTicketBetError(code, msg, t));
} finally {
setPlaceLoading(false);
@@ -1051,7 +1064,10 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
);
}
const canSubmit = !tableDisabled && draftEntries.length > 0 && availableMinor >= debouncedSummary.actual;
const submitActualMinor =
previewData?.summary.total_actual_deduct ?? debouncedSummary.actual;
const canSubmit =
!tableDisabled && draftEntries.length > 0 && availableMinor >= submitActualMinor;
const favoriteChips = favorites.slice(0, 10);
const historyChips = historyNumbers.slice(0, 20);
@@ -1471,7 +1487,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
? t("hall.table.previewing")
: !isBettable
? t("hall.closed.title")
: availableMinor < debouncedSummary.actual
: availableMinor < submitActualMinor
? t("hall.table.insufficientBalance")
: t("hall.table.submitBet")}
</Button>
@@ -1492,7 +1508,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
data={previewData}
placing={placeLoading}
jackpotEnabled={Boolean(jackpot?.enabled)}
allowSubmit={isBettable && availableMinor >= debouncedSummary.actual}
allowSubmit={isBettable && availableMinor >= submitActualMinor}
onConfirmPlace={() => void handlePlace()}
/>