签入版本

This commit is contained in:
小蚂蚁云
2026-10-25 17:24:27 +08:00
parent 48911cc08f
commit fdbeae092a
1010 changed files with 30682 additions and 95274 deletions
+73 -77
View File
@@ -1,92 +1,88 @@
# 3.7 路由注册
# 3.7 路由与元数据注册(RouteSpec)
:::tip 概述
路由定义在 `route/app.php` 中,按模块分组注册。所有需认证的接口统一绑定四个中间件。
本项目的路由**只有一处声明**:`router.go` 内每个控制器的 RouteSpec 表。注册、权限校验、操作日志、公开白名单、OpenAPI 文档全部从这一份声明派生,天然同步。
:::
## 路由文件位置
## RouteSpec 字段
```go
// internal/router/bind.go
type RouteSpec struct {
Method string // HTTP 方法:GET/POST/PUT/DELETE(必填,否则不注册)
Path string // 路由模板,如 /api/link/detail/:id(必填)
Summary string // 接口摘要(OpenAPI)
Permission string // 权限节点 sys:link:page;空表示登录即可
Log string // 操作日志标题;空表示不记录
LogType string // 日志类型:query/add/update/delete/import/export/reset…
Public bool // 免登录(登录、验证码等)
}
```
## 注册写法
在 `internal/router/router.go` 的 `registerControllers` 内,为控制器集中声明(方法名 → 路由元数据,按字典序排列):
```go
// internal/router/router.go
Bind(rg, new(handler.CExample), map[string]RouteSpec{
"Add": {Method: "POST", Path: "/api/example/add", Summary: "新增案例演示", Permission: "sys:example:add", Log: "案例演示-新增记录", LogType: "add"},
"BatchDelete": {Method: "DELETE", Path: "/api/example/batchDelete", Summary: "批量删除案例演示", Permission: "sys:example:batchDelete", Log: "案例演示-批量删除记录", LogType: "delete"},
"Delete": {Method: "DELETE", Path: "/api/example/delete/:id", Summary: "删除案例演示", Permission: "sys:example:delete", Log: "案例演示-删除记录", LogType: "delete"},
"Detail": {Method: "GET", Path: "/api/example/detail/:id", Summary: "案例演示详情", Permission: "sys:example:detail", Log: "案例演示-查询详情", LogType: "query"},
"Export": {Method: "GET", Path: "/api/example/export", Summary: "导出案例演示", Permission: "sys:example:export", Log: "案例演示-导出数据", LogType: "export"},
"Import": {Method: "POST", Path: "/api/example/import", Summary: "导入案例演示", Permission: "sys:example:import", Log: "案例演示-导入数据", LogType: "import"},
"List": {Method: "GET", Path: "/api/example/list", Summary: "案例演示列表", Permission: "sys:example:list", Log: "案例演示-查询列表", LogType: "query"},
"Page": {Method: "GET", Path: "/api/example/page", Summary: "案例演示分页", Permission: "sys:example:page", Log: "案例演示-查询分页记录", LogType: "query"},
"Status": {Method: "PUT", Path: "/api/example/status", Summary: "案例演示状态", Permission: "sys:example:status", Log: "案例演示-设置状态", LogType: "update"},
"Update": {Method: "PUT", Path: "/api/example/update", Summary: "修改案例演示", Permission: "sys:example:update", Log: "案例演示-修改记录", LogType: "update"},
})
```
## 注册后发生什么
`router.Bind` 反射扫描控制器:
```text
route/app.php
按签名筛选方法(ctx, *dto.Req)→(*dto.Res, error)
│
▼
按方法名查 RouteSpec 表 → rg.Handle(Method, Path, 包装函数)
│
▼
包装函数内:绑定解析(path > body > query)→ binding 校验 → 调 handler → 信封响应
│
▼
写入路由元数据表(方法名、路径、权限码、日志配置、公开标记)
│
▼
authz / operation_log / public / OpenAPI 从元数据表消费同一份声明
```
## Example 模块路由(来自项目实际代码)
## 声明规约
```php
// route/app.php 第 370~383 行
| 项 | 规约 |
|---|---|
| 路径 | `/api/{模块}/{动作}`,路径参数用 `:id` |
| 方法映射 | 查询 GET / 新增 POST / 修改 PUT / 删除 DELETE |
| 权限码 | `sys:{模块}:{动作}`,动作与路径动词一致 |
| Permission 为空 | 登录即可访问(不校验权限点) |
| Log 为空 | 不记录操作日志;查询类是否记录还受 `operationLog.logQuery` 开关控制 |
| Public | 仅登录、验证码、令牌兑换等真正公开接口使用 |
| 顺序 | 表内按方法名字典序排列,与既有条目风格逐字一致 |
// ----------------------------------------------------------
// 自动生成 - example
// ----------------------------------------------------------
Route::group('example', function () {
Route::get('page', 'ExampleController/page'); // 分页列表
Route::get('list', 'ExampleController/list'); // 全量列表
Route::get('detail/:id', 'ExampleController/detail'); // 详情(:id 为路径参数)
Route::post('add', 'ExampleController/add'); // 新增
Route::put('update', 'ExampleController/update'); // 修改
Route::delete('delete/:id', 'ExampleController/delete'); // 删除
Route::delete('batchDelete', 'ExampleController/batchDelete'); // 批量删除
Route::post('import', 'ExampleController/import'); // 导入
Route::get('export', 'ExampleController/export'); // 导出
});
```
## 新增接口的完整动作
## 路由格式说明
1. dto 加请求/响应结构
2. service 加方法
3. handler 加同签名方法
4. RouteSpec 表加一条声明
5. 需要权限点时在菜单管理中配置权限节点(见下一页)
```php
Route::HTTP方法('路径', '控制器/方法');
```
## 底层机制深入
| HTTP 方法 | 用途 | 路径格式 | 示例 |
|-----------|------|----------|------|
| GET | 查询 | `/module/page`、`/module/detail/:id` | `GET /api/example/page` |
| POST | 新增/导入 | `/module/add`、`/module/import` | `POST /api/example/add` |
| PUT | 修改 | `/module/update` | `PUT /api/example/update` |
| DELETE | 删除 | `/module/delete/:id`、`/module/batchDelete` | `DELETE /api/example/delete/1` |
反射细节、元数据表结构、中间件如何消费元数据 → [4.4 反射元数据驱动机制](/zh/architecture/bind-mechanism.html)。
## 标准路由模板
## 下一步
每个业务模块通常包含以下路由:
```php
Route::group('模块名', function () {
Route::get('page', 'XxxController/page'); // 分页列表
Route::get('list', 'XxxController/list'); // 全量列表(可选)
Route::get('detail/:id', 'XxxController/detail'); // 详情
Route::post('add', 'XxxController/add'); // 新增
Route::put('update', 'XxxController/update'); // 修改
Route::delete('delete/:id', 'XxxController/delete'); // 删除
Route::delete('batchDelete', 'XxxController/batchDelete'); // 批量删除
Route::post('import', 'XxxController/import'); // 导入(可选)
Route::get('export', 'XxxController/export'); // 导出(可选)
});
```
:::tip 路由命名规范
- 路径使用小写英文(如 `example`、`user`)
- 详情/删除使用 `:id` 参数(如 `detail/:id`)
- 批量删除使用 `batchDelete` 路径
:::
## 中间件绑定
所有需认证的接口在 `route/app.php` 末尾统一绑定中间件:
```php
})->middleware([
\app\middleware\AuthMiddleware::class, // JWT认证 + 权限校验
\app\middleware\TenantMiddleware::class, // 租户上下文注入
\app\middleware\DemoMiddleware::class, // 演示环境拦截
\app\middleware\LogMiddleware::class, // 操作日志记录
]);
```
## 验证路由注册
```bash
# 查看所有已注册路由
php think route:list
# 测试路由是否正确
curl http://localhost:8000/api/example/page -H "Authorization: Bearer <token>"
```
→ [3.8 参数校验与错误上抛](/zh/guide/validation.html)