119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package validator
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/gin-gonic/gin/binding"
|
|
"github.com/go-playground/locales/zh"
|
|
uTrans "github.com/go-playground/universal-translator"
|
|
"github.com/go-playground/validator/v10"
|
|
enTranslations "github.com/go-playground/validator/v10/translations/en"
|
|
zhTranslations "github.com/go-playground/validator/v10/translations/zh"
|
|
)
|
|
|
|
const (
|
|
local = "zh"
|
|
)
|
|
|
|
func NewValidator() binding.StructValidator {
|
|
return &customValidator{}
|
|
}
|
|
|
|
type customValidator struct {
|
|
once sync.Once
|
|
validate *validator.Validate
|
|
translator uTrans.Translator
|
|
}
|
|
|
|
func (c *customValidator) ValidateStruct(obj interface{}) error {
|
|
c.lazyinit()
|
|
if err := c.validate.Struct(obj); err != nil {
|
|
return c.translate(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *customValidator) Engine() any {
|
|
c.lazyinit()
|
|
return c.validate
|
|
}
|
|
|
|
func (c *customValidator) lazyinit() {
|
|
c.once.Do(func() {
|
|
c.validate = validator.New()
|
|
c.validate.SetTagName("binding")
|
|
|
|
if err := c.setTrans(); err != nil {
|
|
fmt.Printf("setTrans fail %s", err.Error())
|
|
}
|
|
|
|
if err := c.registerValidation(); err != nil {
|
|
fmt.Printf("registervalidation fail:%s", err.Error())
|
|
}
|
|
})
|
|
}
|
|
|
|
// 暂时写死英文翻译中文,todo 根据IP或者根据请求头语言决定翻译
|
|
func (c *customValidator) setTrans() error {
|
|
zh := zh.New()
|
|
uni := uTrans.New(zh, zh)
|
|
|
|
trans, exist := uni.GetTranslator(local)
|
|
if !exist {
|
|
return fmt.Errorf("uni.GetTranslator %s fail", local)
|
|
}
|
|
|
|
c.translator = trans
|
|
|
|
switch local {
|
|
case "en":
|
|
if err := enTranslations.RegisterDefaultTranslations(c.validate, c.translator); err != nil {
|
|
return fmt.Errorf("enTranslations fail:%s", err.Error())
|
|
}
|
|
case "zh":
|
|
if err := zhTranslations.RegisterDefaultTranslations(c.validate, c.translator); err != nil {
|
|
return fmt.Errorf("zhTranslations fail:%s", err.Error())
|
|
}
|
|
default:
|
|
if err := zhTranslations.RegisterDefaultTranslations(c.validate, c.translator); err != nil {
|
|
return fmt.Errorf("zhTranslations fail:%s", err.Error())
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *customValidator) registerValidation() error {
|
|
if err := c.validate.RegisterValidation("tableName", tableName); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := c.validate.RegisterValidation("sql_sort", sortVerify); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *customValidator) translate(err error) error {
|
|
if errs, ok := err.(validator.ValidationErrors); ok {
|
|
tErrMap := errs.Translate(c.translator)
|
|
errMsgs := make([]string, 0)
|
|
|
|
for _, msg := range tErrMap {
|
|
errMsgs = append(errMsgs, msg)
|
|
}
|
|
|
|
return errors.New(strings.Join(errMsgs, ";"))
|
|
|
|
// todo 根据定制tag,输出定制的msg
|
|
// todo 翻译后的错误消息按另外的规则输出(当前json)
|
|
}
|
|
|
|
return err
|
|
}
|