tianyuan-api-server/apps/api/internal/validator/validator.go

157 lines
4.6 KiB
Go
Raw Normal View History

2024-10-02 00:57:17 +08:00
package validator
import (
"encoding/json"
"errors"
"fmt"
"github.com/go-playground/validator/v10"
"regexp"
"strconv"
)
var validate *validator.Validate
// 初始化自定义校验器
func init() {
validate = validator.New()
if err := validate.RegisterValidation("validName", validName); err != nil {
panic(fmt.Sprintf("注册 validName 验证器时发生错误: %v", err))
}
// 注册自定义验证器 validMobileNo
if err := validate.RegisterValidation("validMobileNo", validMobileNo); err != nil {
panic(fmt.Sprintf("注册 validMobileNo 验证器时发生错误: %v", err))
}
// 注册自定义验证器 validDate
if err := validate.RegisterValidation("validDate", validDate); err != nil {
panic(fmt.Sprintf("注册 validDate 验证器时发生错误: %v", err))
}
// 注册自定义验证器 validIDCard
if err := validate.RegisterValidation("validIDCard", validIDCard); err != nil {
panic(fmt.Sprintf("注册 validIDCard 验证器时发生错误: %v", err))
}
// 注册自定义验证器 validTimeRange
if err := validate.RegisterValidation("validTimeRange", validTimeRange); err != nil {
panic(fmt.Sprintf("注册 validTimeRange 验证器时发生错误: %v", err))
}
2024-10-13 20:52:47 +08:00
if err := validate.RegisterValidation("validBankCard", validBankCard); err != nil {
panic(fmt.Sprintf("注册 validBankCard 验证器时发生错误: %v", err))
}
if err := validate.RegisterValidation("validUSCI", validUSCI); err != nil {
panic(fmt.Sprintf("注册 validUSCI 验证器时发生错误: %v", err))
}
if err := validate.RegisterValidation("validMobileType", validMobileType); err != nil {
panic(fmt.Sprintf("注册 validMobileType 验证器时发生错误: %v", err))
}
2024-10-02 00:57:17 +08:00
}
// ValidateAndParse 封装了解密、解析和校验逻辑
func ValidateAndParse(decryptData []byte, req interface{}) error {
// 解析解密后的 JSON 数据
if err := json.Unmarshal(decryptData, req); err != nil {
return errors.New("解密后的数据格式不正确")
}
// 校验
v := GetValidator()
if err := v.Struct(req); err != nil {
for _, validationErr := range err.(validator.ValidationErrors) {
field := validationErr.StructField()
tag := validationErr.Tag()
return errors.New(GetErrorMessage(field, tag))
}
}
// 如果没有错误,返回 nil
return nil
}
// 获取验证器实例
func GetValidator() *validator.Validate {
return validate
}
// 自定义的名称验证
func validName(fl validator.FieldLevel) bool {
name := fl.Field().String()
validNamePattern := `^[\p{Han}]+$`
matched, _ := regexp.MatchString(validNamePattern, name)
return matched
}
// 自定义的手机号验证
func validMobileNo(fl validator.FieldLevel) bool {
phone := fl.Field().String()
validMobileNoPattern := `^1[3-9]\d{9}$`
matched, _ := regexp.MatchString(validMobileNoPattern, phone)
return matched
}
// 自定义正则表达式校验 yyyyMMdd 格式
func validDate(fl validator.FieldLevel) bool {
date := fl.Field().String()
validDatePattern := `^\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$`
matched, _ := regexp.MatchString(validDatePattern, date)
return matched
}
// 自定义身份证校验
func validIDCard(fl validator.FieldLevel) bool {
id := fl.Field().String()
2024-10-15 17:19:23 +08:00
validIDPattern := `^\d{17}(\d|X|x)$` // 匹配18位身份证号码
2024-10-02 00:57:17 +08:00
matched, _ := regexp.MatchString(validIDPattern, id)
return matched
}
// 自定义 time_range 校验 (1-5年)
func validTimeRange(fl validator.FieldLevel) bool {
timeRange := fl.Field().String()
if timeRange == "" {
return true // 如果为空,认为是有效的,因为是非必填项
}
value, err := strconv.Atoi(timeRange)
if err != nil || value < 1 || value > 5 {
return false
}
return true
}
2024-10-13 20:52:47 +08:00
func validBankCard(fl validator.FieldLevel) bool {
bankCard := fl.Field().String()
// 银行卡号一般是13到19位的数字
validBankCardPattern := `^\d{13,19}$`
matched, _ := regexp.MatchString(validBankCardPattern, bankCard)
return matched
}
func validUSCI(fl validator.FieldLevel) bool {
usci := fl.Field().String()
// 社会信用代码为18位数字和大写字母的组合最后一位为校验码
validUSCIPattern := `^[1-9A-Z]{2}[0-9]{6}[0-9A-Z]{9}[0-9A-Z]$`
matched, _ := regexp.MatchString(validUSCIPattern, usci)
return matched
}
// 自定义的手机号类型验证(可以为空)
func validMobileType(fl validator.FieldLevel) bool {
mobileType := fl.Field().String()
if mobileType == "" {
return true // 如果为空,认为是有效的
}
// 校验是否是 CTCC, CMCC, CUCC 之一
validTypes := map[string]bool{
"CTCC": true, // 中国电信
"CMCC": true, // 中国移动
"CUCC": true, // 中国联通
}
return validTypes[mobileType]
}