// 游戏管理后台事件代理,逐步替代 game-configs Blade 内联脚本。 let adminGameConfigControlsBound = false; /** * 读取后台 layout 注入的 CSRF token。 * * @returns {string} */ function getCsrfToken() { return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") || ""; } /** * 生成单个统计卡片 HTML。 * * @param {{icon:string,title:string,color:string,items:Array<{label:string,value:string|number}>}} card 统计卡片 * @returns {string} */ function renderStatsCard(card) { return `
${card.icon} ${card.title}
${card.items.map((item) => `
${item.label} ${item.value}
`).join("")}
`; } /** * 将游戏统计接口响应转换为顶部统计卡片。 * * @param {Record>} data 统计接口响应 * @returns {string} */ function renderGameStats(data) { const cards = [ { icon: "🎲", title: "百家乐", items: [ { label: "总局数", value: data.baccarat.total_rounds.toLocaleString() }, { label: "总下注", value: `${data.baccarat.total_bets.toLocaleString()} 笔` }, { label: "今日局数", value: data.baccarat.today_rounds.toLocaleString() }, ], color: "border-red-200 bg-red-50", }, { icon: "🎰", title: "老虎机", items: [ { label: "总转动", value: `${data.slot.total_spins.toLocaleString()} 次` }, { label: "三7大奖", value: `${data.slot.jackpot_count.toLocaleString()} 次` }, { label: "今日转动", value: data.slot.today_spins.toLocaleString() }, ], color: "border-amber-200 bg-amber-50", }, { icon: "🐎", title: "赛马竞猜", items: [ { label: "总场次", value: data.horse.total_races.toLocaleString() }, { label: "总注池", value: `${data.horse.total_pool.toLocaleString()} 金` }, { label: "今日场次", value: data.horse.today_races.toLocaleString() }, ], color: "border-emerald-200 bg-emerald-50", }, { icon: "📦", title: "神秘箱子", items: [ { label: "总投放", value: data.mystery_box.total_dropped.toLocaleString() }, { label: "已领取", value: data.mystery_box.total_claimed.toLocaleString() }, { label: "今日投放", value: data.mystery_box.today_dropped.toLocaleString() }, ], color: "border-purple-200 bg-purple-50", }, { icon: "🔮", title: "神秘占卜", items: [ { label: "总占卜", value: `${data.fortune.total_times.toLocaleString()} 次` }, { label: "吉签/凶签", value: `${data.fortune.jackpot_count} / ${data.fortune.curse_count}` }, { label: "今日占卜", value: data.fortune.today_times.toLocaleString() }, ], color: "border-fuchsia-200 bg-fuchsia-50", }, { icon: "🎟️", title: "双色球彩票", items: [ { label: "总期数", value: `${data.lottery.total_issues.toLocaleString()} 期` }, { label: "历史彩票", value: `${data.lottery.total_bets.toLocaleString()} 张` }, { label: "累计奖池", value: `${data.lottery.total_pool.toLocaleString()} 金` }, ], color: "border-rose-200 bg-rose-50", }, { icon: "♟️", title: "五子棋", items: [ { label: "总对局", value: `${data.gomoku.total_games.toLocaleString()} 局` }, { label: "人机/对战", value: `${data.gomoku.pve_count} / ${data.gomoku.pvp_count}` }, { label: "今日对局", value: data.gomoku.today_games.toLocaleString() }, ], color: "border-blue-200 bg-blue-50", }, ]; return cards.map((card) => renderStatsCard(card)).join(""); } /** * 加载各游戏实时统计摘要并渲染到顶部面板。 * * @param {HTMLButtonElement} button 触发按钮 * @returns {Promise} */ async function loadGameStats(button) { const statsUrl = button.getAttribute("data-game-stats-url") || ""; const panel = document.getElementById("game-stats-panel"); const grid = document.getElementById("game-stats-grid"); if (!statsUrl || !panel || !grid) { return; } grid.innerHTML = '
⏳ 加载中...
'; panel.classList.remove("hidden"); try { const response = await fetch(statsUrl, { headers: { "Accept": "application/json" }, }); const data = await response.json(); grid.innerHTML = renderGameStats(data); } catch (error) { grid.innerHTML = '
❌ 加载失败,请重试
'; } } /** * 根据开关接口响应更新游戏卡片状态。 * * @param {HTMLButtonElement} button 开关按钮 * @param {boolean} enabled 是否启用 * @returns {void} */ function updateGameToggleState(button, enabled) { const gameKey = button.getAttribute("data-game-key") || ""; const card = document.getElementById(`game-card-${gameKey}`); const badge = document.getElementById(`badge-${gameKey}`); const header = card?.querySelector(".flex.items-center.justify-between"); if (badge) { badge.textContent = enabled ? "运行中" : "已关闭"; badge.className = `text-xs px-2 py-0.5 rounded-full font-bold ${ enabled ? "bg-emerald-100 text-emerald-700" : "bg-gray-200 text-gray-500" }`; } button.textContent = enabled ? "⏸ 关闭游戏" : "▶ 开启游戏"; button.className = `px-5 py-2 rounded-lg font-bold text-sm transition shadow-sm ${ enabled ? "bg-red-500 hover:bg-red-600 text-white" : "bg-emerald-500 hover:bg-emerald-600 text-white" }`; // 卡片头部背景是游戏状态的主要视觉反馈,需要和按钮、徽章同步。 if (header) { header.classList.toggle("bg-emerald-50", enabled); header.classList.toggle("bg-gray-50", !enabled); } } /** * 切换游戏开启/关闭状态。 * * @param {HTMLButtonElement} button 开关按钮 * @returns {Promise} */ async function toggleGame(button) { const toggleUrl = button.getAttribute("data-game-toggle-url") || ""; if (!toggleUrl || button.disabled) { return; } button.disabled = true; try { const response = await fetch(toggleUrl, { method: "POST", headers: { "X-CSRF-TOKEN": getCsrfToken(), "Accept": "application/json", }, }); const data = await response.json(); if (!data?.ok) { return; } updateGameToggleState(button, Boolean(data.enabled)); window.adminDialog?.alert( data.message, data.enabled ? "游戏已开启" : "游戏已关闭", data.enabled ? "✅" : "⏸", ); } finally { button.disabled = false; } } /** * 绑定游戏管理页通用操作按钮。 * * @returns {void} */ export function bindAdminGameConfigControls() { if (adminGameConfigControlsBound || typeof document === "undefined") { return; } adminGameConfigControlsBound = true; document.addEventListener("click", (event) => { if (!(event.target instanceof Element)) { return; } const statsButton = event.target.closest("[data-game-stats-url]"); if (statsButton instanceof HTMLButtonElement) { event.preventDefault(); void loadGameStats(statsButton); return; } const toggleButton = event.target.closest("[data-game-toggle-url]"); if (toggleButton instanceof HTMLButtonElement) { event.preventDefault(); void toggleGame(toggleButton); } }); }