mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 11:18:50 +08:00
improve package goai
This commit is contained in:
parent
f580713478
commit
d64898c59a
@ -54,8 +54,7 @@ func (oai *OpenApiV3) newParameterRefWithStructMethod(field gstructs.Field, path
|
||||
parameter.Name = field.Name()
|
||||
}
|
||||
if len(tagMap) > 0 {
|
||||
err := gconv.Struct(oai.fileMapWithShortTags(tagMap), parameter)
|
||||
if err != nil {
|
||||
if err := gconv.Struct(oai.fileMapWithShortTags(tagMap), parameter); err != nil {
|
||||
return nil, gerror.Wrap(err, `mapping struct tags to Parameter failed`)
|
||||
}
|
||||
}
|
||||
|
@ -55,32 +55,33 @@ func (oai *OpenApiV3) getRequestSchemaRef(in getRequestSchemaRefInput) (*SchemaR
|
||||
return nil, err
|
||||
}
|
||||
if in.RequestDataField == "" && bizRequestStructSchemaRefExist {
|
||||
// Normal request.
|
||||
for k, v := range bizRequestStructSchemaRef.Value.Properties {
|
||||
schema.Properties[k] = v
|
||||
}
|
||||
} else {
|
||||
// Common request.
|
||||
structFields, _ := gstructs.Fields(gstructs.FieldsInput{
|
||||
Pointer: in.RequestObject,
|
||||
RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag,
|
||||
})
|
||||
for _, structField := range structFields {
|
||||
var (
|
||||
fieldName = structField.Name()
|
||||
)
|
||||
var fieldName = structField.Name()
|
||||
if jsonName := structField.TagJsonName(); jsonName != "" {
|
||||
fieldName = jsonName
|
||||
}
|
||||
switch len(dataFieldsPartsArray) {
|
||||
case 1:
|
||||
if structField.Name() == dataFieldsPartsArray[0] {
|
||||
if err = oai.tagMapToSchema(structField.TagMap(), bizRequestStructSchemaRef.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
schema.Properties[fieldName] = bizRequestStructSchemaRef
|
||||
break
|
||||
}
|
||||
default:
|
||||
if structField.Name() == dataFieldsPartsArray[0] {
|
||||
var (
|
||||
structFieldInstance = reflect.New(structField.Type().Type).Elem()
|
||||
)
|
||||
var structFieldInstance = reflect.New(structField.Type().Type).Elem()
|
||||
schemaRef, err := oai.getRequestSchemaRef(getRequestSchemaRefInput{
|
||||
BusinessStructName: in.BusinessStructName,
|
||||
RequestObject: structFieldInstance,
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/os/gstructs"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
// Response is specified by OpenAPI/Swagger 3.0 standard.
|
||||
@ -71,17 +70,14 @@ func (oai *OpenApiV3) getResponseSchemaRef(in getResponseSchemaRefInput) (*Schem
|
||||
RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag,
|
||||
})
|
||||
for _, structField := range structFields {
|
||||
var (
|
||||
fieldName = structField.Name()
|
||||
)
|
||||
var fieldName = structField.Name()
|
||||
if jsonName := structField.TagJsonName(); jsonName != "" {
|
||||
fieldName = jsonName
|
||||
}
|
||||
switch len(dataFieldsPartsArray) {
|
||||
case 1:
|
||||
if structField.Name() == dataFieldsPartsArray[0] {
|
||||
err = gconv.Struct(oai.fileMapWithShortTags(structField.TagMap()), bizResponseStructSchemaRef.Value)
|
||||
if err != nil {
|
||||
if err = oai.tagMapToSchema(structField.TagMap(), bizResponseStructSchemaRef.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
schema.Properties[fieldName] = bizResponseStructSchemaRef
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
)
|
||||
|
||||
type Schemas map[string]SchemaRef
|
||||
@ -114,9 +115,8 @@ func (oai *OpenApiV3) structToSchema(object interface{}) (*Schema, error) {
|
||||
}
|
||||
)
|
||||
if len(tagMap) > 0 {
|
||||
err := gconv.Struct(oai.fileMapWithShortTags(tagMap), schema)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, `mapping meta data tags to Schema failed`)
|
||||
if err := oai.tagMapToSchema(tagMap, schema); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if schema.Type != "" && schema.Type != TypeObject {
|
||||
@ -157,3 +157,19 @@ func (oai *OpenApiV3) structToSchema(object interface{}) (*Schema, error) {
|
||||
}
|
||||
return schema, nil
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) tagMapToSchema(tagMap map[string]string, schema *Schema) error {
|
||||
var mergedTagMap = oai.fileMapWithShortTags(tagMap)
|
||||
if err := gconv.Struct(mergedTagMap, schema); err != nil {
|
||||
return gerror.Wrap(err, `mapping struct tags to Schema failed`)
|
||||
}
|
||||
// Validation info to OpenAPI schema pattern.
|
||||
for _, tag := range gvalid.GetTags() {
|
||||
if validationTagValue, ok := tagMap[tag]; ok {
|
||||
_, validationRule, _ := gvalid.ParseTagValue(validationTagValue)
|
||||
schema.Pattern = validationRule
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -9,10 +9,7 @@ package goai
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
)
|
||||
|
||||
type SchemaRefs []SchemaRef
|
||||
@ -33,15 +30,8 @@ func (oai *OpenApiV3) newSchemaRefWithGolangType(golangType reflect.Type, tagMap
|
||||
}
|
||||
)
|
||||
if len(tagMap) > 0 {
|
||||
if err := gconv.Struct(oai.fileMapWithShortTags(tagMap), schema); err != nil {
|
||||
return nil, gerror.Wrap(err, `mapping struct tags to Schema failed`)
|
||||
}
|
||||
// Validation info to OpenAPI schema pattern.
|
||||
for _, tag := range gvalid.GetTags() {
|
||||
if validation, ok := tagMap[tag]; ok {
|
||||
schema.Pattern = validation
|
||||
break
|
||||
}
|
||||
if err := oai.tagMapToSchema(tagMap, schema); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
schemaRef.Value = schema
|
||||
@ -90,9 +80,7 @@ func (oai *OpenApiV3) newSchemaRefWithGolangType(golangType reflect.Type, tagMap
|
||||
|
||||
default:
|
||||
// Normal struct object.
|
||||
var (
|
||||
structTypeName = oai.golangTypeToSchemaName(golangType)
|
||||
)
|
||||
var structTypeName = oai.golangTypeToSchemaName(golangType)
|
||||
if _, ok := oai.Components.Schemas[structTypeName]; !ok {
|
||||
if err := oai.addSchema(reflect.New(golangType).Elem().Interface()); err != nil {
|
||||
return nil, err
|
||||
|
@ -198,9 +198,9 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// parseSequenceTag parses one sequence tag to field, rule and error message.
|
||||
// ParseTagValue parses one sequence tag to field, rule and error message.
|
||||
// The sequence tag is like: [alias@]rule[...#msg...]
|
||||
func parseSequenceTag(tag string) (field, rule, msg string) {
|
||||
func ParseTagValue(tag string) (field, rule, msg string) {
|
||||
// Complete sequence tag.
|
||||
// Example: name@required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致
|
||||
match, _ := gregex.MatchString(`\s*((\w+)\s*@){0,1}\s*([^#]+)\s*(#\s*(.*)){0,1}\s*`, tag)
|
||||
|
@ -31,7 +31,7 @@ func (v *Validator) doCheckMap(ctx context.Context, params interface{}) Error {
|
||||
// Sequence has order for error results.
|
||||
case []string:
|
||||
for _, tag := range assertValue {
|
||||
name, rule, msg := parseSequenceTag(tag)
|
||||
name, rule, msg := ParseTagValue(tag)
|
||||
if len(name) == 0 {
|
||||
continue
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func (v *Validator) doCheckStruct(ctx context.Context, object interface{}) Error
|
||||
// Sequence has order for error results.
|
||||
case []string:
|
||||
for _, tag := range assertValue {
|
||||
name, rule, msg := parseSequenceTag(tag)
|
||||
name, rule, msg := ParseTagValue(tag)
|
||||
if len(name) == 0 {
|
||||
continue
|
||||
}
|
||||
@ -126,8 +126,8 @@ func (v *Validator) doCheckStruct(ctx context.Context, object interface{}) Error
|
||||
for _, field := range tagFields {
|
||||
var (
|
||||
isMeta bool
|
||||
fieldName = field.Name() // Attribute name.
|
||||
name, rule, msg = parseSequenceTag(field.TagValue) // The `name` is different from `attribute alias`, which is used for validation only.
|
||||
fieldName = field.Name() // Attribute name.
|
||||
name, rule, msg = ParseTagValue(field.TagValue) // The `name` is different from `attribute alias`, which is used for validation only.
|
||||
)
|
||||
if len(name) == 0 {
|
||||
if value, ok := fieldToAliasNameMap[fieldName]; ok {
|
||||
|
@ -15,28 +15,28 @@ import (
|
||||
func Test_parseSequenceTag(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := "name@required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致"
|
||||
field, rule, msg := parseSequenceTag(s)
|
||||
field, rule, msg := ParseTagValue(s)
|
||||
t.Assert(field, "name")
|
||||
t.Assert(rule, "required|length:2,20|password3|same:password1")
|
||||
t.Assert(msg, "||密码强度不足|两次密码不一致")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := "required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致"
|
||||
field, rule, msg := parseSequenceTag(s)
|
||||
field, rule, msg := ParseTagValue(s)
|
||||
t.Assert(field, "")
|
||||
t.Assert(rule, "required|length:2,20|password3|same:password1")
|
||||
t.Assert(msg, "||密码强度不足|两次密码不一致")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := "required|length:2,20|password3|same:password1"
|
||||
field, rule, msg := parseSequenceTag(s)
|
||||
field, rule, msg := ParseTagValue(s)
|
||||
t.Assert(field, "")
|
||||
t.Assert(rule, "required|length:2,20|password3|same:password1")
|
||||
t.Assert(msg, "")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := "required"
|
||||
field, rule, msg := parseSequenceTag(s)
|
||||
field, rule, msg := ParseTagValue(s)
|
||||
t.Assert(field, "")
|
||||
t.Assert(rule, "required")
|
||||
t.Assert(msg, "")
|
||||
|
Loading…
x
Reference in New Issue
Block a user