first commit

This commit is contained in:
2025-03-21 11:05:42 +08:00
commit 7dffc94035
1717 changed files with 724764 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
package validation
import (
"errors"
"regexp"
)
// 使用预编译的全局正则表达式,避免重复创建和编译.
var (
lengthRegex = regexp.MustCompile(`^.{3,20}$`) // 长度在 3 到 20 个字符之间
validRegex = regexp.MustCompile(`^[A-Za-z0-9_]+$`) // 仅包含字母、数字和下划线
letterRegex = regexp.MustCompile(`[A-Za-z]`) // 至少包含一个字母
numberRegex = regexp.MustCompile(`\d`) // 至少包含一个数字
emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`) // 邮箱格式
phoneRegex = regexp.MustCompile(`^1[3-9]\d{9}$`) // 中国手机号
)
// IsValidUsername 校验用户名是否合法.
func IsValidUsername(username string) bool {
// 校验长度
if !lengthRegex.MatchString(username) {
return false
}
// 校验字符合法性
if !validRegex.MatchString(username) {
return false
}
return true
}
// IsValidPassword 判断密码是否符合复杂度要求.
func IsValidPassword(password string) error {
switch {
// 检查新密码是否为空
case password == "":
return errors.New("password cannot be empty")
// 检查新密码的长度要求
case len(password) < 6:
return errors.New("password must be at least 6 characters long")
// 使用正则表达式检查是否至少包含一个字母
case !letterRegex.MatchString(password):
return errors.New("password must contain at least one letter")
// 使用正则表达式检查是否至少包含一个数字
case !numberRegex.MatchString(password):
return errors.New("password must contain at least one number")
}
return nil
}
// IsValidEmail 判断电子邮件是否合法.
func IsValidEmail(email string) error {
// 检查电子邮件地址格式
if email == "" {
return errors.New("email cannot be empty")
}
// 使用正则表达式校验电子邮件格式
if !emailRegex.MatchString(email) {
return errors.New("invalid email format")
}
return nil
}
// IsValidPhone 判断手机号码是否合法.
func IsValidPhone(phone string) error {
// 检查手机号码格式
if phone == "" {
return errors.New("phone cannot be empty")
}
// 使用正则表达式校验手机号码格式假设是中国手机号11位数字
if !phoneRegex.MatchString(phone) {
return errors.New("invalid phone format")
}
return nil
}

View File

@@ -0,0 +1,86 @@
package validation
import (
"errors"
"fmt"
"reflect"
"strings"
"time"
"github.com/go-playground/validator/v10"
)
// 初始化一个验证器实例
var validate = validator.New()
// 自定义验证规则requiredint
func init() {
validate.RegisterValidation("telephone", func(fl validator.FieldLevel) bool {
if err := IsValidPhone(fl.Field().String()); err != nil {
return false
}
return true
})
validate.RegisterValidation("dateonly", func(fl validator.FieldLevel) bool {
_, err := time.ParseInLocation("2006-01-02", fl.Field().String(), time.Local)
if err != nil {
return false
}
return true
})
}
func ValidateForm(s any) error {
// 验证结构体数据
if err := validate.Struct(s); err != nil {
if _, ok := err.(*validator.InvalidValidationError); ok {
return errors.New("验证器配置错误")
}
// 获取结构体的反射类型
t := reflect.TypeOf(s)
errorMessages := make([]string, 0)
for _, err := range err.(validator.ValidationErrors) {
// 获取字段名
fieldName := err.Field()
// 获取标签名
tag := err.Tag()
// 获取验证失败的字段值
// value := err.Value()
// 通过反射获取字段
field, found := t.Elem().FieldByName(fieldName)
errorMsg := fmt.Sprintf("[%s] 验证失败: %s", fieldName, translate(tag))
if found {
commentTag := field.Tag.Get("comment")
errorMsg = fmt.Sprintf("[%s] 验证失败: %s", commentTag, translate(tag))
}
errorMessages = append(errorMessages, errorMsg)
}
return errors.New(strings.Join(errorMessages, "; "))
}
return nil
}
func translate(s string) string {
switch s {
case "required":
return "不能为空"
case "min":
return "不能小于"
case "max":
return "不能大于"
case "email":
return "不是有效的邮箱地址"
case "telephone":
return "不是有效的手机号"
case "datetime":
return "不是有效的日期时间"
case "dateonly":
return "不是有效的日期"
}
return s
}