记录 dcat-admin 使用 Laravel-activitylog 记录用户行为过程中遇到的问题
更新: 发布了个扩展包,欢迎提意见 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 协议》,转载必须注明作者和本文链接
学习了,感谢 :kissing_heart:
不是有现成的吗,github.com/dcat-admin/operation-lo...
我现在用V4的dontLogIfAttributesChangedOnly(['updated_at']) 无效了,着实蛋疼。