tianyuan-api-server/apps/api/internal/validator/validator.go
2024-10-15 17:19:23 +08:00

157 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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))
}
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))
}
}
// 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()
validIDPattern := `^\d{17}(\d|X|x)$` // 匹配18位身份证号码
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
}
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]
}