pkg/validator/validator.go

99 lines
2.3 KiB
Go
Raw Permalink Normal View History

2024-12-28 12:01:56 +00:00
// Package validator use for valiate struct
package validator
import (
"context"
"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"
en_translations "github.com/go-playground/validator/v10/translations/en"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
"github.com/samber/lo"
"git.ifooth.com/common/pkg/i18n"
)
var (
validate *validator.Validate
uni *ut.UniversalTranslator
defaultTrans ut.Translator
zhTrans ut.Translator
)
// ValidationError 校验错误
type ValidationError struct {
ctx context.Context
rawErr error
}
// Validator 实现了 Validate 接口自定义调用
type Validator interface {
Validate() error
}
func (e *ValidationError) getTranslator() ut.Translator {
acceptLang, ok := i18n.GetLang(e.ctx)
if ok && acceptLang == "zh" {
return zhTrans
}
return defaultTrans
}
// Error error iface
func (e *ValidationError) Error() string {
if _, ok := e.rawErr.(*validator.InvalidValidationError); ok {
return e.rawErr.Error()
}
errs := e.rawErr.(validator.ValidationErrors)
// 只返回单个错误
for _, ve := range errs {
return ve.Translate(e.getTranslator())
}
return e.rawErr.Error()
}
// Struct 通过 validate tag 校验结构体, Validate 校验需要传入指针类型
func Struct(ctx context.Context, s any) error {
err := validate.StructCtx(ctx, s)
if err != nil {
return &ValidationError{ctx: ctx, rawErr: err}
}
// 实现了 Validate 接口自定义调用
if v, ok := s.(Validator); ok {
return v.Validate()
}
return nil
}
// tagNameFunc 优先从 json tag 获取名称
func tagNameFunc(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
}
func init() {
validate = validator.New(validator.WithRequiredStructEnabled())
validate.RegisterTagNameFunc(tagNameFunc)
// 默认使用英文
en := en.New()
zh := zh.New()
uni = ut.New(en, en, zh)
defaultTrans, _ = uni.GetTranslator("en")
lo.Must0(en_translations.RegisterDefaultTranslations(validate, defaultTrans))
zhTrans, _ = uni.GetTranslator("zh")
lo.Must0(zh_translations.RegisterDefaultTranslations(validate, zhTrans))
}