package form import ( "fmt" "reflect" "strings" "github.com/go-playground/locales/en" "github.com/go-playground/locales/zh" ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" zhtrans "github.com/go-playground/validator/v10/translations/zh" // entrans "github.com/go-playground/validator/v10/translations/en" ) var ( translator = NewValidateTranslator() validate = NewValidate() ) type FieldError struct { Field string `json:"field"` Error string `json:"error"` Value string `json:"value"` Raw validator.FieldError `json:"-"` } func (err FieldError) String() string { return fmt.Sprintf("%s:%s", err.Field, err.Error) } type FieldsError []*FieldError func (errs FieldsError) Error() string { var msg []string for _, err := range errs { msg = append(msg, err.String()) } return strings.Join(msg, ";") } func init() { // en := en.New() //英文翻译器 // zh := zh.New() //中文翻译器 // // 第一个参数是必填,如果没有其他的语言设置,就用这第一个 // // 后面的参数是支持多语言环境( // // uni := ut.New(en, en) 也是可以的 // // uni := ut.New(en, zh, tw) // uni := ut.New(en, zh) // translator, ok := uni.GetTranslator("zh") //获取需要的语言 // if !ok { // panic("translator not found") // } // validate := validator.New() // validate.RegisterTagNameFunc(func(field reflect.StructField) string { // label := field.Tag.Get("label") // if label == "" { // return field.Name // } // return label // }) zhtrans.RegisterDefaultTranslations(validate, translator) } func NewValidateTranslator() ut.Translator { en := en.New() //英文翻译器 zh := zh.New() //中文翻译器 // 第一个参数是必填,如果没有其他的语言设置,就用这第一个 // 后面的参数是支持多语言环境( // uni := ut.New(en, en) 也是可以的 // uni := ut.New(en, zh, tw) uni := ut.New(en, zh) var ok bool trans, ok := uni.GetTranslator("zh") //获取需要的语言 if !ok { panic("form validation translator not found") } return trans } func NewValidate() *validator.Validate { v := validator.New() v.RegisterTagNameFunc(func(field reflect.StructField) string { label := field.Tag.Get("label") if label == "" { return field.Name } return label }) return v } func ValidateStruct(v interface{}) FieldsError { if err := validate.Struct(v); err != nil { validationErrs, ok := err.(validator.ValidationErrors) if ok { var fieldsErr FieldsError for _, ve := range validationErrs { fieldsErr = append(fieldsErr, NewFieldError(ve, translator)) } return fieldsErr } } return nil } func NewFieldError(err validator.FieldError, unt ut.Translator) *FieldError { return &FieldError{ Field: err.StructField(), Error: err.Translate(unt), Raw: err, Value: fmt.Sprintf("%v", err.Value()), } }