From 1cafe70192d899f32ec8c8b8a62bd0f04a94bc95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 Jan 2026 11:27:51 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E9=85=8D?= =?UTF-8?q?=E7=BD=AESecurity=20+=20=E7=A7=BB=E9=99=A4=E4=B8=8D=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E7=9A=84components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/generate.go | 15 +++++++-------- openapi/generate_test.go | 19 ++++++++++++++++++- openapi/option.go | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/openapi/generate.go b/openapi/generate.go index 23c2219..c6011b5 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -29,7 +29,7 @@ var ( func NewOpenApiDoc(optionFunc ...OptionFunc) *openapi3.T { t := &openapi3.T{ Extensions: map[string]any{}, - OpenAPI: "3.1.0", + OpenAPI: "3.0.3", Components: &openapi3.Components{ Extensions: map[string]any{}, Origin: &openapi3.Origin{ @@ -167,7 +167,7 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a schemaData := GenerateOpenAPISchema(requestType) apiOperate, isRead := g.initApiConfig(docFlag, apiMeta) - requestTypeStr := requestType.String() + //requestTypeStr := requestType.String() if isRead { for paramName, paramConfig := range schemaData.Value.Properties { apiOperate.Parameters = append(apiOperate.Parameters, &openapi3.ParameterRef{ @@ -217,14 +217,13 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a } } - // 初始化接口配置 - if _, exist := g.docTable[docFlag].Components.Schemas[requestTypeStr]; !exist { + /*if _, exist := g.docTable[docFlag].Components.Schemas[requestTypeStr]; !exist { g.docTable[docFlag].Components.Schemas[requestTypeStr] = schemaData - } - responseTypeStr := responseType.String() + }*/ + /*responseTypeStr := responseType.String() if _, exist := g.docTable[docFlag].Components.Schemas[responseTypeStr]; !exist { g.docTable[docFlag].Components.Schemas[responseTypeStr] = GenerateOpenAPISchema(responseType) - } + }*/ desc := "请求成功" apiOperate.Responses.Set(fmt.Sprintf("%v", http.StatusOK), &openapi3.ResponseRef{ Extensions: nil, @@ -239,7 +238,7 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a consts.MimeTypeJson: { Extensions: nil, Origin: nil, - Schema: g.docTable[docFlag].Components.Schemas[responseTypeStr], + Schema: GenerateOpenAPISchema(responseType), Example: nil, Examples: nil, Encoding: nil, diff --git a/openapi/generate_test.go b/openapi/generate_test.go index 985a944..7f053fa 100644 --- a/openapi/generate_test.go +++ b/openapi/generate_test.go @@ -11,10 +11,13 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "testing" "time" "git.zhangdeman.cn/zhangdeman/api-doc/define" + "git.zhangdeman.cn/zhangdeman/consts" + "github.com/getkin/kin-openapi/openapi3" ) func TestGenerate_AddApiDoc(t *testing.T) { @@ -35,7 +38,21 @@ func TestGenerate_AddApiDoc(t *testing.T) { Category *Category `json:"category,omitempty" description:"分类"` } docFlag := "demo" - DocManager.NewOpenApiDoc(docFlag) + DocManager.NewOpenApiDoc(docFlag, WithSecurity(&openapi3.SecuritySchemes{ + "Token-Auth": { + Extensions: nil, + Origin: nil, + Ref: "", + Value: &openapi3.SecurityScheme{ + Extensions: nil, + Origin: nil, + Type: "apiKey", + Description: "Token 身份认证", + Name: "token", + In: strings.ToLower(consts.RequestDataLocationHeader.String()), + }, + }, + })) DocManager.AddApiDoc(docFlag, define.UriConfig{ Path: "/a/b/c", RequestMethod: http.MethodGet, diff --git a/openapi/option.go b/openapi/option.go index 3603a99..918a208 100644 --- a/openapi/option.go +++ b/openapi/option.go @@ -7,7 +7,11 @@ // Date : 2026-01-06 22:48 package openapi -import "github.com/getkin/kin-openapi/openapi3" +import ( + "sort" + + "github.com/getkin/kin-openapi/openapi3" +) // OptionFunc 设置文档选项 type OptionFunc func(t *openapi3.T) @@ -31,3 +35,31 @@ func WithInfo(info *openapi3.Info) OptionFunc { t.Info = info } } + +// WithSecurity 设置安全策略 +func WithSecurity(securityTable *openapi3.SecuritySchemes) OptionFunc { + return func(t *openapi3.T) { + if nil == securityTable { + return + } + if nil == t.Components { + t.Components = &openapi3.Components{} + } + if nil == t.Components.SecuritySchemes { + t.Components.SecuritySchemes = make(map[string]*openapi3.SecuritySchemeRef) + } + if nil == t.Security { + t.Security = make([]openapi3.SecurityRequirement, 0) + } + keyList := make([]string, 0) + for k, v := range *securityTable { + keyList = append(keyList, k) + t.Components.SecuritySchemes[k] = v + } + // 保证生成结果有序 + sort.Strings(keyList) + for _, k := range keyList { + t.Security = append(t.Security, map[string][]string{k: {}}) + } + } +} From 4888c7a3dbaa9404bbf3b4117e4f33761916979b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 Jan 2026 11:34:45 +0800 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=E8=AF=B7=E6=B1=82schema=20data=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20NIL=20=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/generate.go | 48 +++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/openapi/generate.go b/openapi/generate.go index c6011b5..a456350 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -169,29 +169,31 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a apiOperate, isRead := g.initApiConfig(docFlag, apiMeta) //requestTypeStr := requestType.String() if isRead { - for paramName, paramConfig := range schemaData.Value.Properties { - apiOperate.Parameters = append(apiOperate.Parameters, &openapi3.ParameterRef{ - Extensions: nil, - Origin: nil, - Ref: "", - Value: &openapi3.Parameter{ - Extensions: nil, - Origin: nil, - Name: paramName, - In: strings.ToLower(consts.RequestDataLocationQuery.String()), - Description: paramConfig.Value.Description, - Style: "", - Explode: nil, - AllowEmptyValue: paramConfig.Value.AllowEmptyValue, - AllowReserved: false, - Deprecated: false, - Required: op_array.ArrayType(paramConfig.Value.Required).Has(paramName) >= 0, - Schema: paramConfig, - Example: nil, - Examples: nil, - Content: nil, - }, - }) + if nil != schemaData { + for paramName, paramConfig := range schemaData.Value.Properties { + apiOperate.Parameters = append(apiOperate.Parameters, &openapi3.ParameterRef{ + Extensions: nil, + Origin: nil, + Ref: "", + Value: &openapi3.Parameter{ + Extensions: nil, + Origin: nil, + Name: paramName, + In: strings.ToLower(consts.RequestDataLocationQuery.String()), + Description: paramConfig.Value.Description, + Style: "", + Explode: nil, + AllowEmptyValue: paramConfig.Value.AllowEmptyValue, + AllowReserved: false, + Deprecated: false, + Required: op_array.ArrayType(paramConfig.Value.Required).Has(paramName) >= 0, + Schema: paramConfig, + Example: nil, + Examples: nil, + Content: nil, + }, + }) + } } } else { apiOperate.RequestBody = &openapi3.RequestBodyRef{ From cae403fddf18e383981faee025dd388449cfa338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 Jan 2026 11:44:28 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=86=97=E4=BD=99=E5=AD=98=E5=82=A8components?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=BC=80=E5=90=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/generate.go | 29 ++++++++++++++++++++--------- openapi/generate_test.go | 1 + 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/openapi/generate.go b/openapi/generate.go index a456350..5934717 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -124,7 +124,13 @@ func NewOpenApiDoc(optionFunc ...OptionFunc) *openapi3.T { // Generate 生成 OpenApi 标准规范的文档 type Generate struct { - docTable map[string]*openapi3.T + docTable map[string]*openapi3.T + enableRedundantStorageComponents bool // 冗余存储 +} + +// EnableRedundantStorageComponents 开启冗余存储 +func (g *Generate) EnableRedundantStorageComponents() { + g.enableRedundantStorageComponents = true } // DocData 获取一个文档数据 @@ -167,7 +173,6 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a schemaData := GenerateOpenAPISchema(requestType) apiOperate, isRead := g.initApiConfig(docFlag, apiMeta) - //requestTypeStr := requestType.String() if isRead { if nil != schemaData { for paramName, paramConfig := range schemaData.Value.Properties { @@ -219,13 +224,19 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a } } - /*if _, exist := g.docTable[docFlag].Components.Schemas[requestTypeStr]; !exist { - g.docTable[docFlag].Components.Schemas[requestTypeStr] = schemaData - }*/ - /*responseTypeStr := responseType.String() - if _, exist := g.docTable[docFlag].Components.Schemas[responseTypeStr]; !exist { - g.docTable[docFlag].Components.Schemas[responseTypeStr] = GenerateOpenAPISchema(responseType) - }*/ + if g.enableRedundantStorageComponents { + // 此处是冗余 components 设置, 便于查看结构体, 不冗余文档也可正常解析 + requestTypeStr := requestType.String() + if _, exist := g.docTable[docFlag].Components.Schemas[requestTypeStr]; !exist { + g.docTable[docFlag].Components.Schemas[requestTypeStr] = schemaData + } + responseTypeStr := responseType.String() + if _, exist := g.docTable[docFlag].Components.Schemas[responseTypeStr]; !exist { + g.docTable[docFlag].Components.Schemas[responseTypeStr] = GenerateOpenAPISchema(responseType) + } + // 冗余处理结束 + } + desc := "请求成功" apiOperate.Responses.Set(fmt.Sprintf("%v", http.StatusOK), &openapi3.ResponseRef{ Extensions: nil, diff --git a/openapi/generate_test.go b/openapi/generate_test.go index 7f053fa..42b746c 100644 --- a/openapi/generate_test.go +++ b/openapi/generate_test.go @@ -37,6 +37,7 @@ func TestGenerate_AddApiDoc(t *testing.T) { UpdatedAt *time.Time `json:"updated_at,omitempty" description:"更新时间"` Category *Category `json:"category,omitempty" description:"分类"` } + DocManager.EnableRedundantStorageComponents() // 启用 components 冗余存储 docFlag := "demo" DocManager.NewOpenApiDoc(docFlag, WithSecurity(&openapi3.SecuritySchemes{ "Token-Auth": { From 55238e0de848511f14dfd892086fdc5fe7cb5c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 Jan 2026 12:09:37 +0800 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=E8=AF=B7=E6=B1=82=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E7=BB=93=E6=9E=84=E4=BD=93=E5=AE=9A=E4=B9=89=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20$ref,=20=E5=8E=8B=E7=BC=A9=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E4=BD=93=E7=A7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/generate.go | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/openapi/generate.go b/openapi/generate.go index 5934717..50dc96e 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -208,16 +208,21 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a Value: &openapi3.RequestBody{ Extensions: nil, Origin: nil, - Description: "", - Required: false, + Description: "接口请求数据", + Required: true, Content: map[string]*openapi3.MediaType{ consts.MimeTypeJson: { Extensions: nil, Origin: nil, - Schema: schemaData, - Example: nil, - Examples: nil, - Encoding: nil, + Schema: &openapi3.SchemaRef{ + Extensions: nil, + Origin: nil, + Ref: "#/components/schemas/" + strings.TrimLeft(requestType.String(), "*"), + Value: nil, + }, + Example: nil, + Examples: nil, + Encoding: nil, }, }, }, @@ -230,13 +235,12 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a if _, exist := g.docTable[docFlag].Components.Schemas[requestTypeStr]; !exist { g.docTable[docFlag].Components.Schemas[requestTypeStr] = schemaData } - responseTypeStr := responseType.String() - if _, exist := g.docTable[docFlag].Components.Schemas[responseTypeStr]; !exist { - g.docTable[docFlag].Components.Schemas[responseTypeStr] = GenerateOpenAPISchema(responseType) - } // 冗余处理结束 } - + responseTypeStr := responseType.String() + if _, exist := g.docTable[docFlag].Components.Schemas[responseTypeStr]; !exist { + g.docTable[docFlag].Components.Schemas[responseTypeStr] = GenerateOpenAPISchema(responseType) + } desc := "请求成功" apiOperate.Responses.Set(fmt.Sprintf("%v", http.StatusOK), &openapi3.ResponseRef{ Extensions: nil, @@ -251,10 +255,15 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a consts.MimeTypeJson: { Extensions: nil, Origin: nil, - Schema: GenerateOpenAPISchema(responseType), - Example: nil, - Examples: nil, - Encoding: nil, + Schema: &openapi3.SchemaRef{ + Extensions: nil, + Origin: nil, + Ref: "#/components/schemas/" + strings.TrimLeft(responseTypeStr, "*"), + Value: nil, + }, + Example: nil, + Examples: nil, + Encoding: nil, }, }, Links: nil, From 7de0c874c63601b3cf83e44a102a9a7bc06fe434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 Jan 2026 12:35:43 +0800 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=85=AC=E5=85=B1=E7=9A=84=E8=AF=B7=E6=B1=82=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/generate.go | 6 ++++++ openapi/generate_test.go | 15 +++++++++++++++ openapi/option.go | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/openapi/generate.go b/openapi/generate.go index 50dc96e..e7a3f3c 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -296,6 +296,12 @@ func (g *Generate) initApiConfig(docFlag string, apiMeta define.UriConfig) (*ope } newOperate := openapi3.NewOperation() newOperate.Parameters = make(openapi3.Parameters, 0) + // 合入公共的 请求参数 + if nil != g.docTable[docFlag].Components.Parameters { + for _, v := range g.docTable[docFlag].Components.Parameters { + newOperate.Parameters = append(newOperate.Parameters, v) + } + } newOperate.Responses = openapi3.NewResponses() newOperate.Summary = apiMeta.Desc newOperate.Description = apiMeta.Desc diff --git a/openapi/generate_test.go b/openapi/generate_test.go index 42b746c..143efa3 100644 --- a/openapi/generate_test.go +++ b/openapi/generate_test.go @@ -53,6 +53,21 @@ func TestGenerate_AddApiDoc(t *testing.T) { In: strings.ToLower(consts.RequestDataLocationHeader.String()), }, }, + }), WithCommonParameter(&openapi3.ParametersMap{ + "Token": { + Value: &openapi3.Parameter{ + Name: "Token", + In: strings.ToLower(consts.RequestDataLocationHeader.String()), + Description: "用户登录 Token", + }, + }, + "User-Agent": { + Value: &openapi3.Parameter{ + Name: "User-Agent", + In: strings.ToLower(consts.RequestDataLocationHeader.String()), + Description: "用户访问 UA", + }, + }, })) DocManager.AddApiDoc(docFlag, define.UriConfig{ Path: "/a/b/c", diff --git a/openapi/option.go b/openapi/option.go index 918a208..76760a1 100644 --- a/openapi/option.go +++ b/openapi/option.go @@ -63,3 +63,25 @@ func WithSecurity(securityTable *openapi3.SecuritySchemes) OptionFunc { } } } + +// WithCommonParameter 设置公共请求蚕食 +func WithCommonParameter(commonParameterTable *openapi3.ParametersMap) OptionFunc { + return func(t *openapi3.T) { + if nil == commonParameterTable { + return + } + if nil == t.Components { + t.Components = &openapi3.Components{} + } + if nil == t.Components.Parameters { + t.Components.Parameters = make(map[string]*openapi3.ParameterRef) + } + // 不要直接复制, 逐个设置, 可以重复调用, 后面的会覆盖前面的 + for k, v := range *commonParameterTable { + if nil == v { + continue + } + t.Components.Parameters[k] = v + } + } +} From 7418c313d1331f30235d3a0333d6ff4c69d6f57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 Jan 2026 18:02:05 +0800 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=E6=95=B0=E6=8D=AE=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E4=BD=BF=E7=94=A8ref=E5=BC=95=E7=94=A8=E6=96=B9?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/generate.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/openapi/generate.go b/openapi/generate.go index e7a3f3c..a21a7b7 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -247,23 +247,12 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a Origin: nil, Ref: "", Value: &openapi3.Response{ - Extensions: nil, - Origin: nil, Description: &desc, - Headers: nil, Content: map[string]*openapi3.MediaType{ consts.MimeTypeJson: { - Extensions: nil, - Origin: nil, Schema: &openapi3.SchemaRef{ - Extensions: nil, - Origin: nil, - Ref: "#/components/schemas/" + strings.TrimLeft(responseTypeStr, "*"), - Value: nil, + Ref: "#/components/schemas/" + strings.TrimLeft(responseTypeStr, "*"), }, - Example: nil, - Examples: nil, - Encoding: nil, }, }, Links: nil, From 2f4c663e5209c3868b9600aef3f5a6d34b39e865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 Jan 2026 21:46:49 +0800 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi/generate.go | 150 +++++++++++++++++++++++++++----------------- 1 file changed, 91 insertions(+), 59 deletions(-) diff --git a/openapi/generate.go b/openapi/generate.go index a21a7b7..abd13d2 100644 --- a/openapi/generate.go +++ b/openapi/generate.go @@ -147,10 +147,9 @@ func (g *Generate) NewOpenApiDoc(docFlag string, docOption ...OptionFunc) *opena return t } -// AddApiDoc 添加接口文档 -func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request any, response any) error { +// formatType 输入输出数据类型, 转化为统一reflect.Type +func (g *Generate) formatType(request any, response any) (reflect.Type, reflect.Type) { var ( - err error requestType reflect.Type responseType reflect.Type ok bool @@ -170,73 +169,106 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a responseType = responseType.Elem() } } + return requestType, responseType +} + +// getComponentsSchemaRef 获取组件 schema ref +func (g *Generate) getComponentsSchemaRef(structKindString string) string { + return "#/components/schemas/" + strings.TrimLeft(structKindString, "*") +} + +// setReadRequestParameter 设置读请求参数 +func (g *Generate) setReadRequestParameter(apiOperate *openapi3.Operation, schemaData *openapi3.SchemaRef) { + if nil == schemaData { + return + } + for paramName, paramConfig := range schemaData.Value.Properties { + apiOperate.Parameters = append(apiOperate.Parameters, &openapi3.ParameterRef{ + Extensions: nil, + Origin: nil, + Ref: "", + Value: &openapi3.Parameter{ + Extensions: nil, + Origin: nil, + Name: paramName, + In: strings.ToLower(consts.RequestDataLocationQuery.String()), + Description: paramConfig.Value.Description, + Style: "", + Explode: nil, + AllowEmptyValue: paramConfig.Value.AllowEmptyValue, + AllowReserved: false, + Deprecated: false, + Required: op_array.ArrayType(paramConfig.Value.Required).Has(paramName) >= 0, + Schema: paramConfig, + Example: nil, + Examples: nil, + Content: nil, + }, + }) + } +} + +// setWriteRequestBody 设置写请求请求 Body +func (g *Generate) setWriteRequestBody(apiOperate *openapi3.Operation, schemaDataRef string) { + apiOperate.RequestBody = &openapi3.RequestBodyRef{ + Extensions: nil, + Origin: nil, + Ref: "", + Value: &openapi3.RequestBody{ + Extensions: nil, + Origin: nil, + Description: "接口请求数据", + Required: true, + Content: map[string]*openapi3.MediaType{ + consts.MimeTypeJson: { + Extensions: nil, + Origin: nil, + Schema: &openapi3.SchemaRef{ + Extensions: nil, + Origin: nil, + Ref: schemaDataRef, + Value: nil, + }, + Example: nil, + Examples: nil, + Encoding: nil, + }, + }, + }, + } +} + +// AddApiDoc 添加接口文档 +func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request any, response any) error { + var ( + err error + requestType reflect.Type + responseType reflect.Type + ) + + // 初始化请求数据与响应数据类型 + requestType, responseType = g.formatType(request, response) schemaData := GenerateOpenAPISchema(requestType) apiOperate, isRead := g.initApiConfig(docFlag, apiMeta) if isRead { - if nil != schemaData { - for paramName, paramConfig := range schemaData.Value.Properties { - apiOperate.Parameters = append(apiOperate.Parameters, &openapi3.ParameterRef{ - Extensions: nil, - Origin: nil, - Ref: "", - Value: &openapi3.Parameter{ - Extensions: nil, - Origin: nil, - Name: paramName, - In: strings.ToLower(consts.RequestDataLocationQuery.String()), - Description: paramConfig.Value.Description, - Style: "", - Explode: nil, - AllowEmptyValue: paramConfig.Value.AllowEmptyValue, - AllowReserved: false, - Deprecated: false, - Required: op_array.ArrayType(paramConfig.Value.Required).Has(paramName) >= 0, - Schema: paramConfig, - Example: nil, - Examples: nil, - Content: nil, - }, - }) + if g.enableRedundantStorageComponents { + // 此处是冗余 components 设置, 便于查看结构体, 不冗余文档也可正常解析 + requestTypeStr := requestType.String() + if _, exist := g.docTable[docFlag].Components.Schemas[requestTypeStr]; !exist { + g.docTable[docFlag].Components.Schemas[requestTypeStr] = schemaData } + // 冗余处理结束 } + g.setReadRequestParameter(apiOperate, schemaData) } else { - apiOperate.RequestBody = &openapi3.RequestBodyRef{ - Extensions: nil, - Origin: nil, - Ref: "", - Value: &openapi3.RequestBody{ - Extensions: nil, - Origin: nil, - Description: "接口请求数据", - Required: true, - Content: map[string]*openapi3.MediaType{ - consts.MimeTypeJson: { - Extensions: nil, - Origin: nil, - Schema: &openapi3.SchemaRef{ - Extensions: nil, - Origin: nil, - Ref: "#/components/schemas/" + strings.TrimLeft(requestType.String(), "*"), - Value: nil, - }, - Example: nil, - Examples: nil, - Encoding: nil, - }, - }, - }, - } - } - - if g.enableRedundantStorageComponents { - // 此处是冗余 components 设置, 便于查看结构体, 不冗余文档也可正常解析 requestTypeStr := requestType.String() if _, exist := g.docTable[docFlag].Components.Schemas[requestTypeStr]; !exist { g.docTable[docFlag].Components.Schemas[requestTypeStr] = schemaData } - // 冗余处理结束 + g.setWriteRequestBody(apiOperate, g.getComponentsSchemaRef(requestType.String())) } + responseTypeStr := responseType.String() if _, exist := g.docTable[docFlag].Components.Schemas[responseTypeStr]; !exist { g.docTable[docFlag].Components.Schemas[responseTypeStr] = GenerateOpenAPISchema(responseType) @@ -251,7 +283,7 @@ func (g *Generate) AddApiDoc(docFlag string, apiMeta define.UriConfig, request a Content: map[string]*openapi3.MediaType{ consts.MimeTypeJson: { Schema: &openapi3.SchemaRef{ - Ref: "#/components/schemas/" + strings.TrimLeft(responseTypeStr, "*"), + Ref: g.getComponentsSchemaRef(responseTypeStr), }, }, },