迁移赛马事件脚本
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
* - game-panels.js:处理通用游戏面板关闭事件。
|
||||
* - gomoku-controls.js:处理五子棋外部打开和接受邀请入口。
|
||||
* - horse-race-fab.js:处理赛马竞猜悬浮按钮拖动与打开面板。
|
||||
* - horse-race-events.js:处理赛马广播事件和页面恢复当前场次。
|
||||
* - holiday-modal.js:处理节日福利弹窗、广播监听、领取状态和系统消息入口。
|
||||
* - initial-state.js:恢复首屏历史消息、欢迎消息、入场特效和挂起婚姻事件。
|
||||
* - bank-modal.js:处理银行弹窗、转账、排行和标签切换。
|
||||
@@ -110,6 +111,7 @@ export { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/g
|
||||
export { bindGamePanelControls } from "./chat-room/game-panels.js";
|
||||
export { acceptGomokuInvite, bindGomokuControls, openGomokuPanel } from "./chat-room/gomoku-controls.js";
|
||||
export { bindHorseRaceFabControls, horseRaceFab } from "./chat-room/horse-race-fab.js";
|
||||
export { bindHorseRaceEvents } from "./chat-room/horse-race-events.js";
|
||||
export {
|
||||
bindHolidayModalControls,
|
||||
buildHolidayClaimActionButton,
|
||||
@@ -256,6 +258,7 @@ import { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/g
|
||||
import { bindGamePanelControls } from "./chat-room/game-panels.js";
|
||||
import { acceptGomokuInvite, bindGomokuControls, openGomokuPanel } from "./chat-room/gomoku-controls.js";
|
||||
import { bindHorseRaceFabControls, horseRaceFab } from "./chat-room/horse-race-fab.js";
|
||||
import { bindHorseRaceEvents } from "./chat-room/horse-race-events.js";
|
||||
import {
|
||||
bindHolidayModalControls,
|
||||
buildHolidayClaimActionButton,
|
||||
@@ -412,6 +415,7 @@ if (typeof window !== "undefined") {
|
||||
openGomokuPanel,
|
||||
bindHorseRaceFabControls,
|
||||
horseRaceFab,
|
||||
bindHorseRaceEvents,
|
||||
bindHolidayModalControls,
|
||||
buildHolidayClaimActionButton,
|
||||
buildHolidaySystemMessage,
|
||||
@@ -654,6 +658,7 @@ if (typeof window !== "undefined") {
|
||||
bindGamePanelControls();
|
||||
bindGomokuControls();
|
||||
bindHorseRaceFabControls();
|
||||
bindHorseRaceEvents();
|
||||
bindHolidayModalControls();
|
||||
bindChatInitialStateControls();
|
||||
bindBankControls();
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
// 赛马竞猜事件监听模块,负责广播事件转发和页面恢复当前场次。
|
||||
|
||||
/**
|
||||
* 读取赛马面板 Alpine 状态。
|
||||
*
|
||||
* @returns {Record<string, any>|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<string, any>|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<string, any>} panelState 赛马面板 Alpine 状态
|
||||
* @param {Record<string, any>} 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<string, any>} panelState 赛马面板 Alpine 状态
|
||||
* @returns {void}
|
||||
*/
|
||||
function resetHorseRacePanel(panelState) {
|
||||
panelState.phase = "idle";
|
||||
panelState.raceId = null;
|
||||
panelState.horses = [];
|
||||
panelState.totalPool = 0;
|
||||
panelState.countdown = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面加载后恢复历史记录、金币和当前场次。
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
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));
|
||||
}
|
||||
@@ -727,80 +727,5 @@
|
||||
};
|
||||
}
|
||||
|
||||
// ─── WebSocket 监听 ──────────────────────────────────────────────
|
||||
|
||||
/** 收到开赛事件:弹出押注面板 */
|
||||
window.addEventListener('chat:horse.opened', (e) => {
|
||||
const panel = document.getElementById('horse-race-panel');
|
||||
if (panel) Alpine.$data(panel).openRace(e.detail);
|
||||
});
|
||||
|
||||
/** 收到跑马进度事件:更新赛道 */
|
||||
window.addEventListener('chat:horse.progress', (e) => {
|
||||
const panel = document.getElementById('horse-race-panel');
|
||||
if (panel) Alpine.$data(panel).updateProgress(e.detail);
|
||||
});
|
||||
|
||||
/** 收到结算事件:展示结果 */
|
||||
window.addEventListener('chat:horse.settled', (e) => {
|
||||
const panel = document.getElementById('horse-race-panel');
|
||||
if (panel) Alpine.$data(panel).showResult(e.detail);
|
||||
});
|
||||
|
||||
/** 页面加载时恢复进行中的场次 */
|
||||
document.addEventListener('DOMContentLoaded', () => window.deferChatGameBootstrap(async () => {
|
||||
try {
|
||||
const panel = document.getElementById('horse-race-panel');
|
||||
const histData = panel ? await Alpine.$data(panel).requestJson('/horse-race/history') : { history: [] };
|
||||
const fab = document.getElementById('horse-race-fab');
|
||||
|
||||
if (panel) {
|
||||
Alpine.$data(panel).history = (histData.history || []).reverse();
|
||||
}
|
||||
|
||||
const curData = panel ? await Alpine.$data(panel).requestJson('/horse-race/current') : { race: null };
|
||||
if (panel) {
|
||||
Alpine.$data(panel).syncUserGold(curData.jjb);
|
||||
}
|
||||
|
||||
// 游戏可访问则常驻显示 FAB(与占卜一致)
|
||||
if (fab) Alpine.$data(fab).visible = true;
|
||||
|
||||
if (curData.race && panel) {
|
||||
const race = curData.race;
|
||||
const seconds = race.seconds_left || 0;
|
||||
const panelData = Alpine.$data(panel);
|
||||
|
||||
panelData.raceId = race.id;
|
||||
panelData.horses = race.horses || [];
|
||||
panelData.totalPool = race.total_pool || 0;
|
||||
|
||||
if (race.my_bet) {
|
||||
panelData.myBet = true;
|
||||
panelData.myBetHorseId = race.my_bet.horse_id;
|
||||
panelData.myBetAmount = race.my_bet.amount;
|
||||
const h = panelData.horses.find(h => h.id === race.my_bet.horse_id);
|
||||
panelData.myBetHorseName = h ? h.emoji + h.name : '';
|
||||
}
|
||||
|
||||
if (race.status === 'betting' && seconds > 0) {
|
||||
panelData.phase = 'betting';
|
||||
panelData.countdown = seconds;
|
||||
} else if (race.status === 'running') {
|
||||
panelData.phase = 'running';
|
||||
} else {
|
||||
panelData.phase = 'settled';
|
||||
}
|
||||
} else if (panel) {
|
||||
const panelData = Alpine.$data(panel);
|
||||
panelData.phase = 'idle';
|
||||
panelData.raceId = null;
|
||||
panelData.horses = [];
|
||||
panelData.totalPool = 0;
|
||||
panelData.countdown = 0;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[赛马] 初始化失败', e);
|
||||
}
|
||||
}));
|
||||
{{-- 赛马广播监听和页面恢复逻辑已迁移到 resources/js/chat-room/horse-race-events.js --}}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user