add: validator

This commit is contained in:
vilet.yy 2021-04-06 17:55:37 +08:00
parent 5d0b7b1009
commit d0cb37ec3e
7 changed files with 83 additions and 79 deletions

View File

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/viletyy/potato/global" "github.com/viletyy/potato/global"
"github.com/viletyy/potato/models/basic" "github.com/viletyy/potato/models/basic"
"github.com/viletyy/potato/utils" "github.com/viletyy/potato/utils"
@ -11,7 +12,7 @@ import (
) )
type CreateVendorRequest struct { type CreateVendorRequest struct {
Name string `json:"name" binding:"required"` Name string `json:"name" validate:"required"`
Uuid int `json:"uuid"` Uuid int `json:"uuid"`
} }
@ -57,11 +58,19 @@ func GetVendors(c *gin.Context) {
func CreateVendor(c *gin.Context) { func CreateVendor(c *gin.Context) {
var vendor CreateVendorRequest var vendor CreateVendorRequest
if err := c.ShouldBindJSON(&vendor); err != nil { if err := c.ShouldBindJSON(&vendor); err != nil {
c.JSON(http.StatusBadRequest, gin.H{ if errs, ok := err.(validator.ValidationErrors); !ok {
"error": err.Error(), c.JSON(http.StatusBadRequest, gin.H{
}) "msg": err.Error(),
return })
return
} else {
c.JSON(http.StatusBadRequest, gin.H{
"msg": errs.Translate(utils.Trans),
})
return
}
} }
if exist := basic.ExistVendorByName(vendor.Name); exist { if exist := basic.ExistVendorByName(vendor.Name); exist {
global.GO_LOG.Error("该系统厂商名称已存在!") global.GO_LOG.Error("该系统厂商名称已存在!")
utils.FailWithMessage("该系统厂商名称已存在", c) utils.FailWithMessage("该系统厂商名称已存在", c)

View File

@ -1,7 +1,7 @@
/* /*
* @Date: 2021-03-21 19:54:57 * @Date: 2021-03-21 19:54:57
* @LastEditors: viletyy * @LastEditors: viletyy
* @LastEditTime: 2021-03-24 10:08:27 * @LastEditTime: 2021-04-06 17:02:38
* @FilePath: /potato/controller/api/v1/user.go * @FilePath: /potato/controller/api/v1/user.go
*/ */
package v1 package v1
@ -23,13 +23,13 @@ type AuthResponse struct {
} }
type AuthRequest struct { type AuthRequest struct {
Username string `json:"username" binding:"required"` Username string `json:"username" validate:"required"`
Password string `json:"password" binding:"required,gte=6` Password string `json:"password" validate:"required,gte=6`
} }
type RegisterRequest struct { type RegisterRequest struct {
Username string `json:"username" binding:"required"` Username string `json:"username" validate:"required"`
Password string `json:"password" binding:"required,gte=6` Password string `json:"password" validate:"required,gte=6`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
} }

4
go.mod
View File

@ -7,6 +7,9 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify v1.4.9
github.com/gin-gonic/gin v1.6.3 github.com/gin-gonic/gin v1.6.3
github.com/go-playground/locales v0.13.0
github.com/go-playground/universal-translator v0.17.0
github.com/go-playground/validator/v10 v10.4.2
github.com/go-redis/redis v6.15.9+incompatible github.com/go-redis/redis v6.15.9+incompatible
github.com/google/uuid v1.2.0 github.com/google/uuid v1.2.0
github.com/jinzhu/gorm v1.9.16 github.com/jinzhu/gorm v1.9.16
@ -18,5 +21,4 @@ require (
github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/gin-swagger v1.3.0
github.com/swaggo/swag v1.7.0 github.com/swaggo/swag v1.7.0
go.uber.org/zap v1.15.0 go.uber.org/zap v1.15.0
gopkg.in/go-playground/validator.v9 v9.31.0
) )

View File

@ -1,7 +1,7 @@
/* /*
* @Date: 2021-03-22 17:03:27 * @Date: 2021-03-22 17:03:27
* @LastEditors: viletyy * @LastEditors: viletyy
* @LastEditTime: 2021-03-23 10:23:12 * @LastEditTime: 2021-04-06 17:47:11
* @FilePath: /potato/initialize/server.go * @FilePath: /potato/initialize/server.go
*/ */
package initialize package initialize
@ -14,15 +14,16 @@ import (
"os/signal" "os/signal"
"time" "time"
"github.com/gin-gonic/gin/binding"
"github.com/viletyy/potato/global" "github.com/viletyy/potato/global"
"github.com/viletyy/potato/routers" "github.com/viletyy/potato/routers"
"github.com/viletyy/potato/utils" "github.com/viletyy/potato/utils"
) )
func RunServer() { func RunServer() {
binding.Validator = new(utils.DefaultValidator) if err := utils.InitTrans("zh"); err != nil {
fmt.Printf("init trans failed, err:%v\n", err)
return
}
router := routers.InitRouter() router := routers.InitRouter()
server := &http.Server{ server := &http.Server{
Addr: fmt.Sprintf(":%d", global.GO_CONFIG.Server.HttpPort), Addr: fmt.Sprintf(":%d", global.GO_CONFIG.Server.HttpPort),

View File

@ -1,23 +0,0 @@
package e
const (
SUCCESS = 200
ERROR = 500
INVALID_PARAMS = 400
ERROR_EXIST_USER = 10001
ERROR_NOT_EXIST_USER = 10002
ERROR_EXIST_VENDOR = 10011
ERROR_NOT_EXIST_VENDOR = 10012
ERROR_EXIST_BUSINESS = 10021
ERROR_NOT_EXIST_BUSINESS = 10022
ERROR_EXIST_META_DATABASE = 10031
ERROR_NOT_EXIST_META_DATABASE = 10032
ERROR_EXIST_META_TABLE = 10041
ERROR_NOT_EXIST_META_TABLE = 10042
ERROR_AUTH_CHECK_TOKEN_FAIL = 20001
ERROR_AUTH_CHECK_TOKEN_TIMEOUT = 20002
ERROR_AUTH_TOKEN = 20003
ERROR_AUTH = 20004
)

View File

@ -1,32 +0,0 @@
package e
var MsgFlags = map[int]string {
SUCCESS : "ok",
ERROR : "fail",
INVALID_PARAMS : "请求参数错误",
ERROR_EXIST_USER : "已存在该用户",
ERROR_NOT_EXIST_USER : "该用户不存在",
ERROR_EXIST_VENDOR : "已存在该系统厂商",
ERROR_NOT_EXIST_VENDOR : "该系统厂商不存在",
ERROR_EXIST_BUSINESS : "已存在该业务系统",
ERROR_NOT_EXIST_BUSINESS : "该业务系统不存在",
ERROR_EXIST_META_DATABASE : "已存在该数据源",
ERROR_NOT_EXIST_META_DATABASE : "该数据源不存在",
ERROR_EXIST_META_TABLE : "已存在该元数据",
ERROR_NOT_EXIST_META_TABLE : "该元数据不存在",
ERROR_AUTH_CHECK_TOKEN_FAIL : "Token鉴权失败",
ERROR_AUTH_CHECK_TOKEN_TIMEOUT : "Token已超时",
ERROR_AUTH_TOKEN : "Token生成失败",
ERROR_AUTH : "Token错误",
}
func GetMsg(code int) string {
msg, ok := MsgFlags[code]
if ok {
return msg
}
return MsgFlags[ERROR]
}

View File

@ -1,17 +1,23 @@
/* /*
* @Date: 2021-03-22 23:17:52 * @Date: 2021-03-22 23:17:52
* @LastEditors: viletyy * @LastEditors: viletyy
* @LastEditTime: 2021-03-22 23:20:43 * @LastEditTime: 2021-04-06 17:46:53
* @FilePath: /potato/utils/validator.go * @FilePath: /potato/utils/validator.go
*/ */
package utils package utils
import ( import (
"fmt"
"reflect" "reflect"
"sync" "sync"
"github.com/gin-gonic/gin/binding" "github.com/gin-gonic/gin/binding"
"gopkg.in/go-playground/validator.v9" "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"
) )
type DefaultValidator struct { type DefaultValidator struct {
@ -21,20 +27,62 @@ type DefaultValidator struct {
var _ binding.StructValidator = &DefaultValidator{} var _ binding.StructValidator = &DefaultValidator{}
func (v *DefaultValidator) ValidateStruct(obj interface{}) error { // 定义一个全局翻译器T
var Trans ut.Translator
// InitTrans 初始化翻译器
func InitTrans(locale string) (err error) {
binding.Validator = new(DefaultValidator)
// 修改gin框架中的Validator引擎属性实现自定制
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
zhT := zh.New() // 中文翻译器
enT := en.New() // 英文翻译器
// 第一个参数是备用fallback的语言环境
// 后面的参数是应该支持的语言环境(支持多个)
// uni := ut.New(zhT, zhT) 也是可以的
uni := ut.New(enT, zhT, enT)
// locale 通常取决于 http 请求头的 'Accept-Language'
var ok bool
// 也可以使用 uni.FindTranslator(...) 传入多个locale进行查找
Trans, ok = uni.GetTranslator(locale)
if !ok {
return fmt.Errorf("uni.GetTranslator(%s) failed", locale)
}
// 注册翻译器
switch locale {
case "en":
err = enTranslations.RegisterDefaultTranslations(v, Trans)
case "zh":
err = zhTranslations.RegisterDefaultTranslations(v, Trans)
default:
err = enTranslations.RegisterDefaultTranslations(v, Trans)
}
return
}
return
}
// ValidateStruct 如果接收到的类型是一个结构体或指向结构体的指针,则执行验证。
func (v *DefaultValidator) ValidateStruct(obj interface{}) error {
if kindOfData(obj) == reflect.Struct { if kindOfData(obj) == reflect.Struct {
v.lazyinit() v.lazyinit()
//如果传递不合规则的值则返回InvalidValidationError否则返回nil。
///如果返回err != nil可通过err.(validator.ValidationErrors)来访问错误数组。
if err := v.validate.Struct(obj); err != nil { if err := v.validate.Struct(obj); err != nil {
return error(err) return err
} }
} }
return nil return nil
} }
// Engine 返回支持`StructValidator`实现的底层验证引擎
func (v *DefaultValidator) Engine() interface{} { func (v *DefaultValidator) Engine() interface{} {
v.lazyinit() v.lazyinit()
return v.validate return v.validate
@ -43,14 +91,13 @@ func (v *DefaultValidator) Engine() interface{} {
func (v *DefaultValidator) lazyinit() { func (v *DefaultValidator) lazyinit() {
v.once.Do(func() { v.once.Do(func() {
v.validate = validator.New() v.validate = validator.New()
v.validate.SetTagName("binding") v.validate.SetTagName("validate")
// //v8版本v8版本使用"binding"
// add any custom validations etc. here // v.validate.SetTagName("binding")
}) })
} }
func kindOfData(data interface{}) reflect.Kind { func kindOfData(data interface{}) reflect.Kind {
value := reflect.ValueOf(data) value := reflect.ValueOf(data)
valueType := value.Kind() valueType := value.Kind()