laraveljutsu/zap 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

laraveljutsu/zap

最新稳定版本:v1.15.2

Composer 安装命令:

composer require laraveljutsu/zap

包简介

A flexible, performant, and developer-friendly schedule management system for Laravel

README 文档

README

Zap Logo

Flexible schedule management for modern Laravel applications

PHP Version Laravel Version License Total Downloads Why PHP

WebsiteDocumentationSupport

Table of contents

🎯 What is Zap?

Zap is a calendar and scheduling package for Laravel. Define availabilities, appointments, blocked times, and custom schedules for any resource (doctors, rooms, employees, etc.).

Use cases: appointment booking, healthcare resources, employee shifts, shared space booking.

📦 Installation

Requirements: PHP ≥8.5 • Laravel ≥13.0

composer require laraveljutsu/zap
php artisan vendor:publish --provider="Zap\ZapServiceProvider"

UUIDs/ULIDs: If your app uses non-integer primary keys, read Custom model support before migrating. You may need to change migrations and config.

php artisan migrate

Make a model schedulable: add the HasSchedules trait.

use Zap\Models\Concerns\HasSchedules;

class Doctor extends Model
{
    use HasSchedules;
}

🧩 Core concepts

Type Purpose Overlaps
Availability When a resource can be booked Allowed
Appointment Bookings / scheduled events Exclusive
Blocked When booking is forbidden Exclusive
Custom Your rules (overlap, etc.) You define

🚀 Quick start

use Zap\Facades\Zap;

// 1. Working hours
Zap::for($doctor)
    ->named('Office Hours')
    ->availability()
    ->forYear(2025)
    ->addPeriod('09:00', '12:00')
    ->addPeriod('14:00', '17:00')
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    ->save();

// 2. Block lunch
Zap::for($doctor)
    ->named('Lunch Break')
    ->blocked()
    ->forYear(2025)
    ->addPeriod('12:00', '13:00')
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    ->save();

// 3. Create an appointment
Zap::for($doctor)
    ->named('Patient A - Consultation')
    ->appointment()
    ->from('2025-01-15')
    ->addPeriod('10:00', '11:00')
    ->withMetadata(['patient_id' => 1, 'type' => 'consultation'])
    ->save();

// 4. Get bookable slots (60 min, 15 min buffer)
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15);

// 5. Next available slot
$nextSlot = $doctor->getNextBookableSlot('2025-01-15', 60, 15);

💡 Use the zap() helper instead of the facade when you prefer: zap()->for($doctor)->...

📅 Schedule patterns

Recurrence at a glance

Pattern Method / example
Daily daily()
Weekly (days) weekly(['monday', 'friday'])
Weekly + period weekDays(['monday', 'friday'], '09:00', '17:00')
Odd/even weeks weeklyOdd(), weeklyEven() (+ weekOddDays / weekEvenDays)
Bi-weekly biweekly(['tuesday'], $startsOn?)
Monthly (dates) monthly(['days_of_month' => [1, 15]])
Bi-monthly / quarter / semi / annual bimonthly(), quarterly(), semiannually(), annually() + config
Ordinal weekday firstWednesdayOfMonth(), secondFridayOfMonth(), lastMondayOfMonth()
Every N weeks everyThreeWeeks(), … everyFiftyTwoWeeks()
Every N months everyFourMonths(), … everyElevenMonths()

Recurrence examples

Daily & weekly

$schedule->daily()->from('2025-01-01')->to('2025-12-31');
$schedule->weekly(['monday', 'wednesday', 'friday'])->forYear(2025);
$schedule->weekDays(['monday', 'wednesday', 'friday'], '09:00', '17:00')->forYear(2025);
$schedule->weeklyOdd(['monday', 'wednesday', 'friday'])->forYear(2025);
$schedule->weeklyEven(['monday', 'wednesday', 'friday'])->forYear(2025);
$schedule->biweekly(['tuesday', 'thursday'], '2025-01-07')->from('2025-01-07')->to('2025-03-31');

Monthly (by day of month)

$schedule->monthly(['days_of_month' => [1, 15]])->forYear(2025);
$schedule->bimonthly(['days_of_month' => [5, 20], 'start_month' => 2])->from('2025-01-05')->to('2025-06-30');
$schedule->quarterly(['days_of_month' => [7, 21], 'start_month' => 2])->from('2025-02-15')->to('2025-11-15');
$schedule->semiannually(['days_of_month' => [10], 'start_month' => 3])->from('2025-03-10')->to('2025-12-10');
$schedule->annually(['days_of_month' => [1, 15], 'start_month' => 4])->from('2025-04-01')->to('2026-04-01');

Monthly ordinal weekday (1st, 2nd, 3rd, 4th, or last weekday of the month)

$schedule->firstWednesdayOfMonth()->forYear(2025);   // Every 1st Wednesday
$schedule->secondFridayOfMonth()->forYear(2025);     // Every 2nd Friday
$schedule->lastMondayOfMonth()->forYear(2025);      // Every last Monday
// Also: thirdTuesdayOfMonth(), fourthSaturdayOfMonth(), lastSundayOfMonth(), etc.

Dynamic intervals

$schedule->everyThreeWeeks(['monday', 'friday'])->from('2025-01-06')->to('2025-12-31');
$schedule->everyFourWeeks(['tuesday'], '2025-01-06')->from('2025-01-13');
$schedule->everyFourMonths(['day_of_month' => 15])->forYear(2025);
$schedule->everyFiveMonths(['days_of_month' => [1, 15], 'start_month' => 2])->forYear(2025);

