AdminLog.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. namespace app\admin\model;
  3. use Throwable;
  4. use think\Model;
  5. use app\admin\library\Auth;
  6. use think\model\relation\BelongsTo;
  7. /**
  8. * AdminLog模型
  9. */
  10. class AdminLog extends Model
  11. {
  12. protected $autoWriteTimestamp = true;
  13. protected $updateTime = false;
  14. /**
  15. * 自定义日志标题
  16. * @var string
  17. */
  18. protected static string $title = '';
  19. /**
  20. * 自定义日志内容
  21. * @var string|array
  22. */
  23. protected static string|array $data = '';
  24. /**
  25. * 忽略的链接正则列表
  26. * @var array
  27. */
  28. protected static array $urlIgnoreRegex = [
  29. '/^(.*)\/(select|index|logout)$/i',
  30. ];
  31. /**
  32. * 设置标题
  33. * @param string $title
  34. */
  35. public static function setTitle(string $title): void
  36. {
  37. self::$title = $title;
  38. }
  39. /**
  40. * 设置日志内容
  41. * @param string|array $data
  42. */
  43. public static function setData(string|array $data): void
  44. {
  45. self::$data = $data;
  46. }
  47. /**
  48. * 设置忽略的链接正则列表
  49. * @param array|string $regex
  50. */
  51. public static function setUrlIgnoreRegex(array|string $regex = []): void
  52. {
  53. $regex = is_array($regex) ? $regex : [$regex];
  54. self::$urlIgnoreRegex = array_merge(self::$urlIgnoreRegex, $regex);
  55. }
  56. /**
  57. * 数据脱敏(只数组,根据数组 key 脱敏)
  58. * @param array|string $data
  59. * @return array|string
  60. */
  61. protected static function pureData(array|string $data): array|string
  62. {
  63. if (!is_array($data)) {
  64. return $data;
  65. }
  66. foreach ($data as $index => &$item) {
  67. if (preg_match("/(password|salt|token)/i", $index)) {
  68. $item = "***";
  69. } else {
  70. if (is_array($item)) {
  71. $item = self::pureData($item);
  72. }
  73. }
  74. }
  75. return $data;
  76. }
  77. /**
  78. * 写入日志
  79. * @param string $title
  80. * @param string|array|null $data
  81. * @throws Throwable
  82. */
  83. public static function record(string $title = '', string|array $data = null): void
  84. {
  85. $auth = Auth::instance();
  86. $admin_id = $auth->isLogin() ? $auth->id : 0;
  87. $username = $auth->isLogin() ? $auth->username : __('Unknown');
  88. $controller = str_replace('.', '/', request()->controller(true));
  89. $action = request()->action(true);
  90. $path = $controller . '/' . $action;
  91. if (self::$urlIgnoreRegex) {
  92. foreach (self::$urlIgnoreRegex as $item) {
  93. if (preg_match($item, $path)) {
  94. return;
  95. }
  96. }
  97. }
  98. $data = $data ?: self::$data;
  99. if (!$data) {
  100. $data = request()->param('', null, 'trim,strip_tags,htmlspecialchars');
  101. }
  102. $data = self::pureData($data);
  103. $title = $title ?: self::$title;
  104. if (!$title) {
  105. $controllerTitle = AdminRule::where('name', $controller)->value('title');
  106. $title = AdminRule::where('name', $path)->value('title');
  107. $title = $title ?: __('Unknown') . '(' . $action . ')';
  108. $title = $controllerTitle ? ($controllerTitle . '-' . $title) : $title;
  109. }
  110. self::create([
  111. 'admin_id' => $admin_id,
  112. 'username' => $username,
  113. 'url' => substr(request()->url(), 0, 1500),
  114. 'title' => $title,
  115. 'data' => !is_scalar($data) ? json_encode($data) : $data,
  116. 'ip' => request()->ip(),
  117. 'useragent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
  118. ]);
  119. }
  120. public function admin(): BelongsTo
  121. {
  122. return $this->belongsTo(Admin::class);
  123. }
  124. }