恢复用户卡片私信查看

This commit is contained in:
pllx
2026-05-09 11:25:28 +08:00
parent 8c1b0b0840
commit da0846c7ab
3 changed files with 73 additions and 15 deletions
@@ -457,8 +457,9 @@ class AdminCommandController extends Controller
abort(403, '仅站长可查看私信');
}
// 查询最近 50 条悄悄话(发送或接收)
// 查询最近 50 条用户之间的悄悄话,系统发给用户的私信通知不展示到管理查看里。
$messages = Message::where('is_secret', true)
->where('from_user', 'not like', '系统%')
->where(function ($q) use ($username) {
$q->where('from_user', $username)
->orWhere('to_user', $username);
@@ -421,7 +421,8 @@
$canBanUser = Auth::id() === 1 || (($roomPermissionMap[\App\Support\PositionPermissionRegistry::USER_BAN] ?? false) === true);
$canBanIpUser = Auth::id() === 1 || (($roomPermissionMap[\App\Support\PositionPermissionRegistry::USER_BANIP] ?? false) === true);
$canRewardUser = Auth::id() === 1 || (($roomPermissionMap[\App\Support\PositionPermissionRegistry::ROOM_REWARD] ?? false) === true);
$hasUserModerationPermission = $canWarnUser || $canKickUser || $canMuteUser || $canBanUser || $canBanIpUser;
$canViewWhispers = $myLevel >= $superLevel;
$hasUserModerationPermission = $canWarnUser || $canKickUser || $canMuteUser || $canBanUser || $canBanIpUser || $canViewWhispers;
$hasPositionActions = Auth::user()->activePosition || $myLevel >= $superLevel;
@endphp
@if ($hasUserModerationPermission || $hasPositionActions)
@@ -445,43 +446,49 @@
<div style="font-size: 10px; color: #9ca3af; margin-bottom: 4px; padding-left: 2px;">
管理员操作
</div>
<div style="display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px;">
<div style="display: flex; gap: 4px; flex-wrap: nowrap; margin-bottom: 8px;">
@if ($canWarnUser)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fef3c7; border: 1px solid #f59e0b; cursor: pointer;"
x-on:click="warnUser()">⚠️ 警告
style="flex: 1 1 0; min-width: 0; padding: 5px 3px; border-radius: 4px; font-size: 11px; white-space: nowrap; background: #fef3c7; border: 1px solid #f59e0b; cursor: pointer;"
x-on:click="warnUser()">警告
</button>
@endif
@if ($canKickUser)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fee2e2; border: 1px solid #ef4444; cursor: pointer;"
x-on:click="kickUser()">🚫 踢出
style="flex: 1 1 0; min-width: 0; padding: 5px 3px; border-radius: 4px; font-size: 11px; white-space: nowrap; background: #fee2e2; border: 1px solid #ef4444; cursor: pointer;"
x-on:click="kickUser()">踢出
</button>
@endif
@if ($canMuteUser)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #e0e7ff; border: 1px solid #6366f1; cursor: pointer;"
x-on:click="isMuting = !isMuting">🔇 禁言
style="flex: 1 1 0; min-width: 0; padding: 5px 3px; border-radius: 4px; font-size: 11px; white-space: nowrap; background: #e0e7ff; border: 1px solid #6366f1; cursor: pointer;"
x-on:click="isMuting = !isMuting">禁言
</button>
@endif
@if ($canBanUser)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fee2e2; border: 1px solid #b91c1c; cursor: pointer;"
x-on:click="banUser()"> 封号
style="flex: 1 1 0; min-width: 0; padding: 5px 3px; border-radius: 4px; font-size: 11px; white-space: nowrap; background: #fee2e2; border: 1px solid #b91c1c; cursor: pointer;"
x-on:click="banUser()">封号
</button>
@endif
@if ($canBanIpUser)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #ffedd5; border: 1px solid #c2410c; cursor: pointer;"
x-on:click="banIpUser()">🌐 封IP
style="flex: 1 1 0; min-width: 0; padding: 5px 3px; border-radius: 4px; font-size: 11px; white-space: nowrap; background: #ffedd5; border: 1px solid #c2410c; cursor: pointer;"
x-on:click="banIpUser()">封IP
</button>
@endif
@if ($canViewWhispers)
<button
style="flex: 1 1 0; min-width: 0; padding: 5px 3px; border-radius: 4px; font-size: 11px; white-space: nowrap; background: #ecfeff; border: 1px solid #0891b2; cursor: pointer;"
x-on:click="loadWhispers()">私信
</button>
@endif
{{-- 职务奖励金币(凭空产生),仅有明确奖励权限且 max_reward != 0 的人可见 --}}
@if ($canRewardUser)
<button x-show="window.chatContext?.myMaxReward !== 0"
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fef3c7; border: 1px solid #f59e0b; cursor: pointer;"
x-on:click="openRewardModal(userInfo.username)">💰 奖励金币
style="flex: 1 1 0; min-width: 0; padding: 5px 3px; border-radius: 4px; font-size: 11px; white-space: nowrap; background: #fef3c7; border: 1px solid #f59e0b; cursor: pointer;"
x-on:click="openRewardModal(userInfo.username)">奖励
</button>
@endif
</div>
@@ -10,6 +10,7 @@ namespace Tests\Feature\Feature;
use App\Events\BrowserRefreshRequested;
use App\Jobs\SaveMessageJob;
use App\Models\Department;
use App\Models\Message;
use App\Models\Position;
use App\Models\Room;
use App\Models\User;
@@ -232,6 +233,55 @@ class AdminCommandControllerTest extends TestCase
Event::assertNotDispatched(BrowserRefreshRequested::class);
}
/**
* 测试站长查看用户私信时不会混入系统发给用户的私信通知。
*/
public function test_view_whispers_excludes_system_private_messages(): void
{
$admin = User::factory()->create([
'id' => 1,
'user_level' => 100,
]);
$target = User::factory()->create([
'username' => '目标用户',
]);
$friend = User::factory()->create([
'username' => '好友用户',
]);
Message::create([
'room_id' => 1,
'from_user' => $target->username,
'to_user' => $friend->username,
'content' => '这条用户私聊需要显示',
'is_secret' => true,
'sent_at' => now(),
]);
Message::create([
'room_id' => 1,
'from_user' => '系统',
'to_user' => $target->username,
'content' => '这条系统私信不应显示',
'is_secret' => true,
'sent_at' => now(),
]);
Message::create([
'room_id' => 1,
'from_user' => '系统传音',
'to_user' => $target->username,
'content' => '这条系统传音私信也不应显示',
'is_secret' => true,
'sent_at' => now(),
]);
$response = $this->actingAs($admin)->getJson(route('command.whispers', $target->username));
$response->assertOk()
->assertJsonPath('status', 'success')
->assertJsonCount(1, 'messages')
->assertJsonPath('messages.0.content', '这条用户私聊需要显示');
}
/**
* 测试管理操作中的奖励金币会给接收方写入带右下角提示的私聊消息。
*/