赠送金币改为私聊通知
This commit is contained in:
@@ -1244,7 +1244,7 @@ class ChatController extends Controller
|
|||||||
* 用户间赠送金币(任何登录用户均可调用)
|
* 用户间赠送金币(任何登录用户均可调用)
|
||||||
*
|
*
|
||||||
* 从自己的余额中扣除指定金额,转入对方账户,
|
* 从自己的余额中扣除指定金额,转入对方账户,
|
||||||
* 并在房间内通过「系统传音」广播一条赠送提示。
|
* 并以私聊消息的方式仅通知赠送双方。
|
||||||
*/
|
*/
|
||||||
public function giftGold(Request $request): JsonResponse
|
public function giftGold(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -1287,20 +1287,20 @@ class ChatController extends Controller
|
|||||||
$sender->decrement('jjb', $amount);
|
$sender->decrement('jjb', $amount);
|
||||||
$receiver->increment('jjb', $amount);
|
$receiver->increment('jjb', $amount);
|
||||||
|
|
||||||
// 广播一条消息:发送者/接收者路由到 say2(下方包厢),其他人路由到 say1(公屏)
|
// 写入真正的私聊消息,避免其他旁观用户在公屏看到赠金币通知。
|
||||||
// 原理:前端 isRelatedToMe = isMe || to_user===me → say2;否则 → say1
|
|
||||||
$giftMsg = [
|
$giftMsg = [
|
||||||
'id' => $this->chatState->nextMessageId($roomId),
|
'id' => $this->chatState->nextMessageId($roomId),
|
||||||
'room_id' => $roomId,
|
'room_id' => $roomId,
|
||||||
'from_user' => $sender->username,
|
'from_user' => $sender->username,
|
||||||
'to_user' => $toName,
|
'to_user' => $toName,
|
||||||
'content' => "悄悄赠送给你 {$amount} 金币!💝",
|
'content' => "赠送了你 {$amount} 金币!💝",
|
||||||
'is_secret' => false,
|
'is_secret' => true,
|
||||||
'font_color' => '#b45309',
|
'font_color' => '#b45309',
|
||||||
'action' => '',
|
'action' => '',
|
||||||
'sent_at' => now()->toDateTimeString(),
|
'sent_at' => now()->toDateTimeString(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 推入 Redis + WebSocket + 异步落库,保持与普通私聊一致的展示与历史记录行为。
|
||||||
$this->chatState->pushMessage($roomId, $giftMsg);
|
$this->chatState->pushMessage($roomId, $giftMsg);
|
||||||
broadcast(new MessageSent($roomId, $giftMsg));
|
broadcast(new MessageSent($roomId, $giftMsg));
|
||||||
SaveMessageJob::dispatch($giftMsg);
|
SaveMessageJob::dispatch($giftMsg);
|
||||||
|
|||||||
@@ -274,6 +274,73 @@ class ChatControllerTest extends TestCase
|
|||||||
$this->assertEquals(0, Redis::hexists("room:{$room->id}:users", $user->username));
|
$this->assertEquals(0, Redis::hexists("room:{$room->id}:users", $user->username));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试双击名片赠金币会写入私聊消息,且只有赠送双方能看到历史记录。
|
||||||
|
*/
|
||||||
|
public function test_gift_gold_creates_secret_message_visible_only_to_participants(): void
|
||||||
|
{
|
||||||
|
$room = Room::create(['room_name' => 'gift-gold']);
|
||||||
|
$sender = User::factory()->create(['jjb' => 500]);
|
||||||
|
$receiver = User::factory()->create(['jjb' => 100]);
|
||||||
|
$outsider = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($sender)->postJson(route('gift.gold'), [
|
||||||
|
'to_user' => $receiver->username,
|
||||||
|
'room_id' => $room->id,
|
||||||
|
'amount' => 88,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
$response->assertJsonFragment([
|
||||||
|
'status' => 'success',
|
||||||
|
'message' => "赠送成功!已向 {$receiver->username} 赠送 88 金币。",
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 余额应同步完成转移,确保消息不是“通知成功但金额未变”。
|
||||||
|
$this->assertSame(412, $sender->fresh()->jjb);
|
||||||
|
$this->assertSame(188, $receiver->fresh()->jjb);
|
||||||
|
|
||||||
|
$messages = Redis::lrange("room:{$room->id}:messages", 0, -1);
|
||||||
|
$giftMessage = collect($messages)
|
||||||
|
->map(fn (string $item) => json_decode($item, true))
|
||||||
|
->first(fn (array $item) => ($item['from_user'] ?? null) === $sender->username
|
||||||
|
&& ($item['to_user'] ?? null) === $receiver->username
|
||||||
|
&& ($item['content'] ?? null) === '赠送了你 88 金币!💝');
|
||||||
|
|
||||||
|
$this->assertNotNull($giftMessage);
|
||||||
|
$this->assertTrue((bool) ($giftMessage['is_secret'] ?? false));
|
||||||
|
|
||||||
|
// 赠送方查看房间历史时,应保留这条私聊通知。
|
||||||
|
$senderHistory = $this->actingAs($sender)
|
||||||
|
->get(route('chat.room', $room->id))
|
||||||
|
->viewData('historyMessages');
|
||||||
|
$this->assertTrue(collect($senderHistory)->contains(
|
||||||
|
fn (array $item) => ($item['from_user'] ?? null) === $sender->username
|
||||||
|
&& ($item['to_user'] ?? null) === $receiver->username
|
||||||
|
&& ($item['content'] ?? null) === '赠送了你 88 金币!💝'
|
||||||
|
));
|
||||||
|
|
||||||
|
// 接收方查看房间历史时,也应看到这条私聊通知。
|
||||||
|
$receiverHistory = $this->actingAs($receiver)
|
||||||
|
->get(route('chat.room', $room->id))
|
||||||
|
->viewData('historyMessages');
|
||||||
|
$this->assertTrue(collect($receiverHistory)->contains(
|
||||||
|
fn (array $item) => ($item['from_user'] ?? null) === $sender->username
|
||||||
|
&& ($item['to_user'] ?? null) === $receiver->username
|
||||||
|
&& ($item['content'] ?? null) === '赠送了你 88 金币!💝'
|
||||||
|
));
|
||||||
|
|
||||||
|
// 旁观者不应在历史消息里看到别人的赠金币私聊。
|
||||||
|
$outsiderHistory = $this->actingAs($outsider)
|
||||||
|
->get(route('chat.room', $room->id))
|
||||||
|
->viewData('historyMessages');
|
||||||
|
$this->assertFalse(collect($outsiderHistory)->contains(
|
||||||
|
fn (array $item) => ($item['from_user'] ?? null) === $sender->username
|
||||||
|
&& ($item['to_user'] ?? null) === $receiver->username
|
||||||
|
&& ($item['content'] ?? null) === '赠送了你 88 金币!💝'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试会员用户首次进房时会把专属欢迎主题写入历史消息。
|
* 测试会员用户首次进房时会把专属欢迎主题写入历史消息。
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user