123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- package check
- import (
- "fmt"
- "github.com/go-playground/locales/zh"
- ut "github.com/go-playground/universal-translator"
- "github.com/go-playground/validator/v10"
- zhTranslations "github.com/go-playground/validator/v10/translations/zh"
- "github.com/pkg/errors"
- "strings"
- "time"
- )
- const (
- timeNotZeroTag = "timenotzero"
- )
- var validate = validator.New(validator.WithRequiredStructEnabled())
- var translator ut.Translator
- func init() {
- validate.SetTagName("check")
- zhLocale := zh.New()
- zhTranslator := ut.New(zhLocale)
- trans, _ := zhTranslator.GetTranslator("zh")
- err := zhTranslations.RegisterDefaultTranslations(validate, trans)
- if err != nil {
- panic(err)
- }
- translator = trans
- registerCustomTags()
- }
- func registerCustomTags() {
- if err := validate.RegisterValidation(timeNotZeroTag, func(fl validator.FieldLevel) bool {
- fieldValue := fl.Field()
- if !fieldValue.IsValid() {
- return true
- }
- switch value := fieldValue.Interface().(type) {
- case time.Time:
- return !value.IsZero()
- case *time.Time:
- if value != nil {
- return true
- }
- return !value.IsZero()
- default:
- return false
- }
- }); err != nil {
- fmt.Println(err)
- return
- }
- }
- func Struct(obj any, fieldNameMap map[string]string) Result {
- return newResult(validate.Struct(obj), nil, fieldNameMap)
- }
- type Result struct {
- err error
- translatedErrs map[string]string
- fieldNameMap map[string]string
- }
- func newResult(err error, translatedErrs map[string]string, fieldNameMap map[string]string) Result {
- return Result{
- err: err,
- translatedErrs: translatedErrs,
- fieldNameMap: fieldNameMap,
- }
- }
- func (result Result) IsError() bool {
- return result.err != nil
- }
- func (result Result) CheckFields(fieldNames ...string) error {
- if len(fieldNames) == 0 {
- return nil
- }
- return result.checkFields(fieldNames...)
- }
- func (result Result) CheckStruct() error {
- return result.checkStruct()
- }
- func (result Result) checkFields(fieldNames ...string) error {
- if result.err == nil {
- return nil
- }
- translatedResult := result.translation()
- if translatedResult.translatedErrs == nil || len(translatedResult.translatedErrs) == 0 {
- return translatedResult.err
- }
- errMsg := strings.Builder{}
- for _, fieldName := range fieldNames {
- for errStructFieldName, translatedErr := range translatedResult.translatedErrs {
- errStructFieldNameParts := strings.Split(errStructFieldName, ".")
- errFieldName := errStructFieldNameParts[len(errStructFieldNameParts)-1]
- if fieldName == errFieldName {
- if translatedResult.fieldNameMap != nil {
- fieldCNName, ok := translatedResult.fieldNameMap[fieldName]
- if ok {
- translatedErr = strings.ReplaceAll(translatedErr, fieldName, fieldCNName)
- }
- }
- errMsg.WriteString(translatedErr + "\n")
- }
- }
- }
- if errMsg.Len() > 0 {
- return errors.New(errMsg.String())
- }
- return nil
- }
- func (result Result) checkStruct() error {
- if result.err == nil {
- return nil
- }
- translatedResult := result.translation()
- if translatedResult.translatedErrs == nil || len(translatedResult.translatedErrs) == 0 {
- return translatedResult.err
- }
- errMsg := strings.Builder{}
- for errStructFieldName, translatedErr := range translatedResult.translatedErrs {
- if translatedResult.fieldNameMap != nil {
- errStructFieldNameParts := strings.Split(errStructFieldName, ".")
- errFieldName := errStructFieldNameParts[len(errStructFieldNameParts)-1]
- fieldCNName, ok := translatedResult.fieldNameMap[errFieldName]
- if ok {
- translatedErr = strings.ReplaceAll(translatedErr, errFieldName, fieldCNName)
- }
- }
- errMsg.WriteString(translatedErr + "\n")
- }
- if errMsg.Len() > 0 {
- return errors.New(errMsg.String())
- }
- return nil
- }
- func (result Result) translation() Result {
- if result.err == nil {
- return result
- }
- if result.translatedErrs != nil {
- return result
- }
- var validationErrors validator.ValidationErrors
- if !errors.As(result.err, &validationErrors) {
- return result
- }
- translatedErrors := validationErrors.Translate(translator)
- for _, validationError := range validationErrors {
- if validationError.Tag() == timeNotZeroTag {
- translatedErrors[validationError.Field()] = validationError.Field() + "使用了时间零值"
- }
- }
- return newResult(result.err, translatedErrors, result.fieldNameMap)
- }
|