Files
tyapi-server/internal/shared/validator/business.go
2025-08-18 18:18:04 +08:00

239 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package validator
import (
"fmt"
"net/url"
"regexp"
"strings"
"github.com/go-playground/validator/v10"
)
// BusinessValidator 业务验证器
type BusinessValidator struct {
validator *validator.Validate
}
// NewBusinessValidator 创建业务验证器
func NewBusinessValidator() *BusinessValidator {
validate := validator.New()
RegisterCustomValidators(validate)
return &BusinessValidator{
validator: validate,
}
}
// ValidateStruct 验证结构体
func (bv *BusinessValidator) ValidateStruct(data interface{}) error {
return bv.validator.Struct(data)
}
// ValidateField 验证单个字段
func (bv *BusinessValidator) ValidateField(field interface{}, tag string) error {
return bv.validator.Var(field, tag)
}
// 以下是具体的业务验证方法,可以在业务逻辑中直接调用
// ValidatePhone 验证手机号
func (bv *BusinessValidator) ValidatePhone(phone string) error {
if phone == "" {
return fmt.Errorf("手机号不能为空")
}
matched, _ := regexp.MatchString(`^1[3-9]\d{9}$`, phone)
if !matched {
return fmt.Errorf("手机号格式不正确")
}
return nil
}
// ValidatePassword 验证密码强度
func (bv *BusinessValidator) ValidatePassword(password string) error {
if password == "" {
return fmt.Errorf("密码不能为空")
}
if len(password) < 8 {
return fmt.Errorf("密码长度不能少于8位")
}
hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)
hasLower := regexp.MustCompile(`[a-z]`).MatchString(password)
hasDigit := regexp.MustCompile(`\d`).MatchString(password)
if !hasUpper {
return fmt.Errorf("密码必须包含大写字母")
}
if !hasLower {
return fmt.Errorf("密码必须包含小写字母")
}
if !hasDigit {
return fmt.Errorf("密码必须包含数字")
}
return nil
}
// ValidateUsername 验证用户名
func (bv *BusinessValidator) ValidateUsername(username string) error {
if username == "" {
return fmt.Errorf("用户名不能为空")
}
matched, _ := regexp.MatchString(`^[a-zA-Z][a-zA-Z0-9_]{2,19}$`, username)
if !matched {
return fmt.Errorf("用户名格式不正确只能包含字母、数字、下划线且必须以字母开头长度3-20位")
}
return nil
}
// ValidateSocialCreditCode 验证统一社会信用代码
func (bv *BusinessValidator) ValidateSocialCreditCode(code string) error {
if code == "" {
return fmt.Errorf("统一社会信用代码不能为空")
}
matched, _ := regexp.MatchString(`^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$`, code)
if !matched {
return fmt.Errorf("统一社会信用代码格式不正确必须是18位统一社会信用代码")
}
return nil
}
// ValidateIDCard 验证身份证号
func (bv *BusinessValidator) ValidateIDCard(idCard string) error {
if idCard == "" {
return fmt.Errorf("身份证号不能为空")
}
matched, _ := regexp.MatchString(`^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[\dXx]$`, idCard)
if !matched {
return fmt.Errorf("身份证号格式不正确必须是18位身份证号")
}
return nil
}
// ValidateUUID 验证UUID
func (bv *BusinessValidator) ValidateUUID(uuid string) error {
if uuid == "" {
return fmt.Errorf("UUID不能为空")
}
matched, _ := regexp.MatchString(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`, uuid)
if !matched {
return fmt.Errorf("UUID格式不正确")
}
return nil
}
// ValidateURL 验证URL
func (bv *BusinessValidator) ValidateURL(urlStr string) error {
if urlStr == "" {
return fmt.Errorf("URL不能为空")
}
_, err := url.ParseRequestURI(urlStr)
if err != nil {
return fmt.Errorf("URL格式不正确: %v", err)
}
return nil
}
// ValidateProductCode 验证产品代码
func (bv *BusinessValidator) ValidateProductCode(code string) error {
if code == "" {
return fmt.Errorf("产品代码不能为空")
}
matched, _ := regexp.MatchString(`^[a-zA-Z0-9_\-\(\)]{3,50}$`, code)
if !matched {
return fmt.Errorf("产品代码格式不正确只能包含字母、数字、下划线、连字符、中英文括号长度3-50位")
}
return nil
}
// ValidateEmail 验证邮箱
func (bv *BusinessValidator) ValidateEmail(email string) error {
if email == "" {
return fmt.Errorf("邮箱不能为空")
}
matched, _ := regexp.MatchString(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`, email)
if !matched {
return fmt.Errorf("邮箱格式不正确")
}
return nil
}
// ValidateSortOrder 验证排序方向
func (bv *BusinessValidator) ValidateSortOrder(sortOrder string) error {
if sortOrder == "" {
return nil // 允许为空
}
if sortOrder != "asc" && sortOrder != "desc" {
return fmt.Errorf("排序方向必须是 asc 或 desc")
}
return nil
}
// ValidatePrice 验证价格
func (bv *BusinessValidator) ValidatePrice(price float64) error {
if price < 0 {
return fmt.Errorf("价格不能为负数")
}
return nil
}
// ValidateStringLength 验证字符串长度
func (bv *BusinessValidator) ValidateStringLength(str string, fieldName string, min, max int) error {
length := len(strings.TrimSpace(str))
if min > 0 && length < min {
return fmt.Errorf("%s长度不能少于%d位", fieldName, min)
}
if max > 0 && length > max {
return fmt.Errorf("%s长度不能超过%d位", fieldName, max)
}
return nil
}
// ValidateRequired 验证必填字段
func (bv *BusinessValidator) ValidateRequired(value interface{}, fieldName string) error {
if value == nil {
return fmt.Errorf("%s不能为空", fieldName)
}
switch v := value.(type) {
case string:
if strings.TrimSpace(v) == "" {
return fmt.Errorf("%s不能为空", fieldName)
}
case *string:
if v == nil || strings.TrimSpace(*v) == "" {
return fmt.Errorf("%s不能为空", fieldName)
}
}
return nil
}
// ValidateRange 验证数值范围
func (bv *BusinessValidator) ValidateRange(value float64, fieldName string, min, max float64) error {
if value < min {
return fmt.Errorf("%s不能小于%v", fieldName, min)
}
if value > max {
return fmt.Errorf("%s不能大于%v", fieldName, max)
}
return nil
}
// ValidateSliceNotEmpty 验证切片不为空
func (bv *BusinessValidator) ValidateSliceNotEmpty(slice interface{}, fieldName string) error {
if slice == nil {
return fmt.Errorf("%s不能为空", fieldName)
}
switch v := slice.(type) {
case []string:
if len(v) == 0 {
return fmt.Errorf("%s不能为空", fieldName)
}
case []int:
if len(v) == 0 {
return fmt.Errorf("%s不能为空", fieldName)
}
}
return nil
}