Compare commits
4 Commits
a338713c77
...
feature/pa
Author | SHA1 | Date | |
---|---|---|---|
bd01c39fcc | |||
7ddd96bcb7 | |||
5d19efa8cf | |||
7c67160c65 |
25
router/config.go
Normal file
25
router/config.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-02-07 17:41
|
||||||
|
package router
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
var defaultValidateErrTag = "err"
|
||||||
|
|
||||||
|
// SetValidateErrTag 设置验证失败时, 获取错误信息的tag字段
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 17:42 2025/2/7
|
||||||
|
func SetValidateErrTag(tagName string) {
|
||||||
|
tagName = strings.TrimSpace(tagName)
|
||||||
|
if tagName == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defaultValidateErrTag = tagName
|
||||||
|
}
|
@ -154,7 +154,22 @@ func (c controller) parseParamConfig(formDataType reflect.Type) []UriParam {
|
|||||||
if jsonTag == "" {
|
if jsonTag == "" {
|
||||||
jsonTag = structField.Name
|
jsonTag = structField.Name
|
||||||
}
|
}
|
||||||
|
validate := strings.TrimSpace(structField.Tag.Get(TagNameBinding))
|
||||||
|
if len(validate) == 0 {
|
||||||
|
validate = strings.TrimSpace(structField.Tag.Get(TagNameValidate))
|
||||||
|
}
|
||||||
|
title := strings.TrimSpace(structField.Tag.Get(TagNameDesc))
|
||||||
|
if len(title) == 0 {
|
||||||
|
title = jsonTag
|
||||||
|
}
|
||||||
|
res = append(res, UriParam{
|
||||||
|
Field: structField.Name,
|
||||||
|
Name: jsonTag,
|
||||||
|
Title: title,
|
||||||
|
Type: structField.Type.String(),
|
||||||
|
Validate: validate,
|
||||||
|
ErrorMsg: "",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ const (
|
|||||||
TagNamePath = "path" // 接口的请求路径
|
TagNamePath = "path" // 接口的请求路径
|
||||||
TagNameMethod = "method" // 接口的请求方法
|
TagNameMethod = "method" // 接口的请求方法
|
||||||
TagNameUriTag = "tag" // 接口的tag
|
TagNameUriTag = "tag" // 接口的tag
|
||||||
TagNameDesc = "desc" // 接口的描述
|
TagNameDesc = "desc" // 接口/接口参数的描述
|
||||||
TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
||||||
TagNameBinding = "binding" // gin 内置的验证规则tag
|
TagNameBinding = "binding" // gin 内置的验证规则tag
|
||||||
TagNameValidate = "validate" // validator v10 默认的验证规则tag
|
TagNameValidate = "validate" // validator v10 默认的验证规则tag
|
||||||
@ -51,13 +51,12 @@ type UriConfig struct {
|
|||||||
//
|
//
|
||||||
// Date : 15:40 2025/1/27
|
// Date : 15:40 2025/1/27
|
||||||
type UriParam struct {
|
type UriParam struct {
|
||||||
Field string `json:"field"` // 结构体字段
|
Field string `json:"field"` // 结构体字段
|
||||||
Name string `json:"name"` // 参数名称
|
Name string `json:"name"` // 参数名称
|
||||||
Type string `json:"type"` // 参数类型
|
Title string `json:"title"` // 参数标题
|
||||||
Validate string `json:"validate"` // 验证规则: validator/v10 库
|
Type string `json:"type"` // 参数类型
|
||||||
ErrorMsg string `json:"error_msg"` // 验证失败的错误信息
|
Validate string `json:"validate"` // 验证规则: validator/v10 库
|
||||||
DisableAutoType bool `json:"disable_auto_type"` // 禁用自动类型转换
|
ErrorMsg string `json:"error_msg"` // 验证失败的错误信息
|
||||||
Sort string `json:"sort"` // 参数读取顺序: 默认 POST : body > query > path GET : query > path > body
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -31,6 +31,8 @@ func RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
|
|||||||
formData := reflect.New(uriCfg.FormDataType).Interface()
|
formData := reflect.New(uriCfg.FormDataType).Interface()
|
||||||
// 表单解析
|
// 表单解析
|
||||||
if err = request.Form.Parse(ctx, formData); nil != err {
|
if err = request.Form.Parse(ctx, formData); nil != err {
|
||||||
|
// 格式化验证错误的信息
|
||||||
|
err = GetValidateErr(formData, err)
|
||||||
e = exception.NewFromError(400, err)
|
e = exception.NewFromError(400, err)
|
||||||
response.SendWithException(ctx, e, nil)
|
response.SendWithException(ctx, e, nil)
|
||||||
return
|
return
|
||||||
|
@ -21,7 +21,7 @@ func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (any, error)
|
|||||||
|
|
||||||
type TestForm struct {
|
type TestForm struct {
|
||||||
Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get"`
|
Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get"`
|
||||||
Age int `json:"age" form:"age" binding:"min=20"`
|
Age int `json:"age" form:"age" binding:"min=20" err_msg:"年龄不能小于20"`
|
||||||
Name string `json:"name" form:"name"`
|
Name string `json:"name" form:"name"`
|
||||||
Test *Test `json:"test" form:"test"`
|
Test *Test `json:"test" form:"test"`
|
||||||
Num *int64 `json:"num" form:"num"`
|
Num *int64 `json:"num" form:"num"`
|
||||||
@ -31,6 +31,7 @@ type Test struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_parseController(t *testing.T) {
|
func Test_parseController(t *testing.T) {
|
||||||
|
SetValidateErrTag("err_msg")
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
Group(r, "test", nil, TestController{})
|
Group(r, "test", nil, TestController{})
|
||||||
r.Run(":8080")
|
r.Run(":8080")
|
||||||
|
55
router/validator.go
Normal file
55
router/validator.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-02-07 17:36
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetValidateErr 格式化错误信息
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:19 2025/1/15
|
||||||
|
func GetValidateErr(obj any, rawErr error) error {
|
||||||
|
if nil == rawErr {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if nil == obj {
|
||||||
|
return rawErr
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
ok bool
|
||||||
|
validationErrs validator.ValidationErrors
|
||||||
|
errString []string
|
||||||
|
field reflect.StructField
|
||||||
|
)
|
||||||
|
if ok = errors.As(rawErr, &validationErrs); !ok {
|
||||||
|
return rawErr
|
||||||
|
}
|
||||||
|
objType := reflect.TypeOf(obj)
|
||||||
|
if objType.Kind() == reflect.Ptr {
|
||||||
|
objType = objType.Elem()
|
||||||
|
}
|
||||||
|
for _, validationErr := range validationErrs {
|
||||||
|
if field, ok = objType.FieldByName(validationErr.Field()); ok {
|
||||||
|
if e := field.Tag.Get(defaultValidateErrTag); e != "" {
|
||||||
|
errString = append(errString, fmt.Sprintf("%s: %s", field.Tag.Get("json"), e))
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
errString = append(errString, fmt.Sprintf("%s: %v", field.Tag.Get("json"), validationErr.Value()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errString = append(errString, validationErr.Error())
|
||||||
|
}
|
||||||
|
return errors.New(strings.Join(errString, "\n"))
|
||||||
|
}
|
Reference in New Issue
Block a user