|
|
|
@ -265,13 +265,12 @@ func (g *Generate) setApiDoc(baseCfg *define.UriBaseConfig, apiDocCfg *define.Pa
|
|
|
|
|
//
|
|
|
|
|
// Date : 16:10 2025/2/14
|
|
|
|
|
func (g *Generate) getApiDocBaseCfg(baseCfg *define.UriBaseConfig, paramType reflect.Type) *define.PathItemOperationConfig {
|
|
|
|
|
defaultPkgPath := wrapper.String(strings.TrimLeft(baseCfg.Uri, "/")).SnakeCaseToCamel()
|
|
|
|
|
cfg := &define.PathItemOperationConfig{
|
|
|
|
|
Tags: baseCfg.TagList,
|
|
|
|
|
Summary: baseCfg.Summary,
|
|
|
|
|
Description: baseCfg.Description,
|
|
|
|
|
ExternalDocs: nil,
|
|
|
|
|
OperationID: baseCfg.Method + "-" + defaultPkgPath,
|
|
|
|
|
OperationID: baseCfg.Method + "-" + baseCfg.Uri,
|
|
|
|
|
Parameters: make([]*define.PathConfigParameter, 0),
|
|
|
|
|
RequestBody: &define.RequestBody{
|
|
|
|
|
Required: true,
|
|
|
|
@ -331,38 +330,59 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
|
|
|
|
|
if propertyName == "-" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
realInputTypeFormat := inputType.Field(i).Type.Kind().String()
|
|
|
|
|
fieldType := inputType.Field(i).Type
|
|
|
|
|
if inputType.Field(i).Type.Kind() == reflect.Ptr {
|
|
|
|
|
fieldType = inputType.Field(i).Type.Elem()
|
|
|
|
|
if inputType.Field(i).Type.Kind() == reflect.Struct && (inputType.Field(i).Type.String() == "Meta" || strings.HasSuffix(inputType.Field(i).Type.String(), ".Meta")) && inputType.Field(i).Type.NumField() == 0 {
|
|
|
|
|
// 空Meta字段认为是用来描述元信息的, 忽略
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if fieldType.Kind() == reflect.Ptr ||
|
|
|
|
|
fieldType.Kind() == reflect.Struct ||
|
|
|
|
|
fieldType.Kind() == reflect.Map ||
|
|
|
|
|
fieldType.Kind() == reflect.Array ||
|
|
|
|
|
fieldType.Kind() == reflect.Slice {
|
|
|
|
|
if convertType := g.realBaseType2SwaggerType(fieldType.String()); !strings.HasPrefix(convertType, "[]") && convertType != inputType.Field(i).Type.Kind().String() {
|
|
|
|
|
// 针对基础类型指针
|
|
|
|
|
realInputTypeFormat := inputType.Field(i).Type.String()
|
|
|
|
|
fieldType := inputType.Field(i).Type
|
|
|
|
|
/*if inputType.Field(i).Type.Kind() == reflect.Ptr {
|
|
|
|
|
fieldType = inputType.Field(i).Type.Elem()
|
|
|
|
|
}*/
|
|
|
|
|
if inputType.Field(i).Type.Kind() == reflect.Ptr {
|
|
|
|
|
// 处理指针
|
|
|
|
|
if inputType.Field(i).Type.Elem().Kind() == reflect.Struct {
|
|
|
|
|
// 结构体指针
|
|
|
|
|
schemaNameNext := g.AddComponentsSchema("", propertyName, inputType.Field(i).Type.Elem())
|
|
|
|
|
baseReqCfg.Parameters = append(baseReqCfg.Parameters, &define.PathConfigParameter{
|
|
|
|
|
Name: ParseStructField.GetParamName(inputType.Field(i)),
|
|
|
|
|
Name: propertyName,
|
|
|
|
|
In: consts.SwaggerParameterInQuery,
|
|
|
|
|
Description: ParseStructField.GetParamDesc(inputType.Field(i)),
|
|
|
|
|
Required: ValidateRule.IsRequired(inputType.Field(i)),
|
|
|
|
|
Deprecated: ParseStructField.Deprecated(inputType.Field(i)),
|
|
|
|
|
Schema: &define.Schema{
|
|
|
|
|
// Format: realInputTypeFormat,
|
|
|
|
|
Ref: g.getSchemaRef(schemaNameNext),
|
|
|
|
|
}, AllowEmptyValue: false,
|
|
|
|
|
Style: "",
|
|
|
|
|
Explode: false,
|
|
|
|
|
AllowReserved: false,
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
// 当做默认基础类型, 默认不会出现 *map *[]
|
|
|
|
|
baseReqCfg.Parameters = append(baseReqCfg.Parameters, &define.PathConfigParameter{
|
|
|
|
|
Name: propertyName,
|
|
|
|
|
In: consts.SwaggerParameterInQuery,
|
|
|
|
|
Description: ParseStructField.GetParamDesc(inputType.Field(i)),
|
|
|
|
|
Required: ValidateRule.IsRequired(inputType.Field(i)),
|
|
|
|
|
Deprecated: ParseStructField.Deprecated(inputType.Field(i)),
|
|
|
|
|
Schema: &define.Schema{
|
|
|
|
|
Type: g.realBaseType2SwaggerType(inputType.Field(i).Type.String()),
|
|
|
|
|
Items: nil,
|
|
|
|
|
Ref: "",
|
|
|
|
|
Format: realInputTypeFormat,
|
|
|
|
|
},
|
|
|
|
|
AllowEmptyValue: false,
|
|
|
|
|
Style: "",
|
|
|
|
|
Explode: false,
|
|
|
|
|
AllowReserved: false,
|
|
|
|
|
Ref: "",
|
|
|
|
|
})
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if fieldType.Kind() == reflect.Struct ||
|
|
|
|
|
fieldType.Kind() == reflect.Map ||
|
|
|
|
|
fieldType.Kind() == reflect.Array ||
|
|
|
|
|
fieldType.Kind() == reflect.Slice {
|
|
|
|
|
// TODO: 完善逻辑解析
|
|
|
|
|
} else {
|
|
|
|
|
baseReqCfg.Parameters = append(baseReqCfg.Parameters, &define.PathConfigParameter{
|
|
|
|
|
Name: ParseStructField.GetParamName(inputType.Field(i)),
|
|
|
|
@ -404,6 +424,10 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
|
|
|
|
|
//
|
|
|
|
|
// Date : 15:25 2025/2/8
|
|
|
|
|
func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, inputType reflect.Type) string {
|
|
|
|
|
if inputType.Kind() == reflect.Struct && (inputType.String() == "Meta" || strings.HasSuffix(inputType.String(), ".Meta")) && inputType.NumField() == 0 {
|
|
|
|
|
// 空Meta字段认为是用来描述元信息的, 忽略
|
|
|
|
|
return "-"
|
|
|
|
|
}
|
|
|
|
|
inputNameArr := strings.Split(inputType.Name(), ".")
|
|
|
|
|
inputName := inputNameArr[len(inputNameArr)-1]
|
|
|
|
|
schemaName := strings.ReplaceAll(pkgPath+"."+inputName, "/", "-")
|
|
|
|
@ -454,32 +478,34 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
|
|
|
|
}
|
|
|
|
|
// 结构体
|
|
|
|
|
if inputType.Kind() == reflect.Struct {
|
|
|
|
|
if len(rootSchemaName) == 0 {
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// g.docData.Components.Schemas[schemaName].Properties[""] = schemaName
|
|
|
|
|
}
|
|
|
|
|
// g.docData.Components.Schemas[schemaName].Ref = consts.SwaggerDataTypeObject
|
|
|
|
|
for i := 0; i < inputType.NumField(); i++ {
|
|
|
|
|
propertyName := ParseStructField.GetParamName(inputType.Field(i))
|
|
|
|
|
if propertyName == "-" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
|
if convertType := g.realBaseType2SwaggerType(inputType.Field(i).Type.String()); !strings.HasPrefix(convertType, "[]") && convertType != inputType.Field(i).Type.Kind().String() {
|
|
|
|
|
// 针对基础类型指针
|
|
|
|
|
if inputType.Field(i).Type.Kind() == reflect.Ptr {
|
|
|
|
|
// 处理指针
|
|
|
|
|
if inputType.Field(i).Type.Elem().Kind() == reflect.Struct {
|
|
|
|
|
// 结构体指针
|
|
|
|
|
schemaNameNext := g.AddComponentsSchema(schemaName, propertyName, inputType.Field(i).Type.Elem())
|
|
|
|
|
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
|
|
|
|
|
Type: g.realBaseType2SwaggerType(convertType),
|
|
|
|
|
Ref: g.getSchemaRef(schemaNameNext),
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 当做默认基础类型, 默认不会出现 *map *[]
|
|
|
|
|
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
|
|
|
|
|
Type: g.realBaseType2SwaggerType(g.realBaseType2SwaggerType(inputType.Field(i).Type.String())),
|
|
|
|
|
Format: inputType.Field(i).Type.String(),
|
|
|
|
|
Default: ParseStructField.GetDefaultValue(inputType.Field(i)),
|
|
|
|
|
Description: ParseStructField.GetParamDesc(inputType.Field(i)),
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if 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 {
|
|
|
|
|
if inputType.Field(i).Type.Kind() == reflect.Struct ||
|
|
|
|
|
inputType.Field(i).Type.Kind() == reflect.Map {
|
|
|
|
|
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
|
|
|
|
@ -499,8 +525,6 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
|
|
|
|
},
|
|
|
|
|
Properties: map[string]*define.Property{},
|
|
|
|
|
}
|
|
|
|
|
} else if inputType.Field(i).Type.Kind() == reflect.Ptr {
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
g.AddComponentsSchema(schemaName, propertyName, inputType.Field(i).Type)
|
|
|
|
|
}
|
|
|
|
@ -520,11 +544,11 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
|
|
|
|
}
|
|
|
|
|
// 指针
|
|
|
|
|
if inputType.Kind() == reflect.Ptr {
|
|
|
|
|
convertType := g.realBaseType2SwaggerType(inputType.String())
|
|
|
|
|
if convertType == inputType.String() {
|
|
|
|
|
if inputType.Elem().Kind() == reflect.Struct {
|
|
|
|
|
// 非基础数据类型
|
|
|
|
|
return g.AddComponentsSchema(schemaName, inputType.Elem().String(), inputType.Elem())
|
|
|
|
|
} else {
|
|
|
|
|
convertType := g.realBaseType2SwaggerType(inputType.String())
|
|
|
|
|
g.docData.Components.Schemas[schemaName].Properties[schemaName] = &define.Property{
|
|
|
|
|
Type: convertType,
|
|
|
|
|
Format: inputType.String(),
|
|
|
|
@ -644,8 +668,11 @@ func (g *Generate) parseBaseUriConfig(uriPrefix string, paramType reflect.Type)
|
|
|
|
|
}
|
|
|
|
|
res.Uri = metaField.Tag.Get(define.TagPath)
|
|
|
|
|
if len(uriPrefix) > 0 {
|
|
|
|
|
res.Uri = strings.TrimRight(uriPrefix, "/") + strings.TrimLeft(res.Uri, "/")
|
|
|
|
|
res.Uri = strings.TrimRight(uriPrefix, "/") + "/" + strings.TrimLeft(res.Uri, "/")
|
|
|
|
|
}
|
|
|
|
|
// 保证接口路由以 /开头
|
|
|
|
|
res.Uri = "/" + strings.TrimLeft(res.Uri, "/")
|
|
|
|
|
|
|
|
|
|
res.Method = strings.ToUpper(metaField.Tag.Get(define.TagMethod))
|
|
|
|
|
res.Description = metaField.Tag.Get(define.TagDesc)
|
|
|
|
|
res.TagList = strings.Split(metaField.Tag.Get(define.TagUriTag), ",")
|
|
|
|
@ -654,20 +681,22 @@ func (g *Generate) parseBaseUriConfig(uriPrefix string, paramType reflect.Type)
|
|
|
|
|
res.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true"
|
|
|
|
|
deprecated := metaField.Tag.Get(define.TagDeprecated)
|
|
|
|
|
res.Deprecated = deprecated == "1" || deprecated == "true"
|
|
|
|
|
res.ContentType = strings.Split(metaField.Tag.Get(define.TagContentType), ",")
|
|
|
|
|
if len(res.ContentType) == 0 {
|
|
|
|
|
requestContentType := strings.TrimSpace(metaField.Tag.Get(define.TagContentType))
|
|
|
|
|
if len(requestContentType) == 0 {
|
|
|
|
|
if wrapper.ArrayType(g.readMethodList).Has(res.Method) >= 0 {
|
|
|
|
|
// get类请求
|
|
|
|
|
res.ContentType = []string{consts.MimeTypeXWWWFormUrlencoded}
|
|
|
|
|
requestContentType = consts.MimeTypeXWWWFormUrlencoded
|
|
|
|
|
} else {
|
|
|
|
|
res.ContentType = []string{consts.MimeTypeJson}
|
|
|
|
|
requestContentType = consts.MimeTypeJson
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
res.OutputContentType = strings.Split(metaField.Tag.Get(define.TagOutputContentType), ",")
|
|
|
|
|
if len(res.OutputContentType) == 0 {
|
|
|
|
|
res.ContentType = strings.Split(requestContentType, ",")
|
|
|
|
|
responseContentType := strings.TrimSpace(metaField.Tag.Get(define.TagOutputContentType))
|
|
|
|
|
if len(responseContentType) == 0 {
|
|
|
|
|
// 未设置响应类型默认JSON数据
|
|
|
|
|
res.OutputContentType = []string{consts.MimeTypeJson}
|
|
|
|
|
responseContentType = consts.MimeTypeJson
|
|
|
|
|
}
|
|
|
|
|
res.OutputContentType = strings.Split(responseContentType, ",")
|
|
|
|
|
res.Summary = ParseStructField.Summary(metaField)
|
|
|
|
|
if res.Method == "" {
|
|
|
|
|
return nil, errors.New("baseCfg.Method is empty")
|
|
|
|
|