custom_rules.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package validators
  2. import (
  3. "errors"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "unicode/utf8"
  8. "github.com/thedevsaddam/govalidator"
  9. "github.com/runningwater/gohub/pkg/database"
  10. )
  11. func init() {
  12. // 自定义验证规则 not_exists, 用于验证数据不存在于数据库中
  13. // 常用于保证数据库某个字段的值唯一, 如用户名、邮箱、手机号或者分类的名称
  14. //
  15. // 用法示例
  16. //
  17. // 规则: not_exists:users,phone
  18. // 解释:验证 users 表中是否存在 phone 字段的值,phone 为待验证的值
  19. //
  20. // 规则: not_exists:users,phone,10
  21. // 解释:验证 users 表中是否存在 phone 字段的值,同时排除 id 为 10 的记录
  22. govalidator.AddCustomRule("not_exists", func(field string, rule string, message string, value any) error {
  23. rng := strings.Split(strings.TrimPrefix(rule, "not_exists:"), ",")
  24. // 第一个参数,表名称,如 users
  25. tableName := rng[0]
  26. // 第二个参数,字段名称,如 phone
  27. fieldName := rng[1]
  28. // 第三个参数,排除 ID
  29. var exceptID string
  30. if len(rng) > 2 {
  31. exceptID = rng[2]
  32. }
  33. // 用户请求的值
  34. requestValue := value.(string)
  35. // 调用数据库查询方法,检查数据是否存在
  36. query := database.DB.Table(tableName).Where(fieldName+" = ?", requestValue)
  37. if len(exceptID) > 0 {
  38. query.Where("id != ?", exceptID)
  39. }
  40. var count int64
  41. query.Count(&count)
  42. // 如果 count 大于 0,表示数据已存在,返回错误信息
  43. if count > 0 {
  44. // 如果有自定义错误消息的话,使用自定义错误消息
  45. if len(message) > 0 {
  46. return errors.New(message)
  47. }
  48. return fmt.Errorf("%v 已存在", requestValue)
  49. }
  50. return nil
  51. })
  52. // max_cn:8 中文最多 8 个字
  53. govalidator.AddCustomRule("max_cn", func(field string, rule string, message string, value any) error {
  54. valueLen := utf8.RuneCountInString(value.(string))
  55. maxLen, _ := strconv.Atoi(strings.TrimPrefix(rule, "max_cn:"))
  56. if valueLen > maxLen {
  57. // 如果有自定义错误消息的话,使用自定义消息
  58. if message != "" {
  59. return errors.New(message)
  60. }
  61. return fmt.Errorf("%v 长度不能超过 %v 个字", field, maxLen)
  62. }
  63. return nil
  64. })
  65. // min_cn:8 中文长度最少 8 个字
  66. govalidator.AddCustomRule("min_cn", func(field string, rule string, message string, value any) error {
  67. valueLen := utf8.RuneCountInString(value.(string))
  68. minLen, _ := strconv.Atoi(strings.TrimPrefix(rule, "min_cn:"))
  69. if valueLen < minLen {
  70. // 如果有自定义错误消息的话,使用自定义消息
  71. if message != "" {
  72. return errors.New(message)
  73. }
  74. return fmt.Errorf("%v 长度不能小于 %v 个字", field, minLen)
  75. }
  76. return nil
  77. })
  78. // 自定义规则 exists, 确保数据库存在某条数据
  79. // exists:categories,id
  80. govalidator.AddCustomRule("exists", func(field string, rule string, message string, value any) error {
  81. rng := strings.Split(strings.TrimPrefix(rule, "exists:"), ",")
  82. // 第一个参数,表名称,如 categories
  83. tableName := rng[0]
  84. // 第二个参数,字段名称,如 id
  85. fieldName := rng[1]
  86. // 用户请求的值
  87. requestValue := value.(string)
  88. // 调用数据库查询方法,检查数据是否存在
  89. var count int64
  90. database.DB.Table(tableName).Where(fieldName+" = ?", requestValue).Count(&count)
  91. // 如果 count 小于等于 0,表示数据不存在,返回错误信息
  92. if count <= 0 {
  93. // 如果有自定义错误消息的话,使用自定义消息
  94. if message != "" {
  95. return errors.New(message)
  96. }
  97. return fmt.Errorf("%v 不存在", requestValue)
  98. }
  99. return nil
  100. })
  101. }