add new api
This commit is contained in:
@@ -15,70 +15,79 @@ import (
|
||||
func RegisterCustomValidators(validate *validator.Validate) {
|
||||
// 手机号验证器
|
||||
validate.RegisterValidation("phone", validatePhone)
|
||||
|
||||
|
||||
// 用户名验证器(字母开头,允许字母数字下划线,3-20位)
|
||||
validate.RegisterValidation("username", validateUsername)
|
||||
|
||||
|
||||
// 强密码验证器(至少8位,包含大小写字母和数字)
|
||||
validate.RegisterValidation("strong_password", validateStrongPassword)
|
||||
|
||||
|
||||
// 统一社会信用代码验证器
|
||||
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)
|
||||
|
||||
|
||||
// 排序方向验证器
|
||||
validate.RegisterValidation("sort_order", validateSortOrder)
|
||||
|
||||
|
||||
// 产品代码验证器(字母数字下划线连字符,3-50位)
|
||||
validate.RegisterValidation("product_code", validateProductCode)
|
||||
|
||||
|
||||
// UUID验证器
|
||||
validate.RegisterValidation("uuid", validateUUID)
|
||||
|
||||
|
||||
// URL验证器
|
||||
validate.RegisterValidation("url", validateURL)
|
||||
|
||||
|
||||
// 企业邮箱验证器
|
||||
validate.RegisterValidation("enterprise_email", validateEnterpriseEmail)
|
||||
|
||||
|
||||
// 企业地址验证器
|
||||
validate.RegisterValidation("enterprise_address", validateEnterpriseAddress)
|
||||
|
||||
|
||||
// IP地址验证器
|
||||
validate.RegisterValidation("ip", validateIP)
|
||||
|
||||
|
||||
// 非空字符串验证器(不能为空字符串或只包含空格)
|
||||
validate.RegisterValidation("notEmpty", validateNotEmpty)
|
||||
|
||||
|
||||
// 授权日期验证器
|
||||
validate.RegisterValidation("auth_date", validateAuthDate)
|
||||
|
||||
// 授权书URL验证器
|
||||
validate.RegisterValidation("authorization_url", validateAuthorizationURL)
|
||||
|
||||
// 唯一标识验证器(小于等于32位字符串)
|
||||
validate.RegisterValidation("validUniqueID", validateUniqueID)
|
||||
|
||||
// 回调地址验证器
|
||||
validate.RegisterValidation("validReturnURL", validateReturnURL)
|
||||
}
|
||||
|
||||
// validatePhone 手机号验证
|
||||
@@ -195,7 +204,7 @@ func validateName(fl validator.FieldLevel) bool {
|
||||
// 必须包含至少一个中文字符或英文字母
|
||||
hasValidChar := regexp.MustCompile(`[\p{Han}a-zA-Z]`).MatchString(trimmedName)
|
||||
return hasValidChar
|
||||
}
|
||||
}
|
||||
|
||||
// validateAuthDate 授权日期验证器
|
||||
// 格式:YYYYMMDD-YYYYMMDD,之前的日期范围必须包括今天
|
||||
@@ -267,7 +276,7 @@ func parseYYYYMMDD(dateStr string) (time.Time, error) {
|
||||
|
||||
// 验证日期有效性
|
||||
date := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
|
||||
// 检查解析后的日期是否与输入一致(防止无效日期如20230230)
|
||||
expectedDateStr := date.Format("20060102")
|
||||
if expectedDateStr != dateStr {
|
||||
@@ -315,7 +324,7 @@ func validateDate(fl validator.FieldLevel) bool {
|
||||
if !matched {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 尝试解析日期
|
||||
_, err := time.Parse("2006-01-02", dateStr)
|
||||
return err == nil
|
||||
@@ -327,29 +336,29 @@ func validateTimeRange(fl validator.FieldLevel) bool {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -369,7 +378,7 @@ func validateBankCard(fl validator.FieldLevel) bool {
|
||||
if !matched {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 使用Luhn算法验证银行卡号
|
||||
return validateLuhn(bankCard)
|
||||
}
|
||||
@@ -378,24 +387,104 @@ func validateBankCard(fl validator.FieldLevel) bool {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// validateAuthorizationURL 授权书URL验证器
|
||||
func validateAuthorizationURL(fl validator.FieldLevel) bool {
|
||||
urlStr := fl.Field().String()
|
||||
if urlStr == "" {
|
||||
return true // 空值由required标签处理
|
||||
}
|
||||
|
||||
// 解析URL
|
||||
parsedURL, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查协议
|
||||
if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查文件扩展名
|
||||
path := parsedURL.Path
|
||||
validExtensions := []string{".pdf", ".jpg", ".jpeg", ".png", ".bmp"}
|
||||
hasValidExtension := false
|
||||
for _, ext := range validExtensions {
|
||||
if strings.HasSuffix(strings.ToLower(path), ext) {
|
||||
hasValidExtension = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return hasValidExtension
|
||||
}
|
||||
|
||||
// validateUniqueID 唯一标识验证器(小于等于32位字符串)
|
||||
func validateUniqueID(fl validator.FieldLevel) bool {
|
||||
uniqueID := fl.Field().String()
|
||||
if uniqueID == "" {
|
||||
return true // 空值由required标签处理
|
||||
}
|
||||
|
||||
// 检查长度:小于等于32位
|
||||
if len(uniqueID) > 32 {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查是否只包含允许的字符:字母、数字、下划线、连字符
|
||||
matched, _ := regexp.MatchString(`^[a-zA-Z0-9_-]+$`, uniqueID)
|
||||
return matched
|
||||
}
|
||||
|
||||
// validateReturnURL 回调地址验证器
|
||||
func validateReturnURL(fl validator.FieldLevel) bool {
|
||||
returnURL := fl.Field().String()
|
||||
if returnURL == "" {
|
||||
return true // 空值由required标签处理
|
||||
}
|
||||
|
||||
// 检查长度:不能超过500字符
|
||||
if len(returnURL) > 500 {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查URL格式
|
||||
parsedURL, err := url.Parse(returnURL)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查协议:只允许http和https
|
||||
if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查是否有域名
|
||||
if parsedURL.Host == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user