Initial Ladill Queue release — enterprise QMS standalone app.
Deploy Ladill Queue / deploy (push) Successful in 56s
Deploy Ladill Queue / deploy (push) Successful in 56s
Phases 1–6: tickets, counters, displays, appointments, workflows, rules, analytics, reports, feedback, admin, device API, and Gitea deploy workflow for queue.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Qms;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Qms\Concerns\ScopesToAccount;
|
||||
use App\Models\AuditLog;
|
||||
use App\Services\Qms\QmsPermissions;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class AuditLogController extends Controller
|
||||
{
|
||||
use ScopesToAccount;
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$this->authorizeAbility($request, 'audit.view');
|
||||
$organization = $this->organization($request);
|
||||
|
||||
$logs = $this->query($request, $organization)->paginate(50)->withQueryString();
|
||||
|
||||
return view('qms.audit.index', [
|
||||
'logs' => $logs,
|
||||
'organization' => $organization,
|
||||
'actions' => config('qms.audit_actions'),
|
||||
'canExport' => app(QmsPermissions::class)->can($this->member($request), 'audit.export'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function export(Request $request): StreamedResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'audit.export');
|
||||
$organization = $this->organization($request);
|
||||
|
||||
$filename = 'queue-audit-'.now()->format('Y-m-d-His').'.csv';
|
||||
|
||||
return response()->streamDownload(function () use ($request, $organization) {
|
||||
$handle = fopen('php://output', 'w');
|
||||
fputcsv($handle, ['Time', 'Action', 'Actor', 'Subject', 'Metadata', 'IP']);
|
||||
|
||||
$this->query($request, $organization)->chunk(200, function ($logs) use ($handle) {
|
||||
foreach ($logs as $log) {
|
||||
fputcsv($handle, [
|
||||
$log->created_at?->toDateTimeString(),
|
||||
$log->action,
|
||||
$log->actor_ref ?? '—',
|
||||
$log->subject_type ? class_basename($log->subject_type).' #'.$log->subject_id : '—',
|
||||
json_encode($log->metadata ?? []),
|
||||
$log->ip_address ?? '—',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
fclose($handle);
|
||||
}, $filename, ['Content-Type' => 'text/csv']);
|
||||
}
|
||||
|
||||
protected function query(Request $request, $organization)
|
||||
{
|
||||
return AuditLog::owned($this->ownerRef($request))
|
||||
->where('organization_id', $organization->id)
|
||||
->when($request->action, fn ($q, $action) => $q->where('action', $action))
|
||||
->when($request->from, fn ($q, $from) => $q->where('created_at', '>=', Carbon::parse($from)->startOfDay()))
|
||||
->when($request->to, fn ($q, $to) => $q->where('created_at', '<=', Carbon::parse($to)->endOfDay()))
|
||||
->when($request->q, function ($q, $search) {
|
||||
$q->where(function ($inner) use ($search) {
|
||||
$inner->where('action', 'like', "%{$search}%")
|
||||
->orWhere('metadata', 'like', "%{$search}%");
|
||||
});
|
||||
})
|
||||
->orderByDesc('created_at');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user