83 lines
4.7 KiB
Plaintext
83 lines
4.7 KiB
Plaintext
---
|
||
description: >
|
||
Hyperf 模块化脚手架技能。在 modules/ 下新建业务模块、创建 module、
|
||
添加模块化功能时激活。基于 Composer path repository + ConfigProvider 机制。
|
||
globs:
|
||
- "**/modules/*/src/**/*.php"
|
||
- "**/modules/*/composer.json"
|
||
alwaysApply: false
|
||
---
|
||
|
||
# Module Scaffold
|
||
|
||
> 本文件是精简执行摘要。完整流程、模板和深度参考见:
|
||
> Read `.cursor/skills/module-scaffold/SKILL.md`
|
||
|
||
> **适用性**(双模式):
|
||
> - **新建**模块:走完整执行流程(Step 1-7)
|
||
> - **修改**已有模块代码:跳过脚手架步骤,完成后走「验证」清单
|
||
|
||
## 执行流程
|
||
|
||
1. 确认模块规格(名称、描述、接口类型:`api` / `admin` / `both`、所需子层)
|
||
2. 生成目录结构(**Controller 按接口类型分子目录,见下方规则**)
|
||
3. 生成模块 `composer.json`(name: `modules/{kebab-case}`, namespace: `Modules\{PascalCase}`, extra.hyperf.config)
|
||
4. 生成 `ConfigProvider.php`(注册 dependencies + annotations scan + publish)
|
||
5. 生成 Controller(根据接口类型选择正确子目录和模板)
|
||
6. **配置依赖检查**(使用事件/队列/缓存时必须检查):
|
||
- 使用异步队列:检查主项目 `config/autoload/async_queue.php` 是否存在
|
||
- 使用 Redis 缓存:检查主项目 `config/autoload/redis.php` 连接池配置
|
||
- 使用 JWT:检查主项目 `config/autoload/jwt.php` 和环境变量 `JWT_SECRET`
|
||
7. **无需修改主项目 `composer.json`**:ModuleLoader 在启动时自动扫描发现
|
||
8. 验证:`require vendor/autoload.php` 后检查 ConfigProvider 是否被发现
|
||
|
||
## Controller 与 Request 目录规则(核心)
|
||
|
||
根据接口路由前缀,Controller 和 Request **均须放入对应子目录**:
|
||
|
||
| 接口类型 | 路由前缀 | Controller 目录 | Request 目录 | 类名规范 |
|
||
|----------|----------|-----------------|--------------|----------|
|
||
| 用户端 | `/api/{module}` | `Http/Controller/Api/` | `Http/Request/Api/` | `{Name}Controller` / `{Name}Request` |
|
||
| 管理端 | `/admin/{module}` | `Http/Controller/Admin/` | `Http/Request/Admin/` | `{Name}Controller` / `{Name}Request` |
|
||
| 两者 | 各自前缀 | 两组子目录都创建 | 两组子目录都创建 | 各自子目录,类名相同 |
|
||
|
||
**额外约定**:
|
||
- `Admin/` 下的控制器**自动添加** `#[Middleware(JwtAuthMiddleware::class)]` 注解
|
||
- **类名不加接口类型前缀**,`Api/` 和 `Admin/` 下同名类通过命名空间区分
|
||
- Controller 中 `use` 的 Request 路径必须与子目录命名空间一致
|
||
- 路由前缀中 `/api/` 和 `/admin/` 是判断依据,不能混放
|
||
- 未明确时,**主动询问**接口类型而不是猜测
|
||
|
||
## 命名约定
|
||
|
||
| 位置 | 格式 | 示例 |
|
||
|------|------|------|
|
||
| 目录名 | PascalCase | `modules/UserCenter/` |
|
||
| Composer 包名 | kebab-case | `modules/user-center` |
|
||
| PHP 命名空间 | PascalCase | `Modules\UserCenter` |
|
||
| 用户端路由前缀 | `/api/kebab-case` | `/api/user-center` |
|
||
| 管理端路由前缀 | `/admin/kebab-case` | `/admin/user-center` |
|
||
|
||
## 关键机制
|
||
|
||
- **ModuleLoader 自动发现**:`app/Support/ModuleLoader.php` 注册在 `autoload.files`,在 `vendor/autoload.php` 执行时扫描 `modules/*/composer.json`,通过反射注入 `Hyperf\Support\Composer::$extra`,让 `ProviderConfig::load()` 发现模块 ConfigProvider。**无需修改 `composer.json` require**
|
||
- **composer-merge-plugin**:合并模块 `composer.json` 的 `autoload` 和第三方 `require` 到主项目(仅在模块有外部依赖时才需要 `composer update`)
|
||
- **ConfigProvider**:模块自注册 DI 绑定、注解扫描路径、可发布配置
|
||
|
||
## 验证
|
||
|
||
- [ ] **Controller 按接口类型放入正确子目录**(`Api/` 或 `Admin/`,不能平铺在 `Controller/` 根目录)
|
||
- [ ] **Request 按接口类型放入正确子目录**(`Request/Api/` 或 `Request/Admin/`,不能平铺在 `Request/` 根目录)
|
||
- [ ] Controller 命名空间含 `\Controller\Api\` 或 `\Controller\Admin\`
|
||
- [ ] Request 命名空间含 `\Request\Api\` 或 `\Request\Admin\`
|
||
- [ ] Controller 中 `use` 的 Request 路径与子目录命名空间一致
|
||
- [ ] `Admin/` 下:Controller 自动加 `JwtAuthMiddleware`;类名与 `Api/` 保持一致,**不加 `Admin` 前缀**
|
||
- [ ] 模块结构完整(composer.json + ConfigProvider.php + Http/Controller/{Api|Admin}/ + Http/Request/{Api|Admin}/)
|
||
- [ ] composer.json name 为 `modules/{kebab-case}`
|
||
- [ ] namespace 为 `Modules\{PascalCase}`
|
||
- [ ] ConfigProvider 注册 `__DIR__` 扫描路径
|
||
- [ ] extra.hyperf.config 指向正确 ConfigProvider
|
||
- [ ] **无需修改主 composer.json**,ModuleLoader 自动发现
|
||
- [ ] Hyperf ProviderConfig 能发现模块 ConfigProvider
|
||
- [ ] `php -l` 无语法错误
|