89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package validate
|
|
|
|
import (
|
|
"fmt"
|
|
"lone-services/pkg/utils"
|
|
"reflect"
|
|
"regexp"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
)
|
|
|
|
// ValidatorMessages 自定义错误消息
|
|
type ValidatorMessages map[string]string
|
|
|
|
// IValidator 业务结构体实现该接口
|
|
type IValidator interface {
|
|
GetMessage() ValidatorMessages
|
|
}
|
|
|
|
var v *validator.Validate
|
|
var mobileReg = regexp.MustCompile(`^1[3-9]\d{9}$`)
|
|
|
|
func init() {
|
|
v = validator.New()
|
|
|
|
_ = v.RegisterValidation("mobile", func(fl validator.FieldLevel) bool {
|
|
return mobileReg.MatchString(fl.Field().String())
|
|
})
|
|
}
|
|
|
|
// CopySameField 反射自动拷贝同名字段:src(proto入参) → dst(校验model结构体指针)
|
|
// src: proto message对象,传值in
|
|
// dst: model校验结构体指针 &model.AdminGroupValidator{}
|
|
func CopySameField(src interface{}, dst interface{}) {
|
|
srcVal := reflect.ValueOf(src)
|
|
dstVal := reflect.ValueOf(dst).Elem()
|
|
|
|
// 如果src是指针,取element
|
|
if srcVal.Kind() == reflect.Ptr {
|
|
srcVal = srcVal.Elem()
|
|
}
|
|
|
|
for i := 0; i < srcVal.NumField(); i++ {
|
|
srcField := srcVal.Field(i)
|
|
fieldName := srcVal.Type().Field(i).Name
|
|
|
|
// 查找dst中同名的字段
|
|
dstField := dstVal.FieldByName(fieldName)
|
|
if !dstField.IsValid() || !dstField.CanSet() {
|
|
continue
|
|
}
|
|
// 类型相同才赋值
|
|
if srcField.Type() == dstField.Type() {
|
|
dstField.Set(srcField)
|
|
}
|
|
}
|
|
}
|
|
|
|
// ValidateStruct 校验,返回 *admin.Response
|
|
func ValidateStruct(obj IValidator) string {
|
|
err := v.Struct(obj)
|
|
if err == nil {
|
|
return utils.StringEmpty
|
|
}
|
|
|
|
customMsg := obj.GetMessage()
|
|
var errMsg string
|
|
if ves, ok := err.(validator.ValidationErrors); ok {
|
|
ve := ves[0]
|
|
key := fmt.Sprintf("%s.%s", ve.Field(), ve.Tag())
|
|
if msg, exist := customMsg[key]; exist {
|
|
errMsg = msg
|
|
} else {
|
|
errMsg = fmt.Sprintf("%s校验失败:%s", ve.Field(), ve.Tag())
|
|
}
|
|
} else {
|
|
errMsg = err.Error()
|
|
}
|
|
return errMsg
|
|
}
|
|
|
|
// ValidateFromProto 一步到位:自动拷贝proto同名字段 + 校验
|
|
// src: proto请求 in (*admin.XXXRequest)
|
|
// dst: model校验结构体实例指针 &model.AdminGroupValidator{}
|
|
func ValidateFromProto(src interface{}, dst IValidator) string {
|
|
CopySameField(src, dst)
|
|
return ValidateStruct(dst)
|
|
}
|