迁移婚礼弹窗组件脚本

This commit is contained in:
2026-04-25 19:22:13 +08:00
parent 2e8bfb61c2
commit 891e18e83f
3 changed files with 184 additions and 151 deletions
+176
View File
@@ -530,6 +530,180 @@ export function divorceRequestModal() {
};
}
/**
* 创建婚礼设置弹窗 Alpine 数据,负责选择婚礼档位并提交举办请求。
*
* @returns {Record<string, any>}
*/
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<string, any>}
*/
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();