fix(phase2a): handleError 增强 + 代码格式化 + 测试报告归档
- auth/contact Controller handleError 增加 fallbackMsg 可变参数,未知错误可返回更有语义的降级提示 - import 排序、变量对齐等 gofmt 格式规范化 - 新增管理端测试报告和路由验证报告 Made-with: Cursor
This commit is contained in:
@@ -6,9 +6,9 @@ import (
|
||||
"errors"
|
||||
"math"
|
||||
|
||||
adminDAO "github.com/echochat/backend/app/admin/dao"
|
||||
authDAO "github.com/echochat/backend/app/auth/dao"
|
||||
"github.com/echochat/backend/app/auth/model"
|
||||
adminDAO "github.com/echochat/backend/app/admin/dao"
|
||||
"github.com/echochat/backend/app/constants"
|
||||
"github.com/echochat/backend/app/dto"
|
||||
"github.com/echochat/backend/pkg/logs"
|
||||
|
||||
@@ -40,7 +40,7 @@ func (ctrl *AdminAuthController) AdminLogin(c *gin.Context) {
|
||||
|
||||
resp, err := ctrl.authService.AdminLogin(ctx, &req, c.ClientIP())
|
||||
if err != nil {
|
||||
handleAuthError(c, err)
|
||||
handleAuthError(c, err, "管理员登录失败")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ func (ctrl *AuthController) Register(c *gin.Context) {
|
||||
|
||||
resp, err := ctrl.authService.Register(ctx, &req)
|
||||
if err != nil {
|
||||
handleAuthError(c, err)
|
||||
handleAuthError(c, err, "注册失败")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func (ctrl *AuthController) Login(c *gin.Context) {
|
||||
|
||||
resp, err := ctrl.authService.Login(ctx, &req, c.ClientIP(), constants.ClientTypeFrontend)
|
||||
if err != nil {
|
||||
handleAuthError(c, err)
|
||||
handleAuthError(c, err, "登录失败")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func (ctrl *AuthController) RefreshToken(c *gin.Context) {
|
||||
|
||||
resp, err := ctrl.authService.RefreshToken(ctx, req.RefreshToken)
|
||||
if err != nil {
|
||||
handleAuthError(c, err)
|
||||
handleAuthError(c, err, "刷新 Token 失败")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ func (ctrl *AuthController) GetProfile(c *gin.Context) {
|
||||
|
||||
userInfo, err := ctrl.authService.GetProfile(ctx, userID)
|
||||
if err != nil {
|
||||
handleAuthError(c, err)
|
||||
handleAuthError(c, err, "获取个人信息失败")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func (ctrl *AuthController) UpdateProfile(c *gin.Context) {
|
||||
|
||||
userInfo, err := ctrl.authService.UpdateProfile(ctx, userID, &req)
|
||||
if err != nil {
|
||||
handleAuthError(c, err)
|
||||
handleAuthError(c, err, "更新个人资料失败")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -200,15 +200,17 @@ func (ctrl *AuthController) ChangePassword(c *gin.Context) {
|
||||
logs.Info(ctx, funcName, "修改密码", zap.Int64("user_id", userID))
|
||||
|
||||
if err := ctrl.authService.ChangePassword(ctx, userID, &req); err != nil {
|
||||
handleAuthError(c, err)
|
||||
handleAuthError(c, err, "修改密码失败")
|
||||
return
|
||||
}
|
||||
|
||||
utils.ResponseOK(c, nil)
|
||||
}
|
||||
|
||||
// handleAuthError 统一处理认证相关业务错误,映射到对应的 HTTP 状态码
|
||||
func handleAuthError(c *gin.Context, err error) {
|
||||
// handleAuthError 统一认证业务错误映射
|
||||
// 已知业务错误 → 返回 Service 层定义的具体提示(如"账号已被禁用")
|
||||
// 未知错误 → 返回 fallbackMsg(未传则默认"服务器内部错误")
|
||||
func handleAuthError(c *gin.Context, err error, fallbackMsg ...string) {
|
||||
switch err {
|
||||
case service.ErrUserAlreadyExists:
|
||||
utils.ResponseBadRequest(c, err.Error())
|
||||
@@ -225,6 +227,10 @@ func handleAuthError(c *gin.Context, err error) {
|
||||
case service.ErrRefreshTokenType:
|
||||
utils.ResponseBadRequest(c, err.Error())
|
||||
default:
|
||||
utils.ResponseError(c, "服务器内部错误")
|
||||
msg := "服务器内部错误"
|
||||
if len(fallbackMsg) > 0 && fallbackMsg[0] != "" {
|
||||
msg = fallbackMsg[0]
|
||||
}
|
||||
utils.ResponseError(c, msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func (ctl *ContactController) GetFriendList(c *gin.Context) {
|
||||
|
||||
friends, err := ctl.contactService.GetFriendList(ctx, userID, groupID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "获取好友列表失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, friends)
|
||||
@@ -65,7 +65,7 @@ func (ctl *ContactController) SendFriendRequest(c *gin.Context) {
|
||||
|
||||
err := ctl.contactService.SendFriendRequest(ctx, userID, req.TargetID, req.Message)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "发送好友申请失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -89,7 +89,7 @@ func (ctl *ContactController) AcceptFriendRequest(c *gin.Context) {
|
||||
|
||||
err := ctl.contactService.AcceptFriendRequest(ctx, req.RequestID, userID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "接受好友申请失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -113,7 +113,7 @@ func (ctl *ContactController) RejectFriendRequest(c *gin.Context) {
|
||||
|
||||
err := ctl.contactService.RejectFriendRequest(ctx, req.RequestID, userID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "拒绝好友申请失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -131,7 +131,7 @@ func (ctl *ContactController) GetPendingRequests(c *gin.Context) {
|
||||
|
||||
requests, err := ctl.contactService.GetPendingRequests(ctx, userID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "获取好友申请列表失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, requests)
|
||||
@@ -154,7 +154,7 @@ func (ctl *ContactController) DeleteFriend(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := ctl.contactService.DeleteFriend(ctx, userID, friendID); err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "删除好友失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -183,7 +183,7 @@ func (ctl *ContactController) UpdateRemark(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := ctl.contactService.UpdateRemark(ctx, userID, friendID, req.Remark); err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "更新备注失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -207,7 +207,7 @@ func (ctl *ContactController) BlockUser(c *gin.Context) {
|
||||
|
||||
err := ctl.contactService.BlockUser(ctx, userID, req.TargetID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "拉黑用户失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -230,7 +230,7 @@ func (ctl *ContactController) UnblockUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := ctl.contactService.UnblockUser(ctx, userID, targetID); err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "取消拉黑失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -248,7 +248,7 @@ func (ctl *ContactController) GetBlockList(c *gin.Context) {
|
||||
|
||||
blocked, err := ctl.contactService.GetBlockList(ctx, userID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "获取黑名单失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, blocked)
|
||||
@@ -275,7 +275,7 @@ func (ctl *ContactController) SearchUsers(c *gin.Context) {
|
||||
|
||||
users, total, err := ctl.contactService.SearchUsers(ctx, userID, keyword, page, pageSize)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "搜索用户失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, gin.H{
|
||||
@@ -296,7 +296,7 @@ func (ctl *ContactController) GetRecommendFriends(c *gin.Context) {
|
||||
|
||||
friends, err := ctl.contactService.GetRecommendFriends(ctx, userID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "获取好友推荐失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, friends)
|
||||
@@ -314,7 +314,7 @@ func (ctl *ContactController) GetGroups(c *gin.Context) {
|
||||
|
||||
groups, err := ctl.contactService.GetGroups(ctx, userID)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "获取分组列表失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, groups)
|
||||
@@ -338,7 +338,7 @@ func (ctl *ContactController) CreateGroup(c *gin.Context) {
|
||||
|
||||
group, err := ctl.contactService.CreateGroup(ctx, userID, req.Name)
|
||||
if err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "创建分组失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseCreated(c, group)
|
||||
@@ -367,7 +367,7 @@ func (ctl *ContactController) UpdateGroup(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := ctl.contactService.UpdateGroup(ctx, userID, groupID, req.Name, req.SortOrder); err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "修改分组失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -390,7 +390,7 @@ func (ctl *ContactController) DeleteGroup(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := ctl.contactService.DeleteGroup(ctx, userID, groupID); err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "删除分组失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
@@ -419,14 +419,16 @@ func (ctl *ContactController) MoveToGroup(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := ctl.contactService.MoveToGroup(ctx, userID, friendID, req.GroupID); err != nil {
|
||||
ctl.handleError(c, err)
|
||||
ctl.handleError(c, err, "移动好友到分组失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
}
|
||||
|
||||
// handleError 统一错误处理
|
||||
func (ctl *ContactController) handleError(c *gin.Context, err error) {
|
||||
// handleError 统一业务错误映射
|
||||
// 已知业务错误 → 返回 Service 层定义的具体提示(如"对方已将你拉黑")
|
||||
// 未知错误 → 返回 fallbackMsg(未传则默认"服务器内部错误")
|
||||
func (ctl *ContactController) handleError(c *gin.Context, err error, fallbackMsg ...string) {
|
||||
switch err {
|
||||
case service.ErrSelfRequest:
|
||||
utils.ResponseBadRequest(c, err.Error())
|
||||
@@ -443,6 +445,10 @@ func (ctl *ContactController) handleError(c *gin.Context, err error) {
|
||||
case service.ErrGroupNotFound:
|
||||
utils.ResponseNotFound(c, err.Error())
|
||||
default:
|
||||
utils.ResponseError(c, "服务内部错误")
|
||||
msg := "服务器内部错误"
|
||||
if len(fallbackMsg) > 0 && fallbackMsg[0] != "" {
|
||||
msg = fallbackMsg[0]
|
||||
}
|
||||
utils.ResponseError(c, msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,14 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrSelfRequest = errors.New("不能添加自己为好友")
|
||||
ErrAlreadyFriend = errors.New("已经是好友了")
|
||||
ErrPendingExists = errors.New("已有待处理的好友申请")
|
||||
ErrBlocked = errors.New("对方已将你拉黑")
|
||||
ErrRequestNotFound = errors.New("好友申请不存在")
|
||||
ErrFriendNotFound = errors.New("好友关系不存在")
|
||||
ErrGroupNotFound = errors.New("分组不存在")
|
||||
ErrUserNotFound = errors.New("用户不存在")
|
||||
ErrSelfRequest = errors.New("不能添加自己为好友")
|
||||
ErrAlreadyFriend = errors.New("已经是好友了")
|
||||
ErrPendingExists = errors.New("已有待处理的好友申请")
|
||||
ErrBlocked = errors.New("对方已将你拉黑")
|
||||
ErrRequestNotFound = errors.New("好友申请不存在")
|
||||
ErrFriendNotFound = errors.New("好友关系不存在")
|
||||
ErrGroupNotFound = errors.New("分组不存在")
|
||||
ErrUserNotFound = errors.New("用户不存在")
|
||||
)
|
||||
|
||||
// ContactService 联系人业务服务
|
||||
|
||||
@@ -3,35 +3,35 @@ package dto
|
||||
|
||||
// UserListRequest 管理端用户列表查询请求参数
|
||||
type UserListRequest struct {
|
||||
Page int `form:"page" binding:"required,min=1"` // 页码,从 1 开始
|
||||
Page int `form:"page" binding:"required,min=1"` // 页码,从 1 开始
|
||||
PageSize int `form:"page_size" binding:"required,min=1,max=100"` // 每页数量,1-100
|
||||
Keyword string `form:"keyword"` // 搜索关键词(匹配用户名或邮箱)
|
||||
Status *int `form:"status"` // 状态筛选:1=正常, 2=禁用, 3=注销;为空则不筛选
|
||||
Keyword string `form:"keyword"` // 搜索关键词(匹配用户名或邮箱)
|
||||
Status *int `form:"status"` // 状态筛选:1=正常, 2=禁用, 3=注销;为空则不筛选
|
||||
}
|
||||
|
||||
// UserListResponse 管理端用户列表响应
|
||||
type UserListResponse struct {
|
||||
Total int64 `json:"total"` // 符合条件的用户总数
|
||||
List []AdminUserInfo `json:"list"` // 当前页的用户列表
|
||||
Total int64 `json:"total"` // 符合条件的用户总数
|
||||
List []AdminUserInfo `json:"list"` // 当前页的用户列表
|
||||
}
|
||||
|
||||
// AdminUserInfo 管理端用户信息(比 UserInfo 更详细,包含管理字段)
|
||||
type AdminUserInfo struct {
|
||||
ID int64 `json:"id"` // 用户 ID
|
||||
Username string `json:"username"` // 用户名
|
||||
Email string `json:"email"` // 邮箱
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
Avatar string `json:"avatar"` // 头像 URL
|
||||
Gender int `json:"gender"` // 性别:0=未知, 1=男, 2=女
|
||||
Phone string `json:"phone,omitempty"` // 手机号
|
||||
Status int `json:"status"` // 账号状态
|
||||
StatusText string `json:"status_text"` // 状态中文描述
|
||||
Roles []RoleInfo `json:"roles"` // 角色详情列表(含 code/name/level)
|
||||
MaxLevel int `json:"max_level"` // 用户最高权限等级(最小 level 值)
|
||||
ID int64 `json:"id"` // 用户 ID
|
||||
Username string `json:"username"` // 用户名
|
||||
Email string `json:"email"` // 邮箱
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
Avatar string `json:"avatar"` // 头像 URL
|
||||
Gender int `json:"gender"` // 性别:0=未知, 1=男, 2=女
|
||||
Phone string `json:"phone,omitempty"` // 手机号
|
||||
Status int `json:"status"` // 账号状态
|
||||
StatusText string `json:"status_text"` // 状态中文描述
|
||||
Roles []RoleInfo `json:"roles"` // 角色详情列表(含 code/name/level)
|
||||
MaxLevel int `json:"max_level"` // 用户最高权限等级(最小 level 值)
|
||||
LastLoginAt string `json:"last_login_at,omitempty"` // 最后登录时间
|
||||
LastLoginIP string `json:"last_login_ip,omitempty"` // 最后登录 IP
|
||||
CreatedAt string `json:"created_at"` // 注册时间
|
||||
UpdatedAt string `json:"updated_at"` // 更新时间
|
||||
CreatedAt string `json:"created_at"` // 注册时间
|
||||
UpdatedAt string `json:"updated_at"` // 更新时间
|
||||
}
|
||||
|
||||
// RoleInfo 角色信息(用于前端角色列表展示和角色分配)
|
||||
|
||||
Reference in New Issue
Block a user