如何利用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
相关产品推荐
相关产品推荐

