resolveCauser(); LogActivityJob::dispatch([ 'log_name' => $logName, 'event' => $event, 'description' => $description, 'subject_type' => $subject ? get_class($subject) : null, 'subject_id' => $subject?->getKey(), 'causer_type' => $causerType, 'causer_id' => $causerId, 'causer_name' => $causerName, 'old_values' => $oldValues ?: null, 'new_values' => $newValues ?: null, 'ip_address' => request()->getClientIp(), 'user_agent' => request()->userAgent(), 'started_at' => $startedAt?->format('Y-m-d H:i:s.v'), 'finished_at' => $finishedAt?->format('Y-m-d H:i:s.v'), 'created_at' => now()->format('Y-m-d H:i:s.v'), ]); } catch (\Throwable $e) { Log::warning('[ActivityLogger] Failed to dispatch log job', [ 'error' => $e->getMessage(), 'event' => $event, 'log_name' => $logName, ]); } } public function logCreated(Model $model, string $logName): void { $causer = $this->getCauserName(); $id = $model->getKey(); $this->log( event: 'created', logName: $logName, description: "$causer tạo mới $logName" . ($id ? " #$id" : ''), subject: $model, newValues: $this->filterValues($model->getAttributes()), ); } public function logUpdated(Model $model, string $logName): void { $dirty = $model->getDirty(); if (empty($dirty)) { return; } $dirty = $this->filterValues($dirty); $original = $this->filterValues(array_intersect_key($model->getOriginal(), $dirty)); if (empty($dirty)) { return; } $causer = $this->getCauserName(); $id = $model->getKey(); $fields = implode(', ', array_keys($dirty)); $this->log( event: 'updated', logName: $logName, description: "$causer cập nhật $logName" . ($id ? " #$id" : '') . " [$fields]", subject: $model, oldValues: $original, newValues: $dirty, ); } public function logDeleted(Model $model, string $logName): void { $causer = $this->getCauserName(); $id = $model->getOriginal($model->getKeyName()) ?? $model->getKey(); $this->log( event: 'deleted', logName: $logName, description: "$causer xóa $logName" . ($id ? " #$id" : ''), subject: $model, ); } public function logRestored(Model $model, string $logName): void { $causer = $this->getCauserName(); $id = $model->getKey(); $this->log( event: 'restored', logName: $logName, description: "$causer khôi phục $logName" . ($id ? " #$id" : ''), subject: $model, ); } public function logAuth(string $event, string $causerType, $causerId, string $causerName): void { $action = match ($event) { 'login' => 'đăng nhập', 'logout' => 'đăng xuất', 'register' => 'đăng ký tài khoản', default => $event, }; $this->log( event: $event, logName: 'auth', description: "[$causerType] $causerName $action", subject: null, oldValues: [], newValues: ['causer_type' => $causerType, 'causer_id' => $causerId, 'causer_name' => $causerName], ); } private function resolveCauser(): array { if ($admin = auth()->guard('admin')->user()) { return ['admin', $admin->id, $admin->username ?? $admin->email]; } if ($customer = auth()->guard('client')->user()) { return ['customer', $customer->id, $customer->email ?? $customer->name]; } return ['system', null, 'System']; } public function getCauserName(): string { [, , $name] = $this->resolveCauser(); return $name; } private function filterValues(array $values): array { return array_diff_key($values, array_flip($this->hiddenFields)); } }