From 5b6f687db6305dd71a41a7cdda3741fd0da10a37 Mon Sep 17 00:00:00 2001 From: lkddi Date: Sat, 25 Apr 2026 19:15:52 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E6=B1=82=E5=A9=9A=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E7=BB=84=E4=BB=B6=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/js/chat-room.js | 6 +- resources/js/chat-room/marriage-modals.js | 122 ++++++++++++++++++ resources/views/chat/frame.blade.php | 2 + .../chat/partials/marriage-modals.blade.php | 104 --------------- 4 files changed, 128 insertions(+), 106 deletions(-) diff --git a/resources/js/chat-room.js b/resources/js/chat-room.js index b85f5b5..ab1eec0 100644 --- a/resources/js/chat-room.js +++ b/resources/js/chat-room.js @@ -94,7 +94,7 @@ export { switchMarriageTab, tryDivorce, } from "./chat-room/marriage-status.js"; -export { appendSystemMessage, bindMarriageModalControls, openProposeModal, openWeddingSetupModal } from "./chat-room/marriage-modals.js"; +export { appendSystemMessage, bindMarriageModalControls, marriageProposeModal, 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"; @@ -266,7 +266,7 @@ import { switchMarriageTab, tryDivorce, } from "./chat-room/marriage-status.js"; -import { appendSystemMessage, bindMarriageModalControls, openProposeModal, openWeddingSetupModal } from "./chat-room/marriage-modals.js"; +import { appendSystemMessage, bindMarriageModalControls, marriageProposeModal, 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"; @@ -531,6 +531,7 @@ if (typeof window !== "undefined") { bindMarriageStatusControls, appendSystemMessage, bindMarriageModalControls, + marriageProposeModal, closeMarriageStatusModal, fetchMarriedList, fetchMyMarriageStatus, @@ -714,6 +715,7 @@ if (typeof window !== "undefined") { window.marriageAction = marriageAction; window.openMarriageStatusModal = openMarriageStatusModal; window.appendSystemMessage = appendSystemMessage; + window.marriageProposeModal = marriageProposeModal; window.openProposeModal = openProposeModal; window.openWeddingSetupModal = openWeddingSetupModal; window.renderMarriedList = renderMarriedList; diff --git a/resources/js/chat-room/marriage-modals.js b/resources/js/chat-room/marriage-modals.js index 7660cbc..c3d48f5 100644 --- a/resources/js/chat-room/marriage-modals.js +++ b/resources/js/chat-room/marriage-modals.js @@ -80,6 +80,127 @@ export function openWeddingSetupModal(marriageId) { } } +/** + * 创建求婚弹窗 Alpine 数据,负责戒指选择、婚礼档位和求婚提交。 + * + * @returns {Record} + */ +export function marriageProposeModal() { + return { + show: false, + targetUsername: "", + marriageId: null, + rings: [], + selectedRing: null, + tiers: window.chatContext?.marriage?.weddingTiers || [], + selectedTierId: window.chatContext?.marriage?.defaultWeddingTierId || "", + loading: false, + sending: false, + error: "", + + get selectedTier() { + if (!this.selectedTierId) { + return null; + } + + return this.tiers.find((tier) => tier.id == this.selectedTierId); + }, + + get canAfford() { + const amount = this.selectedTier ? Number(this.selectedTier.amount) : 0; + + return window.chatContext.userJjb >= amount; + }, + + async open(username) { + this.targetUsername = username; + this.selectedRing = null; + this.error = ""; + this.loading = true; + this.show = true; + + try { + const response = await fetch(window.chatContext.marriage.myRingsUrl, { + headers: { + Accept: "application/json", + }, + }); + const data = await response.json(); + + if (data.status === "success") { + this.rings = data.rings; + + if (this.rings.length > 0) { + this.selectedRing = this.rings[0].purchase_id; + } + } + } catch { + this.rings = []; + } + + this.loading = false; + }, + + /** + * 使用预加载戒指列表打开弹窗,避免入口检查后重复请求背包。 + * + * @param {string} username 求婚对象用户名 + * @param {Array>} rings 已加载的戒指列表 + * @returns {void} + */ + openWithRings(username, rings) { + this.targetUsername = username; + this.error = ""; + this.loading = false; + this.rings = rings; + this.selectedRing = rings.length > 0 ? rings[0].purchase_id : null; + this.show = true; + }, + + close() { + this.show = false; + }, + + async doPropose() { + if (this.sending || !this.selectedRing) { + return; + } + + this.sending = true; + this.error = ""; + + try { + const response = await fetch(window.chatContext.marriage.proposeUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content, + }, + body: JSON.stringify({ + target_username: this.targetUsername, + ring_purchase_id: this.selectedRing, + wedding_tier_id: this.selectedTierId || null, + room_id: window.chatContext.roomId, + }), + }); + const data = await response.json(); + + if (data.status === "success") { + this.close(); + window.chatDialog?.alert("💍 求婚成功!等待对方回应(有效期 48 小时)", "已发出", "#f43f5e"); + } else { + this.error = data.message || "求婚失败"; + } + } catch { + this.error = "网络异常,请稍后重试"; + } + + this.sending = false; + }, + }; +} + /** * 读取 Alpine 组件数据,避免直接访问 Alpine 私有字段。 * @@ -280,6 +401,7 @@ function bindMarriageModalBootstrap() { */ export function bindMarriageModalControls() { window.appendSystemMessage = appendSystemMessage; + window.marriageProposeModal = marriageProposeModal; window.openProposeModal = openProposeModal; window.openWeddingSetupModal = openWeddingSetupModal; diff --git a/resources/views/chat/frame.blade.php b/resources/views/chat/frame.blade.php index 1007af6..ce7a874 100644 --- a/resources/views/chat/frame.blade.php +++ b/resources/views/chat/frame.blade.php @@ -114,6 +114,8 @@ 'statusUrl' => route('marriage.status'), 'targteStatusUrl' => '/marriage/target', 'myRingsUrl' => route('marriage.rings'), + 'weddingTiers' => \App\Models\WeddingTier::query()->where('is_active', true)->orderBy('amount')->get(), + 'defaultWeddingTierId' => \App\Models\WeddingTier::query()->where('is_active', true)->orderBy('amount')->value('id') ?? '', 'acceptUrlTemplate' => '/marriage/__ID__/accept', 'rejectUrlTemplate' => '/marriage/__ID__/reject', 'divorceUrlTemplate' => '/marriage/__ID__/divorce', diff --git a/resources/views/chat/partials/marriage-modals.blade.php b/resources/views/chat/partials/marriage-modals.blade.php index f2d7e54..1278058 100644 --- a/resources/views/chat/partials/marriage-modals.blade.php +++ b/resources/views/chat/partials/marriage-modals.blade.php @@ -683,110 +683,6 @@ {{-- ═══════════ Alpine.js 组件脚本 ═══════════ --}}