- 新增角色菜单关联模型、控制器、请求验证和业务逻辑 - 新增用户角色关联模型、控制器、请求验证和业务逻辑 - 更新系统角色模型,增加与用户和菜单的关联 - 更新用户模型,增加与角色的关联和相关方法 - 在路由文件中添加新功能的路由定义
13 KiB
13 KiB
Laravel CRUD 代码生成模板(优化版)
架构说明
分层架构
- BaseModel.php:提供通用的权限控制(tenant_id 自动过滤)、软删除、时间戳等基础功能
- BaseService.php:提供标准的 CRUD 操作,统一事务处理和异常处理
- BaseController.php:提供统一的响应格式(Success、SuccessPage、Field)和参数获取方法
- Controllers:只负责参数验证和调用服务层,无需关心权限控制和异常处理
权限控制机制
- 查询时:BaseModel 的全局作用域自动过滤当前用户的 tenant_id 数据
- 创建时:BaseModel 的 creating 钩子自动设置当前用户的 tenant_id
- 更新/删除时:BaseService 在操作前验证记录的 tenant_id 权限
目录结构规范
app/
├── Models/
│ └── [模块名]/
│ └── [表名Model].php
├── Services/
│ └── [模块名]/
│ └── [表名Service].php
├── Http/
│ ├── Controllers/
│ │ └── Admin/
│ │ └── [模块名]/
│ │ └── [表名Controller].php
│ └── Requests/
│ └── Admin/
│ └── [模块名]/
│ └── [表名Request].php
└── routes/
└── admin/
└── [模块名]_route.php
模型命名规范
- 模型名必须与数据库表名保持一致的大驼峰格式
- 例如:
system_users表 →SystemUsers模型 - 例如:
system_role表 →SystemRole模型 - 例如:
user_profile表 →UserProfile模型 - 不要使用简化名称,严格按照表名转换大驼峰
模板文件
1. 模型文件模板
文件路径:app/Models/[模块名]/[表名].php
<?php
namespace App\Models\[模块名];
use App\Models\BaseModel;
/**
* [中文名称]模型
*/
class [表名] extends BaseModel
{
protected $table = '[数据库表名]';
protected $fillable = [
'[字段1]',
'[字段2]',
// ... 其他可填充字段
];
protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
// 如果有特殊的查询作用域,可以添加
// public function scopeActive($query)
// {
// return $query->where('status', 1);
// }
// 如果有关联关系,可以添加
// public function relatedModel()
// {
// return $this->belongsTo(RelatedModel::class);
// }
}
2. 服务文件模板
文件路径:app/Services/[模块名]/[表名Service].php
<?php
namespace App\Services\[模块名];
use App\Models\[模块名]\[表名];
use App\Services\BaseService;
use Illuminate\Pagination\LengthAwarePaginator;
/**
* [中文名称]服务类
*/
class [表名Service] extends BaseService
{
protected string $modelClass = [表名]::class;
/**
* 获取[中文名称]列表
*/
public function getList(array $params): LengthAwarePaginator
{
$query = [表名]::query();
// 搜索条件
if (!empty($params['keyword'])) {
$query->where(function ($q) use ($params) {
$q->where('name', 'like', '%' . $params['keyword'] . '%')
->orWhere('code', 'like', '%' . $params['keyword'] . '%');
});
}
// 状态筛选
if (isset($params['status'])) {
$query->where('status', $params['status']);
}
// 排序
$query->orderBy('sort_order', 'asc')
->orderBy('id', 'desc');
return $query->paginate($params['page_size'] ?? 15);
}
/**
* 获取简单列表(用于下拉选择等)
*/
public function getSimpleList(): array
{
return [表名]::select('id', 'name')
->where('status', 1)
->orderBy('sort_order', 'asc')
->get()
->toArray();
}
// 如果有特殊业务逻辑,可以重写父类方法
// protected function beforeCreate(array &$data): void
// {
// // 创建前的特殊处理
// }
// protected function afterCreate($model, array $data): void
// {
// // 创建后的特殊处理
// }
}
3. 控制器文件模板
文件路径:app/Http/Controllers/Admin/[模块名]/[表名Controller].php
<?php
namespace App\Http\Controllers\Admin\[模块名];
use App\Http\Controllers\BaseController;
use App\Http\Requests\Admin\[模块名]\[表名Request];
use App\Services\[模块名]\[表名Service];
use Illuminate\Http\JsonResponse;
/**
* [中文名称]控制器
*/
class [表名Controller] extends BaseController
{
public function __construct(
private [表名Service] $[表名变量]Service
) {}
/**
* 获取[中文名称]列表
*/
public function list([表名Request] $request): JsonResponse
{
$params = $request->validated();
$result = $this->[表名变量]Service->getList($params);
return $this->SuccessPage($result->items(), $result->total());
}
/**
* 获取简单列表
*/
public function simpleList(): JsonResponse
{
$result = $this->[表名变量]Service->getSimpleList();
return $this->Success($result);
}
/**
* 获取[中文名称]详情
*/
public function detail([表名Request] $request): JsonResponse
{
$params = $request->validated();
$result = $this->[表名变量]Service->detail($params['id']);
return $this->Success($result);
}
/**
* 创建[中文名称]
*/
public function create([表名Request] $request): JsonResponse
{
$data = $request->validated();
$result = $this->[表名变量]Service->create($data);
return $this->Success($result);
}
/**
* 更新[中文名称]
*/
public function update([表名Request] $request): JsonResponse
{
$params = $request->validated();
$result = $this->[表名变量]Service->update($params['id'], $params);
return $this->Success($result);
}
/**
* 删除[中文名称]
*/
public function delete([表名Request] $request): JsonResponse
{
$params = $request->validated();
$this->[表名变量]Service->delete($params['id']);
return $this->Success();
}
/**
* 批量删除[中文名称]
*/
public function batchDelete([表名Request] $request): JsonResponse
{
$params = $request->validated();
$this->[表名变量]Service->batchDelete($params['ids']);
return $this->Success();
}
}
4. 验证文件模板
文件路径:app/Http/Requests/Admin/[模块名]/[表名Request].php
<?php
namespace App\Http\Requests\Admin\[模块名];
use App\Http\Requests\BaseRequest;
/**
* [中文名称]请求验证
*/
class [表名Request] extends BaseRequest
{
/**
* 获取验证规则
*/
public function rules(): array
{
$action = $this->route()->getActionMethod();
return match($action) {
'list' => $this->listRules(),
'detail' => $this->detailRules(),
'create' => $this->createRules(),
'update' => $this->updateRules(),
'delete' => $this->deleteRules(),
'batchDelete' => $this->batchDeleteRules(),
'simpleList' => [],
default => []
};
}
/**
* 列表查询验证规则
*/
private function listRules(): array
{
return array_merge($this->getPaginationRules(), [
'keyword' => ['sometimes', 'string', 'max:50'],
'status' => ['sometimes', 'integer', 'in:0,1'],
]);
}
/**
* 详情查询验证规则
*/
private function detailRules(): array
{
return [
'id' => ['required', 'integer', 'exists:[数据库表名],id'],
];
}
/**
* 创建验证规则
*/
private function createRules(): array
{
return [
'name' => ['required', 'string', 'max:100'],
'code' => ['required', 'string', 'max:50', 'unique:[数据库表名],code'],
'status' => ['sometimes', 'integer', 'in:0,1'],
'sort_order' => ['sometimes', 'integer', 'min:0'],
'remark' => ['sometimes', 'string', 'max:200'],
];
}
/**
* 更新验证规则
*/
private function updateRules(): array
{
return [
'id' => ['required', 'integer', 'exists:[数据库表名],id'],
'name' => ['required', 'string', 'max:100'],
'code' => ['required', 'string', 'max:50', 'unique:[数据库表名],code,' . $this->input('id')],
'status' => ['sometimes', 'integer', 'in:0,1'],
'sort_order' => ['sometimes', 'integer', 'min:0'],
'remark' => ['sometimes', 'string', 'max:200'],
];
}
/**
* 删除验证规则
*/
private function deleteRules(): array
{
return [
'id' => ['required', 'integer', 'exists:[数据库表名],id'],
];
}
/**
* 批量删除验证规则
*/
private function batchDeleteRules(): array
{
return [
'ids' => ['required', 'array', 'min:1'],
'ids.*' => ['integer', 'exists:[数据库表名],id'],
];
}
/**
* 获取验证错误消息
*/
public function messages(): array
{
return [
'name.required' => '[中文名称]名称不能为空',
'name.max' => '[中文名称]名称不能超过100个字符',
'code.required' => '[中文名称]编码不能为空',
'code.unique' => '[中文名称]编码已存在',
'status.in' => '[中文名称]状态值无效',
'ids.required' => '请选择要删除的[中文名称]',
'ids.min' => '至少选择一条记录进行删除',
];
}
}
5. 路由文件模板
文件路径:routes/admin/[模块名]_route.php
<?php
use Illuminate\Support\Facades\Route;
/** -------------------------- [中文名称] ----------------------- */
Route::middleware("admin")->group(function () {
// 获取[中文名称]详情
Route::match(['get', 'post'], "[路由前缀]/detail", [App\Http\Controllers\Admin\[模块名]\[表名Controller]::class, 'detail']);
// 创建[中文名称]
Route::match(['get', 'post'], "[路由前缀]/create", [App\Http\Controllers\Admin\[模块名]\[表名Controller]::class, 'create']);
// 更新[中文名称]
Route::match(['put', 'post'], "[路由前缀]/update", [App\Http\Controllers\Admin\[模块名]\[表名Controller]::class, 'update']);
// 删除[中文名称]
Route::match(['delete', 'post'], "[路由前缀]/delete", [App\Http\Controllers\Admin\[模块名]\[表名Controller]::class, 'delete']);
// 获取[中文名称]列表
Route::match(['get', 'post'], "[路由前缀]/list", [App\Http\Controllers\Admin\[模块名]\[表名Controller]::class, 'list']);
// 获取简单列表
Route::match(['get', 'post'], "[路由前缀]/simple/list", [App\Http\Controllers\Admin\[模块名]\[表名Controller]::class, 'simpleList']);
// 批量删除[中文名称]
Route::match(['delete', 'post'], "[路由前缀]/batch/delete", [App\Http\Controllers\Admin\[模块名]\[表名Controller]::class, 'batchDelete']);
});
使用示例
假设我们要为school_class表生成 CRUD 代码:
替换变量说明
[模块名]→Schools[表名]→SchoolClass[表名变量]→schoolClass[数据库表名]→school_class[中文名称]→班级[路由前缀]→school/class
生成的文件结构
app/
├── Models/Schools/SchoolClass.php
├── Services/Schools/SchoolClassService.php
├── Http/
│ ├── Controllers/Admin/Schools/SchoolClassController.php
│ └── Requests/Admin/Schools/SchoolClassRequest.php
└── routes/admin/schools_route.php
控制器方法命名规范
list()- 获取列表(替代 index)detail()- 获取详情(替代 show)create()- 创建(替代 store)update()- 更新delete()- 删除(替代 destroy)batchDelete()- 批量删除simpleList()- 获取简单列表
验证规则命名规范
验证方法根据控制器方法名自动匹配:
listRules()- 列表查询验证detailRules()- 详情查询验证createRules()- 创建验证updateRules()- 更新验证deleteRules()- 删除验证batchDeleteRules()- 批量删除验证
核心优势
- 代码量减少 60%以上:通过 BaseModel、BaseService 提供通用功能
- 权限控制自动化:tenant_id 完全由框架层自动处理
- 异常处理统一化:控制器无需 try-catch,全局异常处理器统一处理
- 命名更加直观:使用功能性命名而非传统 RESTful 命名
- 开发效率极高:新模块只需实现特殊业务逻辑
- 维护成本降低:统一的代码结构和规范