// 赛马竞猜事件监听模块,负责广播事件转发和页面恢复当前场次。 /** * 读取赛马面板 Alpine 状态。 * * @returns {Record|null} */ function getHorseRacePanelState() { const panel = document.getElementById("horse-race-panel"); if (!panel || typeof window.Alpine?.$data !== "function") { return null; } return window.Alpine.$data(panel); } /** * 读取赛马悬浮按钮 Alpine 状态。 * * @returns {Record|null} */ function getHorseRaceFabState() { const fab = document.getElementById("horse-race-fab"); if (!fab || typeof window.Alpine?.$data !== "function") { return null; } return window.Alpine.$data(fab); } /** * 从当前进行中的场次恢复赛马面板状态。 * * @param {Record} panelState 赛马面板 Alpine 状态 * @param {Record} race 当前场次 * @returns {void} */ function restoreCurrentHorseRace(panelState, race) { const seconds = Number(race.seconds_left || 0); panelState.raceId = race.id; panelState.horses = race.horses || []; panelState.totalPool = race.total_pool || 0; if (race.my_bet) { panelState.myBet = true; panelState.myBetHorseId = race.my_bet.horse_id; panelState.myBetAmount = race.my_bet.amount; const selectedHorse = panelState.horses.find((horse) => horse.id === race.my_bet.horse_id); panelState.myBetHorseName = selectedHorse ? `${selectedHorse.emoji}${selectedHorse.name}` : ""; } if (race.status === "betting" && seconds > 0) { panelState.phase = "betting"; panelState.countdown = seconds; return; } panelState.phase = race.status === "running" ? "running" : "settled"; } /** * 没有当前场次时重置赛马面板状态。 * * @param {Record} panelState 赛马面板 Alpine 状态 * @returns {void} */ function resetHorseRacePanel(panelState) { panelState.phase = "idle"; panelState.raceId = null; panelState.horses = []; panelState.totalPool = 0; panelState.countdown = 0; } /** * 页面加载后恢复历史记录、金币和当前场次。 * * @returns {Promise} */ async function restoreHorseRaceOnReady() { try { const panelState = getHorseRacePanelState(); if (!panelState) { return; } const historyData = await panelState.requestJson("/horse-race/history"); panelState.history = (historyData.history || []).reverse(); const currentData = await panelState.requestJson("/horse-race/current"); panelState.syncUserGold(currentData.jjb); // 游戏可访问时常驻显示 FAB,方便用户随时打开赛马面板。 const fabState = getHorseRaceFabState(); if (fabState) { fabState.visible = true; } if (currentData.race) { restoreCurrentHorseRace(panelState, currentData.race); return; } resetHorseRacePanel(panelState); } catch (error) { console.warn("[赛马] 初始化失败", error); } } /** * 绑定赛马广播事件和页面恢复逻辑。 * * @returns {void} */ export function bindHorseRaceEvents() { if (typeof window === "undefined" || typeof document === "undefined" || window.__horseRaceEventsBound) { return; } window.__horseRaceEventsBound = true; window.addEventListener("chat:horse.opened", (event) => { getHorseRacePanelState()?.openRace(event.detail); }); window.addEventListener("chat:horse.progress", (event) => { getHorseRacePanelState()?.updateProgress(event.detail); }); window.addEventListener("chat:horse.settled", (event) => { getHorseRacePanelState()?.showResult(event.detail); }); document.addEventListener("DOMContentLoaded", () => window.deferChatGameBootstrap?.(restoreHorseRaceOnReady)); }