Laravel 避免日期重叠

coo*_*oka 3 laravel laravel-5

我是 Laravel 的新手,正在尝试实施不能在任何一天重叠的预订日期。

我有一个名为“Bookings”的模型,其中包括 room_id、start_date 和 end_date。

我有验证检查结束日期不能在开始之前:

$this->validate($request, [
        'start_date' => 'required|date',
        'end_date' => 'required|date|after_or_equal:start_date',
]);
Run Code Online (Sandbox Code Playgroud)

但是,我不确定如何检查日期范围是否与预订表中存储的同一 room_id 的任何其他日期范围不冲突(因为一个房间不能在同一范围内预订两次)。

任何帮助,将不胜感激,

谢谢!

小智 7

在典型的重叠中,给定两个事件 A 和 B,您必须考虑四种情况:

  1. 事件 A 包含事件 B
  2. 事件 B 包含事件 A
  3. 事件 A 的结束日期与事件 B 的开始日期重叠
  4. 事件 B 的结束日期与事件 A 的开始日期重叠

因此,在 sql 中检查房间是否在日期间隔内忙碌,假设 2018-11-20' 和 '2018-11-30' 它将是:

select * 
from rooms 
where 
    start_date between '2018-11-20' and '2018-11-30' or 
    end_date between '2018-11-20' and '2018-11-30' or 
    '2018-11-20' between start_date and end_date or 
    '2018-11-30' between start_date and end_date;
Run Code Online (Sandbox Code Playgroud)

在 laravel 中,我所做的是在模型中创建一个范围。

public function scopeByBusy($query,$start_date,$end_date) 
{ 
    return $query->whereBetween('start_date', [$start_date, $end_date]) 
        ->orWhereBetween('end_date', [$start_date, $end_date]) 
        ->orWhereRaw('? BETWEEN start_date and end_date', [$start_date]) 
        ->orWhereRaw('? BETWEEN start_date and end_date', [$end_date]); 
}
Run Code Online (Sandbox Code Playgroud)

最后,我可以验证 id 为 95 的房间是否在 '2018-11-20' 和 '2018-11-30' 之间忙碌,如下所示:

$room_id = 95;
$start = '2018-11-20';
$end = '2018-11-30';
$exists = Rooms::where('id', $room_id)
    ->byBusy($start, $end)
    ->first();

if($exists)
{
    echo "the room is busy in the interval you selected";
}
Run Code Online (Sandbox Code Playgroud)

我希望它能帮助你。