feat: 增强开奖 API 的币种支持并优化钱包处理逻辑

更新 getDrawCurrent、getDrawResults 与 getDrawResultByNo 方法,新增币种参数支持,以适配玩家币种偏好。
优化 HallBettingGrid 及相关组件:支持币种切换时自动刷新钱包数据。
重构钱包处理逻辑,简化余额更新流程并提升用户体验。
新增会话过期相关多语言提示文案,并优化现有翻译内容,提升多语言环境下的提示清晰度。
This commit is contained in:
2026-05-27 16:52:12 +08:00
parent adae4a0be1
commit 58afa8e844
34 changed files with 373 additions and 379 deletions

View File

@@ -42,6 +42,7 @@ export function generateCSP(): string {
"connect-src": [
"'self'",
process.env.NEXT_PUBLIC_API_URL || "",
process.env.NEXT_PUBLIC_LOTTERY_API_BASE_URL || "",
// WebSocket 连接
"ws:",
"wss:",

View File

@@ -4,8 +4,8 @@ import axios, {
type AxiosResponse,
} from "axios";
import { setPlayerBearerToken, withPlayerAuthHeader } from "@/lib/lottery-auth";
import { clearPersistedPlayerBearerToken } from "@/lib/player-session";
import { withPlayerAuthHeader } from "@/lib/lottery-auth";
import { usePlayerSessionStore } from "@/stores/player-session-store";
import { withLotteryLocaleHeaders } from "@/lib/lottery-locale";
import {
LotteryApiBizError,
@@ -35,9 +35,10 @@ lotteryHttp.interceptors.response.use(
// 401: 会话过期,清除令牌并重定向
if (status === 401) {
clearPersistedPlayerBearerToken();
setPlayerBearerToken(null);
if (window.location.pathname !== "/") {
usePlayerSessionStore.getState().clearBearerToken();
const onEntry = window.location.pathname === "/";
const alreadyExpired = window.location.search.includes("session=expired");
if (!onEntry || !alreadyExpired) {
window.location.replace("/?session=expired");
}
}

View File

@@ -0,0 +1,12 @@
/** 玩法目录(`play/effective`)需要全量刷新时派发。 */
export const PLAY_CATALOG_REFRESH_EVENT = "lottery-play-catalog-refresh";
export type PlayCatalogRefreshSource = "play_config" | "odds" | "risk_cap" | "play_toggle";
export function dispatchPlayCatalogRefresh(source?: PlayCatalogRefreshSource): void {
if (typeof window !== "undefined") {
window.dispatchEvent(
new CustomEvent(PLAY_CATALOG_REFRESH_EVENT, { detail: { source } }),
);
}
}

View File

@@ -0,0 +1,27 @@
import { useNetworkConnectionStore } from "@/stores/network-connection-store";
const WALLET_REFRESH_BURST_MS = 30_000;
const WALLET_REFRESH_BURST_DURATION_MS = 2 * 60 * 1000;
/**
* 开奖等场景:立即刷新余额,并在限时内每 30s 派发 `lottery-wallet-refresh`(先清旧定时器,避免泄漏)。
*/
export function startWalletRefreshBurst(): void {
const store = useNetworkConnectionStore.getState();
store.clearWalletPolling();
window.dispatchEvent(new Event("lottery-wallet-refresh"));
const expiryAt = Date.now() + WALLET_REFRESH_BURST_DURATION_MS;
store.setWalletPollingExpiryAt(expiryAt);
const intervalId = window.setInterval(() => {
if (Date.now() > expiryAt) {
useNetworkConnectionStore.getState().clearWalletPolling();
return;
}
window.dispatchEvent(new Event("lottery-wallet-refresh"));
}, WALLET_REFRESH_BURST_MS);
store.setWalletPollingIntervalId(intervalId);
}