- 任命/撤销事件增加 type 字段区分类型 - 任命:全屏礼花 + 紫色弹窗 + 紫色系统消息 - 撤销:灰色弹窗 + 灰色系统消息,无礼花 - 消息分发:操作者/被操作者显示在私聊面板,其他人显示在公屏 - 系统消息加随机鼓励语(各5条轮换) - ChatStateService 修复 Redis key 前缀扫描问题(getAllActiveRoomIds) - 用户名片折叠优化:管理员视野、职务履历均可折叠 - 管理操作 + 职务操作合并为「🔧 管理操作」折叠区 - 悄悄话改为「🎁 送礼物」按钮,礼物面板内联展开
154 lines
8.7 KiB
PHP
154 lines
8.7 KiB
PHP
@extends('admin.layouts.app')
|
||
|
||
@section('title', '随机事件管理')
|
||
|
||
@section('content')
|
||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||
<div class="p-6 border-b border-gray-100 flex justify-between items-center bg-gray-50">
|
||
<div>
|
||
<h2 class="text-lg font-bold text-gray-800">随机事件管理 (autoact)</h2>
|
||
<p class="text-xs text-gray-500 mt-1">管理聊天室中随机触发的好运/坏运事件,可增减经验和金币。</p>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- 新增事件表单 --}}
|
||
<div class="p-6 border-b border-gray-100 bg-indigo-50/50">
|
||
<h3 class="text-sm font-bold text-gray-700 mb-3">➕ 添加新事件</h3>
|
||
<form action="{{ route('admin.autoact.store') }}" method="POST">
|
||
@csrf
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 max-w-4xl">
|
||
<div class="md:col-span-2">
|
||
<label class="block text-xs font-bold text-gray-600 mb-1">事件文本
|
||
<span class="text-gray-400 font-normal">({username} 将被替换为触发者用户名)</span></label>
|
||
<input type="text" name="text_body" required placeholder="例:🎉 恭喜【{username}】获得 100 经验値!"
|
||
class="w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 bg-white border">
|
||
</div>
|
||
<div>
|
||
<label class="block text-xs font-bold text-gray-600 mb-1">事件类型</label>
|
||
<select name="event_type"
|
||
class="w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 bg-white border">
|
||
<option value="good">🟢 好运(奖励)</option>
|
||
<option value="bad">🔴 坏运(惩罚)</option>
|
||
<option value="neutral">🟣 中性(纯文字)</option>
|
||
</select>
|
||
</div>
|
||
<div class="flex gap-3">
|
||
<div class="flex-1">
|
||
<label class="block text-xs font-bold text-gray-600 mb-1">经验变化</label>
|
||
<input type="number" name="exp_change" value="0"
|
||
class="w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 bg-white border">
|
||
</div>
|
||
<div class="flex-1">
|
||
<label class="block text-xs font-bold text-gray-600 mb-1">金币变化</label>
|
||
<input type="number" name="jjb_change" value="0"
|
||
class="w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 p-2 bg-white border">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="mt-4">
|
||
<button type="submit"
|
||
class="px-6 py-2 bg-indigo-600 text-white rounded-md font-bold hover:bg-indigo-700 shadow-sm transition text-sm">
|
||
添加事件
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
{{-- 事件列表 --}}
|
||
<div class="p-6">
|
||
<h3 class="text-sm font-bold text-gray-700 mb-3">📋 现有事件列表(共 {{ $events->count() }} 条)</h3>
|
||
<div class="overflow-x-auto">
|
||
<table class="w-full text-sm">
|
||
<thead>
|
||
<tr class="bg-gray-50 text-gray-600 text-left border-b">
|
||
<th class="p-3 w-10">ID</th>
|
||
<th class="p-3">事件文本</th>
|
||
<th class="p-3 w-20">类型</th>
|
||
<th class="p-3 w-16">经验</th>
|
||
<th class="p-3 w-16">金币</th>
|
||
<th class="p-3 w-16">状态</th>
|
||
<th class="p-3 w-32">操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@forelse ($events as $event)
|
||
<tr class="border-b hover:bg-gray-50 {{ !$event->enabled ? 'opacity-40' : '' }}">
|
||
<td class="p-3 text-gray-400">{{ $event->id }}</td>
|
||
<td class="p-3">
|
||
<span class="text-xs">{{ Str::limit($event->text_body, 60) }}</span>
|
||
</td>
|
||
<td class="p-3">
|
||
@if ($event->event_type === 'good')
|
||
<span
|
||
class="px-2 py-0.5 rounded-full bg-green-100 text-green-700 text-xs font-bold">好运</span>
|
||
@elseif($event->event_type === 'bad')
|
||
<span
|
||
class="px-2 py-0.5 rounded-full bg-red-100 text-red-700 text-xs font-bold">坏运</span>
|
||
@else
|
||
<span
|
||
class="px-2 py-0.5 rounded-full bg-purple-100 text-purple-700 text-xs font-bold">中性</span>
|
||
@endif
|
||
</td>
|
||
<td
|
||
class="p-3 {{ $event->exp_change > 0 ? 'text-green-600' : ($event->exp_change < 0 ? 'text-red-600' : 'text-gray-400') }} font-bold">
|
||
{{ $event->exp_change > 0 ? '+' : '' }}{{ $event->exp_change }}
|
||
</td>
|
||
<td
|
||
class="p-3 {{ $event->jjb_change > 0 ? 'text-green-600' : ($event->jjb_change < 0 ? 'text-red-600' : 'text-gray-400') }} font-bold">
|
||
{{ $event->jjb_change > 0 ? '+' : '' }}{{ $event->jjb_change }}
|
||
</td>
|
||
<td class="p-3">
|
||
<button onclick="toggleEvent({{ $event->id }}, this)"
|
||
class="text-xs px-2 py-1 rounded {{ $event->enabled ? 'bg-green-100 text-green-700' : 'bg-gray-200 text-gray-500' }} cursor-pointer">
|
||
{{ $event->enabled ? '启用' : '禁用' }}
|
||
</button>
|
||
</td>
|
||
<td class="p-3">
|
||
<form action="{{ route('admin.autoact.destroy', $event->id) }}" method="POST"
|
||
class="inline" onsubmit="return confirm('确定要删除此事件吗?')">
|
||
@csrf
|
||
@method('DELETE')
|
||
<button type="submit"
|
||
class="text-red-500 hover:text-red-700 text-xs font-bold">删除</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
@empty
|
||
<tr>
|
||
<td colspan="7" class="p-6 text-center text-gray-400">暂无事件,请添加。</td>
|
||
</tr>
|
||
@endforelse
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
/**
|
||
* 切换事件启用/禁用状态
|
||
*/
|
||
function toggleEvent(id, btn) {
|
||
fetch(`/admin/autoact/${id}/toggle`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||
'Content-Type': 'application/json',
|
||
'Accept': 'application/json',
|
||
},
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (data.status === 'success') {
|
||
btn.textContent = data.enabled ? '启用' : '禁用';
|
||
btn.className = data.enabled ?
|
||
'text-xs px-2 py-1 rounded bg-green-100 text-green-700 cursor-pointer' :
|
||
'text-xs px-2 py-1 rounded bg-gray-200 text-gray-500 cursor-pointer';
|
||
// 切换行透明度
|
||
btn.closest('tr').classList.toggle('opacity-40', !data.enabled);
|
||
}
|
||
});
|
||
}
|
||
</script>
|
||
@endsection
|