如何在 Laravel 中将每个用户的数据库字段更新限制为 24 小时一次

Posted

技术标签:

【中文标题】如何在 Laravel 中将每个用户的数据库字段更新限制为 24 小时一次【英文标题】:How do I limit a database field update to once in 24hrs per user in Laravel 【发布时间】:2021-08-12 23:41:37 【问题描述】:

我创建了一个 API,可以在用户登录时在 LoginActivity 表上记录记录。我希望每个用户在 24 小时内只记录一次记录的活动。

这是我的 activity_record.py 模型

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class ActivityRecord extends Model


    protected $fillable = ['user_id','total_logins', 'is_active'];

    public function user()
    
        return $this->belongsTo(User::class);
    


这是我的 create_activity_record_table.py 表

<?php

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

class CreateActivityRecordsTable extends Migration

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        Schema::create('activity_records', function (Blueprint $table) 
            $table->bigIncrements('id');

            $table->integer('user_id');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

            $table->integer('total_logins')->default(0);

            $table->integer('is_active')->nullable();

            $table->timestamps();

        );
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::dropIfExists('activity_records');
    


这是 UserController.py

public function __construct()
    
       $this->middleware('auth:user');
    

public function login(Request $request)
    
$request->validate(['email' => 'required', 'password' => 'required']);

        $credentials = ['email' => $request->email, 'password' => $request->password];

        if (!$token = auth('user')->attempt($credentials)) 
            return response()->json(['success' => false, 'message' => 'Email or Password Is Incorrect'], 401);
        

        $user = Auth::guard('user')->user();

        if (!$this->UpdateTwentyFours($user)) 
        // Work here
            if(!$user->is_active)
                $activity = ActivityRecord::updateOrCreate(['is_active'=> 0,'user_id'=> auth('user')->user()->id])->increment('total_logins', 0);
            else
                $activity_add = ActivityRecord::updateOrCreate(['is_active'=> 1, 'user_id'=> auth('user')->user()->id])->increment('total_logins', 1);
            
        ;

         return response()->json([
            'success' => true,
            'auth' => $this->respondWithToken($token),
            'user' => new UserResource(User::where(['email' => $request->email])->first()),
        ]);
    
    protected function respondWithToken($token)
    

        return [
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ];
    

    public function UpdateTwentyFours($user)
    
        $user = Auth::guard('user')->user()->id;

        $now = Carbon::now()->toDateTimeString();

        $activityUpdatedAt = ActivityRecord::where('user_id', $user)->get('updated_at');

        $activityAt = $activityUpdatedAt->implode('updated_at');

        $diff_in_hours = Carbon::createFromFormat('Y-m-d H:i:s', $activityAt)->format('Y-m-d H:i:s');

        $diff_in = new Carbon($diff_in_hours);

        $length = $diff_in->diffInHours($now);

        if($length > 24)
            return false;
        

        return true;
    

每当我尝试使用上面的代码来实现我的目的时,我都会不断收到此错误

Carbon\Exceptions\InvalidFormatException: Trailing data in file C:\Users\Desktop\PROJECT\vendor\nesbot\carbon\src\Carbon\Traits\Creator.php on line 643

#0 C:\Users\Desktop\PROJECT\vendor\nesbot\carbon\src\Carbon\Traits\Creator.php(665): Carbon\Carbon::rawCreateFromFormat('Y-m-d H:i:s', '2021-04-05 13:1...', NULL)
#1 C:\Users\Desktop\PROJECT\app\Http\Controllers\UserController.php(67): Carbon\Carbon::createFromFormat('Y-m-d H:i:s', '2021-04-05 13:1...')
#2 C:\Users\Desktop\PROJECT\app\Http\Controllers\UserActivityController.php(35): App\Http\Controllers\UserController-&gt;UpdateTwentyFours(11)
#3 C:\Users\Desktop\PROJECT\vendor\laravel\framework\src\Illuminate\Routing\Controller.php(54): App\Http\Controllers\UserController-&gt;store(Object(Illuminate\Http\Request))
#4 C:\Users\Desktop\PROJECT\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php(45): Illuminate\Routing\Controller-&gt;callAction('login', Array)
#5 C:\Users\Desktop\PROJECT\vendor\laravel\framework\src\Illuminate\Routing\Route.php(239): Illuminate\Routing\ControllerDispatcher-&gt;dispatch(Object(Illuminate\Routing\Route), Object(App\Http\Controllers\UserController), 'login')

我哪里出错了,还有其他方法可以让每个用户在 24 小时内只记录一次记录的活动吗?

【问题讨论】:

【参考方案1】:

我认为这是实现更新最清晰的方式:

class UserController 

  public function login()
    ...
    $this->updateActivityEvery24Hours();
    ...
  

  public function updateActivityEvery24Hours()
  
    // Runs given callback function if cache does not exists or 24*60 minutes (24hours) is past
    cache()->remember('user_activity_update', 24 * 60, function()
      $user = Auth::guard('user')->user()->id;

      ActivityRecord::updateOrCreate([
        'is_active'=> !$user->is_active,
        'user_id'=> $user->id
      ])->increment('total_logins', $user->is_active ? 1 : 0);
    );
  

【讨论】:

以上是关于如何在 Laravel 中将每个用户的数据库字段更新限制为 24 小时一次的主要内容,如果未能解决你的问题,请参考以下文章

在laravel 8中将用户的角色更改为另一个角色

在 Laravel Passport 中将用户模型主键 ID 更改为另一个

如何在 LARAVEL 5.2 中将数据存储到数据库中

在 Laravel 5 中将多行从动态表单保存到数据库

如何在laravel中将用户帖子保存在数据库中?

如何在Laravel 5.2中将表单数据作为路由参数传递