daShangDao_psiServer/utils/validator.go
2026-06-15 13:47:39 +08:00

217 lines
5.8 KiB
Go

package utils
import (
"errors"
"strings"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"psi/models/response"
)
// HandleValidationError 处理验证错误并返回自定义JSON响应
// 将 validator 的验证错误转换为友好的中文提示
func HandleValidationError(c *gin.Context, err error) {
if err == nil {
return
}
// 如果是 validator.ValidationErrors 类型
var validationErrors validator.ValidationErrors
if errors.As(err, &validationErrors) {
// 提取所有验证错误信息
errorMessages := make([]string, 0, len(validationErrors))
for _, e := range validationErrors {
errorMessages = append(errorMessages, formatValidationError(e))
}
// 返回第一个错误信息(或者可以返回所有错误)
msg := strings.Join(errorMessages, "; ")
response.FailWithValidateMessage(msg, c)
return
}
// 其他类型的错误,直接返回错误信息
response.FailWithValidateMessage("参数错误: "+err.Error(), c)
}
// formatValidationError 格式化单个验证错误为友好的中文提示
func formatValidationError(e validator.FieldError) string {
field := e.Field()
tag := e.Tag()
param := e.Param()
switch tag {
case "required":
return getFieldChineseName(field) + "不能为空"
case "min":
kind := e.Kind().String()
if kind == "slice" || kind == "array" {
return getFieldChineseName(field) + "至少需要" + param + "个元素"
}
return getFieldChineseName(field) + "最小值为" + param
case "max":
kind := e.Kind().String()
if kind == "slice" || kind == "array" {
return getFieldChineseName(field) + "最多只能有" + param + "个元素"
}
return getFieldChineseName(field) + "最大值为" + param
case "email":
return getFieldChineseName(field) + "邮箱格式不正确"
case "url":
return getFieldChineseName(field) + "URL格式不正确"
case "numeric":
return getFieldChineseName(field) + "必须是数字"
case "alpha":
return getFieldChineseName(field) + "只能是字母"
case "alphanum":
return getFieldChineseName(field) + "只能是字母和数字"
case "oneof":
return getFieldChineseName(field) + "必须是以下值之一: " + param
case "gt":
return getFieldChineseName(field) + "必须大于" + param
case "gte":
return getFieldChineseName(field) + "必须大于等于" + param
case "lt":
return getFieldChineseName(field) + "必须小于" + param
case "lte":
return getFieldChineseName(field) + "必须小于等于" + param
case "len":
kind := e.Kind().String()
if kind == "slice" || kind == "array" {
return getFieldChineseName(field) + "必须有" + param + "个元素"
}
return getFieldChineseName(field) + "长度必须为" + param
case "ne":
return getFieldChineseName(field) + "不能等于" + param
case "eq":
return getFieldChineseName(field) + "必须等于" + param
case "contains":
return getFieldChineseName(field) + "必须包含" + param
case "excludes":
return getFieldChineseName(field) + "不能包含" + param
case "startswith":
return getFieldChineseName(field) + "必须以" + param + "开头"
case "endswith":
return getFieldChineseName(field) + "必须以" + param + "结尾"
default:
return getFieldChineseName(field) + "验证失败"
}
}
// getFieldChineseName 获取字段的中文名称映射
func getFieldChineseName(field string) string {
fieldMap := map[string]string{
//Barcode 相关
"Content": "条形码内容",
// Book 相关
"Isbn": "ISBN",
"BookName": "书名",
"Author": "作者",
"Publisher": "出版社",
"PublicationTime": "出版时间",
"BindingLayout": "装帧方式",
"FixPrice": "定价",
// Car 相关
"Appearance": "品相",
"PushType": "推送类型",
// Employee 相关
"Username": "账号",
"Password": "密码",
"EmpId": "员工ID",
"Level": "等级",
"PayTime": "支付时间",
"OperationType": "操作类型",
"ExpireTime": "过期时间",
// Inventory 相关
"ProductID": "商品ID",
"StockCheckID": "盘库ID",
// Location 相关
"WarehouseID": "仓库ID",
"Code": "编码",
"Type": "类型",
"Capacity": "容量",
"Status": "状态",
// Process 相关
"CarID": "小车ID",
"CarCode": "小车编号",
"Quantity": "数量",
"UnitPrice": "单价",
"WaveID": "波次ID",
"RelatedOrderID": "关联订单ID",
"WaveNo": "波次号",
"Operator": "操作人",
"OperatorID": "操作人ID",
"ReceivingOrderID": "入库单ID",
"WaveTaskID": "波次任务ID",
"AssociationOrderID": "关联平台订单ID",
"AssociationOrderNo": "关联平台订单号",
"OutboundOrderID": "出库单ID",
"ShippingOrderID": "发货单ID",
"SalesOrderItemID": "销售单明细ID",
"LogisticsCompany": "物流公司",
"LogisticsNo": "物流运单号",
"OrderID": "订单ID",
"LocationID": "货位ID",
"AdjustType": "调整类型",
"SalesOrderID": "销售订单ID",
// Product 相关
"CategoryID": "分类ID",
"ProductName": "商品名称",
"Barcode": "条形码",
"Price": "单价",
"UserID": "用户ID",
"SalePrice": "售价",
"OutTaskID": "外部任务ID",
// Warehouse 相关
"Name": "名称",
"ContactPerson": "联系人",
"ContactPhone": "联系电话",
"Province": "省份",
"City": "城市",
"District": "区县",
"Address": "详细地址",
// 通用字段
"Page": "页码",
"PageSize": "每页数量",
"Keyword": "关键词",
"ID": "ID",
}
if chineseName, ok := fieldMap[field]; ok {
return chineseName
}
// 如果没有映射,返回原字段名
return field
}