This commit is contained in:
John Guo
2022-02-15 00:21:05 +08:00
parent 01ba56c38b
commit 2428b27168
6 changed files with 81 additions and 9 deletions

View File

@ -16,6 +16,16 @@ func (r *Request) SetParam(key string, value interface{}) {
r.paramsMap[key] = value
}
// SetParamMap sets custom parameter with key-value pair map.
func (r *Request) SetParamMap(data map[string]interface{}) {
if r.paramsMap == nil {
r.paramsMap = make(map[string]interface{})
}
for k, v := range data {
r.paramsMap[k] = v
}
}
// GetParam returns custom parameter with given name `key`.
// It returns `def` if `key` does not exist.
// It returns nil if `def` is not passed.

View File

@ -527,3 +527,50 @@ func Test_Params_Struct_Validation(t *testing.T) {
t.Assert(c.PostContent(ctx, "/", `id=1`), `The name field is required`)
})
}
// https://github.com/gogf/gf/issues/1488
func Test_Params_Parse_Issue1488(t *testing.T) {
p, _ := gtcp.GetFreePort()
s := g.Server(p)
s.Group("/", func(group *ghttp.RouterGroup) {
group.ALL("/", func(r *ghttp.Request) {
type Request struct {
Type []int `p:"type"`
Keyword string `p:"keyword"`
Limit int `p:"per_page" d:"10"`
Page int `p:"page" d:"1"`
Order string
CreatedAtLte string
CreatedAtGte string
CreatorID []int
}
for i := 0; i < 10; i++ {
r.SetParamMap(g.Map{
"type[]": 0,
"keyword": "",
"t_start": "",
"t_end": "",
"reserve_at_start": "",
"reserve_at_end": "",
"user_name": "",
"flag": "",
"per_page": 6,
})
var parsed Request
_ = r.Parse(&parsed)
r.Response.Write(parsed.Page, parsed.Limit)
}
})
})
s.SetPort(p)
s.SetDumpRouterMap(false)
s.Start()
defer s.Shutdown()
time.Sleep(100 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
c := g.Client()
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p))
t.Assert(c.GetContent(ctx, "/", ``), `16161616161616161616`)
})
}

View File

@ -18,9 +18,15 @@ type Type struct {
// Field contains information of a struct field .
type Field struct {
Value reflect.Value // The underlying value of the field.
Field reflect.StructField // The underlying field of the field.
TagValue string // Retrieved tag value. There might be more than one tags in the field, but only one can be retrieved according to calling function rules.
Value reflect.Value // The underlying value of the field.
Field reflect.StructField // The underlying field of the field.
// Retrieved tag name. It depends TagValue.
TagName string
// Retrieved tag value.
// There might be more than one tags in the field, but only one can be retrieved according to calling function rules.
TagValue string
}
// FieldsInput is the input parameter struct type for function Fields.

View File

@ -180,7 +180,8 @@ func getFieldValuesByTagPriority(pointer interface{}, priority []string, tagMap
return nil, err
}
var (
tagValue = ""
tagName string
tagValue string
tagFields = make([]Field, 0)
)
for _, field := range fields {
@ -190,6 +191,7 @@ func getFieldValuesByTagPriority(pointer interface{}, priority []string, tagMap
}
tagValue = ""
for _, p := range priority {
tagName = p
tagValue = field.Tag(p)
if tagValue != "" && tagValue != "-" {
break
@ -201,6 +203,7 @@ func getFieldValuesByTagPriority(pointer interface{}, priority []string, tagMap
continue
}
tagField := field
tagField.TagName = tagName
tagField.TagValue = tagValue
tagFields = append(tagFields, tagField)
}

View File

@ -34,8 +34,8 @@ var (
}
// StructTagPriority defines the default priority tags for Map*/Struct* functions.
// Note, the "gconv", "param", "params" tags are used by old version of package.
// It is strongly recommended using short tag "c" or "p" instead in the future.
// Note, the `gconv/param/params` tags are used by old version of package.
// It is strongly recommended using short tag `c/p` instead in the future.
StructTagPriority = []string{"gconv", "param", "params", "c", "p", "json"}
)

View File

@ -248,6 +248,12 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string
// orm:"id, priority"
// orm:"name, with:uid=id"
tagMap[attributeName] = utils.RemoveSymbols(strings.Split(tagName, ",")[0])
// If tag and attribute values both exist in `paramsMap`,
// it then uses the tag value overwriting the attribute value in `paramsMap`.
if paramsMap[tagName] != nil && paramsMap[attributeName] != nil {
paramsMap[attributeName] = paramsMap[tagName]
}
}
var (
@ -269,7 +275,7 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string
// string cases and chars like '-'/'_'/'.'/' '.
// Matching the parameters to struct tag names.
// The `tagV` is the attribute name of the struct.
// The `attrKey` is the attribute name of the struct.
for attrKey, cmpKey := range tagMap {
if strings.EqualFold(checkName, cmpKey) {
attrName = attrKey
@ -297,12 +303,12 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string
continue
}
// If the attribute name is already checked converting, then skip it.
if _, ok := doneMap[attrName]; ok {
if _, ok = doneMap[attrName]; ok {
continue
}
// Mark it done.
doneMap[attrName] = struct{}{}
if err := bindVarToStructAttr(pointerElemReflectValue, attrName, mapV, mapping); err != nil {
if err = bindVarToStructAttr(pointerElemReflectValue, attrName, mapV, mapping); err != nil {
return err
}
}