diff --git a/app/Http/Controllers/Admin/AppointmentController.php b/app/Http/Controllers/Admin/AppointmentController.php index ef2eb23..ce22a1a 100644 --- a/app/Http/Controllers/Admin/AppointmentController.php +++ b/app/Http/Controllers/Admin/AppointmentController.php @@ -182,6 +182,42 @@ class AppointmentController extends Controller return view('admin.appointments.history', compact('history')); } + /** + * 我的履职记录:展示当前登录者自己所有的权限操作记录 + * + * 不限于某一任职周期,展示全部历史操作,支持按操作类型和日期筛选。 + */ + public function myDutyLogs(Request $request): View + { + $user = Auth::user(); + $query = \App\Models\PositionAuthorityLog::where('user_id', $user->id) + ->with(['targetUser:id,username', 'targetPosition:id,name', 'userPosition.position.department']); + + // 按操作类型筛选 + if ($request->filled('type')) { + $query->where('action_type', $request->type); + } + + // 按日期范围筛选 + if ($request->filled('date_from')) { + $query->whereDate('created_at', '>=', $request->date_from); + } + if ($request->filled('date_to')) { + $query->whereDate('created_at', '<=', $request->date_to); + } + + $logs = $query->orderByDesc('created_at')->paginate(30)->withQueryString(); + + // 汇总统计 + $summary = \App\Models\PositionAuthorityLog::where('user_id', $user->id) + ->selectRaw('action_type, COUNT(*) as total, COALESCE(SUM(amount),0) as amount_sum') + ->groupBy('action_type') + ->get() + ->keyBy('action_type'); + + return view('admin.appointments.my-duty-logs', compact('logs', 'summary', 'user')); + } + /** * 搜索用户(供任命弹窗 Ajax 快速查找) */ diff --git a/resources/views/admin/appointments/my-duty-logs.blade.php b/resources/views/admin/appointments/my-duty-logs.blade.php new file mode 100644 index 0000000..990d5d8 --- /dev/null +++ b/resources/views/admin/appointments/my-duty-logs.blade.php @@ -0,0 +1,206 @@ +{{-- + 文件功能:我的履职记录页面 + 展示当前登录者自己的全部权限操作记录(奖励、踢人、禁言、任命等) + 支持按操作类型和日期范围筛选,顶部显示各类操作汇总统计卡片 + + @author ChatRoom Laravel + @version 1.0.0 +--}} + +@extends('admin.layouts.app') + +@section('title', '我的履职记录') + +@section('content') + + {{-- ── 页面标题 ── --}} +
+

📝 我的履职记录

+

+ {{ $user->username }} 的全部职务操作历史,共 + {{ $logs->total() }} 条记录 +

+
+ + {{-- ── 汇总统计卡片 ── --}} + @php + $statCards = [ + 'reward' => ['label' => '奖励发放', 'icon' => '🪙', 'color' => 'yellow'], + 'kick' => ['label' => '踢出操作', 'icon' => '🚫', 'color' => 'red'], + 'mute' => ['label' => '禁言操作', 'icon' => '🔇', 'color' => 'purple'], + 'warn' => ['label' => '警告操作', 'icon' => '⚠️', 'color' => 'orange'], + 'appoint' => ['label' => '任命操作', 'icon' => '🎖️', 'color' => 'green'], + 'revoke' => ['label' => '撤职操作', 'icon' => '❌', 'color' => 'gray'], + ]; + $colorMap = [ + 'yellow' => [ + 'bg' => 'bg-yellow-50', + 'border' => 'border-yellow-200', + 'text' => 'text-yellow-700', + 'badge' => 'bg-yellow-100 text-yellow-800', + ], + 'red' => [ + 'bg' => 'bg-red-50', + 'border' => 'border-red-200', + 'text' => 'text-red-700', + 'badge' => 'bg-red-100 text-red-800', + ], + 'purple' => [ + 'bg' => 'bg-purple-50', + 'border' => 'border-purple-200', + 'text' => 'text-purple-700', + 'badge' => 'bg-purple-100 text-purple-800', + ], + 'orange' => [ + 'bg' => 'bg-orange-50', + 'border' => 'border-orange-200', + 'text' => 'text-orange-700', + 'badge' => 'bg-orange-100 text-orange-800', + ], + 'green' => [ + 'bg' => 'bg-green-50', + 'border' => 'border-green-200', + 'text' => 'text-green-700', + 'badge' => 'bg-green-100 text-green-800', + ], + 'gray' => [ + 'bg' => 'bg-gray-50', + 'border' => 'border-gray-200', + 'text' => 'text-gray-700', + 'badge' => 'bg-gray-100 text-gray-800', + ], + ]; + @endphp + +
+ @foreach ($statCards as $type => $card) + @php + $stat = $summary->get($type); + $c = $colorMap[$card['color']]; + @endphp + +
{{ $card['icon'] }}
+
{{ $card['label'] }}
+
{{ $stat?->total ?? 0 }}
+ @if ($type === 'reward' && ($stat?->amount_sum ?? 0) > 0) +
共 {{ number_format($stat->amount_sum) }} 金币
+ @endif +
+ @endforeach +
+ + {{-- ── 筛选栏 ── --}} +
+
+ + +
+
+ + +
+
+ + +
+ + @if (request()->hasAny(['type', 'date_from', 'date_to'])) + + ✖ 清除筛选 + + @endif +
+ + {{-- ── 记录表格 ── --}} + @php + $actionColors = [ + 'appoint' => 'bg-green-100 text-green-700', + 'revoke' => 'bg-red-100 text-red-700', + 'reward' => 'bg-yellow-100 text-yellow-700', + 'warn' => 'bg-orange-100 text-orange-700', + 'kick' => 'bg-red-100 text-red-700', + 'mute' => 'bg-purple-100 text-purple-700', + 'banip' => 'bg-gray-200 text-gray-700', + 'other' => 'bg-gray-100 text-gray-600', + ]; + @endphp + +
+ + + + + + + + + + + + + @forelse ($logs as $log) + @php $colorClass = $actionColors[$log->action_type] ?? 'bg-gray-100 text-gray-600'; @endphp + + + + + + + + + @empty + + + + @endforelse + +
操作时间操作类型操作对象所属职务金币金额备注说明
+ {{ $log->created_at->format('Y-m-d H:i') }} + + + {{ $log->action_label }} + + + {{ $log->targetUser?->username ?? '—' }} + + @if ($log->userPosition?->position) + {{ $log->userPosition->position->department?->name }} + @if ($log->userPosition->position->department) + · + @endif + {{ $log->userPosition->position->name }} + @else + 超级管理员 + @endif + + @if ($log->amount) + +{{ number_format($log->amount) }} + 金币 + @else + + @endif + {{ $log->remark ?: '—' }}
+
📋
+
暂无履职操作记录
+
+
+ +
{{ $logs->links() }}
+ +@endsection diff --git a/resources/views/admin/layouts/app.blade.php b/resources/views/admin/layouts/app.blade.php index 7205f34..17535ea 100644 --- a/resources/views/admin/layouts/app.blade.php +++ b/resources/views/admin/layouts/app.blade.php @@ -34,8 +34,12 @@ {{-- ──────── 部门职务任命系统 ──────── --}}
+ + 📝 我的履职记录 + + class="block px-4 py-3 rounded-md transition {{ request()->routeIs('admin.appointments.*') && !request()->routeIs('admin.appointments.my-duty-logs') ? 'bg-indigo-600 font-bold' : 'hover:bg-white/10' }}"> 🎖️ 任命管理 diff --git a/routes/web.php b/routes/web.php index abeb876..917cb44 100644 --- a/routes/web.php +++ b/routes/web.php @@ -176,6 +176,9 @@ Route::middleware(['chat.auth', 'chat.has_position'])->prefix('admin')->name('ad return view('admin.whispers'); })->name('whispers.index'); + // 我的履职记录(当前登录者自己的权限操作记录) + Route::get('/my-duty-logs', [\App\Http\Controllers\Admin\AppointmentController::class, 'myDutyLogs'])->name('appointments.my-duty-logs'); + // 任命管理(任命权限由 AppointmentService 内部校验) Route::get('/appointments', [\App\Http\Controllers\Admin\AppointmentController::class, 'index'])->name('appointments.index'); Route::post('/appointments', [\App\Http\Controllers\Admin\AppointmentController::class, 'store'])->name('appointments.store');