refactor(valid): 重构验证器初始化和错误处理逻辑

- 调整全局变量声明顺序并移除未使用的 uni 变量
- 添加 ApiResponse 结构体定义
- 重命名 GetFirstValidateError 函数为 ValidateError
- 优化 init 函数中的中文本地化初始化流程
- 更新字段名映射函数的注释说明
- 改进错误处理逻辑和代码注释
main v1.0.00018
black1552 2026-02-03 17:09:46 +08:00
parent 6c72a05b64
commit d549cf929b
1 changed files with 29 additions and 25 deletions

View File

@ -11,60 +11,64 @@ import (
zh_translations "github.com/go-playground/validator/v10/translations/zh"
)
// -------------------------- 全局变量(翻译器+验证器) --------------------------
var (
uni *ut.UniversalTranslator // 全局翻译器实例
validate *validator.Validate // 全局验证器实例
trans ut.Translator // 全局中文翻译器
foun bool
validate *validator.Validate // 全局验证器实例
found bool
)
// -------------------------- 统一响应格式 --------------------------
type ApiResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
// -------------------------- 初始化全局验证器+中文翻译器关键与Gin关联 --------------------------
func init() {
// 1. 初始化中文本地化实例
// 1. 初始化中文本地化
zhLocale := zh.New()
uni := ut.New(zhLocale, zhLocale)
// 2. 初始化通用翻译器,加载中文本地化
uni = ut.New(zhLocale, zhLocale)
// 3. 获取中文翻译器实例
// 2. 获取中文翻译器
var err error
trans, foun = uni.GetTranslator("zh")
if !foun {
trans, found = uni.GetTranslator("zh")
if !found {
panic("获取中文翻译器失败")
}
// 4. 获取 Gin 内置的 validator 验证器实例
// 3. 关键:获取 Gin 内置的 validator 实例(而非手动创建 new(validator.Validate)
// 保证 Gin 绑定参数时使用的是我们注册了翻译的这个验证器
validate = validator.New()
// 5. 注册 validator 中文翻译(替换默认英文错误提示
// 4. 注册中文翻译(核心:将验证器与中文翻译器绑定
err = zh_translations.RegisterDefaultTranslations(validate, trans)
if err != nil {
panic("注册中文翻译失败:" + err.Error())
}
// 6. 核心优化:注册字段名映射函数,用结构体的 json 标签作为返回的字段名
// 例如:结构体字段 Username -> json 标签 username -> 错误提示中显示 username更友好
// 5. 注册字段名映射:用 json 标签替换结构体字段名(解决报错中的 Title -> title 问题)
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
// 提取 json 标签(忽略 ,omitempty 等附加选项)
// 提取 json 标签,忽略 ,omitempty 等附加选项
jsonTag := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
// 若 json 标签为 "-"(表示忽略该字段),返回空字符串
if jsonTag == "-" {
return ""
}
return jsonTag
})
}
func GetFirstValidateError(err error) string {
// 1. 断言错误类型是否为 validator 验证错误
// ValidateError -------------------------- 工具函数:解析第一条验证错误(中文翻译) --------------------------
func ValidateError(err error) string {
// 1. 断言错误类型为 validator.ValidationErrors
var validateErrors validator.ValidationErrors
ok := errors.As(err, &validateErrors)
if !ok {
// 非参数验证错误(如绑定格式错误),直接返回错误信息
// 非参数验证错误,直接返回
return "参数格式错误:" + err.Error()
}
// 2. 仅返回第一条验证错误(核心:取切片索引 0 的元素)
firstErr := validateErrors[0]
// 3. 翻译第一条错误为中文,返回给前端
return firstErr.Translate(trans)
// 2. 只返回第一条中文翻译错误
return validateErrors[0].Translate(trans)
}