记录 dcat-admin 使用 Laravel-activitylog 记录用户行为过程中遇到的问题

更新: 发布了个扩展包,欢迎提意见 jarl/activity-log

在dcat-admin中想要记录后台操作记录,首页我利用了dcat-admin官方的operation-log扩展包,下载下来后发现它是根据http请求记录的日志,虽然可以设置哪些请求不记录,但是还是不够自定义,记录的日志非开发人员还是看不懂的,如下所示

记录 dcat-admin 使用  Laravel-activitylog 记录用户行为过程中遇到的问题
而我想要记录 “谁操作了什么” 这种谁都能看懂的日志记录,于是乎找上了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_typecauser_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字段如下

记录 dcat-admin 使用  Laravel-activitylog 记录用户行为过程中遇到的问题

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 7
NightingaleWK

学习了,感谢 :kissing_heart:

1年前 评论
jarl (楼主) 1年前

不是有现成的吗,github.com/dcat-admin/operation-lo...

1年前 评论
jarl (楼主) 1年前
deMemory (作者) 1年前
jarl (楼主) 1年前
deMemory (作者) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!