355 lines
14 KiB
Go
355 lines
14 KiB
Go
package errors
|
||
|
||
import "fmt"
|
||
|
||
// 错误码定义
|
||
const (
|
||
// 成功
|
||
CodeSuccess = 0
|
||
|
||
// 客户端错误 (1000-1999) -> 4xx HTTP 状态码
|
||
CodeInvalidParam = 1001 // 参数验证失败
|
||
CodeMissingToken = 1002 // 缺失认证令牌
|
||
CodeInvalidToken = 1003 // 无效或过期的令牌
|
||
CodeUnauthorized = 1004 // 未授权
|
||
CodeForbidden = 1005 // 禁止访问
|
||
CodeNotFound = 1006 // 资源未找到
|
||
CodeConflict = 1007 // 资源冲突
|
||
CodeTooManyRequests = 1008 // 请求过多
|
||
CodeRequestTooLarge = 1009 // 请求体过大
|
||
|
||
// RBAC 相关错误 (1010-1099)
|
||
CodeAccountNotFound = 1010 // 账号不存在
|
||
CodeAccountDisabled = 1011 // 账号已禁用
|
||
CodeAccountDeleted = 1012 // 账号已删除
|
||
CodeUsernameExists = 1013 // 用户名已存在
|
||
CodePhoneExists = 1014 // 手机号已存在
|
||
CodeInvalidPassword = 1015 // 密码格式不正确
|
||
CodePasswordTooWeak = 1016 // 密码强度不足
|
||
CodeParentIDRequired = 1017 // 非 root 用户必须提供上级账号
|
||
CodeInvalidParentID = 1018 // 上级账号不存在或无效
|
||
CodeCannotModifyParent = 1019 // 禁止修改上级账号
|
||
CodeCannotModifyUserType = 1020 // 禁止修改用户类型
|
||
CodeRoleNotFound = 1021 // 角色不存在
|
||
CodeRoleNameExists = 1022 // 角色名称已存在
|
||
CodePermissionNotFound = 1023 // 权限不存在
|
||
CodePermCodeExists = 1024 // 权限编码已存在
|
||
CodeInvalidPermCode = 1025 // 权限编码格式不正确
|
||
CodeRoleAlreadyAssigned = 1026 // 角色已分配
|
||
CodePermAlreadyAssigned = 1027 // 权限已分配
|
||
|
||
// 认证相关错误 (1040-1049)
|
||
CodeInvalidCredentials = 1040 // 用户名或密码错误
|
||
CodeAccountLocked = 1041 // 账号已锁定
|
||
CodePasswordExpired = 1042 // 密码已过期
|
||
CodeInvalidOldPassword = 1043 // 旧密码错误
|
||
CodeWechatOAuthFailed = 1044 // 微信 OAuth 授权失败
|
||
CodeWechatUserInfoFailed = 1045 // 获取微信用户信息失败
|
||
CodeWechatPayFailed = 1046 // 微信支付发起失败
|
||
CodeWechatCallbackInvalid = 1047 // 微信回调签名验证失败
|
||
|
||
// 组织相关错误 (1030-1049)
|
||
CodeShopNotFound = 1030 // 店铺不存在
|
||
CodeShopCodeExists = 1031 // 店铺编号已存在
|
||
CodeShopLevelExceeded = 1032 // 店铺层级超过最大值
|
||
CodeEnterpriseNotFound = 1033 // 企业不存在
|
||
CodeEnterpriseCodeExists = 1034 // 企业编号已存在
|
||
CodeCustomerNotFound = 1035 // 个人客户不存在
|
||
CodeCustomerPhoneExists = 1036 // 个人客户手机号已存在
|
||
|
||
// 财务相关错误 (1050-1069)
|
||
CodeInvalidStatus = 1050 // 状态不允许此操作
|
||
CodeInsufficientBalance = 1051 // 余额不足
|
||
CodeWithdrawalNotFound = 1052 // 提现申请不存在
|
||
CodeWalletNotFound = 1053 // 钱包不存在
|
||
CodeInsufficientQuota = 1054 // 额度不足
|
||
CodeExceedLimit = 1055 // 超过限制
|
||
|
||
// IoT 卡相关错误 (1070-1089)
|
||
CodeIotCardNotFound = 1070 // IoT 卡不存在
|
||
CodeIotCardBoundToDevice = 1071 // IoT 卡已绑定设备
|
||
CodeIotCardStatusNotAllowed = 1072 // 卡状态不允许此操作
|
||
CodeAssetAllocationRecordNotFound = 1073 // 分配记录不存在
|
||
CodeNotDirectSubordinate = 1074 // 非直属下级店铺
|
||
CodeCannotAllocateToSelf = 1075 // 不能分配给自己
|
||
CodeCannotRecallFromSelf = 1076 // 不能从自己回收
|
||
CodeCardAlreadyAuthorized = 1077 // 卡已授权给该企业
|
||
CodeCardNotAuthorized = 1078 // 卡未授权给该企业
|
||
CodeCannotAuthorizeOthersCard = 1079 // 不能授权非自己的卡
|
||
CodeCannotRevokeOthersAuthorization = 1080 // 不能回收非自己创建的授权
|
||
CodeCannotAuthorizeBoundCard = 1081 // 不能授权已绑定设备的卡
|
||
CodeCannotAuthorizeToOthersEnterprise = 1082 // 不能授权给非自己的企业
|
||
CodeDeviceAlreadyAuthorized = 1083 // 设备已授权给该企业
|
||
CodeDeviceNotAuthorized = 1084 // 设备未授权给该企业
|
||
CodeDeviceAuthorizedToOther = 1085 // 设备已授权给其他企业
|
||
CodeCannotAuthorizeOthersDevice = 1086 // 不能授权非自己的设备
|
||
|
||
// 对象存储相关错误 (1090-1099)
|
||
CodeStorageNotConfigured = 1090 // 对象存储服务未配置
|
||
CodeStorageUploadFailed = 1091 // 文件上传失败
|
||
CodeStorageDownloadFailed = 1092 // 文件下载失败
|
||
CodeStorageFileNotFound = 1093 // 文件不存在
|
||
CodeStorageInvalidPurpose = 1094 // 不支持的文件用途
|
||
CodeStorageInvalidFileType = 1095 // 不支持的文件类型
|
||
|
||
// 运营商相关错误 (1100-1109)
|
||
CodeCarrierNotFound = 1100 // 运营商不存在
|
||
CodeCarrierCodeExists = 1101 // 运营商编码已存在
|
||
|
||
// 服务端错误 (2000-2999) -> 5xx HTTP 状态码
|
||
CodeInternalError = 2001 // 内部服务器错误
|
||
CodeDatabaseError = 2002 // 数据库错误
|
||
CodeRedisError = 2003 // Redis 错误
|
||
CodeServiceUnavailable = 2004 // 服务不可用
|
||
CodeTimeout = 2005 // 请求超时
|
||
CodeTaskQueueError = 2006 // 任务队列错误
|
||
)
|
||
|
||
// allErrorCodes 所有已注册的错误码
|
||
// 新增错误码时必须同时在此列表中注册
|
||
var allErrorCodes = []int{
|
||
CodeSuccess,
|
||
CodeInvalidParam,
|
||
CodeMissingToken,
|
||
CodeInvalidToken,
|
||
CodeUnauthorized,
|
||
CodeForbidden,
|
||
CodeNotFound,
|
||
CodeConflict,
|
||
CodeTooManyRequests,
|
||
CodeRequestTooLarge,
|
||
CodeAccountNotFound,
|
||
CodeAccountDisabled,
|
||
CodeAccountDeleted,
|
||
CodeUsernameExists,
|
||
CodePhoneExists,
|
||
CodeInvalidPassword,
|
||
CodePasswordTooWeak,
|
||
CodeParentIDRequired,
|
||
CodeInvalidParentID,
|
||
CodeCannotModifyParent,
|
||
CodeCannotModifyUserType,
|
||
CodeRoleNotFound,
|
||
CodeRoleNameExists,
|
||
CodePermissionNotFound,
|
||
CodePermCodeExists,
|
||
CodeInvalidPermCode,
|
||
CodeRoleAlreadyAssigned,
|
||
CodePermAlreadyAssigned,
|
||
CodeShopNotFound,
|
||
CodeShopCodeExists,
|
||
CodeShopLevelExceeded,
|
||
CodeEnterpriseNotFound,
|
||
CodeEnterpriseCodeExists,
|
||
CodeCustomerNotFound,
|
||
CodeCustomerPhoneExists,
|
||
CodeInvalidCredentials,
|
||
CodeAccountLocked,
|
||
CodePasswordExpired,
|
||
CodeInvalidOldPassword,
|
||
CodeWechatOAuthFailed,
|
||
CodeWechatUserInfoFailed,
|
||
CodeWechatPayFailed,
|
||
CodeWechatCallbackInvalid,
|
||
CodeInvalidStatus,
|
||
CodeInsufficientBalance,
|
||
CodeWithdrawalNotFound,
|
||
CodeWalletNotFound,
|
||
CodeInsufficientQuota,
|
||
CodeExceedLimit,
|
||
CodeIotCardNotFound,
|
||
CodeIotCardBoundToDevice,
|
||
CodeIotCardStatusNotAllowed,
|
||
CodeAssetAllocationRecordNotFound,
|
||
CodeNotDirectSubordinate,
|
||
CodeCannotAllocateToSelf,
|
||
CodeCannotRecallFromSelf,
|
||
CodeCardAlreadyAuthorized,
|
||
CodeCardNotAuthorized,
|
||
CodeCannotAuthorizeOthersCard,
|
||
CodeCannotRevokeOthersAuthorization,
|
||
CodeCannotAuthorizeBoundCard,
|
||
CodeCannotAuthorizeToOthersEnterprise,
|
||
CodeDeviceAlreadyAuthorized,
|
||
CodeDeviceNotAuthorized,
|
||
CodeDeviceAuthorizedToOther,
|
||
CodeCannotAuthorizeOthersDevice,
|
||
CodeStorageNotConfigured,
|
||
CodeStorageUploadFailed,
|
||
CodeStorageDownloadFailed,
|
||
CodeStorageFileNotFound,
|
||
CodeStorageInvalidPurpose,
|
||
CodeStorageInvalidFileType,
|
||
CodeCarrierNotFound,
|
||
CodeCarrierCodeExists,
|
||
CodeInternalError,
|
||
CodeDatabaseError,
|
||
CodeRedisError,
|
||
CodeServiceUnavailable,
|
||
CodeTimeout,
|
||
CodeTaskQueueError,
|
||
}
|
||
|
||
func init() {
|
||
for _, code := range allErrorCodes {
|
||
if _, ok := errorMessages[code]; !ok {
|
||
panic(fmt.Sprintf("错误码 %d 缺少映射消息,请在 errorMessages 中添加", code))
|
||
}
|
||
}
|
||
}
|
||
|
||
// errorMessages 错误消息映射表(中文)
|
||
var errorMessages = map[int]string{
|
||
CodeSuccess: "成功",
|
||
CodeInvalidParam: "参数验证失败",
|
||
CodeMissingToken: "缺失认证令牌",
|
||
CodeInvalidToken: "无效或过期的令牌",
|
||
CodeUnauthorized: "未授权访问",
|
||
CodeForbidden: "禁止访问",
|
||
CodeNotFound: "资源未找到",
|
||
CodeConflict: "资源冲突",
|
||
CodeTooManyRequests: "请求过多,请稍后重试",
|
||
CodeRequestTooLarge: "请求体过大",
|
||
CodeAccountNotFound: "账号不存在",
|
||
CodeAccountDisabled: "账号已禁用",
|
||
CodeAccountDeleted: "账号已删除",
|
||
CodeUsernameExists: "用户名已存在",
|
||
CodePhoneExists: "手机号已存在",
|
||
CodeInvalidPassword: "密码格式不正确",
|
||
CodePasswordTooWeak: "密码强度不足",
|
||
CodeParentIDRequired: "非 root 用户必须提供上级账号",
|
||
CodeInvalidParentID: "上级账号不存在或无效",
|
||
CodeCannotModifyParent: "禁止修改上级账号",
|
||
CodeCannotModifyUserType: "禁止修改用户类型",
|
||
CodeRoleNotFound: "角色不存在",
|
||
CodeRoleNameExists: "角色名称已存在",
|
||
CodePermissionNotFound: "权限不存在",
|
||
CodePermCodeExists: "权限编码已存在",
|
||
CodeInvalidPermCode: "权限编码格式不正确(应为 module:action 格式)",
|
||
CodeRoleAlreadyAssigned: "角色已分配",
|
||
CodePermAlreadyAssigned: "权限已分配",
|
||
CodeShopNotFound: "店铺不存在",
|
||
CodeShopCodeExists: "店铺编号已存在",
|
||
CodeShopLevelExceeded: "店铺层级不能超过 7 级",
|
||
CodeEnterpriseNotFound: "企业不存在",
|
||
CodeEnterpriseCodeExists: "企业编号已存在",
|
||
CodeCustomerNotFound: "个人客户不存在",
|
||
CodeCustomerPhoneExists: "个人客户手机号已存在",
|
||
CodeInvalidStatus: "状态不允许此操作",
|
||
CodeInsufficientBalance: "余额不足",
|
||
CodeWithdrawalNotFound: "提现申请不存在",
|
||
CodeWalletNotFound: "钱包不存在",
|
||
CodeInsufficientQuota: "额度不足",
|
||
CodeExceedLimit: "超过限制",
|
||
CodeIotCardNotFound: "IoT 卡不存在",
|
||
CodeIotCardBoundToDevice: "IoT 卡已绑定设备,不能单独操作",
|
||
CodeIotCardStatusNotAllowed: "卡状态不允许此操作",
|
||
CodeAssetAllocationRecordNotFound: "分配记录不存在",
|
||
CodeNotDirectSubordinate: "只能操作直属下级店铺",
|
||
CodeCannotAllocateToSelf: "不能分配给自己",
|
||
CodeCannotRecallFromSelf: "不能从自己回收",
|
||
CodeCardAlreadyAuthorized: "卡已授权给该企业",
|
||
CodeCardNotAuthorized: "卡未授权给该企业",
|
||
CodeCannotAuthorizeOthersCard: "不能授权非自己的卡",
|
||
CodeCannotRevokeOthersAuthorization: "不能回收非自己创建的授权",
|
||
CodeCannotAuthorizeBoundCard: "不能授权已绑定设备的卡",
|
||
CodeCannotAuthorizeToOthersEnterprise: "不能授权给非自己的企业",
|
||
CodeDeviceAlreadyAuthorized: "设备已授权给该企业",
|
||
CodeDeviceNotAuthorized: "设备未授权给该企业",
|
||
CodeDeviceAuthorizedToOther: "设备已授权给其他企业",
|
||
CodeCannotAuthorizeOthersDevice: "不能授权非自己的设备",
|
||
CodeStorageNotConfigured: "对象存储服务未配置",
|
||
CodeStorageUploadFailed: "文件上传失败",
|
||
CodeStorageDownloadFailed: "文件下载失败",
|
||
CodeStorageFileNotFound: "文件不存在",
|
||
CodeStorageInvalidPurpose: "不支持的文件用途",
|
||
CodeStorageInvalidFileType: "不支持的文件类型",
|
||
CodeCarrierNotFound: "运营商不存在",
|
||
CodeCarrierCodeExists: "运营商编码已存在",
|
||
CodeInvalidCredentials: "用户名或密码错误",
|
||
CodeAccountLocked: "账号已锁定",
|
||
CodePasswordExpired: "密码已过期",
|
||
CodeInvalidOldPassword: "旧密码错误",
|
||
CodeWechatOAuthFailed: "微信授权失败",
|
||
CodeWechatUserInfoFailed: "获取微信用户信息失败",
|
||
CodeWechatPayFailed: "微信支付发起失败",
|
||
CodeWechatCallbackInvalid: "微信回调验证失败",
|
||
CodeInternalError: "内部服务器错误",
|
||
CodeDatabaseError: "数据库错误",
|
||
CodeRedisError: "缓存服务错误",
|
||
CodeServiceUnavailable: "服务暂时不可用",
|
||
CodeTimeout: "请求超时",
|
||
CodeTaskQueueError: "任务队列错误",
|
||
}
|
||
|
||
// GetMessage 获取错误码对应的消息
|
||
// lang 参数暂时保留以便未来支持多语言,目前仅支持中文
|
||
func GetMessage(code int, lang string) string {
|
||
if msg, ok := errorMessages[code]; ok {
|
||
return msg
|
||
}
|
||
// 未定义的错误码返回默认消息
|
||
if code >= 2000 && code < 3000 {
|
||
return "内部服务器错误"
|
||
}
|
||
return "请求处理失败"
|
||
}
|
||
|
||
// GetHTTPStatus 将错误码映射为 HTTP 状态码
|
||
func GetHTTPStatus(code int) int {
|
||
switch code {
|
||
case CodeSuccess:
|
||
return 200 // OK
|
||
case CodeInvalidParam, CodeRequestTooLarge:
|
||
return 400 // Bad Request
|
||
case CodeMissingToken, CodeInvalidToken, CodeUnauthorized:
|
||
return 401 // Unauthorized
|
||
case CodeForbidden:
|
||
return 403 // Forbidden
|
||
case CodeNotFound:
|
||
return 404 // Not Found
|
||
case CodeConflict,
|
||
CodeUsernameExists,
|
||
CodePhoneExists,
|
||
CodeRoleNameExists,
|
||
CodePermCodeExists,
|
||
CodeShopCodeExists,
|
||
CodeEnterpriseCodeExists,
|
||
CodeCustomerPhoneExists,
|
||
CodeCarrierCodeExists:
|
||
return 409 // Conflict
|
||
case CodeTooManyRequests:
|
||
return 429 // Too Many Requests
|
||
case CodeServiceUnavailable:
|
||
return 503 // Service Unavailable
|
||
case CodeTimeout:
|
||
return 504 // Gateway Timeout
|
||
default:
|
||
// 服务端错误(2000-2999)默认映射为 500
|
||
if code >= 2000 && code < 3000 {
|
||
return 500 // Internal Server Error
|
||
}
|
||
// 客户端错误(1000-1999)默认映射为 400
|
||
if code >= 1000 && code < 2000 {
|
||
return 400 // Bad Request
|
||
}
|
||
// 其他未知错误默认为 500
|
||
return 500 // Internal Server Error
|
||
}
|
||
}
|
||
|
||
// GetLogLevel 将错误码映射为日志级别
|
||
// 返回值: "warn" (客户端错误), "error" (服务端错误), "info" (成功)
|
||
func GetLogLevel(code int) string {
|
||
if code == 0 {
|
||
return "info" // 成功
|
||
}
|
||
if code >= 2000 && code < 3000 {
|
||
return "error" // 服务端错误
|
||
}
|
||
if code >= 1000 && code < 2000 {
|
||
return "warn" // 客户端错误
|
||
}
|
||
return "error" // 默认为错误级别
|
||
}
|