增加示例值解析 + 优化schema属性配置 #16
@ -155,6 +155,7 @@ type Property struct {
|
||||
XEnumDescription map[string]string `json:"x-enumDescriptions,omitempty"` // 枚举值描述的扩展, redoc-free支持
|
||||
Default any `json:"default,omitempty"` // 默认值 : 不同于 JSON Schema,这个值必须符合定义与相同级别的 Schema 对象 中定义的类型,比如 type 是 string,那么 default 可以是 "foo" 但不能是 1。
|
||||
Description string `json:"description,omitempty"` // 数据描述, CommonMark syntax可以被用来呈现富文本格式.
|
||||
Example string `json:"example,omitempty"` // 媒体类型的示例。示例对象应该符合此媒体类型的格式, 这里指定的example对象 object is mutually exclusive of the examples object. 而且如果引用的schema也包含示例,在这里指定的example值将会覆盖schema提供的示例。
|
||||
Maximum *int64 `json:"maximum,omitempty"` // 最大值
|
||||
Minimum *int64 `json:"minimum,omitempty"` // 最小值
|
||||
MinLength *int64 `json:"minLength,omitempty"` // 字符串最小长度
|
||||
|
@ -29,6 +29,8 @@ const (
|
||||
TagUriTag = "tag" // 接口的tag
|
||||
TagOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
||||
TagErrMsg = "err" // 验证失败错误信息tag
|
||||
TagExample = "example" // 示例值
|
||||
TagEg = "eg" // 示例值
|
||||
TagContentType = "content_type"
|
||||
TagOutputContentType = "output_content_type"
|
||||
TagNameOmitempty = "omitempty"
|
||||
|
105
generate.go
105
generate.go
@ -342,13 +342,8 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
|
||||
convertBaseType, isBaseType := g.realBaseType2SwaggerType(inputType.Field(i).Type.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 isBaseType {
|
||||
// 当做默认基础类型, 默认不会出现 *map *[]
|
||||
minVal := ValidateRule.Minimum(inputType.Field(i))
|
||||
maxVal := ValidateRule.Maximum(inputType.Field(i))
|
||||
itemParam := &define.PathConfigParameter{
|
||||
Name: propertyName,
|
||||
In: consts.SwaggerParameterInQuery,
|
||||
@ -356,24 +351,15 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
|
||||
Required: ValidateRule.IsRequired(inputType.Field(i)),
|
||||
Deprecated: ParseStructFieldTag.Deprecated(inputType.Field(i)),
|
||||
Schema: &define.Schema{
|
||||
Type: convertBaseType,
|
||||
Format: realInputTypeFormat,
|
||||
Default: ParseStructFieldTag.GetDefaultValue(inputType.Field(i)),
|
||||
Enum: ValidateRule.Enum(inputType.Field(i)),
|
||||
XEnumDescription: ParseStructFieldTag.EnumDescription(inputType.Field(i)),
|
||||
Type: convertBaseType,
|
||||
Format: realInputTypeFormat,
|
||||
},
|
||||
AllowEmptyValue: false,
|
||||
Style: "",
|
||||
Explode: false,
|
||||
AllowReserved: false,
|
||||
}
|
||||
if itemParam.Schema.Type == consts.SwaggerDataTypeString {
|
||||
itemParam.Schema.MinLength = minVal
|
||||
itemParam.Schema.MaxLength = maxVal
|
||||
} else {
|
||||
itemParam.Schema.Minimum = minVal
|
||||
itemParam.Schema.Maximum = maxVal
|
||||
}
|
||||
g.setStructFieldProperty(itemParam.Schema, inputType.Field(i))
|
||||
baseReqCfg.Parameters = append(baseReqCfg.Parameters, itemParam)
|
||||
continue
|
||||
}
|
||||
@ -389,6 +375,7 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
|
||||
Format: realInputTypeFormat,
|
||||
Enum: ValidateRule.Enum(inputType.Field(i)),
|
||||
XEnumDescription: ParseStructFieldTag.EnumDescription(inputType.Field(i)),
|
||||
Example: ParseStructFieldTag.GetExampleValue(inputType.Field(i)),
|
||||
},
|
||||
})
|
||||
continue
|
||||
@ -434,6 +421,7 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
|
||||
Format: realInputTypeFormat,
|
||||
Enum: ValidateRule.Enum(inputType.Field(i)),
|
||||
XEnumDescription: ParseStructFieldTag.EnumDescription(inputType.Field(i)),
|
||||
Example: ParseStructFieldTag.GetExampleValue(inputType.Field(i)),
|
||||
},
|
||||
AllowEmptyValue: false,
|
||||
Style: "",
|
||||
@ -521,7 +509,6 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
||||
Items: propertyXOf,
|
||||
}
|
||||
}
|
||||
|
||||
return schemaName
|
||||
}
|
||||
// 结构体
|
||||
@ -554,24 +541,13 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
||||
} else {
|
||||
// 当做默认基础类型, 默认不会出现 *map *[]
|
||||
convertBaseType, _ := g.realBaseType2SwaggerType(inputType.Field(i).Type.String())
|
||||
maxVal := ValidateRule.Maximum(inputType.Field(i))
|
||||
minVal := ValidateRule.Minimum(inputType.Field(i))
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
|
||||
Type: convertBaseType,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
Enum: ValidateRule.Enum(inputType.Field(i)),
|
||||
XEnumDescription: ParseStructFieldTag.EnumDescription(inputType.Field(i)),
|
||||
Default: ParseStructFieldTag.GetDefaultValue(inputType.Field(i)),
|
||||
Description: ParseStructFieldTag.GetParamDesc(inputType.Field(i)),
|
||||
}
|
||||
if g.docData.Components.Schemas[schemaName].Properties[propertyName].Type == consts.SwaggerDataTypeString {
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].MinLength = minVal
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].MaxLength = maxVal
|
||||
} else {
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].Minimum = minVal
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].Maximum = maxVal
|
||||
Type: convertBaseType,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
}
|
||||
}
|
||||
// 设置参数各种属性
|
||||
g.setStructFieldProperty(g.docData.Components.Schemas[schemaName], inputType.Field(i))
|
||||
continue
|
||||
}
|
||||
if inputType.Field(i).Type.Kind() == reflect.Struct ||
|
||||
@ -581,10 +557,9 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
||||
if inputType.Field(i).Type.Kind() == reflect.Struct ||
|
||||
inputType.Field(i).Type.Kind() == reflect.Map {
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
|
||||
Type: consts.SwaggerDataTypeObject,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
Description: ParseStructFieldTag.GetParamDesc(inputType.Field(i)),
|
||||
Properties: map[string]*define.Property{},
|
||||
Type: consts.SwaggerDataTypeObject,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
Properties: map[string]*define.Property{},
|
||||
}
|
||||
} else if inputType.Field(i).Type.Kind() == reflect.Array ||
|
||||
inputType.Field(i).Type.Kind() == reflect.Slice {
|
||||
@ -600,10 +575,9 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
||||
propertyXOf.Ref = g.getSchemaRef(sliceItemType)
|
||||
}
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
|
||||
Type: consts.SwaggerDataTypeArray,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
Description: ParseStructFieldTag.GetParamDesc(inputType.Field(i)),
|
||||
Items: propertyXOf,
|
||||
Type: consts.SwaggerDataTypeArray,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
Items: propertyXOf,
|
||||
}
|
||||
} else {
|
||||
g.AddComponentsSchema(schemaName, propertyName, inputType.Field(i).Type)
|
||||
@ -611,27 +585,17 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
|
||||
} else {
|
||||
if inputType.Field(i).Type.Kind() == reflect.Interface {
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName] = g.anyTypeConfig(inputType.Field(i))
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].Example = ParseStructFieldTag.GetExampleValue(inputType.Field(i))
|
||||
} else {
|
||||
convertBaseType, _ := g.realBaseType2SwaggerType(inputType.Field(i).Type.String())
|
||||
maxVal := ValidateRule.Maximum(inputType.Field(i))
|
||||
minVal := ValidateRule.Minimum(inputType.Field(i))
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
|
||||
Type: convertBaseType,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
Default: ParseStructFieldTag.GetDefaultValue(inputType.Field(i)),
|
||||
Description: ParseStructFieldTag.GetParamDesc(inputType.Field(i)),
|
||||
}
|
||||
if g.docData.Components.Schemas[schemaName].Properties[propertyName].Type == consts.SwaggerDataTypeString {
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].MinLength = minVal
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].MaxLength = maxVal
|
||||
} else {
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].Minimum = minVal
|
||||
g.docData.Components.Schemas[schemaName].Properties[propertyName].Maximum = maxVal
|
||||
Type: convertBaseType,
|
||||
Format: inputType.Field(i).Type.String(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置参数各种属性
|
||||
g.setStructFieldProperty(schemaName, inputType.Field(i))
|
||||
g.setStructFieldProperty(g.docData.Components.Schemas[schemaName], inputType.Field(i))
|
||||
}
|
||||
return schemaName
|
||||
}
|
||||
@ -686,6 +650,7 @@ func (g *Generate) handleAnonymousField(schemaName string, field reflect.StructF
|
||||
g.docData.Components.Schemas[schemaName].Properties[paramName] = &define.Property{
|
||||
Type: baseConvertType,
|
||||
Format: itemField.Type.String(),
|
||||
Example: ParseStructFieldTag.GetExampleValue(itemField),
|
||||
Enum: ValidateRule.Enum(itemField),
|
||||
XEnumDescription: ParseStructFieldTag.EnumDescription(itemField),
|
||||
Default: ParseStructFieldTag.GetDefaultValue(handleType.Field(i)),
|
||||
@ -775,12 +740,34 @@ func (g *Generate) realBaseType2SwaggerType(realType string) (string, bool) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:13 2025/2/13
|
||||
func (g *Generate) setStructFieldProperty(schemaName string, structField reflect.StructField) {
|
||||
func (g *Generate) setStructFieldProperty(schema *define.Schema, structField reflect.StructField) {
|
||||
paramName := ParseStructFieldTag.GetParamName(structField)
|
||||
if ValidateRule.IsRequired(structField) {
|
||||
g.docData.Components.Schemas[schemaName].Required = append(g.docData.Components.Schemas[schemaName].Required, paramName)
|
||||
if paramName == "" || paramName == "-" {
|
||||
return
|
||||
}
|
||||
isRequired := ValidateRule.IsRequired(structField)
|
||||
enum := ValidateRule.Enum(structField)
|
||||
xEnumDescription := ParseStructFieldTag.EnumDescription(structField)
|
||||
example := ParseStructFieldTag.GetExampleValue(structField)
|
||||
description := ParseStructFieldTag.GetParamDesc(structField)
|
||||
maxVal := ValidateRule.Maximum(structField)
|
||||
minVal := ValidateRule.Minimum(structField)
|
||||
if nil != schema {
|
||||
if isRequired {
|
||||
schema.Required = append(schema.Required, paramName)
|
||||
}
|
||||
if schema.Properties[paramName].Type == consts.SwaggerDataTypeString {
|
||||
schema.Properties[paramName].MinLength = minVal
|
||||
schema.Properties[paramName].MaxLength = maxVal
|
||||
} else {
|
||||
schema.Properties[paramName].Minimum = minVal
|
||||
schema.Properties[paramName].Maximum = maxVal
|
||||
}
|
||||
schema.Properties[paramName].Enum = enum
|
||||
schema.Properties[paramName].XEnumDescription = xEnumDescription
|
||||
schema.Properties[paramName].Example = example
|
||||
schema.Properties[paramName].Description = description
|
||||
}
|
||||
g.docData.Components.Schemas[schemaName].Properties[ParseStructFieldTag.GetParamName(structField)].Enum = ValidateRule.Enum(structField)
|
||||
}
|
||||
|
||||
// parseBaseUriConfig 通过Meta字段解析Uri基础配置信息
|
||||
|
@ -178,3 +178,19 @@ func (psf parseStructFieldTag) EnumDescription(structField reflect.StructField)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// GetExampleValue 示例值
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 14:42 2025/2/20
|
||||
func (psf parseStructFieldTag) GetExampleValue(structField reflect.StructField) string {
|
||||
descTagList := []string{define.TagEg, define.TagExample}
|
||||
for _, tag := range descTagList {
|
||||
tagVal := structField.Tag.Get(tag)
|
||||
if tagVal != "" {
|
||||
return strings.ReplaceAll(tagVal, "###", "`")
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user