Skip to content

构建器方法

VEF Framework 的 API 构建器提供了丰富的方法来配置 API 行为。

通用构建器方法

所有预置 API 都支持以下通用方法:

WithPermission

设置 API 所需的权限令牌:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithPermission("user:read")

WithDataScope

设置数据权限范围:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithDataScope(datascope.NewSelfDataScope())

WithHook

添加前置或后置钩子:

go
apis.NewCreateApi[models.User, payloads.UserParams]().
    WithHook(api.BeforeCreate, func(ctx fiber.Ctx, params *payloads.UserParams) error {
        // Pre-processing logic
        return nil
    })

查询 API 构建器方法

WithSelect

指定查询返回的字段:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithSelect("id", "username", "email", "created_at")

WithCondition

添加固定查询条件:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithCondition(func(q *orm.Query[models.User]) *orm.Query[models.User] {
        return q.Where("is_deleted", false)
    })

WithProcessor

添加结果处理器:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithProcessor(func(items []models.User) []models.User {
        for i := range items {
            items[i].Password = "" // Remove sensitive data
        }
        return items
    })

WithOrderBy

设置默认排序:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithOrderBy("created_at DESC")

WithPreload

预加载关联数据:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithPreload("Department", "Roles")

FindPageApi 特有方法

WithDefaultPageSize

设置默认分页大小:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithDefaultPageSize(20)

WithMaxPageSize

设置最大分页大小:

go
apis.NewFindPageApi[models.User, payloads.UserSearch]().
    WithMaxPageSize(100)

FindTreeApi 特有方法

WithIdColumn

设置 ID 列名:

go
apis.NewFindTreeApi[models.Department, payloads.DeptSearch](buildTree).
    WithIdColumn("id")

WithParentIdColumn

设置父 ID 列名:

go
apis.NewFindTreeApi[models.Department, payloads.DeptSearch](buildTree).
    WithParentIdColumn("parent_id")

WithRootCondition

设置根节点查询条件:

go
apis.NewFindTreeApi[models.Department, payloads.DeptSearch](buildTree).
    WithRootCondition(func(q *orm.Query[models.Department]) *orm.Query[models.Department] {
        return q.WhereNull("parent_id")
    })

FindOptionsApi 特有方法

WithDefaultColumnMapping

设置默认的 label/value 列映射:

go
apis.NewFindOptionsApi[models.User, payloads.UserSearch]().
    WithDefaultColumnMapping(&apis.DataOptionColumnMapping{
        LabelColumn: "username",
        ValueColumn: "id",
    })

WithExtraColumns

添加额外返回的列:

go
apis.NewFindOptionsApi[models.User, payloads.UserSearch]().
    WithExtraColumns("email", "department_id")

写入 API 构建器方法

WithValidator

添加自定义验证器:

go
apis.NewCreateApi[models.User, payloads.UserParams]().
    WithValidator(func(ctx fiber.Ctx, params *payloads.UserParams) error {
        if params.Password != params.ConfirmPassword {
            return errors.New("passwords do not match")
        }
        return nil
    })

WithTransformer

添加数据转换器:

go
apis.NewCreateApi[models.User, payloads.UserParams]().
    WithTransformer(func(ctx fiber.Ctx, params *payloads.UserParams, model *models.User) error {
        // Hash password before saving
        hashedPassword, err := bcrypt.GenerateFromPassword([]byte(params.Password), bcrypt.DefaultCost)
        if err != nil {
            return err
        }
        model.Password = string(hashedPassword)
        return nil
    })

WithOmitColumns

指定不更新的列:

go
apis.NewUpdateApi[models.User, payloads.UserParams]().
    WithOmitColumns("password", "created_at")

WithSelectColumns

指定只更新的列:

go
apis.NewUpdateApi[models.User, payloads.UserParams]().
    WithSelectColumns("username", "email", "phone")

导入导出 API 构建器方法

WithDefaultFormat

设置默认导出格式:

go
apis.NewExportApi[models.User, payloads.UserSearch]().
    WithDefaultFormat("excel") // or "csv"

WithFilenameBuilder

自定义导出文件名:

go
apis.NewExportApi[models.User, payloads.UserSearch]().
    WithFilenameBuilder(func(search payloads.UserSearch, ctx fiber.Ctx) string {
        return fmt.Sprintf("users_%s", time.Now().Format("20060102"))
    })

WithColumnMapping

设置导入/导出列映射:

go
apis.NewImportApi[models.User, payloads.UserParams]().
    WithColumnMapping(map[string]string{
        "用户名": "username",
        "邮箱":   "email",
        "手机号": "phone",
    })

链式调用示例

go
func NewUserResource() api.Resource {
    return &UserResource{
        Resource: api.NewResource("smp/sys/user"),
        
        FindPageApi: apis.NewFindPageApi[models.User, payloads.UserSearch]().
            WithPermission("user:read").
            WithSelect("id", "username", "email", "is_active", "created_at").
            WithCondition(func(q *orm.Query[models.User]) *orm.Query[models.User] {
                return q.Where("is_deleted", false)
            }).
            WithProcessor(func(items []models.User) []models.User {
                for i := range items {
                    items[i].Password = ""
                }
                return items
            }).
            WithOrderBy("created_at DESC").
            WithDefaultPageSize(20).
            WithMaxPageSize(100),
        
        CreateApi: apis.NewCreateApi[models.User, payloads.UserParams]().
            WithPermission("user:create").
            WithValidator(validateUserParams).
            WithTransformer(transformUserParams).
            WithHook(api.AfterCreate, sendWelcomeEmail),
        
        UpdateApi: apis.NewUpdateApi[models.User, payloads.UserParams]().
            WithPermission("user:update").
            WithOmitColumns("password", "created_at", "created_by"),
        
        DeleteApi: apis.NewDeleteApi[models.User]().
            WithPermission("user:delete").
            WithHook(api.BeforeDelete, checkUserDeletable),
    }
}

下一步

基于 Apache License 2.0 许可发布