OperationAuditService.php 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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): void
  9. {
  10. $admin = request()->user ?? null;
  11. OperationAudit::query()->create([
  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' => $admin->id ?? null,
  20. 'operator_name' => (string)($admin->username ?? ''),
  21. ]);
  22. }
  23. public static function actor(): array
  24. {
  25. $admin = request()->user ?? null;
  26. return [
  27. 'operator_id' => $admin->id ?? null,
  28. 'operator_name' => (string)($admin->username ?? ''),
  29. ];
  30. }
  31. private static function toArray($value): array
  32. {
  33. if ($value instanceof Model) {
  34. return $value->toArray();
  35. }
  36. return is_array($value) ? $value : [];
  37. }
  38. private static function sanitize(array $value): array
  39. {
  40. foreach ($value as $key => $item) {
  41. $normalized = strtolower((string)$key);
  42. foreach (self::SENSITIVE_KEYS as $needle) {
  43. if (str_contains($normalized, $needle)) {
  44. $value[$key] = empty($item) ? null : '******';
  45. continue 2;
  46. }
  47. }
  48. if (is_array($item)) {
  49. $value[$key] = self::sanitize($item);
  50. }
  51. }
  52. return $value;
  53. }
  54. }