From 1b48707f8273df3030ac865dd9c382eb70eb56b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 10 Feb 2025 14:38:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E6=A1=A3=E4=B8=8D?= =?UTF-8?q?=E8=A7=84=E8=8C=83=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- define/openapi.go | 12 ++++++------ generate.go | 37 ++++++++++++++++++++++++++++++------- parser_test.go | 2 +- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/define/openapi.go b/define/openapi.go index 1707625..7767261 100644 --- a/define/openapi.go +++ b/define/openapi.go @@ -130,8 +130,8 @@ type Schema struct { Properties map[string]*Property `json:"properties,omitempty"` // 数据字段 => 数据规则 Required []string `json:"required,omitempty"` // 必传属性列表 Enum []any `json:"enum,omitempty"` // 枚举值列表 - Type string `json:"type"` // 类型 - Ref string `json:"$ref"` // 类型引用 + Type string `json:"type,omitempty"` // 类型 + Ref string `json:"$ref,omitempty"` // 类型引用 } // Property 是从 JSON Schema 提取出来的,但是做了一些调整以适应 OpenAPI Specification。 @@ -193,10 +193,10 @@ type XML struct { // // Date : 17:17 2024/7/19 type RequestBody struct { - Required bool `json:"required"` // 指定请求体是不是应该被包含在请求中,默认值是false。 - Description string `json:"description"` // 对请求体的简要描述,可以包含使用示例,CommonMark syntax可以被用来呈现富文本格式 - Content map[string]*Media `json:"content"` // content_type => 相应数据描述的映射 必选. 请求体的内容。请求体的属性key是一个媒体类型或者媒体类型范围,值是对应媒体类型的示例数据。对于能匹配多个key的请求,定义更明确的请求会更优先被匹配。比如text/plain会覆盖text/*的定义。 - Ref string `json:"$ref"` // 一个允许引用规范内部的其他部分或外部规范的对象。 Reference 对象 定义于 JSON Reference 且遵循相同的结构、行为和规则。 + Required bool `json:"required"` // 指定请求体是不是应该被包含在请求中,默认值是false。 + Description string `json:"description,omitempty"` // 对请求体的简要描述,可以包含使用示例,CommonMark syntax可以被用来呈现富文本格式 + Content map[string]*Media `json:"content,omitempty"` // content_type => 相应数据描述的映射 必选. 请求体的内容。请求体的属性key是一个媒体类型或者媒体类型范围,值是对应媒体类型的示例数据。对于能匹配多个key的请求,定义更明确的请求会更优先被匹配。比如text/plain会覆盖text/*的定义。 + Ref string `json:"$ref,omitempty"` // 一个允许引用规范内部的其他部分或外部规范的对象。 Reference 对象 定义于 JSON Reference 且遵循相同的结构、行为和规则。 } // Media 本质即为不一样 content_type 对应的数据结构定义 diff --git a/generate.go b/generate.go index 9b9f7aa..37456d5 100644 --- a/generate.go +++ b/generate.go @@ -192,8 +192,8 @@ func (g *Generate) AddApiFromInAndOut(baseCfg *define.UriBaseConfig, paramType r defaultPkgPath := wrapper.String(strings.ReplaceAll(strings.TrimLeft(baseCfg.Uri, "/"), "/", "_")).SnakeCaseToCamel() paramPkgPath := defaultPkgPath + baseCfg.Method + "Param" resultPkgPath := defaultPkgPath + baseCfg.Method + "Result" - g.AddComponentsSchema(paramPkgPath, paramType) - g.AddComponentsSchema(resultPkgPath, resultType) + g.AddComponentsSchema("", paramPkgPath, paramType) + g.AddComponentsSchema("", resultPkgPath, resultType) if _, exist := g.docData.Paths[baseCfg.Uri]; !exist { g.docData.Paths[baseCfg.Uri] = &define.PathConfig{} } @@ -268,7 +268,7 @@ func (g *Generate) AddApiFromInAndOut(baseCfg *define.UriBaseConfig, paramType r // Author : go_developer@163.com<白茶清欢> // // Date : 15:25 2025/2/8 -func (g *Generate) AddComponentsSchema(schemaName string, inputType reflect.Type) string { +func (g *Generate) AddComponentsSchema(rootSchemaName string, schemaName string, inputType reflect.Type) string { if _, exist := g.docData.Components.Schemas[schemaName]; !exist { g.docData.Components.Schemas[schemaName] = &define.Schema{ Nullable: false, @@ -293,7 +293,8 @@ func (g *Generate) AddComponentsSchema(schemaName string, inputType reflect.Type } // 数组 if inputType.Kind() == reflect.Slice || inputType.Kind() == reflect.Array { - sliceItemType := g.parseSliceItem(inputType) + g.docData.Components.Schemas[schemaName].Type = consts.SwaggerDataTypeArray + sliceItemType := g.parseSliceItem(schemaName, inputType) g.docData.Components.Schemas[schemaName].Properties[inputType.Name()] = &define.Property{ Type: consts.SwaggerDataTypeArray, Format: inputType.String(), @@ -303,13 +304,19 @@ func (g *Generate) AddComponentsSchema(schemaName string, inputType reflect.Type } // 结构体 if inputType.Kind() == reflect.Struct { + g.docData.Components.Schemas[schemaName].Type = consts.SwaggerDataTypeObject for i := 0; i < inputType.NumField(); i++ { if inputType.Field(i).Type.Kind() == reflect.Ptr || inputType.Field(i).Type.Kind() == reflect.Struct || inputType.Field(i).Type.Kind() == reflect.Map || inputType.Field(i).Type.Kind() == reflect.Array || inputType.Field(i).Type.Kind() == reflect.Slice { - g.AddComponentsSchema(schemaName+inputType.Field(i).Name, inputType.Field(i).Type) + g.AddComponentsSchema(schemaName, schemaName+inputType.Field(i).Name, inputType.Field(i).Type) + g.docData.Components.Schemas[schemaName].Properties[schemaName+inputType.Field(i).Name] = &define.Property{ + Type: consts.SwaggerDataTypeObject, + Format: inputType.Field(i).Type.String(), + Properties: map[string]*define.Property{}, + } } else { g.docData.Components.Schemas[schemaName].Properties[inputType.Field(i).Name] = &define.Property{ Type: "string", @@ -326,14 +333,30 @@ func (g *Generate) AddComponentsSchema(schemaName string, inputType reflect.Type // Author : go_developer@163.com<白茶清欢> // // Date : 21:33 2025/2/8 -func (g *Generate) parseSliceItem(inputType reflect.Type) string { +func (g *Generate) parseSliceItem(rootSchemaName string, inputType reflect.Type) string { if inputType.Kind() != reflect.Slice && inputType.Kind() != reflect.Array { // 不是数组 return "" } sliceValue := reflect.MakeSlice(inputType, 1, 1) sliceItemType := sliceValue.Index(0).Type() - g.AddComponentsSchema(sliceItemType.PkgPath(), sliceItemType) + g.AddComponentsSchema(rootSchemaName, sliceItemType.PkgPath(), sliceItemType) + if rootSchemaName != "" { + g.docData.Components.Schemas[rootSchemaName].Properties[sliceItemType.PkgPath()] = &define.Property{ + Type: "", + Format: inputType.String(), + Enum: nil, + Default: nil, + Description: "", + AllOf: nil, + OneOf: nil, + AnyOf: nil, + Items: nil, + AdditionalProperties: nil, + Properties: nil, + Ref: g.getSchemaRes(sliceItemType.PkgPath()), + } + } if len(sliceItemType.PkgPath()) == 0 { return sliceItemType.String() } diff --git a/parser_test.go b/parser_test.go index 805d9fc..6c947a8 100644 --- a/parser_test.go +++ b/parser_test.go @@ -44,7 +44,7 @@ func Test_parser_Openapi3(t *testing.T) { }, reflect.TypeOf(bArr), reflect.TypeOf(bArr)) byteData, _ := json.Marshal(g.docData) fmt.Println(string(byteData)) - fmt.Println(g.parseSliceItem(reflect.TypeOf(bArr))) + fmt.Println(g.parseSliceItem("", reflect.TypeOf(bArr))) } func TestParseForSwagger(t *testing.T) {