新增职务权限管理与聊天室管理权限控制

This commit is contained in:
2026-04-21 16:43:17 +08:00
parent cfdbf387af
commit 281315d1cf
19 changed files with 1243 additions and 87 deletions
+77 -12
View File
@@ -16,6 +16,7 @@
showForm: false,
editing: null,
selectedIds: [],
selectedPermissions: [],
form: {
department_id: '',
name: '',
@@ -32,12 +33,14 @@
openCreate() {
this.editing = null;
this.selectedIds = [];
this.selectedPermissions = [];
this.form = { department_id: '', name: '', icon: '🎖️', rank: 50, level: 60, max_persons: 1, max_reward: '', daily_reward_limit: '', recipient_daily_limit: '', sort_order: 0 };
this.showForm = true;
},
openEdit(pos, appointableIds) {
openEdit(pos, appointableIds, permissions) {
this.editing = pos;
this.selectedIds = appointableIds;
this.selectedPermissions = permissions;
this.form = {
department_id: pos.department_id,
name: pos.name,
@@ -61,6 +64,16 @@
},
isSelected(id) {
return this.selectedIds.includes(id);
},
togglePermission(code) {
if (this.selectedPermissions.includes(code)) {
this.selectedPermissions = this.selectedPermissions.filter(item => item !== code);
} else {
this.selectedPermissions.push(code);
}
},
isPermissionSelected(code) {
return this.selectedPermissions.includes(code);
}
}">
@@ -92,15 +105,6 @@
</div>
</div>
@if (session('success'))
<div class="mb-4 px-4 py-3 bg-green-50 border border-green-200 text-green-700 rounded-lg text-sm">
{{ session('success') }}</div>
@endif
@if (session('error'))
<div class="mb-4 px-4 py-3 bg-red-50 border border-red-200 text-red-700 rounded-lg text-sm">
{{ session('error') }}</div>
@endif
{{-- 全局奖励接收上限配置卡片(失焦/回车自动保存) --}}
<div class="mb-6 bg-amber-50 border border-amber-200 rounded-xl p-5" x-data="{
val: {{ $globalRecipientDailyMax }},
@@ -181,6 +185,7 @@
<th class="px-4 py-3 text-center">单次上限</th>
<th class="px-4 py-3 text-center">单日上限</th>
<th class="px-4 py-3 text-center">任命权</th>
<th class="px-4 py-3 text-center">聊天室权限</th>
@php $superLvl = (int) \App\Models\Sysparam::getValue('superlevel', '100'); @endphp
@if (Auth::user()->user_level >= $superLvl)
<th class="px-4 py-3 text-right">操作</th>
@@ -249,6 +254,34 @@
<span class="text-xs text-gray-400"></span>
@endif
</td>
<td class="px-4 py-3">
@if (! empty($pos->permissions))
@php
$permissionSummaryLabels = collect($pos->permissions)
->map(fn ($permissionCode) => $permissionLabels[$permissionCode] ?? $permissionCode)
->values();
$permissionPreview = $permissionSummaryLabels->take(2)->implode('、');
$permissionTitle = $permissionSummaryLabels->implode(' / ');
@endphp
<div class="mx-auto max-w-[220px] rounded-xl border border-amber-100 bg-gradient-to-br from-amber-50 via-white to-orange-50 px-3 py-2 shadow-sm"
title="{{ $permissionTitle }}">
<div class="flex items-center justify-between gap-3">
<span class="text-[11px] font-semibold tracking-[0.08em] text-amber-700">已开通</span>
<span class="rounded-full bg-amber-100 px-2 py-0.5 text-[11px] font-bold text-amber-700">
{{ $permissionSummaryLabels->count() }}
</span>
</div>
<div class="mt-1 text-xs leading-5 text-slate-600">
{{ $permissionPreview }}
@if ($permissionSummaryLabels->count() > 2)
<span class="text-amber-600"> {{ $permissionSummaryLabels->count() }} </span>
@endif
</div>
</div>
@else
<div class="text-center text-xs text-gray-400"></div>
@endif
</td>
<td class="px-4 py-3 text-right space-x-1">
@php $superLvl = (int) \App\Models\Sysparam::getValue('superlevel', '100'); @endphp
@if (Auth::user()->user_level >= $superLvl)
@@ -266,7 +299,7 @@
recipient_daily_limit: {{ $pos->recipient_daily_limit ?? 'null' }},
sort_order: {{ $pos->sort_order }},
requestUrl: '{{ route('admin.positions.update', $pos->id) }}'
}, {{ json_encode($appointableIds) }})"
}, {{ json_encode($appointableIds) }}, {{ json_encode($pos->permissions ?? []) }})"
class="text-xs bg-indigo-50 text-indigo-600 font-bold px-2 py-1 rounded hover:bg-indigo-600 hover:text-white transition">
编辑
</button>
@@ -286,7 +319,8 @@
</tr>
@empty
<tr>
<td colspan="9" class="px-4 py-6 text-center text-gray-400">该部门暂无职务</td>
<td colspan="{{ Auth::user()->user_level >= $superLvl ? 11 : 10 }}"
class="px-4 py-6 text-center text-gray-400">该部门暂无职务</td>
</tr>
@endforelse
</tbody>
@@ -391,6 +425,37 @@
</div>
</div>
{{-- 聊天室权限多选 --}}
<div class="border rounded-lg p-4 bg-amber-50 mt-4">
<h4 class="text-xs font-bold text-amber-800 mb-2">
权限管理
<span class="font-normal text-amber-700 ml-1">(控制聊天室输入框上方「管理」菜单中可见的功能按钮)</span>
</h4>
<div class="space-y-4">
@foreach ($positionPermissions as $groupName => $permissions)
<div>
<div class="text-xs font-bold text-amber-700 mb-2">{{ $groupName }}</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
@foreach ($permissions as $permissionCode => $permissionMeta)
<label
class="flex items-start gap-2 cursor-pointer rounded-lg border border-amber-200 bg-white px-3 py-2 text-sm"
:class="isPermissionSelected('{{ $permissionCode }}') ? 'ring-2 ring-amber-300 border-amber-300' : ''">
<input type="checkbox" name="permissions[]" value="{{ $permissionCode }}"
:checked="isPermissionSelected('{{ $permissionCode }}')"
@change="togglePermission('{{ $permissionCode }}')"
class="mt-0.5 rounded text-amber-600">
<span class="min-w-0">
<span class="block font-bold text-gray-700">{{ $permissionMeta['label'] }}</span>
<span class="block text-xs text-gray-500">{{ $permissionMeta['description'] }}</span>
</span>
</label>
@endforeach
</div>
</div>
@endforeach
</div>
</div>
<div class="flex justify-end space-x-3 pt-4 mt-4 border-t">
<button type="button" @click="showForm = false"
class="px-4 py-2 border rounded font-medium text-gray-600 hover:bg-gray-50">取消</button>
+4
View File
@@ -26,6 +26,7 @@
$levelFreeze = (int) \App\Models\Sysparam::getValue('level_freeze', '14');
$superLevel = (int) \App\Models\Sysparam::getValue('superlevel', '100');
$myLevel = Auth::user()->user_level;
$positionPermissions = array_keys(array_filter($roomPermissionMap ?? []));
@endphp
<script>
window.chatContext = {
@@ -73,6 +74,9 @@
chatBotEnabled: {{ $chatbotEnabledState ? 'true' : 'false' }},
botUser: @json($botUserData),
hasPosition: {{ Auth::user()->activePosition || Auth::user()->user_level >= $superLevel ? 'true' : 'false' }},
hasRoomManagementPermission: {{ ! empty($hasRoomManagementPermission) ? 'true' : 'false' }},
positionPermissions: @json($positionPermissions),
positionPermissionMap: @json($roomPermissionMap ?? []),
@php
$activePos = Auth::user()->activePosition;
$deptName = $activePos?->position?->department?->name ?? '';
@@ -4,9 +4,19 @@
第二行:输入框 + 发送按钮
frame.blade.php 拆分,便于独立维护
依赖变量:$user, $room, $levelKick, $levelMute, $levelBan, $levelBanip
依赖变量:$user, $room, $levelKick, $levelMute, $levelBan, $levelBanip,
$roomPermissionMap, $hasRoomManagementPermission
--}}
@php
$canSetAnnouncement = $roomPermissionMap[\App\Support\PositionPermissionRegistry::ROOM_ANNOUNCEMENT] ?? false;
$canPublicBroadcast = $roomPermissionMap[\App\Support\PositionPermissionRegistry::ROOM_PUBLIC_BROADCAST] ?? false;
$canClearScreen = $roomPermissionMap[\App\Support\PositionPermissionRegistry::ROOM_CLEAR_SCREEN] ?? false;
$canSendRedPacket = $roomPermissionMap[\App\Support\PositionPermissionRegistry::ROOM_RED_PACKET] ?? false;
$canManageLossCover = $roomPermissionMap[\App\Support\PositionPermissionRegistry::ROOM_BACCARAT_LOSS_COVER] ?? false;
$canTriggerFullscreenEffect = $roomPermissionMap[\App\Support\PositionPermissionRegistry::ROOM_FULLSCREEN_EFFECT] ?? false;
@endphp
<div class="input-bar">
<form id="chat-form" onsubmit="sendMessage(event)" enctype="multipart/form-data">
{{-- 第一行:工具选项 --}}
@@ -155,11 +165,7 @@ $welcomeMessages = [
</div>
</div>
@if (
$user->user_level >= (int) \App\Models\Sysparam::getValue('level_announcement', '10') ||
$room->master == $user->username ||
$user->user_level >= (int) \App\Models\Sysparam::getValue('superlevel', '100')
)
@if (! empty($hasRoomManagementPermission))
<div style="position:relative;display:inline-block;" id="admin-btn-wrap">
<button type="button" onclick="toggleAdminMenu(event)"
style="font-size:11px;padding:1px 6px;background:linear-gradient(135deg,#b45309,#d97706);color:#fff;border:none;border-radius:2px;cursor:pointer;font-weight:bold;">
@@ -167,10 +173,7 @@ $welcomeMessages = [
</button>
<div id="admin-menu"
style="display:none;position:absolute;bottom:calc(100% + 6px);left:0;z-index:10020;min-width:244px;max-width:min(80vw,288px);max-height:min(62vh,460px);overflow-y:auto;padding:10px;background:#fffaf0;border:1px solid #fdba74;border-radius:10px;box-shadow:0 10px 24px rgba(15,23,42,.18);">
@if (
$user->user_level >= (int) \App\Models\Sysparam::getValue('level_announcement', '10') ||
$room->master == $user->username
)
@if ($canSetAnnouncement)
<div style="font-size:10px;color:#9a3412;padding:0 2px 6px;">房间管理</div>
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
<button type="button" onclick="runAdminAction('announcement')"
@@ -178,19 +181,29 @@ $welcomeMessages = [
</div>
@endif
@if ($user->user_level >= (int) \App\Models\Sysparam::getValue('superlevel', '100'))
<div style="font-size:10px;color:#9a3412;padding:10px 2px 6px;">站长操作</div>
@if ($canPublicBroadcast || $canClearScreen || $canSendRedPacket || $canManageLossCover)
<div style="font-size:10px;color:#9a3412;padding:10px 2px 6px;">聊天室管理</div>
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
<button type="button" onclick="runAdminAction('announce-message')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #c4b5fd;border-radius:6px;cursor:pointer;">📢 公屏</button>
<button type="button" onclick="runAdminAction('admin-clear')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#dc2626;border:1px solid #fca5a5;border-radius:6px;cursor:pointer;">🧹 清屏</button>
<button type="button" onclick="runAdminAction('red-packet')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#b91c1c;border:1px solid #fdba74;border-radius:6px;cursor:pointer;">🧧 礼包</button>
<button type="button" onclick="runAdminAction('loss-cover')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#15803d;border:1px solid #86efac;border-radius:6px;cursor:pointer;">🎁 买单活动</button>
@if ($canPublicBroadcast)
<button type="button" onclick="runAdminAction('announce-message')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #c4b5fd;border-radius:6px;cursor:pointer;">📢 公屏</button>
@endif
@if ($canClearScreen)
<button type="button" onclick="runAdminAction('admin-clear')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#dc2626;border:1px solid #fca5a5;border-radius:6px;cursor:pointer;">🧹 清屏</button>
@endif
@if ($canSendRedPacket)
<button type="button" onclick="runAdminAction('red-packet')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#b91c1c;border:1px solid #fdba74;border-radius:6px;cursor:pointer;">🧧 礼包</button>
@endif
@if ($canManageLossCover)
<button type="button" onclick="runAdminAction('loss-cover')"
style="font-size:11px;padding:6px 8px;background:#fff;color:#15803d;border:1px solid #86efac;border-radius:6px;cursor:pointer;">🎁 买单活动</button>
@endif
</div>
@endif
@if ($canTriggerFullscreenEffect)
<div style="font-size:10px;color:#9a3412;padding:10px 2px 6px;">全屏特效</div>
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
<button type="button" onclick="selectEffect('fireworks')"
@@ -235,7 +248,7 @@ $welcomeMessages = [
</form>
</div>
@if ($user->user_level >= (int) \App\Models\Sysparam::getValue('superlevel', '100'))
@if ($canManageLossCover)
<div id="baccarat-loss-cover-admin-modal"
style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:10010; justify-content:center; align-items:center;">
<div