统一后台列表页样式并调整站长菜单
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
@section('title', 'AI 厂商配置')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
<div x-data="{
|
||||
showForm: false,
|
||||
editId: null,
|
||||
@@ -68,12 +69,12 @@
|
||||
}">
|
||||
|
||||
{{-- 全局开关 + 高级设置 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden mb-6">
|
||||
<div class="{{ $adminListCardClass }} mb-6">
|
||||
<div class="p-6">
|
||||
<!-- 顶部栏:开关和添加按钮 -->
|
||||
<div class="flex items-center justify-between border-b border-gray-100 pb-4 mb-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<h2 class="text-lg font-bold text-gray-800">🤖 AI 聊天机器人配置</h2>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🤖 AI 聊天机器人配置</h2>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm text-gray-500">大厅状态:</span>
|
||||
<button id="chatbot-toggle-btn" data-ai-chatbot-toggle-url="{{ route('admin.ai-providers.toggle-chatbot') }}"
|
||||
@@ -87,8 +88,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<button x-on:click="openNew()"
|
||||
class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition font-bold text-sm">
|
||||
<button x-on:click="openNew()" class="{{ $adminListPrimaryButtonClass }}">
|
||||
+ 添加 AI 厂商
|
||||
</button>
|
||||
</div>
|
||||
@@ -145,26 +145,26 @@
|
||||
</div>
|
||||
|
||||
{{-- 厂商列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left font-bold">厂商</th>
|
||||
<th class="px-6 py-3 text-left font-bold">模型</th>
|
||||
<th class="px-6 py-3 text-left font-bold">API 端点</th>
|
||||
<th class="px-6 py-3 text-center font-bold">参数</th>
|
||||
<th class="px-6 py-3 text-center font-bold">排序</th>
|
||||
<th class="px-6 py-3 text-center font-bold">状态</th>
|
||||
<th class="px-6 py-3 text-center font-bold">默认</th>
|
||||
<th class="px-6 py-3 text-center font-bold">操作</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">厂商</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">模型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">API 端点</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">参数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">排序</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">默认</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($providers as $provider)
|
||||
<tr class="hover:bg-gray-50 transition {{ !$provider->is_enabled ? 'opacity-50' : '' }}">
|
||||
<tr class="{{ $adminListTableRowClass }} {{ !$provider->is_enabled ? 'opacity-50' : '' }}">
|
||||
<td class="px-6 py-4">
|
||||
<div class="font-bold text-gray-800">{{ $provider->name }}</div>
|
||||
<div class="text-xs text-gray-400">{{ $provider->provider }}</div>
|
||||
<div class="{{ $adminListPrimaryTextClass }}">{{ $provider->name }}</div>
|
||||
<div class="{{ $adminListSecondaryTextClass }}">{{ $provider->provider }}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<code class="bg-gray-100 px-2 py-1 rounded text-xs">{{ $provider->model }}</code>
|
||||
@@ -202,22 +202,22 @@
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<button data-ai-provider-test-url="{{ route('admin.ai-providers.test', $provider->id) }}"
|
||||
data-ai-provider-name="{{ $provider->name }}"
|
||||
class="text-teal-600 hover:text-teal-800 text-xs font-bold">⚡ 测试</button>
|
||||
class="{{ $adminListActionButtonClass }} text-teal-600 hover:text-teal-800 hover:bg-teal-50">⚡ 测试</button>
|
||||
<button x-on:click="openEdit({{ $provider->toJson() }})"
|
||||
class="text-indigo-600 hover:text-indigo-800 text-xs font-bold">编辑</button>
|
||||
class="{{ $adminListActionButtonClass }} text-indigo-600 hover:text-indigo-800 hover:bg-indigo-50">编辑</button>
|
||||
<form action="{{ route('admin.ai-providers.destroy', $provider->id) }}" method="POST"
|
||||
data-admin-confirm="确定要删除 {{ $provider->name }} 吗?">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
class="text-red-500 hover:text-red-700 text-xs font-bold">删除</button>
|
||||
class="{{ $adminListActionButtonClass }} text-red-500 hover:text-red-700 hover:bg-red-50">删除</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="px-6 py-12 text-center text-gray-400">
|
||||
<td colspan="8" class="{{ $adminListEmptyClass }}">
|
||||
暂无 AI 厂商配置,请点击上方"添加 AI 厂商"按钮。
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -11,13 +11,18 @@
|
||||
@section('title', '权限操作日志 · ' . $userPosition->user->username)
|
||||
|
||||
@section('content')
|
||||
<div class="mb-6">
|
||||
<a href="{{ route('admin.appointments.index') }}" class="text-sm text-indigo-600 hover:underline">← 返回任命管理</a>
|
||||
<h2 class="text-lg font-bold text-gray-800 mt-2">
|
||||
{{ $userPosition->position->icon }} {{ $userPosition->user->username }} · {{ $userPosition->position->name }}
|
||||
</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">权限操作记录(共 {{ $logs->total() }} 条)</p>
|
||||
</div>
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div>
|
||||
<a href="{{ route('admin.appointments.index') }}" class="text-sm font-semibold text-indigo-600 hover:text-indigo-700">← 返回任命管理</a>
|
||||
<h2 class="mt-2 {{ $adminListHeaderTitleClass }}">
|
||||
{{ $userPosition->position->icon }} {{ $userPosition->user->username }} · {{ $userPosition->position->name }}
|
||||
</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">权限操作记录(共 {{ $logs->total() }} 条)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$actionColors = [
|
||||
@@ -32,42 +37,51 @@
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">操作时间</th>
|
||||
<th class="px-4 py-3 text-center">操作类型</th>
|
||||
<th class="px-4 py-3 text-left">操作对象</th>
|
||||
<th class="px-4 py-3 text-left">目标职务</th>
|
||||
<th class="px-4 py-3 text-center">奖励金额</th>
|
||||
<th class="px-4 py-3 text-left">备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($logs as $log)
|
||||
@php $colorClass = $actionColors[$log->action_type] ?? 'bg-gray-100 text-gray-600'; @endphp
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 text-gray-500 text-xs">{{ $log->created_at->format('m-d H:i:s') }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="text-xs px-2 py-0.5 rounded font-bold {{ $colorClass }}">
|
||||
{{ $log->action_label }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 font-bold text-gray-700">{{ $log->targetUser->username ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-gray-500">{{ $log->targetPosition?->name ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-center text-yellow-600 font-bold">
|
||||
{{ $log->amount ? number_format($log->amount) . ' 金币' : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-400 text-xs">{{ $log->remark ?? '—' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="px-4 py-12 text-center text-gray-400">暂无权限操作记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">权限操作日志</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">覆盖任命周期内的任命、撤销、奖励、警告、踢出、禁言等权限动作。</p>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} whitespace-nowrap">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">操作时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">操作类型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">操作对象</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">目标职务</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">奖励金额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($logs as $log)
|
||||
@php $colorClass = $actionColors[$log->action_type] ?? 'bg-gray-100 text-gray-600'; @endphp
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">{{ $log->created_at->format('m-d H:i:s') }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold {{ $colorClass }}">
|
||||
{{ $log->action_label }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $log->targetUser->username ?? '—' }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">{{ $log->targetPosition?->name ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-center text-sm font-semibold text-yellow-600">
|
||||
{{ $log->amount ? number_format($log->amount) . ' 金币' : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">{{ $log->remark ?? '—' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="{{ $adminListEmptyClass }}">暂无权限操作记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($logs->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $logs->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">{{ $logs->links() }}</div>
|
||||
@endsection
|
||||
|
||||
@@ -11,70 +11,81 @@
|
||||
@section('title', '在职登录日志 · ' . $userPosition->user->username)
|
||||
|
||||
@section('content')
|
||||
<div class="mb-6">
|
||||
<a href="{{ route('admin.appointments.index') }}" class="text-sm text-indigo-600 hover:underline">← 返回任命管理</a>
|
||||
<h2 class="text-lg font-bold text-gray-800 mt-2">
|
||||
{{ $userPosition->position->icon }} {{ $userPosition->user->username }} · {{ $userPosition->position->name }}
|
||||
</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">
|
||||
任命于 {{ $userPosition->appointed_at->format('Y-m-d') }},
|
||||
任命人:{{ $userPosition->appointedBy?->username ?? '系统' }}
|
||||
</p>
|
||||
</div>
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div>
|
||||
<a href="{{ route('admin.appointments.index') }}" class="text-sm font-semibold text-indigo-600 hover:text-indigo-700">← 返回任命管理</a>
|
||||
<h2 class="mt-2 {{ $adminListHeaderTitleClass }}">
|
||||
{{ $userPosition->position->icon }} {{ $userPosition->user->username }} · {{ $userPosition->position->name }}
|
||||
</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
任命于 {{ $userPosition->appointed_at->format('Y-m-d') }},任命人:{{ $userPosition->appointedBy?->username ?? '系统' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 统计摘要 --}}
|
||||
<div class="grid grid-cols-3 gap-4 mb-6">
|
||||
<div class="bg-white rounded-xl p-5 border shadow-sm text-center">
|
||||
<div class="grid gap-4 md:grid-cols-3">
|
||||
<div class="{{ $adminListCardClass }} p-5 text-center">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ $logs->total() }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">总登录次数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl p-5 border shadow-sm text-center">
|
||||
<div class="{{ $adminListCardClass }} p-5 text-center">
|
||||
<div class="text-2xl font-bold text-green-600">
|
||||
{{ intdiv($totalSeconds, 3600) }}h {{ intdiv($totalSeconds % 3600, 60) }}m
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 mt-1">累计在线时长(所有)</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl p-5 border shadow-sm text-center">
|
||||
<div class="{{ $adminListCardClass }} p-5 text-center">
|
||||
<div class="text-2xl font-bold text-orange-600">{{ $userPosition->total_rewarded_coins }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">在职期间发放金币</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">登录时间</th>
|
||||
<th class="px-4 py-3 text-left">退出时间</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-left">IP 地址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($logs as $log)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 text-gray-700">{{ $log->login_at->format('m-d H:i:s') }}</td>
|
||||
<td class="px-4 py-3 text-gray-500">{{ $log->logout_at?->format('m-d H:i:s') ?? '在线中...' }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($log->duration_seconds)
|
||||
<span
|
||||
class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">{{ $log->formatted_duration }}</span>
|
||||
@else
|
||||
<span class="text-xs text-gray-400">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-gray-500">{{ $log->room_id ? "房间#{$log->room_id}" : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-400 font-mono text-xs">{{ $log->ip_address }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="5" class="px-4 py-12 text-center text-gray-400">暂无登录记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">在职登录记录</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">记录该任职周期内的登录、退出、在线时长与所在房间信息。</p>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} whitespace-nowrap">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">登录时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">退出时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">在线时长</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">房间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">IP 地址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($logs as $log)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $log->login_at->format('m-d H:i:s') }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">{{ $log->logout_at?->format('m-d H:i:s') ?? '在线中...' }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($log->duration_seconds)
|
||||
<span class="inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-semibold text-blue-700">{{ $log->formatted_duration }}</span>
|
||||
@else
|
||||
<span class="{{ $adminListSecondaryTextClass }}">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center {{ $adminListBodyTextClass }}">{{ $log->room_id ? "房间#{$log->room_id}" : '—' }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListNumericTextClass }} text-gray-400">{{ $log->ip_address }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="5" class="{{ $adminListEmptyClass }}">暂无登录记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($logs->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $logs->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">{{ $logs->links() }}</div>
|
||||
@endsection
|
||||
|
||||
@@ -11,52 +11,67 @@
|
||||
@section('title', '历史任职记录')
|
||||
|
||||
@section('content')
|
||||
<div class="mb-6">
|
||||
<a href="{{ route('admin.appointments.index') }}" class="text-sm text-indigo-600 hover:underline">← 返回任命管理</a>
|
||||
<h2 class="text-lg font-bold text-gray-800 mt-2">历史任职记录</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">已撤销的职务记录(共 {{ $history->total() }} 条)</p>
|
||||
</div>
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">用户</th>
|
||||
<th class="px-4 py-3 text-left">职务</th>
|
||||
<th class="px-4 py-3 text-left">任命人</th>
|
||||
<th class="px-4 py-3 text-center">任命时间</th>
|
||||
<th class="px-4 py-3 text-left">撤销人</th>
|
||||
<th class="px-4 py-3 text-center">撤销时间</th>
|
||||
<th class="px-4 py-3 text-center">在职天数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($history as $up)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 font-bold text-gray-800">{{ $up->user->username }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="mr-1">{{ $up->position->icon }}</span>
|
||||
<span style="color: {{ $up->position->department->color }}">{{ $up->position->name }}</span>
|
||||
<span class="text-xs text-gray-400 ml-1">{{ $up->position->department->name }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-500">{{ $up->appointedBy?->username ?? '系统' }}</td>
|
||||
<td class="px-4 py-3 text-center text-gray-500 text-xs">{{ $up->appointed_at->format('Y-m-d') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-500">{{ $up->revokedBy?->username ?? '系统' }}</td>
|
||||
<td class="px-4 py-3 text-center text-gray-500 text-xs">
|
||||
{{ $up->revoked_at?->format('Y-m-d') ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="text-xs bg-gray-100 text-gray-600 px-2 py-0.5 rounded">{{ $up->duration_days }}
|
||||
天</span>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-12 text-center text-gray-400">暂无历史记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
|
||||
<div>
|
||||
<a href="{{ route('admin.appointments.index') }}" class="text-sm font-semibold text-indigo-600 hover:text-indigo-700">← 返回任命管理</a>
|
||||
<h2 class="mt-2 {{ $adminListHeaderTitleClass }}">历史任职记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">已撤销的职务记录(共 {{ $history->total() }} 条)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">任职历史列表</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">按撤销后的记录保留完整的任命与撤销链路,便于审计追踪。</p>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} whitespace-nowrap">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">用户</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">职务</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">任命人</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">任命时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">撤销人</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">撤销时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">在职天数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($history as $up)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $up->user->username }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center gap-1">
|
||||
<span>{{ $up->position->icon }}</span>
|
||||
<span class="text-sm font-semibold" style="color: {{ $up->position->department->color }}">{{ $up->position->name }}</span>
|
||||
<span class="{{ $adminListSecondaryTextClass }}">{{ $up->position->department->name }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">{{ $up->appointedBy?->username ?? '系统' }}</td>
|
||||
<td class="px-4 py-3 text-center {{ $adminListSecondaryTextClass }}">{{ $up->appointed_at->format('Y-m-d') }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">{{ $up->revokedBy?->username ?? '系统' }}</td>
|
||||
<td class="px-4 py-3 text-center {{ $adminListSecondaryTextClass }}">{{ $up->revoked_at?->format('Y-m-d') ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs font-semibold text-gray-600">{{ $up->duration_days }} 天</span>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无历史记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($history->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $history->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">{{ $history->links() }}</div>
|
||||
@endsection
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
@section('title', '任命管理')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div x-data="{
|
||||
showForm: false,
|
||||
username: '',
|
||||
@@ -52,79 +54,86 @@
|
||||
}
|
||||
}">
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
{{-- 头部 --}}
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">任命管理</h2>
|
||||
<p class="text-sm text-gray-500">管理当前所有在职职位人员,执行任命或撤销操作</p>
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">任命管理</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">管理当前所有在职职位人员,执行任命或撤销操作</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<a href="{{ route('admin.appointments.history') }}"
|
||||
style="background-color:#e5e7eb;color:#374151;padding:0.5rem 1rem;border-radius:0.5rem;font-weight:700;font-size:0.875rem;display:inline-flex;align-items:center;text-decoration:none;"
|
||||
onmouseover="this.style.backgroundColor='#d1d5db'" onmouseout="this.style.backgroundColor='#e5e7eb'">
|
||||
class="{{ $adminListSecondaryButtonClass }} inline-flex items-center justify-center">
|
||||
历史记录
|
||||
</a>
|
||||
<button @click="openAppoint()"
|
||||
style="background-color:#f97316;color:#fff;padding:0.5rem 1.25rem;border-radius:0.5rem;font-weight:700;border:none;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.1);"
|
||||
onmouseover="this.style.backgroundColor='#ea580c'" onmouseout="this.style.backgroundColor='#f97316'">
|
||||
class="inline-flex items-center justify-center rounded-lg bg-orange-500 px-4 py-2 text-sm font-semibold text-white shadow-sm transition hover:bg-orange-600">
|
||||
+ 新增任命
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 在职人员列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">用户</th>
|
||||
<th class="px-4 py-3 text-left">部门·职务</th>
|
||||
<th class="px-4 py-3 text-center">等级</th>
|
||||
<th class="px-4 py-3 text-left">任命人</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-right">操作</th>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">在职人员列表</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">展示当前所有已任命且仍在职的人员,可直接查看履职日志或执行撤销。</p>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} whitespace-nowrap">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">用户</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">部门·职务</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">等级</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">任命人</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">任命时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">在职天数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($activePositions as $up)
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3">
|
||||
<div class="font-bold text-gray-800">{{ $up->user->username }}</div>
|
||||
<div class="text-xs text-gray-400">Lv.{{ $up->user->user_level }}</div>
|
||||
<div class="{{ $adminListPrimaryTextClass }}">{{ $up->user->username }}</div>
|
||||
<div class="{{ $adminListSecondaryTextClass }}">Lv.{{ $up->user->user_level }}</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center space-x-1">
|
||||
<span class="text-lg">{{ $up->position->icon }}</span>
|
||||
<div>
|
||||
<div class="text-xs text-gray-400">{{ $up->position->department->name }}</div>
|
||||
<div class="font-bold" style="color: {{ $up->position->department->color }}">
|
||||
<div class="{{ $adminListSecondaryTextClass }}">{{ $up->position->department->name }}</div>
|
||||
<div class="text-sm font-semibold" style="color: {{ $up->position->department->color }}">
|
||||
{{ $up->position->name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="text-xs bg-orange-100 text-orange-700 px-2 py-0.5 rounded font-mono">
|
||||
<span class="inline-flex items-center rounded-full bg-orange-100 px-2 py-0.5 text-xs font-mono font-semibold text-orange-700">
|
||||
Lv.{{ $up->position->level }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-600">{{ $up->appointedBy?->username ?? '系统' }}</td>
|
||||
<td class="px-4 py-3 text-center text-gray-500">
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">{{ $up->appointedBy?->username ?? '系统' }}</td>
|
||||
<td class="px-4 py-3 text-center {{ $adminListSecondaryTextClass }}">
|
||||
{{ $up->appointed_at->format('Y-m-d') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">
|
||||
<span class="inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-semibold text-blue-700">
|
||||
{{ $up->duration_days }} 天
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right space-x-1">
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex flex-wrap items-center justify-end gap-2">
|
||||
<a href="{{ route('admin.appointments.duty-logs', $up->id) }}"
|
||||
class="text-xs bg-blue-50 text-blue-600 font-bold px-2 py-1 rounded hover:bg-blue-600 hover:text-white transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-blue-50 text-blue-600 hover:bg-blue-600 hover:text-white">
|
||||
登录日志
|
||||
</a>
|
||||
<a href="{{ route('admin.appointments.authority-logs', $up->id) }}"
|
||||
class="text-xs bg-purple-50 text-purple-600 font-bold px-2 py-1 rounded hover:bg-purple-600 hover:text-white transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-purple-50 text-purple-600 hover:bg-purple-600 hover:text-white">
|
||||
操作日志
|
||||
</a>
|
||||
<form action="{{ route('admin.appointments.revoke', $up->id) }}" method="POST"
|
||||
@@ -132,53 +141,53 @@
|
||||
data-admin-confirm="确定撤销【{{ $up->user->username }}】的【{{ $up->position->name }}】职务?撤销后其等级将归 1。">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit"
|
||||
class="text-xs bg-red-50 text-red-600 font-bold px-2 py-1 rounded hover:bg-red-600 hover:text-white transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-red-50 text-red-600 hover:bg-red-600 hover:text-white">
|
||||
撤销职务
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-12 text-center text-gray-400">暂无在职人员</td>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无在职人员</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 新增任命弹窗 --}}
|
||||
<div x-show="showForm" style="display: none;"
|
||||
class="fixed inset-0 z-50 bg-black/60 flex items-center justify-center p-4">
|
||||
<div @click.away="showForm = false" class="bg-white rounded-xl shadow-2xl w-full max-w-md" x-transition>
|
||||
<div
|
||||
style="background-color:#c2410c;padding:1rem 1.5rem;display:flex;justify-content:space-between;align-items:center;border-radius:0.75rem 0.75rem 0 0;">
|
||||
<h3 style="font-weight:700;font-size:1.125rem;color:#fff;margin:0;">新增任命</h3>
|
||||
<div class="flex items-center justify-between rounded-t-xl border-b border-orange-800 bg-orange-700 px-6 py-4">
|
||||
<h3 class="text-lg font-bold text-white">新增任命</h3>
|
||||
<button @click="showForm = false"
|
||||
style="color:#fed7aa;background:none;border:none;font-size:1.5rem;cursor:pointer;line-height:1;"
|
||||
onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#fed7aa'">×</button>
|
||||
class="text-2xl leading-none text-orange-200 transition hover:text-white">×</button>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<form action="{{ route('admin.appointments.store') }}" method="POST">
|
||||
@csrf
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">用户名</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">用户名</label>
|
||||
<div class="relative">
|
||||
<input type="text" name="username" x-model="username" required
|
||||
placeholder="输入关键字搜索用户..." @input="doSearch($event.target.value)"
|
||||
@blur="setTimeout(() => showDropdown = false, 200)"
|
||||
@focus="if(username.length > 0) doSearch(username)"
|
||||
class="w-full border rounded-md p-2 text-sm" autocomplete="off">
|
||||
class="w-full {{ $adminListFilterInputClass }}" autocomplete="off">
|
||||
{{-- 搜索中指示 --}}
|
||||
<span x-show="searching"
|
||||
class="absolute right-2 top-2.5 text-gray-400 text-xs">搜索中…</span>
|
||||
{{-- 下拉结果 --}}
|
||||
<div x-show="showDropdown" style="display:none;"
|
||||
class="absolute z-50 w-full bg-white border rounded-md shadow-lg mt-1 max-h-48 overflow-y-auto">
|
||||
class="absolute z-50 mt-1 max-h-48 w-full overflow-y-auto rounded-lg border border-orange-100 bg-white shadow-lg">
|
||||
<template x-for="u in searchResults" :key="u.id">
|
||||
<div @mousedown="selectUser(u)"
|
||||
class="px-3 py-2 hover:bg-orange-50 cursor-pointer flex justify-between items-center">
|
||||
class="flex cursor-pointer items-center justify-between px-3 py-2 hover:bg-orange-50">
|
||||
<span class="font-bold text-sm" x-text="u.username"></span>
|
||||
<span class="text-xs text-gray-400" x-text="'Lv.' + u.user_level"></span>
|
||||
</div>
|
||||
@@ -189,9 +198,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">目标职务</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">目标职务</label>
|
||||
<select name="position_id" x-model="position_id" required
|
||||
class="w-full border rounded-md p-2 text-sm">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
<option value="">-- 请选择职务 --</option>
|
||||
@foreach ($departments as $dept)
|
||||
<optgroup label="{{ $dept->name }}">
|
||||
@@ -215,21 +224,16 @@
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">任命备注(可选)</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">任命备注(可选)</label>
|
||||
<input type="text" name="remark" x-model="remark" maxlength="255"
|
||||
placeholder="例:表现优秀,特此提拔" class="w-full border rounded-md p-2 text-sm">
|
||||
placeholder="例:表现优秀,特此提拔" class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="display:flex;justify-content:flex-end;gap:0.75rem;padding-top:1rem;margin-top:1rem;border-top:1px solid #e5e7eb;">
|
||||
<div class="mt-4 flex justify-end gap-3 border-t border-gray-100 pt-4">
|
||||
<button type="button" @click="showForm = false"
|
||||
style="padding:0.5rem 1rem;border:1px solid #d1d5db;border-radius:0.375rem;font-weight:500;color:#4b5563;background:#fff;cursor:pointer;"
|
||||
onmouseover="this.style.background='#f9fafb'"
|
||||
onmouseout="this.style.background='#fff'">取消</button>
|
||||
class="{{ $adminListSecondaryButtonClass }}">取消</button>
|
||||
<button type="submit"
|
||||
style="padding:0.5rem 1rem;background-color:#f97316;color:#fff;border-radius:0.375rem;font-weight:700;border:none;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.1);"
|
||||
onmouseover="this.style.backgroundColor='#ea580c'"
|
||||
onmouseout="this.style.backgroundColor='#f97316'">
|
||||
class="rounded-lg bg-orange-500 px-4 py-2 text-sm font-semibold text-white shadow-sm transition hover:bg-orange-600">
|
||||
确认任命
|
||||
</button>
|
||||
</div>
|
||||
@@ -237,5 +241,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -12,13 +12,16 @@
|
||||
@section('title', '我的履职记录')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
|
||||
{{-- ── 页面标题 ── --}}
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xl font-bold text-gray-800">📝 我的履职记录</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">📝 我的履职记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
{{ $user->username }} 的全部职务操作历史,共
|
||||
<span class="font-bold text-gray-700">{{ $logs->total() }}</span> 条记录
|
||||
<span class="font-semibold text-gray-700">{{ $logs->total() }}</span> 条记录
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -72,14 +75,14 @@
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div style="display:grid; grid-template-columns:repeat(6,1fr); gap:12px; margin-bottom:24px;">
|
||||
<div class="grid gap-3 md:grid-cols-3 xl:grid-cols-6">
|
||||
@foreach ($statCards as $type => $card)
|
||||
@php
|
||||
$stat = $summary->get($type);
|
||||
$c = $colorMap[$card['color']];
|
||||
@endphp
|
||||
<a href="{{ request()->fullUrlWithQuery(['type' => $type, 'page' => 1]) }}"
|
||||
class="rounded-xl border {{ $c['bg'] }} {{ $c['border'] }} px-3 py-3 text-center hover:shadow-md transition
|
||||
class="rounded-xl border shadow-sm {{ $c['bg'] }} {{ $c['border'] }} px-3 py-3 text-center hover:shadow-md transition
|
||||
{{ request('type') === $type ? 'ring-2 ring-offset-1 ring-indigo-400 shadow-md' : '' }}">
|
||||
<div class="text-xl mb-0.5">{{ $card['icon'] }}</div>
|
||||
<div class="text-xs text-gray-500 mb-0.5 whitespace-nowrap">{{ $card['label'] }}</div>
|
||||
@@ -92,11 +95,13 @@
|
||||
</div>
|
||||
|
||||
{{-- ── 筛选栏 ── --}}
|
||||
<form method="GET" class="bg-white rounded-xl shadow-sm border p-4 mb-4 flex flex-wrap gap-3 items-end">
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form method="GET" class="{{ $adminListFilterFormClass }}">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">操作类型</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">操作类型</label>
|
||||
<select name="type"
|
||||
class="border rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-300 outline-none">
|
||||
class="{{ $adminListFilterInputClass }}">
|
||||
<option value="">全部类型</option>
|
||||
@foreach ($statCards as $type => $card)
|
||||
<option value="{{ $type }}" {{ request('type') === $type ? 'selected' : '' }}>
|
||||
@@ -106,26 +111,28 @@
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">开始日期</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">开始日期</label>
|
||||
<input type="date" name="date_from" value="{{ request('date_from') }}"
|
||||
class="border rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-300 outline-none">
|
||||
class="{{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">结束日期</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">结束日期</label>
|
||||
<input type="date" name="date_to" value="{{ request('date_to') }}"
|
||||
class="border rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-300 outline-none">
|
||||
class="{{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white text-sm font-bold rounded-lg hover:bg-indigo-700 transition">
|
||||
class="{{ $adminListPrimaryButtonClass }}">
|
||||
🔍 查询
|
||||
</button>
|
||||
@if (request()->hasAny(['type', 'date_from', 'date_to']))
|
||||
<a href="{{ route('admin.appointments.my-duty-logs') }}"
|
||||
class="px-5 py-2 bg-gray-100 text-gray-600 text-sm rounded-lg hover:bg-gray-200 transition">
|
||||
class="{{ $adminListSecondaryButtonClass }}">
|
||||
✖ 清除筛选
|
||||
</a>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ── 记录表格 ── --}}
|
||||
@php
|
||||
@@ -141,66 +148,74 @@
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">操作时间</th>
|
||||
<th class="px-4 py-3 text-center">操作类型</th>
|
||||
<th class="px-4 py-3 text-left">操作对象</th>
|
||||
<th class="px-4 py-3 text-left">所属职务</th>
|
||||
<th class="px-4 py-3 text-center">金币金额</th>
|
||||
<th class="px-4 py-3 text-left">备注说明</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($logs as $log)
|
||||
@php $colorClass = $actionColors[$log->action_type] ?? 'bg-gray-100 text-gray-600'; @endphp
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 text-gray-400 text-xs whitespace-nowrap">
|
||||
{{ $log->created_at->format('Y-m-d H:i') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="text-xs px-2 py-0.5 rounded-full font-bold {{ $colorClass }}">
|
||||
{{ $log->action_label }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 font-bold text-gray-700">
|
||||
{{ $log->targetUser?->username ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-500 text-xs">
|
||||
@if ($log->userPosition?->position)
|
||||
<span class="text-gray-400">{{ $log->userPosition->position->department?->name }}</span>
|
||||
@if ($log->userPosition->position->department)
|
||||
<span class="text-gray-300 mx-1">·</span>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">履职操作记录</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">可按操作类型和日期范围筛选当前登录者的历史履职行为。</p>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} whitespace-nowrap">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">操作时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">操作类型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">操作对象</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">所属职务</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">金币金额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">备注说明</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($logs as $log)
|
||||
@php $colorClass = $actionColors[$log->action_type] ?? 'bg-gray-100 text-gray-600'; @endphp
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 whitespace-nowrap {{ $adminListSecondaryTextClass }}">
|
||||
{{ $log->created_at->format('Y-m-d H:i') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold {{ $colorClass }}">
|
||||
{{ $log->action_label }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">
|
||||
{{ $log->targetUser?->username ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">
|
||||
@if ($log->userPosition?->position)
|
||||
<span>{{ $log->userPosition->position->department?->name }}</span>
|
||||
@if ($log->userPosition->position->department)
|
||||
<span class="mx-1 text-gray-300">·</span>
|
||||
@endif
|
||||
<span class="text-gray-600">{{ $log->userPosition->position->name }}</span>
|
||||
@else
|
||||
<span class="text-gray-300">超级管理员</span>
|
||||
@endif
|
||||
{{ $log->userPosition->position->name }}
|
||||
@else
|
||||
<span class="text-gray-300">超级管理员</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($log->amount)
|
||||
<span class="text-yellow-600 font-bold">+{{ number_format($log->amount) }}</span>
|
||||
<span class="text-gray-400 text-xs">金币</span>
|
||||
@else
|
||||
<span class="text-gray-300">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-gray-400 text-xs">{{ $log->remark ?: '—' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="px-4 py-16 text-center text-gray-400">
|
||||
<div class="text-4xl mb-3">📋</div>
|
||||
<div>暂无履职操作记录</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($log->amount)
|
||||
<span class="text-sm font-semibold text-yellow-600">+{{ number_format($log->amount) }}</span>
|
||||
<span class="{{ $adminListSecondaryTextClass }}">金币</span>
|
||||
@else
|
||||
<span class="text-gray-300">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">{{ $log->remark ?: '—' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="{{ $adminListEmptyClass }}">
|
||||
<div class="mb-3 text-4xl">📋</div>
|
||||
<div>暂无履职操作记录</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($logs->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $logs->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="mt-4">{{ $logs->links() }}</div>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -3,30 +3,33 @@
|
||||
@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">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }} flex justify-between items-center">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">随机事件管理 (autoact)</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">管理聊天室中随机触发的好运/坏运事件,可增减经验和金币。</p>
|
||||
<h2 class="{{ $adminListSectionTitleClass }}">随机事件管理 (autoact)</h2>
|
||||
<p class="{{ $adminListSectionDescClass }}">管理聊天室中随机触发的好运、坏运和中性事件,保留原有奖励与惩罚语义。</p>
|
||||
</div>
|
||||
</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>
|
||||
<div class="p-6 border-b border-gray-100 bg-indigo-50/50">
|
||||
<h3 class="{{ $adminListSectionTitleClass }} 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">事件文本
|
||||
<label class="{{ $adminListFilterLabelClass }}">事件文本
|
||||
<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">
|
||||
class="w-full {{ $adminListFilterInputClass }} bg-white">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">事件类型</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">事件类型</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">
|
||||
class="w-full {{ $adminListFilterInputClass }} bg-white">
|
||||
<option value="good">🟢 好运(奖励)</option>
|
||||
<option value="bad">🔴 坏运(惩罚)</option>
|
||||
<option value="neutral">🟣 中性(纯文字)</option>
|
||||
@@ -34,20 +37,19 @@
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<div class="flex-1">
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">经验变化</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">经验变化</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">
|
||||
class="w-full {{ $adminListFilterInputClass }} bg-white">
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">金币变化</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">金币变化</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">
|
||||
class="w-full {{ $adminListFilterInputClass }} bg-white">
|
||||
</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 type="submit" class="{{ $adminListPrimaryButtonClass }}">
|
||||
添加事件
|
||||
</button>
|
||||
</div>
|
||||
@@ -55,52 +57,49 @@
|
||||
</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>
|
||||
<div class="p-6">
|
||||
<h3 class="{{ $adminListSectionTitleClass }} mb-3">📋 现有事件列表(共 {{ $events->count() }} 条)</h3>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-10">ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">事件文本</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-20">类型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-16">经验</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-16">金币</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-16">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-32">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@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>
|
||||
<tr class="{{ $adminListTableRowClass }} {{ !$event->enabled ? 'opacity-40' : '' }}">
|
||||
<td class="p-3 {{ $adminListSecondaryTextClass }}">{{ $event->id }}</td>
|
||||
<td class="p-3">
|
||||
<span class="text-xs">{{ Str::limit($event->text_body, 60) }}</span>
|
||||
<span class="{{ $adminListBodyTextClass }}">{{ 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>
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-green-200 bg-green-100 text-green-700">好运</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>
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-red-200 bg-red-100 text-red-700">坏运</span>
|
||||
@else
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full bg-purple-100 text-purple-700 text-xs font-bold">中性</span>
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-purple-200 bg-purple-100 text-purple-700">中性</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">
|
||||
class="p-3 {{ $adminListNumericTextClass }} {{ $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">
|
||||
class="p-3 {{ $adminListNumericTextClass }} {{ $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 type="button"
|
||||
data-autoact-toggle-url="{{ route('admin.autoact.toggle', $event->id) }}"
|
||||
class="text-xs px-2 py-1 rounded {{ $event->enabled ? 'bg-green-100 text-green-700' : 'bg-gray-200 text-gray-500' }} cursor-pointer">
|
||||
class="{{ $adminListBadgeBaseClass }} px-2 py-1 {{ $event->enabled ? 'border-green-200 bg-green-100 text-green-700' : 'border-gray-200 bg-gray-200 text-gray-500' }} cursor-pointer">
|
||||
{{ $event->enabled ? '启用' : '禁用' }}
|
||||
</button>
|
||||
</td>
|
||||
@@ -110,19 +109,19 @@
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
class="text-red-500 hover:text-red-700 text-xs font-bold">删除</button>
|
||||
class="{{ $adminListActionButtonClass }} bg-red-50 text-red-600 hover:bg-red-100">删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="p-6 text-center text-gray-400">暂无事件,请添加。</td>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无事件,请添加。</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -9,94 +9,104 @@
|
||||
@section('title', '开发日志管理')
|
||||
|
||||
@section('content')
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-gray-800">📋 开发日志管理</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">管理版本更新记录,发布后可在大厅消息区通知用户</p>
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">📋 开发日志管理</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">管理版本更新记录,发布后可在大厅消息区通知用户</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.changelogs.create') }}"
|
||||
class="{{ $adminListPrimaryButtonClass }} inline-flex items-center justify-center">
|
||||
+ 新增日志
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ route('admin.changelogs.create') }}"
|
||||
class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg font-bold text-sm shadow transition">
|
||||
+ 新增日志
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 日志列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr class="text-left text-gray-500 text-xs font-bold uppercase tracking-wider">
|
||||
<th class="px-5 py-3">版本号</th>
|
||||
<th class="px-5 py-3">标题</th>
|
||||
<th class="px-5 py-3">类型</th>
|
||||
<th class="px-5 py-3">状态</th>
|
||||
<th class="px-5 py-3">发布时间</th>
|
||||
<th class="px-5 py-3 text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse($logs as $log)
|
||||
<tr class="hover:bg-gray-50 transition-colors">
|
||||
<td class="px-5 py-3 font-mono text-indigo-700 font-bold">v{{ $log->version }}</td>
|
||||
<td class="px-5 py-3 text-gray-800 font-medium">{{ $log->title }}</td>
|
||||
<td class="px-5 py-3">
|
||||
@php
|
||||
$typeConfig = \App\Models\DevChangelog::TYPE_CONFIG[$log->type] ?? null;
|
||||
$colorMap = [
|
||||
'emerald' => 'bg-emerald-100 text-emerald-700',
|
||||
'rose' => 'bg-rose-100 text-rose-700',
|
||||
'blue' => 'bg-blue-100 text-blue-700',
|
||||
'slate' => 'bg-slate-100 text-slate-700',
|
||||
];
|
||||
@endphp
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold {{ $colorMap[$typeConfig['color'] ?? 'slate'] ?? 'bg-slate-100 text-slate-700' }}">
|
||||
{{ $typeConfig['label'] ?? '其他' }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-5 py-3">
|
||||
@if ($log->is_published)
|
||||
<span class="px-2 py-0.5 bg-green-100 text-green-700 rounded-full text-xs font-bold">✅
|
||||
已发布</span>
|
||||
@else
|
||||
<span class="px-2 py-0.5 bg-gray-100 text-gray-500 rounded-full text-xs font-bold">🔒
|
||||
草稿</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-5 py-3 text-gray-400 text-xs">
|
||||
{{ $log->published_at?->format('Y-m-d H:i') ?? '—' }}
|
||||
</td>
|
||||
<td class="px-5 py-3 text-right">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<a href="{{ route('admin.changelogs.edit', $log->id) }}"
|
||||
class="text-blue-600 hover:text-blue-800 font-semibold text-xs px-2 py-1 rounded hover:bg-blue-50 transition">
|
||||
编辑
|
||||
</a>
|
||||
<form action="{{ route('admin.changelogs.destroy', $log->id) }}" method="POST"
|
||||
data-admin-confirm="确定要删除这条日志吗?">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit"
|
||||
class="text-red-600 hover:text-red-800 font-semibold text-xs px-2 py-1 rounded hover:bg-red-50 transition">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="px-5 py-12 text-center text-gray-400">
|
||||
<p class="text-3xl mb-2">📭</p>
|
||||
<p>还没有任何日志,点击右上角「新增日志」开始吧</p>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@if ($logs->hasPages())
|
||||
<div class="px-5 py-4 border-t border-gray-100">
|
||||
{{ $logs->links() }}
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">开发日志列表</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">统一查看版本、类型、发布状态与管理操作。</p>
|
||||
</div>
|
||||
@endif
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} whitespace-nowrap">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">版本号</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">标题</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">类型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">发布时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse($logs as $log)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-5 py-3 font-mono text-sm font-semibold text-indigo-700">v{{ $log->version }}</td>
|
||||
<td class="px-5 py-3 {{ $adminListPrimaryTextClass }}">{{ $log->title }}</td>
|
||||
<td class="px-5 py-3">
|
||||
@php
|
||||
$typeConfig = \App\Models\DevChangelog::TYPE_CONFIG[$log->type] ?? null;
|
||||
$colorMap = [
|
||||
'emerald' => 'bg-emerald-100 text-emerald-700',
|
||||
'rose' => 'bg-rose-100 text-rose-700',
|
||||
'blue' => 'bg-blue-100 text-blue-700',
|
||||
'slate' => 'bg-slate-100 text-slate-700',
|
||||
];
|
||||
@endphp
|
||||
<span
|
||||
class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold {{ $colorMap[$typeConfig['color'] ?? 'slate'] ?? 'bg-slate-100 text-slate-700' }}">
|
||||
{{ $typeConfig['label'] ?? '其他' }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-5 py-3">
|
||||
@if ($log->is_published)
|
||||
<span class="inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-700">✅ 已发布</span>
|
||||
@else
|
||||
<span class="inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs font-semibold text-gray-500">🔒 草稿</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-5 py-3 {{ $adminListSecondaryTextClass }}">
|
||||
{{ $log->published_at?->format('Y-m-d H:i') ?? '—' }}
|
||||
</td>
|
||||
<td class="px-5 py-3 text-right">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<a href="{{ route('admin.changelogs.edit', $log->id) }}"
|
||||
class="{{ $adminListActionButtonClass }} bg-blue-50 text-blue-600 hover:bg-blue-600 hover:text-white">
|
||||
编辑
|
||||
</a>
|
||||
<form action="{{ route('admin.changelogs.destroy', $log->id) }}" method="POST"
|
||||
data-admin-confirm="确定要删除这条日志吗?">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit"
|
||||
class="{{ $adminListActionButtonClass }} bg-red-50 text-red-600 hover:bg-red-600 hover:text-white">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="{{ $adminListEmptyClass }}">
|
||||
<p class="mb-2 text-3xl">📭</p>
|
||||
<p>还没有任何日志,点击右上角「新增日志」开始吧</p>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($logs->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $logs->links() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -9,28 +9,32 @@
|
||||
@section('title', '积分流水统计')
|
||||
|
||||
@section('content')
|
||||
<div class="p-6 max-w-6xl mx-auto">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h1 class="text-2xl font-bold text-gray-800">📊 积分流水活动统计</h1>
|
||||
{{-- 日期选择器 --}}
|
||||
<form method="GET" action="{{ route('admin.currency-stats.index') }}" class="flex items-center gap-3">
|
||||
<label class="text-sm text-gray-600">查询日期:</label>
|
||||
<input type="date" name="date" value="{{ $date }}"
|
||||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-400">
|
||||
<button type="submit"
|
||||
class="bg-indigo-600 text-white px-4 py-2 rounded-lg text-sm hover:bg-indigo-700 transition">
|
||||
查询
|
||||
</button>
|
||||
</form>
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between">
|
||||
<div>
|
||||
<h1 class="{{ $adminListHeaderTitleClass }}">📊 积分流水活动统计</h1>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查看指定日期下各活动来源的经验、金币、魅力产出,以及当日净流通量。</p>
|
||||
</div>
|
||||
<form method="GET" action="{{ route('admin.currency-stats.index') }}"
|
||||
class="flex flex-wrap items-end gap-3">
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">查询日期</label>
|
||||
<input type="date" name="date" value="{{ $date }}"
|
||||
class="{{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">查询</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 净流通量摘要卡片 --}}
|
||||
<div class="grid grid-cols-3 gap-4 mb-8">
|
||||
<div class="grid gap-4 md:grid-cols-3">
|
||||
@foreach (['exp' => ['label' => '经验', 'icon' => '⚡', 'color' => 'amber'], 'gold' => ['label' => '金币', 'icon' => '💰', 'color' => 'yellow'], 'charm' => ['label' => '魅力', 'icon' => '🌸', 'color' => 'pink']] as $cur => $info)
|
||||
@php $flow = $netFlow[$cur] ?? ['in'=>0,'out'=>0,'net'=>0]; @endphp
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm p-5">
|
||||
<div class="{{ $adminListCardClass }} p-5">
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<span class="text-2xl">{{ $info['icon'] }}</span>
|
||||
<span class="font-semibold text-gray-700">{{ $info['label'] }} 流通</span>
|
||||
@@ -43,26 +47,27 @@
|
||||
净增:{{ $flow['net'] >= 0 ? '+' : '' }}{{ number_format($flow['net']) }}
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
{{-- 来源活动详细统计表 --}}
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-200 bg-gray-50">
|
||||
<h2 class="text-lg font-semibold text-gray-700">各活动来源产出明细</h2>
|
||||
<p class="text-xs text-gray-400 mt-1">日期:{{ $date }}(仅统计正向增加,不含消耗)</p>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h2 class="{{ $adminListSectionTitleClass }}">各活动来源产出明细</h2>
|
||||
<p class="{{ $adminListSectionDescClass }}">日期:{{ $date }}(仅统计正向增加,不含消耗)</p>
|
||||
</div>
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b text-gray-600">
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left">来源活动</th>
|
||||
<th class="px-6 py-3 text-right">⚡ 经验产出</th>
|
||||
<th class="px-6 py-3 text-right">💰 金币产出</th>
|
||||
<th class="px-6 py-3 text-right">🌸 魅力产出</th>
|
||||
<th class="px-6 py-3 text-right">参与人次</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">来源活动</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">⚡ 经验产出</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">💰 金币产出</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">🌸 魅力产出</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">参与人次</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@foreach ($allSources as $source)
|
||||
@php
|
||||
$expRow = $statsByType['exp'][$source->value] ?? null;
|
||||
@@ -75,28 +80,30 @@
|
||||
$charmRow?->participant_count ?? 0,
|
||||
);
|
||||
@endphp
|
||||
<tr class="{{ $hasData ? '' : 'opacity-40' }} hover:bg-gray-50 transition">
|
||||
<td class="px-6 py-3 font-medium text-gray-700">{{ $source->label() }}</td>
|
||||
<tr class="{{ $adminListTableRowClass }} {{ $hasData ? '' : 'opacity-40' }}">
|
||||
<td class="px-4 py-3">
|
||||
<span class="{{ $adminListPrimaryTextClass }}">{{ $source->label() }}</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-6 py-3 text-right {{ $expRow?->total_amount > 0 ? 'text-amber-600 font-semibold' : 'text-gray-300' }}">
|
||||
class="px-4 py-3 text-right {{ $adminListNumericTextClass }} {{ $expRow?->total_amount > 0 ? 'text-amber-600 font-semibold' : 'text-gray-300' }}">
|
||||
{{ $expRow ? number_format($expRow->total_amount) : '—' }}
|
||||
</td>
|
||||
<td
|
||||
class="px-6 py-3 text-right {{ $goldRow?->total_amount > 0 ? 'text-yellow-600 font-semibold' : 'text-gray-300' }}">
|
||||
class="px-4 py-3 text-right {{ $adminListNumericTextClass }} {{ $goldRow?->total_amount > 0 ? 'text-yellow-600 font-semibold' : 'text-gray-300' }}">
|
||||
{{ $goldRow ? number_format($goldRow->total_amount) : '—' }}
|
||||
</td>
|
||||
<td
|
||||
class="px-6 py-3 text-right {{ $charmRow?->total_amount > 0 ? 'text-pink-600 font-semibold' : 'text-gray-300' }}">
|
||||
class="px-4 py-3 text-right {{ $adminListNumericTextClass }} {{ $charmRow?->total_amount > 0 ? 'text-pink-600 font-semibold' : 'text-gray-300' }}">
|
||||
{{ $charmRow ? number_format($charmRow->total_amount) : '—' }}
|
||||
</td>
|
||||
<td class="px-6 py-3 text-right text-gray-500">
|
||||
<td class="px-4 py-3 text-right {{ $adminListBodyTextClass }}">
|
||||
{{ $maxParticipants > 0 ? $maxParticipants . ' 人' : '—' }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
@section('title', '用户反馈管理')
|
||||
|
||||
@section('content')
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListHeaderCardClass }} mb-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-gray-800">
|
||||
💬 用户反馈管理
|
||||
@@ -20,12 +22,12 @@
|
||||
</span>
|
||||
@endif
|
||||
</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">管理用户提交的 Bug 报告和功能建议,修改状态后前台实时更新</p>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">管理用户提交的 Bug 报告和功能建议,修改状态后前台实时更新</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 筛选栏 --}}
|
||||
<div class="flex flex-wrap gap-3 mb-5" x-data="{
|
||||
<div class="{{ $adminListFilterCardClass }} mb-5" x-data="{
|
||||
type: '{{ $currentType ?? '' }}',
|
||||
status: '{{ $currentStatus ?? '' }}',
|
||||
go() {
|
||||
@@ -35,25 +37,32 @@
|
||||
window.location.href = '/admin/feedback?' + params.toString();
|
||||
}
|
||||
}">
|
||||
<select x-model="type" @change="go()"
|
||||
class="border border-gray-200 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-400 outline-none bg-white">
|
||||
<option value="">所有类型</option>
|
||||
<option value="bug">🐛 Bug报告</option>
|
||||
<option value="suggestion">💡 功能建议</option>
|
||||
</select>
|
||||
<select x-model="status" @change="go()"
|
||||
class="border border-gray-200 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-400 outline-none bg-white">
|
||||
<option value="">所有状态</option>
|
||||
@foreach ($statusConfig as $key => $config)
|
||||
<option value="{{ $key }}">{{ $config['icon'] }} {{ $config['label'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@if ($currentType || $currentStatus)
|
||||
<a href="{{ route('admin.feedback.index') }}"
|
||||
class="px-3 py-2 text-sm text-gray-500 hover:text-gray-700 border border-gray-200 rounded-lg bg-white hover:bg-gray-50 transition">
|
||||
✕ 清除筛选
|
||||
</a>
|
||||
@endif
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<div class="{{ $adminListFilterFormClass }}">
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">反馈类型</label>
|
||||
<select x-model="type" @change="go()" class="{{ $adminListFilterInputClass }}">
|
||||
<option value="">所有类型</option>
|
||||
<option value="bug">🐛 Bug报告</option>
|
||||
<option value="suggestion">💡 功能建议</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">处理状态</label>
|
||||
<select x-model="status" @change="go()" class="{{ $adminListFilterInputClass }}">
|
||||
<option value="">所有状态</option>
|
||||
@foreach ($statusConfig as $key => $config)
|
||||
<option value="{{ $key }}">{{ $config['icon'] }} {{ $config['label'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@if ($currentType || $currentStatus)
|
||||
<a href="{{ route('admin.feedback.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
✕ 清除筛选
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 反馈列表 --}}
|
||||
@@ -180,7 +189,7 @@
|
||||
|
||||
{{-- 分页 --}}
|
||||
@if ($feedbacks->hasPages())
|
||||
<div class="mt-6">
|
||||
<div class="{{ $adminListPaginationClass }} mt-6">
|
||||
{{ $feedbacks->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
@section('title', '钓鱼事件管理')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
@php
|
||||
$fishingEventPayload = $events->mapWithKeys(
|
||||
fn($event) => [
|
||||
@@ -25,59 +27,62 @@
|
||||
|
||||
<script type="application/json" id="admin-fishing-events-data">@json($fishingEventPayload)</script>
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🎣 钓鱼事件管理</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
管理钓鱼随机事件。权重越大被触发概率越高。
|
||||
当前激活事件总权重:<strong class="text-indigo-600">{{ $totalWeight }}</strong>
|
||||
</p>
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎣 钓鱼事件管理</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
管理钓鱼随机事件。权重越大被触发概率越高。
|
||||
当前激活事件总权重:<strong class="text-indigo-600">{{ $totalWeight }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="{{ $adminListSecondaryButtonClass }} inline-flex items-center justify-center">
|
||||
⚙️ 钓鱼参数设置
|
||||
</a>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
⚙️ 钓鱼参数设置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 钓鱼事件列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">排序</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">符号</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">名称</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase w-1/3">播报内容</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">经验</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">金币</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">权重</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">概率</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">状态</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">操作</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">排序</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">符号</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">名称</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-1/3">播报内容</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">经验</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">金币</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">权重</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">概率</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@foreach ($events as $event)
|
||||
<tr id="row-{{ $event->id }}" class="{{ $event->is_active ? '' : 'opacity-50' }}">
|
||||
<td class="px-4 py-3 text-gray-500 text-xs">{{ $event->sort }}</td>
|
||||
<tr id="row-{{ $event->id }}" class="{{ $adminListTableRowClass }} {{ $event->is_active ? '' : 'opacity-50' }}">
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">{{ $event->sort }}</td>
|
||||
<td class="px-4 py-3 text-xl">{{ $event->emoji }}</td>
|
||||
<td class="px-4 py-3 font-medium text-gray-800">{{ $event->name }}</td>
|
||||
<td class="px-4 py-3 text-gray-500 text-xs">{{ $event->message }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $event->name }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">{{ $event->message }}</td>
|
||||
<td
|
||||
class="px-4 py-3 text-center font-mono text-xs
|
||||
class="px-4 py-3 text-center {{ $adminListNumericTextClass }}
|
||||
{{ $event->exp > 0 ? 'text-green-600' : ($event->exp < 0 ? 'text-red-500' : 'text-gray-400') }}">
|
||||
{{ $event->exp > 0 ? '+' : '' }}{{ $event->exp }}
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-center font-mono text-xs
|
||||
class="px-4 py-3 text-center {{ $adminListNumericTextClass }}
|
||||
{{ $event->jjb > 0 ? 'text-amber-600' : ($event->jjb < 0 ? 'text-red-500' : 'text-gray-400') }}">
|
||||
{{ $event->jjb > 0 ? '+' : '' }}{{ $event->jjb }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-xs text-indigo-600 font-bold">{{ $event->weight }}</td>
|
||||
<td class="px-4 py-3 text-center text-xs text-gray-500">
|
||||
<td class="px-4 py-3 text-center text-indigo-600 {{ $adminListNumericTextClass }} font-bold">{{ $event->weight }}</td>
|
||||
<td class="px-4 py-3 text-center {{ $adminListBodyTextClass }}">
|
||||
@if ($totalWeight > 0 && $event->is_active)
|
||||
{{ number_format(($event->weight / $totalWeight) * 100, 1) }}%
|
||||
@else
|
||||
@@ -87,78 +92,78 @@
|
||||
<td class="px-4 py-3 text-center">
|
||||
<button type="button" data-fishing-toggle-id="{{ $event->id }}"
|
||||
id="toggle-{{ $event->id }}"
|
||||
class="px-2 py-1 rounded-full text-xs font-bold transition
|
||||
{{ $event->is_active ? 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200' : 'bg-gray-100 text-gray-500 hover:bg-gray-200' }}">
|
||||
class="{{ $adminListBadgeBaseClass }} px-2 py-1 transition
|
||||
{{ $event->is_active ? 'border-emerald-200 bg-emerald-100 text-emerald-700 hover:bg-emerald-200' : 'border-gray-200 bg-gray-100 text-gray-500 hover:bg-gray-200' }}">
|
||||
{{ $event->is_active ? '启用' : '禁用' }}
|
||||
</button>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<button type="button" data-fishing-edit-id="{{ $event->id }}"
|
||||
class="px-3 py-1 bg-indigo-50 text-indigo-700 rounded text-xs font-bold hover:bg-indigo-100 transition mr-1">
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-50 text-indigo-700 hover:bg-indigo-100 mr-1">
|
||||
编辑
|
||||
</button>
|
||||
<form action="{{ route('admin.fishing.destroy', $event->id) }}" method="POST"
|
||||
class="inline" data-fishing-delete-confirm="确定删除事件「{{ $event->name }}」?">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit"
|
||||
class="px-3 py-1 bg-red-50 text-red-600 rounded text-xs font-bold hover:bg-red-100 transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-red-50 text-red-600 hover:bg-red-100">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 新增事件卡片 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<div class="p-5 border-b border-gray-100 bg-gray-50">
|
||||
<h3 class="font-bold text-gray-700 text-sm">➕ 新增钓鱼事件</h3>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">➕ 新增钓鱼事件</h3>
|
||||
</div>
|
||||
<form action="{{ route('admin.fishing.store') }}" method="POST" class="p-5">
|
||||
@csrf
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">Emoji 符号</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">Emoji 符号</label>
|
||||
<input type="text" name="emoji" value="{{ old('emoji') }}" placeholder="🐟" required
|
||||
class="w-full border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">名称</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">名称</label>
|
||||
<input type="text" name="name" value="{{ old('name') }}" placeholder="小鲤鱼" required
|
||||
class="w-full border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">经验变化</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">经验变化</label>
|
||||
<input type="number" name="exp" value="{{ old('exp', 0) }}"
|
||||
class="w-full border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">金币变化</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">金币变化</label>
|
||||
<input type="number" name="jjb" value="{{ old('jjb', 0) }}"
|
||||
class="w-full border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div class="md:col-span-2">
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">播报内容</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">播报内容</label>
|
||||
<input type="text" name="message" value="{{ old('message') }}" placeholder="钓到一条小鲤鱼..." required
|
||||
class="w-full border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">权重(概率)</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">权重(概率)</label>
|
||||
<input type="number" name="weight" value="{{ old('weight', 10) }}" min="1"
|
||||
class="w-full border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">排序</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">排序</label>
|
||||
<input type="number" name="sort" value="{{ old('sort', 0) }}" min="0"
|
||||
class="w-full border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 flex items-center gap-4">
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm shadow-sm">
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">
|
||||
💾 添加事件
|
||||
</button>
|
||||
<label class="flex items-center gap-2 text-sm text-gray-600 cursor-pointer">
|
||||
@@ -224,12 +229,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 flex gap-3">
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm">
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">
|
||||
💾 保存修改
|
||||
</button>
|
||||
<button type="button" data-fishing-edit-close
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg font-bold hover:bg-gray-200 transition text-sm">
|
||||
class="{{ $adminListSecondaryButtonClass }}">
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -11,20 +11,19 @@
|
||||
@section('title', '禁用用户名管理')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 标题 --}}
|
||||
<div class="flex items-start justify-between mb-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-gray-800">🚫 禁用用户名管理</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">
|
||||
以下词语永久禁止注册或改名使用(领导人名称、攻击性词汇、违禁词等)。
|
||||
临时保留的旧昵称(改名后30天)不在此列表中显示。
|
||||
</p>
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🚫 禁用用户名管理</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
以下词语永久禁止注册或改名使用。临时保留的旧昵称(改名后 30 天)不在此列表中显示。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 新增表单 + 搜索栏 --}}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6" x-data="{
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2" x-data="{
|
||||
tab: 'single',
|
||||
username: '',
|
||||
words: '',
|
||||
@@ -76,107 +75,112 @@
|
||||
}
|
||||
}">
|
||||
|
||||
{{-- 新增卡片(单个 + 批量 Tab) --}}
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm p-5">
|
||||
{{-- Tab 切换 --}}
|
||||
<div class="flex border-b border-gray-200 mb-4 -mx-5 px-5 gap-1">
|
||||
<button @click="tab='single'; msg=''"
|
||||
:class="tab === 'single' ? 'border-b-2 border-indigo-600 text-indigo-700 font-bold' :
|
||||
'text-gray-500 hover:text-gray-700'"
|
||||
class="pb-2 text-sm px-1 transition">➕ 单个添加</button>
|
||||
<button @click="tab='batch'; msg=''"
|
||||
:class="tab === 'batch' ? 'border-b-2 border-indigo-600 text-indigo-700 font-bold' :
|
||||
'text-gray-500 hover:text-gray-700'"
|
||||
class="pb-2 text-sm px-1 transition">📋 批量添加</button>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
{{-- 单个模式 --}}
|
||||
<div x-show="tab==='single'">
|
||||
<label class="text-xs text-gray-500 mb-1 block">禁用词 <span class="text-red-500">*</span></label>
|
||||
<input x-model="username" type="text" maxlength="50" placeholder="如:admin、习近平、fuck…"
|
||||
@keydown.enter="addSingle()"
|
||||
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-400 outline-none">
|
||||
<div class="{{ $adminListCardClass }} p-5">
|
||||
{{-- Tab 切换 --}}
|
||||
<div class="mb-4 -mx-5 flex gap-1 border-b border-gray-200 px-5">
|
||||
<button @click="tab='single'; msg=''"
|
||||
:class="tab === 'single' ? 'border-b-2 border-indigo-600 text-indigo-700 font-bold' :
|
||||
'text-gray-500 hover:text-gray-700'"
|
||||
class="px-1 pb-2 text-sm transition">➕ 单个添加</button>
|
||||
<button @click="tab='batch'; msg=''"
|
||||
:class="tab === 'batch' ? 'border-b-2 border-indigo-600 text-indigo-700 font-bold' :
|
||||
'text-gray-500 hover:text-gray-700'"
|
||||
class="px-1 pb-2 text-sm transition">📋 批量添加</button>
|
||||
</div>
|
||||
|
||||
{{-- 批量模式 --}}
|
||||
<div x-show="tab==='batch'">
|
||||
<label class="text-xs text-gray-500 mb-1 block">
|
||||
批量词语 <span class="text-red-500">*</span>
|
||||
<span class="text-gray-400 font-normal">(每行一个,或用逗号/空格分隔)</span>
|
||||
</label>
|
||||
<textarea x-model="words" rows="6" maxlength="5000"
|
||||
placeholder="admin root fuck 操,草,傻 …(每行一个或逗号分隔)"
|
||||
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-400 outline-none resize-y font-mono"></textarea>
|
||||
<p class="text-xs text-gray-400 mt-1">
|
||||
自动去重,跳过已存在的词语,超过50字符的词语忽略
|
||||
</p>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
{{-- 单个模式 --}}
|
||||
<div x-show="tab==='single'">
|
||||
<label class="{{ $adminListFilterLabelClass }}">禁用词 <span class="text-red-500">*</span></label>
|
||||
<input x-model="username" type="text" maxlength="50" placeholder="如:admin、习近平、fuck…"
|
||||
@keydown.enter="addSingle()"
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
|
||||
{{-- 共用原因 --}}
|
||||
<div>
|
||||
<label class="text-xs text-gray-500 mb-1 block">禁用原因(选填)</label>
|
||||
<input x-model="reason" type="text" maxlength="100" placeholder="如:国家领导人姓名 / 攻击性词汇"
|
||||
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-400 outline-none">
|
||||
</div>
|
||||
{{-- 批量模式 --}}
|
||||
<div x-show="tab==='batch'">
|
||||
<label class="{{ $adminListFilterLabelClass }}">
|
||||
批量词语 <span class="text-red-500">*</span>
|
||||
<span class="text-gray-400 font-normal">(每行一个,或用逗号/空格分隔)</span>
|
||||
</label>
|
||||
<textarea x-model="words" rows="6" maxlength="5000"
|
||||
placeholder="admin root fuck 操,草,傻 …(每行一个或逗号分隔)"
|
||||
class="w-full resize-y font-mono {{ $adminListFilterInputClass }}"></textarea>
|
||||
<p class="mt-1 text-xs text-gray-400">
|
||||
自动去重,跳过已存在的词语,超过50字符的词语忽略
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- 提交按钮 --}}
|
||||
<button x-show="tab==='single'" @click="addSingle()" :disabled="saving || !username.trim()"
|
||||
class="w-full bg-indigo-600 hover:bg-indigo-700 disabled:opacity-40 text-white rounded-lg px-4 py-2 text-sm font-bold transition">
|
||||
<span x-text="saving ? '添加中…' : '➕ 添加到禁用列表'"></span>
|
||||
</button>
|
||||
<button x-show="tab==='batch'" @click="addBatch()" :disabled="saving || !words.trim()"
|
||||
class="w-full bg-indigo-600 hover:bg-indigo-700 disabled:opacity-40 text-white rounded-lg px-4 py-2 text-sm font-bold transition">
|
||||
<span x-text="saving ? '处理中…' : '📋 批量添加到禁用列表'"></span>
|
||||
</button>
|
||||
{{-- 共用原因 --}}
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">禁用原因(选填)</label>
|
||||
<input x-model="reason" type="text" maxlength="100" placeholder="如:国家领导人姓名 / 攻击性词汇"
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
|
||||
<p x-show="msg" x-text="msg" :class="msgOk ? 'text-green-600' : 'text-red-500'"
|
||||
class="text-xs font-bold"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 搜索卡片 --}}
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm p-5">
|
||||
<h3 class="font-bold text-gray-700 text-sm mb-3">🔍 搜索禁用词</h3>
|
||||
<form method="GET" action="{{ route('admin.forbidden-usernames.index') }}" class="space-y-3">
|
||||
<input type="text" name="q" value="{{ $q }}" placeholder="输入关键词搜索…"
|
||||
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-400 outline-none">
|
||||
<div class="flex gap-2">
|
||||
<button type="submit"
|
||||
class="flex-1 bg-gray-600 hover:bg-gray-700 text-white rounded-lg px-4 py-2 text-sm font-bold transition">
|
||||
搜索
|
||||
{{-- 提交按钮 --}}
|
||||
<button x-show="tab==='single'" @click="addSingle()" :disabled="saving || !username.trim()"
|
||||
class="w-full rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-indigo-700 disabled:opacity-40">
|
||||
<span x-text="saving ? '添加中…' : '➕ 添加到禁用列表'"></span>
|
||||
</button>
|
||||
<button x-show="tab==='batch'" @click="addBatch()" :disabled="saving || !words.trim()"
|
||||
class="w-full rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-indigo-700 disabled:opacity-40">
|
||||
<span x-text="saving ? '处理中…' : '📋 批量添加到禁用列表'"></span>
|
||||
</button>
|
||||
@if ($q)
|
||||
<a href="{{ route('admin.forbidden-usernames.index') }}"
|
||||
class="px-4 py-2 text-sm text-gray-500 border border-gray-300 rounded-lg hover:bg-gray-50 transition">
|
||||
✕ 清除
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</form>
|
||||
<p class="text-xs text-gray-400 mt-3">
|
||||
共 <strong>{{ $items->total() }}</strong> 条永久禁用词
|
||||
@if ($q)
|
||||
(当前筛选"{{ $q }}")
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 禁用词列表 --}}
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-200">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">词语</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">禁用原因</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">添加时间</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($items as $item)
|
||||
<tr x-data="{
|
||||
<p x-show="msg" x-text="msg" :class="msgOk ? 'text-green-600' : 'text-red-500'"
|
||||
class="text-xs font-bold"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="{{ $adminListCardClass }} p-5">
|
||||
<h3 class="{{ $adminListSectionTitleClass }} mb-3">🔍 搜索禁用词</h3>
|
||||
<form method="GET" action="{{ route('admin.forbidden-usernames.index') }}" class="space-y-3">
|
||||
<input type="text" name="q" value="{{ $q }}" placeholder="输入关键词搜索…"
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
<div class="flex gap-2">
|
||||
<button type="submit"
|
||||
class="flex-1 rounded-lg bg-gray-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-gray-700">
|
||||
搜索
|
||||
</button>
|
||||
@if ($q)
|
||||
<a href="{{ route('admin.forbidden-usernames.index') }}"
|
||||
class="{{ $adminListSecondaryButtonClass }}">
|
||||
✕ 清除
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</form>
|
||||
<p class="mt-3 text-xs text-gray-400">
|
||||
共 <strong>{{ $items->total() }}</strong> 条永久禁用词
|
||||
@if ($q)
|
||||
(当前筛选"{{ $q }}")
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div>
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">禁用词列表</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">表格、按钮与分页统一到用户管理页风格,保留高风险词的红色提示。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">词语</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">禁用原因</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">添加时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($items as $item)
|
||||
<tr x-data="{
|
||||
editing: false,
|
||||
reason: @js($item->reason ?? ''),
|
||||
saving: false,
|
||||
@@ -209,11 +213,11 @@
|
||||
});
|
||||
location.reload();
|
||||
}
|
||||
}" class="hover:bg-gray-50 transition">
|
||||
}" class="{{ $adminListTableRowClass }}">
|
||||
{{-- 词语 --}}
|
||||
<td class="px-4 py-3">
|
||||
<span
|
||||
class="font-mono font-bold text-gray-800 bg-red-50 border border-red-200 px-2 py-0.5 rounded text-xs">
|
||||
class="inline-flex items-center rounded-full border border-red-200 bg-red-50 px-2 py-0.5 text-xs font-semibold text-gray-800">
|
||||
{{ $item->username }}
|
||||
</span>
|
||||
</td>
|
||||
@@ -224,9 +228,9 @@
|
||||
<div x-show="editing" class="flex items-center gap-2">
|
||||
<input x-model="reason" type="text" maxlength="100" @keydown.enter="saveReason()"
|
||||
@keydown.escape="editing = false"
|
||||
class="border border-indigo-300 rounded px-2 py-1 text-xs focus:ring-1 focus:ring-indigo-400 outline-none w-48">
|
||||
class="w-48 rounded border border-indigo-300 px-2 py-1 text-xs outline-none focus:ring-1 focus:ring-indigo-400">
|
||||
<button @click="saveReason()" :disabled="saving"
|
||||
class="text-xs bg-indigo-600 text-white rounded px-2 py-1 hover:bg-indigo-700 disabled:opacity-50">
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-600 text-white hover:bg-indigo-700 disabled:opacity-50">
|
||||
<span x-text="saving ? '…' : '保存'"></span>
|
||||
</button>
|
||||
<button @click="editing = false"
|
||||
@@ -240,29 +244,30 @@
|
||||
{{-- 操作 --}}
|
||||
<td class="px-4 py-3 text-center">
|
||||
<button @click="destroy()"
|
||||
class="text-xs text-red-600 hover:text-red-800 border border-red-200 hover:border-red-400 rounded px-3 py-1 transition">
|
||||
class="{{ $adminListActionButtonClass }} border border-red-200 text-red-600 hover:border-red-400 hover:bg-red-50">
|
||||
🗑 删除
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="4" class="py-16 text-center text-gray-400">
|
||||
<td colspan="4" class="{{ $adminListEmptyClass }}">
|
||||
<p class="text-3xl mb-2">🚫</p>
|
||||
<p class="font-bold">暂无禁用词</p>
|
||||
<p class="text-xs mt-1">使用左侧表单添加第一条禁用词</p>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($items->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $items->links() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 分页 --}}
|
||||
@if ($items->hasPages())
|
||||
<div class="mt-6">
|
||||
{{ $items->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -3,110 +3,113 @@
|
||||
@section('title', "百家乐第 #{$round->id} 局下注明细")
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🎲 百家乐 #{{ $round->id }} 局下注明细</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎲 百家乐 #{{ $round->id }} 局下注明细</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
结算时间:{{ $round->settled_at?->format('Y-m-d H:i:s') ?? '未结算' }}
|
||||
· 结果:
|
||||
<span class="font-bold text-indigo-600">{{ $round->resultLabel() }}</span>
|
||||
· 总点数:<span class="font-bold">{{ $round->total_points }}</span>
|
||||
· 结果:<span class="font-semibold text-indigo-600">{{ $round->resultLabel() }}</span>
|
||||
· 总点数:<span class="font-semibold text-gray-700">{{ $round->total_points }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-history.baccarat') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-history.baccarat') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
← 返回历史列表
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 本局摘要 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($round->bet_count ?? 0) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">参与下注人数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">参与下注人数</div>
|
||||
</div>
|
||||
<div class="bg-red-50 rounded-xl shadow-sm border border-red-100 p-5">
|
||||
<div class="rounded-xl border border-red-100 bg-red-50 p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-red-600">{{ number_format($round->total_bet_big ?? 0) }}</div>
|
||||
<div class="text-xs text-red-400 mt-1">押大总金额</div>
|
||||
<div class="mt-1 text-xs text-red-400">押大总金额</div>
|
||||
</div>
|
||||
<div class="bg-blue-50 rounded-xl shadow-sm border border-blue-100 p-5">
|
||||
<div class="rounded-xl border border-blue-100 bg-blue-50 p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-blue-600">{{ number_format($round->total_bet_small ?? 0) }}</div>
|
||||
<div class="text-xs text-blue-400 mt-1">押小总金额</div>
|
||||
<div class="mt-1 text-xs text-blue-400">押小总金额</div>
|
||||
</div>
|
||||
<div class="bg-amber-50 rounded-xl shadow-sm border border-amber-100 p-5">
|
||||
<div class="rounded-xl border border-amber-100 bg-amber-50 p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($round->total_payout ?? 0) }}</div>
|
||||
<div class="text-xs text-amber-400 mt-1">本局派奖总额</div>
|
||||
<div class="mt-1 text-xs text-amber-400">本局派奖总额</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 下注明细表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">玩家</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">押注方向</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">押注金额</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">实际获得</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">是否中奖</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">下注时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($bets as $bet)
|
||||
@php
|
||||
$betLabels = ['big' => '大', 'small' => '小', 'triple' => '豹子'];
|
||||
$betColors = [
|
||||
'big' => 'bg-red-100 text-red-700',
|
||||
'small' => 'bg-blue-100 text-blue-700',
|
||||
'triple' => 'bg-purple-100 text-purple-700',
|
||||
];
|
||||
$won = $bet->payout > 0;
|
||||
@endphp
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 font-medium text-gray-800">
|
||||
{{ $bet->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold {{ $betColors[$bet->bet_type] ?? 'bg-gray-100 text-gray-600' }}">
|
||||
{{ $betLabels[$bet->bet_type] ?? $bet->bet_type }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-sm text-gray-700">
|
||||
{{ number_format($bet->amount) }}
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-right font-mono text-sm {{ $won ? 'text-emerald-600 font-bold' : 'text-gray-400' }}">
|
||||
{{ $won ? '+' . number_format($bet->payout) : '0' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($won)
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-emerald-100 text-emerald-700">🎉
|
||||
中奖</span>
|
||||
@else
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-gray-100 text-gray-500">未中</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right text-xs text-gray-400">
|
||||
{{ $bet->created_at->format('H:i:s') }}
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">下注明细</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">保留原有大小单双与中奖状态颜色,统一列表结构与空态层级。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">玩家</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">押注方向</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">押注金额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">实际获得</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">是否中奖</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">下注时间</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="px-4 py-10 text-center text-gray-400 text-sm">本局无人下注</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($bets as $bet)
|
||||
@php
|
||||
$betLabels = ['big' => '大', 'small' => '小', 'triple' => '豹子'];
|
||||
$betColors = [
|
||||
'big' => 'bg-red-100 text-red-700 border-red-200',
|
||||
'small' => 'bg-blue-100 text-blue-700 border-blue-200',
|
||||
'triple' => 'bg-purple-100 text-purple-700 border-purple-200',
|
||||
];
|
||||
$won = $bet->payout > 0;
|
||||
@endphp
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }}">
|
||||
{{ $bet->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
<span class="{{ $badgeClass }} {{ $betColors[$bet->bet_type] ?? 'bg-gray-100 text-gray-600 border-gray-200' }}">
|
||||
{{ $betLabels[$bet->bet_type] ?? $bet->bet_type }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} text-gray-700">
|
||||
{{ number_format($bet->amount) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} {{ $won ? 'font-semibold text-emerald-600' : 'text-gray-400' }}">
|
||||
{{ $won ? '+' . number_format($bet->payout) : '0' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($won)
|
||||
<span class="{{ $badgeClass }} bg-emerald-100 text-emerald-700 border-emerald-200">🎉 中奖</span>
|
||||
@else
|
||||
<span class="{{ $badgeClass }} bg-gray-100 text-gray-500 border-gray-200">未中</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListSecondaryTextClass }}">
|
||||
{{ $bet->created_at->format('H:i:s') }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="{{ $adminListEmptyClass }}">本局无人下注</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($bets->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $bets->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,43 +3,46 @@
|
||||
@section('title', '百家乐历史记录')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🎲 百家乐历史记录</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">查询所有已结算的百家乐局次及下注明细。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎲 百家乐历史记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查询所有已结算的百家乐局次及下注明细。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-configs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
⚙️ 游戏配置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 统计卡片 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-5 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($summary['total_rounds']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史总局数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史总局数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($summary['total_bets']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史总下注次</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史总下注次</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-emerald-600">{{ number_format($summary['total_payout']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">累计派奖金币</div>
|
||||
<div class="mt-1 text-xs text-gray-500">累计派奖金币</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-red-100 p-5">
|
||||
<div class="rounded-xl border border-red-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-red-600">{{ number_format($summary['total_lost']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">会员输掉金币</div>
|
||||
<div class="mt-1 text-xs text-gray-500">会员输掉金币</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="text-sm font-bold text-gray-700 mb-2">结果分布</div>
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="mb-2 text-sm font-bold text-gray-700">结果分布</div>
|
||||
<div class="space-y-1">
|
||||
@foreach (['big' => '大', 'small' => '小', 'triple' => '豹子', 'kill' => '收割'] as $key => $label)
|
||||
<div class="flex justify-between text-xs">
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-gray-500">{{ $label }}</span>
|
||||
<span class="font-bold text-gray-700">{{ $summary['result_dist'][$key] ?? 0 }} 局</span>
|
||||
</div>
|
||||
@@ -48,93 +51,96 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 局次列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">局次ID</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">结算时间</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">骰子</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">点数</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">结果</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">押注笔数</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">押大/小/豹</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">派奖金币</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($rounds as $round)
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 text-gray-400 text-xs font-mono">#{{ $round->id }}</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-600">
|
||||
{{ $round->settled_at ? $round->settled_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-lg">
|
||||
@if ($round->dice1)
|
||||
{{ $round->dice1 }} {{ $round->dice2 }} {{ $round->dice3 }}
|
||||
@else
|
||||
—
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-bold text-gray-700">
|
||||
{{ $round->total_points ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@php
|
||||
$resultColors = [
|
||||
'big' => 'bg-red-100 text-red-700',
|
||||
'small' => 'bg-blue-100 text-blue-700',
|
||||
'triple' => 'bg-purple-100 text-purple-700',
|
||||
'kill' => 'bg-gray-100 text-gray-600',
|
||||
];
|
||||
$label = match ($round->result) {
|
||||
'big' => '大',
|
||||
'small' => '小',
|
||||
'triple' => '豹子',
|
||||
'kill' => '收割',
|
||||
default => $round->result ?? '—',
|
||||
};
|
||||
$colorClass = $resultColors[$round->result] ?? 'bg-gray-100 text-gray-600';
|
||||
@endphp
|
||||
@if ($round->result)
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-bold {{ $colorClass }}">
|
||||
{{ $label }}
|
||||
</span>
|
||||
@else
|
||||
<span class="text-gray-400 text-xs">未结算</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-xs font-bold text-indigo-600">
|
||||
{{ number_format($round->bet_count ?? 0) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right text-xs text-gray-500 font-mono">
|
||||
<span class="text-red-500">{{ number_format($round->total_bet_big ?? 0) }}</span> /
|
||||
<span class="text-blue-500">{{ number_format($round->total_bet_small ?? 0) }}</span> /
|
||||
<span class="text-purple-500">{{ number_format($round->total_bet_triple ?? 0) }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-xs text-amber-600 font-bold">
|
||||
{{ number_format($round->total_payout ?? 0) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<a href="{{ route('admin.game-history.baccarat.round', $round->id) }}"
|
||||
class="px-3 py-1 bg-indigo-50 text-indigo-700 rounded text-xs font-bold hover:bg-indigo-100 transition">
|
||||
下注明细
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-4 py-10 text-center text-gray-400 text-sm">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">局次列表</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一展示结算结果、投注分布与派奖数据。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">局次ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">结算时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">骰子</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">点数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">结果</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">押注笔数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">押大/小/豹</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">派奖金币</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($rounds as $round)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListSecondaryTextClass }} font-mono">#{{ $round->id }}</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListBodyTextClass }}">
|
||||
{{ $round->settled_at ? $round->settled_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center text-lg">
|
||||
@if ($round->dice1)
|
||||
{{ $round->dice1 }} {{ $round->dice2 }} {{ $round->dice3 }}
|
||||
@else
|
||||
—
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center {{ $adminListPrimaryTextClass }}">
|
||||
{{ $round->total_points ?? '—' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@php
|
||||
$resultColors = [
|
||||
'big' => 'bg-red-100 text-red-700 border-red-200',
|
||||
'small' => 'bg-blue-100 text-blue-700 border-blue-200',
|
||||
'triple' => 'bg-purple-100 text-purple-700 border-purple-200',
|
||||
'kill' => 'bg-gray-100 text-gray-600 border-gray-200',
|
||||
];
|
||||
$label = match ($round->result) {
|
||||
'big' => '大',
|
||||
'small' => '小',
|
||||
'triple' => '豹子',
|
||||
'kill' => '收割',
|
||||
default => $round->result ?? '—',
|
||||
};
|
||||
$colorClass = $resultColors[$round->result] ?? 'bg-gray-100 text-gray-600 border-gray-200';
|
||||
@endphp
|
||||
@if ($round->result)
|
||||
<span class="{{ $badgeClass }} {{ $colorClass }}">{{ $label }}</span>
|
||||
@else
|
||||
<span class="{{ $adminListSecondaryTextClass }}">未结算</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center text-sm font-semibold text-indigo-600">
|
||||
{{ number_format($round->bet_count ?? 0) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} text-gray-500">
|
||||
<span class="text-red-500">{{ number_format($round->total_bet_big ?? 0) }}</span> /
|
||||
<span class="text-blue-500">{{ number_format($round->total_bet_small ?? 0) }}</span> /
|
||||
<span class="text-purple-500">{{ number_format($round->total_bet_triple ?? 0) }}</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} font-semibold text-amber-600">
|
||||
{{ number_format($round->total_payout ?? 0) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right">
|
||||
<a href="{{ route('admin.game-history.baccarat.round', $round->id) }}"
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-50 text-indigo-700 hover:bg-indigo-100">
|
||||
下注明细
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- 分页 --}}
|
||||
@if ($rounds->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $rounds->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,49 +3,49 @@
|
||||
@section('title', '神秘占卜历史记录')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
$gradeAll = [
|
||||
'jackpot' => ['label' => '上上签', 'color' => 'text-amber-600'],
|
||||
'good' => ['label' => '上签', 'color' => 'text-emerald-600'],
|
||||
'normal' => ['label' => '中签', 'color' => 'text-gray-500'],
|
||||
'bad' => ['label' => '下签', 'color' => 'text-orange-500'],
|
||||
'curse' => ['label' => '大凶签', 'color' => 'text-red-600'],
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🔮 神秘占卜历史记录</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">查询所有玩家的占卜记录,支持按等级和玩家名筛选。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🔮 神秘占卜历史记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查询所有玩家的占卜记录,支持按等级和玩家名筛选。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-configs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
⚙️ 游戏配置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 统计卡片 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($summary['total_times']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史总占卜次</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史总占卜次</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="text-2xl font-bold text-amber-500">{{ number_format($summary['grade_dist']['jackpot'] ?? 0) }}
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 mt-1">✨ 上上签次数</div>
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-amber-500">{{ number_format($summary['grade_dist']['jackpot'] ?? 0) }}</div>
|
||||
<div class="mt-1 text-xs text-gray-500">✨ 上上签次数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-red-500">{{ number_format($summary['grade_dist']['curse'] ?? 0) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">💀 大凶签次数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">💀 大凶签次数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="text-sm font-bold text-gray-700 mb-2">签文分布</div>
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="mb-2 text-sm font-bold text-gray-700">签文分布</div>
|
||||
<div class="space-y-1">
|
||||
@php
|
||||
$gradeAll = [
|
||||
'jackpot' => ['label' => '上上签', 'color' => 'text-amber-600'],
|
||||
'good' => ['label' => '上签', 'color' => 'text-emerald-600'],
|
||||
'normal' => ['label' => '中签', 'color' => 'text-gray-500'],
|
||||
'bad' => ['label' => '下签', 'color' => 'text-orange-500'],
|
||||
'curse' => ['label' => '大凶签', 'color' => 'text-red-600'],
|
||||
];
|
||||
@endphp
|
||||
@foreach ($gradeAll as $key => $meta)
|
||||
<div class="flex justify-between text-xs">
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="{{ $meta['color'] }}">{{ $meta['label'] }}</span>
|
||||
<span class="font-bold text-gray-700">{{ $summary['grade_dist'][$key] ?? 0 }}</span>
|
||||
</div>
|
||||
@@ -54,107 +54,100 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 筛选 --}}
|
||||
<form method="GET"
|
||||
class="bg-white rounded-xl shadow-sm border border-gray-100 p-4 flex flex-wrap items-end gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">签文等级</label>
|
||||
<select name="grade"
|
||||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:border-indigo-400 min-w-[130px]">
|
||||
<option value="">全部等级</option>
|
||||
@foreach ($gradeAll as $key => $meta)
|
||||
<option value="{{ $key }}" {{ request('grade') === $key ? 'selected' : '' }}>
|
||||
{{ $meta['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form method="GET" class="{{ $adminListFilterFormClass }}">
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">签文等级</label>
|
||||
<select name="grade" class="min-w-[130px] {{ $adminListFilterInputClass }}">
|
||||
<option value="">全部等级</option>
|
||||
@foreach ($gradeAll as $key => $meta)
|
||||
<option value="{{ $key }}" {{ request('grade') === $key ? 'selected' : '' }}>
|
||||
{{ $meta['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">玩家名称</label>
|
||||
<input type="text" name="username" value="{{ request('username') }}" placeholder="模糊搜索..."
|
||||
class="w-40 {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">筛选</button>
|
||||
<a href="{{ route('admin.game-history.fortune') }}" class="{{ $adminListSecondaryButtonClass }}">重置</a>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">玩家名称</label>
|
||||
<input type="text" name="username" value="{{ request('username') }}" placeholder="模糊搜索..."
|
||||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:border-indigo-400 w-40">
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm">
|
||||
🔍 筛选
|
||||
</button>
|
||||
<a href="{{ route('admin.game-history.fortune') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg font-bold hover:bg-gray-200 transition text-sm">
|
||||
重置
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- 记录列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">时间</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">玩家</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">签文等级</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase w-1/3">签文内容</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">加成/减益</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">是否免费</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">消耗金币</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($logs as $log)
|
||||
@php
|
||||
$gradeInfo = match ($log->grade) {
|
||||
'jackpot' => ['label' => '✨ 上上签', 'color' => 'bg-amber-100 text-amber-700'],
|
||||
'good' => ['label' => '🌸 上签', 'color' => 'bg-emerald-100 text-emerald-700'],
|
||||
'normal' => ['label' => '📜 中签', 'color' => 'bg-gray-100 text-gray-600'],
|
||||
'bad' => ['label' => '😞 下签', 'color' => 'bg-orange-100 text-orange-700'],
|
||||
'curse' => ['label' => '💀 大凶签', 'color' => 'bg-red-100 text-red-700'],
|
||||
default => ['label' => $log->grade, 'color' => 'bg-gray-100 text-gray-500'],
|
||||
};
|
||||
@endphp
|
||||
<tr
|
||||
class="hover:bg-gray-50 transition {{ in_array($log->grade, ['jackpot']) ? 'bg-amber-50/50' : (in_array($log->grade, ['curse']) ? 'bg-red-50/30' : '') }}">
|
||||
<td class="px-4 py-3 text-xs text-gray-400">
|
||||
{{ $log->created_at->format('m-d H:i') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 font-medium text-gray-800">
|
||||
{{ $log->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-bold {{ $gradeInfo['color'] }}">
|
||||
{{ $gradeInfo['label'] }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-600 leading-relaxed">
|
||||
{{ \Illuminate\Support\Str::limit($log->text, 50) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-500">
|
||||
{{ $log->buff_desc ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($log->is_free)
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-emerald-100 text-emerald-700">免费</span>
|
||||
@else
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-amber-100 text-amber-700">付费</span>
|
||||
@endif
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-right font-mono text-xs {{ $log->cost > 0 ? 'text-red-500' : 'text-gray-400' }}">
|
||||
{{ $log->cost > 0 ? '-' . number_format($log->cost) : '0' }}
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">占卜记录</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一表格与筛选层级,保留签文等级、免费状态和消耗配色。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">玩家</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">签文等级</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-1/3">签文内容</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">加成/减益</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">是否免费</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">消耗金币</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-10 text-center text-gray-400 text-sm">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($logs as $log)
|
||||
@php
|
||||
$gradeInfo = match ($log->grade) {
|
||||
'jackpot' => ['label' => '✨ 上上签', 'color' => 'bg-amber-100 text-amber-700 border-amber-200'],
|
||||
'good' => ['label' => '🌸 上签', 'color' => 'bg-emerald-100 text-emerald-700 border-emerald-200'],
|
||||
'normal' => ['label' => '📜 中签', 'color' => 'bg-gray-100 text-gray-600 border-gray-200'],
|
||||
'bad' => ['label' => '😞 下签', 'color' => 'bg-orange-100 text-orange-700 border-orange-200'],
|
||||
'curse' => ['label' => '💀 大凶签', 'color' => 'bg-red-100 text-red-700 border-red-200'],
|
||||
default => ['label' => $log->grade, 'color' => 'bg-gray-100 text-gray-500 border-gray-200'],
|
||||
};
|
||||
@endphp
|
||||
<tr class="{{ $adminListTableRowClass }} {{ in_array($log->grade, ['jackpot']) ? 'bg-amber-50/50' : (in_array($log->grade, ['curse']) ? 'bg-red-50/30' : '') }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListSecondaryTextClass }}">
|
||||
{{ $log->created_at->format('m-d H:i') }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }}">
|
||||
{{ $log->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
<span class="{{ $badgeClass }} {{ $gradeInfo['color'] }}">{{ $gradeInfo['label'] }}</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-xs leading-relaxed text-gray-600">
|
||||
{{ \Illuminate\Support\Str::limit($log->text, 50) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-xs text-gray-500">
|
||||
{{ $log->buff_desc ?? '—' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($log->is_free)
|
||||
<span class="{{ $badgeClass }} border-emerald-200 bg-emerald-100 text-emerald-700">免费</span>
|
||||
@else
|
||||
<span class="{{ $badgeClass }} border-amber-200 bg-amber-100 text-amber-700">付费</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} {{ $log->cost > 0 ? 'text-red-500' : 'text-gray-400' }}">
|
||||
{{ $log->cost > 0 ? '-' . number_format($log->cost) : '0' }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($logs->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $logs->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,120 +3,122 @@
|
||||
@section('title', '五子棋对局记录')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">♟️ 五子棋历史记录</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">查询全站所有的五子棋人机及 PvP 对局。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">♟️ 五子棋历史记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查询全站所有的五子棋人机及 PvP 对局。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-configs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
⚙️ 游戏配置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 统计卡片 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($summary['total_games']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史对局数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史对局数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-emerald-600">{{ number_format($summary['completed']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">正常完赛</div>
|
||||
<div class="mt-1 text-xs text-gray-500">正常完赛</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($summary['pvp_count']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">PvP 人人对战数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">PvP 人人对战数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-rose-600">{{ number_format($summary['today_games']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">今日新建对局</div>
|
||||
<div class="mt-1 text-xs text-gray-500">今日新建对局</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 期数列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">赛事ID</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">创建时间</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">模式</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">黑方 (发起)</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">白方 (迎战)</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">状态</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">胜负</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($games as $game)
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 text-gray-600 text-xs font-mono font-bold">#{{ $game->id }}</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-600">
|
||||
{{ $game->created_at ? $game->created_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($game->mode === 'pve')
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-purple-100 text-purple-700">单机
|
||||
PvE(L{{ $game->ai_level }})</span>
|
||||
@else
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-blue-100 text-blue-700">在线
|
||||
PvP</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-bold">
|
||||
{{ $game->playerBlack?->username ?? '已注销/未知' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-bold">
|
||||
@if ($game->mode === 'pve')
|
||||
<span class="text-xs text-gray-400">AI 机器人</span>
|
||||
@else
|
||||
{{ $game->playerWhite?->username ?? '已注销/未加入' }}
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@php
|
||||
$s = match ($game->status) {
|
||||
'waiting' => ['label' => '等待中', 'bg' => 'bg-amber-100 text-amber-600'],
|
||||
'playing' => ['label' => '对弈中', 'bg' => 'bg-blue-100 text-blue-600'],
|
||||
'finished' => ['label' => '已结束', 'bg' => 'bg-emerald-100 text-emerald-700'],
|
||||
default => ['label' => $game->status, 'bg' => 'bg-gray-100 text-gray-600'],
|
||||
};
|
||||
@endphp
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold {{ $s['bg'] }}">{{ $s['label'] }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($game->status !== 'finished')
|
||||
<span class="text-xs text-gray-400">-</span>
|
||||
@else
|
||||
@if ($game->winner === 1)
|
||||
<span class="text-xs font-bold text-gray-800 bg-gray-200 px-2 py-1 rounded">⚫
|
||||
黑胜</span>
|
||||
@elseif($game->winner === 2)
|
||||
<span class="text-xs font-bold bg-white border border-gray-300 px-2 py-1 rounded">⚪
|
||||
白胜</span>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">对局列表</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一表格层次,保留 PvE/PvP、对局状态与胜负视觉语义。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">赛事ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">创建时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">模式</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">黑方 (发起)</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">白方 (迎战)</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">胜负</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($games as $game)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }} font-mono">#{{ $game->id }}</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListBodyTextClass }}">
|
||||
{{ $game->created_at ? $game->created_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($game->mode === 'pve')
|
||||
<span class="{{ $badgeClass }} border-purple-200 bg-purple-100 text-purple-700">单机 PvE(L{{ $game->ai_level }})</span>
|
||||
@else
|
||||
<span
|
||||
class="text-xs font-bold text-gray-500 bg-gray-100 px-2 py-1 rounded">平局撤销</span>
|
||||
<span class="{{ $badgeClass }} border-blue-200 bg-blue-100 text-blue-700">在线 PvP</span>
|
||||
@endif
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-10 text-center text-gray-400 text-sm">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center {{ $adminListPrimaryTextClass }}">
|
||||
{{ $game->playerBlack?->username ?? '已注销/未知' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center {{ $adminListPrimaryTextClass }}">
|
||||
@if ($game->mode === 'pve')
|
||||
<span class="{{ $adminListSecondaryTextClass }}">AI 机器人</span>
|
||||
@else
|
||||
{{ $game->playerWhite?->username ?? '已注销/未加入' }}
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@php
|
||||
$s = match ($game->status) {
|
||||
'waiting' => ['label' => '等待中', 'bg' => 'bg-amber-100 text-amber-600 border-amber-200'],
|
||||
'playing' => ['label' => '对弈中', 'bg' => 'bg-blue-100 text-blue-600 border-blue-200'],
|
||||
'finished' => ['label' => '已结束', 'bg' => 'bg-emerald-100 text-emerald-700 border-emerald-200'],
|
||||
default => ['label' => $game->status, 'bg' => 'bg-gray-100 text-gray-600 border-gray-200'],
|
||||
};
|
||||
@endphp
|
||||
<span class="{{ $badgeClass }} {{ $s['bg'] }}">{{ $s['label'] }}</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($game->status !== 'finished')
|
||||
<span class="{{ $adminListSecondaryTextClass }}">-</span>
|
||||
@else
|
||||
@if ($game->winner === 1)
|
||||
<span class="{{ $badgeClass }} border-gray-300 bg-gray-200 text-gray-800">⚫ 黑胜</span>
|
||||
@elseif ($game->winner === 2)
|
||||
<span class="{{ $badgeClass }} border-gray-300 bg-white text-gray-700">⚪ 白胜</span>
|
||||
@else
|
||||
<span class="{{ $badgeClass }} border-gray-200 bg-gray-100 text-gray-500">平局撤销</span>
|
||||
@endif
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($games->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $games->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,43 +3,44 @@
|
||||
@section('title', "赛马第 #{$race->id} 场下注明细")
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
@php
|
||||
$horses = $race->horses ?? [];
|
||||
$winner = collect($horses)->firstWhere('id', $race->winner_horse_id);
|
||||
@endphp
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$horses = $race->horses ?? [];
|
||||
$winner = collect($horses)->firstWhere('id', $race->winner_horse_id);
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🐎 赛马 #{{ $race->id }} 场下注明细</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🐎 赛马 #{{ $race->id }} 场下注明细</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
结算时间:{{ $race->settled_at?->format('Y-m-d H:i:s') ?? '未结算' }}
|
||||
@if ($winner)
|
||||
· 胜者:<span class="font-bold text-indigo-600">{{ $winner['emoji'] ?? '' }}
|
||||
{{ $winner['name'] ?? '' }}</span>
|
||||
· 胜者:<span class="font-semibold text-indigo-600">{{ $winner['emoji'] ?? '' }} {{ $winner['name'] ?? '' }}</span>
|
||||
@endif
|
||||
· 注池:<span class="font-bold text-amber-600">{{ number_format($race->total_pool ?? 0) }}
|
||||
金币</span>
|
||||
· 注池:<span class="font-semibold text-amber-600">{{ number_format($race->total_pool ?? 0) }} 金币</span>
|
||||
</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-history.horse') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-history.horse') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
← 返回场次列表
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 马匹信息 --}}
|
||||
@if (count($horses) > 0)
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="text-sm font-bold text-gray-700 mb-3">参赛马匹</div>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">参赛马匹</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">保留冠军高亮,仅统一容器与间距风格。</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-3 p-6">
|
||||
@foreach ($horses as $horse)
|
||||
<div
|
||||
class="px-4 py-2 rounded-lg {{ $horse['id'] === $race->winner_horse_id ? 'bg-amber-100 border-2 border-amber-400' : 'bg-gray-100' }}">
|
||||
class="rounded-lg border px-4 py-3 {{ $horse['id'] === $race->winner_horse_id ? 'border-amber-400 bg-amber-100' : 'border-gray-200 bg-gray-50' }}">
|
||||
<div class="text-lg">{{ $horse['emoji'] ?? '🐎' }}</div>
|
||||
<div
|
||||
class="text-xs font-bold {{ $horse['id'] === $race->winner_horse_id ? 'text-amber-700' : 'text-gray-600' }}">
|
||||
<div class="mt-1 text-xs font-bold {{ $horse['id'] === $race->winner_horse_id ? 'text-amber-700' : 'text-gray-600' }}">
|
||||
{{ $horse['name'] }}
|
||||
@if ($horse['id'] === $race->winner_horse_id)
|
||||
🏆
|
||||
@@ -51,71 +52,72 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- 下注明细表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">玩家</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">押注马匹</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">押注金额</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">实际获得</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">是否中奖</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">下注时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($bets as $bet)
|
||||
@php
|
||||
$betHorse = collect($horses)->firstWhere('id', $bet->horse_id);
|
||||
$isWinner = $bet->horse_id === $race->winner_horse_id;
|
||||
$won = ($bet->payout ?? 0) > 0;
|
||||
@endphp
|
||||
<tr class="hover:bg-gray-50 transition {{ $won ? 'bg-amber-50/50' : '' }}">
|
||||
<td class="px-4 py-3 font-medium text-gray-800">
|
||||
{{ $bet->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($betHorse)
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold {{ $isWinner ? 'bg-amber-100 text-amber-700' : 'bg-gray-100 text-gray-600' }}">
|
||||
{{ $betHorse['emoji'] ?? '' }} {{ $betHorse['name'] ?? '' }}
|
||||
</span>
|
||||
@else
|
||||
<span class="text-gray-400 text-xs">#{{ $bet->horse_id }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-sm text-gray-700">
|
||||
{{ number_format($bet->amount) }}
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-right font-mono text-sm {{ $won ? 'text-emerald-600 font-bold' : 'text-gray-400' }}">
|
||||
{{ $won ? '+' . number_format($bet->payout) : '0' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($won)
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-emerald-100 text-emerald-700">🎉
|
||||
中奖</span>
|
||||
@else
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-gray-100 text-gray-500">未中</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right text-xs text-gray-400">
|
||||
{{ $bet->created_at->format('H:i:s') }}
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">下注明细</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一下注列表样式,保留命中胜马与中奖状态颜色。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">玩家</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">押注马匹</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">押注金额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">实际获得</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">是否中奖</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">下注时间</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="px-4 py-10 text-center text-gray-400 text-sm">本场无人下注</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($bets as $bet)
|
||||
@php
|
||||
$betHorse = collect($horses)->firstWhere('id', $bet->horse_id);
|
||||
$isWinner = $bet->horse_id === $race->winner_horse_id;
|
||||
$won = ($bet->payout ?? 0) > 0;
|
||||
@endphp
|
||||
<tr class="{{ $adminListTableRowClass }} {{ $won ? 'bg-amber-50/50' : '' }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }}">
|
||||
{{ $bet->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($betHorse)
|
||||
<span class="{{ $badgeClass }} {{ $isWinner ? 'border-amber-200 bg-amber-100 text-amber-700' : 'border-gray-200 bg-gray-100 text-gray-600' }}">
|
||||
{{ $betHorse['emoji'] ?? '' }} {{ $betHorse['name'] ?? '' }}
|
||||
</span>
|
||||
@else
|
||||
<span class="{{ $adminListSecondaryTextClass }}">#{{ $bet->horse_id }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} text-gray-700">
|
||||
{{ number_format($bet->amount) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} {{ $won ? 'font-semibold text-emerald-600' : 'text-gray-400' }}">
|
||||
{{ $won ? '+' . number_format($bet->payout) : '0' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($won)
|
||||
<span class="{{ $badgeClass }} border-emerald-200 bg-emerald-100 text-emerald-700">🎉 中奖</span>
|
||||
@else
|
||||
<span class="{{ $badgeClass }} border-gray-200 bg-gray-100 text-gray-500">未中</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListSecondaryTextClass }}">
|
||||
{{ $bet->created_at->format('H:i:s') }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="{{ $adminListEmptyClass }}">本场无人下注</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($bets->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $bets->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,108 +3,115 @@
|
||||
@section('title', '赛马竞猜历史记录')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🐎 赛马竞猜历史记录</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">查询所有已完成的赛马场次及下注明细。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🐎 赛马竞猜历史记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查询所有已完成的赛马场次及下注明细。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-configs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
⚙️ 游戏配置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 统计卡片 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($summary['total_races']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史总场次</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史总场次</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($summary['total_bets']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史总下注笔</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史总下注笔</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-emerald-600">{{ number_format($summary['total_pool']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">累计注池金币</div>
|
||||
<div class="mt-1 text-xs text-gray-500">累计注池金币</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 场次列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">场次ID</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">结算时间</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">参赛马匹</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">胜者</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">状态</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">下注总笔</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">注池总额</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($races as $race)
|
||||
@php
|
||||
$horses = $race->horses ?? [];
|
||||
$winner = collect($horses)->firstWhere('id', $race->winner_horse_id);
|
||||
$statusLabel = match ($race->status) {
|
||||
'betting' => ['label' => '押注中', 'color' => 'bg-blue-100 text-blue-700'],
|
||||
'running' => ['label' => '比赛中', 'color' => 'bg-amber-100 text-amber-700'],
|
||||
'settled' => ['label' => '已结算', 'color' => 'bg-emerald-100 text-emerald-700'],
|
||||
'canceled' => ['label' => '已取消', 'color' => 'bg-red-100 text-red-600'],
|
||||
default => ['label' => $race->status, 'color' => 'bg-gray-100 text-gray-500'],
|
||||
};
|
||||
@endphp
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 text-gray-400 text-xs font-mono">#{{ $race->id }}</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-600">
|
||||
{{ $race->settled_at ? $race->settled_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-sm">
|
||||
{{ collect($horses)->pluck('emoji')->implode('') ?: '—' }}
|
||||
<span class="text-xs text-gray-400">({{ count($horses) }} 匹)</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-bold text-indigo-700">
|
||||
@if ($winner)
|
||||
{{ $winner['emoji'] ?? '' }} {{ $winner['name'] ?? '' }}
|
||||
@else
|
||||
<span class="text-gray-400">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-bold {{ $statusLabel['color'] }}">
|
||||
{{ $statusLabel['label'] }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-xs text-indigo-600 font-bold">
|
||||
{{ number_format($race->total_bets ?? 0) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-xs text-amber-600 font-bold">
|
||||
{{ number_format($race->total_pool ?? 0) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<a href="{{ route('admin.game-history.horse.race', $race->id) }}"
|
||||
class="px-3 py-1 bg-indigo-50 text-indigo-700 rounded text-xs font-bold hover:bg-indigo-100 transition">
|
||||
下注明细
|
||||
</a>
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">场次列表</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一表格层级,保留场次状态与胜者展示语义。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">场次ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">结算时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">参赛马匹</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">胜者</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">下注总笔</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">注池总额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="px-4 py-10 text-center text-gray-400 text-sm">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($races as $race)
|
||||
@php
|
||||
$horses = $race->horses ?? [];
|
||||
$winner = collect($horses)->firstWhere('id', $race->winner_horse_id);
|
||||
$statusLabel = match ($race->status) {
|
||||
'betting' => ['label' => '押注中', 'color' => 'bg-blue-100 text-blue-700 border-blue-200'],
|
||||
'running' => ['label' => '比赛中', 'color' => 'bg-amber-100 text-amber-700 border-amber-200'],
|
||||
'settled' => ['label' => '已结算', 'color' => 'bg-emerald-100 text-emerald-700 border-emerald-200'],
|
||||
'canceled' => ['label' => '已取消', 'color' => 'bg-red-100 text-red-600 border-red-200'],
|
||||
default => ['label' => $race->status, 'color' => 'bg-gray-100 text-gray-500 border-gray-200'],
|
||||
};
|
||||
@endphp
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListSecondaryTextClass }} font-mono">#{{ $race->id }}</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListBodyTextClass }}">
|
||||
{{ $race->settled_at ? $race->settled_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center {{ $adminListBodyTextClass }}">
|
||||
{{ collect($horses)->pluck('emoji')->implode('') ?: '—' }}
|
||||
<span class="{{ $adminListSecondaryTextClass }}">({{ count($horses) }} 匹)</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center font-semibold text-indigo-700">
|
||||
@if ($winner)
|
||||
{{ $winner['emoji'] ?? '' }} {{ $winner['name'] ?? '' }}
|
||||
@else
|
||||
<span class="{{ $adminListSecondaryTextClass }}">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
<span class="{{ $badgeClass }} {{ $statusLabel['color'] }}">{{ $statusLabel['label'] }}</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} font-semibold text-indigo-600">
|
||||
{{ number_format($race->total_bets ?? 0) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} font-semibold text-amber-600">
|
||||
{{ number_format($race->total_pool ?? 0) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right">
|
||||
<a href="{{ route('admin.game-history.horse.race', $race->id) }}"
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-50 text-indigo-700 hover:bg-indigo-100">
|
||||
下注明细
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($races->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $races->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,117 +3,111 @@
|
||||
@section('title', "双色球第 {$issue->issue_no} 期购买明细")
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🎟️ 双色球 第 {{ $issue->issue_no }} 期购买明细</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎟️ 双色球第 {{ $issue->issue_no }} 期购买明细</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
开奖时间:{{ $issue->draw_at?->format('Y-m-d H:i:s') ?? '未开奖' }}
|
||||
@if ($issue->status === 'settled')
|
||||
· 开奖号码:
|
||||
<span class="font-bold text-indigo-600">
|
||||
<span
|
||||
class="bg-red-100 text-red-600 px-1 rounded">{{ str_pad($issue->red1, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="bg-red-100 text-red-600 px-1 rounded">{{ str_pad($issue->red2, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="bg-red-100 text-red-600 px-1 rounded">{{ str_pad($issue->red3, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="bg-blue-100 text-blue-600 px-1 rounded">{{ str_pad($issue->blue, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="inline-flex items-center gap-1 font-semibold text-indigo-600">
|
||||
<span class="rounded border border-red-200 bg-red-100 px-1.5 py-0.5 text-red-600">{{ str_pad($issue->red1, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-red-200 bg-red-100 px-1.5 py-0.5 text-red-600">{{ str_pad($issue->red2, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-red-200 bg-red-100 px-1.5 py-0.5 text-red-600">{{ str_pad($issue->red3, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-blue-200 bg-blue-100 px-1.5 py-0.5 text-blue-600">{{ str_pad($issue->blue, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
</span>
|
||||
@endif
|
||||
· 奖池:<span class="font-bold text-amber-600">{{ number_format($issue->pool_amount ?? 0) }}
|
||||
金币</span>
|
||||
· 奖池:<span class="font-semibold text-amber-600">{{ number_format($issue->pool_amount ?? 0) }} 金币</span>
|
||||
</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-history.lottery') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-history.lottery') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
← 返回期号列表
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 购买明细表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">玩家</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">投注号码</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">彩票类型</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">花费</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">奖金获得</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">中奖等级</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">下注时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($tickets as $ticket)
|
||||
@php
|
||||
$won = ($ticket->payout ?? 0) > 0;
|
||||
@endphp
|
||||
<tr class="hover:bg-gray-50 transition {{ $won ? 'bg-amber-50/50' : '' }}">
|
||||
<td class="px-4 py-3 font-medium text-gray-800">
|
||||
{{ $ticket->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-mono">
|
||||
<div class="flex items-center justify-center gap-1 flex-wrap">
|
||||
<span
|
||||
class="text-xs bg-red-50 text-red-500 px-1 rounded shadow-sm border border-red-100">{{ str_pad($ticket->red1, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="text-xs bg-red-50 text-red-500 px-1 rounded shadow-sm border border-red-100">{{ str_pad($ticket->red2, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="text-xs bg-red-50 text-red-500 px-1 rounded shadow-sm border border-red-100">{{ str_pad($ticket->red3, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="text-xs bg-blue-50 text-blue-500 px-1 rounded shadow-sm border border-blue-100">{{ str_pad($ticket->blue, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($ticket->is_quick_pick)
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-purple-100 text-purple-700">随机机选</span>
|
||||
@else
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-blue-100 text-blue-700">自选号码</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-sm text-gray-700">
|
||||
{{ number_format($ticket->amount) }}
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-right font-mono text-sm {{ $won ? 'text-emerald-600 font-bold' : 'text-gray-400' }}">
|
||||
{{ $won ? '+' . number_format($ticket->payout) : '0' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($issue->status === 'settled')
|
||||
@if ($won)
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-amber-100 text-amber-700">
|
||||
🎉 {{ $ticket->prize_level }}等奖
|
||||
</span>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">购买明细</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一明细表格样式,保留号码球颜色、票种和中奖等级语义。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">玩家</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">投注号码</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">彩票类型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">花费</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">奖金获得</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">中奖等级</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">下注时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($tickets as $ticket)
|
||||
@php
|
||||
$won = ($ticket->payout ?? 0) > 0;
|
||||
@endphp
|
||||
<tr class="{{ $adminListTableRowClass }} {{ $won ? 'bg-amber-50/50' : '' }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }}">
|
||||
{{ $ticket->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center {{ $adminListNumericTextClass }}">
|
||||
<div class="flex flex-wrap items-center justify-center gap-1">
|
||||
<span class="rounded border border-red-100 bg-red-50 px-1.5 py-0.5 text-xs text-red-500">{{ str_pad($ticket->red1, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-red-100 bg-red-50 px-1.5 py-0.5 text-xs text-red-500">{{ str_pad($ticket->red2, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-red-100 bg-red-50 px-1.5 py-0.5 text-xs text-red-500">{{ str_pad($ticket->red3, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-blue-100 bg-blue-50 px-1.5 py-0.5 text-xs text-blue-500">{{ str_pad($ticket->blue, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($ticket->is_quick_pick)
|
||||
<span class="{{ $badgeClass }} border-purple-200 bg-purple-100 text-purple-700">随机机选</span>
|
||||
@else
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-gray-100 text-gray-500">未中奖</span>
|
||||
<span class="{{ $badgeClass }} border-blue-200 bg-blue-100 text-blue-700">自选号码</span>
|
||||
@endif
|
||||
@else
|
||||
<span class="text-xs text-gray-400">等待开奖</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right text-xs text-gray-400">
|
||||
{{ $ticket->created_at->format('H:i:s') }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-10 text-center text-gray-400 text-sm">本期暂无人购买</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} text-gray-700">
|
||||
{{ number_format($ticket->amount) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} {{ $won ? 'font-semibold text-emerald-600' : 'text-gray-400' }}">
|
||||
{{ $won ? '+' . number_format($ticket->payout) : '0' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($issue->status === 'settled')
|
||||
@if ($won)
|
||||
<span class="{{ $badgeClass }} border-amber-200 bg-amber-100 text-amber-700">🎉 {{ $ticket->prize_level }}等奖</span>
|
||||
@else
|
||||
<span class="{{ $badgeClass }} border-gray-200 bg-gray-100 text-gray-500">未中奖</span>
|
||||
@endif
|
||||
@else
|
||||
<span class="{{ $adminListSecondaryTextClass }}">等待开奖</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListSecondaryTextClass }}">
|
||||
{{ $ticket->created_at->format('H:i:s') }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">本期暂无人购买</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($tickets->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $tickets->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,109 +3,112 @@
|
||||
@section('title', '双色球彩票开奖记录')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🎟️ 双色球彩票历史记录</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">查询各期双色球的开奖结果及购买明细。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎟️ 双色球彩票历史记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查询各期双色球的开奖结果及购买明细。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-configs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
⚙️ 游戏配置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 统计卡片 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($summary['total_issues']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史总期数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史总期数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-emerald-600">{{ number_format($summary['drawn_count']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">已开奖期数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">已开奖期数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($summary['total_tickets']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史售出彩票</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史售出彩票</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-rose-600">{{ number_format($summary['total_pool']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史开奖总奖池</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史开奖总奖池</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 期数列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">期号</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">开奖时间</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">状态</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">开奖号码</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">售出票数</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">期奖池</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($issues as $issue)
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 text-gray-600 text-xs font-mono font-bold">第 {{ $issue->issue_no }} 期</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-600">
|
||||
{{ $issue->draw_at ? $issue->draw_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($issue->status === 'settled')
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-emerald-100 text-emerald-700">已开奖</span>
|
||||
@else
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold bg-amber-100 text-amber-700">销售中</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-mono">
|
||||
@if ($issue->status === 'settled')
|
||||
<div class="flex items-center justify-center gap-1">
|
||||
<span
|
||||
class="text-xs bg-red-100 text-red-600 px-1 rounded">{{ str_pad($issue->red1, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="text-xs bg-red-100 text-red-600 px-1 rounded">{{ str_pad($issue->red2, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="text-xs bg-red-100 text-red-600 px-1 rounded">{{ str_pad($issue->red3, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span
|
||||
class="text-xs bg-blue-100 text-blue-600 px-1 rounded">{{ str_pad($issue->blue, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
</div>
|
||||
@else
|
||||
<span class="text-xs text-gray-400">等待开奖</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-xs text-indigo-600 font-bold">
|
||||
{{ number_format($issue->total_tickets) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-xs text-amber-600 font-bold">
|
||||
{{ number_format($issue->pool_amount) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<a href="{{ route('admin.game-history.lottery.issue', $issue->id) }}"
|
||||
class="px-3 py-1 bg-indigo-50 text-indigo-700 rounded text-xs font-bold hover:bg-indigo-100 transition">
|
||||
购买明细
|
||||
</a>
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">期数列表</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一开奖记录列表结构,保留双色球号码配色和开奖状态语义。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">期号</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">开奖时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">开奖号码</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">售出票数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">期奖池</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-10 text-center text-gray-400 text-sm">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($issues as $issue)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }} font-mono">第 {{ $issue->issue_no }} 期</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListBodyTextClass }}">
|
||||
{{ $issue->draw_at ? $issue->draw_at->format('m-d H:i') : '—' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
@if ($issue->status === 'settled')
|
||||
<span class="{{ $badgeClass }} border-emerald-200 bg-emerald-100 text-emerald-700">已开奖</span>
|
||||
@else
|
||||
<span class="{{ $badgeClass }} border-amber-200 bg-amber-100 text-amber-700">销售中</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center {{ $adminListNumericTextClass }}">
|
||||
@if ($issue->status === 'settled')
|
||||
<div class="flex flex-wrap items-center justify-center gap-1">
|
||||
<span class="rounded border border-red-200 bg-red-100 px-1.5 py-0.5 text-xs text-red-600">{{ str_pad($issue->red1, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-red-200 bg-red-100 px-1.5 py-0.5 text-xs text-red-600">{{ str_pad($issue->red2, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-red-200 bg-red-100 px-1.5 py-0.5 text-xs text-red-600">{{ str_pad($issue->red3, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
<span class="rounded border border-blue-200 bg-blue-100 px-1.5 py-0.5 text-xs text-blue-600">{{ str_pad($issue->blue, 2, '0', STR_PAD_LEFT) }}</span>
|
||||
</div>
|
||||
@else
|
||||
<span class="{{ $adminListSecondaryTextClass }}">等待开奖</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} font-semibold text-indigo-600">
|
||||
{{ number_format($issue->total_tickets) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} font-semibold text-amber-600">
|
||||
{{ number_format($issue->pool_amount) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right">
|
||||
<a href="{{ route('admin.game-history.lottery.issue', $issue->id) }}"
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-50 text-indigo-700 hover:bg-indigo-100">
|
||||
购买明细
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($issues->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $issues->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,46 +3,49 @@
|
||||
@section('title', '神秘箱子历史记录')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">📦 神秘箱子历史记录</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">查询所有投放过的神秘箱子记录,含领取情况。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">📦 神秘箱子历史记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查询所有投放过的神秘箱子记录,含领取情况。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-configs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
⚙️ 游戏配置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 统计卡片 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($summary['total_dropped']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">历史总投放数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">历史总投放数</div>
|
||||
</div>
|
||||
<div class="bg-emerald-50 rounded-xl shadow-sm border border-emerald-100 p-5">
|
||||
<div class="rounded-xl border border-emerald-100 bg-emerald-50 p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-emerald-600">{{ number_format($summary['total_claimed']) }}</div>
|
||||
<div class="text-xs text-emerald-500 mt-1">已被领取</div>
|
||||
<div class="mt-1 text-xs text-emerald-500">已被领取</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 rounded-xl shadow-sm border border-gray-200 p-5">
|
||||
<div class="rounded-xl border border-gray-200 bg-gray-50 p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-gray-500">{{ number_format($summary['total_expired']) }}</div>
|
||||
<div class="text-xs text-gray-400 mt-1">已过期/未领取</div>
|
||||
<div class="mt-1 text-xs text-gray-400">已过期/未领取</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="text-sm font-bold text-gray-700 mb-2">类型分布</div>
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="mb-2 text-sm font-bold text-gray-700">类型分布</div>
|
||||
<div class="space-y-1">
|
||||
<div class="flex justify-between text-xs">
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-gray-500">📦 普通箱</span>
|
||||
<span class="font-bold">{{ $summary['type_dist']['normal'] ?? 0 }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs">
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-gray-500">💎 稀有箱</span>
|
||||
<span class="font-bold text-purple-600">{{ $summary['type_dist']['rare'] ?? 0 }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs">
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-gray-500">☠️ 黑化箱</span>
|
||||
<span class="font-bold text-red-600">{{ $summary['type_dist']['trap'] ?? 0 }}</span>
|
||||
</div>
|
||||
@@ -50,122 +53,115 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 筛选条件 --}}
|
||||
<form method="GET"
|
||||
class="bg-white rounded-xl shadow-sm border border-gray-100 p-4 flex flex-wrap items-end gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">箱子类型</label>
|
||||
<select name="box_type"
|
||||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:border-indigo-400 min-w-[130px]">
|
||||
<option value="">全部类型</option>
|
||||
<option value="normal" {{ request('box_type') === 'normal' ? 'selected' : '' }}>📦 普通箱</option>
|
||||
<option value="rare" {{ request('box_type') === 'rare' ? 'selected' : '' }}>💎 稀有箱</option>
|
||||
<option value="trap" {{ request('box_type') === 'trap' ? 'selected' : '' }}>☠️ 黑化箱</option>
|
||||
</select>
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form method="GET" class="{{ $adminListFilterFormClass }}">
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">箱子类型</label>
|
||||
<select name="box_type" class="min-w-[130px] {{ $adminListFilterInputClass }}">
|
||||
<option value="">全部类型</option>
|
||||
<option value="normal" {{ request('box_type') === 'normal' ? 'selected' : '' }}>📦 普通箱</option>
|
||||
<option value="rare" {{ request('box_type') === 'rare' ? 'selected' : '' }}>💎 稀有箱</option>
|
||||
<option value="trap" {{ request('box_type') === 'trap' ? 'selected' : '' }}>☠️ 黑化箱</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">状态</label>
|
||||
<select name="status" class="min-w-[120px] {{ $adminListFilterInputClass }}">
|
||||
<option value="">全部状态</option>
|
||||
<option value="open" {{ request('status') === 'open' ? 'selected' : '' }}>等待领取</option>
|
||||
<option value="claimed" {{ request('status') === 'claimed' ? 'selected' : '' }}>已领取</option>
|
||||
<option value="expired" {{ request('status') === 'expired' ? 'selected' : '' }}>已过期</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">筛选</button>
|
||||
<a href="{{ route('admin.game-history.mystery-box') }}" class="{{ $adminListSecondaryButtonClass }}">重置</a>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">状态</label>
|
||||
<select name="status"
|
||||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:border-indigo-400 min-w-[120px]">
|
||||
<option value="">全部状态</option>
|
||||
<option value="open" {{ request('status') === 'open' ? 'selected' : '' }}>等待领取</option>
|
||||
<option value="claimed" {{ request('status') === 'claimed' ? 'selected' : '' }}>已领取</option>
|
||||
<option value="expired" {{ request('status') === 'expired' ? 'selected' : '' }}>已过期</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm">
|
||||
🔍 筛选
|
||||
</button>
|
||||
<a href="{{ route('admin.game-history.mystery-box') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg font-bold hover:bg-gray-200 transition text-sm">
|
||||
重置
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- 箱子列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">投放时间</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">类型</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">奖励范围</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">暗号</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">状态</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">领取者</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">实际奖励</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">领取时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($boxes as $box)
|
||||
@php
|
||||
$typeInfo = match ($box->box_type) {
|
||||
'normal' => ['label' => '📦 普通箱', 'color' => 'bg-emerald-100 text-emerald-700'],
|
||||
'rare' => ['label' => '💎 稀有箱', 'color' => 'bg-purple-100 text-purple-700'],
|
||||
'trap' => ['label' => '☠️ 黑化箱', 'color' => 'bg-red-100 text-red-700'],
|
||||
default => ['label' => '📦 未知', 'color' => 'bg-gray-100 text-gray-600'],
|
||||
};
|
||||
$statusInfo = match ($box->status) {
|
||||
'open' => ['label' => '等待领取', 'color' => 'bg-blue-100 text-blue-700'],
|
||||
'claimed' => ['label' => '✅ 已领取', 'color' => 'bg-emerald-100 text-emerald-700'],
|
||||
'expired' => ['label' => '⏰ 已过期', 'color' => 'bg-gray-100 text-gray-500'],
|
||||
default => ['label' => $box->status, 'color' => 'bg-gray-100 text-gray-500'],
|
||||
};
|
||||
$claim = $box->claim;
|
||||
@endphp
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 text-xs text-gray-400">
|
||||
{{ $box->created_at->format('m-d H:i:s') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-bold {{ $typeInfo['color'] }}">
|
||||
{{ $typeInfo['label'] }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-xs text-gray-600 font-mono">
|
||||
{{ number_format($box->reward_min) }} ~ {{ number_format($box->reward_max) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<code class="bg-gray-100 px-2 py-0.5 rounded text-xs text-indigo-700 font-bold">
|
||||
{{ $box->passcode ?? '—' }}
|
||||
</code>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-bold {{ $statusInfo['color'] }}">
|
||||
{{ $statusInfo['label'] }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 font-medium text-gray-700 text-sm">
|
||||
{{ $claim?->user?->username ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-xs">
|
||||
@if ($claim)
|
||||
<span
|
||||
class="{{ $claim->reward_amount > 0 ? 'text-emerald-600 font-bold' : 'text-red-500 font-bold' }}">
|
||||
{{ $claim->reward_amount > 0 ? '+' : '' }}{{ number_format($claim->reward_amount) }}
|
||||
</span>
|
||||
@else
|
||||
<span class="text-gray-400">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-400">
|
||||
{{ $claim?->created_at?->format('m-d H:i:s') ?? '—' }}
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">箱子列表</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一列表容器与分页层级,保留箱子类型、状态和奖励色彩语义。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">投放时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">类型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">奖励范围</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">暗号</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">领取者</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">实际奖励</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">领取时间</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="px-4 py-10 text-center text-gray-400 text-sm">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($boxes as $box)
|
||||
@php
|
||||
$typeInfo = match ($box->box_type) {
|
||||
'normal' => ['label' => '📦 普通箱', 'color' => 'bg-emerald-100 text-emerald-700 border-emerald-200'],
|
||||
'rare' => ['label' => '💎 稀有箱', 'color' => 'bg-purple-100 text-purple-700 border-purple-200'],
|
||||
'trap' => ['label' => '☠️ 黑化箱', 'color' => 'bg-red-100 text-red-700 border-red-200'],
|
||||
default => ['label' => '📦 未知', 'color' => 'bg-gray-100 text-gray-600 border-gray-200'],
|
||||
};
|
||||
$statusInfo = match ($box->status) {
|
||||
'open' => ['label' => '等待领取', 'color' => 'bg-blue-100 text-blue-700 border-blue-200'],
|
||||
'claimed' => ['label' => '✅ 已领取', 'color' => 'bg-emerald-100 text-emerald-700 border-emerald-200'],
|
||||
'expired' => ['label' => '⏰ 已过期', 'color' => 'bg-gray-100 text-gray-500 border-gray-200'],
|
||||
default => ['label' => $box->status, 'color' => 'bg-gray-100 text-gray-500 border-gray-200'],
|
||||
};
|
||||
$claim = $box->claim;
|
||||
@endphp
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListSecondaryTextClass }}">
|
||||
{{ $box->created_at->format('m-d H:i:s') }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
<span class="{{ $badgeClass }} {{ $typeInfo['color'] }}">{{ $typeInfo['label'] }}</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center {{ $adminListNumericTextClass }} text-gray-600">
|
||||
{{ number_format($box->reward_min) }} ~ {{ number_format($box->reward_max) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
<code class="rounded bg-gray-100 px-2 py-0.5 text-xs font-bold text-indigo-700">
|
||||
{{ $box->passcode ?? '—' }}
|
||||
</code>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
<span class="{{ $badgeClass }} {{ $statusInfo['color'] }}">{{ $statusInfo['label'] }}</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }}">
|
||||
{{ $claim?->user?->username ?? '—' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }}">
|
||||
@if ($claim)
|
||||
<span class="{{ $claim->reward_amount > 0 ? 'font-semibold text-emerald-600' : 'font-semibold text-red-500' }}">
|
||||
{{ $claim->reward_amount > 0 ? '+' : '' }}{{ number_format($claim->reward_amount) }}
|
||||
</span>
|
||||
@else
|
||||
<span class="{{ $adminListSecondaryTextClass }}">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListSecondaryTextClass }}">
|
||||
{{ $claim?->created_at?->format('m-d H:i:s') ?? '—' }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($boxes->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $boxes->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -3,167 +3,175 @@
|
||||
@section('title', '老虎机历史记录')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
{{-- 页头 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
@php
|
||||
$tableCellClass = 'px-4 py-3';
|
||||
$badgeClass = $adminListBadgeBaseClass;
|
||||
$resultLabels = [
|
||||
'jackpot' => ['label' => '🎉 三个7', 'color' => 'bg-yellow-100 text-yellow-700 border-yellow-200'],
|
||||
'triple_gem' => ['label' => '💎 三钻', 'color' => 'bg-blue-100 text-blue-700 border-blue-200'],
|
||||
'triple' => ['label' => '✨ 三同', 'color' => 'bg-green-100 text-green-700 border-green-200'],
|
||||
'pair' => ['label' => '🎁 两同', 'color' => 'bg-indigo-100 text-indigo-700 border-indigo-200'],
|
||||
'curse' => ['label' => '☠️ 三骷髅', 'color' => 'bg-red-100 text-red-700 border-red-200'],
|
||||
'miss' => ['label' => '😔 未中奖', 'color' => 'bg-gray-100 text-gray-600 border-gray-200'],
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }} flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">🎰 老虎机历史记录</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">查询所有玩家的老虎机转动记录,支持按结果类型和玩家名筛选。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎰 老虎机历史记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查询所有玩家的老虎机转动记录,支持按结果类型和玩家名筛选。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.game-configs.index') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-bold hover:bg-gray-200 transition">
|
||||
<a href="{{ route('admin.game-configs.index') }}" class="{{ $adminListSecondaryButtonClass }}">
|
||||
⚙️ 游戏配置
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 统计卡片 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-5 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ number_format($summary['total_spins']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">总转动次数</div>
|
||||
<div class="mt-1 text-xs text-gray-500">总转动次数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-red-500">{{ number_format($summary['total_cost']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">总消耗金币</div>
|
||||
<div class="mt-1 text-xs text-gray-500">总消耗金币</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-emerald-600">{{ number_format($summary['total_payout']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">总派奖金币</div>
|
||||
<div class="mt-1 text-xs text-gray-500">总派奖金币</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($summary['net_income']) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">庄家净收(消耗-派奖)</div>
|
||||
<div class="mt-1 text-xs text-gray-500">庄家净收(消耗-派奖)</div>
|
||||
</div>
|
||||
<div class="bg-yellow-50 rounded-xl shadow-sm border border-yellow-100 p-5">
|
||||
<div class="text-2xl font-bold text-yellow-600">{{ number_format($summary['result_dist']['jackpot'] ?? 0) }}
|
||||
</div>
|
||||
<div class="text-xs text-yellow-500 mt-1">🎉 三7大奖次数</div>
|
||||
<div class="rounded-xl border border-yellow-100 bg-yellow-50 p-5 shadow-sm">
|
||||
<div class="text-2xl font-bold text-yellow-600">{{ number_format($summary['result_dist']['jackpot'] ?? 0) }}</div>
|
||||
<div class="mt-1 text-xs text-yellow-500">🎉 三7大奖次数</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 结果分布 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
|
||||
<div class="text-sm font-bold text-gray-700 mb-3">结果类型分布</div>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
@php
|
||||
$resultLabels = [
|
||||
'jackpot' => ['label' => '🎉 三个7', 'color' => 'bg-yellow-100 text-yellow-700'],
|
||||
'triple_gem' => ['label' => '💎 三钻', 'color' => 'bg-blue-100 text-blue-700'],
|
||||
'triple' => ['label' => '✨ 三同', 'color' => 'bg-green-100 text-green-700'],
|
||||
'pair' => ['label' => '🎁 两同', 'color' => 'bg-indigo-100 text-indigo-700'],
|
||||
'curse' => ['label' => '☠️ 三骷髅', 'color' => 'bg-red-100 text-red-700'],
|
||||
'miss' => ['label' => '😔 未中奖', 'color' => 'bg-gray-100 text-gray-600'],
|
||||
];
|
||||
@endphp
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">结果类型分布</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">保留中奖结果配色,仅统一卡片容器与排版节奏。</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-3 p-6">
|
||||
@foreach ($resultLabels as $key => $meta)
|
||||
<div class="px-4 py-2 rounded-lg {{ $meta['color'] }}">
|
||||
@php
|
||||
$distributionBorderClass = match ($key) {
|
||||
'jackpot' => 'border-yellow-200',
|
||||
'triple_gem' => 'border-blue-200',
|
||||
'triple' => 'border-green-200',
|
||||
'pair' => 'border-indigo-200',
|
||||
'curse' => 'border-red-200',
|
||||
default => 'border-gray-200',
|
||||
};
|
||||
@endphp
|
||||
<div class="rounded-lg border px-4 py-2 {{ $distributionBorderClass }} {{ $meta['color'] }}">
|
||||
<div class="text-sm font-bold">{{ $meta['label'] }}</div>
|
||||
<div class="text-xs mt-0.5">{{ number_format($summary['result_dist'][$key] ?? 0) }} 次</div>
|
||||
<div class="mt-0.5 text-xs">{{ number_format($summary['result_dist'][$key] ?? 0) }} 次</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 筛选条件 --}}
|
||||
<form method="GET"
|
||||
class="bg-white rounded-xl shadow-sm border border-gray-100 p-4 flex flex-wrap items-end gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">结果类型</label>
|
||||
<select name="result_type"
|
||||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:border-indigo-400 min-w-[140px]">
|
||||
<option value="">全部结果</option>
|
||||
@foreach ($resultLabels as $key => $meta)
|
||||
<option value="{{ $key }}" {{ request('result_type') === $key ? 'selected' : '' }}>
|
||||
{{ $meta['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form method="GET" class="{{ $adminListFilterFormClass }}">
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">结果类型</label>
|
||||
<select name="result_type" class="min-w-[140px] {{ $adminListFilterInputClass }}">
|
||||
<option value="">全部结果</option>
|
||||
@foreach ($resultLabels as $key => $meta)
|
||||
<option value="{{ $key }}" {{ request('result_type') === $key ? 'selected' : '' }}>
|
||||
{{ $meta['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">玩家名称</label>
|
||||
<input type="text" name="username" value="{{ request('username') }}" placeholder="模糊搜索..."
|
||||
class="w-40 {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">筛选</button>
|
||||
<a href="{{ route('admin.game-history.slot') }}" class="{{ $adminListSecondaryButtonClass }}">重置</a>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">玩家名称</label>
|
||||
<input type="text" name="username" value="{{ request('username') }}" placeholder="模糊搜索..."
|
||||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:border-indigo-400 w-40">
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm">
|
||||
🔍 筛选
|
||||
</button>
|
||||
<a href="{{ route('admin.game-history.slot') }}"
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg font-bold hover:bg-gray-200 transition text-sm">
|
||||
重置
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- 记录列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">时间</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">玩家</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">三列图案</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">结果</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">消耗</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">获得</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">净值</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
@forelse ($logs as $log)
|
||||
@php
|
||||
$symbols = \App\Models\SlotMachineLog::symbols();
|
||||
$r1Emoji = $symbols[$log->reel1]['emoji'] ?? $log->reel1;
|
||||
$r2Emoji = $symbols[$log->reel2]['emoji'] ?? $log->reel2;
|
||||
$r3Emoji = $symbols[$log->reel3]['emoji'] ?? $log->reel3;
|
||||
$net = $log->payout - $log->cost;
|
||||
$rowBg = match ($log->result_type) {
|
||||
'jackpot' => 'bg-yellow-50',
|
||||
'triple_gem' => 'bg-blue-50',
|
||||
'curse' => 'bg-red-50',
|
||||
default => '',
|
||||
};
|
||||
@endphp
|
||||
<tr class="hover:bg-gray-50 transition {{ $rowBg }}">
|
||||
<td class="px-4 py-3 text-xs text-gray-400">
|
||||
{{ $log->created_at->format('m-d H:i:s') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 font-medium text-gray-800">
|
||||
{{ $log->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-lg tracking-widest">
|
||||
{{ $r1Emoji }} {{ $r2Emoji }} {{ $r3Emoji }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold {{ $resultLabels[$log->result_type]['color'] ?? 'bg-gray-100 text-gray-600' }}">
|
||||
{{ $resultLabels[$log->result_type]['label'] ?? $log->result_type }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right font-mono text-xs text-red-500">
|
||||
-{{ number_format($log->cost) }}
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-right font-mono text-xs {{ $log->payout > 0 ? 'text-emerald-600 font-bold' : 'text-gray-400' }}">
|
||||
{{ $log->payout > 0 ? '+' . number_format($log->payout) : '0' }}
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-right font-mono text-xs {{ $net >= 0 ? 'text-emerald-600' : 'text-red-500' }} font-bold">
|
||||
{{ $net >= 0 ? '+' : '' }}{{ number_format($net) }}
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="{{ $adminListSectionTitleClass }}">转动记录</div>
|
||||
<div class="{{ $adminListSectionDescClass }}">统一表格、空态和分页样式,保留高价值结果的行底色提示。</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">玩家</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">三列图案</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">结果</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">消耗</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">获得</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">净值</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-10 text-center text-gray-400 text-sm">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($logs as $log)
|
||||
@php
|
||||
$symbols = \App\Models\SlotMachineLog::symbols();
|
||||
$r1Emoji = $symbols[$log->reel1]['emoji'] ?? $log->reel1;
|
||||
$r2Emoji = $symbols[$log->reel2]['emoji'] ?? $log->reel2;
|
||||
$r3Emoji = $symbols[$log->reel3]['emoji'] ?? $log->reel3;
|
||||
$net = $log->payout - $log->cost;
|
||||
$rowBg = match ($log->result_type) {
|
||||
'jackpot' => 'bg-yellow-50',
|
||||
'triple_gem' => 'bg-blue-50',
|
||||
'curse' => 'bg-red-50',
|
||||
default => '',
|
||||
};
|
||||
@endphp
|
||||
<tr class="{{ $adminListTableRowClass }} {{ $rowBg }}">
|
||||
<td class="{{ $tableCellClass }} {{ $adminListSecondaryTextClass }}">
|
||||
{{ $log->created_at->format('m-d H:i:s') }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} {{ $adminListPrimaryTextClass }}">
|
||||
{{ $log->user?->username ?? '已注销' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center text-lg tracking-widest">
|
||||
{{ $r1Emoji }} {{ $r2Emoji }} {{ $r3Emoji }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-center">
|
||||
<span class="{{ $badgeClass }} {{ $resultLabels[$log->result_type]['color'] ?? 'bg-gray-100 text-gray-600 border-gray-200' }}">
|
||||
{{ $resultLabels[$log->result_type]['label'] ?? $log->result_type }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} text-red-500">
|
||||
-{{ number_format($log->cost) }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} {{ $log->payout > 0 ? 'font-semibold text-emerald-600' : 'text-gray-400' }}">
|
||||
{{ $log->payout > 0 ? '+' . number_format($log->payout) : '0' }}
|
||||
</td>
|
||||
<td class="{{ $tableCellClass }} text-right {{ $adminListNumericTextClass }} font-semibold {{ $net >= 0 ? 'text-emerald-600' : 'text-red-500' }}">
|
||||
{{ $net >= 0 ? '+' : '' }}{{ number_format($net) }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($logs->hasPages())
|
||||
<div class="px-4 py-3 border-t border-gray-100">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $logs->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
@section('title', '节日福利管理')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
@php
|
||||
$visibleEvents = $events->getCollection();
|
||||
$enabledCount = $visibleEvents->where('enabled', true)->count();
|
||||
@@ -24,14 +26,13 @@
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="space-y-6">
|
||||
{{-- 页头 --}}
|
||||
<div class="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div class="space-y-2">
|
||||
<div>
|
||||
<h2 class="text-xl font-black tracking-tight text-slate-800">节日福利管理</h2>
|
||||
<p class="mt-1 text-sm text-slate-500">统一维护节日福利模板与触发计划。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">节日福利管理</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">统一维护节日福利模板与触发计划。</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2 text-xs font-semibold">
|
||||
<span class="rounded-full bg-slate-100 px-3 py-1 text-slate-600">当前页 {{ $visibleEvents->count() }} 个活动</span>
|
||||
@@ -41,40 +42,39 @@
|
||||
</div>
|
||||
|
||||
<a href="{{ route('admin.holiday-events.create') }}"
|
||||
class="inline-flex items-center justify-center gap-2 rounded-lg bg-amber-500 px-4 py-2.5 text-sm font-bold text-white shadow-sm transition hover:bg-amber-600">
|
||||
class="inline-flex items-center justify-center gap-2 rounded-lg bg-amber-500 px-4 py-2.5 text-sm font-semibold text-white shadow-sm transition hover:bg-amber-600">
|
||||
<span class="text-base leading-none">+</span>
|
||||
<span>创建活动</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 列表 --}}
|
||||
<div class="overflow-hidden rounded-xl border border-gray-100 bg-white shadow-sm">
|
||||
<div class="border-b border-gray-100 px-6 py-3">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div class="flex flex-col gap-1 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<h3 class="text-base font-bold text-slate-800">福利模板列表</h3>
|
||||
<p class="mt-1 text-xs text-slate-500">列表按关键信息压缩展示,适合批量查看。</p>
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">福利模板列表</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">列表按关键信息压缩展示,适合批量查看。</p>
|
||||
</div>
|
||||
<div class="text-xs text-slate-400">年度模板额外显示月日、持续天数、轮次与轮次间隔</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="min-w-[1120px] w-full table-fixed text-sm">
|
||||
<thead class="bg-slate-50 text-left text-xs font-bold uppercase tracking-[0.16em] text-slate-500">
|
||||
<tr>
|
||||
<th class="px-4 py-3 w-14">编号</th>
|
||||
<th class="px-4 py-3 w-[25%]">活动信息</th>
|
||||
<th class="px-4 py-3 w-[10%]">奖池</th>
|
||||
<th class="px-4 py-3 w-[10%]">分配</th>
|
||||
<th class="px-4 py-3 w-[11%]">限额 / 重复</th>
|
||||
<th class="px-4 py-3 w-[15%]">触发计划</th>
|
||||
<th class="px-4 py-3 w-[13%]">运行状态</th>
|
||||
<th class="px-4 py-3 w-[16%] text-right">操作</th>
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-14">编号</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-[25%]">活动信息</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-[10%]">奖池</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-[10%]">分配</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-[11%]">限额 / 重复</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-[15%]">触发计划</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-[13%]">运行状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} w-[16%] text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($events as $event)
|
||||
@php
|
||||
[$statusLabel, $statusClass] = $statusMap[$event->status] ?? ['未知', 'bg-slate-100 text-slate-600'];
|
||||
@@ -203,14 +203,14 @@
|
||||
method="POST" data-holiday-event-confirm="确定立即触发此活动吗?">
|
||||
@csrf
|
||||
<button type="submit"
|
||||
class="inline-flex items-center justify-center rounded-lg bg-amber-500 px-3 py-2 text-xs font-bold text-white transition hover:bg-amber-600">
|
||||
class="{{ $adminListActionButtonClass }} inline-flex items-center justify-center bg-amber-500 text-white hover:bg-amber-600">
|
||||
▶ 立即触发
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
<a href="{{ route('admin.holiday-events.edit', $event) }}"
|
||||
class="inline-flex items-center justify-center rounded-lg bg-indigo-50 px-3 py-2 text-xs font-bold text-indigo-700 transition hover:bg-indigo-100">
|
||||
class="{{ $adminListActionButtonClass }} inline-flex items-center justify-center bg-indigo-50 text-indigo-700 hover:bg-indigo-100">
|
||||
编辑
|
||||
</a>
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
class="inline-flex items-center justify-center rounded-lg bg-rose-50 px-3 py-2 text-xs font-bold text-rose-600 transition hover:bg-rose-100">
|
||||
class="{{ $adminListActionButtonClass }} inline-flex items-center justify-center bg-rose-50 text-rose-600 hover:bg-rose-100">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
@@ -228,7 +228,7 @@
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="px-6 py-16 text-center text-slate-400">
|
||||
<td colspan="8" class="{{ $adminListEmptyClass }}">
|
||||
暂无节日福利活动,<a href="{{ route('admin.holiday-events.create') }}"
|
||||
class="font-bold text-amber-500 hover:text-amber-600">立即创建一个</a>。
|
||||
</td>
|
||||
@@ -239,7 +239,7 @@
|
||||
</div>
|
||||
|
||||
@if ($events->hasPages())
|
||||
<div class="border-t border-gray-100 px-6 py-4">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $events->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -64,10 +64,6 @@
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.system.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
{!! '⚙️ 聊天室参数' !!}
|
||||
</a>
|
||||
<a href="{{ route('admin.wechat_bot.edit') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.wechat_bot.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
{!! '🤖 微信机器人' !!}
|
||||
</a>
|
||||
<a href="{{ route('admin.currency-logs.index') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.currency-logs.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
{!! '💴 用户流水' !!}
|
||||
@@ -84,14 +80,6 @@
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.sign-in-rules.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
{!! '✅ 签到奖励' !!}
|
||||
</a>
|
||||
<a href="{{ route('admin.vip.index') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.vip.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
{!! '👑 VIP 会员等级' !!}
|
||||
</a>
|
||||
<a href="{{ route('admin.vip-payment-logs.index') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.vip-payment-logs.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
{!! '🧾 会员购买日志' !!}
|
||||
</a>
|
||||
<a href="{{ route('admin.shop.index') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.shop.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
{!! '🛒 商店管理' !!}
|
||||
@@ -133,6 +121,18 @@
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.vip-payment.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
💳 VIP 支付配置
|
||||
</a>
|
||||
<a href="{{ route('admin.vip.index') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.vip.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
👑 VIP 会员等级
|
||||
</a>
|
||||
<a href="{{ route('admin.vip-payment-logs.index') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.vip-payment-logs.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
🧾 会员购买日志
|
||||
</a>
|
||||
<a href="{{ route('admin.wechat_bot.edit') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.wechat_bot.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
🤖 微信机器人
|
||||
</a>
|
||||
<a href="{{ route('admin.ai-providers.index') }}"
|
||||
class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.ai-providers.*') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}">
|
||||
🤖 AI 厂商配置
|
||||
|
||||
@@ -10,95 +10,108 @@
|
||||
@section('title', '婚礼红包记录')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h2 class="text-xl font-bold text-gray-800">🎊 婚礼红包记录</h2>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="text-sm text-indigo-600 hover:underline">← 返回总览</a>
|
||||
</div>
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎊 婚礼红包记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">统一查看婚礼红包发放进度与领取详情。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="{{ $adminListSecondaryButtonClass }}">返回总览</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs uppercase">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">ID</th>
|
||||
<th class="px-4 py-3 text-left">新人</th>
|
||||
<th class="px-4 py-3 text-left">档位</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>
|
||||
<th class="px-4 py-3 text-center">状态</th>
|
||||
<th class="px-4 py-3 text-left">时间</th>
|
||||
<th class="px-4 py-3 text-center">详情</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y">
|
||||
@forelse ($ceremonies as $c)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 text-gray-400 font-mono text-xs">{{ $c->id }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="font-bold">{{ $c->marriage?->user?->username }}</span>
|
||||
<span class="text-gray-400 mx-1">×</span>
|
||||
<span class="font-bold">{{ $c->marriage?->partner?->username }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
{{ $c->tier?->icon }} {{ $c->tier?->name ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-bold text-amber-600">
|
||||
{{ number_format($c->total_amount) }} 金
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-gray-600">
|
||||
{{ $c->online_count ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($c->total_amount > 0)
|
||||
<div class="text-xs text-gray-600">
|
||||
{{ $c->claimed_count }} / {{ $c->online_count ?? '?' }} 人
|
||||
</div>
|
||||
<div class="text-xs text-emerald-600 font-bold">
|
||||
{{ number_format($c->claimed_amount) }} / {{ number_format($c->total_amount) }}
|
||||
</div>
|
||||
@else
|
||||
<span class="text-gray-300 text-xs">无红包</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold
|
||||
{{ match ($c->status) {
|
||||
'completed' => 'bg-green-100 text-green-700',
|
||||
'active' => 'bg-blue-100 text-blue-700',
|
||||
'pending' => 'bg-amber-100 text-amber-700',
|
||||
'expired' => 'bg-gray-100 text-gray-500',
|
||||
'cancelled' => 'bg-red-100 text-red-600',
|
||||
default => 'bg-gray-100 text-gray-600',
|
||||
} }}">
|
||||
{{ ['completed' => '已完成', 'active' => '进行中', 'pending' => '待触发', 'expired' => '已过期', 'cancelled' => '已取消'][$c->status] ?? $c->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-500">
|
||||
{{ $c->ceremony_at?->format('Y-m-d H:i') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div>
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">婚礼红包列表</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">保留婚礼状态色彩与金额语义,其他布局统一到后台列表样式。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">新人</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">档位</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">总金额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">在线人数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">领取进度</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">详情</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($ceremonies as $c)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }} {{ $adminListNumericTextClass }}">{{ $c->id }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="{{ $adminListPrimaryTextClass }}">{{ $c->marriage?->user?->username }}</span>
|
||||
<span class="mx-1 text-gray-400">×</span>
|
||||
<span class="{{ $adminListPrimaryTextClass }}">{{ $c->marriage?->partner?->username }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">
|
||||
{{ $c->tier?->icon }} {{ $c->tier?->name ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-semibold text-amber-600">
|
||||
{{ number_format($c->total_amount) }} 金
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center {{ $adminListBodyTextClass }}">
|
||||
{{ $c->online_count ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($c->total_amount > 0)
|
||||
<div class="text-xs text-gray-600">
|
||||
{{ $c->claimed_count }} / {{ $c->online_count ?? '?' }} 人
|
||||
</div>
|
||||
<div class="text-xs font-semibold text-emerald-600">
|
||||
{{ number_format($c->claimed_amount) }} / {{ number_format($c->total_amount) }}
|
||||
</div>
|
||||
@else
|
||||
<span class="text-gray-300 text-xs">无红包</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="{{ $adminListBadgeBaseClass }} {{ match ($c->status) {
|
||||
'completed' => 'border-green-200 bg-green-100 text-green-700',
|
||||
'active' => 'border-blue-200 bg-blue-100 text-blue-700',
|
||||
'pending' => 'border-amber-200 bg-amber-100 text-amber-700',
|
||||
'expired' => 'border-gray-200 bg-gray-100 text-gray-500',
|
||||
'cancelled' => 'border-red-200 bg-red-100 text-red-600',
|
||||
default => 'border-gray-200 bg-gray-100 text-gray-600',
|
||||
} }}">
|
||||
{{ ['completed' => '已完成', 'active' => '进行中', 'pending' => '待触发', 'expired' => '已过期', 'cancelled' => '已取消'][$c->status] ?? $c->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">
|
||||
{{ $c->ceremony_at?->format('Y-m-d H:i') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($c->total_amount > 0)
|
||||
<a href="{{ route('admin.marriages.claim-detail', $c->id) }}"
|
||||
class="text-xs text-indigo-600 hover:underline font-bold">明细</a>
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-50 text-indigo-600 hover:bg-indigo-600 hover:text-white">明细</a>
|
||||
@else
|
||||
<span class="text-gray-300 text-xs">—</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-4 py-12 text-center text-gray-400">暂无婚礼记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="{{ $adminListEmptyClass }}">暂无婚礼记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($ceremonies->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $ceremonies->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@if ($ceremonies->hasPages())
|
||||
<div class="px-4 py-4 border-t">{{ $ceremonies->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -10,76 +10,85 @@
|
||||
@section('title', '婚礼红包明细')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-gray-800">🎁 红包领取明细</h2>
|
||||
<p class="text-sm text-gray-500 mt-1">
|
||||
{{ $ceremony->marriage?->user?->username }} × {{ $ceremony->marriage?->partner?->username }}
|
||||
— {{ $ceremony->tier?->icon }} {{ $ceremony->tier?->name ?? '婚礼' }}
|
||||
· 总额 <strong class="text-amber-600">{{ number_format($ceremony->total_amount) }} 金</strong>
|
||||
</p>
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">🎁 红包领取明细</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">
|
||||
{{ $ceremony->marriage?->user?->username }} × {{ $ceremony->marriage?->partner?->username }}
|
||||
— {{ $ceremony->tier?->icon }} {{ $ceremony->tier?->name ?? '婚礼' }}
|
||||
· 总额 <strong class="text-amber-600">{{ number_format($ceremony->total_amount) }} 金</strong>
|
||||
</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.marriages.ceremonies') }}" class="{{ $adminListSecondaryButtonClass }}">返回婚礼列表</a>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ route('admin.marriages.ceremonies') }}" class="text-sm text-indigo-600 hover:underline">← 返回婚礼列表</a>
|
||||
</div>
|
||||
|
||||
{{-- 汇总 --}}
|
||||
<div class="grid grid-cols-3 gap-4 mb-5">
|
||||
<div class="bg-white rounded-xl border shadow-sm p-4 text-center">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ $ceremony->online_count ?? 0 }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">在线人数</div>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div class="{{ $adminListCardClass }} p-4 text-center">
|
||||
<div class="text-2xl font-bold text-indigo-600">{{ $ceremony->online_count ?? 0 }}</div>
|
||||
<div class="mt-1 text-xs text-gray-500">在线人数</div>
|
||||
</div>
|
||||
<div class="{{ $adminListCardClass }} p-4 text-center">
|
||||
<div class="text-2xl font-bold text-green-600">{{ $ceremony->claimed_count }}</div>
|
||||
<div class="mt-1 text-xs text-gray-500">已领取人数</div>
|
||||
</div>
|
||||
<div class="{{ $adminListCardClass }} p-4 text-center">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($ceremony->claimed_amount) }}</div>
|
||||
<div class="mt-1 text-xs text-gray-500">已领取金额</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl border shadow-sm p-4 text-center">
|
||||
<div class="text-2xl font-bold text-green-600">{{ $ceremony->claimed_count }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">已领取人数</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl border shadow-sm p-4 text-center">
|
||||
<div class="text-2xl font-bold text-amber-600">{{ number_format($ceremony->claimed_amount) }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">已领取金额</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-xs uppercase text-gray-600">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">用户</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-left">领取时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y">
|
||||
@forelse ($claims as $claim)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 font-bold">{{ $claim->user?->username }}</td>
|
||||
<td class="px-4 py-3 text-center font-bold text-amber-600">
|
||||
{{ number_format($claim->amount) }} 金
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($claim->claimed)
|
||||
<span class="px-2 py-0.5 rounded-full text-xs bg-green-100 text-green-700 font-bold">✅
|
||||
已领取</span>
|
||||
@else
|
||||
<span class="px-2 py-0.5 rounded-full text-xs bg-gray-100 text-gray-500">未领取</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-500">
|
||||
{{ $claim->claimed_at?->format('H:i:s') ?? '—' }}
|
||||
</td>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div>
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">领取明细</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">明细表头、正文、状态徽章与分页统一到后台列表页样式。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">用户</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">分配金额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">领取时间</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="4" class="px-4 py-12 text-center text-gray-400">暂无领取记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($claims as $claim)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $claim->user?->username }}</td>
|
||||
<td class="px-4 py-3 text-center font-semibold text-amber-600">
|
||||
{{ number_format($claim->amount) }} 金
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($claim->claimed)
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-green-200 bg-green-100 text-green-700">✅ 已领取</span>
|
||||
@else
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-gray-200 bg-gray-100 text-gray-500">未领取</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">
|
||||
{{ $claim->claimed_at?->format('H:i:s') ?? '—' }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="4" class="{{ $adminListEmptyClass }}">暂无领取记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($claims->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $claims->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@if ($claims->hasPages())
|
||||
<div class="px-4 py-4 border-t">{{ $claims->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -10,88 +10,101 @@
|
||||
@section('title', '亲密度日志')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h2 class="text-xl font-bold text-gray-800">💞 亲密度变更日志</h2>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="text-sm text-indigo-600 hover:underline">← 返回总览</a>
|
||||
</div>
|
||||
|
||||
{{-- 筛选 --}}
|
||||
<form method="GET" class="bg-white rounded-xl border shadow-sm p-4 mb-5 flex flex-wrap gap-3 items-end">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">搜索用户名</label>
|
||||
<input type="text" name="search" value="{{ request('search') }}" placeholder="双方任一用户名..."
|
||||
class="border rounded-lg px-3 py-2 text-sm w-44 focus:outline-none">
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">💞 亲密度变更日志</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">按统一后台列表样式审计婚姻亲密度的增减来源与余额变化。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="{{ $adminListSecondaryButtonClass }}">返回总览</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">来源(Source)</label>
|
||||
<select name="source" class="border rounded-lg px-3 py-2 text-sm focus:outline-none">
|
||||
<option value="">全部</option>
|
||||
@foreach (\App\Enums\IntimacySource::cases() as $src)
|
||||
<option value="{{ $src->value }}" @selected(request('source') === $src->value)>
|
||||
{{ $src->label() }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="bg-indigo-600 text-white px-4 py-2 rounded-lg text-sm font-bold hover:bg-indigo-700 transition">
|
||||
筛选
|
||||
</button>
|
||||
<a href="{{ route('admin.marriages.intimacy-logs') }}" class="text-sm text-gray-500 hover:underline py-2">重置</a>
|
||||
</form>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-xs uppercase text-gray-600">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">ID</th>
|
||||
<th class="px-4 py-3 text-left">婚姻双方</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-left">来源</th>
|
||||
<th class="px-4 py-3 text-left">备注</th>
|
||||
<th class="px-4 py-3 text-left">时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y">
|
||||
@forelse ($logs as $log)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 text-gray-400 font-mono text-xs">{{ $log->id }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="font-bold">{{ $log->marriage?->user?->username }}</span>
|
||||
<span class="text-gray-400 mx-1">×</span>
|
||||
<span class="font-bold">{{ $log->marriage?->partner?->username }}</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-3 text-center font-bold {{ $log->amount >= 0 ? 'text-green-600' : 'text-red-500' }}">
|
||||
{{ $log->amount >= 0 ? '+' : '' }}{{ $log->amount }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-indigo-600 font-bold">
|
||||
{{ number_format($log->balance_after) }}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="text-xs bg-purple-50 text-purple-700 px-2 py-0.5 rounded-full font-mono">
|
||||
{{ \App\Enums\IntimacySource::tryFrom($log->source)?->label() ?? $log->source }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-500">{{ $log->remark ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-400">
|
||||
{{ $log->created_at?->format('m-d H:i') }}
|
||||
</td>
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form method="GET" class="{{ $adminListFilterFormClass }}">
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">搜索用户名</label>
|
||||
<input type="text" name="search" value="{{ request('search') }}" placeholder="双方任一用户名..."
|
||||
class="w-44 {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">来源(Source)</label>
|
||||
<select name="source" class="{{ $adminListFilterInputClass }}">
|
||||
<option value="">全部</option>
|
||||
@foreach (\App\Enums\IntimacySource::cases() as $src)
|
||||
<option value="{{ $src->value }}" @selected(request('source') === $src->value)>
|
||||
{{ $src->label() }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">筛选</button>
|
||||
<a href="{{ route('admin.marriages.intimacy-logs') }}" class="{{ $adminListSecondaryButtonClass }}">重置</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div>
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">亲密度日志</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">保留增减与来源的颜色语义,其他样式对齐统一列表页。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">婚姻双方</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">变动量</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">变后余额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">来源</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">备注</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">时间</th>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-12 text-center text-gray-400">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($logs as $log)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }} {{ $adminListNumericTextClass }}">{{ $log->id }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="{{ $adminListPrimaryTextClass }}">{{ $log->marriage?->user?->username }}</span>
|
||||
<span class="mx-1 text-gray-400">×</span>
|
||||
<span class="{{ $adminListPrimaryTextClass }}">{{ $log->marriage?->partner?->username }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-semibold {{ $log->amount >= 0 ? 'text-green-600' : 'text-red-500' }}">
|
||||
{{ $log->amount >= 0 ? '+' : '' }}{{ $log->amount }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center font-semibold text-indigo-600">
|
||||
{{ number_format($log->balance_after) }}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-purple-200 bg-purple-50 text-purple-700">
|
||||
{{ \App\Enums\IntimacySource::tryFrom($log->source)?->label() ?? $log->source }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">{{ $log->remark ?? '—' }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">
|
||||
{{ $log->created_at?->format('m-d H:i') }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($logs->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $logs->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@if ($logs->hasPages())
|
||||
<div class="px-4 py-4 border-t">{{ $logs->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -10,99 +10,110 @@
|
||||
@section('title', '婚姻列表')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h2 class="text-xl font-bold text-gray-800">📋 婚姻列表</h2>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="text-sm text-indigo-600 hover:underline">← 返回总览</a>
|
||||
</div>
|
||||
|
||||
{{-- 筛选栏 --}}
|
||||
<form method="GET" class="bg-white rounded-xl border shadow-sm p-4 mb-5 flex flex-wrap gap-3 items-end">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">状态</label>
|
||||
<select name="status" class="border rounded-lg px-3 py-2 text-sm focus:outline-none">
|
||||
<option value="">全部</option>
|
||||
@foreach (['married' => '已婚', 'pending' => '求婚中', 'divorced' => '已离婚', 'rejected' => '被拒', 'expired' => '已过期'] as $val => $label)
|
||||
<option value="{{ $val }}" @selected(request('status') === $val)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">📋 婚姻列表</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">统一查看婚姻状态、亲密度与后台管理操作。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="{{ $adminListSecondaryButtonClass }}">返回总览</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">搜索用户名</label>
|
||||
<input type="text" name="search" value="{{ request('search') }}" placeholder="双方任一用户名..."
|
||||
class="border rounded-lg px-3 py-2 text-sm w-48 focus:outline-none">
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="bg-indigo-600 text-white px-4 py-2 rounded-lg text-sm font-bold hover:bg-indigo-700 transition">
|
||||
筛选
|
||||
</button>
|
||||
<a href="{{ route('admin.marriages.list') }}" class="text-sm text-gray-500 hover:underline py-2">重置</a>
|
||||
</form>
|
||||
|
||||
{{-- 婚姻列表 --}}
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs uppercase">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">ID</th>
|
||||
<th class="px-4 py-3 text-left">双方</th>
|
||||
<th class="px-4 py-3 text-left">戒指</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>
|
||||
<th class="px-4 py-3 text-left">时间</th>
|
||||
<th class="px-4 py-3 text-center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y">
|
||||
@forelse ($marriages as $m)
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<td class="px-4 py-3 text-gray-400 font-mono text-xs">{{ $m->id }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="font-bold">{{ $m->user?->username }}</div>
|
||||
<div class="text-gray-400 text-xs">× {{ $m->partner?->username }}</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
{{ $m->ringItem?->icon }} {{ $m->ringItem?->name ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold
|
||||
{{ match ($m->status) {
|
||||
'married' => 'bg-green-100 text-green-700',
|
||||
'pending' => 'bg-amber-100 text-amber-700',
|
||||
'divorced' => 'bg-red-100 text-red-700',
|
||||
'rejected' => 'bg-gray-100 text-gray-600',
|
||||
'expired' => 'bg-slate-100 text-slate-500',
|
||||
default => 'bg-gray-100 text-gray-600',
|
||||
} }}">
|
||||
{{ ['married' => '💑 已婚', 'pending' => '💍 求婚中', 'divorced' => '💔 已离婚', 'rejected' => '❌ 被拒', 'expired' => '⏰ 已过期'][$m->status] ?? $m->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<div class="font-bold text-indigo-600">{{ number_format($m->intimacy) }}</div>
|
||||
<div class="text-xs text-gray-400">
|
||||
{{ \App\Services\MarriageIntimacyService::levelIcon($m->level) }}
|
||||
Lv{{ $m->level }}</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-gray-600">
|
||||
{{ $m->married_at ? $m->married_at->diffInDays(now()) . ' 天' : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-500">
|
||||
@if ($m->married_at)
|
||||
结婚:{{ $m->married_at->format('Y-m-d') }}
|
||||
@elseif ($m->proposed_at)
|
||||
求婚:{{ $m->proposed_at->format('Y-m-d') }}
|
||||
@endif
|
||||
@if ($m->divorced_at)
|
||||
<div>离婚:{{ $m->divorced_at->format('Y-m-d') }}</div>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center" x-data="{ showDissolve: false }">
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form method="GET" class="{{ $adminListFilterFormClass }}">
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">状态</label>
|
||||
<select name="status" class="{{ $adminListFilterInputClass }}">
|
||||
<option value="">全部</option>
|
||||
@foreach (['married' => '已婚', 'pending' => '求婚中', 'divorced' => '已离婚', 'rejected' => '被拒', 'expired' => '已过期'] as $val => $label)
|
||||
<option value="{{ $val }}" @selected(request('status') === $val)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="{{ $adminListFilterLabelClass }}">搜索用户名</label>
|
||||
<input type="text" name="search" value="{{ request('search') }}" placeholder="双方任一用户名..."
|
||||
class="w-48 {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">筛选</button>
|
||||
<a href="{{ route('admin.marriages.list') }}" class="{{ $adminListSecondaryButtonClass }}">重置</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div>
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">婚姻记录</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">保留婚姻状态语义色,其他列表结构按统一后台样式展示。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">双方</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">戒指</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">亲密度/等级</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">结婚天数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($marriages as $m)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }} {{ $adminListNumericTextClass }}">{{ $m->id }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="{{ $adminListPrimaryTextClass }}">{{ $m->user?->username }}</div>
|
||||
<div class="{{ $adminListSecondaryTextClass }}">× {{ $m->partner?->username }}</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">
|
||||
{{ $m->ringItem?->icon }} {{ $m->ringItem?->name ?? '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="{{ $adminListBadgeBaseClass }} {{ match ($m->status) {
|
||||
'married' => 'border-green-200 bg-green-100 text-green-700',
|
||||
'pending' => 'border-amber-200 bg-amber-100 text-amber-700',
|
||||
'divorced' => 'border-red-200 bg-red-100 text-red-700',
|
||||
'rejected' => 'border-gray-200 bg-gray-100 text-gray-600',
|
||||
'expired' => 'border-slate-200 bg-slate-100 text-slate-500',
|
||||
default => 'border-gray-200 bg-gray-100 text-gray-600',
|
||||
} }}">
|
||||
{{ ['married' => '💑 已婚', 'pending' => '💍 求婚中', 'divorced' => '💔 已离婚', 'rejected' => '❌ 被拒', 'expired' => '⏰ 已过期'][$m->status] ?? $m->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<div class="text-sm font-semibold text-indigo-600">{{ number_format($m->intimacy) }}</div>
|
||||
<div class="{{ $adminListSecondaryTextClass }}">
|
||||
{{ \App\Services\MarriageIntimacyService::levelIcon($m->level) }}
|
||||
Lv{{ $m->level }}</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center {{ $adminListBodyTextClass }}">
|
||||
{{ $m->married_at ? $m->married_at->diffInDays(now()) . ' 天' : '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">
|
||||
@if ($m->married_at)
|
||||
结婚:{{ $m->married_at->format('Y-m-d') }}
|
||||
@elseif ($m->proposed_at)
|
||||
求婚:{{ $m->proposed_at->format('Y-m-d') }}
|
||||
@endif
|
||||
@if ($m->divorced_at)
|
||||
<div>离婚:{{ $m->divorced_at->format('Y-m-d') }}</div>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center" x-data="{ showDissolve: false }">
|
||||
@if ($m->status === 'married')
|
||||
<button @click="showDissolve = true"
|
||||
class="text-xs bg-red-50 text-red-600 font-bold px-3 py-1.5 rounded hover:bg-red-600 hover:text-white transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-red-50 text-red-600 hover:bg-red-600 hover:text-white">
|
||||
强制离婚
|
||||
</button>
|
||||
{{-- 强制离婚确认弹窗 --}}
|
||||
@@ -123,9 +134,9 @@
|
||||
class="w-full border rounded px-3 py-2 text-sm mb-3">
|
||||
<div class="flex gap-2 justify-end">
|
||||
<button type="button" @click="showDissolve = false"
|
||||
class="px-3 py-1.5 border rounded text-sm text-gray-600">取消</button>
|
||||
class="{{ $adminListSecondaryButtonClass }}">取消</button>
|
||||
<button type="submit"
|
||||
class="px-3 py-1.5 bg-red-600 text-white rounded text-sm font-bold">确认解除</button>
|
||||
class="{{ $adminListActionButtonClass }} bg-red-600 text-white hover:bg-red-700">确认解除</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -135,28 +146,28 @@
|
||||
data-admin-confirm="确定取消该求婚吗?">
|
||||
@csrf
|
||||
<button type="submit"
|
||||
class="text-xs bg-amber-50 text-amber-600 font-bold px-3 py-1.5 rounded hover:bg-amber-600 hover:text-white transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-amber-50 text-amber-600 hover:bg-amber-600 hover:text-white">
|
||||
取消求婚
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="text-xs text-gray-300">—</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="px-4 py-12 text-center text-gray-400">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="{{ $adminListEmptyClass }}">暂无记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- 分页 --}}
|
||||
@if ($marriages->hasPages())
|
||||
<div class="px-4 py-4 border-t">{{ $marriages->links() }}</div>
|
||||
@endif
|
||||
@if ($marriages->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $marriages->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -10,82 +10,94 @@
|
||||
@section('title', '求婚记录')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h2 class="text-xl font-bold text-gray-800">💌 求婚记录</h2>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="text-sm text-indigo-600 hover:underline">← 返回总览</a>
|
||||
</div>
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">💌 求婚记录</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">统一查看求婚进度,并保留婚姻状态语义色彩。</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.marriages.index') }}" class="{{ $adminListSecondaryButtonClass }}">返回总览</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-xs uppercase text-gray-600">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">ID</th>
|
||||
<th class="px-4 py-3 text-left">发起方</th>
|
||||
<th class="px-4 py-3 text-left">目标</th>
|
||||
<th class="px-4 py-3 text-left">戒指</th>
|
||||
<th class="px-4 py-3 text-center">状态</th>
|
||||
<th class="px-4 py-3 text-left">求婚时间</th>
|
||||
<th class="px-4 py-3 text-left">过期时间</th>
|
||||
<th class="px-4 py-3 text-center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y">
|
||||
@forelse ($proposals as $p)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 text-gray-400 font-mono text-xs">{{ $p->id }}</td>
|
||||
<td class="px-4 py-3 font-bold">{{ $p->user?->username }}</td>
|
||||
<td class="px-4 py-3 font-bold">{{ $p->partner?->username }}</td>
|
||||
<td class="px-4 py-3">{{ $p->ringItem?->icon }} {{ $p->ringItem?->name ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="px-2 py-0.5 rounded-full text-xs font-bold
|
||||
{{ match ($p->status) {
|
||||
'pending' => 'bg-amber-100 text-amber-700',
|
||||
'rejected' => 'bg-red-100 text-red-600',
|
||||
'expired' => 'bg-gray-100 text-gray-500',
|
||||
'married' => 'bg-emerald-100 text-emerald-700',
|
||||
'divorced' => 'bg-purple-100 text-purple-700',
|
||||
default => 'bg-gray-100 text-gray-600',
|
||||
} }}">
|
||||
{{ ['pending' => '⏳ 等待中', 'rejected' => '❌ 已拒绝', 'expired' => '⏰ 已过期', 'married' => '✅ 已结婚', 'divorced' => '💔 已离婚'][$p->status] ?? $p->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-gray-500">{{ $p->proposed_at?->format('Y-m-d H:i') }}</td>
|
||||
<td
|
||||
class="px-4 py-3 text-xs {{ $p->expires_at?->isPast() ? 'text-red-400' : 'text-gray-500' }}">
|
||||
{{ $p->expires_at?->format('Y-m-d H:i') }}
|
||||
@if ($p->status === 'pending' && $p->expires_at?->isPast())
|
||||
<span class="text-red-500">(已超时)</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<div>
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">求婚列表</h3>
|
||||
<p class="{{ $adminListSectionDescClass }}">列表布局、表头、按钮与分页对齐后台统一风格。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead>
|
||||
<tr class="{{ $adminListTableHeadRowClass }}">
|
||||
<th class="{{ $adminListTableHeadCellClass }}">ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">发起方</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">目标</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">戒指</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">求婚时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">过期时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($proposals as $p)
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }} {{ $adminListNumericTextClass }}">{{ $p->id }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $p->user?->username }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $p->partner?->username }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListBodyTextClass }}">{{ $p->ringItem?->icon }} {{ $p->ringItem?->name ?? '—' }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="{{ $adminListBadgeBaseClass }} {{ match ($p->status) {
|
||||
'pending' => 'border-amber-200 bg-amber-100 text-amber-700',
|
||||
'rejected' => 'border-red-200 bg-red-100 text-red-600',
|
||||
'expired' => 'border-gray-200 bg-gray-100 text-gray-500',
|
||||
'married' => 'border-emerald-200 bg-emerald-100 text-emerald-700',
|
||||
'divorced' => 'border-purple-200 bg-purple-100 text-purple-700',
|
||||
default => 'border-gray-200 bg-gray-100 text-gray-600',
|
||||
} }}">
|
||||
{{ ['pending' => '⏳ 等待中', 'rejected' => '❌ 已拒绝', 'expired' => '⏰ 已过期', 'married' => '✅ 已结婚', 'divorced' => '💔 已离婚'][$p->status] ?? $p->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 {{ $adminListSecondaryTextClass }}">{{ $p->proposed_at?->format('Y-m-d H:i') }}</td>
|
||||
<td class="px-4 py-3 text-xs {{ $p->expires_at?->isPast() ? 'text-red-400' : 'text-gray-500' }}">
|
||||
{{ $p->expires_at?->format('Y-m-d H:i') }}
|
||||
@if ($p->status === 'pending' && $p->expires_at?->isPast())
|
||||
<span class="text-red-500">(已超时)</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
@if ($p->status === 'pending')
|
||||
<form action="{{ route('admin.marriages.cancel-proposal', $p->id) }}" method="POST"
|
||||
data-admin-confirm="确定取消该求婚吗?">
|
||||
@csrf
|
||||
<button type="submit"
|
||||
class="text-xs bg-amber-50 text-amber-600 font-bold px-3 py-1.5 rounded hover:bg-amber-600 hover:text-white transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-amber-50 text-amber-600 hover:bg-amber-600 hover:text-white">
|
||||
取消求婚
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="text-gray-300 text-xs">—</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="px-4 py-12 text-center text-gray-400">暂无求婚记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="{{ $adminListEmptyClass }}">暂无求婚记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if ($proposals->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $proposals->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@if ($proposals->hasPages())
|
||||
<div class="px-4 py-4 border-t">{{ $proposals->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
$adminListPageClass = 'space-y-6';
|
||||
$adminListHeaderCardClass = 'rounded-xl border border-gray-100 bg-white p-5 shadow-sm';
|
||||
$adminListHeaderTitleClass = 'text-lg font-bold text-gray-800';
|
||||
$adminListHeaderSubtitleClass = 'mt-1 text-sm text-gray-500';
|
||||
$adminListFilterCardClass = 'bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden mb-6';
|
||||
$adminListFilterInnerClass = 'p-6 border-b border-gray-100 bg-gray-50';
|
||||
$adminListFilterFormClass = 'flex flex-wrap items-end gap-3';
|
||||
$adminListFilterLabelClass = 'block mb-1 text-xs font-semibold uppercase tracking-wider text-gray-500';
|
||||
$adminListFilterInputClass = 'px-3 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm';
|
||||
$adminListPrimaryButtonClass = 'bg-indigo-600 text-white px-4 py-2 rounded-lg font-semibold shadow-sm transition hover:bg-indigo-700';
|
||||
$adminListSecondaryButtonClass = 'px-4 py-2 bg-white border border-gray-300 rounded-lg text-sm font-semibold text-gray-700 hover:bg-gray-50 transition';
|
||||
$adminListCardClass = 'bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden';
|
||||
$adminListSectionHeadClass = 'px-6 py-4 border-b border-gray-100 bg-gray-50';
|
||||
$adminListSectionTitleClass = 'text-base font-semibold text-gray-700';
|
||||
$adminListSectionDescClass = 'text-xs text-gray-400 mt-1';
|
||||
$adminListTableWrapClass = 'overflow-x-auto';
|
||||
$adminListTableClass = 'w-full text-sm';
|
||||
$adminListTableHeadRowClass = 'bg-gray-50 border-b border-gray-100';
|
||||
$adminListTableHeadCellClass = 'px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-500';
|
||||
$adminListTableBodyClass = 'divide-y divide-gray-100';
|
||||
$adminListTableRowClass = 'hover:bg-gray-50 transition';
|
||||
$adminListPrimaryTextClass = 'text-sm font-semibold text-gray-800';
|
||||
$adminListSecondaryTextClass = 'text-xs text-gray-400';
|
||||
$adminListBodyTextClass = 'text-sm text-gray-600';
|
||||
$adminListNumericTextClass = 'text-sm font-mono';
|
||||
$adminListPaginationClass = 'p-4 border-t border-gray-100 text-sm text-gray-600';
|
||||
$adminListEmptyClass = 'px-4 py-12 text-center text-gray-400';
|
||||
$adminListBadgeBaseClass = 'inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-semibold';
|
||||
$adminListActionButtonClass = 'text-xs font-semibold px-3 py-1.5 rounded transition cursor-pointer';
|
||||
@@ -12,6 +12,7 @@
|
||||
@section('title', '职务管理')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
<div x-data="{
|
||||
showForm: false,
|
||||
editing: null,
|
||||
@@ -82,30 +83,27 @@
|
||||
}">
|
||||
|
||||
{{-- 头部 --}}
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">职务管理</h2>
|
||||
<p class="text-sm text-gray-500">管理各部门职务,配置等级、图标、人数上限和任命权限</p>
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
<div class="{{ $adminListHeaderCardClass }} mb-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">职务管理</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">管理各部门职务,配置等级、图标、人数上限和任命权限</p>
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
<a href="{{ route('admin.departments.index') }}"
|
||||
style="background-color:#e5e7eb;color:#374151;padding:0.5rem 1rem;border-radius:0.5rem;font-weight:700;font-size:0.875rem;display:inline-flex;align-items:center;text-decoration:none;"
|
||||
onmouseover="this.style.backgroundColor='#d1d5db'" onmouseout="this.style.backgroundColor='#e5e7eb'">
|
||||
class="{{ $adminListSecondaryButtonClass }}">
|
||||
← 部门管理
|
||||
</a>
|
||||
<a href="{{ route('admin.appointments.index') }}"
|
||||
style="background-color:#f97316;color:#fff;padding:0.5rem 1rem;border-radius:0.5rem;font-weight:700;font-size:0.875rem;display:inline-flex;align-items:center;text-decoration:none;box-shadow:0 1px 2px rgba(0,0,0,.1);"
|
||||
onmouseover="this.style.backgroundColor='#ea580c'" onmouseout="this.style.backgroundColor='#f97316'">
|
||||
class="px-4 py-2 rounded-lg text-sm font-semibold text-white bg-orange-500 hover:bg-orange-600 transition shadow-sm">
|
||||
🎖️ 任命管理 →
|
||||
</a>
|
||||
@if (Auth::id() === 1)
|
||||
<button @click="openCreate()"
|
||||
style="background-color:#4f46e5;color:#fff;padding:0.5rem 1.25rem;border-radius:0.5rem;font-weight:700;border:none;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.1);"
|
||||
onmouseover="this.style.backgroundColor='#4338ca'"
|
||||
onmouseout="this.style.backgroundColor='#4f46e5'">
|
||||
<button @click="openCreate()" class="{{ $adminListPrimaryButtonClass }}">
|
||||
+ 新增职务
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -176,33 +174,33 @@
|
||||
<span class="text-xs text-gray-400">位阶 {{ $dept->rank }}</span>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-600 text-xs">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">图标</th>
|
||||
<th class="px-4 py-3 text-left">职务名</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>
|
||||
<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>
|
||||
<th class="px-4 py-3 text-center">礼包默认</th>
|
||||
<th class="px-4 py-3 text-center">聊天室权限</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">图标</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">职务名</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">位阶</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">等级</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">人数上限</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">当前在职</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">单次上限</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">单日上限</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">任命权</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">礼包默认</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} 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>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($dept->positions as $pos)
|
||||
@php $appointableIds = $pos->appointablePositions->pluck('id')->toArray(); @endphp
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-3 text-xl">{{ $pos->icon }}</td>
|
||||
<td class="px-4 py-3 font-bold">{{ $pos->name }}</td>
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">{{ $pos->name }}</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<span
|
||||
class="text-xs bg-indigo-100 text-indigo-700 px-2 py-0.5 rounded font-mono">{{ $pos->rank }}</span>
|
||||
@@ -313,7 +311,7 @@
|
||||
sort_order: {{ $pos->sort_order }},
|
||||
requestUrl: '{{ route('admin.positions.update', $pos->id) }}'
|
||||
}, {{ 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">
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-50 text-indigo-600 hover:bg-indigo-600 hover:text-white">
|
||||
编辑
|
||||
</button>
|
||||
@endif
|
||||
@@ -323,17 +321,17 @@
|
||||
data-admin-confirm="确定删除职务【{{ $pos->name }}】?">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit"
|
||||
class="text-xs bg-red-50 text-red-600 font-bold px-2 py-1 rounded hover:bg-red-600 hover:text-white transition">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
class="{{ $adminListActionButtonClass }} bg-red-50 text-red-600 hover:bg-red-600 hover:text-white">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="{{ Auth::user()->user_level >= $superLvl ? 11 : 10 }}"
|
||||
class="px-4 py-6 text-center text-gray-400">该部门暂无职务</td>
|
||||
class="{{ $adminListEmptyClass }}">该部门暂无职务</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
@section('title', '🛒 商店商品管理')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
@php
|
||||
$typeLabels = [
|
||||
@@ -90,48 +91,49 @@
|
||||
}">
|
||||
|
||||
{{-- 头部操作栏 --}}
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">商店商品列表</h2>
|
||||
<p class="text-sm text-gray-500">管理聊天室商店内所有可出售商品,支持上下架控制。</p>
|
||||
<div class="{{ $adminListHeaderCardClass }} mb-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">商店商品列表</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">管理聊天室商店内所有可出售商品,支持上下架控制。</p>
|
||||
</div>
|
||||
@if ($isSuperAdmin)
|
||||
<button @click="openCreate()" class="{{ $adminListPrimaryButtonClass }}">
|
||||
+ 新增商品
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
@if ($isSuperAdmin)
|
||||
<button @click="openCreate()"
|
||||
class="bg-indigo-600 text-white px-5 py-2.5 rounded-lg font-bold hover:bg-indigo-700 transition shadow-sm">
|
||||
+ 新增商品
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- 商品列表表格 --}}
|
||||
<div class="bg-white rounded-xl shadow overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-gray-500 uppercase text-xs tracking-wider">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left">商品</th>
|
||||
<th class="px-4 py-3 text-left">类型</th>
|
||||
<th class="px-4 py-3 text-right">价格</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>
|
||||
<th class="px-4 py-3 text-center">操作</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">商品</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">类型</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">价格</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">有效期</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">排序</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($items as $item)
|
||||
@php $tl = $typeLabels[$item->type] ?? ['label' => $item->type, 'color' => 'bg-gray-100 text-gray-600']; @endphp
|
||||
<tr class="hover:bg-gray-50 transition {{ $item->is_active ? '' : 'opacity-50' }}">
|
||||
<tr class="{{ $adminListTableRowClass }} {{ $item->is_active ? '' : 'opacity-50' }}">
|
||||
{{-- 商品信息 --}}
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-2xl leading-none">{{ $item->icon }}</span>
|
||||
<div>
|
||||
<p class="font-semibold text-gray-800">{{ $item->name }}</p>
|
||||
<p class="text-xs text-gray-400 font-mono">{{ $item->slug }}</p>
|
||||
@if ($item->description)
|
||||
<p class="text-xs text-gray-500 mt-0.5 max-w-xs truncate">
|
||||
<p class="{{ $adminListPrimaryTextClass }}">{{ $item->name }}</p>
|
||||
<p class="{{ $adminListSecondaryTextClass }} font-mono">{{ $item->slug }}</p>
|
||||
@if ($item->description)
|
||||
<p class="text-xs text-gray-500 mt-0.5 max-w-xs truncate" title="{{ $item->description }}">
|
||||
{{ $item->description }}</p>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@@ -189,7 +191,7 @@
|
||||
'sort_order' => $item->sort_order,
|
||||
'is_active' => (bool) $item->is_active,
|
||||
]) }})"
|
||||
class="text-indigo-600 hover:text-indigo-800 text-xs font-semibold px-2 py-1 rounded hover:bg-indigo-50 transition">
|
||||
class="{{ $adminListActionButtonClass }} text-indigo-600 hover:text-indigo-800 hover:bg-indigo-50">
|
||||
编辑
|
||||
</button>
|
||||
@if ($isSuperAdmin)
|
||||
@@ -197,7 +199,7 @@
|
||||
data-admin-confirm="确定要删除「{{ $item->name }}」吗?此操作不可撤销!">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit"
|
||||
class="text-red-500 hover:text-red-700 text-xs font-semibold px-2 py-1 rounded hover:bg-red-50 transition">
|
||||
class="{{ $adminListActionButtonClass }} text-red-500 hover:text-red-700 hover:bg-red-50">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
@@ -207,7 +209,7 @@
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-12 text-center text-gray-400">暂无商品数据</td>
|
||||
<td colspan="7" class="{{ $adminListEmptyClass }}">暂无商品数据</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
@section('title', '签到奖励管理')
|
||||
|
||||
@section('content')
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
@php
|
||||
$signInRulePayload = $rules->mapWithKeys(
|
||||
fn($rule) => [
|
||||
@@ -27,60 +29,63 @@
|
||||
|
||||
<script type="application/json" id="admin-sign-in-rules-data">@json($signInRulePayload)</script>
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-gray-800">✅ 签到奖励管理</h2>
|
||||
<p class="text-xs text-gray-500 mt-1">按连续签到天数配置金币、经验、魅力和专属身份。</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}">✅ 签到奖励管理</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">按连续签到天数配置金币、经验、魅力和专属身份。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 border-b border-gray-100">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }}">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">连续天数</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">金币</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">经验</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">魅力</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-bold text-gray-500 uppercase">身份</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">有效期</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-bold text-gray-500 uppercase">状态</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-bold text-gray-500 uppercase">操作</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">连续天数</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">金币</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">经验</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">魅力</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">身份</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">有效期</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-center">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($rules as $rule)
|
||||
<tr id="rule-row-{{ $rule->id }}" class="{{ $rule->is_enabled ? '' : 'opacity-50' }}">
|
||||
<td class="px-4 py-3 font-bold text-gray-800">第 {{ $rule->streak_days }} 天</td>
|
||||
<td class="px-4 py-3 text-center text-amber-600 font-mono">+{{ $rule->gold_reward }}</td>
|
||||
<td class="px-4 py-3 text-center text-emerald-600 font-mono">+{{ $rule->exp_reward }}</td>
|
||||
<td class="px-4 py-3 text-center text-pink-600 font-mono">+{{ $rule->charm_reward }}</td>
|
||||
<tr id="rule-row-{{ $rule->id }}" class="{{ $adminListTableRowClass }} {{ $rule->is_enabled ? '' : 'opacity-50' }}">
|
||||
<td class="px-4 py-3 {{ $adminListPrimaryTextClass }}">第 {{ $rule->streak_days }} 天</td>
|
||||
<td class="px-4 py-3 text-center text-amber-600 {{ $adminListNumericTextClass }}">+{{ $rule->gold_reward }}</td>
|
||||
<td class="px-4 py-3 text-center text-emerald-600 {{ $adminListNumericTextClass }}">+{{ $rule->exp_reward }}</td>
|
||||
<td class="px-4 py-3 text-center text-pink-600 {{ $adminListNumericTextClass }}">+{{ $rule->charm_reward }}</td>
|
||||
<td class="px-4 py-3">
|
||||
@if ($rule->identity_badge_name)
|
||||
<span class="inline-flex items-center gap-1 rounded-full border px-2 py-1 text-xs font-bold"
|
||||
<span class="{{ $adminListBadgeBaseClass }} px-2 py-1"
|
||||
style="color: {{ $rule->identity_badge_color ?: '#0f766e' }}; border-color: #99f6e4; background: #f0fdfa;">
|
||||
<span>{{ $rule->identity_badge_icon ?: '✅' }}</span>
|
||||
<span>{{ $rule->identity_badge_name }}</span>
|
||||
</span>
|
||||
<div class="mt-1 text-[11px] text-gray-400">{{ $rule->identity_badge_code }}</div>
|
||||
<div class="mt-1 {{ $adminListSecondaryTextClass }}">{{ $rule->identity_badge_code }}</div>
|
||||
@else
|
||||
<span class="text-xs text-gray-400">未配置身份</span>
|
||||
<span class="{{ $adminListSecondaryTextClass }}">未配置身份</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center text-xs text-gray-600">
|
||||
<td class="px-4 py-3 text-center {{ $adminListBodyTextClass }}">
|
||||
{{ $rule->identity_duration_days > 0 ? $rule->identity_duration_days . ' 天' : '永久' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<button type="button" data-sign-in-rule-toggle-url="{{ route('admin.sign-in-rules.toggle', $rule) }}"
|
||||
id="toggle-rule-{{ $rule->id }}"
|
||||
class="px-2 py-1 rounded-full text-xs font-bold transition {{ $rule->is_enabled ? 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200' : 'bg-gray-100 text-gray-500 hover:bg-gray-200' }}">
|
||||
class="{{ $adminListBadgeBaseClass }} px-2 py-1 transition {{ $rule->is_enabled ? 'border-emerald-200 bg-emerald-100 text-emerald-700 hover:bg-emerald-200' : 'border-gray-200 bg-gray-100 text-gray-500 hover:bg-gray-200' }}">
|
||||
{{ $rule->is_enabled ? '启用' : '停用' }}
|
||||
</button>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<button type="button" data-sign-in-rule-edit-id="{{ $rule->id }}"
|
||||
class="px-3 py-1 bg-indigo-50 text-indigo-700 rounded text-xs font-bold hover:bg-indigo-100 transition mr-1">
|
||||
class="{{ $adminListActionButtonClass }} bg-indigo-50 text-indigo-700 hover:bg-indigo-100 mr-1">
|
||||
编辑
|
||||
</button>
|
||||
<form action="{{ route('admin.sign-in-rules.destroy', $rule) }}" method="POST"
|
||||
@@ -88,7 +93,7 @@
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
class="px-3 py-1 bg-red-50 text-red-600 rounded text-xs font-bold hover:bg-red-100 transition">
|
||||
class="{{ $adminListActionButtonClass }} bg-red-50 text-red-600 hover:bg-red-100">
|
||||
删除
|
||||
</button>
|
||||
</form>
|
||||
@@ -96,23 +101,23 @@
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="px-4 py-8 text-center text-sm text-gray-400">暂无签到奖励规则。</td>
|
||||
<td colspan="8" class="{{ $adminListEmptyClass }}">暂无签到奖励规则。</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<div class="p-5 border-b border-gray-100 bg-gray-50">
|
||||
<h3 class="font-bold text-gray-700 text-sm">➕ 新增签到档位</h3>
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListSectionHeadClass }}">
|
||||
<h3 class="{{ $adminListSectionTitleClass }}">➕ 新增签到档位</h3>
|
||||
</div>
|
||||
<form action="{{ route('admin.sign-in-rules.store') }}" method="POST" class="p-5">
|
||||
@csrf
|
||||
@include('admin.sign-in-rules.partials.form-fields', ['rule' => null])
|
||||
<div class="mt-4 flex items-center gap-4">
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm shadow-sm">
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">
|
||||
💾 添加规则
|
||||
</button>
|
||||
<label class="flex items-center gap-2 text-sm text-gray-600 cursor-pointer">
|
||||
@@ -124,9 +129,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="edit-rule-modal" class="hidden fixed inset-0 bg-black/40 z-50 flex items-center justify-center p-4">
|
||||
<div class="bg-white rounded-xl w-full max-w-3xl shadow-2xl">
|
||||
<div class="p-5 border-b border-gray-100 flex justify-between items-center">
|
||||
<div id="edit-rule-modal" class="hidden fixed inset-0 bg-black/40 z-50 flex items-center justify-center p-4">
|
||||
<div class="bg-white rounded-xl w-full max-w-3xl shadow-2xl">
|
||||
<div class="p-5 border-b border-gray-100 flex justify-between items-center">
|
||||
<h3 class="font-bold text-gray-800">✏️ 编辑签到规则</h3>
|
||||
<button type="button" data-sign-in-rule-close class="text-gray-400 hover:text-gray-600 text-xl">✕</button>
|
||||
</div>
|
||||
@@ -135,8 +140,7 @@
|
||||
@method('PUT')
|
||||
@include('admin.sign-in-rules.partials.form-fields', ['rule' => null, 'prefix' => 'edit-'])
|
||||
<div class="mt-5 flex items-center gap-4">
|
||||
<button type="submit"
|
||||
class="px-5 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm">
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">
|
||||
💾 保存修改
|
||||
</button>
|
||||
<label class="flex items-center gap-2 text-sm text-gray-600 cursor-pointer">
|
||||
@@ -144,7 +148,7 @@
|
||||
启用此规则
|
||||
</label>
|
||||
<button type="button" data-sign-in-rule-close
|
||||
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg font-bold hover:bg-gray-200 transition text-sm">
|
||||
class="{{ $adminListSecondaryButtonClass }}">
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -7,110 +7,117 @@
|
||||
@section('title', '会员购买日志')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-white p-5 rounded-xl border border-gray-100 shadow-sm mb-6">
|
||||
<form action="{{ route('admin.vip-payment-logs.index') }}" method="GET" class="flex flex-wrap items-end gap-4">
|
||||
<div class="flex-1 min-w-[140px]">
|
||||
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">用户名</label>
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form action="{{ route('admin.vip-payment-logs.index') }}" method="GET"
|
||||
class="{{ $adminListFilterFormClass }}">
|
||||
<div class="flex-1 min-w-[140px]">
|
||||
<label class="{{ $adminListFilterLabelClass }}">用户名</label>
|
||||
<input type="text" name="username" value="{{ request('username') }}"
|
||||
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2"
|
||||
class="w-full {{ $adminListFilterInputClass }}"
|
||||
placeholder="支持模糊搜索">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-w-[140px]">
|
||||
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">订单号/流水号</label>
|
||||
<div class="flex-1 min-w-[140px]">
|
||||
<label class="{{ $adminListFilterLabelClass }}">订单号/流水号</label>
|
||||
<input type="text" name="order_no" value="{{ request('order_no') }}"
|
||||
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2"
|
||||
class="w-full {{ $adminListFilterInputClass }}"
|
||||
placeholder="本地单号 / 平台单号 / 第三方单号">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-w-[130px]">
|
||||
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">订单状态</label>
|
||||
<select name="status"
|
||||
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2">
|
||||
<option value="">全部状态</option>
|
||||
@foreach ($statusOptions as $value => $label)
|
||||
<option value="{{ $value }}" {{ request('status') === $value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex-1 min-w-[130px]">
|
||||
<label class="{{ $adminListFilterLabelClass }}">订单状态</label>
|
||||
<select name="status" class="w-full {{ $adminListFilterInputClass }}">
|
||||
<option value="">全部状态</option>
|
||||
@foreach ($statusOptions as $value => $label)
|
||||
<option value="{{ $value }}" {{ request('status') === $value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="flex-none w-36">
|
||||
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">开始日期</label>
|
||||
<div class="flex-none w-36">
|
||||
<label class="{{ $adminListFilterLabelClass }}">开始日期</label>
|
||||
<input type="date" name="date_start" value="{{ request('date_start') }}"
|
||||
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2">
|
||||
</div>
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
|
||||
<div class="flex-none w-36">
|
||||
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">结束日期</label>
|
||||
<div class="flex-none w-36">
|
||||
<label class="{{ $adminListFilterLabelClass }}">结束日期</label>
|
||||
<input type="date" name="date_end" value="{{ request('date_end') }}"
|
||||
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm px-3 py-2">
|
||||
</div>
|
||||
class="w-full {{ $adminListFilterInputClass }}">
|
||||
</div>
|
||||
|
||||
<div class="flex-none flex items-center space-x-2">
|
||||
<button type="submit"
|
||||
class="bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-5 rounded-lg shadow-sm transition text-sm">查询</button>
|
||||
<a href="{{ route('admin.vip-payment-logs.index') }}"
|
||||
class="bg-white border border-gray-300 hover:bg-gray-50 text-gray-700 font-medium py-2 px-4 rounded-lg shadow-sm transition text-sm">重置</a>
|
||||
<div class="flex-none flex items-center gap-2">
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">查询</button>
|
||||
<a href="{{ route('admin.vip-payment-logs.index') }}"
|
||||
class="{{ $adminListSecondaryButtonClass }}">重置</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded shadow overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse min-w-[1200px]">
|
||||
<thead>
|
||||
<tr class="bg-gray-50 text-gray-600 text-sm uppercase tracking-wider border-b border-gray-200">
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">订单ID</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">用户</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">会员等级</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">本地订单号</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">平台支付单号</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">支付金额</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">状态</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">支付时间</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap">开通时间</th>
|
||||
<th class="px-6 py-4 font-semibold whitespace-nowrap text-right">创建时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} min-w-[1200px] text-left">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">订单ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">用户</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">会员等级</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">本地订单号</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">平台支付单号</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">支付金额</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">支付时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap">开通时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }} whitespace-nowrap text-right">创建时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($logs as $log)
|
||||
@php
|
||||
$statusClass = match ($log->status) {
|
||||
'paid' => 'bg-emerald-100 text-emerald-700',
|
||||
'pending' => 'bg-amber-100 text-amber-700',
|
||||
'closed' => 'bg-gray-100 text-gray-500',
|
||||
'failed' => 'bg-rose-100 text-rose-700',
|
||||
default => 'bg-slate-100 text-slate-700',
|
||||
'paid' => 'border-emerald-200 bg-emerald-100 text-emerald-700',
|
||||
'pending' => 'border-amber-200 bg-amber-100 text-amber-700',
|
||||
'closed' => 'border-gray-200 bg-gray-100 text-gray-500',
|
||||
'failed' => 'border-rose-200 bg-rose-100 text-rose-700',
|
||||
default => 'border-slate-200 bg-slate-100 text-slate-700',
|
||||
};
|
||||
@endphp
|
||||
<tr class="hover:bg-gray-50 transition cursor-default">
|
||||
<td class="px-6 py-4 text-sm text-gray-500">#{{ $log->id }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="font-bold text-gray-800 whitespace-nowrap">{{ $log->user?->username ?? '未知用户' }}</div>
|
||||
<tr class="{{ $adminListTableRowClass }} cursor-default">
|
||||
<td class="px-4 py-4 {{ $adminListSecondaryTextClass }}">#{{ $log->id }}</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap">
|
||||
<div class="{{ $adminListPrimaryTextClass }} whitespace-nowrap">{{ $log->user?->username ?? '未知用户' }}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<td class="px-4 py-4 whitespace-nowrap">
|
||||
<span style="color: {{ $log->vipLevel?->color ?: '#111827' }}">{{ $log->vipLevel?->icon ?: '👑' }}</span>
|
||||
<span class="font-bold text-gray-800 ml-1">{{ $log->vip_name }}</span>
|
||||
<span class="{{ $adminListPrimaryTextClass }} ml-1">{{ $log->vip_name }}</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 font-mono text-xs text-gray-600 whitespace-nowrap">{{ $log->order_no }}</td>
|
||||
<td class="px-6 py-4 font-mono text-xs text-gray-600 whitespace-nowrap">{{ $log->payment_order_no ?: '-' }}</td>
|
||||
<td class="px-6 py-4 font-bold text-rose-600 whitespace-nowrap">¥{{ number_format((float) $log->amount, 2) }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap"><span class="inline-flex px-2.5 py-1 rounded-full text-xs font-bold {{ $statusClass }}">{{ $statusOptions[$log->status] ?? $log->status }}</span></td>
|
||||
<td class="px-6 py-4 text-sm text-gray-500 whitespace-nowrap">{{ $log->paid_at?->format('Y-m-d H:i:s') ?? '未支付' }}</td>
|
||||
<td class="px-6 py-4 text-sm text-gray-500 whitespace-nowrap">{{ $log->opened_vip_at?->format('Y-m-d H:i:s') ?? '未开通' }}</td>
|
||||
<td class="px-6 py-4 text-sm text-gray-500 text-right whitespace-nowrap">{{ $log->created_at->format('Y-m-d H:i:s') }}</td>
|
||||
<td class="px-4 py-4 {{ $adminListNumericTextClass }} text-xs text-gray-600 whitespace-nowrap">{{ $log->order_no }}</td>
|
||||
<td class="px-4 py-4 {{ $adminListNumericTextClass }} text-xs text-gray-600 whitespace-nowrap">{{ $log->payment_order_no ?: '-' }}</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap font-bold text-rose-600">¥{{ number_format((float) $log->amount, 2) }}</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap">
|
||||
<span class="{{ $adminListBadgeBaseClass }} {{ $statusClass }}">{{ $statusOptions[$log->status] ?? $log->status }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-4 {{ $adminListBodyTextClass }} whitespace-nowrap">{{ $log->paid_at?->format('Y-m-d H:i:s') ?? '未支付' }}</td>
|
||||
<td class="px-4 py-4 {{ $adminListBodyTextClass }} whitespace-nowrap">{{ $log->opened_vip_at?->format('Y-m-d H:i:s') ?? '未开通' }}</td>
|
||||
<td class="px-4 py-4 {{ $adminListBodyTextClass }} text-right whitespace-nowrap">{{ $log->created_at->format('Y-m-d H:i:s') }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="10" class="px-6 py-8 text-center text-gray-500">📭 暂无会员购买记录</td>
|
||||
<td colspan="10" class="{{ $adminListEmptyClass }}">📭 暂无会员购买记录</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($logs->hasPages())
|
||||
<div class="px-6 py-4 border-t border-gray-200">{{ $logs->links() }}</div>
|
||||
@endif
|
||||
@if ($logs->hasPages())
|
||||
<div class="{{ $adminListPaginationClass }}">{{ $logs->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -8,81 +8,86 @@
|
||||
@section('title', $vip->name . ' 会员列表')
|
||||
|
||||
@section('content')
|
||||
<div class="space-y-6">
|
||||
<div class="flex flex-col gap-4 rounded-2xl border border-gray-200 bg-white p-6 shadow-sm lg:flex-row lg:items-center lg:justify-between">
|
||||
@php require resource_path('views/admin/partials/list-theme.php'); @endphp
|
||||
|
||||
<div class="{{ $adminListPageClass }}">
|
||||
<div class="{{ $adminListHeaderCardClass }}">
|
||||
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-3xl">{{ $vip->icon }}</span>
|
||||
<div>
|
||||
<h2 class="text-xl font-bold" style="color: {{ $vip->color }}">{{ $vip->name }} 会员列表</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">查看该等级下的会员用户名、当前状态与会员到期日期</p>
|
||||
<h2 class="{{ $adminListHeaderTitleClass }}" style="color: {{ $vip->color }}">{{ $vip->name }} 会员列表</h2>
|
||||
<p class="{{ $adminListHeaderSubtitleClass }}">查看该等级下的会员用户名、当前状态与会员到期日期</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 flex flex-wrap gap-3 text-sm">
|
||||
<span class="inline-flex items-center rounded-full bg-indigo-50 px-3 py-1 font-semibold text-indigo-600">
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-indigo-200 bg-indigo-50 px-3 py-1 text-indigo-600">
|
||||
总分配人数:{{ $totalAssignedCount }}
|
||||
</span>
|
||||
<span class="inline-flex items-center rounded-full bg-emerald-50 px-3 py-1 font-semibold text-emerald-600">
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-emerald-200 bg-emerald-50 px-3 py-1 text-emerald-600">
|
||||
当前有效会员:{{ $activeCount }}
|
||||
</span>
|
||||
<span class="inline-flex items-center rounded-full bg-amber-50 px-3 py-1 font-semibold text-amber-600">
|
||||
<span class="{{ $adminListBadgeBaseClass }} border-amber-200 bg-amber-50 px-3 py-1 text-amber-600">
|
||||
等级时长:{{ $vip->duration_days ?: '永久' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3">
|
||||
<div class="flex gap-3">
|
||||
<a href="{{ route('admin.vip.index') }}"
|
||||
class="inline-flex items-center justify-center rounded-lg border border-gray-300 px-4 py-2 text-sm font-semibold text-gray-600 transition hover:bg-gray-50">
|
||||
class="{{ $adminListSecondaryButtonClass }} inline-flex items-center justify-center">
|
||||
返回等级列表
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-2xl border border-gray-200 bg-white p-5 shadow-sm">
|
||||
<form action="{{ route('admin.vip.members', $vip->id) }}" method="GET" class="flex flex-wrap items-end gap-4">
|
||||
<div class="{{ $adminListFilterCardClass }}">
|
||||
<div class="{{ $adminListFilterInnerClass }}">
|
||||
<form action="{{ route('admin.vip.members', $vip->id) }}" method="GET" class="{{ $adminListFilterFormClass }}">
|
||||
<div class="min-w-[180px] flex-1">
|
||||
<label class="mb-1.5 block text-xs font-semibold uppercase tracking-wider text-gray-500">用户名</label>
|
||||
<label class="{{ $adminListFilterLabelClass }}">用户名</label>
|
||||
<input type="text" name="keyword" value="{{ request('keyword') }}"
|
||||
class="w-full rounded-lg border-gray-300 px-3 py-2 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
|
||||
class="w-full {{ $adminListFilterInputClass }}"
|
||||
placeholder="支持模糊搜索用户名">
|
||||
</div>
|
||||
<div class="w-44">
|
||||
<label class="mb-1.5 block text-xs font-semibold uppercase tracking-wider text-gray-500">会员状态</label>
|
||||
<select name="status"
|
||||
class="w-full rounded-lg border-gray-300 px-3 py-2 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
|
||||
<label class="{{ $adminListFilterLabelClass }}">会员状态</label>
|
||||
<select name="status" class="w-full {{ $adminListFilterInputClass }}">
|
||||
<option value="">全部状态</option>
|
||||
<option value="active" @selected(request('status') === 'active')>当前有效</option>
|
||||
<option value="expired" @selected(request('status') === 'expired')>已过期</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button type="submit"
|
||||
class="rounded-lg bg-indigo-600 px-5 py-2 text-sm font-semibold text-white transition hover:bg-indigo-700">
|
||||
<div class="flex gap-2">
|
||||
<button type="submit" class="{{ $adminListPrimaryButtonClass }}">
|
||||
查询
|
||||
</button>
|
||||
<a href="{{ route('admin.vip.members', $vip->id) }}"
|
||||
class="rounded-lg border border-gray-300 px-4 py-2 text-sm font-semibold text-gray-600 transition hover:bg-gray-50">
|
||||
class="{{ $adminListSecondaryButtonClass }}">
|
||||
重置
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-hidden rounded-2xl border border-gray-200 bg-white shadow-sm">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full text-left">
|
||||
<thead class="bg-gray-50 text-xs font-semibold uppercase tracking-wider text-gray-500">
|
||||
<div class="{{ $adminListCardClass }}">
|
||||
<div class="{{ $adminListTableWrapClass }}">
|
||||
<table class="{{ $adminListTableClass }} min-w-full text-left">
|
||||
<thead class="{{ $adminListTableHeadRowClass }}">
|
||||
<tr>
|
||||
<th class="px-6 py-4">用户ID</th>
|
||||
<th class="px-6 py-4">用户名</th>
|
||||
<th class="px-6 py-4">性别</th>
|
||||
<th class="px-6 py-4">会员状态</th>
|
||||
<th class="px-6 py-4">到期日期</th>
|
||||
<th class="px-6 py-4">注册时间</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">用户ID</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">用户名</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">性别</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">会员状态</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">到期日期</th>
|
||||
<th class="{{ $adminListTableHeadCellClass }}">注册时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100 text-sm text-gray-700">
|
||||
<tbody class="{{ $adminListTableBodyClass }}">
|
||||
@forelse ($members as $member)
|
||||
@php
|
||||
$status = $member->hy_time === null ? 'permanent' : ($member->hy_time->isFuture() ? 'active' : 'expired');
|
||||
@@ -92,9 +97,9 @@
|
||||
default => '已过期',
|
||||
};
|
||||
$statusClass = match ($status) {
|
||||
'permanent' => 'bg-purple-50 text-purple-600',
|
||||
'active' => 'bg-emerald-50 text-emerald-600',
|
||||
default => 'bg-rose-50 text-rose-600',
|
||||
'permanent' => 'border-purple-200 bg-purple-50 text-purple-600',
|
||||
'active' => 'border-emerald-200 bg-emerald-50 text-emerald-600',
|
||||
default => 'border-rose-200 bg-rose-50 text-rose-600',
|
||||
};
|
||||
$sexLabel = match ((int) $member->sex) {
|
||||
1 => '男',
|
||||
@@ -102,29 +107,29 @@
|
||||
default => '未知',
|
||||
};
|
||||
@endphp
|
||||
<tr class="transition hover:bg-gray-50">
|
||||
<td class="px-6 py-4 font-mono text-xs text-gray-500">#{{ $member->id }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="font-semibold text-gray-800">{{ $member->username }}</div>
|
||||
<tr class="{{ $adminListTableRowClass }}">
|
||||
<td class="px-4 py-4 {{ $adminListNumericTextClass }} text-xs text-gray-500">#{{ $member->id }}</td>
|
||||
<td class="px-4 py-4">
|
||||
<div class="{{ $adminListPrimaryTextClass }}">{{ $member->username }}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-gray-500">{{ $sexLabel }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex rounded-full px-2.5 py-1 text-xs font-semibold {{ $statusClass }}">
|
||||
<td class="px-4 py-4 {{ $adminListBodyTextClass }}">{{ $sexLabel }}</td>
|
||||
<td class="px-4 py-4">
|
||||
<span class="{{ $adminListBadgeBaseClass }} {{ $statusClass }}">
|
||||
{{ $statusLabel }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-gray-600">
|
||||
<td class="px-4 py-4 {{ $adminListBodyTextClass }}">
|
||||
@if ($member->hy_time)
|
||||
{{ $member->hy_time->format('Y-m-d H:i') }}
|
||||
@else
|
||||
永久
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-4 text-gray-500">{{ $member->created_at?->format('Y-m-d H:i') }}</td>
|
||||
<td class="px-4 py-4 {{ $adminListBodyTextClass }}">{{ $member->created_at?->format('Y-m-d H:i') }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="px-6 py-12 text-center text-sm text-gray-400">
|
||||
<td colspan="6" class="{{ $adminListEmptyClass }}">
|
||||
当前条件下暂无该等级会员记录
|
||||
</td>
|
||||
</tr>
|
||||
@@ -134,7 +139,7 @@
|
||||
</div>
|
||||
|
||||
@if ($members->hasPages())
|
||||
<div class="border-t border-gray-200 px-6 py-4">
|
||||
<div class="{{ $adminListPaginationClass }}">
|
||||
{{ $members->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
Reference in New Issue
Block a user