diff --git a/app/Http/Controllers/DutyHallController.php b/app/Http/Controllers/DutyHallController.php index caf6e60..910fa71 100644 --- a/app/Http/Controllers/DutyHallController.php +++ b/app/Http/Controllers/DutyHallController.php @@ -5,14 +5,20 @@ * 左侧五个子菜单:任职列表、日榜、周榜、月榜、总榜 * 路由:GET /duty-hall?tab=roster|day|week|month|all * + * 榜单统计三项指标: + * 1. 在线时长 — position_duty_logs.duration_seconds 合计 + * 2. 管理操作次数 — position_authority_logs 非任免类操作次数(warn/kick/mute/banip/other) + * 3. 奖励金币次数 — position_authority_logs WHERE action_type='reward' 的次数及累计金额 + * * @author ChatRoom Laravel * - * @version 1.1.0 + * @version 1.2.0 */ namespace App\Http\Controllers; use App\Models\Department; +use App\Models\PositionAuthorityLog; use App\Models\PositionDutyLog; use Illuminate\Http\Request; use Illuminate\View\View; @@ -26,7 +32,7 @@ class DutyHallController extends Controller { $tab = $request->input('tab', 'roster'); - // ── 任职列表:按部门→职务展示全部(含空缺) ──────────────────── + // ── 任职列表:按部门→职务展示全部(含空缺) ────────────────── $currentStaff = null; if ($tab === 'roster') { $currentStaff = Department::query() @@ -38,26 +44,64 @@ class DutyHallController extends Controller ->get(); } - // ── 日/周/月/总榜:勤务时长排行 ────────────────────────────────── + // ── 日/周/月/总榜:三项指标综合排行 ───────────────────────── $leaderboard = null; if (in_array($tab, ['day', 'week', 'month', 'all'])) { - $query = PositionDutyLog::query() + + // ① 在线时长(position_duty_logs) + $dutyQuery = PositionDutyLog::query() ->selectRaw('user_id, SUM(duration_seconds) as total_seconds, COUNT(*) as checkin_count'); - // 按时间段过滤 + // ② 管理操作(position_authority_logs,排除任命/撤销等人事操作) + $authQuery = PositionAuthorityLog::query() + ->selectRaw(' + user_id, + COUNT(*) as admin_count, + SUM(CASE WHEN action_type = \'reward\' THEN 1 ELSE 0 END) as reward_count, + SUM(CASE WHEN action_type = \'reward\' THEN COALESCE(amount, 0) ELSE 0 END) as reward_total + ') + ->whereNotIn('action_type', ['appoint', 'revoke']); + + // 按时间段同步过滤两张表 match ($tab) { - 'day' => $query->whereDate('login_at', today()), - 'week' => $query->whereBetween('login_at', [now()->startOfWeek(), now()->endOfWeek()]), - 'month' => $query->whereYear('login_at', now()->year)->whereMonth('login_at', now()->month), - 'all' => null, // 不加时间限制 + 'day' => [ + $dutyQuery->whereDate('login_at', today()), + $authQuery->whereDate('created_at', today()), + ], + 'week' => [ + $dutyQuery->whereBetween('login_at', [now()->startOfWeek(), now()->endOfWeek()]), + $authQuery->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()]), + ], + 'month' => [ + $dutyQuery->whereYear('login_at', now()->year)->whereMonth('login_at', now()->month), + $authQuery->whereYear('created_at', now()->year)->whereMonth('created_at', now()->month), + ], + 'all' => null, // 不限制时间 }; - $leaderboard = $query + // 执行查询 + $dutyRows = $dutyQuery ->groupBy('user_id') ->orderByDesc('total_seconds') ->limit(20) ->with('user') ->get(); + + // 管理操作数据(按 user_id 索引,方便后续合并) + $authMap = $authQuery + ->groupBy('user_id') + ->get() + ->keyBy('user_id'); + + // 合并两表数据:为每条勤务记录附加管理操作指标 + $leaderboard = $dutyRows->map(function ($row) use ($authMap) { + $auth = $authMap->get($row->user_id); + $row->admin_count = (int) ($auth?->admin_count ?? 0); + $row->reward_count = (int) ($auth?->reward_count ?? 0); + $row->reward_total = (int) ($auth?->reward_total ?? 0); + + return $row; + }); } // 各榜标签配置 diff --git a/resources/views/duty-hall/index.blade.php b/resources/views/duty-hall/index.blade.php index fcb88f6..e486c8d 100644 --- a/resources/views/duty-hall/index.blade.php +++ b/resources/views/duty-hall/index.blade.php @@ -154,7 +154,7 @@
{{ $periodLabel }} · 按在职期间登录时长排名
+{{ $periodLabel }} · 综合统计在线时长、管理操作、奖励金币
该时段暂无勤务记录
{{ $row->user?->username ?? '未知' }}
-LV.{{ $row->user?->user_level ?? '' }}
+LV.{{ $row->user?->user_level ?? '' }}
+ {{ $row->user?->username ?? '未知' }} +
+{{ $h }}h{{ $m }}m · + 登录{{ $row->checkin_count }}次
+⚡{{ $row->admin_count }}次管理
+ @endif + @if ($row->reward_count > 0) +🎁{{ $row->reward_count }}次奖励
+ @endif +