优化:管理操作按等级独立显示,查看私信仅站长可用

- 新增 level_warn(警告等级) 和 level_freeze(冻结等级) 系统参数
- AdminCommandController 各操作使用独立等级检查
- 弹窗各按钮按 sysparam 等级条件独立显示/隐藏
- 查看私信(🔍)仅 superlevel 站长可见
- 后台系统参数可配置各操作所需等级
This commit is contained in:
2026-02-26 22:38:33 +08:00
parent 5722d5be25
commit ba1c94e0f7
3 changed files with 100 additions and 35 deletions

View File

@@ -56,8 +56,8 @@ class AdminCommandController extends Controller
$roomId = $request->input('room_id');
$reason = $request->input('reason', '请注意言行');
// 权限检查
if (! $this->canManage($admin, $targetUsername)) {
// 权限检查(等级由 level_warn 配置)
if (! $this->canExecute($admin, $targetUsername, 'level_warn', '5')) {
return response()->json(['status' => 'error', 'message' => '权限不足'], 403);
}
@@ -101,7 +101,8 @@ class AdminCommandController extends Controller
$roomId = $request->input('room_id');
$reason = $request->input('reason', '违反聊天室规则');
if (! $this->canManage($admin, $targetUsername)) {
// 权限检查(等级由 level_kick 配置)
if (! $this->canExecute($admin, $targetUsername, 'level_kick', '10')) {
return response()->json(['status' => 'error', 'message' => '权限不足'], 403);
}
@@ -151,7 +152,8 @@ class AdminCommandController extends Controller
$roomId = $request->input('room_id');
$duration = $request->input('duration');
if (! $this->canManage($admin, $targetUsername)) {
// 权限检查(等级由 level_mute 配置)
if (! $this->canExecute($admin, $targetUsername, 'level_mute', '8')) {
return response()->json(['status' => 'error', 'message' => '权限不足'], 403);
}
@@ -202,7 +204,8 @@ class AdminCommandController extends Controller
$roomId = $request->input('room_id');
$reason = $request->input('reason', '违反聊天室规则');
if (! $this->canManage($admin, $targetUsername)) {
// 权限检查(等级由 level_freeze 配置)
if (! $this->canExecute($admin, $targetUsername, 'level_freeze', '14')) {
return response()->json(['status' => 'error', 'message' => '权限不足'], 403);
}
@@ -321,21 +324,21 @@ class AdminCommandController extends Controller
}
/**
* 权限检查:管理员是否可管理目标用户
* 权限检查:管理员是否可目标用户执行指定操作
*
* 管理员等级必须高于目标用户等级,且不能操作自己
* 根据 sysparam 中配置的等级门槛判断权限
*
* @param User $admin 管理员用户
* @param string $targetUsername 目标用户名
* @param string $levelKey sysparam 中的等级键名(如 level_kick、level_warn
* @param string $defaultLevel 默认等级值
* @return bool 是否有权限
*/
private function canManage(User $admin, string $targetUsername): bool
private function canExecute(User $admin, string $targetUsername, string $levelKey, string $defaultLevel = '5'): bool
{
$superLevel = (int) Sysparam::getValue('superlevel', '100');
// 必须是管理员(达到踢人等级)
$kickLevel = (int) Sysparam::getValue('level_kick', '5');
if ($admin->user_level < $kickLevel) {
// 必须达到该操作所需的最低等级
$requiredLevel = (int) Sysparam::getValue($levelKey, $defaultLevel);
if ($admin->user_level < $requiredLevel) {
return false;
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* 文件功能:补充警告(level_warn)和冻结(level_freeze)所需等级的系统参数
*
* 使管理员各操作均有独立的等级门槛配置。
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* 插入警告和冻结等级参数
*/
public function up(): void
{
$now = now();
DB::table('sysparam')->insertOrIgnore([
[
'alias' => 'level_warn',
'body' => '5',
'guidetxt' => '警告所需等级(管理员可在聊天室警告用户的最低等级)',
'created_at' => $now,
'updated_at' => $now,
],
[
'alias' => 'level_freeze',
'body' => '14',
'guidetxt' => '冻结账号所需等级(管理员可冻结用户账号的最低等级)',
'created_at' => $now,
'updated_at' => $now,
],
]);
}
/**
* 回滚:删除补充的参数记录
*/
public function down(): void
{
DB::table('sysparam')->whereIn('alias', [
'level_warn',
'level_freeze',
])->delete();
}
};

View File

@@ -17,11 +17,14 @@
<meta name="csrf-token" content="{{ csrf_token() }}">
@php
// 从 sysparam 读取权限等级配置
$levelKick = (int) \App\Models\Sysparam::getValue('level_kick', '60');
$levelMute = (int) \App\Models\Sysparam::getValue('level_mute', '50');
$levelBan = (int) \App\Models\Sysparam::getValue('level_ban', '80');
$levelBanip = (int) \App\Models\Sysparam::getValue('level_banip', '90');
$levelWarn = (int) \App\Models\Sysparam::getValue('level_warn', '5');
$levelKick = (int) \App\Models\Sysparam::getValue('level_kick', '10');
$levelMute = (int) \App\Models\Sysparam::getValue('level_mute', '8');
$levelBan = (int) \App\Models\Sysparam::getValue('level_ban', '12');
$levelBanip = (int) \App\Models\Sysparam::getValue('level_banip', '14');
$levelFreeze = (int) \App\Models\Sysparam::getValue('level_freeze', '14');
$superLevel = (int) \App\Models\Sysparam::getValue('superlevel', '100');
$myLevel = Auth::user()->user_level;
@endphp
<script>
window.chatContext = {
@@ -298,27 +301,37 @@
</a>
</div>
{{-- 特权操作(管理员/房主 --}}
@if (Auth::user()->user_level >= $levelKick || $room->master == Auth::user()->username)
{{-- 特权操作(各按钮按等级独立显示 --}}
@if ($myLevel >= $levelWarn || $room->master == Auth::user()->username)
<div style="padding: 0 16px 12px;"
x-show="userInfo.username !== window.chatContext.username && userInfo.user_level < {{ Auth::user()->user_level }}">
x-show="userInfo.username !== window.chatContext.username && userInfo.user_level < {{ $myLevel }}">
<div style="font-size: 11px; color: #c00; margin-bottom: 6px; font-weight: bold;">管理操作</div>
<div style="display: flex; gap: 6px; flex-wrap: wrap;">
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fef3c7; border: 1px solid #f59e0b; cursor: pointer;"
x-on:click="warnUser()">⚠️ 警告</button>
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fee2e2; border: 1px solid #ef4444; cursor: pointer;"
x-on:click="kickUser()">🚫 踢出</button>
<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">🔇 禁言</button>
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #dbeafe; border: 1px solid #3b82f6; cursor: pointer;"
x-on:click="freezeUser()">🧊 冻结</button>
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #f3e8ff; border: 1px solid #a855f7; cursor: pointer;"
x-on:click="loadWhispers()">🔍 私信</button>
@if ($myLevel >= $levelWarn)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fef3c7; border: 1px solid #f59e0b; cursor: pointer;"
x-on:click="warnUser()">⚠️ 警告</button>
@endif
@if ($myLevel >= $levelKick)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #fee2e2; border: 1px solid #ef4444; cursor: pointer;"
x-on:click="kickUser()">🚫 踢出</button>
@endif
@if ($myLevel >= $levelMute)
<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">🔇 禁言</button>
@endif
@if ($myLevel >= $levelFreeze)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #dbeafe; border: 1px solid #3b82f6; cursor: pointer;"
x-on:click="freezeUser()">🧊 冻结</button>
@endif
@if ($myLevel >= $superLevel)
<button
style="flex:1; padding: 5px; border-radius: 4px; font-size: 11px; background: #f3e8ff; border: 1px solid #a855f7; cursor: pointer;"
x-on:click="loadWhispers()">🔍 私信</button>
@endif
</div>
</div>
{{-- 禁言表单 --}}