feat: 完善结构体字段类型解析
This commit is contained in:
@@ -9,7 +9,6 @@ package openapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.zhangdeman.cn/zhangdeman/api-doc/define"
|
"git.zhangdeman.cn/zhangdeman/api-doc/define"
|
||||||
@@ -69,7 +68,7 @@ func ParseStructField(field reflect.StructField) *StructFieldInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenerateOpenAPISchema 生成完整的 OpenAPI Schema
|
// GenerateOpenAPISchema 生成完整的 OpenAPI Schema
|
||||||
func GenerateOpenAPISchema(s interface{}) *openapi3.SchemaRef {
|
func GenerateOpenAPISchema(s any) *openapi3.SchemaRef {
|
||||||
t := reflect.TypeOf(s)
|
t := reflect.TypeOf(s)
|
||||||
if t.Kind() == reflect.Ptr {
|
if t.Kind() == reflect.Ptr {
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
@@ -78,6 +77,7 @@ func GenerateOpenAPISchema(s interface{}) *openapi3.SchemaRef {
|
|||||||
return generateSchemaRecursive(t, make(map[string]bool))
|
return generateSchemaRecursive(t, make(map[string]bool))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成 schema
|
||||||
func generateSchemaRecursive(t reflect.Type, seen map[string]bool) *openapi3.SchemaRef {
|
func generateSchemaRecursive(t reflect.Type, seen map[string]bool) *openapi3.SchemaRef {
|
||||||
// 检查循环引用
|
// 检查循环引用
|
||||||
typeName := t.PkgPath() + "." + t.Name()
|
typeName := t.PkgPath() + "." + t.Name()
|
||||||
@@ -182,10 +182,10 @@ func applyFieldInfoToSchema(schema *openapi3.Schema, info *StructFieldInfo) {
|
|||||||
schema.Max = info.Max
|
schema.Max = info.Max
|
||||||
}
|
}
|
||||||
if info.MinLength != nil {
|
if info.MinLength != nil {
|
||||||
schema.MinLength = *info.MinLength
|
schema.MinLength = uint64(*info.MinLength)
|
||||||
}
|
}
|
||||||
if info.MaxLength != nil {
|
if info.MaxLength != nil {
|
||||||
schema.MaxLength = openapi3.Uint64Ptr(*info.MaxLength)
|
schema.MaxLength = openapi3.Ptr(uint64(*info.MaxLength))
|
||||||
}
|
}
|
||||||
if info.Pattern != "" {
|
if info.Pattern != "" {
|
||||||
schema.Pattern = info.Pattern
|
schema.Pattern = info.Pattern
|
||||||
@@ -194,10 +194,10 @@ func applyFieldInfoToSchema(schema *openapi3.Schema, info *StructFieldInfo) {
|
|||||||
schema.Format = info.Format
|
schema.Format = info.Format
|
||||||
}
|
}
|
||||||
if len(info.Enum) > 0 {
|
if len(info.Enum) > 0 {
|
||||||
schema.Enum = make([]any, 0)
|
schema.Enum = info.Enum
|
||||||
for _, item := range info.Enum {
|
/*for _, item := range info.Enum {
|
||||||
schema.Enum = append(schema.Enum, item.Value)
|
schema.Enum = append(schema.Enum, item.Value)
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
58
openapi/schema_test.go
Normal file
58
openapi/schema_test.go
Normal file
@@ -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))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user