补齐 HTTP 层:实现用户模块、路由与中间件接线、COS 上传及优雅启动

- 新增用户与上传错误码文件及 Recovery 中间件
- 修复 router.go 导入与中间件链,注册用户路由并补 handler 错误码导入
- 补充用户状态常量与 UserGetByWechatOpenID 查询,修订刷新令牌 dto
- 移除 upload 包 OTel 调用,新增 FileUploadCos 上传封装
- 实现 UserService 微信登录/刷新令牌/我的信息/改资料/上传头像
- 裁剪 main.go 配置段并移除 OTel 桥接,补启动与优雅退出
- 新增 configs 示例配置、global 配置结构及 go.mod 依赖
This commit is contained in:
2026-09-27 15:02:01 +08:00
parent 8f08d94a56
commit ff9add8655
33 changed files with 2473 additions and 0 deletions
+43
View File
@@ -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, "未知错误")
)
+77
View File
@@ -0,0 +1,77 @@
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():
return http.StatusInternalServerError
}
return http.StatusOK
}
+14
View File
@@ -0,0 +1,14 @@
package errcode
// 上传模块错误码段位:30000 - 39999
//
// 细分:
// 30000 - 30999 参数 / 校验
// 39000 - 39999 服务端错误
var (
UploadFileEmpty = NewError(30000, "上传文件为空")
UploadFileExtNotAllow = NewError(30001, "不支持的文件类型")
UploadFileTooLarge = NewError(30002, "文件大小超过限制")
UploadFileSaveFailed = NewError(39000, "文件保存失败")
)
+28
View File
@@ -0,0 +1,28 @@
package errcode
// 用户模块错误码段位:20000 - 29999
//
// 细分:
// 20000 - 20999 参数错误
// 21000 - 21999 鉴权 / 登录
// 22000 - 22999 资源不存在
// 23000 - 23999 冲突 / 重复
// 29000 - 29999 服务端错误
// ===== 鉴权 / 登录(21000 - 21999) =====
var (
UserDisabled = NewError(21001, "账号已被禁用")
UserWxLoginFailed = NewError(21002, "微信登录失败")
UserWxCodeInvalid = NewError(21003, "微信 Code 无效")
)
// ===== 资源不存在(22000 - 22999) =====
var (
UserNotFound = NewError(22000, "用户不存在")
)
// ===== 服务端错误(29000 - 29999) =====
var (
UserCreateFailed = NewError(29000, "用户创建失败")
UserUpdateFailed = NewError(29001, "用户更新失败")
)