diff --git a/src/features/wallet/wallet-transfer-forms.tsx b/src/features/wallet/wallet-transfer-forms.tsx index 8227a97..5aaf8e6 100644 --- a/src/features/wallet/wallet-transfer-forms.tsx +++ b/src/features/wallet/wallet-transfer-forms.tsx @@ -29,6 +29,12 @@ import { formatWalletClientError } from "@/lib/wallet-api-error"; import { LotteryApiBizError } from "@/types/api/errors"; /** 处理中 / 待对账:刷新数据后提示用文案即可 */ +function emitWalletRefresh() { + if (typeof window !== "undefined") { + window.dispatchEvent(new Event("lottery-wallet-refresh")); + } +} + async function handleTransferMaybePending( e: unknown, onRefresh: () => Promise, @@ -37,11 +43,13 @@ async function handleTransferMaybePending( if (e instanceof LotteryApiBizError && e.code === 1002) { toast.message(e.message || t("wallet.pendingToast")); await onRefresh(); + emitWalletRefresh(); return true; } if (isAxiosError(e) && e.response?.status === 409) { toast.message(t("wallet.pendingShort")); await onRefresh(); + emitWalletRefresh(); return true; } return false; @@ -166,6 +174,7 @@ export function TransferInPanel({ toast.success(t("wallet.successIn")); setAmountText(""); await onSuccess(); + emitWalletRefresh(); } catch (e) { if (await handleTransferMaybePending(e, onSuccess, t)) { setLocalError(formatWalletClientError(e, t)); @@ -298,6 +307,7 @@ export function TransferOutPanel({ toast.success(t("wallet.successOut")); setAmountText(""); await onSuccess(); + emitWalletRefresh(); } catch (e) { if (await handleTransferMaybePending(e, onSuccess, t)) { setLocalError(formatWalletClientError(e, t)); diff --git a/src/lib/play-rules-html.ts b/src/lib/play-rules-html.ts index 75eaacf..f9facc1 100644 --- a/src/lib/play-rules-html.ts +++ b/src/lib/play-rules-html.ts @@ -7,6 +7,15 @@ const KEY_NE = "frontend.play_rules_html_ne"; type SettingItem = { key: string; value: unknown }; +function removeScriptTags(html: string | null): string | null { + if (!html) return html; + // React won't execute scripts injected via `dangerouslySetInnerHTML`. + // Removing them avoids the warning and prevents unintended script injection. + return html + .replace(/]*>[\s\S]*?<\/script>/gi, "") + .replace(/]*\/>/gi, ""); +} + function asNonEmptyString(value: unknown): string | null { if (typeof value !== "string") { return null; @@ -29,10 +38,10 @@ export function resolvePlayRulesHtml( const lang: AppLanguage = normalizeLanguage(language); if (lang === "zh") { - return zh ?? legacy; + return removeScriptTags(zh ?? legacy); } if (lang === "ne") { - return ne ?? en ?? zh ?? legacy; + return removeScriptTags(ne ?? en ?? zh ?? legacy); } - return en ?? zh ?? legacy; + return removeScriptTags(en ?? zh ?? legacy); }