迁移婚姻弹窗全局入口
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
* - lottery-panel.js:提供双色球彩票 lotteryPanel Alpine 组件和全局开关入口。
|
||||
* - mobile-drawer.js:处理移动端抽屉、房间列表和在线名单。
|
||||
* - marriage-status.js:处理婚姻状态弹窗、已婚列表、接受拒绝和离婚申请。
|
||||
* - marriage-modals.js:处理婚姻弹窗的系统消息、求婚和婚礼设置全局入口。
|
||||
* - toolbar.js:处理工具栏按钮和功能快捷入口。
|
||||
* - user-card.js:提供用户名片弹窗 Alpine 组件和管理/礼物操作。
|
||||
* - user-target-actions.js:处理点击用户名切换私聊目标和打开名片。
|
||||
@@ -93,6 +94,7 @@ export {
|
||||
switchMarriageTab,
|
||||
tryDivorce,
|
||||
} from "./chat-room/marriage-status.js";
|
||||
export { appendSystemMessage, bindMarriageModalControls, openProposeModal, openWeddingSetupModal } from "./chat-room/marriage-modals.js";
|
||||
export { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js";
|
||||
export { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
||||
export { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
||||
@@ -264,6 +266,7 @@ import {
|
||||
switchMarriageTab,
|
||||
tryDivorce,
|
||||
} from "./chat-room/marriage-status.js";
|
||||
import { appendSystemMessage, bindMarriageModalControls, openProposeModal, openWeddingSetupModal } from "./chat-room/marriage-modals.js";
|
||||
import { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js";
|
||||
import { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
||||
import { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
||||
@@ -526,11 +529,15 @@ if (typeof window !== "undefined") {
|
||||
showInlineMsg,
|
||||
unbindWechat,
|
||||
bindMarriageStatusControls,
|
||||
appendSystemMessage,
|
||||
bindMarriageModalControls,
|
||||
closeMarriageStatusModal,
|
||||
fetchMarriedList,
|
||||
fetchMyMarriageStatus,
|
||||
marriageAction,
|
||||
openMarriageStatusModal,
|
||||
openProposeModal,
|
||||
openWeddingSetupModal,
|
||||
renderMarriedList,
|
||||
renderMarriageStatus,
|
||||
switchMarriageTab,
|
||||
@@ -706,6 +713,9 @@ if (typeof window !== "undefined") {
|
||||
window.fetchMyMarriageStatus = fetchMyMarriageStatus;
|
||||
window.marriageAction = marriageAction;
|
||||
window.openMarriageStatusModal = openMarriageStatusModal;
|
||||
window.appendSystemMessage = appendSystemMessage;
|
||||
window.openProposeModal = openProposeModal;
|
||||
window.openWeddingSetupModal = openWeddingSetupModal;
|
||||
window.renderMarriedList = renderMarriedList;
|
||||
window.renderMarriageStatus = renderMarriageStatus;
|
||||
window.switchMarriageTab = switchMarriageTab;
|
||||
@@ -761,6 +771,7 @@ if (typeof window !== "undefined") {
|
||||
bindFishingControls();
|
||||
bindFortunePanelControls();
|
||||
bindMarriageStatusControls();
|
||||
bindMarriageModalControls();
|
||||
bindProfileControls();
|
||||
bindShopControls();
|
||||
bindCompactShopPanelControls();
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// 婚姻弹窗辅助入口,承接从 marriage-modals.blade.php 迁移出的全局函数。
|
||||
|
||||
/**
|
||||
* 向聊天主窗口追加一条婚姻系统公告,允许传入受控 HTML 按钮。
|
||||
*
|
||||
* @param {string} html 系统模板生成的 HTML 内容
|
||||
* @returns {void}
|
||||
*/
|
||||
export function appendSystemMessage(html) {
|
||||
const container = document.getElementById("chat-messages-container");
|
||||
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
const div = document.createElement("div");
|
||||
div.style.cssText = "background:linear-gradient(135deg,#fdf4ff,#fce7f3); border-left:3px solid #ec4899; border-radius:6px; padding:5px 12px; margin:3px 0; font-size:13px; line-height:1.6;";
|
||||
div.innerHTML = `<span style="color:#9d174d;">${html}</span>`;
|
||||
container.appendChild(div);
|
||||
container.scrollTop = container.scrollHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开求婚弹窗入口,从用户名片按钮触发。
|
||||
*
|
||||
* @param {string} username 求婚对象用户名
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function openProposeModal(username) {
|
||||
let rings = [];
|
||||
|
||||
try {
|
||||
const response = await fetch(window.chatContext.marriage.myRingsUrl, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === "success") {
|
||||
rings = data.rings || [];
|
||||
}
|
||||
} catch {
|
||||
// 网络异常时继续交给后端兜底,避免前端误拦截真实可用的求婚流程。
|
||||
}
|
||||
|
||||
if (rings.length === 0) {
|
||||
const goShop = await window.chatDialog?.confirm(
|
||||
"求婚需要一枚💍结婚戒指,你的背包里还没有。\n\n要前往商店购买吗?",
|
||||
"需要结婚戒指",
|
||||
);
|
||||
|
||||
if (goShop && typeof window.openShopModal === "function") {
|
||||
window.openShopModal();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const modal = document.getElementById("marriage-propose-modal");
|
||||
const alpine = window.Alpine;
|
||||
|
||||
if (modal && alpine) {
|
||||
alpine.$data(modal).openWithRings(username, rings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开婚礼设置弹窗,供新婚公告和名片入口复用。
|
||||
*
|
||||
* @param {number|string} marriageId 婚姻记录 ID
|
||||
* @returns {void}
|
||||
*/
|
||||
export function openWeddingSetupModal(marriageId) {
|
||||
const modal = document.getElementById("wedding-setup-modal");
|
||||
const alpine = window.Alpine;
|
||||
|
||||
if (modal && alpine) {
|
||||
alpine.$data(modal).open(marriageId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暴露婚姻弹窗存量入口,兼容 Blade 内 onclick、Alpine 方法和广播回调。
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function bindMarriageModalControls() {
|
||||
window.appendSystemMessage = appendSystemMessage;
|
||||
window.openProposeModal = openProposeModal;
|
||||
window.openWeddingSetupModal = openWeddingSetupModal;
|
||||
}
|
||||
@@ -683,21 +683,6 @@
|
||||
|
||||
{{-- ═══════════ Alpine.js 组件脚本 ═══════════ --}}
|
||||
<script>
|
||||
/**
|
||||
* 全局辅助:向聊天主窗口追加一条婚姻系统公告(支持 HTML 内容,如按钮)
|
||||
* 使用 innerHTML 而非 textContent,以支持内嵌的领取按钮等交互元素。
|
||||
*/
|
||||
window.appendSystemMessage = function(html) {
|
||||
const container = document.getElementById('chat-messages-container');
|
||||
if (!container) return;
|
||||
const div = document.createElement('div');
|
||||
div.style.cssText =
|
||||
'background:linear-gradient(135deg,#fdf4ff,#fce7f3); border-left:3px solid #ec4899; border-radius:6px; padding:5px 12px; margin:3px 0; font-size:13px; line-height:1.6;';
|
||||
div.innerHTML = `<span style="color:#9d174d;">${html}</span>`;
|
||||
container.appendChild(div);
|
||||
container.scrollTop = container.scrollHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
* 求婚弹窗组件
|
||||
*/
|
||||
@@ -917,7 +902,7 @@
|
||||
},
|
||||
|
||||
openWeddingSetup() {
|
||||
openWeddingSetupModal(this.marriageId);
|
||||
window.openWeddingSetupModal?.(this.marriageId);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1248,57 +1233,6 @@
|
||||
};
|
||||
}
|
||||
|
||||
// ───────── 全局入口函数 ─────────────────────────────────
|
||||
|
||||
/**
|
||||
* 打开求婚弹窗(从名片按钮调用)。
|
||||
* 先检查背包是否有戒指:
|
||||
* - 有 → 直接开弹窗(戒指列表已预加载,无需二次请求)
|
||||
* - 无 → 提示用户前往商店购买
|
||||
*/
|
||||
async function openProposeModal(username) {
|
||||
// 显示加载中(通过按钮禁用已阻止,这里只做静默检查)
|
||||
let rings = [];
|
||||
try {
|
||||
const res = await fetch(window.chatContext.marriage.myRingsUrl, {
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.status === 'success') {
|
||||
rings = data.rings || [];
|
||||
}
|
||||
} catch {
|
||||
/* 网络异常时继续走有戒指逻辑(后端再兜底) */
|
||||
}
|
||||
|
||||
if (rings.length === 0) {
|
||||
// 没有戒指:弹确认框引导购买
|
||||
const goShop = await window.chatDialog?.confirm(
|
||||
'求婚需要一枚💍结婚戒指,你的背包里还没有。\n\n要前往商店购买吗?',
|
||||
'需要结婚戒指'
|
||||
);
|
||||
if (goShop) {
|
||||
// 直接打开当前页面的商店浮窗(toolbar 中的 openShopModal)
|
||||
if (typeof window.openShopModal === 'function') {
|
||||
window.openShopModal();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 有戒指:打开弹窗,将已加载的列表传入(避免二次请求)
|
||||
const el = document.getElementById('marriage-propose-modal');
|
||||
if (el) Alpine.$data(el).openWithRings(username, rings);
|
||||
}
|
||||
|
||||
/** 打开婚礼设置弹窗 */
|
||||
function openWeddingSetupModal(marriageId) {
|
||||
const el = document.getElementById('wedding-setup-modal');
|
||||
if (el) Alpine.$data(el).open(marriageId);
|
||||
}
|
||||
|
||||
// ───────── WebSocket 事件处理 ───────────────────────────
|
||||
|
||||
/** 收到全局结婚公告:弹出全屏通知 + 追加公屏文字 */
|
||||
@@ -1307,8 +1241,8 @@
|
||||
const groomName = detail.user?.username ?? detail.groom_name ?? '??';
|
||||
const brideName = detail.partner?.username ?? detail.bride_name ?? '??';
|
||||
// 追加公屏消息
|
||||
if (typeof appendSystemMessage === 'function') {
|
||||
appendSystemMessage(`💑 ${groomName} 与 ${brideName} 喜结连理!`);
|
||||
if (typeof window.appendSystemMessage === 'function') {
|
||||
window.appendSystemMessage(`💑 ${groomName} 与 ${brideName} 喜结连理!`);
|
||||
}
|
||||
// 弹出全屏公告(fireworks 效果)
|
||||
const el = document.getElementById('marriage-accepted-modal');
|
||||
@@ -1338,14 +1272,14 @@
|
||||
window._weddingEnvelopes[ceremonyId] = detail;
|
||||
|
||||
// 公屏追加带按钮的系统消息(按钮通过 ceremonyId 引用全局 Map)
|
||||
if (typeof appendSystemMessage === 'function') {
|
||||
if (typeof window.appendSystemMessage === 'function') {
|
||||
const claimBtn = `<button data-wedding-envelope-claim="${Number(ceremonyId)}"
|
||||
style="display:inline-block; margin-left:10px; padding:4px 14px; border-radius:20px;
|
||||
background:#d97706; color:#fff;
|
||||
border:none; font-size:12px; font-weight:bold; cursor:pointer;
|
||||
vertical-align:middle; line-height:1.8; box-shadow:0 2px 8px rgba(0,0,0,.3);"
|
||||
title="点击领取婚礼红包">🧧 点击领取红包</button>`;
|
||||
appendSystemMessage(
|
||||
window.appendSystemMessage(
|
||||
`${tierIcon} ${groomName} 与 ${brideName} 举办了【${tierName}】!总金额 💰${amount} 金币,快来抢红包!${claimBtn}`
|
||||
);
|
||||
}
|
||||
@@ -1402,8 +1336,8 @@
|
||||
const userName = detail.user_username ?? detail.user?.username ?? '??';
|
||||
const partnerName = detail.partner_username ?? detail.partner?.username ?? '??';
|
||||
// 追加公屏文字
|
||||
if (typeof appendSystemMessage === 'function') {
|
||||
appendSystemMessage(`💔 ${userName} 与 ${partnerName} 解除了婚姻关系。`);
|
||||
if (typeof window.appendSystemMessage === 'function') {
|
||||
window.appendSystemMessage(`💔 ${userName} 与 ${partnerName} 解除了婚姻关系。`);
|
||||
}
|
||||
// 触发全屏离婚公告弹窗(暗色阴郁风格 + 雷雨特效)
|
||||
const modal = document.getElementById('marriage-divorced-modal')?._x_dataStack?.[0];
|
||||
@@ -1452,14 +1386,14 @@
|
||||
};
|
||||
|
||||
// 在包厢窗口追加提示 + 领取按钮
|
||||
if (typeof appendSystemMessage === 'function') {
|
||||
if (typeof window.appendSystemMessage === 'function') {
|
||||
const claimBtn = `<button data-wedding-envelope-claim="${Number(ceremonyId)}"
|
||||
style="display:inline-block; margin-left:10px; padding:4px 14px; border-radius:20px;
|
||||
background:#d97706; color:#fff;
|
||||
border:none; font-size:12px; font-weight:bold; cursor:pointer;
|
||||
vertical-align:middle; line-height:1.8; box-shadow:0 2px 8px rgba(0,0,0,.3);"
|
||||
title="点击领取婚礼红包">🧧 点击领取红包</button>`;
|
||||
appendSystemMessage(
|
||||
window.appendSystemMessage(
|
||||
`⚠️ 您有来自 ${env.tier_icon} ${env.groom} 与 ${env.bride}【${env.tier_name}】的婚礼红包未领取!${claimBtn}`
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user