diff --git a/resources/js/chat-room.js b/resources/js/chat-room.js index a20a407..5766794 100644 --- a/resources/js/chat-room.js +++ b/resources/js/chat-room.js @@ -105,6 +105,8 @@ export { marriageProposeModal, openProposeModal, openWeddingSetupModal, + weddingEnvelopeModal, + weddingSetupModal, } from "./chat-room/marriage-modals.js"; export { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js"; export { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js"; @@ -288,6 +290,8 @@ import { marriageProposeModal, openProposeModal, openWeddingSetupModal, + weddingEnvelopeModal, + weddingSetupModal, } from "./chat-room/marriage-modals.js"; import { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js"; import { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js"; @@ -566,6 +570,8 @@ if (typeof window !== "undefined") { openMarriageStatusModal, openProposeModal, openWeddingSetupModal, + weddingEnvelopeModal, + weddingSetupModal, renderMarriedList, renderMarriageStatus, switchMarriageTab, @@ -750,6 +756,8 @@ if (typeof window !== "undefined") { window.marriageProposeModal = marriageProposeModal; window.openProposeModal = openProposeModal; window.openWeddingSetupModal = openWeddingSetupModal; + window.weddingEnvelopeModal = weddingEnvelopeModal; + window.weddingSetupModal = weddingSetupModal; window.renderMarriedList = renderMarriedList; window.renderMarriageStatus = renderMarriageStatus; window.switchMarriageTab = switchMarriageTab; diff --git a/resources/js/chat-room/marriage-modals.js b/resources/js/chat-room/marriage-modals.js index 6897e34..66bbe7e 100644 --- a/resources/js/chat-room/marriage-modals.js +++ b/resources/js/chat-room/marriage-modals.js @@ -530,6 +530,180 @@ export function divorceRequestModal() { }; } +/** + * 创建婚礼设置弹窗 Alpine 数据,负责选择婚礼档位并提交举办请求。 + * + * @returns {Record} + */ +export function weddingSetupModal() { + return { + show: false, + marriageId: null, + tiers: [], + selectedTier: null, + payBy: "groom", + loading: false, + sending: false, + error: "", + + get myCost() { + if (!this.selectedTier) { + return 0; + } + + return this.payBy === "split" ? Math.ceil(this.selectedTier.amount / 2) : this.selectedTier.amount; + }, + + async open(marriageId) { + this.marriageId = marriageId; + this.selectedTier = null; + this.payBy = "groom"; + this.error = ""; + this.loading = true; + this.show = true; + + try { + const response = await fetch(window.chatContext.marriage.weddingTiersUrl, { + headers: { + Accept: "application/json", + }, + }); + const data = await response.json(); + + if (data.status === "success") { + this.tiers = data.tiers; + + if (this.tiers.length > 0) { + this.selectedTier = this.tiers[0]; + } + } + } catch { + this.tiers = []; + } + + this.loading = false; + }, + + close() { + this.show = false; + }, + + async doSetup() { + if (this.sending || !this.selectedTier) { + return; + } + + this.error = ""; + this.sending = true; + + try { + // 当前产品只支持立即举办,前端固定 ceremony_type,避免保留无效时间选择状态。 + const body = { + tier_id: this.selectedTier.id, + payer_type: this.payBy, + ceremony_type: "immediate", + room_id: window.chatContext.roomId, + }; + const response = await fetch(window.chatContext.marriage.weddingSetupUrl(this.marriageId), { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content, + }, + body: JSON.stringify(body), + }); + const data = await response.json(); + + if (data.status === "success") { + this.close(); + window.chatDialog?.alert("🎊 婚礼已开始!红包正在分发给在线用户…", "设置成功", "#f59e0b"); + } else { + this.error = data.message || "设置失败"; + } + } catch { + this.error = "网络异常,请稍后重试"; + } + + this.sending = false; + }, + }; +} + +/** + * 创建婚礼红包弹窗 Alpine 数据,负责展示和领取婚礼红包。 + * + * @returns {Record} + */ +export function weddingEnvelopeModal() { + return { + show: false, + marriageId: null, + ceremonyId: null, + title: "", + subTitle: "", + claimed: false, + claiming: false, + claimedAmount: 0, + + open(detail) { + this.marriageId = detail.marriage_id; + this.ceremonyId = detail.ceremony_id; + const groomName = detail.groom_name ?? detail.user?.username ?? "??"; + const brideName = detail.bride_name ?? detail.partner?.username ?? "??"; + + this.title = `${groomName} × ${brideName} 婚礼红包`; + this.subTitle = detail.tier_name ? `【${detail.tier_name}】普天同庆` : "婚礼庆典红包"; + this.claimed = false; + this.claimedAmount = 0; + this.show = true; + }, + + close() { + this.show = false; + }, + + async doClaim() { + if (this.claiming || this.claimed) { + return; + } + + this.claiming = true; + + try { + const response = await fetch(`/wedding/ceremony/${this.ceremonyId}/claim`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content, + }, + body: JSON.stringify({ + ceremony_id: this.ceremonyId, + }), + }); + const data = await response.json(); + + if (data.ok) { + this.claimed = true; + this.claimedAmount = data.amount || 0; + } else { + window.chatDialog?.alert(data.message || "领取失败", "提示", "#f59e0b"); + + // 已领取或已过期时同步锁定按钮,避免用户重复提交同一个红包。 + if (data.message?.includes("已领取") || data.message?.includes("已过期")) { + this.claimed = true; + } + } + } catch { + window.chatDialog?.alert("网络异常", "错误", "#cc4444"); + } + + this.claiming = false; + }, + }; +} + /** * 读取 Alpine 组件数据,避免直接访问 Alpine 私有字段。 * @@ -738,6 +912,8 @@ export function bindMarriageModalControls() { window.marriageProposeModal = marriageProposeModal; window.openProposeModal = openProposeModal; window.openWeddingSetupModal = openWeddingSetupModal; + window.weddingEnvelopeModal = weddingEnvelopeModal; + window.weddingSetupModal = weddingSetupModal; bindMarriageModalEvents(); bindMarriageModalBootstrap(); diff --git a/resources/views/chat/partials/marriage-modals.blade.php b/resources/views/chat/partials/marriage-modals.blade.php index bf99c7c..258429c 100644 --- a/resources/views/chat/partials/marriage-modals.blade.php +++ b/resources/views/chat/partials/marriage-modals.blade.php @@ -680,154 +680,3 @@ } } - -{{-- ═══════════ Alpine.js 组件脚本 ═══════════ --}} -