Files
chatroom/resources/views/duty-hall/index.blade.php

316 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{--
文件功能:勤务台页面(职务管理荣誉展示台)
左侧子菜单:任职列表、日榜、周榜、月榜、总榜
URL/duty-hall?tab=roster|day|week|month|all
@extends layouts.app
--}}
@extends('layouts.app')
@section('title', '勤务台 · ' . ($tabs[$tab]['label'] ?? '任职列表') . ' - 飘落流星')
@section('nav-icon', '🏛️')
@section('nav-title', '勤务台')
@section('content')
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 flex gap-6 items-start">
{{-- ═══ 左侧子菜单 ═══ --}}
<aside
class="w-52 shrink-0 bg-white border border-gray-100 rounded-2xl shadow-sm overflow-hidden sticky top-20 self-start hidden md:block">
<div class="px-4 pt-4 pb-2">
<p class="text-xs font-bold text-gray-400 uppercase tracking-widest mb-3">勤务台</p>
<nav class="space-y-1">
@foreach ($tabs as $key => $meta)
<a href="{{ route('duty-hall.index', ['tab' => $key]) }}"
class="flex items-center gap-2.5 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors
{{ $tab === $key
? 'bg-purple-50 text-purple-700 font-bold'
: 'text-gray-600 hover:bg-gray-50 hover:text-gray-800' }}">
<span class="text-base">{{ $meta['icon'] }}</span>
<span>{{ $meta['label'] }}</span>
@if ($tab === $key)
<span class="ml-auto w-1.5 h-1.5 rounded-full bg-purple-600"></span>
@endif
</a>
@endforeach
</nav>
</div>
<div class="px-4 py-3 mt-2 border-t border-gray-50 text-xs text-gray-400 text-center">
光荣服务,公示透明
</div>
</aside>
{{-- ═══ 主内容区 ═══ --}}
<main class="flex-1 min-w-0">
{{-- ─── Tab任职列表 ─── --}}
@if ($tab === 'roster')
<div class="mb-4">
<h2 class="text-lg font-bold text-gray-800">🏛️ 任职列表</h2>
<p class="text-xs text-gray-400 mt-0.5">按部门 · 职务展示当前全部在职人员</p>
</div>
@if ($currentStaff->isEmpty())
<div class="bg-white rounded-2xl border border-gray-100 shadow-sm py-20 text-center text-gray-400">
<div class="text-5xl mb-4">📭</div>
<p>暂未设置任何部门</p>
</div>
@else
<div class="space-y-5">
@foreach ($currentStaff as $dept)
<div class="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden">
{{-- 部门标题 --}}
<div
class="px-5 py-3 bg-gradient-to-r from-purple-50 to-indigo-50 border-b border-gray-100 flex items-center gap-2">
<span class="text-base">{{ $dept->icon ?? '🏢' }}</span>
<span class="font-bold text-purple-700 text-sm">{{ $dept->name }}</span>
<span class="ml-auto text-xs text-gray-400">{{ $dept->positions->count() }} 个职务</span>
</div>
@if ($dept->positions->isEmpty())
<div class="px-5 py-4 text-xs text-gray-400 italic">该部门暂无职务设置</div>
@else
<div class="divide-y divide-gray-50">
@foreach ($dept->positions as $position)
<div class="px-5 py-3">
{{-- 职务名 --}}
<div class="flex items-center gap-1.5 mb-2">
<span class="text-sm">{{ $position->icon }}</span>
<span
class="text-sm font-semibold text-gray-700">{{ $position->name }}</span>
@php
$current = $position->activeUserPositions->count();
$maxSlots = $position->max_persons;
$isFull = $maxSlots !== null && $current >= $maxSlots;
@endphp
{{-- 名额计数标签 --}}
<span
class="ml-1 inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded-md text-[10px] font-bold
{{ $current === 0
? 'bg-gray-100 text-gray-400'
: ($isFull
? 'bg-red-100 text-red-600'
: 'bg-purple-100 text-purple-600') }}">
{{ $current }}
@if ($maxSlots !== null)
<span class="opacity-60">/{{ $maxSlots }}</span>
@endif
</span>
@if ($isFull)
<span class="text-[10px] text-red-400">已满</span>
@elseif ($current === 0)
<span class="text-[10px] text-gray-300">(暂缺)</span>
@endif
</div>
{{-- 在职人员列表 --}}
@if ($position->activeUserPositions->isNotEmpty())
<div class="flex flex-wrap gap-2">
@foreach ($position->activeUserPositions as $up)
<div
class="flex items-center gap-2 px-3 py-1.5 bg-gray-50 border border-gray-100 rounded-xl">
<img src="{{ $up->user?->headface_url ?? '/images/headface/1.gif' }}"
class="w-7 h-7 rounded-full border border-purple-100 object-cover bg-white"
onerror="this.src='/images/headface/1.gif'">
<div>
<p class="text-xs font-bold text-gray-800">
{{ $up->user?->username ?? '未知' }}</p>
<p class="text-[10px] text-gray-400">
{{ $up->appointed_at?->format('Y-m-d') }} ·
{{ $up->duration_days }} </p>
</div>
</div>
@endforeach
</div>
@else
{{-- 空缺占位 --}}
<div
class="flex items-center gap-2 px-3 py-2 border border-dashed border-gray-200 rounded-xl text-xs text-gray-300 w-fit">
<span>👤</span>
<span>暂无任职人员</span>
</div>
@endif
</div>
@endforeach
</div>
@endif
</div>
@endforeach
</div>
@endif
{{-- ─── Tab///总榜 ─── --}}
@else
@php
$tabMeta = $tabs[$tab];
$periodLabel = match ($tab) {
'day' => today()->format('Y年m月d日'),
'week' => now()->startOfWeek()->format('m月d日') . ' ' . now()->endOfWeek()->format('m月d日'),
'month' => now()->format('Y年m月'),
'all' => '历史累计',
};
@endphp
<div class="mb-4">
<h2 class="text-lg font-bold text-gray-800">{{ $tabMeta['icon'] }} 勤务{{ $tabMeta['label'] }}</h2>
<p class="text-xs text-gray-400 mt-0.5">{{ $periodLabel }} · 综合统计在线时长、管理操作、奖励金币</p>
</div>
<div class="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden">
@if ($leaderboard->isEmpty())
<div class="py-20 text-center text-gray-400">
<div class="text-5xl mb-4">📊</div>
<p>该时段暂无勤务记录</p>
</div>
@else
{{-- 表头桌面端网格名次1 + 成员4 + 在线3 + 签到2 + 管理操作2 --}}
<div
class="hidden md:grid grid-cols-12 gap-2 px-5 py-2.5 bg-gray-50 border-b border-gray-100 text-xs font-bold text-gray-400 uppercase tracking-wide">
<div class="col-span-1 text-center">名次</div>
<div class="col-span-4">成员</div>
<div class="col-span-3 text-right">🕐 在线时长</div>
<div class="col-span-2 text-right">📋 登录</div>
<div class="col-span-1 text-right">⚡管理</div>
<div class="col-span-1 text-right">🎁奖励</div>
</div>
@foreach ($leaderboard as $i => $row)
@php
$h = intdiv($row->total_seconds, 3600);
$m = intdiv($row->total_seconds % 3600, 60);
$medal = match ($i) {
0 => '🥇',
1 => '🥈',
2 => '🥉',
default => null,
};
$rowBg = match ($i) {
0 => 'bg-yellow-50/50',
1 => 'bg-gray-50/70',
2 => 'bg-amber-50/40',
default => '',
};
@endphp
{{-- 桌面端行 --}}
<div
class="hidden md:grid grid-cols-12 gap-2 items-center px-5 py-3.5
border-b border-gray-50 last:border-0 {{ $rowBg }}
hover:bg-purple-50/30 transition-colors">
{{-- 名次 --}}
<div class="col-span-1 text-center">
@if ($medal)
<span class="text-xl">{{ $medal }}</span>
@else
<span class="text-sm font-bold text-gray-300">{{ $i + 1 }}</span>
@endif
</div>
{{-- 成员 --}}
<div class="col-span-4 flex items-center gap-3">
<img src="{{ $row->user?->headface_url ?? '/images/headface/1.gif' }}"
class="w-9 h-9 rounded-full border-2 border-purple-100 object-cover bg-white"
onerror="this.src='/images/headface/1.gif'">
<div>
<p class="font-bold text-sm text-gray-800">{{ $row->user?->username ?? '未知' }}</p>
<p class="text-[10px] text-gray-400">LV.{{ $row->user?->user_level ?? '' }}</p>
</div>
</div>
{{-- 在线时长 --}}
<div class="col-span-3 text-right">
<span class="text-sm font-bold text-purple-600 tabular-nums">{{ $h }}h
{{ $m }}m</span>
</div>
{{-- 登录次数 --}}
<div class="col-span-2 text-right">
<span class="text-sm font-bold text-indigo-500 tabular-nums">{{ $row->checkin_count }}
</span>
</div>
{{-- 管理操作次数 --}}
<div class="col-span-1 text-right">
@if ($row->admin_count > 0)
<span
class="inline-flex items-center justify-end gap-0.5 text-sm font-bold text-orange-500 tabular-nums">
{{ $row->admin_count }}
</span>
@else
<span class="text-gray-300 text-sm"></span>
@endif
</div>
{{-- 奖励金币次数 --}}
<div class="col-span-1 text-right">
@if ($row->reward_count > 0)
<span class="text-sm font-bold text-emerald-500 tabular-nums"
title="{{ $row->reward_count }}次 · 共{{ $row->reward_total }}金币">
{{ $row->reward_count }}
</span>
@else
<span class="text-gray-300 text-sm"></span>
@endif
</div>
</div>
{{-- 移动端:紧凑卡片 --}}
<div
class="md:hidden flex items-center gap-3 px-4 py-3 border-b border-gray-50 last:border-0 {{ $rowBg }}">
<div class="w-7 text-center shrink-0">
@if ($medal)
<span class="text-lg">{{ $medal }}</span>
@else
<span class="text-xs font-bold text-gray-300">{{ $i + 1 }}</span>
@endif
</div>
<img src="{{ $row->user?->headface_url ?? '/images/headface/1.gif' }}"
class="w-8 h-8 rounded-full border border-purple-100 object-cover bg-white shrink-0"
onerror="this.src='/images/headface/1.gif'">
<div class="flex-1 min-w-0">
<p class="font-bold text-sm text-gray-800 truncate">{{ $row->user?->username ?? '未知' }}
</p>
<p class="text-[10px] text-gray-400">{{ $h }}h{{ $m }}m ·
登录{{ $row->checkin_count }}</p>
</div>
<div class="text-right shrink-0 space-y-0.5">
@if ($row->admin_count > 0)
<p class="text-xs font-bold text-orange-500">{{ $row->admin_count }}次管理</p>
@endif
@if ($row->reward_count > 0)
<p class="text-xs font-bold text-emerald-500">🎁{{ $row->reward_count }}次奖励</p>
@endif
</div>
</div>
@endforeach
{{-- 图例说明 --}}
<div
class="px-5 py-2.5 bg-gray-50/60 border-t border-gray-50 text-[10px] text-gray-400 flex flex-wrap gap-x-4 gap-y-1">
<span>🕐 在线时长:在职期间进入房间的累计时长</span>
<span>📋 登录:进入房间次数</span>
<span> 管理:警告/踢出/禁言/封IP等操作次数</span>
<span>🎁 奖励:发送奖励金币次数(悬停查看总金额)</span>
</div>
@endif
</div>
@endif
</main>
</div>
{{-- 移动端底部 Tab 导航 --}}
<div class="md:hidden fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 flex z-30">
@foreach ($tabs as $key => $meta)
<a href="{{ route('duty-hall.index', ['tab' => $key]) }}"
class="flex-1 flex flex-col items-center py-2 text-xs
{{ $tab === $key ? 'text-purple-600 font-bold' : 'text-gray-500' }}">
<span class="text-lg">{{ $meta['icon'] }}</span>
<span class="mt-0.5">{{ $meta['label'] }}</span>
</a>
@endforeach
</div>
@endsection