fix(phase2a): 代码审查修复 - 8项关键/重要问题
安全修复: - WebSocket Token 增加 Redis 有效性校验(已登出用户无法建立 WS) 功能修复: - GetRecommendFriends 改为批量查询,正确返回用户名/昵称/头像 - 上下线通知:OnlineService 通过接口注入获取好友列表推送状态变更 - 管理端在线用户 API 补充用户名信息 代码质量: - 所有 json.Marshal/Redis 错误增加检查与日志 - ContactController 13 个 endpoint 统一走 handleError 业务错误映射 - 管理端 Controller 补全包注释、函数注释和结构化日志 - 前端 5 个联系人页面 avatar 工具函数抽取到 utils/avatar.js Made-with: Cursor
This commit is contained in:
@@ -1,41 +1,56 @@
|
||||
// Package controller 提供 admin 模块的 HTTP 接口处理
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/echochat/backend/app/admin/service"
|
||||
"github.com/echochat/backend/pkg/logs"
|
||||
"github.com/echochat/backend/pkg/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// ContactManageController 联系人关系管理控制器(管理端)
|
||||
type ContactManageController struct {
|
||||
contactManageService *service.ContactManageService
|
||||
}
|
||||
|
||||
// NewContactManageController 创建 ContactManageController 实例
|
||||
func NewContactManageController(contactManageService *service.ContactManageService) *ContactManageController {
|
||||
return &ContactManageController{contactManageService: contactManageService}
|
||||
}
|
||||
|
||||
// GetAllContacts GET /api/v1/admin/contacts
|
||||
// GetAllContacts 获取所有好友关系列表(分页)
|
||||
// GET /api/v1/admin/contacts
|
||||
func (ctl *ContactManageController) GetAllContacts(c *gin.Context) {
|
||||
funcName := "admin.contact_manage_controller.GetAllContacts"
|
||||
ctx := c.Request.Context()
|
||||
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
|
||||
contacts, total, err := ctl.contactManageService.GetAllFriendships(ctx, page, pageSize)
|
||||
if err != nil {
|
||||
logs.Error(ctx, funcName, "获取好友关系列表失败", zap.Error(err))
|
||||
utils.ResponseError(c, "获取好友关系列表失败")
|
||||
return
|
||||
}
|
||||
|
||||
logs.Info(ctx, funcName, "获取好友关系列表成功",
|
||||
zap.Int64("total", total), zap.Int("page", page))
|
||||
utils.ResponseOK(c, gin.H{
|
||||
"list": contacts,
|
||||
"total": total,
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteContact DELETE /api/v1/admin/contacts/:id
|
||||
// DeleteContact 删除好友关系
|
||||
// DELETE /api/v1/admin/contacts/:id
|
||||
func (ctl *ContactManageController) DeleteContact(c *gin.Context) {
|
||||
funcName := "admin.contact_manage_controller.DeleteContact"
|
||||
ctx := c.Request.Context()
|
||||
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
utils.ResponseBadRequest(c, "ID 格式错误")
|
||||
@@ -43,8 +58,12 @@ func (ctl *ContactManageController) DeleteContact(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := ctl.contactManageService.DeleteFriendship(ctx, id); err != nil {
|
||||
logs.Error(ctx, funcName, "删除好友关系失败",
|
||||
zap.Int64("friendship_id", id), zap.Error(err))
|
||||
utils.ResponseError(c, "删除好友关系失败")
|
||||
return
|
||||
}
|
||||
|
||||
logs.Info(ctx, funcName, "删除好友关系成功", zap.Int64("friendship_id", id))
|
||||
utils.ResponseOK(c, nil)
|
||||
}
|
||||
|
||||
@@ -1,37 +1,54 @@
|
||||
// Package controller 提供 admin 模块的 HTTP 接口处理
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/echochat/backend/app/admin/service"
|
||||
"github.com/echochat/backend/pkg/logs"
|
||||
"github.com/echochat/backend/pkg/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// OnlineController 在线用户管理控制器(管理端)
|
||||
type OnlineController struct {
|
||||
onlineManageService *service.OnlineManageService
|
||||
}
|
||||
|
||||
// NewOnlineController 创建 OnlineController 实例
|
||||
func NewOnlineController(onlineManageService *service.OnlineManageService) *OnlineController {
|
||||
return &OnlineController{onlineManageService: onlineManageService}
|
||||
}
|
||||
|
||||
// GetOnlineUsers GET /api/v1/admin/online/users
|
||||
// GetOnlineUsers 获取在线用户列表
|
||||
// GET /api/v1/admin/online/users
|
||||
func (ctl *OnlineController) GetOnlineUsers(c *gin.Context) {
|
||||
funcName := "admin.online_controller.GetOnlineUsers"
|
||||
ctx := c.Request.Context()
|
||||
userIDs, err := ctl.onlineManageService.GetOnlineUsers(ctx)
|
||||
|
||||
users, err := ctl.onlineManageService.GetOnlineUsers(ctx)
|
||||
if err != nil {
|
||||
logs.Error(ctx, funcName, "获取在线用户列表失败", zap.Error(err))
|
||||
utils.ResponseError(c, "获取在线用户列表失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, userIDs)
|
||||
|
||||
logs.Info(ctx, funcName, "获取在线用户列表成功", zap.Int("count", len(users)))
|
||||
utils.ResponseOK(c, users)
|
||||
}
|
||||
|
||||
// GetOnlineCount GET /api/v1/admin/online/count
|
||||
// GetOnlineCount 获取在线用户总数
|
||||
// GET /api/v1/admin/online/count
|
||||
func (ctl *OnlineController) GetOnlineCount(c *gin.Context) {
|
||||
funcName := "admin.online_controller.GetOnlineCount"
|
||||
ctx := c.Request.Context()
|
||||
|
||||
count, err := ctl.onlineManageService.GetOnlineCount(ctx)
|
||||
if err != nil {
|
||||
logs.Error(ctx, funcName, "获取在线用户数失败", zap.Error(err))
|
||||
utils.ResponseError(c, "获取在线用户数失败")
|
||||
return
|
||||
}
|
||||
|
||||
logs.Info(ctx, funcName, "获取在线用户数成功", zap.Int64("count", count))
|
||||
utils.ResponseOK(c, gin.H{"count": count})
|
||||
}
|
||||
|
||||
@@ -33,7 +33,10 @@ func (s *ContactManageService) GetAllFriendships(ctx context.Context, page, page
|
||||
logs.Debug(ctx, funcName, "管理端查询好友关系")
|
||||
|
||||
var total int64
|
||||
s.db.WithContext(ctx).Model(&model.Friendship{}).Count(&total)
|
||||
if err := s.db.WithContext(ctx).Model(&model.Friendship{}).Count(&total).Error; err != nil {
|
||||
logs.Error(ctx, funcName, "统计好友关系总数失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var results []AdminFriendship
|
||||
offset := (page - 1) * pageSize
|
||||
@@ -60,8 +63,11 @@ func (s *ContactManageService) DeleteFriendship(ctx context.Context, friendshipI
|
||||
}
|
||||
|
||||
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
tx.Where("user_id = ? AND friend_id = ?", f.UserID, f.FriendID).Delete(&model.Friendship{})
|
||||
tx.Where("user_id = ? AND friend_id = ?", f.FriendID, f.UserID).Delete(&model.Friendship{})
|
||||
return nil
|
||||
if err := tx.Where("user_id = ? AND friend_id = ?", f.UserID, f.FriendID).
|
||||
Delete(&model.Friendship{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Where("user_id = ? AND friend_id = ?", f.FriendID, f.UserID).
|
||||
Delete(&model.Friendship{}).Error
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,24 +3,72 @@ package service
|
||||
import (
|
||||
"context"
|
||||
|
||||
authModel "github.com/echochat/backend/app/auth/model"
|
||||
wsApp "github.com/echochat/backend/app/ws"
|
||||
"github.com/echochat/backend/pkg/logs"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// OnlineUserInfo 在线用户信息(包含用户名,用于管理端展示)
|
||||
type OnlineUserInfo struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
// OnlineManageService 管理端在线状态查询服务
|
||||
type OnlineManageService struct {
|
||||
onlineService *wsApp.OnlineService
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewOnlineManageService(onlineService *wsApp.OnlineService) *OnlineManageService {
|
||||
return &OnlineManageService{onlineService: onlineService}
|
||||
// NewOnlineManageService 创建 OnlineManageService 实例
|
||||
func NewOnlineManageService(onlineService *wsApp.OnlineService, db *gorm.DB) *OnlineManageService {
|
||||
return &OnlineManageService{
|
||||
onlineService: onlineService,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *OnlineManageService) GetOnlineUsers(ctx context.Context) ([]int64, error) {
|
||||
// GetOnlineUsers 获取在线用户列表(含用户名)
|
||||
func (s *OnlineManageService) GetOnlineUsers(ctx context.Context) ([]OnlineUserInfo, error) {
|
||||
funcName := "service.online_manage_service.GetOnlineUsers"
|
||||
logs.Debug(ctx, funcName, "获取在线用户列表")
|
||||
return s.onlineService.GetOnlineUserIDs(ctx)
|
||||
|
||||
ids, err := s.onlineService.GetOnlineUserIDs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return []OnlineUserInfo{}, nil
|
||||
}
|
||||
|
||||
var users []authModel.User
|
||||
if err := s.db.WithContext(ctx).
|
||||
Model(&authModel.User{}).
|
||||
Select("id, username").
|
||||
Where("id IN ?", ids).
|
||||
Find(&users).Error; err != nil {
|
||||
logs.Error(ctx, funcName, "查询在线用户信息失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userMap := make(map[int64]string, len(users))
|
||||
for _, u := range users {
|
||||
userMap[u.ID] = u.Username
|
||||
}
|
||||
|
||||
result := make([]OnlineUserInfo, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
result = append(result, OnlineUserInfo{
|
||||
UserID: id,
|
||||
Username: userMap[id],
|
||||
})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetOnlineCount 获取在线用户总数
|
||||
func (s *OnlineManageService) GetOnlineCount(ctx context.Context) (int64, error) {
|
||||
return s.onlineService.GetOnlineCount(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user