优化 红包 页面
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:红包领取成功广播事件(广播至领取者私有频道)
|
||||
* 文件功能:红包领取成功广播事件(广播至房间与领取者私有频道)
|
||||
*
|
||||
* 触发时机:RedPacketController::claim() 成功后广播,
|
||||
* 前端收到后弹出 Toast 通知展示到账金额。
|
||||
* 房间内在线用户收到后实时刷新剩余份数,领取者本人可同步收到到账提示。
|
||||
*
|
||||
* @author ChatRoom Laravel
|
||||
*
|
||||
@@ -15,11 +15,18 @@ namespace App\Events;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* 类功能:广播礼包被领取后的实时状态
|
||||
*
|
||||
* 统一向房间频道推送剩余份数变化,同时向领取者私有频道推送到账结果,
|
||||
* 让红包弹窗与用户提示保持一致。
|
||||
*/
|
||||
class RedPacketClaimed implements ShouldBroadcastNow
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
@@ -28,32 +35,49 @@ class RedPacketClaimed implements ShouldBroadcastNow
|
||||
* @param User $claimer 领取用户
|
||||
* @param int $amount 领取金额
|
||||
* @param int $envelopeId 红包 ID
|
||||
* @param int $roomId 房间 ID
|
||||
* @param int $remainingCount 剩余份数
|
||||
* @param string $type 红包类型
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly User $claimer,
|
||||
public readonly int $amount,
|
||||
public readonly int $envelopeId,
|
||||
public readonly int $roomId,
|
||||
public readonly int $remainingCount,
|
||||
public readonly string $type = 'gold',
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 广播至领取者私有频道。
|
||||
* 广播至房间频道与领取者私有频道。
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [new PrivateChannel('user.'.$this->claimer->id)];
|
||||
return [
|
||||
new PresenceChannel('room.'.$this->roomId),
|
||||
new PrivateChannel('user.'.$this->claimer->id),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 广播领取结果与剩余份数。
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function broadcastWith(): array
|
||||
{
|
||||
$typeLabel = $this->type === 'exp' ? '经验' : '金币';
|
||||
|
||||
return [
|
||||
'envelope_id' => $this->envelopeId,
|
||||
'claimer_id' => $this->claimer->id,
|
||||
'claimer_username' => $this->claimer->username,
|
||||
'amount' => $this->amount,
|
||||
'message' => "🧧 成功抢到 {$this->amount} 金币礼包!",
|
||||
'remaining_count' => $this->remainingCount,
|
||||
'type' => $this->type,
|
||||
'message' => "🧧 成功抢到 {$this->amount} {$typeLabel}礼包!",
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* 类功能:处理聊天室礼包的发包、查状态与抢包流程
|
||||
*
|
||||
* 负责礼包主记录创建、Redis 拆包金额管理、领取入账以及实时广播。
|
||||
*/
|
||||
class RedPacketController extends Controller
|
||||
{
|
||||
/** 礼包固定总数量 */
|
||||
@@ -307,8 +312,19 @@ class RedPacketController extends Controller
|
||||
return response()->json(['status' => 'error', 'message' => '您已经领过这个礼包了'], 422);
|
||||
}
|
||||
|
||||
// 广播领取事件(给自己的私有频道,前端弹 Toast)
|
||||
broadcast(new RedPacketClaimed($user, $amount, $envelope->id));
|
||||
// 重新读取红包统计,确保广播与响应使用的是最新剩余份数。
|
||||
$envelope->refresh();
|
||||
$remainingCount = $envelope->remainingCount();
|
||||
|
||||
// 广播领取事件:房间内所有在线用户实时刷新剩余份数,领取者本人同步收到到账通知。
|
||||
broadcast(new RedPacketClaimed(
|
||||
claimer: $user,
|
||||
amount: $amount,
|
||||
envelopeId: $envelope->id,
|
||||
roomId: $envelope->room_id,
|
||||
remainingCount: $remainingCount,
|
||||
type: $envelopeType,
|
||||
));
|
||||
|
||||
// 在聊天室发送领取播报(所有人可见)
|
||||
$typeLabel = $envelopeType === 'exp' ? '经验' : '金币';
|
||||
@@ -335,6 +351,7 @@ class RedPacketController extends Controller
|
||||
'status' => 'success',
|
||||
'amount' => $amount,
|
||||
'type' => $envelopeType,
|
||||
'remaining_count' => $remainingCount,
|
||||
'message' => "🧧 恭喜!您抢到了 {$amount} {$typeLabel}!当前{$typeLabel}:{$balanceNow}。",
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user