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] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=96=87=E6=A1=A3?= =?UTF-8?q?=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), }, }, },