shirokovnv/innkeeper

您下一个Laravel预订应用的库

2.0.0 2023-09-06 10:29 UTC

This package is auto-updated.

Last update: 2024-09-26 21:19:45 UTC


README

ci.yml Latest Version on Packagist Total Downloads

您的下一个Laravel预订应用的库。

支持的Laravel版本:>=9.x

安装

  1. 通过Composer安装包
$ composer require shirokovnv/innkeeper
  1. 运行迁移
$ php artisan migrate
  1. 完成!

用法

将可预订功能添加到您的eloquent模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Shirokovnv\Innkeeper\Contracts\Bookable;
use Shirokovnv\Innkeeper\Traits\HasBooking;

class Room extends Model implements Bookable {
    use HasBooking;
}

基本上就是这样。现在您的房间可以被预订了。

检查预订机会

Innkeeper服务提供检查在日期范围内是否可以预订某物的功能

use \Shirokovnv\Innkeeper\Contracts\Innkeepable;

$room = \App\Models\Room::find(1);

$innkeeper = app()->make(Innkeepable::class);

// Has bookings in a date range ?
$has_bookings = $innkeeper->exists(
    $room,
    new DateTime('2022-08-01 15:00'), 
    new DateTime('2022-08-07 12:00')
);

创建新的预订

创建新的预订非常直接,可以按照以下方式完成

use \Shirokovnv\Innkeeper\Contracts\Innkeepable;

$room = \App\Models\Room::find(1);

$innkeeper = app()->make(Innkeepable::class);
$booking_hash = generateBookingHash();

$innkeeper->book(
    $room, 
    $booking_hash, 
    new DateTime('2022-08-01 15:00'), 
    new DateTime('2022-08-07 12:00')
);

或者如果您喜欢外观,您可以这样做

use Shirokovnv\Innkeeper\Facades\Innkeeper;

Innkeeper::book(
    $room, 
    $booking_hash, 
    new DateTime('2022-08-01 15:00'), 
    new DateTime('2022-08-07 12:00')
);

注意

为什么我们需要booking_hash以及它是什么?

  • 这是一个具有唯一约束条件的数据库字段
  • 它用于防止一些重复预订,而不需要显式锁定表

让我给您举个例子

假设,您在预订网站上有一些访客。所有的访客都要求在同一时间预订同一个房间。

在这种情况下,您可能需要将房间分配给第一个客户,并通知其他客户房间已被预订。

您可以通过以下简单步骤来完成

  1. 定义哈希函数
function generateBookingHash(int $room_id, string $started_at, string $ended_at) {
    return $room_id . $started_at . $ended_at;
}
  1. 在您的业务逻辑代码中
use Illuminate\Database\QueryException;

$room = \App\Models\Room::find(1);
$booking_hash = generateBookingHash($room->id, $started_at, $ended_at);

try {
    $innkeeper->book($room, $booking_hash, $started_at, $ended_at);
} catch (QueryException $exception) {
    // Catch SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: bookings.hash
    // show user popup with apologies or
    // redirect to another free room or ...
}

此示例仅涵盖具有无交集的确定性预订计划的情况,如下所示

  • 09:00 - 10:00
  • 10:00 - 11:00
  • 11:00 - 12:00
  • ...

如果您有一些交集,如下所示

  • 09:00 - 10:00
  • 09:30 - 10:30

您仍然可能遇到重复问题。

当然,您可以检查房间的可用性

$can_be_booked = ! $innkeeper->exists($room, $started_at, $ended_at);
if ($can_be_booked) {
    $innkeeper->book($room, $booking_hash, $started_at, $ended_at);
} else {
    // show user an error message
}

但这并不保证解决对您的计划的并发请求。

因此,如果您的情况是这样,请告诉我可以采取什么解决方案。

查询预订

use \Shirokovnv\Innkeeper\Contracts\Innkeepable;

$room = \App\Models\Room::find(1);

$innkeeper = app()->make(Innkeepable::class);

// All the bookings for the room
$bookings = $innkeeper->all($room);

// All the bookings for the room in a range.
$bookings = $innkeeper->allInRange($room, $started_at, $ended_at);

// The first started booking
$first_booking = $innkeeper->first($room);

// The last ended booking
$last_booking = $innkeeper->last($room);

删除预订

$room = \App\Models\Room::find(1);

$booking_hash = 'some hash';

// Delete by predefined hash
$innkeeper->deleteByHash($room, $booking_hash);

$started_at = new DateTime('2022-08-01 09:00');
$ended_at = new DateTime('2022-08-02 09:00');

// Delete by specific date range.
$innkeeper->deleteByRange($room, $started_at, $ended_at);

变更日志

有关最近更改的更多信息,请参阅变更日志

测试

$ composer test

贡献

有关详细信息,请参阅contributing.md,并查看待办事项列表。

安全性

如果您发现任何与安全相关的问题,请通过shirokovnv@gmail.com发送电子邮件,而不是使用问题跟踪器。

鸣谢

许可协议

MIT。有关更多信息,请参阅许可文件