feat: 增强投注结果弹窗与投注网格功能
更新 HallBetResultDialog:根据成功与失败数量显示不同的结果图标与标题。 优化 HallBettingGrid:新增 place trace ID 管理机制,更好地处理投注提交流程,并防止重复扣费。 增强注单详情页面:针对临时状态中的注单自动刷新,提升用户体验。 新增多语言翻译:补充投注结果与状态相关文案,支持更完善的用户反馈。
This commit is contained in:
@@ -85,37 +85,43 @@ export function useHallDrawLive(): HallDrawLiveSnapshot {
|
||||
(s) => s.setWalletPollingExpiryAt,
|
||||
);
|
||||
|
||||
const latestSnapshotMsRef = useRef(0);
|
||||
|
||||
const applySnapshot = useCallback((anchorMs: number, data: DrawCurrentPayload | null) => {
|
||||
if (anchorMs < latestSnapshotMsRef.current) {
|
||||
return;
|
||||
}
|
||||
latestSnapshotMsRef.current = anchorMs;
|
||||
setServerNowMs(anchorMs);
|
||||
setRaw(data);
|
||||
setEmittedAtMs(anchorMs);
|
||||
}, []);
|
||||
|
||||
const mergeFromWs = useCallback((evt: HallWsEnvelope) => {
|
||||
const anchor = evt.emitted_at_ms ?? Date.now();
|
||||
setServerNowMs(anchor);
|
||||
setRaw(evt.data);
|
||||
setEmittedAtMs(anchor);
|
||||
}, []);
|
||||
applySnapshot(anchor, evt.data);
|
||||
}, [applySnapshot]);
|
||||
|
||||
const mergeCountdownFromWs = useCallback((evt: HallWsEnvelope) => {
|
||||
if (evt.data === null) return;
|
||||
const anchor = evt.emitted_at_ms ?? Date.now();
|
||||
setServerNowMs(anchor);
|
||||
setRaw(evt.data);
|
||||
setEmittedAtMs(anchor);
|
||||
}, []);
|
||||
applySnapshot(anchor, evt.data);
|
||||
}, [applySnapshot]);
|
||||
|
||||
const updateFromResponse = useCallback((resp: DrawCurrentResponse) => {
|
||||
setServerNowMs(resp.server_now_ms);
|
||||
setRaw(resp.data);
|
||||
setEmittedAtMs(resp.server_now_ms);
|
||||
}, []);
|
||||
|
||||
const load = useCallback(async () => {
|
||||
const load = useCallback(async (options?: { force?: boolean }) => {
|
||||
try {
|
||||
setError(null);
|
||||
const d = await getDrawCurrent();
|
||||
updateFromResponse(d);
|
||||
const wsConnected = useNetworkConnectionStore.getState().isWebSocketConnected;
|
||||
if (!options?.force && wsConnected && d.server_now_ms < latestSnapshotMsRef.current) {
|
||||
return;
|
||||
}
|
||||
applySnapshot(d.server_now_ms, d.data);
|
||||
} catch {
|
||||
setError("draw.loadFailedRefresh");
|
||||
setRaw(undefined);
|
||||
}
|
||||
}, [updateFromResponse]);
|
||||
}, [applySnapshot]);
|
||||
|
||||
// 初始加载
|
||||
useEffect(() => {
|
||||
@@ -212,7 +218,9 @@ export function useHallDrawLive(): HallDrawLiveSnapshot {
|
||||
}
|
||||
|
||||
return () => {
|
||||
echo.leave("lottery-hall");
|
||||
channel.stopListening(".draw.countdown");
|
||||
channel.stopListening(".draw.status_change");
|
||||
channel.stopListening(".result.published");
|
||||
if (echo.connector?.pusher) {
|
||||
echo.connector.pusher.connection.unbind("connected", handleConnected);
|
||||
echo.connector.pusher.connection.unbind(
|
||||
@@ -312,7 +320,7 @@ export function useHallDrawLive(): HallDrawLiveSnapshot {
|
||||
|
||||
if (trigger && zeroRefreshKeyRef.current !== trigger) {
|
||||
zeroRefreshKeyRef.current = trigger;
|
||||
void load();
|
||||
void load({ force: true });
|
||||
}
|
||||
}, [display, nowMs, load]);
|
||||
|
||||
@@ -342,14 +350,17 @@ export function useHallDrawLive(): HallDrawLiveSnapshot {
|
||||
return () => window.clearInterval(intervalId);
|
||||
}, [needsFastDrawPoll, load]);
|
||||
|
||||
// WebSocket 已连接时的兜底轮询(tick 延迟时的保险)
|
||||
// WebSocket 已连接时的兜底轮询(tick 延迟时的保险;常态下由 WS 推送,避免 HTTP 覆盖新快照)
|
||||
useEffect(() => {
|
||||
if (isWebSocketConnected && !needsFastDrawPoll) {
|
||||
return;
|
||||
}
|
||||
const intervalMs = needsFastDrawPoll ? 15_000 : 45_000;
|
||||
const intervalId = window.setInterval(() => {
|
||||
void load();
|
||||
}, intervalMs);
|
||||
return () => window.clearInterval(intervalId);
|
||||
}, [load, needsFastDrawPoll]);
|
||||
}, [load, needsFastDrawPoll, isWebSocketConnected]);
|
||||
|
||||
return { raw, display, serverNowMs, nowMs, error, reload: load, isBettable };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user