迁移百家乐买单活动脚本
This commit is contained in:
@@ -37,7 +37,13 @@ export {
|
||||
openAdminBaccaratLossCoverModal,
|
||||
submitBaccaratLossCoverEvent,
|
||||
} from "./chat-room/baccarat-loss-cover-admin.js";
|
||||
export { bindBaccaratLossCoverControls } from "./chat-room/baccarat-loss-cover.js";
|
||||
export {
|
||||
bindBaccaratLossCoverControls,
|
||||
claimBaccaratLossCover,
|
||||
closeBaccaratLossCoverModal,
|
||||
openBaccaratLossCoverModal,
|
||||
switchBaccaratLossCoverTab,
|
||||
} from "./chat-room/baccarat-loss-cover.js";
|
||||
export { bindGameHallControls } from "./chat-room/game-hall.js";
|
||||
export { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/game-bootstrap.js";
|
||||
export { bindGamePanelControls } from "./chat-room/game-panels.js";
|
||||
@@ -121,7 +127,13 @@ import {
|
||||
openAdminBaccaratLossCoverModal,
|
||||
submitBaccaratLossCoverEvent,
|
||||
} from "./chat-room/baccarat-loss-cover-admin.js";
|
||||
import { bindBaccaratLossCoverControls } from "./chat-room/baccarat-loss-cover.js";
|
||||
import {
|
||||
bindBaccaratLossCoverControls,
|
||||
claimBaccaratLossCover,
|
||||
closeBaccaratLossCoverModal,
|
||||
openBaccaratLossCoverModal,
|
||||
switchBaccaratLossCoverTab,
|
||||
} from "./chat-room/baccarat-loss-cover.js";
|
||||
import { bindGameHallControls } from "./chat-room/game-hall.js";
|
||||
import { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/game-bootstrap.js";
|
||||
import { bindGamePanelControls } from "./chat-room/game-panels.js";
|
||||
@@ -217,6 +229,10 @@ if (typeof window !== "undefined") {
|
||||
closeAdminBaccaratLossCoverModal,
|
||||
closeCurrentBaccaratLossCoverEvent,
|
||||
bindBaccaratLossCoverControls,
|
||||
claimBaccaratLossCover,
|
||||
closeBaccaratLossCoverModal,
|
||||
openBaccaratLossCoverModal,
|
||||
switchBaccaratLossCoverTab,
|
||||
bindGameHallControls,
|
||||
bindGameBootstrapControls,
|
||||
deferChatGameBootstrap,
|
||||
@@ -298,8 +314,12 @@ if (typeof window !== "undefined") {
|
||||
window.openHolidayRunFromSystemMessage = openHolidayRunFromSystemMessage;
|
||||
window.closeAdminBaccaratLossCoverModal = closeAdminBaccaratLossCoverModal;
|
||||
window.closeCurrentBaccaratLossCoverEvent = closeCurrentBaccaratLossCoverEvent;
|
||||
window.claimBaccaratLossCover = claimBaccaratLossCover;
|
||||
window.closeBaccaratLossCoverModal = closeBaccaratLossCoverModal;
|
||||
window.openBaccaratLossCoverModal = openBaccaratLossCoverModal;
|
||||
window.openAdminBaccaratLossCoverModal = openAdminBaccaratLossCoverModal;
|
||||
window.submitBaccaratLossCoverEvent = submitBaccaratLossCoverEvent;
|
||||
window.switchBaccaratLossCoverTab = switchBaccaratLossCoverTab;
|
||||
window.bankAction = bankAction;
|
||||
window.bankLoadInfo = bankLoadInfo;
|
||||
window.bankShowMsg = bankShowMsg;
|
||||
|
||||
@@ -1,18 +1,360 @@
|
||||
// 百乐加强买单活动前台弹窗事件代理,替代 Blade 内联 onclick。
|
||||
// 百乐加强买单活动前台弹窗逻辑,负责活动摘要、历史记录和补偿领取。
|
||||
|
||||
import { escapeHtml } from "./html.js";
|
||||
|
||||
let baccaratLossCoverEventsBound = false;
|
||||
|
||||
/**
|
||||
* 调用买单活动前台存量全局函数。
|
||||
* 获取前台买单活动弹窗。
|
||||
*
|
||||
* @param {string} functionName 全局函数名
|
||||
* @param {...unknown} args 参数
|
||||
* @returns {HTMLElement|null}
|
||||
*/
|
||||
function getLossCoverModal() {
|
||||
return document.getElementById("baccarat-loss-cover-modal");
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 Blade 注入到弹窗上的接口地址。
|
||||
*
|
||||
* @returns {{summaryUrl:string,historyUrl:string,claimUrlTemplate:string}|null}
|
||||
*/
|
||||
function resolveLossCoverUrls() {
|
||||
const modal = getLossCoverModal();
|
||||
if (!modal) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
summaryUrl: modal.dataset.blcSummaryUrl || "",
|
||||
historyUrl: modal.dataset.blcHistoryUrl || "",
|
||||
claimUrlTemplate: modal.dataset.blcClaimUrlTemplate || "",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成补偿领取接口地址。
|
||||
*
|
||||
* @param {number|string} eventId 活动 ID
|
||||
* @returns {string}
|
||||
*/
|
||||
function resolveClaimUrl(eventId) {
|
||||
const urls = resolveLossCoverUrls();
|
||||
|
||||
return urls?.claimUrlTemplate.replace("__EVENT__", encodeURIComponent(String(eventId))) || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 CSRF Token。
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
function csrf() {
|
||||
return document.querySelector('meta[name="csrf-token"]')?.content || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全格式化活动时间。
|
||||
*
|
||||
* @param {string|null|undefined} value
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatTime(value) {
|
||||
if (!value) {
|
||||
return "—";
|
||||
}
|
||||
|
||||
return new Date(value).toLocaleString("zh-CN", {
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步当前用户金币到全局上下文和相关展示节点。
|
||||
*
|
||||
* @param {number} amount
|
||||
* @returns {void}
|
||||
*/
|
||||
function callLossCoverGlobal(functionName, ...args) {
|
||||
// 前台弹窗的数据加载、领取接口和金币同步仍由 Blade 旧脚本维护。
|
||||
if (typeof window[functionName] === "function") {
|
||||
window[functionName](...args);
|
||||
function syncUserGold(amount) {
|
||||
if (!Number.isFinite(amount) || !window.chatContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.chatContext.userJjb = Number(window.chatContext.userJjb || 0) + amount;
|
||||
window.chatContext.myGold = Number(window.chatContext.myGold || 0) + amount;
|
||||
|
||||
const hallGold = document.getElementById("game-hall-jjb");
|
||||
if (hallGold) {
|
||||
hallGold.textContent = Number(window.chatContext.userJjb || 0).toLocaleString();
|
||||
}
|
||||
|
||||
const modalGold = document.getElementById("blc-modal-jjb");
|
||||
if (modalGold) {
|
||||
modalGold.textContent = Number(window.chatContext.userJjb || 0).toLocaleString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染当前买单活动摘要。
|
||||
*
|
||||
* @param {object|null} event
|
||||
* @returns {void}
|
||||
*/
|
||||
function renderCurrentEvent(event) {
|
||||
const container = document.getElementById("blc-current-event");
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
container.innerHTML = `
|
||||
<div style="font-size:30px; margin-bottom:10px;">📭</div>
|
||||
<div style="font-size:16px; font-weight:bold; color:#166534;">当前暂无进行中的买单活动</div>
|
||||
<div style="font-size:12px; color:#4b5563; margin-top:8px;">可以在输入框上方的管理员按钮中创建新活动,也可以在这里查看历史记录。</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
const myRecord = event.my_record;
|
||||
const claimButton = event.status === "claimable" && myRecord?.claim_status === "pending"
|
||||
? `<button type="button" data-blc-claim="${Number(event.id)}" style="padding:8px 18px;border:none;border-radius:999px;background:#16a34a;color:#fff;font-size:12px;font-weight:bold;cursor:pointer;">领取补偿</button>`
|
||||
: "";
|
||||
|
||||
// 服务端活动字段进入 HTML 前统一转义,避免标题、说明或用户名污染 DOM。
|
||||
container.innerHTML = `
|
||||
<div style="display:flex; justify-content:space-between; align-items:flex-start; gap:12px; text-align:left;">
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:18px; font-weight:900; color:#166534;">${escapeHtml(String(event.title || ""))}</div>
|
||||
<div style="font-size:12px; color:#4b5563; margin-top:6px; line-height:1.7;">${escapeHtml(String(event.description || "活动期间参与百家乐,输掉的金币可在活动结束后领取补偿。"))}</div>
|
||||
</div>
|
||||
<span style="padding:4px 10px; border-radius:999px; background:#dcfce7; color:#166534; font-size:12px; font-weight:bold;">${escapeHtml(String(event.status_label || ""))}</span>
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-top:16px; text-align:left;">
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">开启人</div>
|
||||
<div style="font-size:14px; font-weight:bold; color:#166534; margin-top:3px;">${escapeHtml(String(event.creator_username || ""))}</div>
|
||||
</div>
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">活动时间</div>
|
||||
<div style="font-size:13px; font-weight:bold; color:#166534; margin-top:3px;">${escapeHtml(formatTime(event.starts_at))} - ${escapeHtml(formatTime(event.ends_at))}</div>
|
||||
</div>
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">最终已发补偿</div>
|
||||
<div style="font-size:14px; font-weight:bold; color:#166534; margin-top:3px;">${Number(event.total_claimed_amount || 0).toLocaleString()} 金币</div>
|
||||
</div>
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">我的状态</div>
|
||||
<div style="font-size:14px; font-weight:bold; color:#166534; margin-top:3px;">${escapeHtml(String(myRecord?.claim_status_label || "未参与"))}</div>
|
||||
</div>
|
||||
</div>
|
||||
${myRecord ? `
|
||||
<div style="margin-top:16px; background:#fffbeb; border:1px solid #fde68a; border-radius:10px; padding:14px; text-align:left;">
|
||||
<div style="font-size:13px; font-weight:bold; color:#a16207; margin-bottom:8px;">我的活动记录</div>
|
||||
<div style="display:grid; grid-template-columns:repeat(2,1fr); gap:8px; font-size:12px; color:#4b5563;">
|
||||
<div>累计下注:<b style="color:#166534;">${Number(myRecord.total_bet_amount || 0).toLocaleString()}</b></div>
|
||||
<div>累计输掉:<b style="color:#b91c1c;">${Number(myRecord.total_loss_amount || 0).toLocaleString()}</b></div>
|
||||
<div>可领补偿:<b style="color:#166534;">${Number(myRecord.compensation_amount || 0).toLocaleString()}</b></div>
|
||||
<div>已领补偿:<b style="color:#166534;">${Number(myRecord.claimed_amount || 0).toLocaleString()}</b></div>
|
||||
</div>
|
||||
${claimButton ? `<div style="margin-top:12px;">${claimButton}</div>` : ""}
|
||||
</div>
|
||||
` : ""}
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染买单活动历史记录。
|
||||
*
|
||||
* @param {object[]} events
|
||||
* @returns {void}
|
||||
*/
|
||||
function renderHistory(events) {
|
||||
const container = document.getElementById("blc-history-list");
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!events || events.length === 0) {
|
||||
container.innerHTML = '<div style="text-align:center;color:#6b7280;padding:24px 0;">暂无活动记录</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = events.map((event) => {
|
||||
const myRecord = event.my_record;
|
||||
const claimButton = event.status === "claimable" && myRecord?.claim_status === "pending"
|
||||
? `<button type="button" data-blc-claim="${Number(event.id)}" style="padding:6px 14px;border:none;border-radius:999px;background:#16a34a;color:#fff;font-size:12px;font-weight:bold;cursor:pointer;">领取补偿</button>`
|
||||
: "";
|
||||
|
||||
return `
|
||||
<div style="background:#fff; border:1px solid #dcfce7; border-left:4px solid #16a34a; border-radius:8px; padding:14px;">
|
||||
<div style="display:flex; justify-content:space-between; gap:10px; align-items:flex-start;">
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:15px; font-weight:bold; color:#166534;">${escapeHtml(String(event.title || ""))}</div>
|
||||
<div style="font-size:12px; color:#4b5563; margin-top:4px;">开启人:${escapeHtml(String(event.creator_username || ""))} | ${escapeHtml(formatTime(event.starts_at))} - ${escapeHtml(formatTime(event.ends_at))}</div>
|
||||
</div>
|
||||
<span style="padding:4px 10px; border-radius:999px; background:#f0fdf4; color:#166534; font-size:12px; font-weight:bold;">${escapeHtml(String(event.status_label || ""))}</span>
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns:repeat(2,1fr); gap:8px; margin-top:12px; font-size:12px; color:#4b5563;">
|
||||
<div>最终补偿发放:<b style="color:#166534;">${Number(event.total_claimed_amount || 0).toLocaleString()}</b></div>
|
||||
<div>本次总输金币:<b style="color:#b91c1c;">${Number(event.total_loss_amount || 0).toLocaleString()}</b></div>
|
||||
<div>我的状态:<b style="color:#166534;">${escapeHtml(String(myRecord?.claim_status_label || "未参与"))}</b></div>
|
||||
<div>我的可领:<b style="color:#166534;">${Number(myRecord?.compensation_amount || 0).toLocaleString()}</b></div>
|
||||
</div>
|
||||
${myRecord ? `<div style="margin-top:8px; font-size:12px; color:#6b7280;">累计下注 ${Number(myRecord.total_bet_amount || 0).toLocaleString()} | 累计输掉 ${Number(myRecord.total_loss_amount || 0).toLocaleString()} | 已领 ${Number(myRecord.claimed_amount || 0).toLocaleString()}</div>` : ""}
|
||||
${claimButton ? `<div style="margin-top:10px;">${claimButton}</div>` : ""}
|
||||
</div>
|
||||
`;
|
||||
}).join("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载当前活动摘要。
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function loadSummary() {
|
||||
const current = document.getElementById("blc-current-event");
|
||||
const urls = resolveLossCoverUrls();
|
||||
if (!current || !urls?.summaryUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
current.innerHTML = "加载中…";
|
||||
|
||||
try {
|
||||
const response = await fetch(`${urls.summaryUrl}?scene=overview`, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
renderCurrentEvent(data.event || null);
|
||||
} catch (error) {
|
||||
current.innerHTML = '<div style="color:#dc2626;">活动摘要加载失败,请稍后重试。</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载活动历史记录。
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function loadHistory() {
|
||||
const list = document.getElementById("blc-history-list");
|
||||
const urls = resolveLossCoverUrls();
|
||||
if (!list || !urls?.historyUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = "加载中…";
|
||||
|
||||
try {
|
||||
const response = await fetch(urls.historyUrl, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
renderHistory(data.events || []);
|
||||
} catch (error) {
|
||||
list.innerHTML = '<div style="color:#dc2626;">活动历史加载失败,请稍后重试。</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换买单活动弹窗 Tab。
|
||||
*
|
||||
* @param {string} tab
|
||||
* @returns {void}
|
||||
*/
|
||||
export function switchBaccaratLossCoverTab(tab) {
|
||||
const overview = document.getElementById("blc-overview-pane");
|
||||
const history = document.getElementById("blc-history-pane");
|
||||
const overviewButton = document.getElementById("blc-tab-overview");
|
||||
const historyButton = document.getElementById("blc-tab-history");
|
||||
|
||||
if (!overview || !history || !overviewButton || !historyButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
const showingHistory = tab === "history";
|
||||
overview.style.display = showingHistory ? "none" : "block";
|
||||
history.style.display = showingHistory ? "block" : "none";
|
||||
overviewButton.style.background = showingHistory ? "#dcfce7" : "#15803d";
|
||||
overviewButton.style.color = showingHistory ? "#166534" : "#fff";
|
||||
historyButton.style.background = showingHistory ? "#15803d" : "#dcfce7";
|
||||
historyButton.style.color = showingHistory ? "#fff" : "#166534";
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开买单活动前台弹窗。
|
||||
*
|
||||
* @param {string} [tab]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function openBaccaratLossCoverModal(tab = "overview") {
|
||||
const modal = getLossCoverModal();
|
||||
if (!modal) {
|
||||
return;
|
||||
}
|
||||
|
||||
modal.style.display = "flex";
|
||||
|
||||
const modalGold = document.getElementById("blc-modal-jjb");
|
||||
if (modalGold) {
|
||||
modalGold.textContent = Number(window.chatContext?.userJjb || 0).toLocaleString();
|
||||
}
|
||||
|
||||
switchBaccaratLossCoverTab(tab);
|
||||
await Promise.all([loadSummary(), loadHistory()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭买单活动前台弹窗。
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function closeBaccaratLossCoverModal() {
|
||||
const modal = getLossCoverModal();
|
||||
if (modal) {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 领取买单活动补偿。
|
||||
*
|
||||
* @param {number|string} eventId
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function claimBaccaratLossCover(eventId) {
|
||||
const claimUrl = resolveClaimUrl(eventId);
|
||||
if (!claimUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(claimUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": csrf(),
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.ok) {
|
||||
syncUserGold(Number(data.amount || 0));
|
||||
await window.chatDialog?.alert?.(data.message || "补偿领取成功", "系统通知", "#16a34a");
|
||||
await Promise.all([loadSummary(), loadHistory()]);
|
||||
return;
|
||||
}
|
||||
|
||||
await window.chatDialog?.alert?.(data.message || "领取失败", "提示", "#f59e0b");
|
||||
} catch (error) {
|
||||
await window.chatDialog?.alert?.("领取失败,请稍后重试。", "提示", "#dc2626");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +369,12 @@ export function bindBaccaratLossCoverControls() {
|
||||
}
|
||||
|
||||
baccaratLossCoverEventsBound = true;
|
||||
|
||||
window.openBaccaratLossCoverModal = openBaccaratLossCoverModal;
|
||||
window.closeBaccaratLossCoverModal = closeBaccaratLossCoverModal;
|
||||
window.switchBaccaratLossCoverTab = switchBaccaratLossCoverTab;
|
||||
window.claimBaccaratLossCover = claimBaccaratLossCover;
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
if (!(event.target instanceof Element)) {
|
||||
return;
|
||||
@@ -34,22 +382,27 @@ export function bindBaccaratLossCoverControls() {
|
||||
|
||||
if (event.target.closest("[data-blc-close]")) {
|
||||
event.preventDefault();
|
||||
callLossCoverGlobal("closeBaccaratLossCoverModal");
|
||||
closeBaccaratLossCoverModal();
|
||||
return;
|
||||
}
|
||||
|
||||
const tabButton = event.target.closest("[data-blc-tab]");
|
||||
if (tabButton) {
|
||||
event.preventDefault();
|
||||
callLossCoverGlobal("switchBaccaratLossCoverTab", tabButton.getAttribute("data-blc-tab") || "overview");
|
||||
switchBaccaratLossCoverTab(tabButton.getAttribute("data-blc-tab") || "overview");
|
||||
return;
|
||||
}
|
||||
|
||||
const claimButton = event.target.closest("[data-blc-claim]");
|
||||
if (claimButton) {
|
||||
event.preventDefault();
|
||||
// 动态活动卡片只传活动 ID,领取流程继续复用旧全局函数。
|
||||
callLossCoverGlobal("claimBaccaratLossCover", claimButton.getAttribute("data-blc-claim") || "");
|
||||
void claimBaccaratLossCover(claimButton.getAttribute("data-blc-claim") || "");
|
||||
return;
|
||||
}
|
||||
|
||||
const modal = event.target.closest("#baccarat-loss-cover-modal");
|
||||
if (modal && event.target === modal) {
|
||||
closeBaccaratLossCoverModal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
--}}
|
||||
|
||||
<div id="baccarat-loss-cover-modal"
|
||||
data-blc-summary-url="{{ route('baccarat-loss-cover.summary') }}"
|
||||
data-blc-history-url="{{ route('baccarat-loss-cover.history') }}"
|
||||
data-blc-claim-url-template="{{ route('baccarat-loss-cover.claim', ['event' => '__EVENT__']) }}"
|
||||
style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:9997; justify-content:center; align-items:center;">
|
||||
<div
|
||||
style="width:720px; max-width:96vw; max-height:88vh; border-radius:8px; overflow:hidden; box-shadow:0 8px 32px rgba(0,0,0,.3); background:#fff; display:flex; flex-direction:column;">
|
||||
@@ -63,240 +66,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const SUMMARY_URL = '{{ route('baccarat-loss-cover.summary') }}';
|
||||
const HISTORY_URL = '{{ route('baccarat-loss-cover.history') }}';
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text ?? '';
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function formatTime(value) {
|
||||
if (!value) return '—';
|
||||
return new Date(value).toLocaleString('zh-CN', {
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
}
|
||||
|
||||
function syncUserGold(amount) {
|
||||
if (typeof amount !== 'number' || !window.chatContext) return;
|
||||
window.chatContext.userJjb = Number(window.chatContext.userJjb || 0) + amount;
|
||||
window.chatContext.myGold = Number(window.chatContext.myGold || 0) + amount;
|
||||
|
||||
const hallGold = document.getElementById('game-hall-jjb');
|
||||
if (hallGold) {
|
||||
hallGold.textContent = Number(window.chatContext.userJjb || 0).toLocaleString();
|
||||
}
|
||||
const modalGold = document.getElementById('blc-modal-jjb');
|
||||
if (modalGold) {
|
||||
modalGold.textContent = Number(window.chatContext.userJjb || 0).toLocaleString();
|
||||
}
|
||||
}
|
||||
|
||||
function renderCurrentEvent(event) {
|
||||
const container = document.getElementById('blc-current-event');
|
||||
if (!event) {
|
||||
container.innerHTML = `
|
||||
<div style="font-size:30px; margin-bottom:10px;">📭</div>
|
||||
<div style="font-size:16px; font-weight:bold; color:#166534;">当前暂无进行中的买单活动</div>
|
||||
<div style="font-size:12px; color:#4b5563; margin-top:8px;">可以在输入框上方的管理员按钮中创建新活动,也可以在这里查看历史记录。</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
const myRecord = event.my_record;
|
||||
const claimButton = event.status === 'claimable' && myRecord?.claim_status === 'pending'
|
||||
? `<button type="button" data-blc-claim="${Number(event.id)}" style="padding:8px 18px;border:none;border-radius:999px;background:#16a34a;color:#fff;font-size:12px;font-weight:bold;cursor:pointer;">领取补偿</button>`
|
||||
: '';
|
||||
|
||||
container.innerHTML = `
|
||||
<div style="display:flex; justify-content:space-between; align-items:flex-start; gap:12px; text-align:left;">
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:18px; font-weight:900; color:#166534;">${escapeHtml(event.title)}</div>
|
||||
<div style="font-size:12px; color:#4b5563; margin-top:6px; line-height:1.7;">${escapeHtml(event.description || '活动期间参与百家乐,输掉的金币可在活动结束后领取补偿。')}</div>
|
||||
</div>
|
||||
<span style="padding:4px 10px; border-radius:999px; background:#dcfce7; color:#166534; font-size:12px; font-weight:bold;">${escapeHtml(event.status_label)}</span>
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-top:16px; text-align:left;">
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">开启人</div>
|
||||
<div style="font-size:14px; font-weight:bold; color:#166534; margin-top:3px;">${escapeHtml(event.creator_username)}</div>
|
||||
</div>
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">活动时间</div>
|
||||
<div style="font-size:13px; font-weight:bold; color:#166534; margin-top:3px;">${formatTime(event.starts_at)} - ${formatTime(event.ends_at)}</div>
|
||||
</div>
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">最终已发补偿</div>
|
||||
<div style="font-size:14px; font-weight:bold; color:#166534; margin-top:3px;">${Number(event.total_claimed_amount || 0).toLocaleString()} 金币</div>
|
||||
</div>
|
||||
<div style="background:#f0fdf4; border-radius:8px; padding:12px;">
|
||||
<div style="font-size:11px; color:#6b7280;">我的状态</div>
|
||||
<div style="font-size:14px; font-weight:bold; color:#166534; margin-top:3px;">${escapeHtml(myRecord?.claim_status_label || '未参与')}</div>
|
||||
</div>
|
||||
</div>
|
||||
${myRecord ? `
|
||||
<div style="margin-top:16px; background:#fffbeb; border:1px solid #fde68a; border-radius:10px; padding:14px; text-align:left;">
|
||||
<div style="font-size:13px; font-weight:bold; color:#a16207; margin-bottom:8px;">我的活动记录</div>
|
||||
<div style="display:grid; grid-template-columns:repeat(2,1fr); gap:8px; font-size:12px; color:#4b5563;">
|
||||
<div>累计下注:<b style="color:#166534;">${Number(myRecord.total_bet_amount || 0).toLocaleString()}</b></div>
|
||||
<div>累计输掉:<b style="color:#b91c1c;">${Number(myRecord.total_loss_amount || 0).toLocaleString()}</b></div>
|
||||
<div>可领补偿:<b style="color:#166534;">${Number(myRecord.compensation_amount || 0).toLocaleString()}</b></div>
|
||||
<div>已领补偿:<b style="color:#166534;">${Number(myRecord.claimed_amount || 0).toLocaleString()}</b></div>
|
||||
</div>
|
||||
${claimButton ? `<div style="margin-top:12px;">${claimButton}</div>` : ''}
|
||||
</div>
|
||||
` : ''}
|
||||
`;
|
||||
}
|
||||
|
||||
function renderHistory(events) {
|
||||
const container = document.getElementById('blc-history-list');
|
||||
if (!events || events.length === 0) {
|
||||
container.innerHTML = '<div style="text-align:center;color:#6b7280;padding:24px 0;">暂无活动记录</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = events.map(event => {
|
||||
const myRecord = event.my_record;
|
||||
const claimButton = event.status === 'claimable' && myRecord?.claim_status === 'pending'
|
||||
? `<button type="button" data-blc-claim="${Number(event.id)}" style="padding:6px 14px;border:none;border-radius:999px;background:#16a34a;color:#fff;font-size:12px;font-weight:bold;cursor:pointer;">领取补偿</button>`
|
||||
: '';
|
||||
|
||||
return `
|
||||
<div style="background:#fff; border:1px solid #dcfce7; border-left:4px solid #16a34a; border-radius:8px; padding:14px;">
|
||||
<div style="display:flex; justify-content:space-between; gap:10px; align-items:flex-start;">
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:15px; font-weight:bold; color:#166534;">${escapeHtml(event.title)}</div>
|
||||
<div style="font-size:12px; color:#4b5563; margin-top:4px;">开启人:${escapeHtml(event.creator_username)} | ${formatTime(event.starts_at)} - ${formatTime(event.ends_at)}</div>
|
||||
</div>
|
||||
<span style="padding:4px 10px; border-radius:999px; background:#f0fdf4; color:#166534; font-size:12px; font-weight:bold;">${escapeHtml(event.status_label)}</span>
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns:repeat(2,1fr); gap:8px; margin-top:12px; font-size:12px; color:#4b5563;">
|
||||
<div>最终补偿发放:<b style="color:#166534;">${Number(event.total_claimed_amount || 0).toLocaleString()}</b></div>
|
||||
<div>本次总输金币:<b style="color:#b91c1c;">${Number(event.total_loss_amount || 0).toLocaleString()}</b></div>
|
||||
<div>我的状态:<b style="color:#166534;">${escapeHtml(myRecord?.claim_status_label || '未参与')}</b></div>
|
||||
<div>我的可领:<b style="color:#166534;">${Number(myRecord?.compensation_amount || 0).toLocaleString()}</b></div>
|
||||
</div>
|
||||
${myRecord ? `<div style="margin-top:8px; font-size:12px; color:#6b7280;">累计下注 ${Number(myRecord.total_bet_amount || 0).toLocaleString()} | 累计输掉 ${Number(myRecord.total_loss_amount || 0).toLocaleString()} | 已领 ${Number(myRecord.claimed_amount || 0).toLocaleString()}</div>` : ''}
|
||||
${claimButton ? `<div style="margin-top:10px;">${claimButton}</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
async function loadSummary() {
|
||||
const current = document.getElementById('blc-current-event');
|
||||
current.innerHTML = '加载中…';
|
||||
|
||||
try {
|
||||
const response = await fetch(`${SUMMARY_URL}?scene=overview`, {
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
renderCurrentEvent(data.event || null);
|
||||
} catch (error) {
|
||||
current.innerHTML = '<div style="color:#dc2626;">活动摘要加载失败,请稍后重试。</div>';
|
||||
}
|
||||
}
|
||||
|
||||
async function loadHistory() {
|
||||
const list = document.getElementById('blc-history-list');
|
||||
list.innerHTML = '加载中…';
|
||||
|
||||
try {
|
||||
const response = await fetch(HISTORY_URL, {
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
renderHistory(data.events || []);
|
||||
} catch (error) {
|
||||
list.innerHTML = '<div style="color:#dc2626;">活动历史加载失败,请稍后重试。</div>';
|
||||
}
|
||||
}
|
||||
|
||||
window.switchBaccaratLossCoverTab = function(tab) {
|
||||
const overview = document.getElementById('blc-overview-pane');
|
||||
const history = document.getElementById('blc-history-pane');
|
||||
const overviewBtn = document.getElementById('blc-tab-overview');
|
||||
const historyBtn = document.getElementById('blc-tab-history');
|
||||
|
||||
if (tab === 'history') {
|
||||
overview.style.display = 'none';
|
||||
history.style.display = 'block';
|
||||
overviewBtn.style.background = '#dcfce7';
|
||||
overviewBtn.style.color = '#166534';
|
||||
historyBtn.style.background = '#15803d';
|
||||
historyBtn.style.color = '#fff';
|
||||
return;
|
||||
}
|
||||
|
||||
overview.style.display = 'block';
|
||||
history.style.display = 'none';
|
||||
overviewBtn.style.background = '#15803d';
|
||||
overviewBtn.style.color = '#fff';
|
||||
historyBtn.style.background = '#dcfce7';
|
||||
historyBtn.style.color = '#166534';
|
||||
};
|
||||
|
||||
window.openBaccaratLossCoverModal = async function(tab = 'overview') {
|
||||
document.getElementById('baccarat-loss-cover-modal').style.display = 'flex';
|
||||
const modalGold = document.getElementById('blc-modal-jjb');
|
||||
if (modalGold) {
|
||||
modalGold.textContent = Number(window.chatContext?.userJjb || 0).toLocaleString();
|
||||
}
|
||||
window.switchBaccaratLossCoverTab(tab);
|
||||
await Promise.all([loadSummary(), loadHistory()]);
|
||||
};
|
||||
|
||||
window.closeBaccaratLossCoverModal = function() {
|
||||
document.getElementById('baccarat-loss-cover-modal').style.display = 'none';
|
||||
};
|
||||
|
||||
window.claimBaccaratLossCover = async function(eventId) {
|
||||
try {
|
||||
const response = await fetch(`/baccarat-loss-cover/${eventId}/claim`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || '',
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.ok) {
|
||||
syncUserGold(Number(data.amount || 0));
|
||||
if (window.chatDialog?.alert) {
|
||||
await window.chatDialog.alert(data.message || '补偿领取成功', '系统通知', '#16a34a');
|
||||
}
|
||||
await Promise.all([loadSummary(), loadHistory()]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.chatDialog?.alert) {
|
||||
await window.chatDialog.alert(data.message || '领取失败', '提示', '#f59e0b');
|
||||
}
|
||||
} catch (error) {
|
||||
if (window.chatDialog?.alert) {
|
||||
await window.chatDialog.alert('领取失败,请稍后重试。', '提示', '#dc2626');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById('baccarat-loss-cover-modal').addEventListener('click', function(event) {
|
||||
if (event.target === this) {
|
||||
closeBaccaratLossCoverModal();
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{{-- 前台买单活动脚本已迁移到 resources/js/chat-room/baccarat-loss-cover.js --}}
|
||||
|
||||
Reference in New Issue
Block a user