diff --git a/valid/valid.go b/valid/valid.go index b3a68f8..c2bcd68 100644 --- a/valid/valid.go +++ b/valid/valid.go @@ -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 + trans ut.Translator // 全局中文翻译器 + 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) }