This commit is contained in:
2025-08-18 14:13:16 +08:00
parent 9e6248efb2
commit 133e8e7e5a
7 changed files with 285 additions and 29 deletions

View File

@@ -25,9 +25,31 @@ func RegisterCustomValidators(validate *validator.Validate) {
// 统一社会信用代码验证器
validate.RegisterValidation("social_credit_code", validateSocialCreditCode)
// 身份证号验证器
// 姓名验证器不能为空字符串长度1-50字符
validate.RegisterValidation("validName", validateName)
// 身份证号验证器(兼容两种标签)
validate.RegisterValidation("validIDCard", validateIDCard)
validate.RegisterValidation("id_card", validateIDCard)
// 统一社会信用代码验证器
validate.RegisterValidation("validUSCI", validateUSCI)
// 手机号验证器
validate.RegisterValidation("validMobileNo", validateMobileNo)
// 手机类型验证器
validate.RegisterValidation("validMobileType", validateMobileType)
// 日期验证器
validate.RegisterValidation("validDate", validateDate)
// 时间范围验证器
validate.RegisterValidation("validTimeRange", validateTimeRange)
// 银行卡验证器
validate.RegisterValidation("validBankCard", validateBankCard)
// 价格验证器(非负数)
validate.RegisterValidation("price", validatePrice)
@@ -52,6 +74,9 @@ func RegisterCustomValidators(validate *validator.Validate) {
// IP地址验证器
validate.RegisterValidation("ip", validateIP)
// 非空字符串验证器(不能为空字符串或只包含空格)
validate.RegisterValidation("notEmpty", validateNotEmpty)
// 授权日期验证器
validate.RegisterValidation("auth_date", validateAuthDate)
}
@@ -156,6 +181,20 @@ func validateIP(fl validator.FieldLevel) bool {
pattern := `^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`
matched, _ := regexp.MatchString(pattern, ip)
return matched
}
// validateName 姓名验证器
func validateName(fl validator.FieldLevel) bool {
name := fl.Field().String()
// 去除首尾空格后检查长度
trimmedName := strings.TrimSpace(name)
if len(trimmedName) < 1 || len(trimmedName) > 50 {
return false
}
// 姓名不能只包含空格或特殊字符
// 必须包含至少一个中文字符或英文字母
hasValidChar := regexp.MustCompile(`[\p{Han}a-zA-Z]`).MatchString(trimmedName)
return hasValidChar
}
// validateAuthDate 授权日期验证器
@@ -236,4 +275,127 @@ func parseYYYYMMDD(dateStr string) (time.Time, error) {
}
return date, nil
}
// validateUSCI 统一社会信用代码验证器
func validateUSCI(fl validator.FieldLevel) bool {
usci := fl.Field().String()
// 统一社会信用代码格式18位由数字和大写字母组成
// 格式1位登记管理部门代码 + 1位机构类别代码 + 6位登记管理机关行政区划码 + 9位主体标识码 + 1位校验码
matched, _ := regexp.MatchString(`^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$`, usci)
return matched
}
// validateMobileNo 手机号验证器
func validateMobileNo(fl validator.FieldLevel) bool {
mobile := fl.Field().String()
// 中国手机号格式1开头第二位是3-9总共11位数字
matched, _ := regexp.MatchString(`^1[3-9]\d{9}$`, mobile)
return matched
}
// validateMobileType 手机类型验证器
func validateMobileType(fl validator.FieldLevel) bool {
mobileType := fl.Field().String()
// 手机类型:移动、联通、电信等
validTypes := []string{"移动", "联通", "电信", "广电", "虚拟运营商"}
for _, validType := range validTypes {
if mobileType == validType {
return true
}
}
return false
}
// validateDate 日期验证器
func validateDate(fl validator.FieldLevel) bool {
dateStr := fl.Field().String()
// 检查日期格式YYYY-MM-DD
matched, _ := regexp.MatchString(`^\d{4}-\d{2}-\d{2}$`, dateStr)
if !matched {
return false
}
// 尝试解析日期
_, err := time.Parse("2006-01-02", dateStr)
return err == nil
}
// validateTimeRange 时间范围验证器
func validateTimeRange(fl validator.FieldLevel) bool {
timeRange := fl.Field().String()
if timeRange == "" {
return true // 空值由omitempty标签处理
}
// 时间范围格式HH:MM-HH:MM
parts := strings.Split(timeRange, "-")
if len(parts) != 2 {
return false
}
startTime := parts[0]
endTime := parts[1]
// 检查时间格式HH:MM
timePattern := `^([01]?[0-9]|2[0-3]):[0-5][0-9]$`
startMatched, _ := regexp.MatchString(timePattern, startTime)
endMatched, _ := regexp.MatchString(timePattern, endTime)
if !startMatched || !endMatched {
return false
}
// 检查开始时间不能晚于结束时间
start, _ := time.Parse("15:04", startTime)
end, _ := time.Parse("15:04", endTime)
return start.Before(end) || start.Equal(end)
}
// validateNotEmpty 非空字符串验证器
func validateNotEmpty(fl validator.FieldLevel) bool {
value := fl.Field().String()
// 去除首尾空格后检查是否为空
trimmedValue := strings.TrimSpace(value)
return len(trimmedValue) > 0
}
// validateBankCard 银行卡验证器
func validateBankCard(fl validator.FieldLevel) bool {
bankCard := fl.Field().String()
// 银行卡号格式13-19位数字
matched, _ := regexp.MatchString(`^\d{13,19}$`, bankCard)
if !matched {
return false
}
// 使用Luhn算法验证银行卡号
return validateLuhn(bankCard)
}
// validateLuhn Luhn算法验证银行卡号
func validateLuhn(cardNumber string) bool {
sum := 0
alternate := false
// 从右到左遍历
for i := len(cardNumber) - 1; i >= 0; i-- {
digit, err := strconv.Atoi(string(cardNumber[i]))
if err != nil {
return false
}
if alternate {
digit *= 2
if digit > 9 {
digit = digit%10 + digit/10
}
}
sum += digit
alternate = !alternate
}
return sum%10 == 0
}