签入版本
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# 5.18 gmeta 注解系统总览
|
||||
|
||||
:::tip 概述
|
||||
gmeta 注解是本项目的"声明即事实"机制:请求结构体上的一个 gmeta.Meta 标签同时驱动路由注册、权限校验、操作日志、OpenAPI 文档四件事。解析与分发在 internal/router/bind.go(反射绑定)与 meta/(路由元数据表)。
|
||||
:::
|
||||
|
||||
## 一个标签,四份事实
|
||||
|
||||
```go
|
||||
type UserPageReq struct {
|
||||
gmeta.Meta `method:"get" path:"/api/user/page" summary:"用户分页"
|
||||
permission:"sys:user:page" log:"用户管理-查询分页记录" logType:"query"`
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
解析后同时产出:
|
||||
① 路由注册 GET /api/user/page → CUser.Page
|
||||
② 权限校验 HasPerm("sys:user:page")(包装层每请求判定)
|
||||
③ 操作日志 标题"用户管理-查询分页记录"、类型 query
|
||||
④ OpenAPI 文档 /api.json 的 path/summary/参数说明
|
||||
```
|
||||
|
||||
不存在"代码改了忘改路由表/权限表/文档"——标签是唯一真相。
|
||||
|
||||
## 标签字段语义
|
||||
|
||||
| 标签 | 语义 |
|
||||
|------|------|
|
||||
| `method` | HTTP 方法(get/post/put/delete) |
|
||||
| `path` | 完整路由模板(含 /api 前缀;`:id` 为路由参数,req 同名字段承接) |
|
||||
| `summary` | OpenAPI 摘要 |
|
||||
| `permission` | 权限节点 `sys:{module小驼峰}:{action}`;空 = 登录即可 |
|
||||
| `log` | 操作日志标题 `"{模块中文名}-{动作}"`;空 = 不记录 |
|
||||
| `logType` | 日志类型字符串(query/add/update/delete/import/export/reset/…),经 LogTypeMap 转 41 个枚举值 |
|
||||
| `public` | `"true"` = 免登录(仍需与 middleware/public.go 白名单一致) |
|
||||
|
||||
## Bind 绑定流程(internal/router/bind.go)
|
||||
|
||||
```text
|
||||
Bind(s, new(controller.CXxx)) 扫描控制器全部导出方法:
|
||||
1) 校验签名:func (c *Xxx) Page(ctx, req *v1.XxxReq) (*v1.XxxRes, error)
|
||||
(签名不符静默跳过——排障注意)
|
||||
2) 解析请求结构体内嵌 gmeta.Meta 扩展标签
|
||||
3) 按 method:path 注册路由 + meta.Register(rm) 写入路由元数据表
|
||||
(键 "METHOD /path",读写锁保护;Lookup 供调试,All 供文档生成)
|
||||
4) 补注册进 gf goai(闭包路由 gf 不会自动收集)→ /api.json 原生 OpenAPI
|
||||
5) 生成统一包装 handler:
|
||||
路由元数据写入 ctx(操作日志中间件读取)
|
||||
→ 权限校验(403 短路;不设独立 Permission 中间件)
|
||||
→ r.Parse(req)(路由参数+query+body,含 gvalid 校验)
|
||||
→ 调用业务方法 → response.Ok/Fail 信封写出
|
||||
```
|
||||
|
||||
## BodyUnmarshaler 逃生舱
|
||||
|
||||
```text
|
||||
当请求体顶层形态无法用结构体标签表达(如平铺 map)时,
|
||||
Req 实现 UnmarshalBody(r *ghttp.Request) error 接口:
|
||||
→ 跳过默认 Parse,实现内自行完成解析与 gvalid 校验
|
||||
```
|
||||
|
||||
## 注册验证
|
||||
|
||||
```sh
|
||||
# OpenAPI 检查(gmeta 补注册后全量可用)
|
||||
curl http://127.0.0.1:8000/api.json | grep "user/page"
|
||||
|
||||
# 启动路由表
|
||||
# config.yaml: server.dumpRouterMap: true
|
||||
```
|
||||
|
||||
## 开发规约
|
||||
|
||||
```text
|
||||
* 每个接口必须有 gmeta——没有标签的方法不会注册路由
|
||||
* permission 新码必须同步菜单节点 + 角色勾选(否则 403)
|
||||
* public:"true" 必须同时出现在 middleware/public.go 白名单(三处一致)
|
||||
* log 空 = 不记录(有意不记录才留空);logType 缺省按 HTTP 方法自动推断(0)
|
||||
* path 一律 /api 开头、无 /v1 版本段
|
||||
* 改 path/permission 等标签后重启生效(路由与元数据表启动期构建)
|
||||
```
|
||||
Reference in New Issue
Block a user