goframe-v2

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 脚本或不相关的基础设施任务。

76Star
2Fork
更新于 2026/6/5
SKILL.md
readonly只读
name
goframe-v2
description

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/ 目录中实现业务逻辑。
  • 参考完整项目示例:

组件使用标准

  • 在创建新方法或变量之前,检查它们是否已存在于其他地方,并重用现有实现。
  • 使用 gerror 组件处理所有错误,以确保完整的堆栈跟踪,便于追溯。
  • 探索新组件时,优先使用 GoFrame 内置组件,并参考示例中的最佳实践代码。
  • 数据库操作必须使用 DO 对象internal/model/do/),绝不使用 g.Mapmap[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_atupdated_atdeleted_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 示例