184 lines
6.2 KiB
PHP
184 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
use Spatie\Activitylog\Models\Activity;
|
|
use App\Models\User;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class ActivityLogController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$user = auth()->user();
|
|
|
|
// Permission check
|
|
if (!$user->can('manage-activity-logs')) {
|
|
abort(403);
|
|
}
|
|
|
|
$query = Activity::with('causer')
|
|
->orderBy('created_at', 'desc');
|
|
|
|
// Filter by module (log_name)
|
|
if ($request->filled('module')) {
|
|
$query->where('log_name', $request->module);
|
|
}
|
|
|
|
// Filter by user (causer)
|
|
if ($request->filled('user_id')) {
|
|
$query->where('causer_id', $request->user_id)
|
|
->where('causer_type', User::class);
|
|
}
|
|
|
|
// Filter by event type
|
|
if ($request->filled('event')) {
|
|
$query->where('event', $request->event);
|
|
}
|
|
|
|
// Filter by date range
|
|
if ($request->filled('date_from')) {
|
|
$query->whereDate('created_at', '>=', $request->date_from);
|
|
}
|
|
if ($request->filled('date_to')) {
|
|
$query->whereDate('created_at', '<=', $request->date_to);
|
|
}
|
|
|
|
// Search in description
|
|
if ($request->filled('search')) {
|
|
$search = $request->search;
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('description', 'like', "%{$search}%")
|
|
->orWhere('properties', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
// Sorting
|
|
$sortField = $request->get('sort', 'created_at');
|
|
$sortDirection = $request->get('direction', 'desc');
|
|
$allowedSorts = ['created_at', 'log_name', 'event', 'description'];
|
|
if (in_array($sortField, $allowedSorts)) {
|
|
$query->orderBy($sortField, $sortDirection === 'asc' ? 'asc' : 'desc');
|
|
}
|
|
|
|
$perPage = $request->get('per_page', 25);
|
|
$activities = $query->paginate($perPage)->withQueryString();
|
|
|
|
// Transform for frontend
|
|
$activities->through(function ($activity) {
|
|
return [
|
|
'id' => $activity->id,
|
|
'log_name' => $activity->log_name,
|
|
'description' => $activity->description,
|
|
'event' => $activity->event,
|
|
'subject_type' => $activity->subject_type ? class_basename($activity->subject_type) : null,
|
|
'subject_id' => $activity->subject_id,
|
|
'causer' => $activity->causer ? [
|
|
'id' => $activity->causer->id,
|
|
'name' => $activity->causer->name,
|
|
'email' => $activity->causer->email,
|
|
'type' => $activity->causer->type ?? null,
|
|
] : null,
|
|
'properties' => $activity->properties?->toArray() ?? [],
|
|
'changes' => $activity->attribute_changes ?? null,
|
|
'created_at' => $activity->created_at->toISOString(),
|
|
];
|
|
});
|
|
|
|
// Get available modules for filter dropdown
|
|
$modules = Activity::select('log_name')
|
|
->distinct()
|
|
->whereNotNull('log_name')
|
|
->orderBy('log_name')
|
|
->pluck('log_name');
|
|
|
|
// Get users for filter dropdown
|
|
$users = User::select('id', 'name', 'email')
|
|
->whereIn('id', Activity::select('causer_id')->whereNotNull('causer_id')->distinct())
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
return Inertia::render('ActivityLogs/Index', [
|
|
'activities' => $activities,
|
|
'modules' => $modules,
|
|
'users' => $users,
|
|
'filters' => [
|
|
'module' => $request->get('module', ''),
|
|
'user_id' => $request->get('user_id', ''),
|
|
'event' => $request->get('event', ''),
|
|
'date_from' => $request->get('date_from', ''),
|
|
'date_to' => $request->get('date_to', ''),
|
|
'search' => $request->get('search', ''),
|
|
'per_page' => $perPage,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function export(Request $request): StreamedResponse
|
|
{
|
|
$user = auth()->user();
|
|
|
|
if (!$user->can('manage-activity-logs')) {
|
|
abort(403);
|
|
}
|
|
|
|
$query = Activity::with('causer')
|
|
->orderBy('created_at', 'desc');
|
|
|
|
if ($request->filled('module')) {
|
|
$query->where('log_name', $request->module);
|
|
}
|
|
if ($request->filled('user_id')) {
|
|
$query->where('causer_id', $request->user_id)
|
|
->where('causer_type', User::class);
|
|
}
|
|
if ($request->filled('event')) {
|
|
$query->where('event', $request->event);
|
|
}
|
|
if ($request->filled('date_from')) {
|
|
$query->whereDate('created_at', '>=', $request->date_from);
|
|
}
|
|
if ($request->filled('date_to')) {
|
|
$query->whereDate('created_at', '<=', $request->date_to);
|
|
}
|
|
if ($request->filled('search')) {
|
|
$query->where('description', 'like', "%{$request->search}%");
|
|
}
|
|
|
|
$activities = $query->get();
|
|
|
|
return response()->streamDownload(function () use ($activities) {
|
|
$handle = fopen('php://output', 'w');
|
|
|
|
// CSV header
|
|
fputcsv($handle, [
|
|
'Date/Time',
|
|
'User',
|
|
'Email',
|
|
'Action',
|
|
'Module',
|
|
'Description',
|
|
'Subject',
|
|
]);
|
|
|
|
foreach ($activities as $activity) {
|
|
fputcsv($handle, [
|
|
$activity->created_at->format('Y-m-d H:i:s'),
|
|
$activity->causer?->name ?? 'System',
|
|
$activity->causer?->email ?? '',
|
|
$activity->event ?? '',
|
|
$activity->log_name ?? '',
|
|
$activity->description,
|
|
$activity->subject_type ? class_basename($activity->subject_type) . ' #' . $activity->subject_id : '',
|
|
]);
|
|
}
|
|
|
|
fclose($handle);
|
|
}, 'activity-logs-' . now()->format('Y-m-d') . '.csv', [
|
|
'Content-Type' => 'text/csv',
|
|
]);
|
|
}
|
|
}
|