diff --git a/openapi/generate.go b/openapi/generate.go index ce5edb9..1ac9de1 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -8,6 +8,8 @@ package openapi import ( + "reflect" + "git.zhangdeman.cn/zhangdeman/consts" "github.com/getkin/kin-openapi/openapi3" ) @@ -17,7 +19,7 @@ func NewGenerate() *Generate { return &Generate{ doc: &openapi3.T{ Extensions: map[string]any{}, - OpenAPI: "openapi", + OpenAPI: "3.1.0", Components: &openapi3.Components{ Extensions: map[string]any{}, Origin: &openapi3.Origin{ @@ -106,5 +108,34 @@ type Generate struct { // AddApiDoc 添加接口文档 func (g *Generate) AddApiDoc(request any, response any) error { - return nil + var ( + err error + requestType reflect.Type + responseType reflect.Type + ok bool + ) + + // 初始化请求数据与响应数据类型 + if requestType, ok = request.(reflect.Type); !ok { + requestType = reflect.TypeOf(request) + if requestType.Kind() == reflect.Ptr { + requestType = requestType.Elem() + } + } + + if responseType, ok = response.(reflect.Type); !ok { + responseType = reflect.TypeOf(response) + if responseType.Kind() == reflect.Ptr { + responseType = responseType.Elem() + } + } + requestTypeStr := requestType.String() + if _, exist := g.doc.Components.Schemas[requestTypeStr]; !exist { + g.doc.Components.Schemas[requestTypeStr] = GenerateOpenAPISchema(requestType) + } + responseTypeStr := requestType.String() + if _, exist := g.doc.Components.Schemas[responseTypeStr]; !exist { + g.doc.Components.Schemas[responseTypeStr] = GenerateOpenAPISchema(responseType) + } + return err } diff --git a/openapi/generate_test.go b/openapi/generate_test.go new file mode 100644 index 0000000..413fc7e --- /dev/null +++ b/openapi/generate_test.go @@ -0,0 +1,38 @@ +// Package openapi ... +// +// Description : openapi ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2026-01-06 11:48 +package openapi + +import ( + "encoding/json" + "fmt" + "testing" + "time" +) + +func TestGenerate_AddApiDoc(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:"分类"` + } + instance := NewGenerate() + instance.AddApiDoc(Category{}, Product{}) + // 输出 JSON + data, _ := json.MarshalIndent(instance.doc, "", " ") + fmt.Println(string(data)) +} diff --git a/openapi/schema.go b/openapi/schema.go index 0fc3a24..c7ef10d 100644 --- a/openapi/schema.go +++ b/openapi/schema.go @@ -69,12 +69,19 @@ func ParseStructField(field reflect.StructField) *StructFieldInfo { // GenerateOpenAPISchema 生成完整的 OpenAPI Schema func GenerateOpenAPISchema(s any) *openapi3.SchemaRef { - t := reflect.TypeOf(s) - if t.Kind() == reflect.Ptr { - t = t.Elem() + var ( + ok bool + tType reflect.Type + ) + + if tType, ok = s.(reflect.Type); !ok { + tType = reflect.TypeOf(s) + if tType.Kind() == reflect.Ptr { + tType = tType.Elem() + } } - return generateSchemaRecursive(t, make(map[string]bool)) + return generateSchemaRecursive(tType, make(map[string]bool)) } // 生成 schema