修复普通定向发言公屏可见
This commit is contained in:
@@ -26,9 +26,9 @@ class MessageSent implements ShouldBroadcastNow
|
|||||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event instance.
|
* 创建消息广播事件实例。
|
||||||
*
|
*
|
||||||
* @param int $roomId 房间ID
|
* @param int $roomId 房间 ID
|
||||||
* @param array $message 发送的消息数据
|
* @param array $message 发送的消息数据
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -39,8 +39,8 @@ class MessageSent implements ShouldBroadcastNow
|
|||||||
/**
|
/**
|
||||||
* 获取消息应广播到的频道。
|
* 获取消息应广播到的频道。
|
||||||
*
|
*
|
||||||
* 公共消息走房间 Presence 频道;
|
* 公共消息和普通定向发言走房间 Presence 频道;
|
||||||
* 定向消息 / 悄悄话只发给发送方与接收方的私有用户频道。
|
* 悄悄话只发给发送方与接收方的私有用户频道。
|
||||||
*
|
*
|
||||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||||
*/
|
*/
|
||||||
@@ -78,9 +78,7 @@ class MessageSent implements ShouldBroadcastNow
|
|||||||
*/
|
*/
|
||||||
private function shouldBroadcastPrivately(): bool
|
private function shouldBroadcastPrivately(): bool
|
||||||
{
|
{
|
||||||
$toUser = trim((string) ($this->message['to_user'] ?? ''));
|
return (bool) ($this->message['is_secret'] ?? false);
|
||||||
|
|
||||||
return $toUser !== '' && $toUser !== '大家';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -248,8 +248,8 @@ class ChatController extends Controller
|
|||||||
return $fromUser === $username || $toUser === $username;
|
return $fromUser === $username || $toUser === $username;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对特定人说话:只显示发给自己或自己发出的(含系统通知)
|
// 非悄悄话的定向发言仍属于公屏消息,历史回放也要让房间内其他人可见。
|
||||||
return $fromUser === $username || $toUser === $username;
|
return true;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 7. 如果用户有在职職务,开始记录这次入场的心跳登录 (仅初次)
|
// 7. 如果用户有在职職务,开始记录这次入场的心跳登录 (仅初次)
|
||||||
|
|||||||
@@ -568,9 +568,54 @@ class ChatControllerTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试定向消息仅广播到发送方与接收方私有频道。
|
* 测试历史消息会让旁观用户看到普通定向发言,但不会泄露悄悄话。
|
||||||
*/
|
*/
|
||||||
public function test_targeted_message_event_uses_private_user_channels(): void
|
public function test_room_history_keeps_non_secret_targeted_messages_visible_to_others(): void
|
||||||
|
{
|
||||||
|
$room = Room::create(['room_name' => 'histtg']);
|
||||||
|
$sender = User::factory()->create(['username' => 'history-sender']);
|
||||||
|
$receiver = User::factory()->create(['username' => 'history-receiver']);
|
||||||
|
$observer = User::factory()->create(['username' => 'history-observer']);
|
||||||
|
$chatState = app(\App\Services\ChatStateService::class);
|
||||||
|
|
||||||
|
$chatState->pushMessage($room->id, [
|
||||||
|
'id' => 1,
|
||||||
|
'room_id' => $room->id,
|
||||||
|
'from_user' => $sender->username,
|
||||||
|
'to_user' => $receiver->username,
|
||||||
|
'content' => '公开对你说',
|
||||||
|
'is_secret' => false,
|
||||||
|
'font_color' => '#000000',
|
||||||
|
'action' => '',
|
||||||
|
'sent_at' => now()->toDateTimeString(),
|
||||||
|
]);
|
||||||
|
$chatState->pushMessage($room->id, [
|
||||||
|
'id' => 2,
|
||||||
|
'room_id' => $room->id,
|
||||||
|
'from_user' => $sender->username,
|
||||||
|
'to_user' => $receiver->username,
|
||||||
|
'content' => '旁人不可见悄悄话',
|
||||||
|
'is_secret' => true,
|
||||||
|
'font_color' => '#000000',
|
||||||
|
'action' => '',
|
||||||
|
'sent_at' => now()->toDateTimeString(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->actingAs($observer)->get(route('chat.room', $room->id));
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
$response->assertViewHas('historyMessages', function (array $messages): bool {
|
||||||
|
$contents = collect($messages)->pluck('content');
|
||||||
|
|
||||||
|
return $contents->contains('公开对你说')
|
||||||
|
&& ! $contents->contains('旁人不可见悄悄话');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试悄悄话消息仅广播到发送方与接收方私有频道。
|
||||||
|
*/
|
||||||
|
public function test_secret_message_event_uses_private_user_channels(): void
|
||||||
{
|
{
|
||||||
$sender = User::factory()->create(['username' => 'sender-user']);
|
$sender = User::factory()->create(['username' => 'sender-user']);
|
||||||
$receiver = User::factory()->create(['username' => 'receiver-user']);
|
$receiver = User::factory()->create(['username' => 'receiver-user']);
|
||||||
@@ -597,7 +642,30 @@ class ChatControllerTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试公共消息仍广播到房间 Presence 频道。
|
* 测试普通定向消息仍广播到房间 Presence 频道。
|
||||||
|
*/
|
||||||
|
public function test_non_secret_targeted_message_event_uses_room_presence_channel(): void
|
||||||
|
{
|
||||||
|
$event = new MessageSent(3, [
|
||||||
|
'room_id' => 3,
|
||||||
|
'from_user' => 'tester',
|
||||||
|
'to_user' => 'receiver-user',
|
||||||
|
'content' => '公开对你说',
|
||||||
|
'is_secret' => false,
|
||||||
|
'font_color' => '#000000',
|
||||||
|
'action' => '',
|
||||||
|
'sent_at' => now()->toDateTimeString(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$channels = $event->broadcastOn();
|
||||||
|
|
||||||
|
$this->assertCount(1, $channels);
|
||||||
|
$this->assertInstanceOf(PresenceChannel::class, $channels[0]);
|
||||||
|
$this->assertSame('presence-room.3', $channels[0]->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试对大家消息仍广播到房间 Presence 频道。
|
||||||
*/
|
*/
|
||||||
public function test_public_message_event_still_uses_room_presence_channel(): void
|
public function test_public_message_event_still_uses_room_presence_channel(): void
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user