fix: 优化嵌入登录等待态并修复大厅与订单筛选交互

This commit is contained in:
2026-06-08 17:42:04 +08:00
parent 36adf8699d
commit 2ddba8462e
13 changed files with 71 additions and 75 deletions

View File

@@ -26,7 +26,6 @@ import type { HallDrawLiveSnapshot } from "@/features/hall/use-hall-draw-live";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
import { triggerWalletPollingAfterBet } from "@/hooks/use-wallet-polling";
import { getLotteryEcho } from "@/lib/lottery-echo";
import { getLotteryRequestLocale } from "@/lib/lottery-locale";
import { formatMinorAsCurrency, parseDecimalInputToMinor } from "@/lib/money";
import { playLabel } from "@/lib/play-labels";
import {
@@ -459,6 +458,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
const [resultOpen, setResultOpen] = useState(false);
const [resultData, setResultData] = useState<TicketPlaceData | null>(null);
const [quickFillState, setQuickFillState] = useState<QuickFillState>(() => loadQuickFillState());
const [riskStateDrawNo, setRiskStateDrawNo] = useState<string | null>(display?.draw_no ?? null);
const [liveSoldOutNumbers, setLiveSoldOutNumbers] = useState<Set<string>>(() => new Set());
const [liveWarningNumbers, setLiveWarningNumbers] = useState<Set<string>>(() => new Set());
const [debouncedSummary, setDebouncedSummary] = useState({ bet: 0, rebate: 0, actual: 0 });
@@ -475,9 +475,9 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
? crypto.randomUUID()
: `pl-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
const clearPlaceTraceId = () => {
const clearPlaceTraceId = useCallback(() => {
placeTraceIdRef.current = null;
};
}, []);
const loadCatalog = useCallback(async () => {
setCatalogState((s) => (s.kind === "ok" ? s : { kind: "loading" }));
try {
@@ -576,34 +576,17 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
const drawNo = display?.draw_no ?? null;
useEffect(() => {
if (riskStateDrawNo !== drawNo) {
setRiskStateDrawNo(drawNo);
setLiveSoldOutNumbers(new Set());
setLiveWarningNumbers(new Set());
}, [drawNo]);
}
const alertRows = display?.risk_pool_alerts ?? [];
const jackpot = display?.jackpot;
const currentQuickFill = quickFillState[activeCategory] ?? { favorites: [], history: [] };
const favorites = currentQuickFill.favorites;
const historyNumbers = currentQuickFill.history;
const jackpotPanelCopy = !jackpot?.enabled
? {
title: t("hall.jackpotPanel.disabledTitle"),
subtitle: t("hall.jackpotPanel.disabledSubtitle"),
description: t("hall.jackpotPanel.disabledDescription"),
}
: isBettable
? {
title: t("hall.jackpotPanel.infoTitle"),
subtitle: t("hall.jackpotPanel.infoSubtitle"),
description: t("hall.jackpotPanel.infoDescription"),
}
: {
title: t("hall.jackpotPanel.closedInfoTitle"),
subtitle: t("hall.jackpotPanel.closedInfoSubtitle"),
description: t("hall.jackpotPanel.closedInfoDescription"),
};
const tableDisabled = !isBettable || catalogState.kind !== "ok";
const sealedBetUi = Boolean(display && isHallSealedCountdownUi(display.status));
const defaultNumberPlaceholder =
@@ -715,8 +698,18 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
});
};
const clearAmountsForPlay = useCallback((playCode: string): boolean => {
let removed = false;
const hasAmountsForPlay = useCallback(
(playCode: string): boolean =>
rows.some((row) =>
Object.entries(row.amounts).some(
([amountKey, amountValue]) =>
amountKey.split("@")[0] === playCode && Boolean(amountValue?.trim()),
),
),
[rows],
);
const clearAmountsForPlay = useCallback((playCode: string) => {
setRows((current) =>
current.map((row) => {
const nextAmounts = { ...row.amounts };
@@ -726,13 +719,10 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
if (keyPlayCode !== playCode || !nextAmounts[amountKey]) return;
nextAmounts[amountKey] = "";
changed = true;
removed = true;
});
return changed ? { ...row, amounts: nextAmounts } : row;
}),
);
return removed;
}, []);
useEffect(() => {
@@ -743,7 +733,8 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
const onPlayToggle = (evt: PlayToggleWsEvent) => {
if (evt.enabled === false && typeof evt.play_code === "string") {
const removed = clearAmountsForPlay(evt.play_code);
const removed = hasAmountsForPlay(evt.play_code);
clearAmountsForPlay(evt.play_code);
setPreviewOpen(false);
setPreviewData(null);
clearPlaceTraceId();
@@ -809,7 +800,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
channel.stopListening(".risk.sold_out");
channel.stopListening(".risk.warning");
};
}, [clearAmountsForPlay, drawNo, loadCatalog, reloadDraw, t]);
}, [clearAmountsForPlay, clearPlaceTraceId, drawNo, hasAmountsForPlay, reloadDraw, t]);
const collectDraftLineIssues = useCallback((): DraftLineIssue[] => {
if (activeCategory === "JACKPOT") return [];