diff --git a/resources/views/chat/partials/marriage-modals.blade.php b/resources/views/chat/partials/marriage-modals.blade.php index 46da528..31a5fdd 100644 --- a/resources/views/chat/partials/marriage-modals.blade.php +++ b/resources/views/chat/partials/marriage-modals.blade.php @@ -404,6 +404,20 @@ this.loading = false; }, + /** + * 由 openProposeModal() 传入已预加载的戒指列表,无需二次请求。 + * @param {string} username 求婚对象用户名 + * @param {Array} rings 已加载的戒指列表 + */ + 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; }, @@ -718,10 +732,44 @@ // ───────── 全局入口函数 ───────────────────────────────── - /** 打开求婚弹窗(从名片按钮调用) */ - function openProposeModal(username) { + /** + * 打开求婚弹窗(从名片按钮调用)。 + * 先检查背包是否有戒指: + * - 有 → 直接开弹窗(戒指列表已预加载,无需二次请求) + * - 无 → 提示用户前往商店购买 + */ + 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) { + window.open('/shop', '_blank'); + } + return; + } + + // 有戒指:打开弹窗,将已加载的列表传入(避免二次请求) const el = document.getElementById('marriage-propose-modal'); - if (el) Alpine.$data(el).open(username); + if (el) Alpine.$data(el).openWithRings(username, rings); } /** 打开婚礼设置弹窗 */