Date ranges

$schedule->from('2025-01-15');                           // Start
$schedule->on('2025-01-15');                             // Alias for from()
$schedule->from('2025-01-01')->to('2025-12-31');        // Range
$schedule->between('2025-01-01', '2025-12-31');          // Same
$schedule->forYear(2025);                                // Full year

Time periods

$schedule->addPeriod('09:00', '17:00');
$schedule->addPeriod('09:00', '12:00');
$schedule->addPeriod('14:00', '17:00');

🔍 Query & check availability

Need Method
Any bookable slot today? $model->isBookableAt('2025-01-15', 60)
Time range bookable? $model->isBookableAtTime('2025-01-15', '09:00', '09:30')
Time range bookable (custom slot)? $model->isBookableAtTime('2025-01-15', '09:30', '10:00', null, 30)
Time range bookable (custom slot + buffer)? $model->isBookableAtTime('2025-01-15', '09:45', '10:15', null, 30, 15)
List bookable slots $model->getBookableSlots('2025-01-15', 60, 15)
Next bookable slot $model->getNextBookableSlot('2025-01-15', 60, 15)
Conflicts for a schedule Zap::findConflicts($schedule) / Zap::hasConflicts($schedule)
Schedules on a date $model->schedulesForDate('2025-01-15')->get()
Schedules in range $model->schedulesForDateRange('2025-01-01', '2025-01-31')->get()
By type $model->appointmentSchedules(), availabilitySchedules(), blockedSchedules()
Schedule type checks $schedule->isAvailability(), isAppointment(), isBlocked()

⚠️ isAvailableAt() is deprecated. Prefer isBookableAt(), isBookableAtTime(), and getBookableSlots().

💼 Real-world examples

Doctor

Zap::for($doctor)->named('Office Hours')->availability()->forYear(2025)
    ->addPeriod('09:00', '12:00')->addPeriod('14:00', '17:00')
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])->save();

Zap::for($doctor)->named('Lunch Break')->blocked()->forYear(2025)
    ->addPeriod('12:00', '13:00')
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])->save();

Zap::for($doctor)->named('Patient A - Checkup')->appointment()
    ->from('2025-01-15')->addPeriod('10:00', '11:00')->withMetadata(['patient_id' => 1])->save();

$slots = $doctor->getBookableSlots('2025-01-15', 60, 15);

Meeting room

Zap::for($room)->named('Conference Room A')->availability()
    ->weekDays(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'], '08:00', '18:00')
    ->forYear(2025)->save();

Zap::for($room)->named('Board Meeting')->appointment()
    ->from('2025-03-15')->addPeriod('09:00', '11:00')
    ->withMetadata(['organizer' => 'john@company.com'])->save();

Employee (with vacation)

Zap::for($employee)->named('Regular Shift')->availability()
    ->weekDays(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'], '09:00', '17:00')
    ->forYear(2025)->save();

Zap::for($employee)->named('Vacation Leave')->blocked()
    ->between('2025-06-01', '2025-06-15')->addPeriod('00:00', '23:59')->save();

⚙️ Configuration

Publish assets:

php artisan vendor:publish --tag=zap-migrations
php artisan vendor:publish --tag=zap-config

Important keys in config/zap.php: time_slots.buffer_minutes, default_rules.no_overlap, conflict_detection, validation.

🛡️ Advanced features

Custom schedules & rules

Zap::for($user)->named('Custom Event')->custom()
    ->from('2025-01-15')->addPeriod('15:00', '16:00')->noOverlap()->save();

Metadata

->withMetadata(['patient_id' => 1, 'type' => 'consultation', 'notes' => 'Follow-up'])

Validation rules: noOverlap(), allowOverlap(), workingHoursOnly('09:00', '17:00'), maxDuration(120), noWeekends().

Custom model support (UUIDs)

If your app uses UUIDs/ULIDs for primary keys:

  1. Models — Extend Zap\Models\Schedule and Zap\Models\SchedulePeriod, add Laravel’s HasUuids trait. Add HasUuids to your schedulable model (e.g. Doctor) as well.
  2. Config — In config/zap.php, set models.schedule and models.schedule_period to your extended classes.
  3. Migrations — After publishing, change id() to uuid('id')->primary(), morphs('schedulable') to uuidMorphs('schedulable'), and foreignId('schedule_id') to foreignUuid('schedule_id') in the schedules and schedule_periods tables.

Do this before running migrations.

🧠 AI agent support

Zap provides Laravel Boost 2.0 skills. With Boost installed, agents get accurate knowledge of the API.

Skill Contents
zap-schedules Types, builder API, validation, conflict detection
zap-availability Bookable slots, availability checks, querying
zap-recurrence All recurrence patterns (daily, weekly, odd/even, monthly, ordinal weekday, dynamic)

No extra configuration.

🤝 Contributing

Contributions are welcome. Use PSR-12 and add tests.

git clone https://github.com/ludoguenet/laravel-zap.git
cd laravel-zap
composer install
composer pest

📄 License

MIT License.

🔒 Security

Report issues to ludo@epekta.com (not the public issue tracker).

Made with 💛 by Ludovic Guénet for the Laravel community

统计信息

  • 总下载量: 89.4k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1437
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1436
  • Watchers: 18
  • Forks: 104
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-06-08

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固