1135 lines
26 KiB
Markdown
1135 lines
26 KiB
Markdown
# Laravel + Laravel-S 后端 API 项目开发规范
|
||
|
||
## 项目概述
|
||
|
||
本项目是一个基于 Laravel 框架开发的纯后端 API 系统,使用 `hhxsv5/laravel-s` 作为粘合剂,将 Swoole 与 Laravel 框架完美结合,提供高性能的异步服务能力。项目采用模块化开发架构,使用 `nwidart/laravel-modules` 扩展实现业务模块化管理。
|
||
|
||
## 技术栈
|
||
|
||
- **PHP**: 主要开发语言
|
||
- **Laravel**: Web 应用框架
|
||
- **Laravel-S (hhxsv5/laravel-s)**: Swoole 集成扩展
|
||
- **Swoole**: 高性能 PHP 协程框架
|
||
- **JWT (tymon/jwt-auth)**: 用户认证
|
||
- **nwidart/laravel-modules**: 模块化开发扩展
|
||
- **MySQL**: 关系型数据库
|
||
|
||
## 模块化架构
|
||
|
||
### 模块分类
|
||
|
||
项目分为两类模块:
|
||
|
||
1. **基础模块 (Base Modules)**
|
||
- **Auth**: 认证授权模块(用户、角色、权限)
|
||
- **System**: 系统配置模块(配置、日志、字典)
|
||
- 特点:不使用 `nwidart/laravel-modules` 扩展,直接在 Laravel 应用结构中开发
|
||
- 位置:`app/` 目录下
|
||
|
||
2. **业务模块 (Business Modules)**
|
||
- 使用 `nwidart/laravel-modules` 扩展创建
|
||
- 位置:`Modules/` 目录下
|
||
- 每个业务模块独立拥有完整的 MVC 结构
|
||
|
||
### 项目结构
|
||
|
||
```
|
||
├── app/ # 基础模块目录
|
||
│ ├── Http/
|
||
│ │ ├── Controllers/ # 基础模块控制器
|
||
│ │ │ ├── Auth/ # 认证相关控制器
|
||
│ │ │ │ └── Admin
|
||
│ │ │ │ │ ├── Auth.php
|
||
│ │ │ │ │ ├── User.php
|
||
│ │ │ │ │ ├── Role.php
|
||
│ │ │ │ │ └── Permission.php
|
||
│ │ │ └── System/ # 系统相关控制器
|
||
│ │ │ └── Admin
|
||
│ │ │ └── Api
|
||
│ │ └── Middleware/ # 中间件
|
||
│ ├── Models/ # 基础模块模型
|
||
│ │ └── Auth/
|
||
│ │ ├── User.php
|
||
│ │ ├── Role.php
|
||
│ │ └── Permission.php
|
||
│ └── Services/ # 基础模块服务层
|
||
│ └── Auth/
|
||
│ ├── AuthService.php
|
||
│ ├── UserService.php
|
||
│ ├── RoleService.php
|
||
│ └── PermissionService.php
|
||
├── Modules/ # 业务模块目录
|
||
│ ├── ModuleName/ # 业务模块示例
|
||
│ │ ├── App/
|
||
│ │ │ ├── Http/
|
||
│ │ │ │ ├── Controllers/ # 模块控制器
|
||
│ │ │ │ │ ├── Admin/ # 后台管理控制器
|
||
│ │ │ │ │ └── Api/ # 用户端API控制器
|
||
│ │ │ │ ├── Middleware/ # 模块中间件
|
||
│ │ │ │ └── Requests/ # 表单验证
|
||
│ │ │ ├── Models/ # 模块模型
|
||
│ │ │ ├── Services/ # 模块服务层
|
||
│ │ │ └── Providers/ # 模块服务提供者
|
||
│ │ ├── Database/
|
||
│ │ │ ├── migrations/ # 模块迁移文件
|
||
│ │ │ └── seeders/ # 模块数据填充
|
||
│ │ ├── Routes/
|
||
│ │ │ ├── admin.php # 后台管理路由(/admin前缀)
|
||
│ │ │ └── api.php # 用户端API路由(/api前缀)
|
||
│ │ ├── Resources/ # API 资源
|
||
│ │ ├── config/ # 模块配置文件
|
||
│ │ ├── module.json # 模块配置
|
||
│ │ └── README.md # 模块说明文档
|
||
├── config/
|
||
│ ├── modules.php # 模块配置
|
||
│ └── laravels.php # Laravel-S 配置文件
|
||
├── database/
|
||
│ ├── migrations/ # 基础模块迁移文件
|
||
│ └── seeders/ # 基础模块数据填充
|
||
├── routes/
|
||
│ ├── admin.php # 后台管理路由(基础模块)
|
||
│ └── api.php # 公共 API 路由(基础模块)
|
||
└── storage/
|
||
├── laravels.conf # Laravel-S 运行时配置
|
||
└── laravels.pid # Laravel-S 进程 ID
|
||
```
|
||
|
||
## 开发规范
|
||
|
||
### 1. 控制器层 (Controllers)
|
||
|
||
#### 基础模块控制器
|
||
|
||
**命名规范:**
|
||
- 文件路径: `app/Http/Controllers/{Module}/{Name}.php`
|
||
- 类名: `{Name}` (不加 Controller 后缀)
|
||
- 命名空间: `App\Http\Controllers\{Module}`
|
||
|
||
**示例:**
|
||
```php
|
||
<?php
|
||
|
||
namespace App\Http\Controllers\Auth;
|
||
|
||
use Illuminate\Http\Request;
|
||
use App\Services\Auth\UserService;
|
||
|
||
class User extends Controller
|
||
{
|
||
protected $userService;
|
||
|
||
public function __construct(UserService $userService)
|
||
{
|
||
$this->userService = $userService;
|
||
}
|
||
|
||
public function index(Request $request)
|
||
{
|
||
$result = $this->userService->getList($request->all());
|
||
return response()->json($result);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 业务模块控制器
|
||
|
||
业务模块控制器分为两类:
|
||
|
||
**1. 后台管理控制器**
|
||
|
||
**命名规范:**
|
||
- 文件路径: `Modules/{ModuleName}/App/Http/Controllers/Admin/{Name}.php`
|
||
- 类名: `{Name}` (不加 Controller 后缀)
|
||
- 命名空间: `Modules\{ModuleName}\App\Http\Controllers\Admin`
|
||
- 访问路径: `/admin/{module}/{resource}`
|
||
|
||
**示例:**
|
||
```php
|
||
<?php
|
||
|
||
namespace Modules\Blog\App\Http\Controllers\Admin;
|
||
|
||
use Illuminate\Http\Request;
|
||
use Modules\Blog\App\Services\PostService;
|
||
|
||
class Post extends Controller
|
||
{
|
||
protected $postService;
|
||
|
||
public function __construct(PostService $postService)
|
||
{
|
||
$this->postService = $postService;
|
||
}
|
||
|
||
public function index(Request $request)
|
||
{
|
||
$result = $this->postService->getList($request->all());
|
||
return response()->json($result);
|
||
}
|
||
}
|
||
```
|
||
|
||
**2. 用户端 API 控制器**
|
||
|
||
**命名规范:**
|
||
- 文件路径: `Modules/{ModuleName}/App/Http/Controllers/Api/{Name}.php`
|
||
- 类名: `{Name}` (不加 Controller 后缀)
|
||
- 命名空间: `Modules\{ModuleName}\App\Http\Controllers\Api`
|
||
- 访问路径: `/api/{module}/{resource}`
|
||
|
||
**示例:**
|
||
```php
|
||
<?php
|
||
|
||
namespace Modules\Blog\App\Http\Controllers\Api;
|
||
|
||
use Illuminate\Http\Request;
|
||
use Modules\Blog\App\Services\PostService;
|
||
|
||
class Post extends Controller
|
||
{
|
||
protected $postService;
|
||
|
||
public function __construct(PostService $postService)
|
||
{
|
||
$this->postService = $postService;
|
||
}
|
||
|
||
public function index(Request $request)
|
||
{
|
||
$result = $this->postService->getList($request->all());
|
||
return response()->json($result);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 服务层 (Services)
|
||
|
||
#### 基础模块服务
|
||
|
||
**命名规范:**
|
||
- 文件路径: `app/Services/{Module}/{Name}Service.php`
|
||
- 类名: `{Name}Service`
|
||
- 命名空间: `App\Services\{Module}`
|
||
|
||
**示例:**
|
||
```php
|
||
<?php
|
||
|
||
namespace App\Services\Auth;
|
||
|
||
use App\Models\Auth\User;
|
||
use Illuminate\Support\Facades\Hash;
|
||
|
||
class UserService
|
||
{
|
||
public function create(array $data): User
|
||
{
|
||
$data['password'] = Hash::make($data['password']);
|
||
return User::create($data);
|
||
}
|
||
|
||
public function getById(int $id): ?User
|
||
{
|
||
return User::find($id);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 业务模块服务
|
||
|
||
**命名规范:**
|
||
- 文件路径: `Modules/{ModuleName}/App/Services/{Name}Service.php`
|
||
- 类名: `{Name}Service`
|
||
- 命名空间: `Modules\{ModuleName}\App\Services`
|
||
|
||
**示例:**
|
||
```php
|
||
<?php
|
||
|
||
namespace Modules\Blog\App\Services;
|
||
|
||
use Modules\Blog\App\Models\Post;
|
||
|
||
class PostService
|
||
{
|
||
public function create(array $data): Post
|
||
{
|
||
return Post::create($data);
|
||
}
|
||
|
||
public function getById(int $id): ?Post
|
||
{
|
||
return Post::find($id);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 模型层 (Models)
|
||
|
||
#### 基础模块模型
|
||
|
||
**命名规范:**
|
||
- 文件路径: `app/Models/{Module}/{Name}.php`
|
||
- 类名: `{Name}` (单数形式)
|
||
- 命名空间: `App\Models\{Module}`
|
||
- 数据表: `{module}_{names}` (复数形式,带模块前缀)
|
||
|
||
**示例:**
|
||
```php
|
||
<?php
|
||
|
||
namespace App\Models\Auth;
|
||
|
||
use Illuminate\Database\Eloquent\Model;
|
||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||
|
||
class Role extends Model
|
||
{
|
||
protected $table = 'auth_roles';
|
||
|
||
protected $fillable = ['name', 'description'];
|
||
|
||
public function permissions(): BelongsToMany
|
||
{
|
||
return $this->belongsToMany(Permission::class, 'auth_role_permission');
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 业务模块模型
|
||
|
||
**命名规范:**
|
||
- 文件路径: `Modules/{ModuleName}/App/Models/{Name}.php`
|
||
- 类名: `{Name}` (单数形式)
|
||
- 命名空间: `Modules\{ModuleName}\App\Models`
|
||
- 数据表: `{module}_{names}` (复数形式,带模块前缀)
|
||
|
||
**示例:**
|
||
```php
|
||
<?php
|
||
|
||
namespace Modules\Blog\App\Models;
|
||
|
||
use Illuminate\Database\Eloquent\Model;
|
||
|
||
class Post extends Model
|
||
{
|
||
protected $table = 'blog_posts';
|
||
|
||
protected $fillable = ['title', 'content', 'status'];
|
||
}
|
||
```
|
||
|
||
### 4. 中间件 (Middleware)
|
||
|
||
**常用中间件:**
|
||
- `AdminAuth`: 后台管理认证
|
||
- `api.throttle`: API 请求频率限制
|
||
|
||
### 5. API 路由
|
||
|
||
#### 基础模块路由
|
||
|
||
基础模块路由定义在 `routes/` 目录下,通过 `bootstrap/app.php` 进行配置:
|
||
|
||
- `routes/admin.php`: 后台管理路由,自动添加 `/admin` 前缀和 `admin.` 路由名称前缀
|
||
- `routes/api.php`: 公共 API 路由,自动添加 `/api` 前缀
|
||
- `routes/web.php`: Web 路由
|
||
- `routes/console.php`: 命令行路由
|
||
|
||
**路由配置 (bootstrap/app.php):**
|
||
```php
|
||
<?php
|
||
|
||
return Application::configure(basePath: dirname(__DIR__))
|
||
->withRouting(
|
||
web: __DIR__.'/../routes/web.php',
|
||
api: __DIR__.'/../routes/api.php',
|
||
commands: __DIR__.'/../routes/console.php',
|
||
then: function() {
|
||
Route::middleware(['api'])
|
||
->prefix('admin')
|
||
->name('admin.')
|
||
->group(base_path('routes/admin.php'));
|
||
},
|
||
health: '/up',
|
||
)
|
||
->create();
|
||
```
|
||
|
||
**中间件配置:**
|
||
```php
|
||
<?php
|
||
|
||
->withMiddleware(function (Middleware $middleware): void {
|
||
$middleware->alias([
|
||
'auth.check' => \App\Http\Middleware\AuthCheckMiddleware::class,
|
||
]);
|
||
})
|
||
```
|
||
|
||
**异常处理配置:**
|
||
```php
|
||
<?php
|
||
|
||
->withExceptions(function (Exceptions $exceptions): void {
|
||
$exceptions->shouldRenderJsonWhen(function(Request $request, Throwable $e){
|
||
return $request->expectsJson();
|
||
});
|
||
})
|
||
```
|
||
|
||
**事件监听器配置:**
|
||
```php
|
||
<?php
|
||
|
||
->withEvents(discover: [
|
||
__DIR__ . '/../app/Listeners'
|
||
])
|
||
```
|
||
|
||
**路由示例:**
|
||
```php
|
||
<?php
|
||
|
||
// routes/admin.php - 后台管理路由
|
||
use Illuminate\Support\Facades\Route;
|
||
use App\Http\Controllers\Auth\User;
|
||
|
||
Route::middleware(['admin.auth'])->group(function () {
|
||
Route::apiResource('users', User::class);
|
||
// 路由名称: admin.users.index, admin.users.store, etc.
|
||
});
|
||
|
||
// routes/api.php - 公共 API 路由
|
||
use Illuminate\Support\Facades\Route;
|
||
use App\Http\Controllers\Auth\User;
|
||
|
||
Route::middleware(['auth:api'])->group(function () {
|
||
Route::apiResource('profile', User::class);
|
||
});
|
||
```
|
||
|
||
#### 业务模块路由
|
||
|
||
业务模块路由包含两个文件,分别定义后台管理和用户端 API 路由:
|
||
|
||
**1. 后台管理路由 (Routes/admin.php)**
|
||
|
||
文件路径:`Modules/{ModuleName}/Routes/admin.php`
|
||
|
||
```php
|
||
<?php
|
||
|
||
use Illuminate\Support\Facades\Route;
|
||
use Modules\Blog\App\Http\Controllers\Admin\Post;
|
||
|
||
Route::middleware(['admin.auth'])->group(function () {
|
||
Route::apiResource('blog/posts', Post::class);
|
||
});
|
||
```
|
||
|
||
路由访问路径:`/admin/{module}/{resource}`
|
||
|
||
**2. 用户端 API 路由 (Routes/api.php)**
|
||
|
||
文件路径:`Modules/{ModuleName}/Routes/api.php`
|
||
|
||
```php
|
||
<?php
|
||
|
||
use Illuminate\Support\Facades\Route;
|
||
use Modules\Blog\App\Http\Controllers\Api\Post;
|
||
|
||
Route::middleware(['auth:api'])->group(function () {
|
||
Route::apiResource('blog/posts', Post::class);
|
||
});
|
||
```
|
||
|
||
路由访问路径:`/api/{module}/{resource}`
|
||
|
||
### 6. 模块创建命令
|
||
|
||
使用 `nwidart/laravel-modules` 创建新业务模块:
|
||
|
||
```bash
|
||
# 创建模块
|
||
php artisan module:make ModuleName
|
||
|
||
# 创建带有资源的模块
|
||
php artisan module:make ModuleName --resource
|
||
|
||
# 创建多个模块
|
||
php artisan module:make Blog Shop Order
|
||
```
|
||
|
||
### 7. 模块组件创建命令
|
||
|
||
```bash
|
||
# 在指定模块中创建后台管理控制器
|
||
php artisan module:make-controller Admin/Post Blog
|
||
|
||
# 在指定模块中创建用户端API控制器
|
||
php artisan module:make-controller Api/Post Blog
|
||
|
||
# 在指定模块中创建模型
|
||
php artisan module:make-model Post Blog
|
||
|
||
# 在指定模块中创建迁移
|
||
php artisan module:make-migration create_posts_table Blog
|
||
|
||
# 在指定模块中创建服务类(需要自定义)
|
||
# 手动在 Modules/Blog/App/Services/ 目录创建
|
||
```
|
||
|
||
**注意:** 使用 `module:make-controller` 命令创建的控制器会自动添加 `Controller` 后缀,需要手动重命名文件和类名以移除后缀。
|
||
|
||
## API 响应规范
|
||
|
||
### 统一响应格式
|
||
|
||
**成功响应:**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
**错误响应:**
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "错误信息",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
**分页响应:**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": {
|
||
"list": [],
|
||
"total": 100,
|
||
"page": 1,
|
||
"page_size": 20
|
||
}
|
||
}
|
||
```
|
||
|
||
**树形响应:**
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "success",
|
||
"data": [
|
||
{...,children: [
|
||
{...}
|
||
]},
|
||
{...,children: [
|
||
{...}
|
||
]}
|
||
]
|
||
}
|
||
```
|
||
|
||
### HTTP 状态码规范
|
||
|
||
- `200 OK`: 请求成功
|
||
- `201 Created`: 创建成功
|
||
- `204 No Content`: 删除成功
|
||
- `400 Bad Request`: 请求参数错误
|
||
- `401 Unauthorized`: 未认证
|
||
- `403 Forbidden`: 无权限
|
||
- `404 Not Found`: 资源不存在
|
||
- `422 Unprocessable Entity`: 表单验证失败
|
||
- `500 Internal Server Error`: 服务器错误
|
||
|
||
## Laravel-S / Swoole 开发注意事项
|
||
|
||
### 1. 长生命周期注意事项
|
||
|
||
由于 Swoole 是长生命周期运行,需注意以下几点:
|
||
|
||
**避免使用静态变量:**
|
||
```php
|
||
// ❌ 错误
|
||
public function handle()
|
||
{
|
||
static $counter = 0; // 会累积,不会重置
|
||
}
|
||
|
||
// ✅ 正确
|
||
public function handle()
|
||
{
|
||
$counter = 0; // 每次请求重新初始化
|
||
}
|
||
```
|
||
|
||
**避免使用全局变量:**
|
||
- 不要依赖 `$_GET`, `$_POST` 等超全局变量
|
||
- 使用 Laravel 的 `Request` 对象获取请求数据
|
||
|
||
### 2. 连接池管理
|
||
|
||
数据库、Redis 等连接需要正确管理,避免连接泄漏。
|
||
|
||
**配置连接池:** 在 `config/laravels.php` 中配置:
|
||
```php
|
||
'swoole' => [
|
||
'enable_coroutine' => true,
|
||
'worker_num' => 4,
|
||
'max_request' => 5000,
|
||
'max_request_grace' => 500,
|
||
]
|
||
```
|
||
|
||
### 3. 热重载机制
|
||
|
||
开发环境可以使用文件监控实现热重载:
|
||
|
||
```bash
|
||
# 使用 bin/laravels reload
|
||
php bin/laravels reload
|
||
|
||
# 或使用文件监控
|
||
bin/fswatch # Linux/Mac
|
||
bin/inotify # Linux
|
||
```
|
||
|
||
### 4. 定时器
|
||
|
||
使用 Swoole 定时器时,要确保定时器在合适的时机清除:
|
||
|
||
```php
|
||
\Swoole\Timer::after(5000, function() {
|
||
// 5秒后执行
|
||
});
|
||
|
||
$timerId = \Swoole\Timer::tick(1000, function() {
|
||
// 每秒执行
|
||
return false; // 返回 false 停止定时器
|
||
});
|
||
```
|
||
|
||
## 数据库规范
|
||
|
||
### 迁移文件
|
||
|
||
#### 基础模块迁移
|
||
|
||
- 文件路径: `database/migrations/`
|
||
- 迁移文件命名: `{YYYY_MM_DD_HHMMSS}_{description}.php`
|
||
- 表命名: `{module}_{table_names}` (模块名小写 + 下划线 + 表名复数,所有模块表都必须带模块名前缀)
|
||
|
||
**表命名示例:**
|
||
- Auth 模块: `auth_users`, `auth_roles`, `auth_permissions`, `auth_role_permission`
|
||
- System 模块: `system_setting`, `system_logs`, `system_dictionaries`
|
||
|
||
**迁移文件示例:**
|
||
```php
|
||
<?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('auth_users', function (Blueprint $table) {
|
||
$table->id();
|
||
$table->string('name');
|
||
$table->string('email')->unique();
|
||
$table->timestamps();
|
||
$table->softDeletes();
|
||
});
|
||
}
|
||
|
||
public function down()
|
||
{
|
||
Schema::dropIfExists('auth_users');
|
||
}
|
||
};
|
||
```
|
||
|
||
#### 业务模块迁移
|
||
|
||
- 文件路径: `Modules/{ModuleName}/Database/migrations/`
|
||
- 迁移文件命名: `{YYYY_MM_DD_HHMMSS}_{description}.php`
|
||
- 表命名: `{module}_{table_names}` (模块名小写 + 下划线 + 表名复数,所有模块表都必须带模块名前缀)
|
||
|
||
**表命名示例:**
|
||
- Blog 模块: `blog_posts`, `blog_categories`, `blog_tags`, `blog_post_tag`
|
||
- Shop 模块: `shop_products`, `shop_orders`, `shop_order_items`
|
||
- Order 模块: `order_payments`, `order_shippings`
|
||
|
||
### 字段命名规范
|
||
|
||
- 使用蛇形命名: `user_id`, `created_at`
|
||
- 布尔类型使用 `is_` 前缀: `is_active`, `is_deleted`
|
||
- 主键统一使用 `id`
|
||
|
||
### 数据填充
|
||
|
||
#### 基础模块数据填充
|
||
|
||
- 文件路径: `database/seeders/`
|
||
|
||
#### 业务模块数据填充
|
||
|
||
- 文件路径: `Modules/{ModuleName}/Database/seeders/`
|
||
|
||
#### 菜单权限节点 Seed 规范
|
||
|
||
在 Seeder 文件中创建菜单权限节点时,需要遵循以下规范。
|
||
|
||
**数据库字段说明 (auth_permissions 表):**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | number | 权限ID |
|
||
| title | string | 权限标题(用于菜单显示) |
|
||
| name | string | 权限编码(唯一标识) |
|
||
| type | string | 权限类型:menu(菜单)、api(接口)、button(按钮)、url(链接) |
|
||
| parent_id | number | 父级ID,顶级菜单为 0 |
|
||
| path | string | 路由路径(如 `/system/users`) |
|
||
| component | string | 前端组件路径(如 `system/users/index`) |
|
||
| meta | json | 元数据(包含 icon、hidden、keepAlive 等) |
|
||
| sort | number | 排序 |
|
||
| status | number | 状态:1启用 0禁用 |
|
||
|
||
**菜单结构规范:**
|
||
|
||
1. **顶级菜单**(parent_id=0)不需要 component 值
|
||
- 顶级菜单作为分组容器,不需要指定组件路径
|
||
- 示例:系统管理菜单
|
||
|
||
2. **只有最后一级的菜单**才需要 component 值
|
||
- 如果菜单没有子菜单,则需要指定 component
|
||
- 如果菜单有子菜单,则不需要指定 component
|
||
|
||
3. **非菜单类型**(如 button)不需要 component 值
|
||
- 按钮权限只用于权限控制,不涉及页面路由
|
||
|
||
4. **所有页面组件的菜单**在前端处理时都拉平挂载在 Layouts 框架组件下
|
||
- 前端会将菜单数据转换为路由,所有页面路由都会挂载到 Layout 布局下
|
||
- 不需要在前端维护嵌套的路由结构
|
||
|
||
** Seeder 示例:**
|
||
|
||
```php
|
||
<?php
|
||
|
||
private function createPermissions(): void
|
||
{
|
||
$permissions = [
|
||
// 顶级菜单(无 component)
|
||
[
|
||
'title' => '系统管理',
|
||
'name' => 'system',
|
||
'type' => 'menu',
|
||
'parent_id' => 0,
|
||
'path' => '/system',
|
||
'component' => null, // 顶级菜单不需要 component
|
||
'meta' => json_encode([
|
||
'icon' => 'Setting',
|
||
'hidden' => false,
|
||
'hiddenBreadcrumb' => false,
|
||
'keepAlive' => false
|
||
]),
|
||
'sort' => 1,
|
||
'status' => 1,
|
||
],
|
||
|
||
// 最后一级菜单(有 component)
|
||
[
|
||
'title' => '用户管理',
|
||
'name' => 'system.users',
|
||
'type' => 'menu',
|
||
'parent_id' => 0,
|
||
'path' => '/system/users',
|
||
'component' => 'system/users/index', // 最后一级菜单需要 component
|
||
'meta' => json_encode([
|
||
'icon' => 'User',
|
||
'hidden' => false,
|
||
'hiddenBreadcrumb' => false,
|
||
'keepAlive' => true
|
||
]),
|
||
'sort' => 1,
|
||
'status' => 1,
|
||
],
|
||
|
||
// 按钮权限(无 component)
|
||
[
|
||
'title' => '查看用户',
|
||
'name' => 'system.users.view',
|
||
'type' => 'button',
|
||
'parent_id' => 0,
|
||
'path' => 'admin.users.index',
|
||
'component' => null, // 非菜单类型不需要 component
|
||
'meta' => null,
|
||
'sort' => 1,
|
||
'status' => 1,
|
||
],
|
||
|
||
// API 权限
|
||
[
|
||
'title' => '获取用户列表',
|
||
'name' => 'system.users.list',
|
||
'type' => 'api',
|
||
'parent_id' => 0,
|
||
'path' => 'admin.users.index',
|
||
'component' => null,
|
||
'meta' => null,
|
||
'sort' => 1,
|
||
'status' => 1,
|
||
],
|
||
];
|
||
|
||
foreach ($permissions as $permission) {
|
||
Permission::create($permission);
|
||
}
|
||
}
|
||
```
|
||
|
||
**重要说明:**
|
||
|
||
- `title` 用于显示在菜单中的标题
|
||
- `name` 是权限的唯一标识编码,用于前端路由和权限验证
|
||
- `parent_id` 主要用于构建菜单树的层级关系(侧边栏显示)
|
||
- `path` 用于菜单类型的路由路径,或 API 类型的接口路由名称
|
||
- `component` 值只需要在最后一级菜单(叶子节点)中设置
|
||
- 前端会根据 `type` 字段判断是否需要加载组件
|
||
|
||
## 认证与授权
|
||
|
||
### JWT 认证
|
||
|
||
使用 `tymon/jwt-auth` 实现 JWT 认证:
|
||
|
||
```php
|
||
// 登录获取 token
|
||
$token = auth('api')->attempt($credentials);
|
||
|
||
// 使用 token 认证
|
||
$user = auth('api')->user();
|
||
|
||
// 刷新 token
|
||
$newToken = auth('api')->refresh();
|
||
|
||
// 登出
|
||
auth('api')->logout();
|
||
```
|
||
|
||
### RBAC 权限控制
|
||
|
||
基于角色的访问控制 (Role-Based Access Control):
|
||
|
||
- User (用户) - Role (角色) - Permission (权限)
|
||
- 多对多关系设计
|
||
|
||
## 常用命令
|
||
|
||
### Laravel 命令
|
||
|
||
```bash
|
||
# 创建基础模块控制器
|
||
php artisan make:controller Auth/UserController
|
||
|
||
# 创建基础模块模型
|
||
php artisan make:model Auth/User
|
||
|
||
# 创建基础模块迁移
|
||
php artisan make:migration create_auth_users_table
|
||
|
||
# 执行迁移(包括所有模块)
|
||
php artisan migrate
|
||
|
||
# 回滚迁移
|
||
php artisan migrate:rollback
|
||
|
||
# 清除缓存
|
||
php artisan cache:clear
|
||
php artisan config:clear
|
||
php artisan route:clear
|
||
```
|
||
|
||
### Laravel-S 命令
|
||
|
||
```bash
|
||
# 启动服务
|
||
php bin/laravels start
|
||
|
||
# 停止服务
|
||
php bin/laravels stop
|
||
|
||
# 重启服务
|
||
php bin/laravels restart
|
||
|
||
# 重载服务(平滑重启)
|
||
php bin/laravels reload
|
||
|
||
# 查看状态
|
||
php bin/laravels status
|
||
|
||
# 查看帮助
|
||
php bin/laravels help
|
||
```
|
||
|
||
### Laravel Modules 命令
|
||
|
||
```bash
|
||
# 创建模块
|
||
php artisan module:make ModuleName
|
||
|
||
# 列出所有模块
|
||
php artisan module:list
|
||
|
||
# 启用模块
|
||
php artisan module:enable ModuleName
|
||
|
||
# 禁用模块
|
||
php artisan module:disable ModuleName
|
||
|
||
# 删除模块
|
||
php artisan module:delete ModuleName
|
||
|
||
# 模块迁移
|
||
php artisan module:migrate ModuleName
|
||
|
||
# 回滚模块迁移
|
||
php artisan module:migrate-rollback ModuleName
|
||
|
||
# 刷新模块迁移
|
||
php artisan module:migrate-refresh ModuleName
|
||
|
||
# 模块数据填充
|
||
php artisan module:seed ModuleName
|
||
|
||
# 重新发布模块配置
|
||
php artisan vendor:publish --tag=modules-config
|
||
```
|
||
|
||
## 代码质量
|
||
|
||
### PSR 规范
|
||
|
||
遵循 PSR-4 自动加载规范和 PSR-12 编码规范。
|
||
|
||
### 注释规范
|
||
|
||
- 类和方法添加 DocBlock 注释
|
||
- 复杂逻辑添加行内注释
|
||
|
||
**示例:**
|
||
```php
|
||
/**
|
||
* 用户服务类
|
||
*
|
||
* @package App\Services\Auth
|
||
*/
|
||
class UserService
|
||
{
|
||
/**
|
||
* 创建用户
|
||
*
|
||
* @param array $data 用户数据
|
||
* @return User
|
||
*/
|
||
public function create(array $data): User
|
||
{
|
||
// 业务逻辑
|
||
}
|
||
}
|
||
```
|
||
|
||
## 模块开发规范
|
||
|
||
### 1. 模块独立性
|
||
|
||
每个业务模块应保持独立,避免直接依赖其他业务模块:
|
||
|
||
- 模块间通信通过接口或事件实现
|
||
- 避免跨模块直接调用服务类
|
||
- 使用 Laravel 事件系统实现模块间解耦
|
||
|
||
### 2. 模块配置
|
||
|
||
每个业务模块应提供配置文件:
|
||
|
||
```php
|
||
// Modules/Blog/config/blog.php
|
||
return [
|
||
'per_page' => 20,
|
||
'status' => [
|
||
'draft' => 0,
|
||
'published' => 1,
|
||
],
|
||
];
|
||
```
|
||
|
||
### 3. 模块 README
|
||
|
||
每个业务模块应包含 README.md 文档,说明:
|
||
|
||
- 模块功能描述
|
||
- API 接口列表
|
||
- 数据库表结构
|
||
- 依赖说明
|
||
- 使用示例
|
||
|
||
### 4. 模块版本控制
|
||
|
||
使用 `module.json` 文件管理模块版本:
|
||
|
||
```json
|
||
{
|
||
"name": "Blog",
|
||
"alias": "blog",
|
||
"description": "Blog module",
|
||
"keywords": [],
|
||
"priority": 0,
|
||
"providers": [
|
||
"Modules\\Blog\\App\\Providers\\BlogServiceProvider"
|
||
],
|
||
"files": []
|
||
}
|
||
```
|
||
|
||
## 异常处理
|
||
|
||
### 自定义异常
|
||
|
||
创建自定义异常类处理业务异常:
|
||
|
||
```php
|
||
<?php
|
||
|
||
namespace App\Exceptions;
|
||
|
||
use Exception;
|
||
|
||
class BusinessException extends Exception
|
||
{
|
||
protected $code;
|
||
|
||
public function __construct(string $message, int $code = 400)
|
||
{
|
||
parent::__construct($message, $code);
|
||
$this->code = $code;
|
||
}
|
||
|
||
public function render()
|
||
{
|
||
return response()->json([
|
||
'code' => $this->code,
|
||
'message' => $this->message,
|
||
'data' => null
|
||
], $this->code);
|
||
}
|
||
}
|
||
```
|
||
|
||
## 测试规范
|
||
|
||
### 单元测试
|
||
|
||
```bash
|
||
# 创建测试
|
||
php artisan make:test UserTest
|
||
|
||
# 运行测试
|
||
php artisan test
|
||
```
|
||
|
||
### 模块测试
|
||
|
||
```bash
|
||
# 创建模块测试
|
||
php artisan module:test PostTest Blog
|
||
|
||
# 运行所有测试
|
||
php artisan test
|
||
```
|
||
|
||
## 部署注意事项
|
||
|
||
1. 生产环境关闭调试模式: `APP_ENV=production`, `APP_DEBUG=false`
|
||
2. 配置合适的 Worker 数量
|
||
3. 设置 `max_request` 防止内存泄漏
|
||
4. 配置日志轮转
|
||
5. 设置适当的超时时间
|
||
6. 确保所有模块的迁移都已执行
|
||
|
||
## 安全规范
|
||
|
||
1. 所有用户输入必须经过验证
|
||
2. 敏感数据必须加密存储
|
||
3. 使用 CSRF 防护(API 除外)
|
||
4. 使用 HTTPS 传输
|
||
5. 定期更新依赖包
|
||
6. 不要在代码中硬编码密码或密钥
|
||
7. 模块间通信需进行权限验证
|
||
|
||
## 性能优化
|
||
|
||
1. 使用 Redis 缓存热点数据
|
||
2. 使用队列处理耗时任务
|
||
3. 优化数据库查询,避免 N+1 问题
|
||
4. 使用 Eager Loading
|
||
5. 合理使用索引
|
||
6. 使用 Swoole 协程提高并发性能
|
||
7. 模块按需加载,禁用不使用的模块
|
||
|
||
## Git 规范
|
||
|
||
### 提交信息格式
|
||
|
||
```
|
||
<type>(<scope>): <subject>
|
||
|
||
<body>
|
||
|
||
<footer>
|
||
```
|
||
|
||
**Type 类型:**
|
||
- `feat`: 新功能
|
||
- `fix`: 修复
|
||
- `docs`: 文档
|
||
- `style`: 格式
|
||
- `refactor`: 重构
|
||
- `test`: 测试
|
||
- `chore`: 构建/工具
|
||
|
||
**Scope 示例:**
|
||
- `auth`: 认证模块
|
||
- `system`: 系统模块
|
||
- `blog`: 博客业务模块
|
||
- `shop`: 商城业务模块
|
||
|
||
**示例:**
|
||
```
|
||
feat(auth): 添加用户登录功能
|
||
|
||
- 实现 JWT 认证
|
||
- 添加登录接口
|
||
- 完善权限验证
|
||
|
||
Closes #123
|
||
```
|
||
|
||
## 资源链接
|
||
|
||
- [Laravel 文档](https://laravel.com/docs)
|
||
- [Laravel-S 文档](https://github.com/hhxsv5/laravel-s)
|
||
- [Swoole 文档](https://www.swoole.com/)
|
||
- [JWT-Auth 文档](https://github.com/tymondesigns/jwt-auth)
|
||
- [Laravel Modules 文档](https://nwidart.com/laravel-modules/)
|