305 lines
8.6 KiB
Markdown
305 lines
8.6 KiB
Markdown
# 3.6 控制器开发
|
|
|
|
:::tip 概述
|
|
控制器是 HTTP 请求的入口,负责参数获取、调用 Logic 层、返回 JSON 响应。通过 `#[Permission]` 和 `#[Log]` 注解实现权限校验和操作日志。
|
|
:::
|
|
|
|
## 控制器文件位置
|
|
|
|
```text
|
|
app/controller/ExampleController.php
|
|
```
|
|
|
|
## 完整代码(来自项目实际代码)
|
|
|
|
```php
|
|
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace app\controller;
|
|
|
|
use app\BaseController; // 控制器基类
|
|
use app\logic\ExampleLogic; // 案例演示业务逻辑
|
|
use app\attribute\Log; // 操作日志注解
|
|
use app\attribute\Permission; // 权限校验注解
|
|
use think\response\Json; // JSON 响应类型
|
|
|
|
/**
|
|
* 案例演示管理控制器
|
|
*
|
|
* 负责案例演示相关的 HTTP 接口入口,包括:
|
|
* - 分页列表、列表查询、详情查询;
|
|
* - 新增、修改、删除、批量删除;
|
|
* - 导入、导出。
|
|
*
|
|
* 具体业务逻辑委托给 ExampleLogic 处理,
|
|
* 并通过注解统一实现日志记录与权限校验。
|
|
*/
|
|
class ExampleController extends BaseController
|
|
{
|
|
/**
|
|
* 案例演示业务逻辑层
|
|
*
|
|
* @var ExampleLogic
|
|
*/
|
|
protected ExampleLogic $logic;
|
|
|
|
/**
|
|
* 控制器初始化
|
|
*
|
|
* 在每次请求进入控制器方法前执行,用于实例化业务逻辑层。
|
|
* ThinkPHP 会自动调用此方法(在构造函数之后)。
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function initialize(): void
|
|
{
|
|
$this->logic = new ExampleLogic();
|
|
}
|
|
|
|
// ... 以下为各接口方法
|
|
}
|
|
```
|
|
|
|
:::tip 控制器模式
|
|
每个控制器遵循固定模式:
|
|
1. `initialize()` 中实例化 Logic
|
|
2. 每个方法标注 `#[Log]` 和 `#[Permission]` 注解
|
|
3. 简单调用 `parent::_index()` / `_detail()` / `_add()` 等通用方法
|
|
4. 复杂操作(如导入导出)自行处理并 try-catch
|
|
:::
|
|
|
|
```php
|
|
/**
|
|
* 案例演示分页列表
|
|
*
|
|
* GET /example/page
|
|
* 对应权限:sys:example:page
|
|
*
|
|
* 调用 BaseController::_index(),内部流程:
|
|
* 1. 合并分页参数(pageNo/pageSize)和普通参数
|
|
* 2. 调用 ExampleLogic::pageList()
|
|
* 3. 返回标准分页响应
|
|
*
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-查询分页记录', Log::TYPE_QUERY)]
|
|
#[Permission('sys:example:page', '案例演示分页')]
|
|
public function page(): Json
|
|
{
|
|
return parent::_index($this->logic);
|
|
}
|
|
|
|
/**
|
|
* 案例演示列表
|
|
*
|
|
* GET /example/list
|
|
* 返回全量数据(不分页),适用于下拉选择等场景。
|
|
*
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-查询列表', Log::TYPE_QUERY)]
|
|
public function list(): Json
|
|
{
|
|
return parent::_list($this->logic);
|
|
}
|
|
|
|
/**
|
|
* 案例演示详情
|
|
*
|
|
* GET /example/detail/{id}
|
|
*
|
|
* 调用 BaseController::_detail(),内部流程:
|
|
* 1. 调用 ExampleLogic::detail($id)
|
|
* 2. 查询为空返回 404
|
|
* 3. 自动补全文件字段域名、枚举显示名
|
|
* 4. 触发 afterDetail 钩子
|
|
*
|
|
* @param int $id 案例演示ID
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-查询详情', Log::TYPE_QUERY, '查询案例演示ID:{id}')]
|
|
public function detail(int $id): Json
|
|
{
|
|
return parent::_detail($this->logic, $id);
|
|
}
|
|
|
|
/**
|
|
* 添加案例演示
|
|
*
|
|
* POST /example/add
|
|
* 对应权限:sys:example:add
|
|
*
|
|
* 调用 BaseController::_add(),内部流程:
|
|
* 1. 调用 ExampleLogic::add($data)
|
|
* 2. 触发 beforeAdd/afterAdd 钩子
|
|
* 3. 返回新记录 ID
|
|
*
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-新增记录', Log::TYPE_ADD, '新增案例演示:{name}')]
|
|
#[Permission('sys:example:add', '添加案例演示')]
|
|
public function add(): Json
|
|
{
|
|
// getJsonBody() 获取前端 POST 提交的 JSON 数据
|
|
return parent::_add($this->logic, $this->getJsonBody());
|
|
}
|
|
|
|
/**
|
|
* 更新案例演示
|
|
*
|
|
* PUT /example/update
|
|
* 对应权限:sys:example:update
|
|
*
|
|
* 从 JSON 请求体中读取 id,若缺失则直接返回失败。
|
|
*
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-修改记录', Log::TYPE_UPDATE, '修改案例演示ID:{id}')]
|
|
#[Permission('sys:example:update', '修改案例演示')]
|
|
public function update(): Json
|
|
{
|
|
$data = $this->getJsonBody();
|
|
$id = $data['id'] ?? 0;
|
|
|
|
// 校验 ID 参数
|
|
if (empty($id)) {
|
|
return $this->fail('缺少id参数');
|
|
}
|
|
|
|
return parent::_edit($this->logic, $id, $data);
|
|
}
|
|
|
|
/**
|
|
* 删除案例演示
|
|
*
|
|
* DELETE /example/delete/{id}
|
|
* 对应权限:sys:example:delete
|
|
*
|
|
* 调用 BaseController::_remove(),内部流程:
|
|
* 1. 调用 ExampleLogic::delete($id)
|
|
* 2. 触发 beforeDelete/afterDelete 钩子
|
|
* 3. 设置 is_delete=1(软删除)
|
|
*
|
|
* @param int $id 案例演示ID
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-删除记录', Log::TYPE_DELETE, '删除案例演示ID:{id}')]
|
|
#[Permission('sys:example:delete', '删除案例演示')]
|
|
public function delete(int $id): Json
|
|
{
|
|
return parent::_remove($this->logic, $id);
|
|
}
|
|
|
|
/**
|
|
* 批量删除案例演示
|
|
*
|
|
* DELETE /example/batchDelete
|
|
* 对应权限:sys:example:delete
|
|
*
|
|
* 从 JSON 请求体中读取 ids 数组。
|
|
*
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-批量删除记录', Log::TYPE_DELETE)]
|
|
#[Permission('sys:example:delete', '删除案例演示')]
|
|
public function batchDelete(): Json
|
|
{
|
|
$ids = $this->getJsonBody()['ids'] ?? [];
|
|
return parent::_batchRemove($this->logic, $ids);
|
|
}
|
|
|
|
/**
|
|
* 导入案例演示
|
|
*
|
|
* POST /example/import
|
|
* 对应权限:sys:example:import
|
|
*
|
|
* 处理流程:
|
|
* 1. 从请求中获取上传文件
|
|
* 2. 校验文件扩展名(仅 xls、xlsx)
|
|
* 3. 调用 ExampleLogic::import() 解析并导入
|
|
*
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-导入数据', Log::TYPE_IMPORT)]
|
|
#[Permission('sys:example:import', '导入案例演示')]
|
|
public function import(): Json
|
|
{
|
|
$file = $this->request->file('file');
|
|
if (!$file) {
|
|
return $this->fail('请选择文件');
|
|
}
|
|
|
|
$ext = strtolower($file->getOriginalExtension());
|
|
if (!in_array($ext, ['xls', 'xlsx'])) {
|
|
return $this->fail('仅支持 xls、xlsx 格式的文件');
|
|
}
|
|
|
|
try {
|
|
$result = $this->logic->import($file->getRealPath());
|
|
|
|
$msg = empty($result['errors'])
|
|
? "成功导入 {$result['count']} 条数据"
|
|
: "成功导入 {$result['count']} 条,失败 " . count($result['errors']) . " 条";
|
|
|
|
return $this->success($result, $msg);
|
|
} catch (\Exception $e) {
|
|
return $this->fail('导入失败: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 导出案例演示
|
|
*
|
|
* GET /example/export
|
|
* 对应权限:sys:example:export
|
|
*
|
|
* @return Json
|
|
*/
|
|
#[Log('案例演示-导出数据', Log::TYPE_EXPORT)]
|
|
#[Permission('sys:example:export', '导出案例演示')]
|
|
public function export(): Json
|
|
{
|
|
try {
|
|
$filePath = $this->logic->export($this->getParams());
|
|
return $this->success($filePath, '导出成功');
|
|
} catch (\Exception $e) {
|
|
return $this->fail('导出失败: ' . $e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 注解说明
|
|
|
|
### #[Log] 操作日志注解
|
|
|
|
```php
|
|
#[Log('案例演示-新增记录', Log::TYPE_ADD, '新增案例演示:{name}')]
|
|
// │ │ │
|
|
// │ │ └── 描述(支持 {param} 占位符)
|
|
// │ └── 操作类型
|
|
// └── 操作标题
|
|
```
|
|
|
|
### #[Permission] 权限注解
|
|
|
|
```php
|
|
#[Permission('sys:example:add', '添加案例演示')]
|
|
// │ │
|
|
// │ └── 权限名称
|
|
// └── 权限编码
|
|
```
|
|
|
|
## BaseController 通用方法
|
|
|
|
| 方法 | 用途 | 内部调用 |
|
|
|------|------|----------|
|
|
| `_index($logic)` | 分页查询 | `$logic->pageList()` |
|
|
| `_list($logic)` | 全量列表 | `$logic->allList()` |
|
|
| `_detail($logic, $id)` | 详情查询 | `$logic->detail($id)` |
|
|
| `_add($logic, $data)` | 新增 | `$logic->add($data)` |
|
|
| `_edit($logic, $id, $data)` | 修改 | `$logic->update($id, $data)` |
|
|
| `_remove($logic, $id)` | 删除 | `$logic->delete($id)` |
|
|
| `_batchRemove($logic, $ids)` | 批量删除 | `$logic->batchDelete($ids)` | |