
goframe-v2
GoFrame v2 开发技能。仅当目标 Go 项目使用或明确采用 GoFrame v2 时使用:最近的 go.mod 要求 github.com/gogf/gf/v2,现有 Go 文件导入 github.com/gogf/gf/v2 或任何 github.com/gogf/gf/v2/... 组件包,或者用户要求使用 GoFrame 搭建、迁移或构建。触发于基于 GoFrame 的 Go 工作,例如 API/控制器/服务、中间件、路由/配置、ORM/DAO/DO/实体/数据库操作、gf CLI/代码生成、HTTP/gRPC 服务以及微服务约定。不要触发于没有 GoFrame 证据的通用 Go 项目、纯前端工作、shell 脚本或不相关的基础设施任务。
GoFrame v2 开发技能。仅当目标 Go 项目使用或明确采用 GoFrame v2 时使用:最近的 go.mod 要求 github.com/gogf/gf/v2,现有 Go 文件导入 github.com/gogf/gf/v2 或任何 github.com/gogf/gf/v2/... 组件包,或者用户要求使用 GoFrame 搭建、迁移或构建。触发于基于 GoFrame 的 Go 工作,例如 API/控制器/服务、中间件、路由/配置、ORM/DAO/DO/实体/数据库操作、gf CLI/代码生成、HTTP/gRPC 服务以及微服务约定。不要触发于没有 GoFrame 证据的通用 Go 项目、纯前端工作、shell 脚本或不相关的基础设施任务。
关键约定
项目开发标准
- 对于完整项目(HTTP/微服务),安装 GoFrame CLI 并使用
gf init创建项目脚手架。详见项目创建 - init。 - 自动生成的代码文件(dao、do、entity)不得手动创建或修改,遵循 GoFrame 约定。
- 除非明确要求,否则不要使用
logic/目录存放业务逻辑。直接在service/目录中实现业务逻辑。 - 参考完整项目示例:
- HTTP 服务最佳实践:user-http-service
- gRPC 服务最佳实践:user-grpc-service
组件使用标准
- 在创建新方法或变量之前,检查它们是否已存在于其他地方,并重用现有实现。
- 使用
gerror组件处理所有错误,以确保完整的堆栈跟踪,便于追溯。 - 探索新组件时,优先使用 GoFrame 内置组件,并参考示例中的最佳实践代码。
- 数据库操作必须使用 DO 对象(
internal/model/do/),绝不使用g.Map或map[string]interface{}。DO 结构体字段类型为interface{};未设置的字段保持nil,ORM 会自动忽略:// 正确 - 使用 DO 对象 dao.Users.Ctx(ctx).Where(cols.Id, id).Data(do.User{Uid: uid}).Update() // 正确 - 条件字段,未设置的字段为 nil 并被忽略 data := do.User{} if password != "" { data.PasswordHash = hash } if isAdmin != nil { data.IsAdmin = *isAdmin } dao.Users.Ctx(ctx).Where(cols.Id, id).Data(data).Update() // 正确 - 使用 gdb.Raw 显式将列设置为 NULL dao.Instances.Ctx(ctx).Where(cols.Id, id).Data(do.Instance{IdleSince: gdb.Raw("NULL")}).Update() // 错误 - 绝不使用 g.Map 进行数据库操作 dao.Users.Ctx(ctx).Data(g.Map{cols.Uid: uid}).Update()
代码风格标准
- 变量声明:定义多个变量时,使用
var块进行分组,以获得更好的对齐和可读性:// 正确 - 对齐且整洁 var ( authSvc *auth.Service bizCtxSvc *bizctx.Service k8sSvc *svcK8s.Service notebookSvc *notebook.Service middlewareSvc *middleware.Service ) // 避免 - 分散的声明 authSvc := auth.New() bizCtxSvc := bizctx.New() k8sSvc := svcK8s.New() - 当同一作用域中有 3 个或更多相关变量声明时,应用此模式。
软删除与时间维护
GoFrame 提供自动软删除和时间维护功能。当表包含 created_at、updated_at 或 deleted_at 字段时,ORM 会自动处理这些字段。
自动时间字段
| 字段 | 自动行为 |
|---|---|
created_at |
在 Insert/InsertAndGetId 时自动写入,之后不再修改 |
updated_at |
在 Insert/Update/Save 时自动写入 |
deleted_at |
在 Delete 时自动写入(软删除),查询时自动过滤 |
关键规则
1. 绝不手动设置时间字段 - GoFrame 自动处理:
// 错误 - 冗余的手动时间设置
dao.User.Ctx(ctx).Data(do.User{
Name: "john",
CreatedAt: gtime.Now(), // 冗余!框架会处理
UpdatedAt: gtime.Now(), // 冗余!框架会处理
}).Insert()
// 正确 - 让框架处理时间字段
dao.User.Ctx(ctx).Data(do.User{
Name: "john",
}).Insert()
2. 绝不手动添加 WhereNull(cols.DeletedAt) - GoFrame 自动添加软删除过滤:
// 错误 - 冗余的软删除条件
dao.User.Ctx(ctx).
Where(do.User{Status: 1}).
WhereNull(cols.DeletedAt). // 冗余!框架会自动添加
Scan(&list)
// 正确 - 框架自动添加 deleted_at IS NULL
dao.User.Ctx(ctx).
Where(do.User{Status: 1}).
Scan(&list)
3. 使用 Delete() 进行软删除 - 框架转换为 UPDATE SET deleted_at = NOW():
// 正确 - 使用 Delete(),框架处理软删除
dao.User.Ctx(ctx).Where(do.User{Id: id}).Delete()
// 实际 SQL: UPDATE `sys_user` SET `deleted_at`=NOW() WHERE `id`=?
// 错误 - 手动 Update 设置 deleted_at
dao.User.Ctx(ctx).
Where(do.User{Id: id}).
Data(do.User{DeletedAt: gtime.Now()}). // 冗余!
Update()
字段类型支持
deleted_at 字段支持多种类型:
- DateTime/Timestamp:默认,存储删除时间
- Integer:存储 Unix 时间戳(秒)
- Boolean:存储 0/1 表示删除状态
配置(可选)
时间字段名称可在 config.yaml 中自定义:
database:
default:
createdAt: "created_at" # 自定义字段名
updatedAt: "updated_at"
deletedAt: "deleted_at"
timeMaintainDisabled: false # 设置为 true 禁用此功能
GoFrame 文档
完整的 GoFrame 开发资源,涵盖组件设计、使用、最佳实践和注意事项:GoFrame 文档
GoFrame 代码示例
丰富的实用代码示例,涵盖 HTTP 服务、gRPC 服务和各种项目类型:GoFrame 示例





