first commit
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
package errcode
|
||||
|
||||
// 衣物相关错误码段位:50000 - 59999
|
||||
var (
|
||||
ClothesNotFound = NewError(50000, "衣物不存在")
|
||||
ClothesInUse = NewError(50001, "衣服已被搭配使用,无法删除")
|
||||
ClothesCreateFailed = NewError(50002, "创建衣物失败")
|
||||
ClothesDeleteFailed = NewError(50003, "删除衣物失败")
|
||||
ClothesUpdateFailed = NewError(50004, "更新衣物失败")
|
||||
ClothesNoPermission = NewError(50005, "无权操作该衣物")
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
package errcode
|
||||
|
||||
// 公共错误码段位:10000 - 19999
|
||||
//
|
||||
// 细分:
|
||||
// 10000 - 10999 通用 / 参数错误
|
||||
// 11000 - 11999 鉴权 / Token
|
||||
// 12000 - 12999 权限 / 资源
|
||||
// 19000 - 19999 系统级错误(DB、缓存、RPC)
|
||||
|
||||
// 成功
|
||||
var Success = NewError(0, "成功")
|
||||
|
||||
// ===== 通用错误(10000 - 10999) =====
|
||||
var (
|
||||
InvalidParams = NewError(10000, "请求参数错误")
|
||||
NotFound = NewError(10001, "资源不存在")
|
||||
MethodNotAllow = NewError(10002, "请求方法不允许")
|
||||
TooManyRequests = NewError(10003, "请求过于频繁")
|
||||
)
|
||||
|
||||
// ===== 鉴权 / Token(11000 - 11999) =====
|
||||
var (
|
||||
Unauthorized = NewError(11000, "未授权")
|
||||
UnauthorizedTokenError = NewError(11001, "Token 鉴权失败")
|
||||
UnauthorizedTokenTimeout = NewError(11002, "Token 已过期")
|
||||
UnauthorizedTokenGenerate = NewError(11003, "Token 生成失败")
|
||||
UnauthorizedTokenMissing = NewError(11004, "Token 缺失")
|
||||
)
|
||||
|
||||
// ===== 权限(12000 - 12999) =====
|
||||
var (
|
||||
Forbidden = NewError(12000, "无权限访问")
|
||||
)
|
||||
|
||||
// ===== 系统错误(19000 - 19999) =====
|
||||
var (
|
||||
ServerError = NewError(19000, "服务内部错误")
|
||||
DatabaseError = NewError(19001, "数据库错误")
|
||||
CacheError = NewError(19002, "缓存错误")
|
||||
RPCError = NewError(19003, "下游服务调用失败")
|
||||
UnknownError = NewError(19999, "未知错误")
|
||||
)
|
||||
@@ -0,0 +1,79 @@
|
||||
package errcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Error 业务错误
|
||||
type Error struct {
|
||||
code int
|
||||
msg string
|
||||
details []string
|
||||
}
|
||||
|
||||
// codes 用于注册时去重检查
|
||||
var codes = map[int]string{}
|
||||
|
||||
// NewError 注册并创建一个错误码
|
||||
func NewError(code int, msg string) *Error {
|
||||
if _, exists := codes[code]; exists {
|
||||
panic(fmt.Sprintf("error code %d already exists, please change", code))
|
||||
}
|
||||
codes[code] = msg
|
||||
return &Error{code: code, msg: msg}
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return fmt.Sprintf("error code: %d, msg: %s", e.code, e.msg)
|
||||
}
|
||||
|
||||
func (e *Error) Code() int { return e.code }
|
||||
func (e *Error) Msg() string { return e.msg }
|
||||
func (e *Error) Details() []string { return e.details }
|
||||
|
||||
func (e *Error) Msgf(args ...interface{}) string {
|
||||
return fmt.Sprintf(e.msg, args...)
|
||||
}
|
||||
|
||||
// WithDetails 附加详细信息(返回副本)
|
||||
func (e *Error) WithDetails(details ...string) *Error {
|
||||
newError := *e
|
||||
newError.details = append(newError.details, details...)
|
||||
return &newError
|
||||
}
|
||||
|
||||
// StatusCode 业务码 → HTTP 状态码
|
||||
// 仅对少数特殊错误返回非 200,其余统一 200,由前端按业务 code 处理
|
||||
func (e *Error) StatusCode() int {
|
||||
switch e.code {
|
||||
case Success.Code():
|
||||
return http.StatusOK
|
||||
|
||||
// 鉴权类返回 401,便于前端拦截器统一处理跳转登录
|
||||
case Unauthorized.Code(),
|
||||
UnauthorizedTokenError.Code(),
|
||||
UnauthorizedTokenTimeout.Code(),
|
||||
UnauthorizedTokenMissing.Code():
|
||||
return http.StatusUnauthorized
|
||||
|
||||
// 越权/无权限返回 403,便于网关与审计识别越权事件
|
||||
case Forbidden.Code():
|
||||
return http.StatusForbidden
|
||||
|
||||
// 限流返回 429,便于网关识别限流事件
|
||||
case TooManyRequests.Code():
|
||||
return http.StatusTooManyRequests
|
||||
|
||||
// 系统错误返回 500,便于运维监控告警
|
||||
case ServerError.Code(),
|
||||
DatabaseError.Code(),
|
||||
CacheError.Code(),
|
||||
RPCError.Code(),
|
||||
UnknownError.Code(),
|
||||
MattingFailed.Code(),
|
||||
ClassifyFailed.Code():
|
||||
return http.StatusInternalServerError
|
||||
}
|
||||
return http.StatusOK
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package errcode
|
||||
|
||||
// 商品模块错误码段位:60000 - 69999
|
||||
//
|
||||
// 60000 - 60999 业务错误
|
||||
// 69000 - 69999 服务端错误
|
||||
var (
|
||||
GoodsNotFound = NewError(60000, "商品不存在")
|
||||
GoodsOffShelf = NewError(60001, "商品已下架")
|
||||
GoodsCreateFailed = NewError(69000, "创建商品失败")
|
||||
GoodsUpdateFailed = NewError(69001, "更新商品失败")
|
||||
GoodsDeleteFailed = NewError(69002, "删除商品失败")
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
package errcode
|
||||
|
||||
// 通知/分享/社区/星座/AI 模块错误码段位:90000 - 99999
|
||||
var (
|
||||
// 通知(90000 - 90099)
|
||||
NotificationNotFound = NewError(90000, "通知不存在")
|
||||
|
||||
// 分享(90100 - 90199)
|
||||
ShareNotFound = NewError(90100, "分享不存在")
|
||||
ShareExpired = NewError(90101, "分享已过期")
|
||||
ShareCancelled = NewError(90102, "分享已取消")
|
||||
|
||||
// 点赞/收藏/社区(90200 - 90299)
|
||||
TargetNotFound = NewError(90200, "目标内容不存在")
|
||||
LikeFailed = NewError(90201, "点赞操作失败")
|
||||
CollectFailed = NewError(90202, "收藏操作失败")
|
||||
|
||||
// 星座(90300 - 90399)
|
||||
HoroscopeNotFound = NewError(90300, "星座运势不存在")
|
||||
|
||||
// AI 推荐(90400 - 90499)
|
||||
AIRecommendFailed = NewError(90400, "AI 推荐失败")
|
||||
AIRecommendQuotaLimit = NewError(90401, "AI 推荐次数已达上限")
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
package errcode
|
||||
|
||||
// 订单模块错误码段位:70000 - 70999
|
||||
// 退款子模块:71000 - 71999
|
||||
// 服务端错误:79000 - 79999
|
||||
var (
|
||||
// 订单
|
||||
OrderNotFound = NewError(70000, "订单不存在")
|
||||
OrderStatusInvalid = NewError(70001, "订单状态不正确")
|
||||
OrderAlreadyPaid = NewError(70002, "订单已支付")
|
||||
OrderAlreadyCancelled = NewError(70003, "订单已取消")
|
||||
OrderExpired = NewError(70004, "订单已过期")
|
||||
OrderCreateFailed = NewError(79000, "创建订单失败")
|
||||
OrderCancelFailed = NewError(79001, "取消订单失败")
|
||||
OrderUpdateFailed = NewError(79002, "更新订单失败")
|
||||
|
||||
// 虚拟支付
|
||||
VirtualPayNotEnabled = NewError(70005, "虚拟支付未开通")
|
||||
VirtualPayGoodsNotPublished = NewError(70006, "商品尚未发布为虚拟支付道具")
|
||||
VirtualOrderCancelNotAllowed = NewError(70007, "虚拟支付订单不支持取消")
|
||||
VirtualPayAmountTooLow = NewError(70008, "iOS 虚拟支付最低 1 元")
|
||||
OrderRealityCheckFailed = NewError(70009, "订单真实性校验失败")
|
||||
VirtualOrderCreateFailed = NewError(79003, "创建虚拟支付订单失败")
|
||||
|
||||
// 退款
|
||||
RefundNotFound = NewError(71000, "退款记录不存在")
|
||||
RefundNotAllowed = NewError(71001, "当前状态不允许退款")
|
||||
RefundAmountInvalid = NewError(71002, "退款金额不合法")
|
||||
RefundApplyFailed = NewError(71003, "退款申请失败")
|
||||
IOSRefundViaAppStore = NewError(71004, "iOS 订单请通过 App Store 申请退款")
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
package errcode
|
||||
|
||||
// 穿搭相关错误码段位:40000 - 49999
|
||||
var (
|
||||
OutfitNotFound = NewError(40000, "穿搭不存在")
|
||||
OutfitCreateFailed = NewError(40001, "创建穿搭失败")
|
||||
OutfitDeleteFailed = NewError(40002, "删除穿搭失败")
|
||||
OutfitUpdateFailed = NewError(40003, "更新穿搭失败")
|
||||
OutfitNoPermission = NewError(40004, "无权操作该穿搭")
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
package errcode
|
||||
|
||||
// 额度模块错误码段位:80000 - 80999
|
||||
// VIP 子模块:81000 - 81999
|
||||
// 服务端错误:89000 - 89999
|
||||
var (
|
||||
// 额度
|
||||
QuotaInsufficient = NewError(80000, "额度不足")
|
||||
QuotaNotFound = NewError(80001, "额度记录不存在")
|
||||
AdRewardClaimed = NewError(80002, "广告激励已领取")
|
||||
AdRewardInvalid = NewError(80003, "无效的激励类型")
|
||||
AdRewardDisabled = NewError(80004, "广告激励未开启")
|
||||
QuotaUpdateFailed = NewError(89000, "额度更新失败")
|
||||
|
||||
// VIP
|
||||
VIPNotFound = NewError(81000, "会员记录不存在")
|
||||
VIPExpired = NewError(81001, "会员已过期")
|
||||
VIPCreateFailed = NewError(81002, "会员开通失败")
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package errcode
|
||||
|
||||
// 上传模块错误码段位:30000-39999
|
||||
// 30000-30999 参数/校验
|
||||
// 39000-39999 服务端错误
|
||||
|
||||
var (
|
||||
UploadFileEmpty = NewError(30000, "上传文件为空")
|
||||
UploadFileExtNotAllow = NewError(30001, "不支持的文件类型")
|
||||
UploadFileTooLarge = NewError(30002, "文件大小超过限制")
|
||||
UploadFileNotFound = NewError(30004, "文件不存在")
|
||||
UploadFileSaveFailed = NewError(39000, "文件保存失败")
|
||||
FileNotPublic = NewError(30005, "文件不是公开的")
|
||||
FileNoPermission = NewError(30006, "权限不足")
|
||||
FileProcessing = NewError(30007, "文件处理中")
|
||||
MattingFailed = NewError(39001, "图片抠图处理失败")
|
||||
ClassifyFailed = NewError(39002, "图片分类处理失败")
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
package errcode
|
||||
|
||||
// 用户模块错误码段位:20000 - 29999
|
||||
//
|
||||
// 细分:
|
||||
// 20000 - 20999 参数错误
|
||||
// 21000 - 21999 鉴权 / 登录
|
||||
// 22000 - 22999 资源不存在
|
||||
// 23000 - 23999 冲突 / 重复
|
||||
// 29000 - 29999 服务端错误
|
||||
|
||||
// ===== 参数错误(20000 - 20999) =====
|
||||
var (
|
||||
UserParamsInvalid = NewError(20000, "用户参数错误")
|
||||
)
|
||||
|
||||
// ===== 鉴权 / 登录(21000 - 21999) =====
|
||||
var (
|
||||
UserLoginFailed = NewError(21000, "用户名或密码错误")
|
||||
UserDisabled = NewError(21001, "账号已被禁用")
|
||||
UserWxLoginFailed = NewError(21002, "微信登录失败")
|
||||
UserWxCodeInvalid = NewError(21003, "微信 Code 无效")
|
||||
UserRegistrationDisabled = NewError(21004, "注册暂未开放")
|
||||
)
|
||||
|
||||
// ===== 资源不存在(22000 - 22999) =====
|
||||
var (
|
||||
UserNotFound = NewError(22000, "用户不存在")
|
||||
)
|
||||
|
||||
// ===== 冲突(23000 - 23999) =====
|
||||
var (
|
||||
UserAlreadyExists = NewError(23000, "用户已存在")
|
||||
UserEmailExists = NewError(23001, "邮箱已被注册")
|
||||
)
|
||||
|
||||
// ===== 服务端错误(29000 - 29999) =====
|
||||
var (
|
||||
UserCreateFailed = NewError(29000, "用户创建失败")
|
||||
UserUpdateFailed = NewError(29001, "用户更新失败")
|
||||
UserDeleteFailed = NewError(29002, "用户删除失败")
|
||||
UserQueryFailed = NewError(29003, "用户查询失败")
|
||||
)
|
||||
Reference in New Issue
Block a user