Skip to content
CatchAdmin 插件市场也正式上线啦!!! GO ! 还有 CatchAdmin 正在参加 Gitee 2025 最受欢迎的开源软件投票活动 ⭐请给我投一票吧!

插件开发实战

在上一篇 快速入门 中,我们已经成功搭建了一个基础插件并完成安装。本章将带你从零开始,通过一个完整的实战案例,手把手教你开发一个功能完善的 CatchAdmin 后台模块插件。

开始之前

在开始开发之前,请确保你已经:

  • 完成了 快速入门 的学习
  • 熟悉 Laravel 的基本概念(路由、控制器、模型)
  • 了解 Vue.js 的基础知识(可选,用于前端页面开发)

目录结构约定

开发一个完整的后台模块插件时,我们推荐遵循以下约定的目录结构

├─test                         # 插件根目录
│  ├─resource                  # 资源目录(可选)
│  │  └─views                  # Vue 视图文件目录
│  ├─config                    # 配置文件目录(可选)
│  ├─migrations                # 数据库迁移目录(可选)
│  ├─routes                    # 路由定义目录(可选)
│  ├─src                       # 源代码目录(核心)
│  │  ├─Http                   # HTTP 层
│  │  │  ├─Controllers         # 控制器
│  │  │  └─Requests            # 表单验证(可选)
│  │  └─Models                 # 数据模型(可选)
│  ├─hook.php                  # 生命周期钩子
│  ├─composer.json             # Composer 配置
│  └─README.md                 # 说明文档

目录说明

目录/文件必需说明
src/存放插件的核心源代码
composer.json定义插件的依赖和元信息
hook.php插件生命周期钩子,详见 钩子文档
routes/可选定义插件的 API 路由
migrations/可选数据库迁移文件
resource/views/可选Vue 前端页面文件
config/可选插件配置文件

TIP

什么时候需要这些目录?

  • 开发完整后台模块:上述所有目录基本都需要用到
  • 开发简单功能插件:根据实际需求选择性添加
  • 开发 API 接口:必须按照约定的目录结构进行开发

CatchAdmin 的插件本质上就是一个 Composer 包,因此你可以根据实际需求灵活组织代码结构。

接下来,我们将使用上一篇创建的 test/test 插件,一步步开发一个完整的后台模块。

第一步:创建数据迁移

大多数插件都需要存储数据,因此我们首先创建数据库迁移文件。

生成迁移文件

执行以下命令,在插件目录中创建迁移文件:

shell
php artisan make:migration CreateUser --path=packages\test\test\migrations

命令执行后,会在 packages/test/test/migrations 目录下生成一个迁移文件:

创建数据迁移

📚 不熟悉数据迁移?

如果你对 Laravel 的数据迁移不太了解,可以先阅读官方文档:Laravel 数据迁移

编写迁移文件

打开生成的迁移文件,添加表结构定义:

php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('test_user', function (Blueprint $table) {
            $table->id();
            $table->string('name')->comment('名称');
            $table->string('mobile')->comment('手机号');
            $table->string('avatar')->nullable()->comment('头像');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('test_user');
    }
};

执行迁移

运行以下命令创建数据表:

shell
php artisan migrate --path=packages\test\test\migrations\

执行成功后,使用数据库客户端(如 Navicat)查看,可以看到 test_user 表已创建:

数据表

第二步:创建模型

数据表创建完成后,我们需要创建对应的 Eloquent 模型来操作数据。

生成模型文件

执行 Laravel 的模型生成命令:

shell
php artisan make:model TestUser

该命令会在 app/Models 目录下生成模型文件:

创建模型

移动到插件目录

将生成的模型文件移动到插件的 src/Models 目录下(如果目录不存在,请先手动创建):

创建模型

⚠️ 注意命名空间

移动文件后,必须修改命名空间以匹配新的目录位置!详见 常见问题 - 命名空间相关

修改后的模型内容如下:

php
<?php

namespace Test\Test\Models;

use Illuminate\Database\Eloquent\Model;

class TestUser extends Model
{
    protected $table = 'test_user';
    
    protected $fillable = [
        'name', 'mobile', 'avatar'
    ];
}

第三步:创建控制器

控制器负责处理 HTTP 请求,是连接前端和数据的桥梁。

创建目录结构

按照约定,在 src 目录下创建以下目录结构:

src/
└─Http/
  └─Controllers/

然后在 Controllers 目录中创建 TestUserController.php

创建控制器

编写控制器代码

php
<?php

namespace Test\Test\Http\Controllers;

use Catch\Base\CatchController;

class TestUserController extends CatchController
{
    public function index()
    {
        return ['test_user' => 'has no users'];
    }
}

第四步:配置路由

控制器创建完成后,还需要配置路由才能访问。

创建路由文件

在插件根目录创建 routes 目录,并在其中创建 api.php 文件:

创建路由

api.php 中添加路由定义:

php
\Illuminate\Support\Facades\Route::get('/test/user', [\Test\Test\Http\Controllers\TestUserController::class, 'index']);

重新安装插件

⚠️ 重要步骤

每次修改插件的路由、配置等文件后,都需要重新安装插件才能生效!详见 常见问题 - 安装相关

shell
# 先卸载旧版本
composer remove test/test --ignore-platform-reqs

