Files
gjs 0dbec86c00
CI / changes (push) Successful in 4s
CI / docker-bff (push) Failing after 2s
CI / docker-product (push) Failing after 2s
CI / docker-admin (push) Failing after 2s
CI / docker-user (push) Failing after 2s
add validator model
2026-08-21 10:53:31 +08:00

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)
}