217 lines
5.8 KiB
Go
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
|
|
}
|