# 12.6 后端编码规范 :::tip 概述 后端规范汇总:分层职责、命名、错误处理、事务纪律、注释风格。多数条目在前文有机制详解,本节为速查总表。 ::: ## 分层与依赖 ```text □ controller 薄层:只透传,无业务/无 dao/无手写响应 □ service 接口手维护:方法签名变更同步接口文件;禁 gf gen service 整体运行 □ logic 差异进 spec 声明与钩子;装不下就手写(逃生舱) □ dao.Ctx 唯一查询入口;自定义 dao 方法也必须 Ctx 起手 □ 依赖红线:task→logic 单向;middleware 经 wire 接线;migrate 不走 dao □ base.go 只依赖 dao/utility/consts;导出 ≤15 ``` ## 命名 ```text □ 文件:表名去 goframe_ 前缀 snake_case(config_item.go) □ 控制器:CXxx(CConfigItem);logic 实现:sXxx □ spec 变量:xxxSpec;字典映射:xxxSerializeMaps □ service:IXxx 接口 / Xxx() 取用 / RegisterXxx() 注册 □ 权限码:sys:{module小驼峰}:{action} □ 缓存键:easygoadmin: 前缀(consts/cache_key.go 统一) □ json:驼峰(登录/令牌四字段下划线例外) ``` ## 请求与响应 ```text □ 每接口一 Req/Res 结构体;内嵌 gmeta.Meta 全标签 □ 校验用 v 标签(required#文案);复杂校验在钩子 □ 分页 PageData;新增 {id};空结果 struct{} □ 出参字段 dc 注释 + 行注释(OpenAPI 文档质量) ``` ## 错误与日志 ```text □ gerror 上抛(NewCodef 语义码+消息);不吞 err □ 钩子错误记 stage 日志后原样上抛 □ fmt.Println 禁用——用 glog(带上下文) □ 敏感字段(password/salt/token)不进日志 □ panic 只在编程错误(mustAs 失败等);运行期错误返回 error ``` ## 事务与并发 ```text □ WithTrans 包裹多表写;错误自动回滚 □ 事务内禁 HTTP/文件 IO;bcrypt 事务外预计算 □ 共享 map 加锁;goroutine 有生命周期管理 □ 大数据量用 ChunkQuery 分批;循环内禁止查库(批查) ``` ## 注释风格 ```text □ 按当前功能直述(禁比较/来源痕迹/历史考古) □ 导出函数/类型有注释(godoc 风格,首句概括) □ 关键设计决策注释"为什么"(而非复述代码) □ 生成物注释保留工具标记(勿删头注释) ``` ## 静态门禁 ```sh go build ./... # 编译 go vet ./... # vet test -z "$(gofmt -l .)" # 格式(CI 同款) go test ./... # sqlite + hooks MySQL 集成测试 ``` ## 反例速查 ```text ❌ g.DB().Table("goframe_user").Where(...) 绕过 dao ❌ .Where("del_flag", 0) 手写 应由 Ctx 注入 ❌ WithTrans 内 bcrypt 拉长锁 ❌ for range ids { dao.Xxx.One } N+1 ❌ err 被 _ 丢弃 吞错误 ❌ 接口返回 map[string]any 拼装 应有结构体契约 ❌ 在钩子里 if module == "user" 基座禁止按模块分支 ```