package validators import ( "errors" "fmt" "strconv" "strings" "unicode/utf8" "github.com/thedevsaddam/govalidator" "github.com/runningwater/gohub/pkg/database" ) func init() { // 自定义验证规则 not_exists, 用于验证数据不存在于数据库中 // 常用于保证数据库某个字段的值唯一, 如用户名、邮箱、手机号或者分类的名称 // // 用法示例 // // 规则: not_exists:users,phone // 解释:验证 users 表中是否存在 phone 字段的值,phone 为待验证的值 // // 规则: not_exists:users,phone,10 // 解释:验证 users 表中是否存在 phone 字段的值,同时排除 id 为 10 的记录 govalidator.AddCustomRule("not_exists", func(field string, rule string, message string, value any) error { rng := strings.Split(strings.TrimPrefix(rule, "not_exists:"), ",") // 第一个参数,表名称,如 users tableName := rng[0] // 第二个参数,字段名称,如 phone fieldName := rng[1] // 第三个参数,排除 ID var exceptID string if len(rng) > 2 { exceptID = rng[2] } // 用户请求的值 requestValue := value.(string) // 调用数据库查询方法,检查数据是否存在 query := database.DB.Table(tableName).Where(fieldName+" = ?", requestValue) if len(exceptID) > 0 { query.Where("id != ?", exceptID) } var count int64 query.Count(&count) // 如果 count 大于 0,表示数据已存在,返回错误信息 if count > 0 { // 如果有自定义错误消息的话,使用自定义错误消息 if len(message) > 0 { return errors.New(message) } return fmt.Errorf("%v 已存在", requestValue) } return nil }) // max_cn:8 中文最多 8 个字 govalidator.AddCustomRule("max_cn", func(field string, rule string, message string, value any) error { valueLen := utf8.RuneCountInString(value.(string)) maxLen, _ := strconv.Atoi(strings.TrimPrefix(rule, "max_cn:")) if valueLen > maxLen { // 如果有自定义错误消息的话,使用自定义消息 if message != "" { return errors.New(message) } return fmt.Errorf("%v 长度不能超过 %v 个字", field, maxLen) } return nil }) // min_cn:8 中文长度最少 8 个字 govalidator.AddCustomRule("min_cn", func(field string, rule string, message string, value any) error { valueLen := utf8.RuneCountInString(value.(string)) minLen, _ := strconv.Atoi(strings.TrimPrefix(rule, "min_cn:")) if valueLen < minLen { // 如果有自定义错误消息的话,使用自定义消息 if message != "" { return errors.New(message) } return fmt.Errorf("%v 长度不能小于 %v 个字", field, minLen) } return nil }) }