Skip to content

Commit

Permalink
用户最后活跃时间
Browse files Browse the repository at this point in the history
  • Loading branch information
summerblue committed Sep 20, 2019
1 parent a802e27 commit 677b853
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 4 deletions.
18 changes: 18 additions & 0 deletions app/Console/Commands/SyncUserActivedAt.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\User;

class SyncUserActivedAt extends Command
{
protected $signature = 'larabbs:sync-user-actived-at';
protected $description = '将用户最后登录时间从 Redis 同步到数据库中';

public function handle(User $user)
{
$user->syncUserActivedAt();
$this->info("同步成功!");
}
}
4 changes: 3 additions & 1 deletion app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ protected function schedule(Schedule $schedule)
// $schedule->command('inspire')
// ->hourly();


// 一小时执行一次『活跃用户』数据生成的命令
$schedule->command('larabbs:calculate-active-user')->hourly();

// 每日零时执行一次
$schedule->command('larabbs:sync-user-actived-at')->dailyAt('00:00');
}

/**
Expand Down
4 changes: 4 additions & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class Kernel extends HttpKernel
\Illuminate\Routing\Middleware\SubstituteBindings::class,

\App\Http\Middleware\EnsureEmailIsVerified::class, // <<--- 只需添加这一行


// 记录用户最后活跃时间
\App\Http\Middleware\RecordLastActivedTime::class,
],

'api' => [
Expand Down
20 changes: 20 additions & 0 deletions app/Http/Middleware/RecordLastActivedTime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Auth;

class RecordLastActivedTime
{
public function handle($request, Closure $next)
{
// 如果是登录用户的话
if (Auth::check()) {
// 记录最后登录时间
Auth::user()->recordLastActivedAt();
}

return $next($request);
}
}
84 changes: 84 additions & 0 deletions app/Models/Traits/LastActivedAtHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace App\Models\Traits;

use Redis;
use Carbon\Carbon;

trait LastActivedAtHelper
{
// 缓存相关
protected $hash_prefix = 'larabbs_last_actived_at_';
protected $field_prefix = 'user_';

public function recordLastActivedAt()
{
// 获取今日 Redis 哈希表名称,如:larabbs_last_actived_at_2017-10-21
$hash = $this->getHashFromDateString(Carbon::now()->toDateString());

// 字段名称,如:user_1
$field = $this->getHashField();

// 当前时间,如:2017-10-21 08:35:15
$now = Carbon::now()->toDateTimeString();

// 数据写入 Redis ,字段已存在会被更新
Redis::hSet($hash, $field, $now);
}

public function syncUserActivedAt()
{
// 获取昨日的哈希表名称,如:larabbs_last_actived_at_2017-10-21
$hash = $this->getHashFromDateString(Carbon::yesterday()->toDateString());

// 从 Redis 中获取所有哈希表里的数据
$dates = Redis::hGetAll($hash);

// 遍历,并同步到数据库中
foreach ($dates as $user_id => $actived_at) {
// 会将 `user_1` 转换为 1
$user_id = str_replace($this->field_prefix, '', $user_id);

// 只有当用户存在时才更新到数据库中
if ($user = $this->find($user_id)) {
$user->last_actived_at = $actived_at;
$user->save();
}
}

// 以数据库为中心的存储,既已同步,即可删除
Redis::del($hash);
}

public function getLastActivedAtAttribute($value)
{
// 获取今日对应的哈希表名称
$hash = $this->getHashFromDateString(Carbon::now()->toDateString());

// 字段名称,如:user_1
$field = $this->getHashField();

// 三元运算符,优先选择 Redis 的数据,否则使用数据库中
$datetime = Redis::hGet($hash, $field) ? : $value;

// 如果存在的话,返回时间对应的 Carbon 实体
if ($datetime) {
return new Carbon($datetime);
} else {
// 否则使用用户注册时间
return $this->created_at;
}
}

public function getHashFromDateString($date)
{
// Redis 哈希表的命名,如:larabbs_last_actived_at_2017-10-21
return $this->hash_prefix . $date;
}

public function getHashField()
{
// 字段名称,如:user_1
return $this->field_prefix . $this->id;
}
}
1 change: 1 addition & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class User extends Authenticatable implements MustVerifyEmailContract
use HasRoles;
use MustVerifyEmailTrait;
use Traits\ActiveUserHelper;
use Traits\LastActivedAtHelper;

use Notifiable {
notify as protected laravelNotify;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddLastActivedAtToUsersTable extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->timestamp('last_actived_at')->nullable();
});
}

public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('last_actived_at');
});
}
}
6 changes: 3 additions & 3 deletions resources/views/users/show.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
<div class="card ">
<img class="card-img-top" src="{{ $user->avatar }}" alt="{{ $user->name }}">
<div class="card-body">
<h5><strong>个人简介</strong></h5>
<p>{{ $user->introduction }}</p>
<hr>
<h5><strong>注册于</strong></h5>
<p>{{ $user->created_at->diffForHumans() }}</p>
<hr>
<h5><strong>最后活跃</strong></h5>
<p title="{{ $user->last_actived_at }}">{{ $user->last_actived_at->diffForHumans() }}</p>
</div>
</div>
</div>
Expand Down

0 comments on commit 677b853

Please sign in to comment.