# 再安装新版本
composer require test/test:* --ignore-platform-reqs

启动开发服务器

shell
php artisan serve

验证接口

打开浏览器访问 http://127.0.0.1:8000/test/user

访问接口链接

🎉 恭喜! 如果看到返回的 JSON 数据,说明接口已经成功运行了!

第五步:集成 CatchAdmin 功能

到目前为止,我们已经有了一个可以访问的基础接口。接下来,我们将让插件与 CatchAdmin 深度集成,实现:

  • ✅ 身份认证
  • ✅ 权限控制
  • ✅ Vue 前端页面
  • ✅ 自动生成菜单

5.1 添加身份认证

为了让插件接口需要登录才能访问,我们需要添加身份认证中间件。

修改 routes/api.php 文件:

php
\Illuminate\Support\Facades\Route::prefix(config('catch.route.prefix'))
    ->middleware([
        \Catch\Middleware\AuthMiddleware::class // 身份认证中间件
    ])
    ->group(function(){
        \Illuminate\Support\Facades\Route::get('test/user',
            [\Test\Test\Http\Controllers\TestUserController::class, 'index']);
    });

重新安装插件后,访问 http://127.0.0.1:8000/api/test/user

出现身份认证失效:Unauthenticated.

看到 Unauthenticated 提示,说明身份认证中间件已生效!🔐

5.2 添加权限控制

在身份认证的基础上,我们还可以添加权限控制,确保只有拥有相应权限的用户才能访问接口。

继续修改 routes/api.php

php
\Illuminate\Support\Facades\Route::prefix(config('catch.route.prefix'))
    ->middleware([
        \Catch\Middleware\AuthMiddleware::class,           // 身份认证
        \Modules\Permissions\Middlewares\PermissionGate::class // 权限控制
    ])
    ->group(function(){
        \Illuminate\Support\Facades\Route::get('test/user',
            [\Test\Test\Http\Controllers\TestUserController::class, 'index']);
    });

5.3 添加 Vue 前端页面

CatchAdmin 使用 Vue 作为前端框架。好消息是,插件的 Vue 页面无需编译,可以实现即插即用!

创建视图目录

在插件根目录创建以下目录结构:

resource/
└─views/
  └─user/
    └─index.vue

添加 Vue 页面

编写 Vue 页面

index.vue 中添加内容:

vue
<script>
export default {
    name: "index.vue"
}
</script>

<template>
    <div>这是测试用户页面</div>
</template>

<style scoped>

</style>

访问 Vue 页面

安装插件后,可以通过以下 URL 访问 Vue 文件内容:

http://127.0.0.1:8000/api/plugins/test/test/user/index

📝 URL 规则说明

部分说明
api/plugins固定前缀
test/test插件包名
user/index对应 resource/views/user/index.vue

注意:必须先安装插件,URL 才能生效!

访问 Vue 页面

5.4 使用钩子自动创建菜单

最后一步,我们使用插件钩子在安装时自动创建后台菜单。更多钩子用法请参考 生命周期钩子

编辑钩子文件

找到插件根目录的 hook.php 文件:

钩子自动创建菜单

afterInstall 方法中添加菜单创建代码:

php
public function afterInstall(array $context): void
{
    Plugin::createMenus([
        Plugin::createMenu('测试插件', '/test', 'Test\Test', children: [
            Plugin::createMenu('测试用户', 'user', 'Test\Test',
                controller: 'TestUser', controllerMethod: 'index', type: 2,
                component: Plugin::view('test/test', 'user.index')
            )
        ])
    ]);
}

⚠️ module 参数说明

module 参数必须填写插件的根命名空间(如 Test\Test),这用于标识菜单归属于哪个插件。

module

重新安装并查看效果

shell
composer remove test/test --ignore-platform-reqs
composer require test/test:* --ignore-platform-reqs

刷新后台页面,你将看到新创建的菜单:

CatchAdmin 插件测试页面

🎉 大功告成! 你已经成功开发了一个完整的 CatchAdmin 后台模块插件!

卸载插件

卸载插件非常简单,只需执行以下命令:

shell
composer remove test/test --ignore-platform-reqs

使用钩子清理数据

为了在卸载时自动清理插件创建的菜单等数据,可以在 hook.phpafterUninstall 方法中添加清理逻辑:

php
public function afterUninstall(array $context): void
{
    // 删除该插件创建的所有菜单
    Permissions::where('module', $context['namespace'])->delete();
}

💡 提示

  • $context['namespace'] 会自动获取插件的根命名空间
  • 上述代码会删除该插件的所有菜单,你可以根据实际需求调整删除逻辑

总结

通过本教程,你已经学会了:

  1. 目录结构约定 - 插件的标准目录组织方式
  2. 数据库迁移 - 在插件中创建和管理数据表
  3. 模型与控制器 - 编写业务逻辑代码
  4. 路由配置 - 定义 API 接口
  5. 中间件集成 - 添加身份认证和权限控制
  6. Vue 页面开发 - 创建无需编译的前端页面
  7. 生命周期钩子 - 在安装/卸载时执行自定义逻辑

遇到问题?请查看 常见问题

现在,你可以根据实际需求,开发更复杂的插件功能了!🚀