Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validator for data verification and custom Chinese translator #148

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions validator/govalidator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
### Quick Start

## Prerequesites:

- Install `go-zero`:

```shell
go get -u github.com/zeromicro/go-zero
```



+ Download the module:

```shell
go get -u github.com/zeromicro/zero-contrib/validator/govalidator
```

## For example:

```go
func (l *RegisterLogic) Register(in *user.RegisterReq) (*user.CommonReply, error) {
// todo: add your logic here and delete this line
....
err := govalidator.DefaultGetValidParams(l.ctx, in)
if err != nil {
return nil, errorx.NewDefaultError(fmt.Sprintf("validate校验错误: %v", err))
}
.....

}

```

16 changes: 16 additions & 0 deletions validator/govalidator/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module govalidator

go 1.20

require (
github.com/go-playground/locales v0.14.1
github.com/go-playground/universal-translator v0.18.1
github.com/go-playground/validator/v10 v10.13.0
)

require (
github.com/leodido/go-urn v1.2.3 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
)
31 changes: 31 additions & 0 deletions validator/govalidator/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA=
github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
115 changes: 115 additions & 0 deletions validator/govalidator/validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package govalidator

import (
"context"
"errors"
"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"
enTranslations "github.com/go-playground/validator/v10/translations/en"
zhTranslations "github.com/go-playground/validator/v10/translations/zh"
"reflect"
"regexp"
"strings"
)

const (
ValidatorKey = "ValidatorKey"
TranslatorKey = "TranslatorKey"
locale = "chinese"
)

func TransInit(ctx context.Context) context.Context {
// Set the supported language
chinese := zh.New()
english := en.New()
// Set up an internationalized translator
uni := ut.New(chinese, chinese, english)
// Set up validators
val := validator.New()
// Take the translator instance as an argument
trans, _ := uni.GetTranslator(locale)
// Register the translator with validatorfw
switch locale {
case "chinese":
zhTranslations.RegisterDefaultTranslations(val, trans)
// Register a custom method to get a tag with fld.Tag.Get("comment")
val.RegisterTagNameFunc(func(fld reflect.StructField) string {
return fld.Tag.Get("comment")
})
val.RegisterValidation("phone", func(fl validator.FieldLevel) bool {
phone := fl.Field().String()
// Validate phone number with a regular expression
pattern := `^1[3456789]\d{9}$`
matched, _ := regexp.MatchString(pattern, phone)
return matched
})
zhTranslations.RegisterDefaultTranslations(val, trans)
val.RegisterTranslation("phone", trans, func(ut ut.Translator) error {
return ut.Add("phone", "{0}格式不正确,必须为手机号码", true)
}, func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T("phone", fe.Field())
return t
})

case "english":
enTranslations.RegisterDefaultTranslations(val, trans)
val.RegisterTagNameFunc(func(fld reflect.StructField) string {
return fld.Tag.Get("en_comment")
})
val.RegisterValidation("phone", func(fl validator.FieldLevel) bool {
phone := fl.Field().String()
// Validate phone number with a regular expression
pattern := `^1[3456789]\d{9}$`
matched, _ := regexp.MatchString(pattern, phone)
return matched
})
zhTranslations.RegisterDefaultTranslations(val, trans)
val.RegisterTranslation("phone", trans, func(ut ut.Translator) error {
return ut.Add("phone", "The {0} format is incorrect;it must be a cell phone number", true)
}, func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T("phone", fe.Field())
return t
})
}

ctx = context.WithValue(ctx, ValidatorKey, val)
ctx = context.WithValue(ctx, TranslatorKey, trans)
return ctx
}

func DefaultGetValidParams(ctx context.Context, params interface{}) error {
ctx = TransInit(ctx)
err := validate(ctx, params)
if err != nil {
return err
}
return nil
}

func validate(ctx context.Context, params interface{}) error {
// Get the validatorfw
val, ok := ctx.Value(ValidatorKey).(*validator.Validate)
if !ok {
return errors.New("Validator not found in context")
}

// Get the translator
tran, ok := ctx.Value(TranslatorKey).(ut.Translator)
if !ok {
return errors.New("Translator not found in context")
}
err := val.Struct(params)
// If the data validation fails, output all err in a slice
if err != nil {
errs := err.(validator.ValidationErrors)
sliceErrs := []string{}
for _, e := range errs {
// use the validatorfw. ValidationErrors types in the `Translate` method for translation
sliceErrs = append(sliceErrs, e.Translate(tran))
}
return errors.New(strings.Join(sliceErrs, ","))
}
return nil
}
29 changes: 29 additions & 0 deletions validator/govalidator/validtor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package govalidator

import (
"context"
"fmt"
"testing"
)

type User struct {
UserId int64
PassWord string `validate:"min=6,max=20"`
UserNick string `validate:"min=4,max=15"`
UserPhone string `validate:"phone"`
UserEmail string `validate:"email"`
}

func TestValid(t *testing.T) {
user := User{
UserId: 1,
PassWord: "123",
UserNick: "fjwenfjwkfnkwnefjwnfwjkf",
UserPhone: "12g2f",
UserEmail: "lijfwf",
}
err := DefaultGetValidParams(context.Background(), user)
if err != nil {
fmt.Println(err) // PassWord长度必须至少为6个字符,UserNick长度不能超过15个字符,UserPhone格式不正确,必须为手机号码,UserEmail必须是一个有效的邮箱
}
}