OperationAuditService.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. <?php
  2. namespace App\Services;
  3. use App\Models\OperationAudit;
  4. use Illuminate\Database\Eloquent\Model;
  5. class OperationAuditService
  6. {
  7. private const SENSITIVE_KEYS = ['secret', 'key', 'password', 'token', 'private'];
  8. public static function record(string $resourceType, ?int $resourceId, string $action, $before, $after, ?string $createdAt = null, ?array $actor = null): void
  9. {
  10. $admin = request()->user ?? null;
  11. $attributes = [
  12. 'resource_type' => $resourceType,
  13. 'resource_id' => $resourceId,
  14. 'action' => $action,
  15. 'changes' => [
  16. 'before' => self::sanitize(self::toArray($before)),
  17. 'after' => self::sanitize(self::toArray($after)),
  18. ],
  19. 'operator_id' => $actor !== null ? ($actor['operator_id'] ?? null) : ($admin->id ?? null),
  20. 'operator_name' => $actor !== null ? (string) ($actor['operator_name'] ?? '') : (string)($admin->username ?? ''),
  21. ];
  22. if ($createdAt !== null) $attributes['created_at'] = $createdAt;
  23. OperationAudit::query()->create($attributes);
  24. }
  25. public static function actor(): array
  26. {
  27. $admin = request()->user ?? null;
  28. return [
  29. 'operator_id' => $admin->id ?? null,
  30. 'operator_name' => (string)($admin->username ?? ''),
  31. ];
  32. }
  33. private static function toArray($value): array
  34. {
  35. if ($value instanceof Model) {
  36. return $value->toArray();
  37. }
  38. return is_array($value) ? $value : [];
  39. }
  40. private static function sanitize(array $value): array
  41. {
  42. foreach ($value as $key => $item) {
  43. $normalized = strtolower((string)$key);
  44. foreach (self::SENSITIVE_KEYS as $needle) {
  45. if (str_contains($normalized, $needle)) {
  46. $value[$key] = empty($item) ? null : '******';
  47. continue 2;
  48. }
  49. }
  50. if (is_array($item)) {
  51. $value[$key] = self::sanitize($item);
  52. }
  53. }
  54. return $value;
  55. }
  56. }