更新: 釋出了個擴充套件包,歡迎提意見 jarl/activity-log
在dcat-admin中想要記錄後臺操作記錄,首頁我利用了dcat-admin官方的operation-log擴充套件包,下載下來後發現它是根據http請求記錄的日誌,雖然可以設定哪些請求不記錄,但是還是不夠自定義,記錄的日誌非開發人員還是看不懂的,如下所示
而我想要記錄 “誰操作了什麼” 這種誰都能看懂的日誌記錄,於是乎找上了Laravel-activitylog
。
簡單的使用就不說了,去看官方文件,我在使用自動記錄模型事件的時候遇上了一些問題。
根據文件我的model
最終變成了這樣
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
class User extends Model
{
use HasDateTimeFormatter;
use SoftDeletes;
use LogsActivity;
protected function getDescriptionForEvent(string $eventName): string
{
$description = '';
switch ($eventName) {
case 'created':
$description = '管理員' . Auth('admin')->user()->username . '新增了' . $this->table.'表id為' . $this->id . '的資料';
break;
case 'updated':
$description = '管理員' . Auth('admin')->user()->username . '修改了' . $this->table.'表id為' . $this->id . '的資料';
break;
case 'deleted':
$description = '管理員' . Auth('admin')->user()->username . '刪除了' . $this->table.'表id為' . $this->id . '的資料';
break;
}
return $description;
}
protected function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logAll() // 記錄所有欄位的更改
->dontLogIfAttributesChangedOnly(['updated_at']) // 當只有updated_at 欄位更改時不記錄
->logOnlyDirty() // 只有實際發生更改的欄位記錄
->dontSubmitEmptyLogs() // 不記錄空日誌
->useLogName('users') // 設定日誌名
->setDescriptionForEvent(fn (string $eventName) => $this->getDescriptionForEvent($eventName));
}
}
現在既然這些程式碼在每個類裡都基本一樣了,於是我將它提取成一個trait
.
namespace App\Admin\Traits;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
trait LogsActivityTrait
{
use LogsActivity;
protected string $logName = '';
protected function getDescriptionForEvent(string $eventName): string
{
$description = '';
switch ($eventName) {
case 'created':
$description = '管理員' . Auth('admin')->user()->username . '新增了' . $this->table.'表id為' . $this->id . '的資料';
break;
case 'updated':
$description = '管理員' . Auth('admin')->user()->username . '修改了' . $this->table.'表id為' . $this->id . '的資料';
break;
case 'deleted':
$description = '管理員' . Auth('admin')->user()->username . '刪除了' . $this->table.'表id為' . $this->id . '的資料';
break;
}
return $description;
}
protected function getLogName(): string
{
return $this->logName ?: strtolower(class_basename($this)); // 小寫類名作為日誌名方便分類
}
protected function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logAll() // 記錄所有欄位的更改
->dontLogIfAttributesChangedOnly(['updated_at']) // 當只有updated_at 欄位更改時不記錄
->logOnlyDirty() // 只有實際發生更改的欄位記錄
->dontSubmitEmptyLogs() // 不記錄空日誌
->useLogName($this->getLogName()) // 設定日誌名
->setDescriptionForEvent(fn (string $eventName) => $this->getDescriptionForEvent($eventName));
}
}
這樣每個model
裡只需要use LogsActivityTrait;
就行,同時logName
屬性 和 getDescriptionForEvent
方法也可重寫覆蓋,甚至說getActivitylogOptions
方法裡的各種方法你想要的不想要的都能自己修改進行自定義
最後再說一點
-Activitylog
安裝完後 在activitylog.php
配置檔案裡的default_auth_driver
屬性預設是null
,這樣生成的日誌裡causer_type
和causer_id
都是null
,注意改成你定義的guard,一般後臺是admin
,前臺是web
,也可以建立箇中介軟體動態設定這個值
public function handle($request, Closure $next, $guard = 'admin')
{
config()->set('activitylog.default_auth_driver', $guard);
return $next($request);
}
- 如果你想自定義設定causer_type和causer_id,可以在
LogsActivityTrait
裡定義tapActivity
方法public function tapActivity(Activity $activity, string $eventName) { $activity->causer_id = 2; //$activity->description = '你想要修改的description'; }
tapActivity
方法裡可以修改任何欄位。LogsActivity
的sql欄位如下
本作品採用《CC 協議》,轉載必須註明作者和本文連結