87 lines
1.9 KiB
Go
87 lines
1.9 KiB
Go
package validation
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"reflect"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/go-playground/validator/v10"
|
||
)
|
||
|
||
// 初始化一个验证器实例
|
||
var validate = validator.New()
|
||
|
||
// 自定义验证规则:requiredint
|
||
func init() {
|
||
validate.RegisterValidation("telephone", func(fl validator.FieldLevel) bool {
|
||
if err := IsValidPhone(fl.Field().String()); err != nil {
|
||
return false
|
||
}
|
||
return true
|
||
})
|
||
validate.RegisterValidation("dateonly", func(fl validator.FieldLevel) bool {
|
||
_, err := time.ParseInLocation("2006-01-02", fl.Field().String(), time.Local)
|
||
if err != nil {
|
||
return false
|
||
}
|
||
return true
|
||
})
|
||
}
|
||
|
||
func ValidateForm(s any) error {
|
||
// 验证结构体数据
|
||
if err := validate.Struct(s); err != nil {
|
||
if _, ok := err.(*validator.InvalidValidationError); ok {
|
||
return errors.New("验证器配置错误")
|
||
}
|
||
|
||
// 获取结构体的反射类型
|
||
t := reflect.TypeOf(s)
|
||
|
||
errorMessages := make([]string, 0)
|
||
for _, err := range err.(validator.ValidationErrors) {
|
||
// 获取字段名
|
||
fieldName := err.Field()
|
||
// 获取标签名
|
||
tag := err.Tag()
|
||
// 获取验证失败的字段值
|
||
// value := err.Value()
|
||
|
||
// 通过反射获取字段
|
||
field, found := t.Elem().FieldByName(fieldName)
|
||
errorMsg := fmt.Sprintf("[%s] 验证失败: %s", fieldName, translate(tag))
|
||
if found {
|
||
commentTag := field.Tag.Get("comment")
|
||
errorMsg = fmt.Sprintf("[%s] 验证失败: %s", commentTag, translate(tag))
|
||
}
|
||
|
||
errorMessages = append(errorMessages, errorMsg)
|
||
}
|
||
return errors.New(strings.Join(errorMessages, "; "))
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func translate(s string) string {
|
||
switch s {
|
||
case "required":
|
||
return "不能为空"
|
||
case "min":
|
||
return "不能小于"
|
||
case "max":
|
||
return "不能大于"
|
||
case "email":
|
||
return "不是有效的邮箱地址"
|
||
case "telephone":
|
||
return "不是有效的手机号"
|
||
case "datetime":
|
||
return "不是有效的日期时间"
|
||
case "dateonly":
|
||
return "不是有效的日期"
|
||
}
|
||
return s
|
||
}
|