这是我如何实现这一目标的。
1) 创建迁移以在模型中添加 2 列is_editing
and editing_by
and updated_at
(无需创建updated_at
如果已经在那里)
2)制作中间件php artisan make:middleware StopConcurrentOperations
.
3)注册中间件app/Http/Kernel.php
under $routeMiddleware
.
4)将中间件应用到控制器
$this->middleware('concurrent.operations',["only"=>["edit","update"]]);
5) 阻止中间件中的并发编辑
<?php
namespace App\Http\Middleware;
use App\OperationActivity;
use Carbon\Carbon;
use Closure;
use Illuminate\Support\Facades\Auth;
class StopConcurrentOperations
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
$operation_id = current($request->route()->parameters());
$user_id = Auth::guard('admin')->user()->id;
if(Auth::guard('admin')->user() && !empty($operation_id)){
$activity = OperationActivity::firstOrNew(["operation_id" => $operation_id]);
if($activity->is_editing && $activity->updated_at->diffInMinutes(Carbon::now())<5 && $activity->editing_by!=$user_id)
abort(409);
else {
$activity->is_editing = true;
$activity->editing_by = $user_id;
$activity->save();
}
}
return $next($request);
}
}
在这里我检查是否有人已经编辑记录并检查执行编辑的时间。
6) 如果编辑用户关闭窗口,则可以选择在客户端,然后取消阻止记录,例如
window.onbeforeunload = function() {
var url = "{{route('unlock_route_name',$operation->id)}}";
$.ajax({ url: url, method: 'post' })
};
要从客户端完成该过程,您必须创建一个route and a method在控制器中,只需解锁记录即可
$operation = Operation::findOrFail($id);
$activity = $operation->activities()->where("is_editing",true)->first();
$activity->is_editing = false;
$activity->save();
注意:在我的示例中,我已经有不同的表来记录活动OperationActivity
可能的型号名称是Operation