优化 红包 页面

This commit is contained in:
2026-04-21 15:10:41 +08:00
parent 916f4c5aa6
commit 96a449d94b
4 changed files with 154 additions and 25 deletions
@@ -279,7 +279,7 @@
* 2. showRedPacketModal() 收到 RedPacketSent 事件后弹出红包卡片
* 3. claimRedPacket() 用户点击「立即抢红包」
* 4. closeRedPacketModal() 关闭红包弹窗
* 5. WebSocket 监听 监听 red-packet.sent 广播事件
* 5. WebSocket 监听 监听 red-packet.sent / red-packet.claimed 广播事件
*/
(function() {
'use strict';
@@ -616,6 +616,10 @@
btn.textContent = '🎉 已抢到!';
statusEl.style.color = '#16a34a';
statusEl.textContent = `恭喜!您抢到了 ${data.amount} ${typeLabel}`;
const remainingEl = document.getElementById('rp-remaining');
if (remainingEl && typeof data.remaining_count === 'number') {
remainingEl.textContent = data.remaining_count;
}
// 弹出全局 Toast
window.chatToast.show({
@@ -631,9 +635,17 @@
} else {
statusEl.style.color = '#dc2626';
statusEl.textContent = data.message || '抢包失败';
// 若已领过或已抢完则禁用按钮,否则解除禁用以重试
if (data.message && (data.message.includes('已经领过') || data.message.includes('已被抢完') ||
data.message.includes('已抢完'))) {
const message = data.message || '';
const shouldAutoClose = message.includes('已过期')
|| message.includes('已抢完')
|| message.includes('已抢完')
|| message.includes('红包已抢完或已过期');
// 若红包已经结束,则保持禁用并在 3 秒后自动关闭弹窗。
if (shouldAutoClose) {
btn.textContent = '礼包已结束';
setTimeout(() => closeRedPacketModal(), 3000);
} else if (message.includes('已经领过')) {
btn.textContent = '已参与';
} else {
btn.disabled = false;
@@ -652,11 +664,12 @@
/**
* 收到「系统传音」中的领取播报时,同步更新弹窗内的名单与剩余数。
*
* @param {string} username 领取者用户名
* @param {number} amount 领取金额
* @param {number} remaining 剩余份数
* @param {string} username 领取者用户名
* @param {number} amount 领取金额
* @param {number} remaining 剩余份数
* @param {'gold'|'exp'} [type] 红包类型
*/
window.updateRedPacketClaimsUI = function(username, amount, remaining) {
window.updateRedPacketClaimsUI = function(username, amount, remaining, type = _rpType) {
const remainingEl = document.getElementById('rp-remaining');
if (remainingEl) {
remainingEl.textContent = remaining;
@@ -669,9 +682,10 @@
}
listEl.style.display = 'block';
const typeLabel = type === 'exp' ? '经验' : '金币';
const item = document.createElement('div');
item.className = 'rp-claim-item';
item.innerHTML = `<span>${username}</span><span>+${amount} 金币</span>`;
item.innerHTML = `<span>${username}</span><span>+${amount} ${typeLabel}</span>`;
itemsEl.prepend(item);
// 若已全部领完,更新按钮状态
@@ -687,10 +701,10 @@
}
};
// ── WebSocket 监听 red-packet.sent ───────────────
// ── WebSocket 监听 red-packet.sent / red-packet.claimed ───────────────
/**
* 等待 Echo 就绪后注册 red-packet.sent 事件监听,
* 每次收到新红包时弹出红包卡片弹窗
* 等待 Echo 就绪后注册红包相关事件监听,
* 新红包弹窗展示,领取成功后实时刷新剩余份数
*/
function setupRedPacketListener() {
if (!window.Echo || !window.chatContext) {
@@ -708,6 +722,18 @@
e.expire_seconds,
e.type || 'gold',
);
})
.listen('.red-packet.claimed', (e) => {
if (Number(e.envelope_id) !== Number(_rpEnvelopeId)) {
return;
}
window.updateRedPacketClaimsUI(
e.claimer_username,
e.amount,
e.remaining_count,
e.type || _rpType,
);
});
console.log('RedPacketSent 监听器已注册');
}