Files
full/module/base/mgt/internal/libs/validator.go

124 lines
3.2 KiB
Go
Raw Normal View History

package libs
import (
"fmt"
"strings"
"git.apinb.com/bsm-sdk/core/errcode"
"github.com/go-playground/validator/v10"
)
var (
validate *validator.Validate
)
func init() {
validate = validator.New()
// 注册自定义验证规则
registerCustomValidators()
}
// registerCustomValidators 注册自定义验证器
func registerCustomValidators() {
// 注册手机号验证
validate.RegisterValidation("phone", validatePhone)
// 注册邮箱验证
validate.RegisterValidation("email_format", validateEmail)
}
// validatePhone 验证手机号11位数字以1开头
func validatePhone(fl validator.FieldLevel) bool {
phone := fl.Field().String()
// 空字符串由omitempty或required处理这里返回true
if phone == "" {
return true
}
if len(phone) != 11 {
return false
}
if len(phone) > 0 && phone[0] != '1' {
return false
}
for _, char := range phone {
if char < '0' || char > '9' {
return false
}
}
return true
}
// validateEmail 验证邮箱格式(简单的邮箱格式验证)
func validateEmail(fl validator.FieldLevel) bool {
email := fl.Field().String()
if email == "" {
return true // 允许为空使用omitempty处理
}
parts := strings.Split(email, "@")
if len(parts) != 2 {
return false
}
if len(parts[0]) == 0 || len(parts[1]) == 0 {
return false
}
if !strings.Contains(parts[1], ".") {
return false
}
return true
}
// ValidateStruct 验证结构体,返回格式化的错误信息
func ValidateStruct(s interface{}) error {
if err := validate.Struct(s); err != nil {
return formatValidationError(err)
}
return nil
}
// formatValidationError 格式化验证错误信息
func formatValidationError(err error) error {
if validationErrors, ok := err.(validator.ValidationErrors); ok {
var errMsg strings.Builder
errMsg.WriteString("参数验证失败: ")
for i, validationError := range validationErrors {
if i > 0 {
errMsg.WriteString("; ")
}
errMsg.WriteString(getFieldErrorMsg(validationError))
}
// 返回ErrInvalidArgument错误
return errcode.ErrInvalidArgument
}
return errcode.ErrInvalidArgument
}
// getFieldErrorMsg 获取字段错误信息
func getFieldErrorMsg(fe validator.FieldError) string {
field := fe.Field()
tag := fe.Tag()
switch tag {
case "required":
return fmt.Sprintf("%s 字段为必填项", field)
case "min":
return fmt.Sprintf("%s 字段长度不能小于 %s", field, fe.Param())
case "max":
return fmt.Sprintf("%s 字段长度不能大于 %s", field, fe.Param())
case "len":
return fmt.Sprintf("%s 字段长度必须为 %s", field, fe.Param())
case "email_format":
return fmt.Sprintf("%s 字段邮箱格式不正确", field)
case "phone":
return fmt.Sprintf("%s 字段手机号格式不正确应为11位数字", field)
case "gte":
return fmt.Sprintf("%s 字段值必须大于或等于 %s", field, fe.Param())
case "lte":
return fmt.Sprintf("%s 字段值必须小于或等于 %s", field, fe.Param())
case "gt":
return fmt.Sprintf("%s 字段值必须大于 %s", field, fe.Param())
case "lt":
return fmt.Sprintf("%s 字段值必须小于 %s", field, fe.Param())
default:
return fmt.Sprintf("%s 字段验证失败 (%s)", field, tag)
}
}