签入版本

This commit is contained in:
2026-09-16 10:11:44 +08:00
parent bf08cf1248
commit 20d8a85989
205 changed files with 34363 additions and 0 deletions
@@ -0,0 +1,157 @@
# 请求处理器(Handler)
Handler 层是 HTTP 接口层,负责接收请求、校验权限、记录操作日志,然后委托给 Service 层处理。每个业务模块对应一个 `handlers.py` 文件,所有 Handler 继承 `BaseHandler`。
## 文件位置
```
src/modules/link/handlers.py
```
## 完整代码
```python
from common.middleware.access_decorators import check_demo, permission_required
from common.middleware.operation_log import operation_log
from core import response as R
from core.base_handler import BaseHandler
from modules.link.service import link_service
class LinkPageHandler(BaseHandler):
"""查询友链分页数据。"""
@permission_required("sys:link:list")
async def get(self):
return await link_service.get_page(self)
class LinkDetailHandler(BaseHandler):
"""查询友链详情。"""
@permission_required("sys:link:detail")
async def get(self, id):
return R.ok(self, data=link_service.get_detail(id))
class LinkAddHandler(BaseHandler):
"""添加友链。"""
@permission_required("sys:link:add")
@check_demo
@operation_log("友链管理", "添加")
async def post(self):
return await link_service.add(self)
class LinkUpdateHandler(BaseHandler):
"""更新友链。"""
@permission_required("sys:link:update")
@check_demo
@operation_log("友链管理", "更新")
async def put(self):
return await link_service.update(self)
class LinkDeleteHandler(BaseHandler):
"""删除友链。"""
@permission_required("sys:link:delete")
@check_demo
@operation_log("友链管理", "删除")
async def delete(self, id):
return await link_service.delete(self, id)
class LinkStatusHandler(BaseHandler):
"""设置友链状态。"""
@permission_required("sys:link:status")
@check_demo
@operation_log("友链管理", "设置状态")
async def put(self):
return await link_service.update_status(self)
class LinkBatchDeleteHandler(BaseHandler):
"""批量删除友链。"""
@permission_required("sys:link:delete")
@check_demo
@operation_log("友链管理", "批量删除")
async def post(self):
return await link_service.batch_delete(self)
```
## 代码解析
### Handler 类
```python
class LinkPageHandler(BaseHandler):
```
每个 Handler 继承 `BaseHandler`(即 `tornado.web.RequestHandler`),负责一个 HTTP 端点。与 Tornado 的 Endpoint 函数不同,Tornado 使用类来组织处理器。
### 装饰器说明
| 装饰器 | 作用 | 位置 |
|:----|:----|:----|
| `@permission_required("sys:link:list")` | RBAC 权限校验 | 类方法上 |
| `@check_demo` | 演示模式拦截(仅写操作) | 权限装饰器之后 |
| `@operation_log("模块", "动作")` | 操作日志记录 | 最内层 |
**装饰器顺序必须严格遵守**:权限 → 演示模式 → 操作日志。
### 路径参数
```python
async def get(self, id):
```
Tornado 的路径参数通过正则捕获组传入方法参数。路由定义 `(r"/link/detail/(\d+)", LinkDetailHandler)` 中的 `(\d+)` 对应 `id` 参数。
### 响应封装
- **Service 返回 R 对象的**(如 `add`、`update`、`delete`):直接 `return`
- **Service 返回原始数据的**(如 `get_detail`):用 `R.ok(self, data=...)` 包装
### HTTP 方法映射
| 操作 | HTTP 方法 | Handler 方法 |
|:----|:----|:----|
| 分页查询 | GET | `async def get(self)` |
| 详情查询 | GET | `async def get(self, id)` |
| 新增 | POST | `async def post(self)` |
| 更新 | PUT | `async def put(self)` |
| 删除 | DELETE | `async def delete(self, id)` |
| 状态变更 | PUT | `async def put(self)` |
| 批量删除 | POST | `async def post(self)` |
### 权限字符串命名规范
```
sys:{module}:{action}
```
| 动作 | HTTP 方法 | 说明 |
|:----|:----|:----|
| `list` | GET | 分页/列表查询 |
| `detail` | GET | 详情查询 |
| `add` | POST | 新增 |
| `update` | PUT | 更新 |
| `delete` | DELETE | 单条/批量删除 |
| `status` | PUT | 状态变更 |
## 开发要点
1. **Handler 层不含业务逻辑**:仅做权限校验、日志记录和请求分发
2. **装饰器顺序**:权限 → 演示模式 → 操作日志
3. **写操作必须加 `@check_demo`**:防止演示环境被修改
4. **写操作建议加 `@operation_log`**:记录操作日志用于审计
5. **所有方法都是 `async def`**:Tornado Handler 方法默认异步
## 总结
Handler 层是 HTTP 请求的入口,负责权限校验、操作日志记录和请求分发,不含业务逻辑。装饰器顺序固定为权限 → 演示模式 → 操作日志,写操作必须加 `@check_demo`,所有逻辑委托 Service 处理。