## 路由生成（gen route）

通过在控制器方法上编写注释，解析器从 Go AST 中读取注释、方法签名与参数列表，自动生成路由注册与参数绑定代码。

- 核心标签：`@Router` 定义路径与方法；`@Bind` 定义方法参数的来源与键名。
- 生成行为：输出 `router.<METHOD>(path, FuncN(...))` 或 `DataFuncN(...)` 包装调用，并自动汇聚所需 imports 与控制器注入字段。

### 快速开始

```
atomctl gen route [path]
```

- 生成文件：当前包目录下 `routes.gen.go`
- 分组与排序：按控制器分组，导入、方法、路由项稳定排序，便于审阅 diff。

### 注释语法

- `@Router <path> [<method>]`
  - 示例：`@Router /users/:id [get]`

- `@Bind <paramName> <position> [key(<key>)] [model(<field>|<model>[:<field>])]`
  - `paramName` 与方法参数名一致（大小写敏感）
  - `position`：`path`、`query`、`body`、`header`、`cookie`、`local`、`file`
  - 可选：
    - `key()` 覆盖默认键名；
    - `model()` 详见“模型绑定”。

### 参数绑定规则（按 position）

- query：标量用 `QueryParam[T]("key")`，非标量用 `Query[T]("key")`
- path：标量用 `PathParam[T]("key")`，非标量用 `Path[T]("key")`
  - 若使用 `model()`（仅在 path 有效），会按字段值查询并绑定为 `T`，详见下文
- header：`Header[T]("key")`
- body：`Body[T]("key")`
- cookie：`string` 用 `CookieParam("key")`，其他用 `Cookie[T]("key")`
- file：`File[multipart.FileHeader]("key")`
- local：`Local[T]("key")`

说明：

- 标量类型集合：`string`、`int`、`int32`、`int64`、`float32`、`float64`、`bool`
- `key` 默认等于 `paramName`；设置 `key(...)` 后以其为准
- `file` 使用固定类型 `multipart.FileHeader`

### 类型与指针处理

- 支持 `T`、`*T`、`pkg.T`、`*pkg.T`；会正确收集选择子表达式对应 import
- 忽略结尾为 `Context` 或 `Ctx` 的参数（框架上下文）
- 指针处理：除 `local` 外会去掉前导 `*` 作为泛型实参；`local` 保留指针（便于写回）

### 解析与匹配

- 先收集注释中的多条 `@Bind`，再按“方法参数列表顺序”匹配并输出绑定器，确保调用顺序与方法签名一致
- 未在方法参数中的 `@Bind` 会被忽略；缺失 `@Router` 或方法无注释将跳过该方法
- import 自动收集去重；控制器注入字段名为类型名的小驼峰形式，例如 `userController *UserController`

### 返回值与包装函数

- 返回值个数 > 1：使用 `DataFuncN`
- 否则使用 `FuncN`
- `N` 为参与绑定的参数个数

### 模型绑定（path + model）

当 `@Bind ... model(...)` 配合 `position=path` 使用时，将根据路径参数值查询模型并绑定为方法参数类型的实例（`T` 来自方法参数）。

- 语法：
  - 仅字段：`model(id)`（推荐）
  - 指定字段与类型：`model(id:int)`、`model(code:string)`（用于非字符串路径参数）
  - 指定类型与字段：`model(pkg.Type:field)` 或 `model(pkg.Type)`（字段缺省为 `id`）
- 行为：
  - 生成的绑定器会按给定字段构造查询条件并返回首条记录
  - 自动注入 import：`field "go.ipao.vip/gen/field"`，用于构造字段条件表达式

示例：

```go
// @Router /users/:id [get]
// @Bind user path key(id) model(id)
func (uc *UserController) Show(ctx context.Context, user *models.User) (*UserDTO, error)
```

### 完整示例

注释与方法签名：

```go
// @Router /users/:id [get]
// @Bind user path key(id) model(id)
// @Bind fields query
// @Bind token header key(Authorization)
// @Bind sess cookie key(session_id)
// @Bind cfg local
func (uc *UserController) GetUser(ctx context.Context, user *models.User, fields []string, token string, sess string, cfg *AppConfig) (*User, error)
```

生成的路由注册（示意）：

```go
router.Get("/users/:id", DataFunc4(
    r.userController.GetUser,
    PathModel[models.User]("id", "id"),
    Query[[]string]("fields"),
    Header[string]("Authorization"),
    CookieParam("session_id"),
))
```

### 错误与限制

- 无效的 `@Router` 语法会报错；无效的 `position` 会在解析阶段触发错误
- `file` 仅支持单文件头；`model()` 仅在 `position=path` 时参与代码生成
- 请确保路由段变量名与 `key(...)` 保持一致
