You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Laravel自定义命令实现可复用的通用预约系统?

当然可以!用自定义Artisan命令实现可复用的预约系统生成器

完全没问题——这正是Laravel Artisan的核心能力之一:把重复的代码生成逻辑封装成自定义命令,像make:auth那样一键生成预约系统的核心组件(模型、控制器、迁移),轻松在多个项目里复用。下面是具体的实现步骤:

1. 创建自定义命令类

首先生成命令的基础结构:

php artisan make:command AppointmentMakeCommand

打开生成的文件app/Console/Commands/AppointmentMakeCommand.php,修改$signature和$description,让命令更直观:

protected $signature = 'appointment:make';
protected $description = 'Generate core files for appointment system (model, migration, controller)';

2. 准备Stub模板文件

Laravel自带的make:*命令都是用Stub文件(预定义的代码模板)来生成文件的,我们也沿用这个思路。在项目根目录创建resources/stubs文件夹,然后添加以下几个Stub文件:

2.1 迁移文件Stub(appointment-migration.stub)

<?php

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

return new class extends Migration
{
    public function up()
    {
        Schema::create('appointments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->foreignId('service_id')->constrained()->onDelete('cascade');
            $table->datetime('appointment_date');
            $table->enum('status', ['pending', 'confirmed', 'cancelled'])->default('pending');
            $table->text('notes')->nullable();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('appointments');
    }
};

2.2 模型文件Stub(appointment-model.stub)

<?php

namespace {{ namespace }};

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class {{ class }} extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'service_id',
        'appointment_date',
        'status',
        'notes'
    ];

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

    public function service()
    {
        return $this->belongsTo(Service::class);
    }
}

2.3 控制器文件Stub(appointment-controller.stub)

<?php

namespace App\Http\Controllers;

use App\Models\Appointment;
use Illuminate\Http\Request;

class AppointmentController extends Controller
{
    public function index()
    {
        $appointments = Appointment::with(['user', 'service'])->get();
        return view('appointments.index', compact('appointments'));
    }

    public function create()
    {
        // 这里可以添加获取服务/用户列表的逻辑
        return view('appointments.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'service_id' => 'required|exists:services,id',
            'appointment_date' => 'required|datetime',
            'status' => 'nullable|in:pending,confirmed,cancelled',
            'notes' => 'nullable|string'
        ]);

        Appointment::create($validated);

        return redirect()->route('appointments.index')->with('success', 'Appointment created successfully');
    }

    public function show(Appointment $appointment)
    {
        return view('appointments.show', compact('appointment'));
    }
}

3. 实现命令的核心逻辑

回到AppointmentMakeCommand.php的handle()方法,编写代码来复制Stub文件并替换变量:

use Illuminate\Support\Facades\File;

public function handle()
{
    // 生成迁移文件
    $migrationFileName = date('Y_m_d_His') . '_create_appointments_table.php';
    $migrationStubPath = resource_path('stubs/appointment-migration.stub');
    $migrationTargetPath = database_path("migrations/$migrationFileName");

    File::copy($migrationStubPath, $migrationTargetPath);
    $this->info('Migration file created successfully!');

    // 生成模型文件
    $modelName = 'Appointment';
    $modelStubPath = resource_path('stubs/appointment-model.stub');
    $modelTargetPath = app_path("Models/$modelName.php");

    $modelContent = File::get($modelStubPath);
    $modelContent = str_replace(['{{ namespace }}', '{{ class }}'], ['App\Models', $modelName], $modelContent);
    File::put($modelTargetPath, $modelContent);
    $this->info('Model file created successfully!');

    // 生成控制器文件
    $controllerName = 'AppointmentController';
    $controllerStubPath = resource_path('stubs/appointment-controller.stub');
    $controllerTargetPath = app_path("Http/Controllers/$controllerName.php");

    File::copy($controllerStubPath, $controllerTargetPath);
    $this->info('Controller file created successfully!');

    $this->info('All appointment system core files generated! 🎉');
}

4. 注册命令

打开app/Console/Kernel.php,在$commands数组中添加你的命令类,让Laravel识别它:

protected $commands = [
    \App\Console\Commands\AppointmentMakeCommand::class,
];

5. 测试命令

现在执行命令,就能一键生成所有文件了:

php artisan appointment:make

检查database/migrations/、app/Models/和app/Http/Controllers/目录,确认文件都正确生成。

进阶:打包成可复用的Laravel包

如果想在多个项目里更方便地复用这个命令,你可以把命令和Stub文件打包成一个Laravel包:

  • 创建符合Composer规范的包结构
  • 把命令和Stub文件放到包的目录里
  • 在包的服务提供者中注册命令
  • 可选:发布Stub文件到项目的resources/stubs目录,让用户可以自定义模板

这样其他项目只需要通过Composer安装你的包,就能直接使用appointment:make命令了。

内容的提问来源于stack exchange,提问作者baig772

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:47:11