From b03fc5acf9672bd89d995a7eecbcb5288c9d6e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Tue, 6 Jan 2026 10:55:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BD=93=E5=AD=97=E6=AE=B5=E7=B1=BB=E5=9E=8B=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/schema.go | 14 +++++----- openapi/schema_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 openapi/schema_test.go diff --git a/openapi/schema.go b/openapi/schema.go index ca338f5..0fc3a24 100644 --- a/openapi/schema.go +++ b/openapi/schema.go @@ -9,7 +9,6 @@ package openapi import ( "reflect" - "strconv" "time" "git.zhangdeman.cn/zhangdeman/api-doc/define" @@ -69,7 +68,7 @@ func ParseStructField(field reflect.StructField) *StructFieldInfo { } // GenerateOpenAPISchema 生成完整的 OpenAPI Schema -func GenerateOpenAPISchema(s interface{}) *openapi3.SchemaRef { +func GenerateOpenAPISchema(s any) *openapi3.SchemaRef { t := reflect.TypeOf(s) if t.Kind() == reflect.Ptr { t = t.Elem() @@ -78,6 +77,7 @@ func GenerateOpenAPISchema(s interface{}) *openapi3.SchemaRef { return generateSchemaRecursive(t, make(map[string]bool)) } +// 生成 schema func generateSchemaRecursive(t reflect.Type, seen map[string]bool) *openapi3.SchemaRef { // 检查循环引用 typeName := t.PkgPath() + "." + t.Name() @@ -182,10 +182,10 @@ func applyFieldInfoToSchema(schema *openapi3.Schema, info *StructFieldInfo) { schema.Max = info.Max } if info.MinLength != nil { - schema.MinLength = *info.MinLength + schema.MinLength = uint64(*info.MinLength) } if info.MaxLength != nil { - schema.MaxLength = openapi3.Uint64Ptr(*info.MaxLength) + schema.MaxLength = openapi3.Ptr(uint64(*info.MaxLength)) } if info.Pattern != "" { schema.Pattern = info.Pattern @@ -194,10 +194,10 @@ func applyFieldInfoToSchema(schema *openapi3.Schema, info *StructFieldInfo) { schema.Format = info.Format } if len(info.Enum) > 0 { - schema.Enum = make([]any, 0) - for _, item := range info.Enum { + schema.Enum = info.Enum + /*for _, item := range info.Enum { schema.Enum = append(schema.Enum, item.Value) - } + }*/ } } diff --git a/openapi/schema_test.go b/openapi/schema_test.go new file mode 100644 index 0000000..1a9aa61 --- /dev/null +++ b/openapi/schema_test.go @@ -0,0 +1,58 @@ +// Package openapi ... +// +// Description : openapi ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2026-01-06 10:50 +package openapi + +import ( + "encoding/json" + "fmt" + "testing" + "time" + + "github.com/getkin/kin-openapi/openapi3" +) + +func TestParseStructField(t *testing.T) { + type Category struct { + ID int64 `json:"id" description:"分类ID"` + Name string `json:"name" description:"分类名称"` + } + type Product struct { + ID int64 `json:"id" description:"产品ID" example:"1001" required:"true"` + Name string `json:"name" description:"产品名称" example:"iPhone 13" minLength:"2" maxLength:"100" required:"true"` + Price float64 `json:"price" description:"价格" example:"6999.99" min:"0"` + Stock int `json:"stock" description:"库存" example:"100" min:"0"` + Tags []string `json:"tags" description:"标签"` + Attributes map[string]string `json:"attributes" description:"属性"` + CreatedAt time.Time `json:"created_at" description:"创建时间"` + UpdatedAt *time.Time `json:"updated_at,omitempty" description:"更新时间"` + Category *Category `json:"category,omitempty" description:"分类"` + } + + // 生成 Product 的 Schema + productSchema := GenerateOpenAPISchema(Product{}) + + // 创建完整的 OpenAPI 文档 + doc := &openapi3.T{ + OpenAPI: "3.0.0", + Info: &openapi3.Info{ + Title: "产品服务 API", + Description: "产品管理相关接口", + Version: "1.0.0", + }, + Components: &openapi3.Components{ + Schemas: map[string]*openapi3.SchemaRef{ + "Product": productSchema, + "Category": GenerateOpenAPISchema(Category{}), + }, + }, + } + + // 输出 JSON + data, _ := json.MarshalIndent(doc, "", " ") + fmt.Println(string(data)) +}