Laravel 5.5 实现管理后台操作日志功能:监听且实时记录模型操作数据

前言: 管理后台实现操作日志功能,能够监听且实时记录模型操作数据。?

通过provider中间件和配置文件配合实现

(一)初建数据库

使用laravel数据迁移,迁移文件内容如下:

<?php
/**
 **类名与迁移文件名要对应上才可以顺利迁移
 **/
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePowerActionLogsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::connection('mysql_store_power')->create('action_logs', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned()->comment('执行人用户id');
            $table->string('title', 32)->nullable()->comment('行为名称');
            $table->text('content')->comment('行为内容');
            $table->string('model', 256)->nullable()->comment('行为的关联表格名称或者模型名称(包含命名空间)');
            $table->integer('model_id')->unsigned()->nullable()->comment('行为的关联表格受影响记录ID');
            $table->string('uri', 256)->default('')->comment('执行操作时的当前uri');
            $table->ipAddress('created_ip')->nullable()->comment('执行行为时的IP');
            $table->timestamps();              
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::connection('mysql_store_power')->dropIfExists('action_logs');
    }
}

 

(二) 创建event(事件)和listen(监听)和observe(观察者)

备注:在这里我们没有使用->常规流程:laravel5.5事件系统

所以这里只是备注说明。非文章步骤

  • 在App\Events下创建DefaultLoggable.php文件
<?php

namespace App\Events\Power\Log;
use Auth;
use Illuminate\Queue\SerializesModels;

class DefaultLoggable
{
    use SerializesModels;

    protected $title;

    protected $content;

    protected $userId;

    protected $model;

    protected $modelId;

    public function __construct(string $title, string $content, $userId = null, $model = null, $modelId = null)
    {
        $this->title = $title;
        $this->content = $content;
        $this->userId = $userId ? $userId : (Auth::check() ? Auth::user()->id : 0);
        $this->model = $model;
        $this->modelId = $modelId;
    }
}
  • 在App\Listeners下创建DefaultLogger.php
<?php

namespace App\Listeners\Power\Log;

use Request;
use App\Events\Power\Log\DefaultLoggable;
use App\Models\Power\Log\ActionLog;
use Wunsun\Cms\Support\BrowserDetector;

class DefaultLogger
{
    /**
     * 处理事件
     */
    public function handle(DefaultLoggable $event)
    {
        ActionLog::create([
            'user_id'    => $event->userId,
            'title'      => $event->title,
            'content'    => $event->content,
            'model'      => $event->model,
            'model_id'   => $event->modelId,
            'uri'        => Request::getRequestUri(),
            'os'         => BrowserDetector::getOS(),
            'browser'    => BrowserDetector::getBrowser(),
            'created_ip' => get_client_ip(),
        ]);
    }
}
  • 在App\Observer下创建ModelObserver.php
<?php

namespace App\Observers\Power\Log;

use Illuminate\Support\Arr;
use App\Events\Power\Log\DefaultLoggable;

class ModelObserver
{
    /**
     * 模型新建后
     */
    public function created($model)   
    {
        $attributes = $model->getAttributes();
        $attributes = Arr::except($attributes, ['created_at', 'updated_at']);

        $modelName = get_class($model);
        $baseModelName = get_base_class($model);
        $modelId = $model->getKey();
        $title = "新建【{$baseModelName}】模型";
        $content = "模型数据:".pretty_string($attributes);

        event(new DefaultLoggable($title, $content, null, $modelName, $modelId));
    }    

    /**
     * 只有确定更新后才记录日志
     */
    public function updated($model)   
    {
        $dirty = $model->getDirty();
        $original = $model->getOriginal();

        // 有时候可能只要监控某些字段
        if (method_exists($model, 'limitObservedFields')) {
            $fields = $model->limitObservedFields();
            $dirty = Arr::only($dirty, $fields);
            $original = Arr::only($original, array_keys($dirty));
        } else {
            $dirty = Arr::except($dirty, ['updated_at']);
            $original = Arr::only($original, array_keys($dirty));
        }

        if (count($dirty)) {
            $modelName = get_class($model);
            $baseModelName = get_base_class($model);
            $modelId = $model->getKey();
            $title = "修改【{$baseModelName}】模型";
            $content = "数据修改前:".pretty_string($original).";数据修改后:".pretty_string($dirty);

            event(new DefaultLoggable($title, $content, null, $modelName, $modelId));            
        }
    }

    /**
     * 模型删除后
     */
    public function deleted($model)   
    {
        $attributes = $model->getAttributes();

        $modelName = get_class($model);
        $baseModelName = get_base_class($model);
        $modelId = $model->getKey();
        $title = "删除【{$baseModelName}】模型";
        $content = "模型数据:".pretty_string($attributes);

        event(new DefaultLoggable($title, $content, null, $modelName, $modelId));
    }      
}

 

(三)创建服务中间件

(1)首先,我们在config下创建power.php配置文件。内容如下:

<?php

return [
    /**
     * 事件相关
     */
    'event' => [
        /**
         * 监听者
         */
        'listeners' => [
            /**
             * 默认的记录事件
             */
            'App\Events\Power\Log\DefaultLoggable' => [
                'App\Listeners\Power\Log\DefaultLogger',
            ],
        ],

        /**
         * 模型观察者.
         * 以下添加的模型都被ModelObserver监听和观察
         * 后续添加
         */
        'observers' => [
            \App\Models\Power\Access\Role::class,
        ],
    ],
];

(2)然后我们需要创建一个服务的类,比如叫CqhServiceProvider,最简单的方式就是用artisan来帮我们创建

php artisan make:provider PowerServiceProvider

然后,我们会看到app\Provider文件夹下在生成了如下的文件PowerServiceProvider.php,并写上代码内容如下

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;
use App\Observers\Power\Log\ModelObserver;

class PowerServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerEvents();
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
    }

    /**
     * 执行配置文件
     */
    public function registerEvents()
    {
        $allListeners = config('power.event.listeners');
        foreach ($allListeners as $event => $listeners) {
            foreach ($listeners as $listener) {
                Event::listen($event, $listener);
            }
        }

        $subscribers = config('power.event.subscribers');
        foreach ($subscribers as $subscriber) {
            Event::subscribe($subscriber);
        }

        $observers = config('power.event.observers');
        foreach ($observers as $observer) {
            $observer::observe(ModelObserver::class);
        }
    }     
}

但是,这样还不能使用,我们需要把这个服务添加到我们的配置文件中,在打开config/app.php,找到providers数组,把刚刚生成的服务添加上

<?php

return [

'providers' => [
        ...

        'App\Providers\PowerServiceProvider',

        ...

    ],

];

这样服务就会自动运行了

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值